news-pubish-management(5)--audit business

The audit list should be showing date the user ownself, audiState should not equals to 0 and publishState should less than 1.

1. Get back data in AuditList.js

copy from RightList.js and mofify as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { Button, Table, Tag } from 'antd';

import axios from 'axios';
import React, { useEffect, useState } from 'react'

export default function AuditList() {
const { username } = JSON.parse(localStorage.getItem('token'));

const [dataSource, setDataSource] = useState([]);

const columns = [
{
title: '新闻标题',
dataIndex: 'title',
render: (title, item) => {
return <a href={`#/news-manage/preview/${item.id}`}>{title}</a>
}
},
{
title: '新闻分类',
dataIndex: 'category',
render: category => {
return category.title
}
},
{
title: '作者',
dataIndex: 'author',
},
{
title: '审核状态',
dataIndex: 'auditState',
render: auditState => {
const colorList = ['', 'orange', 'green', 'red'];
const auditList = ['未审核', '审核中', '已通过', '未通过'];
return <Tag color={colorList[auditState]}>{auditList[auditState]}</Tag>
}
},
{
title: '操作',
render: item => {
return <div>
{
item.auditState === 1 && <Button danger>撤销</Button>
}
{
item.auditState === 2 && <Button>发布</Button>
}
{
item.auditState === 3 && <Button type='primary'>更新</Button>
}
</div>
}
},
];

useEffect(() => {
axios.get(`/api/news?_expand=category&author=${username}&auditState_ne=0&publishState_lte=1`).then(res => {
// console.log(res.data);
setDataSource(res.data);
})
}, [username]);

return (
<div>
<Table dataSource={dataSource} columns={columns} pagination={{ pageSize: 5 }} rowKey={item => item.id} />;
</div>
)
}

1
const auditList = ['未审核', '审核中', '已通过', '未通过'];

you wan to revert from audit. it is easy, change the auditState from 2 to 0.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const navigate = useNavigate();

const handleRevert = item => {
setDataSource(dataSource.filter(data=>data.id!==item.id));

axios.patch(`/api/news/${item.id}`, {
auditStats: 0
}).then(res=>{
navigate('/news-manage/draft');
notification.info({
message: `Notification`,
description:
`Please go to draft box for reviewing your news`,
placement: 'bottomRight',
});
})
}

update is easy, useNavigate to NewsUpdate.

1
2
3
const handleUpdate = item => {
navigate(`/news-manage/update/${item.id}`);
}

publish news, change the publishState from 1 to 2

1
2
3
4
5
6
7
8
9
10
11
12
13
const handlePublish = item => {
axios.patch(`/api/news/${item.id}`, {
publishStats: 2
}).then(res => {
navigate('/publish-manage/published');
notification.info({
message: `Notification`,
description:
`Please go to published box for reviewing your news`,
placement: 'bottomRight',
});
})
}

2. Audit news

copy from AuditList.js and modify as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { Table, Button } from 'antd';
import axios from 'axios';
import React, { useEffect, useState } from 'react'
import { useNavigate } from 'react-router'

export default function Audit() {
const [dataSource, setDataSource] = useState([])

const navigate = useNavigate();

const { roleId, region, username } = JSON.parse(localStorage.getItem('token'));

const columns = [
{
title: '新闻标题',
dataIndex: 'title',
render: (title, item) => {
return <a href={`#/news-manage/preview/${item.id}`}>{title}</a>
}
},
{
title: '新闻分类',
dataIndex: 'category',
render: category => {
return category.title
}
},
{
title: '作者',
dataIndex: 'author',
},
{
title: '操作',
render: item => {
return <div>
<Button type='primary'>通过</Button>
<Button >驳回</Button>
</div>
}
},
];

useEffect(() => {
const roleObj = {
"1": "superadmin",
"2": "admin",
"3": "editor",
}

axios.get(`/api/news?auditState=1&_expand=category`).then(res => {
console.log(res.data);
const list = res.data;
setDataSource(roleObj[roleId] === 'superadmin' ? list : [
...list.filter(item => item.username === username),
...list.filter(item => item.region === region && roleObj[item.roleId] === 'editor')
]);
});
}, [roleId, region, username]);

return (
<div>
<Table dataSource={dataSource} columns={columns} pagination={{ pageSize: 5 }} rowKey={item => item.id} />;
</div>
)
}

Audit & Reject
audit change the auditState from 1 to 2, publishState change to 1,
reject change the auditState from 1 to 3, publishState change to 0

1
2
3
4
5
6
7
8
9
10
const handleAudit = (item, auditState, publishState) => {
setDataSource(dataSource.filter(data => data.id !== item.id));

axios.patch(`/api/news/${item.id}`, {
auditState,
publishState
}).then(res=>{

})
}

3. Add NewsCategory

copy RightList.js and modify it as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { Button, Table, Modal } from 'antd';
import {
DeleteOutlined,
ExclamationCircleOutlined,
} from '@ant-design/icons';

import axios from 'axios';
import React, { useEffect, useState } from 'react'

const { confirm } = Modal;

export default function NewsCategory() {
const [dataSource, setDataSource] = useState([]);
const columns = [
{
title: 'ID',
dataIndex: 'id',
render: (id) => <b>{id}</b>
},
{
title: '分类名称',
dataIndex: 'title',
},
{
title: '操作',
render: item => {
return <div>
<Button danger shape='circle' icon={<DeleteOutlined />} onClick={() => confirmDelete(item)} />
</div>
}
},
];

const confirmDelete = item => {
confirm({
title: 'Do you Want to delete this item?',
icon: <ExclamationCircleOutlined />,
onOk() {
// console.log('OK');
realDelete(item)
},
onCancel() {
console.log('Cancel');
},
});
}

const realDelete = (item) => {
// console.log(item);
setDataSource(dataSource.filter(data => data.id !== item.id));
axios.delete(`/api/categories/${item.id}`);
}

useEffect(() => {
axios.get(`/api/categories`).then(res => {
// console.log(res.data);
setDataSource(res.data);
})
}, []);

return (
<div>
<Table dataSource={dataSource} columns={columns} pagination={{ pageSize: 5 }} rowKey={item => item.id} />;
</div>
)
}

use table Table EditCell for editing title

add components proeprty in Table, the components nees EditableRow and EditableCell, it is complex to read this document but need careful, at the end the NewsCategory should be looks like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import { Button, Table, Modal, Form, Input } from 'antd';
import {
DeleteOutlined,
ExclamationCircleOutlined,
} from '@ant-design/icons';

import axios from 'axios';
import React, { useContext, useState, useEffect, useRef } from 'react'

const { confirm } = Modal;

export default function NewsCategory() {
const [dataSource, setDataSource] = useState([]);

const EditableContext = React.createContext(null);

const columns = [
{
title: 'ID',
dataIndex: 'id',
render: (id) => <b>{id}</b>
},
{
title: '分类名称',
dataIndex: 'title',
onCell: (record) => ({
record,
editable: true,
dataIndex: 'title',
title: '分类名称',
handleSave: handleCellSave,
}),
},
{
title: '操作',
render: item => {
return <div>
<Button danger shape='circle' icon={<DeleteOutlined />} onClick={() => confirmDelete(item)} />
</div>
}
},
];

const handleCellSave = record => {
// console.log(record);
setDataSource(dataSource.map(item => {
if (item.id === record.id) {
return {
id: item.id,
title: record.title,
value: record.title,
}
}
return item;
}))

axios.patch(`/api/categories/${record.id}`, {
title: record.title,
value: record.title,
})
}

const confirmDelete = item => {
confirm({
title: 'Do you Want to delete this item?',
icon: <ExclamationCircleOutlined />,
onOk() {
// console.log('OK');
realDelete(item)
},
onCancel() {
console.log('Cancel');
},
});
}

const realDelete = (item) => {
// console.log(item);
setDataSource(dataSource.filter(data => data.id !== item.id));
axios.delete(`/api/categories/${item.id}`);
}

useEffect(() => {
axios.get(`/api/categories`).then(res => {
// console.log(res.data);
setDataSource(res.data);
})
}, []);

const EditableRow = ({ index, ...props }) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};

const EditableCell = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef(null);
const form = useContext(EditableContext);
useEffect(() => {
if (editing) {
inputRef.current.focus();
}
}, [editing]);

const toggleEdit = () => {
setEditing(!editing);
form.setFieldsValue({
[dataIndex]: record[dataIndex],
});
};

const save = async () => {
try {
const values = await form.validateFields();
toggleEdit();
handleSave({ ...record, ...values });
} catch (errInfo) {
console.log('Save failed:', errInfo);
}
};

let childNode = children;

if (editable) {
childNode = editing ? (
<Form.Item
style={{
margin: 0,
}}
name={dataIndex}
rules={[
{
required: true,
message: `${title} is required.`,
},
]}
>
<Input ref={inputRef} onPressEnter={save} onBlur={save} />
</Form.Item>
) : (
<div
className="editable-cell-value-wrap"
style={{
paddingRight: 24,
}}
onClick={toggleEdit}
>
{children}
</div>
);
}

return <td {...restProps}>{childNode}</td>;
};

return (
<div>
<Table dataSource={dataSource} columns={columns} pagination={{ pageSize: 5 }} rowKey={item => item.id} components={{
body: {
row: EditableRow,
cell: EditableCell,
},
}} />;
</div>
)
}