Skip to content

Commit ac2ecb2

Browse files
committed
feat & fix: fix admin search button has no response issue, add manager for fragment
Signed-off-by: panyunyi97 <cuferpan@gmail.com>
1 parent d28beaf commit ac2ecb2

File tree

10 files changed

+176
-30
lines changed

10 files changed

+176
-30
lines changed

package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@
8080
"webpack-dev-server": "3.2.1",
8181
"webpack-manifest-plugin": "2.0.4",
8282
"workbox-webpack-plugin": "4.3.1",
83-
"xss": "^1.0.6"
83+
"xss": "^1.0.6",
84+
"yarn": "^1.22.17"
8485
},
8586
"scripts": {
8687
"start": "node scripts/start.js",

server/controllers/fragment.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,21 @@ class FragmentController {
2626
ctx.body = data
2727
}
2828
}
29+
30+
static async deleteFragment(ctx) {
31+
const validator = ctx.validate(ctx.request.body, {
32+
id: Joi.string()
33+
})
34+
if (validator) {
35+
const fragmentId = ctx.params.id
36+
await sequelize.query(
37+
`delete *
38+
from fragment
39+
where article.id=${fragmentId}`
40+
)
41+
ctx.status = 204
42+
}
43+
}
2944
}
3045

3146
module.exports = FragmentController

server/middlewares/authHandler.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const { checkToken } = require('../utils/token')
77
const verifyList1 = [
88
{ regexp: /\/article\/output/, required: 'get', verifyTokenBy: 'url' }, // 导出文章 verifyTokenBy 从哪里验证 token
99
{ regexp: /\/article/, required: 'post, put, delete' }, // 普通用户 禁止修改或者删除、添加文章
10+
{ regexp: /\/fragment/, required: 'post, put, delete' }, // 普通用户 禁止修改或者删除、添加文章
1011
{ regexp: /\/discuss/, required: 'delete, post' }, // 普通用户 禁止删除评论
1112
{ regexp: /\/user/, required: 'put, delete' } // 普通用户 禁止获取用户、修改用户、以及删除用户
1213
]

server/router/fragment.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ const router = new Router({prefix: '/fragment'})
33
const {fetchFragmentList, create} = require('../controllers/fragment')
44

55
router
6-
.get('/', fetchFragmentList) // 创建评论或者回复 articleId 文章 id
6+
.get('/list', fetchFragmentList) // 创建评论或者回复 articleId 文章 id
77
.post('/create', create)
8+
.delete('/:id', deleteFragment) // 删除指定文章
89
// .delete('/comment/:commentId', deleteComment) // 删除一级评论
910
// .delete('/reply/:replyId', deleteReply) // 删除回复
1011

src/routes/admin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export default {
1212
{ path: 'article/manager', component: lazy(() => import('@/views/admin/article/manager')) },
1313
{ path: 'article/graph', component: lazy(() => import('@/views/admin/article/graph')) },
1414
{ path: 'fragment/add', component: lazy(() => import('@/views/admin/fragment/edit')) },
15+
{ path: 'fragment/manager', component: lazy(() => import('@/views/admin/fragment/manager')) },
1516
{ path: 'user', component: lazy(() => import('@/views/admin/user')) },
1617
{ path: 'monitor', component: lazy(() => import('@/views/admin/monitor')) },
1718
],

src/views/admin/article/manager/index.jsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { Component, useState, useEffect } from 'react'
22
import { connect, useSelector, useDispatch } from 'react-redux'
3-
import { Table, Tag, Switch, message, Input, Button, Popconfirm, Select, Form} from 'antd'
3+
import { Table, Tag, Switch, message, Input, Button, Popconfirm, Select, Form } from 'antd'
44

55
import axios from '@/utils/axios'
66

@@ -138,14 +138,13 @@ function ArticleManager(props) {
138138
})
139139
}
140140

141-
function handleSubmit(e) {
142-
e.preventDefault()
143-
props.form.validateFields((err, values) => {
144-
if (!err) {
145-
setQueryParams({ ...queryParams, ...values })
146-
onSearch({ ...queryParams, ...values })
147-
}
148-
})
141+
const handleSubmit = values => {
142+
try {
143+
setQueryParams({ ...queryParams, ...values })
144+
onSearch({ ...queryParams, ...values })
145+
} catch (errorInfo) {
146+
console.log('Failed:', errorInfo)
147+
}
149148
}
150149

151150
const rowSelection = batch ? {
@@ -156,7 +155,7 @@ function ArticleManager(props) {
156155
return (
157156
<div className='admin-article-manager'>
158157
{/* 检索 */}
159-
<Form layout='inline' onSubmit={handleSubmit} style={{ marginBottom: 20 }}>
158+
<Form layout='inline' onFinish={handleSubmit} style={{ marginBottom: 20 }}>
160159
<Form.Item label='关键词' name='keyword'>
161160
<Input placeholder='请输入文章关键词' allowClear />
162161
</Form.Item>
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import React, { Component, useState, useEffect } from 'react'
2+
import { connect, useSelector, useDispatch } from 'react-redux'
3+
import { Table, Tag, Switch, message, Input, Button, Popconfirm, Select, Form } from 'antd'
4+
5+
import axios from '@/utils/axios'
6+
7+
import { Link } from 'react-router-dom'
8+
import dayjs from '@/utils/dayjs'
9+
import download from '@/utils/download'
10+
11+
import useAntdTable from '@/hooks/useAntdTable'
12+
13+
import useBreadcrumb from '@/hooks/useBreadcrumb'
14+
15+
function FragmentManager(props) {
16+
useBreadcrumb(['碎语管理'])
17+
18+
const [queryParams, setQueryParams] = useState({})
19+
const [batch, setBatch] = useState(false)
20+
const [selectedRowKeys, setSelectedRowKeys] = useState([])
21+
const { tableProps, updateList, onSearch } = useAntdTable({
22+
requestUrl: '/fragment/list',
23+
queryParams,
24+
columns: [
25+
{
26+
title: '编号',
27+
dataIndex: 'id',
28+
},
29+
{
30+
title: '作者',
31+
dataIndex: 'author',
32+
},
33+
34+
{
35+
title: '发布时间',
36+
dataIndex: 'createdAt',
37+
sorter: (a, b) => (dayjs(a.createdAt).isBefore(b.createdAt) ? 1 : -1),
38+
},
39+
{
40+
dataIndex: 'id',
41+
title: '操作',
42+
render: (articleId, record) => {
43+
return (
44+
<ul className='action-list'>
45+
<li>
46+
<Link to={`/fragment/${articleId}`}>查看</Link>
47+
</li>
48+
<li>
49+
<Link to={{ pathname: `/admin/fragment/edit/${record.id}`, state: { articleId } }}>编辑</Link>
50+
</li>
51+
<li>
52+
<Popconfirm
53+
title='Are you sure?'
54+
cancelText='No'
55+
onConfirm={e => updateList(() => axios.delete(`/fragment/${articleId}`))}>
56+
<a className='delete-text'>删除</a>
57+
</Popconfirm>
58+
</li>
59+
</ul>
60+
)
61+
},
62+
},
63+
],
64+
})
65+
66+
function delList() {
67+
axios.delete(`/fragment/list/${selectedRowKeys}`).then(() => {
68+
onSearch()
69+
setSelectedRowKeys([])
70+
})
71+
}
72+
73+
const handleSubmit = values => {
74+
try {
75+
setQueryParams({ ...queryParams, ...values })
76+
onSearch({ ...queryParams, ...values })
77+
} catch (errorInfo) {
78+
console.log('Failed:', errorInfo)
79+
}
80+
}
81+
82+
const rowSelection = batch ? {
83+
selectedRowKeys,
84+
onChange: selectList => setSelectedRowKeys(selectList),
85+
} : null
86+
87+
return (
88+
<div className='admin-fragment-manager'>
89+
{/* 检索 */}
90+
<Form layout='inline' onFinish={handleSubmit} style={{ marginBottom: 20 }}>
91+
<Form.Item label='关键词' name='keyword'>
92+
<Input placeholder='请输入碎语关键词' allowClear />
93+
</Form.Item>
94+
<Form.Item>
95+
<Button type='primary' htmlType='submit' style={{ marginRight: 8 }}>
96+
检索
97+
</Button>
98+
</Form.Item>
99+
</Form>
100+
101+
<Table
102+
{...tableProps}
103+
rowSelection={rowSelection}
104+
footer={() => (
105+
<>
106+
批量操作 <Switch checked={batch} onChange={e => setBatch(prev => !prev)} style={{ marginRight: 8 }} />
107+
{batch && (
108+
<>
109+
<Popconfirm
110+
title='Are you sure delete the fragments?'
111+
onConfirm={delList}
112+
// onCancel={cancel}
113+
okText='Yes'
114+
cancelText='No'>
115+
<Button type='danger' size='small' disabled={selectedRowKeys.length === 0}>
116+
批量删除
117+
</Button>
118+
</Popconfirm>
119+
</>
120+
)}
121+
</>
122+
)}
123+
/>
124+
</div>
125+
)
126+
}
127+
128+
export default FragmentManager

src/views/web/fragments/index.jsx

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,6 @@ function FragmentList(props) {
7979
</div>
8080
</div>
8181
</List.Item>
82-
// <List.Item>
83-
// <Card
84-
// style={{ width: 300 }}
85-
// // cover={
86-
// // <img
87-
// // alt='随机图片'
88-
// // src={'https://picsum.photos/id/' + getRandomInt(100) + '/300/400'}
89-
// // />
90-
// // }
91-
// >
92-
// <Meta
93-
// title={dayjs(item.createdAt, 'YYYYMMDD').fromNow()}
94-
// avatar={<Avatar src='http://127.0.0.1/static/media/avatar.7e58ba1b.jpeg' />}
95-
// description={item.content}
96-
// // datetime={moment('2020-12-06T04:00:00.000Z').format('MMMM Do YYYY, h:mm:ss a')}
97-
// />
98-
// </Card>
99-
// </List.Item>
10082
)}
10183
/>
10284
</div>

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12996,6 +12996,11 @@ yargs@^13.3.0, yargs@^13.3.2:
1299612996
y18n "^4.0.0"
1299712997
yargs-parser "^13.1.2"
1299812998

12999+
yarn@^1.22.17:
13000+
version "1.22.17"
13001+
resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.17.tgz#bf910747d22497b573131f7341c0e1d15c74036c"
13002+
integrity sha512-H0p241BXaH0UN9IeH//RT82tl5PfNraVpSpEoW+ET7lmopNC61eZ+A+IDvU8FM6Go5vx162SncDL8J1ZjRBriQ==
13003+
1299913004
yeast@0.1.2:
1300013005
version "0.1.2"
1300113006
resolved "https://registry.npm.taobao.org/yeast/download/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"

0 commit comments

Comments
 (0)