现有的剧本编写系统中,全部剧本列表页,是可以正常显示全部的剧本的列表的:
但是显示的数据不对,应该改为:超级用户权限的,所有的用户的剧本的列表。
并且,支持从别处传入的参数去过滤,比如点击某个用户:
虽然显示列出了对应数据
但是作者的下拉框中,不是所有的成员
以及不支持传入:
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
转载请注明:在路上 » 【已解决】剧本编写系统中优化全部剧本列表页