现有的剧本编写系统中,全部剧本列表页,是可以正常显示全部的剧本的列表的:
但是显示的数据不对,应该改为:超级用户权限的,所有的用户的剧本的列表。
并且,支持从别处传入的参数去过滤,比如点击某个用户:

虽然显示列出了对应数据

但是作者的下拉框中,不是所有的成员
以及不支持传入:
group的id:
某个用户的是否已发布:
现在去优化,支持这些操作。
期间,为了能获取当前所有用户的列表,而且所有的用户,都应属属于某个script的funciton group的,所以找了找代码,发现可以借用已有的functionGroup/fetch去获取到所有的group的列表
但是每个group中,没有包含members,所以打算去加上members,所以先去解决:
【已解决】Django中序列化一个模型对象中的另外子对象的数组
此时即可得到带members的script的function group了。
然后就可以去过滤得到所有的组员了
所以此处页面上还要添加剧本组和剧本成员列表:
【已解决】全部剧本列表中添加剧本组和组成员列表
其中涉及到,先去给返回的script的数据中,加上能有当前已加入的剧本组的信息:
【已解决】Django的Serializer中如何序列化Script中的Author的Function Group
和:
【已解决】js中判断变量类型是否是字符串还是int
然后再去想办法支持前端传递的各种参数
- 传入group_id时,返回整个script的group的members的剧本列表
- 传入author_id时,返回单个用户的剧本列表
- 传入group_id+author_id时,自己确保author是属于此group的,所以忽略group_id,等价于:只传入author_id
然后先去解决:
【已解决】Django中如何查询一个对象包含于一个列表内均可
然后就可以继续优化代码了。
【已解决】Reactjs警告:[eslint] Expected ‘this’ to be used by class method (class-methods-use-this)
然后再去优化,参数传递进来后,要选择对应的选项:
现在是缺少了审核状态:

然后再去:
【已解决】reactjs中setState如何更新设置dict对象中某个key键的值
【总结】
然后现在可以用代码:
import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
import {
Row,
Col,
Card,
Form,
Input,
Button,
Divider,
Popconfirm,
Tooltip,
Select,
} from 'antd';
import { routerRedux } from 'dva/router';
import SimpleTable from 'components/SimpleTable';
import PageHeaderLayout from '../../layouts/PageHeaderLayout';
import styles from '../List/TableList.less';
import { scriptWordExportUrl } from '../../services/api';
import { getEncodedToken } from '../../utils/token';
import { isEmptyObj } from '../../utils/utils';
const queryString = require('query-string');
const FormItem = Form.Item;
const { Option } = Select;
@connect(({ script, topic, user, functionGroup, loading }) => ({
// @connect(({ script, topic, user, functionGroup }) => ({
script,
topic,
currentUser: user.currentUser,
functionGroup,
loading: loading.models.script,
}))
@Form.create()
export default class GroupOwnerScriptList extends PureComponent {
state = {
formValues: {},
currentPage: 1,
pageSize: 20,
first_level_topic: [],
// second_level_topic: [],
groupMemberList: [],
};
componentWillMount() {
console.log(`GroupOwnerScriptList componentWillMount`)
this.fetchUser = this.fetchUser.bind(this)
this.updateGroupMemberList = this.updateGroupMemberList.bind(this)
this.updateFormFieldAndState = this.updateFormFieldAndState.bind(this)
console.log(`this.props=`, this.props)
const { currentUser} = this.props;
console.log(`currentUser=`, currentUser)
this.fetchTopicList()
const queryParamDict = this.generateQueryParamDict()
this.updateGroupOwnerScriptList(queryParamDict)
}
componentDidMount() {
console.log(`GroupOwnerScriptList componentDidMount`)
const { currentUser} = this.props;
console.log(`currentUser=`, currentUser)
if(isEmptyObj(this.props.currentUser)) {
this.fetchUser(this.updateGroupMemberList)
} else {
this.updateGroupMemberList()
}
}
onSecondOptionChange(topicList, value) {
const { form } = this.props;
form.setFieldsValue({
second_level_topic: value || '',
});
// this.setState({
// second_level_topic: value || '',
// });
}
fetchUser(callback=undefined){
console.log("fetchUser: callback=", callback)
this.props.dispatch({
type: 'user/fetchCurrent',
}).then( () => {
if (callback){
callback()
}
})
}
updateFormFieldAndState(){
console.log("updateFormFieldAndState: this", this)
const queryParamDict = this.generateQueryParamDict()
console.log("queryParamDict=", queryParamDict)
if (queryParamDict.author_id) {
this.props.form.setFieldsValue({
author_id: queryParamDict.author_id,
});
}
if (queryParamDict.publish_status){
this.props.form.setFieldsValue({
publish_status: queryParamDict.publish_status,
})
}
console.log(`updated form getFieldsValue=`, this.props.form.getFieldsValue())
const curFormValues = this.state.formValues
console.log(`curFormValues=`, curFormValues)
if (queryParamDict.publish_status) {
curFormValues.publish_status = queryParamDict.publish_status
}
if (queryParamDict.author_id) {
curFormValues.author_id = queryParamDict.author_id
}
console.log(`updated curFormValues=`, curFormValues)
this.setState({
formValues: curFormValues,
})
}
updateGroupMemberList(){
console.log("updateGroupMemberList: this", this)
const { currentUser} = this.props;
console.log(`currentUser=`, currentUser)
let curFunctionGroup = {}
if (currentUser &&
currentUser.functionGroup &&
currentUser.functionGroup.scriptGroup &&
currentUser.functionGroup.scriptGroup.joinedGroup) {
curFunctionGroup = currentUser.functionGroup.scriptGroup.joinedGroup
console.log(`curFunctionGroup=`, curFunctionGroup)
const curGroupMemberList = curFunctionGroup.members
console.log(`curGroupMemberList=`, curGroupMemberList)
this.setState({
groupMemberList: curGroupMemberList,
})
this.updateFormFieldAndState()
}
// if (curFunctionGroup) {
// const functionGroupID = curFunctionGroup.id;
// if (functionGroupID) {
// this.props.dispatch({
// type: 'functionGroup/fetchFunctionGroupAndMembers',
// payload: functionGroupID,
// }).then((respGroupAndMembers) => {
// console.log(`fetchFunctionGroupAndMembers response`)
// console.log(`respGroupAndMembers=`, respGroupAndMembers)
// console.log(`this.props=`, this.props)
// const { functionGroup: { functionGroup, members } } = this.props;
// // const { functionGroup, members } = this.props;
// console.log(`functionGroup=`, functionGroup)
// console.log(`members=`, members)
// if (members) {
// const membersList = members.results
// console.log(`membersList=`, membersList)
// console.log(`before setFieldsValue authorId=`, authorId)
// const { form } = this.props;
// form.setFieldsValue({
// author_id: authorId || "",
// });
// const { formValues } = this.state;
// console.log(`formValues=`, formValues)
// const newFormValues = {
// author_id: authorId || "",
// ...formValues,
// };
// console.log(`newFormValues=`, newFormValues)
// this.setState({
// formValues: newFormValues,
// });
// this.setState({
// groupMemberList: membersList || [],
// });
// }
// });
// }
// }
}
fetchTopicList(){
// topic select 取所有的 topic
const params = {
page_size: 1000,
}
this.props.dispatch({
type: 'topic/fetch',
payload: params,
})
}
updateGroupOwnerScriptList(queryParamDict = {}){
console.log("updateGroupOwnerScriptList: queryParamDict=", queryParamDict)
const { dispatch } = this.props
dispatch({
type: 'script/fetchGroupOnwerScripts',
payload: queryParamDict,
});
}
generateQueryParamDict(){
const searchStr = this.props.location.search
console.log(`generateQueryParamDict: searchStr=`, searchStr)
const parsedQueryString = queryString.parse(searchStr);
console.log(`parsedQueryString=`, parsedQueryString)
return parsedQueryString
}
handleFirstOptionChange(topicList, value) {
const { form } = this.props;
form.setFieldsValue({
topic: value,
second_level_topic: '', // when first topic change, clear second topic
});
this.setState({
first_level_topic: topicList[value],
// second_level_topic: '', // when first topic change, clear second topic
});
}
handleEdit = (record) => {
const { dispatch } = this.props;
dispatch(routerRedux.push({
pathname: '/script/script-edit',
search: `?script_id=${record.id}`,
}));
};
handleReview = (record) => {
const { dispatch } = this.props;
dispatch(routerRedux.push({
pathname: '/script/script-review',
search: `?script_id=${record.id}`,
}));
};
handleHistories = (record) => {
const { dispatch } = this.props;
dispatch(routerRedux.push({
pathname: '/script/script-histories',
search: `?script_id=${record.id}`,
}));
};
handleExport = (record) => {
const { dispatch } = this.props;
dispatch({
type: 'script/scriptWordExport',
payload: record.id,
});
};
handleDeleteScript(scriptID) {
const { dispatch } = this.props;
dispatch({
type: 'script/deleteScript',
payload: scriptID,
}).then(() => {
dispatch({
type: 'script/fetchGroupOnwerScripts',
});
});
};
handleDetail = (record) => {
const { dispatch } = this.props;
dispatch(routerRedux.push({
pathname: '/script/script-detail',
search: `?script_id=${record.id}`,
}));
};
handleSearch = e => {
e.preventDefault();
const { dispatch, form } = this.props;
form.validateFields((err, fieldsValue) => {
console.log(`err=`, err, `fieldsValue=`, fieldsValue)
if (err) return;
const values = {
...fieldsValue,
};
console.log(`values=`, values)
this.setState({
formValues: values,
});
// console.log(`formValues=`, this.state.formValues)
dispatch({
type: 'script/fetchGroupOnwerScripts',
payload: values,
});
});
};
handleFormReset = () => {
const { form, dispatch } = this.props;
form.resetFields();
this.setState({
formValues: {},
});
dispatch({
type: 'script/fetchGroupOnwerScripts',
payload: {},
});
};
handleStandardTableChange = (pagination) => {
console.log(`handleStandardTableChange: pagination=`, pagination)
const { dispatch } = this.props;
const { formValues } = this.state;
console.log(`formValues=`, formValues)
this.setState({
currentPage: pagination.current,
pageSize: pagination.pageSize,
});
const params = {
page: pagination.current,
page_size: pagination.pageSize,
...formValues,
};
console.log(`params=`, params)
dispatch({
type: 'script/fetchGroupOnwerScripts',
payload: params,
});
};
renderSimpleForm() {
const { getFieldDecorator } = this.props.form;
const topicList = this.props.topic.topics;
const firstLevelOptions = Object.keys(topicList).map(first => <Option key={first}>{first}</Option>);
const secondLevelOptions = this.state.first_level_topic.map(second => <Option key={second}>{second}</Option>);
const authorOptions = this.state.groupMemberList.map(eachAuthor => <Option key={eachAuthor.id}>{eachAuthor.username}</Option>);
const selectFormItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 7 },
},
wrapperCol: {
xs: { span: 36 },
sm: { span: 18 },
md: { span: 16 },
},
};
return (
<Form onSubmit={this.handleSearch} layout="inline">
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={6} sm={18}>
<FormItem label="作者">
{getFieldDecorator('author_id')(
// <Select placeholder="请选择" style={{ width: '100%' }}>
<Select
showSearch
optionFilterProp="children"
filterOption={(input, option) => option.props.children.indexOf(input) >= 0}
style={{ width: '100%' }}
placeholder="作者"
>
{authorOptions}
</Select>
)}
</FormItem>
</Col>
<Col md={8} sm={18}>
<FormItem label="Place/Title">
{getFieldDecorator('search')(<Input placeholder="Place/Title" />)}
</FormItem>
</Col>
<Col md={6} sm={18}>
<FormItem label="审核状态">
{getFieldDecorator('publish_status')(
<Select placeholder="请选择" style={{ width: '100%' }}>
<Option value="">全部</Option>
<Option value="0">未通过</Option>
<Option value="1">已通过</Option>
</Select>
)}
</FormItem>
</Col>
<Col md={12} sm={18}>
<FormItem {...selectFormItemLayout} label="Topic" style={{ marginBottom: 5 }} >
{getFieldDecorator('topic', {
rules: [{ required: false, message: '请选择Topic'}],
})(
<Select
showSearch
optionFilterProp="children"
filterOption={(input, option) => option.props.children.indexOf(input) >= 0}
style={{ width: '46%' }}
onChange={this.handleFirstOptionChange.bind(this, topicList)}
placeholder="一级Topic"
>
{firstLevelOptions}
</Select>
)}
<span style={{ marginLeft: 5 }} className="ant-form-text"> - </span>
{getFieldDecorator('second_level_topic', {
rules: [{ required: false, message: '请选择Topic'}],
})(
<Select
showSearch
optionFilterProp="children"
filterOption={(input, option) => option.props.children.indexOf(input) >= 0}
style={{ width: '46%' }}
onChange={this.onSecondOptionChange.bind(this, topicList)}
placeholder="二级Topic"
>
{secondLevelOptions}
</Select>
)}
</FormItem>
</Col>
<Col md={12} sm={18}>
<span className={styles.submitButtons}>
<Button type="primary" htmlType="submit">
查询
</Button>
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
重置
</Button>
</span>
</Col>
</Row>
</Form>
);
}
render() {
const { script: { groupOwnerScripts }, loading } = this.props;
const { currentPage, pageSize } = this.state;
console.log("groupOwnerScripts=", groupOwnerScripts)
const columns = [
{
title: '序号',
dataIndex: 'no',
rowKey: 'no',
fixed: 'left',
render(text, record, index) {
const no = (currentPage - 1) * pageSize
return no + index + 1;
},
},
{
title: '作者',
dataIndex: 'author',
rowKey: 'author',
},
{
title: 'Place',
dataIndex: 'place',
rowKey: 'place',
width: 80,
},
{
title: 'Title',
dataIndex: 'title',
rowKey: 'title',
width: 120,
},
{
title: '一级Topic',
dataIndex: 'topic',
rowKey: 'topic',
width: 100,
},
{
title: '二级Topic',
dataIndex: 'second_level_topic',
rowKey: 'second_level_topic',
width: 100,
},
{
title: 'Age',
dataIndex: 'age',
rowKey: 'age',
width: 60,
render(text, record) {
const age = `${record.age_start}-${record.age_end}`
return age;
},
},
{
title: '对话轮数',
dataIndex: 'dialog_count',
rowKey: 'dialog_count',
width: 60,
},
{
title: '编辑状态',
dataIndex: 'edit_status',
rowKey: 'edit_status',
width: 60,
},
{
title: '发布状态',
dataIndex: 'publish_status',
rowKey: 'publish_status',
width: 60,
},
{
title: 'Version',
dataIndex: 'version',
rowKey: 'version',
},
{
title: '批注人',
dataIndex: 'review.reviewer',
rowKey: 'reviewer',
},
{
title: '批注内容',
dataIndex: 'review.remark',
rowKey: 'remark',
render: (text) => {
let textSlice = '';
if (text) {
textSlice = text.slice(0, 10);
}
return (
<Tooltip title={text}>
<span>{textSlice}</span>
</Tooltip>
);
},
},
{
title: '批注结果',
dataIndex: 'review.result',
rowKey: 'result',
},
{
title: '创建时间',
dataIndex: 'created_at',
rowKey: 'created_at',
},
{
title: '更新时间',
dataIndex: 'updated_at',
rowKey: 'updated_at',
},
{
title: '操作',
dataIndex: 'operate',
rowKey: 'operate',
fixed: 'right',
width: 180,
render: (text, record) => {
const encodedJwtToken = getEncodedToken()
const exportScritpUrl = scriptWordExportUrl(record.id, encodedJwtToken)
return (
<Fragment>
<a href="javascript:;" onClick={() => this.handleDetail(record)} >查看</a>
<Divider type="vertical" />
<a href="javascript:;" onClick={() => this.handleEdit(record)} >编辑</a>
<Divider type="vertical" />
<a href="javascript:;" onClick={() => this.handleReview(record)} >审核</a>
<Divider type="vertical" />
<a href="javascript:;" onClick={() => this.handleHistories(record)} >所有版本</a>
<Divider type="vertical" />
<a href={exportScritpUrl} >导出</a>
<Divider type="vertical" />
<Popconfirm title="是否删除次剧本?" onConfirm={() => this.handleDeleteScript(record.id)} >
<a>删除</a>
</Popconfirm>
</Fragment>
)
},
},
];
return (
<PageHeaderLayout title="组员剧本列表">
<Card bordered={false}>
<div className={styles.tableList}>
<div className={styles.tableListForm}>{this.renderSimpleForm()}</div>
<SimpleTable
loading={loading}
data={groupOwnerScripts}
columns={columns}
scroll={{ x: 1800 }}
rowKey={'id'}
onChange={this.handleStandardTableChange}
/>
</div>
</Card>
</PageHeaderLayout>
);
}
}可以实现:
从统计页面,点击后,可以把相关参数都传递过来,且表格中列表选项可以选择对应值,且可以将相关参数传递到后台返回对应数据:


内部过程涉及到:
获取到组的列表和组员的列表
前端均可选择了:


以及审核状态:

注:
后续再去优化:组员剧本列表
其中涉及到:
【已解决】Antd Pro中警告:Warning: Each record in table should have a unique `key` prop,or set `rowKey` to an unique primary key
转载请注明:在路上 » 【已解决】剧本编写系统中优化全部剧本列表页