fangmingyue 1年前
父节点
当前提交
6bcc3835f3

+ 4111
- 0
package-lock.json
文件差异内容过多而无法显示
查看文件


+ 1
- 0
package.json 查看文件

@@ -17,6 +17,7 @@
17 17
     "antd": "^5.11.2",
18 18
     "axios": "^1.2.0",
19 19
     "classnames": "^2.3.2",
20
+    "dayjs": "^1.11.8",
20 21
     "echarts": "^5.4.0",
21 22
     "md5": "^2.3.0",
22 23
     "react": "18.2.0",

+ 2
- 2
src/components/Page/index.jsx 查看文件

@@ -10,14 +10,14 @@ const pageStyle = {
10 10
 const { Title } = Typography;
11 11
 
12 12
 export default (props) => {
13
-  console.log(props);
13
+  // console.log(props);
14 14
   const { meta = {} } = useRoute() || {};
15 15
   const style = meta.noLayout ? { height: '100%' } : pageStyle;
16 16
   const title = props.title || meta.title;
17 17
 
18 18
   return (
19 19
     <div style={style}>
20
-      { title && !meta.noLayout && <Title level={3} style={{ paddingBottom: '12px', fontWeight: 400 }}>{ title }</Title> }
20
+      {title && !meta.noLayout && <Title level={3} style={{ paddingBottom: '12px', fontWeight: 400 }}>{title}</Title>}
21 21
       {props.children}
22 22
     </div>
23 23
   )

+ 9
- 6
src/components/Upload/UploadFiles.jsx 查看文件

@@ -50,18 +50,23 @@ export default function UploadFiles (props) {
50 50
       setLoading(false)
51 51
       const resp = info.file.response;
52 52
       const data = typeof transform == 'function' ? transform(resp) : resp;
53
-      // let da = data?.url
54 53
       if (multiple) {
55
-        // console.log('-------2---->>');
56 54
         const idList = list.map(getId);
57 55
         const targId = getId(data);
58 56
         // if (idList.findIndex(x => x == targId) == -1) {
59
-        let da = { ...data, status: 1 }
57
+        let da = [{ ...data, status: 1 }]
58
+        // console.log('------da----->', da);
59
+        const destda = da.map(item => {
60
+          const { createdBy, createdTime, updatedBy, updatedTime, ...rest } = item;
61
+          return rest;
62
+        });
63
+
60 64
         const destList = list.map(item => {
61 65
           const { createdBy, createdTime, updatedBy, updatedTime, ...rest } = item;
62 66
           return rest;
63 67
         });
64
-        onChange(destList.concat(da))
68
+
69
+        onChange(destList.concat(destda))
65 70
         // }
66 71
       } else {
67 72
         onChange(data)
@@ -79,8 +84,6 @@ export default function UploadFiles (props) {
79 84
     }
80 85
   }
81 86
 
82
-  // console.log('-----valuefang--->', value);
83
-
84 87
   return (
85 88
     <Upload
86 89
       multiple={multiple}

+ 3
- 1
src/components/Upload/UploadImage.jsx 查看文件

@@ -1,10 +1,12 @@
1 1
 import React, { useState } from 'react';
2 2
 import { setProperty } from '@/utils/css';
3 3
 import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
4
+import { message } from 'antd'
4 5
 import Upload from './Upload';
5 6
 import styles from './style.less';
6 7
 
7 8
 function beforeUpload (file) {
9
+  // console.log('--------file----->', file);
8 10
   const isImage = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif';
9 11
   if (!isImage) {
10 12
     message.error('请上传 JPG , PNG或GIF 图片!');
@@ -61,7 +63,7 @@ export default (props) => {
61 63
   return (
62 64
     <Upload
63 65
       listType="picture-card"
64
-      className={styles['ant-upload']}
66
+      // className={styles['ant-upload']}
65 67
       style={{ width: '200px' }}
66 68
       showUploadList={false}
67 69
       beforeUpload={beforeUpload}

+ 1
- 0
src/components/Upload/UploadImageList.jsx 查看文件

@@ -2,6 +2,7 @@
2 2
 import React, { useEffect, useState } from 'react';
3 3
 import { Modal } from 'antd'
4 4
 import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
5
+import { message } from 'antd'
5 6
 import Upload from './Upload';
6 7
 
7 8
 function beforeUpload (file) {

+ 12
- 12
src/components/Upload/style.less 查看文件

@@ -6,16 +6,16 @@
6 6
   }
7 7
 }
8 8
 
9
-.ant-upload {
10
-  :global(.ant-upload-select) {
11
-    width: var(--cust-upload-width) !important;
12
-    height: auto !important;
13
-    aspect-ratio: var(--cust-upload-ratio);
14
-  }
9
+// .ant-upload {
10
+//   :global(.ant-upload-select) {
11
+//     width: var(--cust-upload-width) !important;
12
+//     height: auto !important;
13
+//     aspect-ratio: var(--cust-upload-ratio);
14
+//   }
15 15
 
16
-  .cust-img-thumb {
17
-    width: var(--cust-upload-width) !important;
18
-    height: auto !important;
19
-    aspect-ratio: var(--cust-upload-ratio);
20
-  }
21
-}
16
+//   .cust-img-thumb {
17
+//     width: var(--cust-upload-width) !important;
18
+//     height: auto !important;
19
+//     aspect-ratio: var(--cust-upload-ratio);
20
+//   }
21
+// }

+ 97
- 25
src/components/Wangeditor/index.jsx 查看文件

@@ -1,6 +1,14 @@
1 1
 import React, { useState, useEffect } from "react";
2
+import { Spin } from 'antd';
2 3
 import "@wangeditor/editor/dist/css/style.css";
3 4
 import { Editor, Toolbar } from "@wangeditor/editor-for-react";
5
+import { DomEditor, Boot } from "@wangeditor/editor";
6
+import { customUploadImage, customBrowseAndUploadVideo } from "./util";
7
+import videoToHtmlConf from "./plugins/video/videoToHtmlConf";
8
+import imageToHtmlConf from "./plugins/image/imageToHtmlConf";
9
+
10
+Boot.registerElemToHtml(videoToHtmlConf);
11
+Boot.registerElemToHtml(imageToHtmlConf);
4 12
 
5 13
 // 工具栏配置参考
6 14
 // https://www.cnblogs.com/-roc/p/16400965.html
@@ -8,29 +16,77 @@ import { Editor, Toolbar } from "@wangeditor/editor-for-react";
8 16
 const defaultStyle = {
9 17
   border: "1px solid #ccc",
10 18
   zIndex: 100,
11
-  marginTop: "15px"
12
-}
13
-
14
-function MyEditor(props) {
19
+  marginTop: "15px",
20
+};
15 21
 
16
-  const style = React.useMemo(() => ({ ...defaultStyle, ...(props.style || {}) }), [props.style])
22
+function MyEditor (props) {
23
+  const style = React.useMemo(
24
+    () => ({ ...defaultStyle, ...(props.style || {}) }),
25
+    [props.style]
26
+  );
17 27
 
18 28
   const {
19 29
     value = "",
20 30
     onChange = (e) => {
21 31
       setHtml(e);
22 32
     },
23
-    toolbarConfig = {
24
-      excludeKeys: ["group-image", "group-video"],
25
-    },
33
+    toolbarKeys,
34
+    toolbarConfig = {},
26 35
     editorConfig = {
27 36
       placeholder: "请输入内容...",
28 37
     },
29 38
     readonly = false,
39
+    mode = "default",
40
+    height = 500,
30 41
   } = props;
31 42
   const [editor, setEditor] = useState(null); // 存储 editor 实例
32 43
   const [html, setHtml] = useState("");
33
- 
44
+  const [loading, setLoading] = useState(false);
45
+
46
+  const toolbarConf = React.useMemo(() => {
47
+    return toolbarKeys
48
+      ? {
49
+        toolbarKeys,
50
+        ...toolbarConfig,
51
+      }
52
+      : toolbarConfig;
53
+  }, [toolbarConfig, toolbarKeys]);
54
+
55
+  const editorConf = React.useMemo(() => {
56
+    const menuConf = editorConfig.MENU_CONF;
57
+
58
+    return {
59
+      ...editorConfig,
60
+      MENU_CONF: {
61
+        uploadImage: { customUpload: customUploadImage },
62
+        uploadVideo: { customBrowseAndUpload: customBrowseAndUploadVideo(setLoading) },
63
+        ...menuConf,
64
+        fontSize: {
65
+          fontSizeList: [
66
+            "10px",
67
+            "11px",
68
+            "12px",
69
+            "13px",
70
+            "14px",
71
+            "15px",
72
+            "16px",
73
+            "18px",
74
+            "20px",
75
+            "24px",
76
+            "28px",
77
+            "40px",
78
+            "64px",
79
+            "72px",
80
+          ]
81
+        },
82
+        lineHeight: {
83
+          // 从1 到 2.5
84
+          lineHeightList: (new Array(16)).fill().map((_, inx) => `${1 + inx / 10}`),
85
+        }
86
+      },
87
+    };
88
+  }, [editorConfig]);
89
+
34 90
   // 模拟 ajax 请求,异步设置 html
35 91
   useEffect(() => {
36 92
     setHtml(value || "");
@@ -38,6 +94,13 @@ function MyEditor(props) {
38 94
 
39 95
   // 及时销毁 editor
40 96
   useEffect(() => {
97
+    if (editor) {
98
+      const toolbar = DomEditor.getToolbar(editor);
99
+      const curToolbarConfig = toolbar.getConfig();
100
+      // console.log(curToolbarConfig.toolbarKeys); // 当前菜单排序和分组
101
+      // console.log(editor?.getAllMenuKeys());
102
+    }
103
+
41 104
     return () => {
42 105
       if (editor == null) return;
43 106
       editor.destroy();
@@ -45,39 +108,48 @@ function MyEditor(props) {
45 108
     };
46 109
   }, [editor]);
47 110
 
48
-  function insertText() {
111
+  function insertText () {
49 112
     if (editor == null) return;
50 113
     editor.insertText(" hello ");
51 114
   }
52 115
 
53
-  function printHtml() {
116
+  function printHtml () {
54 117
     if (editor == null) return;
55 118
     console.log(editor.getHtml());
56 119
   }
57 120
 
58 121
   const handleChange = (editor) => {
59
-    const raw = editor.getHtml();
60
-    if (raw !== '<p><br></p>') {
61
-      onChange(raw)
122
+    let raw = editor.getHtml();
123
+
124
+    if (raw) {
125
+      raw = raw.replaceAll('<p>', '<p class="rich-paragraph">');
62 126
     }
63
-  }
127
+
128
+    if (raw !== "<p><br></p>") {
129
+      onChange(raw);
130
+    } else {
131
+      onChange("");
132
+    }
133
+  };
64 134
 
65 135
   return !readonly ? (
66 136
     <div className={props.className} style={style}>
67 137
       <Toolbar
68 138
         editor={editor}
69
-        defaultConfig={toolbarConfig}
70
-        mode="default"
139
+        defaultConfig={toolbarConf}
140
+        mode={mode}
71 141
         style={{ borderBottom: "1px solid #ccc" }}
72 142
       />
73
-      <Editor
74
-        defaultConfig={editorConfig}
75
-        value={html}
76
-        onCreated={setEditor}
77
-        onChange={handleChange}
78
-        mode="default"
79
-        style={{ height: "500px" }}
80
-      />
143
+      <Spin spinning={loading}>
144
+        <Editor
145
+          defaultConfig={editorConf}
146
+          value={html}
147
+          onCreated={setEditor}
148
+          onChange={handleChange}
149
+          mode={mode}
150
+          style={{ height: `${height}px` }}
151
+        />
152
+      </Spin>
81 153
     </div>
82 154
   ) : (
83 155
     <div dangerouslySetInnerHTML={{ __html: value }}></div>

+ 15
- 0
src/components/Wangeditor/plugins/image/imageToHtmlConf.js 查看文件

@@ -0,0 +1,15 @@
1
+
2
+const imageToHtmlConf = {
3
+  type: 'image',
4
+  elemToHtml: function(elemNode, childrenHtml) {
5
+    const { src, alt = '', href = '', style = {} } = elemNode;
6
+    const { width = '', height = '' } = style;
7
+
8
+    let styleStr = ''
9
+    if (width) styleStr += `width: ${width};`
10
+    if (height) styleStr += `height: ${height};`
11
+    return `<img class="rich-img" src="${src}" alt="${alt}" data-href="${href}" style="${styleStr}"/>`
12
+  },
13
+}
14
+
15
+export default imageToHtmlConf;

+ 27
- 0
src/components/Wangeditor/plugins/video/videoToHtmlConf.js 查看文件

@@ -0,0 +1,27 @@
1
+
2
+// 这段代码是从 官方源码 拷贝过来的
3
+// 但是去掉了 iframe 的支持
4
+// https://github.com/wangeditor-team/wangEditor/blob/f35d8a73a0a3dc159134d483afc5963d0256ea18/packages/video-module/src/module/elem-to-html.ts
5
+const videoToHtmlConf = {
6
+  type: 'video',
7
+  elemToHtml: function(elemNode, childrenHtml) {
8
+    const { src = '', poster = '', width = 'auto', height = 'auto' } = elemNode;
9
+
10
+    // 不能按照下方的格式写, 会带入 回车符
11
+    // const videoHtml = `
12
+    //   <div data-w-e-type="video" data-w-e-is-void>
13
+    //     <video src="${src}" poster="${poster}" controls="true" width="${width}" height="${height}"></video>
14
+    //   </div>
15
+    // `
16
+
17
+    const videoHtml = [
18
+      `<div data-w-e-type="video" data-w-e-is-void>`,
19
+      `<video src="${src}" poster="${poster}" controls="true" width="${width}" height="${height}"></video>`,
20
+      `</div>`
21
+    ].join('');
22
+  
23
+    return videoHtml;
24
+  }
25
+}
26
+
27
+export default videoToHtmlConf;

+ 47
- 0
src/components/Wangeditor/util.js 查看文件

@@ -0,0 +1,47 @@
1
+import { upload } from '@/services/comm';
2
+
3
+export const customUploadImage = async (file, insertFn) => {
4
+  const formData = new FormData();
5
+  formData.append("file", file);
6
+  formData.append("type", file.type);
7
+
8
+  const res = await upload(file);
9
+  // console.log('----------内部--res->', res);
10
+  insertFn(`${prefix}` + res.attachUrl, '', res.href)
11
+}
12
+
13
+export const customUploadVideo = async (file, insertFn) => {
14
+  const formData = new FormData();
15
+  formData.append("file", file);
16
+  formData.append("type", file.type);
17
+
18
+  const res = await upload(file);
19
+  insertFn(`${prefix}` + res.attachUrl)
20
+}
21
+
22
+
23
+export const customBrowseAndUploadVideo = (setLoading) => (insertFn) => {
24
+  const input = document.createElement('input');
25
+  input.type = "file";
26
+  input.accept = ".mp4,.m4v";
27
+  input.onchange = () => {
28
+    const files = input.files;
29
+    if (!files || files.length < 1) return;
30
+
31
+    const file = files[0];
32
+
33
+    const formData = new FormData();
34
+    // console.log(file)
35
+    formData.append("file", file);
36
+    formData.append("type", file.type);
37
+
38
+    setLoading(true)
39
+    upload(file).then(res => {
40
+      insertFn(`${prefix}` + res.attachUrl)
41
+    }).finally(() => {
42
+      setLoading(false);
43
+    });
44
+  }
45
+
46
+  input.click();
47
+}

+ 1
- 1
src/layouts/AuthLayout/Main.jsx 查看文件

@@ -14,7 +14,7 @@ export default (props) => {
14 14
   const { user, menus } = useModel('user')
15 15
   const navigate = useNavigate()
16 16
   const location = useLocation()
17
-  console.log('menus', menus)
17
+  // console.log('menus', menus)
18 18
   return (
19 19
     <Layout className={theme} style={{ height: '100vh' }}>
20 20
       <Header theme={theme} user={user} />

+ 22
- 4
src/pages/article/Edit.jsx 查看文件

@@ -1,4 +1,4 @@
1
-import React, { useRef, useState } from 'react'
1
+import React, { useRef, useState, useEffect } from 'react'
2 2
 import { Button, Input, Form, Select } from 'antd'
3 3
 import Edit from '@/components/Page/Edit'
4 4
 import Wangeditor from '@/components/Wangeditor'
@@ -7,6 +7,7 @@ import UploadImages from '@/components/Upload/UploadImages'
7 7
 import UploadImageList from '@/components/Upload/UploadImageList'
8 8
 import { previewFile, downladFile } from '@/utils/attach';
9 9
 import { getTaPostById, postTaPost, putTaPost } from "@/services/taPost";
10
+import { getTdCategory } from "@/services/tdCategory";
10 11
 
11 12
 const request = {
12 13
   get: getTaPostById,
@@ -15,10 +16,17 @@ const request = {
15 16
 }
16 17
 
17 18
 export default (props) => {
19
+  const [options, setOptions] = useState([])
18 20
 
19 21
   const transform = (_, item) => {
20 22
     let images = item?.images ? JSON.stringify(item?.images) : null
21
-    let taAttachList = item?.taAttachList ? item?.taAttachList : []
23
+
24
+    // let destTaAttachList = 
25
+
26
+    let taAttachList = item?.taAttachList ? item?.taAttachList.map(item => {
27
+      const { createdBy, createdTime, updatedBy, updatedTime, ...rest } = item;
28
+      return rest;
29
+    }) : null
22 30
     let tags = item?.tags ? JSON.stringify(item?.tags) : null
23 31
     let data = { ...item, images: images, taAttachList: taAttachList, tags: tags }
24 32
     return data
@@ -30,6 +38,13 @@ export default (props) => {
30 38
     return { ...formData, tags: tags, images: images }
31 39
   }
32 40
 
41
+  useEffect(() => {
42
+    getTdCategory().then((res) => {
43
+      let data = res?.records.map(x => ({ label: x.categoryName, value: x.categoryId }))
44
+      setOptions(data)
45
+    })
46
+  }, [])
47
+
33 48
   return (
34 49
     <Edit
35 50
       rowKey="postId"
@@ -52,15 +67,18 @@ export default (props) => {
52 67
             <UploadImageList />
53 68
           </Form.Item>
54 69
           <Form.Item label="横向封面" name="coverHorizontal">
55
-            <UploadImages ratio={0.5} />
70
+            <UploadImages />
56 71
           </Form.Item>
57 72
           <Form.Item label="纵向封面" name="coverVertical">
58 73
             <UploadImages ratio={'100:200'} />
59 74
           </Form.Item>
60
-
75
+          <Form.Item label="文章分类" name="categoryId" required>
76
+            <Select options={options} placeholder="请输入" />
77
+          </Form.Item>
61 78
           <Form.Item label="文章标签" name="tags">
62 79
             <Select mode="tags" tokenSeparators={[',']} placeholder="请输入" />
63 80
           </Form.Item>
81
+
64 82
           <Form.Item label="文章作者" name="author">
65 83
             <Input placeholder="请输入" />
66 84
           </Form.Item>

+ 92
- 22
src/pages/article/index.jsx 查看文件

@@ -1,40 +1,66 @@
1
-import React, { useRef, useState } from 'react'
1
+import React, { useRef, useState, useEffect } from 'react'
2 2
 import List from '@/components/Page/List'
3
-import { Button, Tag, Image } from 'antd'
3
+import { Button, Tag, Image, Typography, Popconfirm } from 'antd'
4 4
 import { useNavigate } from 'react-router-dom'
5
-import { getTaPost, deleteTaPost } from "@/services/taPost";
5
+import dayjs from 'dayjs';
6
+import { queryDict } from "@/utils/request";
7
+import { getTaPost, deleteTaPost, putTaPost } from "@/services/taPost";
8
+import { getTdCategory } from "@/services/tdCategory";
9
+
10
+const { Text } = Typography;
11
+
12
+const queryCategory = queryDict(getTdCategory, { labelKey: "categoryName", valueKey: "categoryId" })
6 13
 
7 14
 export default (props) => {
15
+  const [categoryList, setCategoryList] = useState()
8 16
   const actionRef = useRef();
9 17
   const navigate = useNavigate();
10 18
 
11 19
   const columns = [
20
+    {
21
+      title: "创建时间",
22
+      dataIndex: "createdTime",
23
+      valueType: "dateRange",
24
+      render: (_, it) => it.createdTime?.replace("T", " ").replace(/\d+\:\d+\:\d+/, ""),
25
+      hideInTable: true,
26
+      search: {
27
+        transform: (val) => {
28
+          return {
29
+            startDate: val[0],
30
+            endDate: val[1],
31
+          };
32
+        },
33
+      }
34
+    },
12 35
     {
13 36
       title: '标题',
14 37
       dataIndex: 'title',
15
-      ellipsis: true,
38
+      render: (_, it) => <Text key="title" ellipsis={true}>{it?.title}</Text>,
16 39
     },
17 40
     {
18 41
       title: '描述',
19 42
       dataIndex: 'describe',
20
-      ellipsis: true,
43
+      render: (_, it) => <Text key="describe" ellipsis={true}>{it?.describe}</Text>,
21 44
       search: false,
22 45
     },
23 46
     {
24 47
       title: '正文',
25 48
       dataIndex: 'content',
26
-      render: (_, it) =>
27
-        <div style={{ width: '9vw' }}>
28
-          <div dangerouslySetInnerHTML={{ __html: it?.content }} style={{ textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap' }} />
29
-        </div>,
49
+      render: (_, it) => <Text key="content" style={{ width: 200 }} ellipsis={true}>{it?.content?.replace(/<[^>]+>/g, '')}</Text>,
30 50
       search: false,
31 51
     },
32 52
     {
33 53
       title: '图片',
34 54
       dataIndex: 'images',
35
-      render: (_, it) => it?.images ? <Image src={`${prefix}` + JSON.parse(it?.images)[0]} width={80} /> : null,
55
+      render: (_, it) => it?.images ? <Text key="images" style={{ width: 100 }} ellipsis={true}><Image src={`${prefix}` + JSON.parse(it?.images)[0]} height={60} /></Text> : null,
36 56
       search: false,
37 57
     },
58
+    {
59
+      title: '分类',
60
+      dataIndex: 'categoryId',
61
+      valueType: 'select',
62
+      request: queryCategory
63
+    },
38 64
     // {
39 65
     //   title: '横向封面',
40 66
     //   dataIndex: 'coverHorizontal',
@@ -51,27 +77,34 @@ export default (props) => {
51 77
       title: '标签',
52 78
       dataIndex: 'tags',
53 79
       search: false,
54
-      render: (_, it) => it?.tags ? JSON.parse(it?.tags).map(it => <Tag color="red">{it}</Tag>) : null
80
+      render: (_, it) => it?.tags ? <Text key="tags" style={{ width: 140 }} ellipsis={true}>{JSON.parse(it?.tags).map(it => <Tag color="processing">{it}</Tag>)}</Text> : null
55 81
     },
56 82
     {
57 83
       title: '作者',
58
-      dataIndex: 'author'
84
+      dataIndex: 'author',
85
+      render: (_, it) => <Text key="author" style={{ width: 100 }} ellipsis={true}>{it?.author}</Text>,
59 86
     },
60 87
     {
61 88
       title: '链接',
62 89
       dataIndex: 'link',
63
-      ellipsis: true,
64
-      render: (_, it) =>
65
-        <div style={{ width: '8vw' }}>
66
-          <div style={{ textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap' }}><a href="#">{it?.link}</a></div>
67
-        </div>,
90
+      render: (_, it) => <Text key="link" style={{ width: 100 }} ellipsis={true}><a href={it?.link} target="_bank">{it?.link}</a></Text>,
68 91
       search: false,
69 92
     },
70
-    // {
71
-    //   title: '附件',
72
-    //   dataIndex: 'attachment',
73
-    //   search: false,
74
-    // }
93
+    {
94
+      title: '状态',
95
+      dataIndex: 'status',
96
+      valueEnum: {
97
+        0: '未发布',
98
+        1: '发布'
99
+      },
100
+      search: false,
101
+    },
102
+    {
103
+      title: '创建时间',
104
+      dataIndex: 'createdTime',
105
+      render: (_, it) => dayjs(it?.createdTime).format('YYYY-MM-DD HH:mm'),
106
+      search: false,
107
+    }
75 108
   ]
76 109
 
77 110
   const onEdit = (it) => {
@@ -83,11 +116,32 @@ export default (props) => {
83 116
       actionRef.current.reload();
84 117
     })
85 118
   }
119
+  useEffect(() => {
120
+    getTdCategory().then((res) => {
121
+      let data = res?.records.map(x => ({ categoryName: x.categoryName, categoryId: x.categoryId }))
122
+      setCategoryList(data)
123
+    })
124
+  }, [])
86 125
 
87 126
   const onDetail = (it) => {
88 127
     navigate(`/article/detail?id=${it.postId}`)
89 128
   }
90 129
 
130
+  const onRelease = (item) => {
131
+    let status = item.status === 1 ? 0 : 1
132
+    let id = item.postId
133
+    let cName = categoryList.find(item => item.categoryId === item?.categoryId)
134
+    let data = [item].map(item => {
135
+      const { createdTime, updatedTime, ...rest } = item
136
+      return { ...rest, status: status, categoryName: cName.categoryName }
137
+    })
138
+
139
+    // console.log('--------categoryList------------->', categoryList);
140
+    putTaPost(id, data[0]).then(res => {
141
+      actionRef.current?.reload()
142
+    })
143
+  }
144
+
91 145
   return (
92 146
     <List
93 147
       rowKey="postId"
@@ -108,6 +162,22 @@ export default (props) => {
108 162
           新增
109 163
         </Button>
110 164
       ]}
165
+      columnOptionRender={(item) => [
166
+        <Popconfirm
167
+          key="release"
168
+          title={item?.status === 0 ? '确定要发布吗?' : '确定要取消发布吗?'}
169
+          onConfirm={() => onRelease(item)}
170
+          okText="确定"
171
+          cancelText="取消"
172
+        >
173
+          <Button
174
+            key="3"
175
+            type="link"
176
+          >
177
+            状态
178
+          </Button>
179
+        </Popconfirm>
180
+      ]}
111 181
     />
112 182
   )
113 183
 }

+ 10
- 0
src/services/comm.js 查看文件

@@ -0,0 +1,10 @@
1
+import request from "@/utils/request";
2
+
3
+export const upload = file => {
4
+  // let deFile = { file: file, fileType: file.type }
5
+  // console.log('----------小方------>', deFile);
6
+  const formData = new FormData();
7
+  formData.append("file", file);
8
+  formData.append("fileType", file.type);
9
+  return request(uploadAPI, { method: "POST", data: formData });
10
+};

+ 3
- 2
src/utils/request.js 查看文件

@@ -80,7 +80,7 @@ instance.interceptors.response.use(
80 80
         message.error("未登录或者超时, 请重新登录");
81 81
       }
82 82
     } else {
83
-      console.log(config);
83
+      // console.log(config);
84 84
       if (!config.silent) {
85 85
         const errMsg = data.msg || "系统错误";
86 86
         message.error(errMsg.indexOf("exception") > -1 ? "服务异常" : errMsg);
@@ -93,7 +93,7 @@ instance.interceptors.response.use(
93 93
     // 超出 2xx 范围的状态码都会触发该函数。
94 94
     // 对响应错误做点什么
95 95
 
96
-    console.error(error);
96
+    // console.error(error);
97 97
 
98 98
     return Promise.reject("网络异常, 请重试...");
99 99
   }
@@ -136,6 +136,7 @@ export function queryDict (
136 136
       ...(leftParams || {}),
137 137
     })
138 138
       .then((res) => {
139
+        // console.log('----------------res?.records----->', res?.records);
139 140
         return res?.records?.map((x) => ({
140 141
           label: x[labelKey],
141 142
           value: x[valueKey],

+ 2357
- 2456
yarn.lock
文件差异内容过多而无法显示
查看文件