|
@@ -0,0 +1,235 @@
|
|
|
+import { getExampleScenes } from 'api'
|
|
|
+import { useEffect, useState } from 'react'
|
|
|
+import { SceneType, QuoteSceneStatus, SceneTypeDesc } from 'constant';
|
|
|
+import { Table } from 'components'
|
|
|
+import { Modal, Button, Input, message } from 'antd'
|
|
|
+import { EditOutlined, CheckOutlined } from '@ant-design/icons'
|
|
|
+import { ScenePage, sceneTitleColumn, sceneTimeColumn, sceneActionColumn } from 'views/scene'
|
|
|
+import { fetchScenes, filterScenesSelector, useSelector, getScenesIdents, getSceneIdent } from 'store'
|
|
|
+import { useThunkPaging, useRefersh } from 'hook'
|
|
|
+import style from './style.module.scss'
|
|
|
+
|
|
|
+import type { Example, Scene, SceneIdents } from "api";
|
|
|
+import type { SceneColumn } from 'views/scene'
|
|
|
+
|
|
|
+export type ExampleScenesProps = Pick<Example, 'caseId'> & {
|
|
|
+ onClose: () => void,
|
|
|
+ onChangeScenes: (newSceneIds: SelectScenesProps['sceneIdents'], oldSceneIds: SelectScenesProps['sceneIdents']) => void
|
|
|
+ // onAddScene: () => void
|
|
|
+}
|
|
|
+
|
|
|
+export type EditExampleTitleProps = {
|
|
|
+ example: Example
|
|
|
+ onChangeTitle: (title: string) => void
|
|
|
+}
|
|
|
+export const EditExampleTitle = (props: EditExampleTitleProps) => {
|
|
|
+ const [inEditMode, setInEditMode] = useState(false)
|
|
|
+ const [title, setTitle] = useState(props.example.caseTitle)
|
|
|
+ const enterHandler = async () => {
|
|
|
+ if (title) {
|
|
|
+ if (title !== props.example.caseTitle) {
|
|
|
+ await props.onChangeTitle(title)
|
|
|
+ }
|
|
|
+ setInEditMode(false)
|
|
|
+ } else {
|
|
|
+ message.warning('请输入标题')
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const renderTitle = inEditMode
|
|
|
+ ? <Input.Group style={{width: '200px'}}>
|
|
|
+ <Input
|
|
|
+ autoFocus
|
|
|
+ style={{ width: 'calc(100% - 40px)' }}
|
|
|
+ value={title}
|
|
|
+ onChange={ev => setTitle(ev.target.value)}
|
|
|
+ />
|
|
|
+ <Button icon={<CheckOutlined />} onClick={enterHandler} />
|
|
|
+ </Input.Group>
|
|
|
+ : <div className={style['show-case-title']}>
|
|
|
+ <p>{props.example.caseTitle}</p>
|
|
|
+ <EditOutlined onClick={() => setInEditMode(true)} />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ return renderTitle
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+export type InsertExampleProps = {
|
|
|
+ onChangeTitle: (title: string) => void
|
|
|
+ onClose: () => void
|
|
|
+}
|
|
|
+export const InsertExample = (props: InsertExampleProps) => {
|
|
|
+ const [title, setTitle] = useState('')
|
|
|
+ const enterHandler = async () => {
|
|
|
+ if (title) {
|
|
|
+ await props.onChangeTitle(title)
|
|
|
+ } else {
|
|
|
+ message.warning('请输入标题')
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Modal
|
|
|
+ width="400px"
|
|
|
+ title="添加案件"
|
|
|
+ visible={true}
|
|
|
+ onOk={enterHandler}
|
|
|
+ onCancel={props.onClose}
|
|
|
+ okText="确定"
|
|
|
+ cancelText="取消"
|
|
|
+ >
|
|
|
+ <div className={style['add-case-title']}>
|
|
|
+ <label htmlFor="case-title">案件名称</label>
|
|
|
+ <Input value={title} id="case-title" onChange={ev => setTitle(ev.target.value)} />
|
|
|
+ </div>
|
|
|
+ </Modal>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+export const ExampleScenes = (props: ExampleScenesProps) => {
|
|
|
+ const [scenes, setScenes] = useState<Scene[]>([])
|
|
|
+ const [inSelectMode, setInSelectMode] = useState(false)
|
|
|
+ const idents = getScenesIdents(scenes)
|
|
|
+ const columns: SceneColumn[] = [
|
|
|
+ sceneTitleColumn,
|
|
|
+ {
|
|
|
+ title: '类型',
|
|
|
+ key: 'title',
|
|
|
+ render: (_, scene) => SceneTypeDesc[scene.type]
|
|
|
+ },
|
|
|
+ sceneTimeColumn,
|
|
|
+ sceneActionColumn
|
|
|
+ ]
|
|
|
+ const fetchExampleScenes = () => {
|
|
|
+ getExampleScenes({ caseId: props.caseId })
|
|
|
+ .then(setScenes)
|
|
|
+ }
|
|
|
+ useEffect(fetchExampleScenes, [props.caseId])
|
|
|
+
|
|
|
+ const renderSelectMode = inSelectMode
|
|
|
+ && <SelectScenes
|
|
|
+ onClose={() => setInSelectMode(false)}
|
|
|
+ sceneIdents={idents}
|
|
|
+ onSelect={async newIdents => {
|
|
|
+ await props.onChangeScenes(newIdents, idents)
|
|
|
+ await fetchExampleScenes()
|
|
|
+ setInSelectMode(false)
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ const renderSelf = (
|
|
|
+ <Modal
|
|
|
+ width="800px"
|
|
|
+ title="案件场景管理"
|
|
|
+ visible={true}
|
|
|
+ onOk={props.onClose}
|
|
|
+ onCancel={props.onClose}
|
|
|
+ okText="确定"
|
|
|
+ cancelText="取消"
|
|
|
+ >
|
|
|
+ <div className={style['model-header']}>
|
|
|
+ <Button type="primary" onClick={() => setInSelectMode(true)}>
|
|
|
+ 添加场景
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ <Table
|
|
|
+ rowKey={'id'}
|
|
|
+ columns={columns}
|
|
|
+ data={scenes}
|
|
|
+ />
|
|
|
+ </Modal>
|
|
|
+ )
|
|
|
+
|
|
|
+ return <>
|
|
|
+ {renderSelectMode}
|
|
|
+ {renderSelf}
|
|
|
+ </>
|
|
|
+}
|
|
|
+
|
|
|
+export type SelectScenesProps = {
|
|
|
+ sceneIdents: SceneIdents
|
|
|
+ onClose: () => void,
|
|
|
+ onSelect: (ids: SelectScenesProps['sceneIdents']) => void
|
|
|
+}
|
|
|
+export const SelectScenes = ({ sceneIdents, ...props }: SelectScenesProps) => {
|
|
|
+ let idents:SceneIdents = sceneIdents.map(ident => ({
|
|
|
+ ...ident,
|
|
|
+ numList: [...ident.numList]
|
|
|
+ }))
|
|
|
+ const getTypeIdents = (type: SceneType) => idents.find(ident => ident.type === type) as SceneIdents[number]
|
|
|
+
|
|
|
+ const getSelectIds = (type: SceneType, scenes: Scene[]) => {
|
|
|
+ const typeIdents = getTypeIdents(type)
|
|
|
+ const selectedIds = []
|
|
|
+ for (const scene of scenes) {
|
|
|
+ const sceneIdent = getSceneIdent(scene)
|
|
|
+ if (typeIdents.numList.includes(sceneIdent)) {
|
|
|
+ selectedIds.push(scene.id)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return selectedIds
|
|
|
+ }
|
|
|
+ const replaceIdents = (type: SceneType, scenes: Scene[], selectScenes: Scene[]) => {
|
|
|
+ const typeIdents = getTypeIdents(type)
|
|
|
+ for (const scene of scenes) {
|
|
|
+ const sceneIdent = getSceneIdent(scene)
|
|
|
+ const inSelect = selectScenes.includes(scene)
|
|
|
+ const identIndex = typeIdents?.numList.indexOf(sceneIdent)
|
|
|
+ if (~identIndex && !inSelect) {
|
|
|
+ typeIdents.numList.splice(identIndex, 1)
|
|
|
+ } else if (!~identIndex && inSelect) {
|
|
|
+ typeIdents.numList.push(sceneIdent)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const Content = ({type}: {type: SceneType}) => {
|
|
|
+ const scenes = useSelector((state) => filterScenesSelector(state, { type }))
|
|
|
+ const states = useThunkPaging({ type, sceneName: '', status: QuoteSceneStatus.SUCCESS }, fetchScenes)
|
|
|
+ const [[paging, setPaging], [, setParams]] = states
|
|
|
+ const selectedIds = getSelectIds(type, scenes)
|
|
|
+ const refersh = useRefersh()
|
|
|
+
|
|
|
+ const rowSelection: any = {
|
|
|
+ selectedRowKeys: selectedIds,
|
|
|
+ onChange(ids: string, selectScenes: Scene[]) {
|
|
|
+ replaceIdents(type, scenes, selectScenes)
|
|
|
+ refersh()
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <div className={style['model-header']}>
|
|
|
+ <Input.Search
|
|
|
+ className='content-header-search'
|
|
|
+ placeholder="输入名称搜索"
|
|
|
+ onSearch={sceneName => setParams({ sceneName }) }
|
|
|
+ style={{ width: 264 }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <Table
|
|
|
+ columns={[sceneTitleColumn, sceneTimeColumn]}
|
|
|
+ rowSelection={rowSelection}
|
|
|
+ data={scenes}
|
|
|
+ paging={paging}
|
|
|
+ onChangePaging={setPaging}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Modal
|
|
|
+ width="800px"
|
|
|
+ title="添加场景"
|
|
|
+ visible={true}
|
|
|
+ onOk={() => props.onSelect(idents)}
|
|
|
+ onCancel={props.onClose}
|
|
|
+ okText="确定"
|
|
|
+ cancelText="取消"
|
|
|
+ >
|
|
|
+ <ScenePage TabContent={Content} />
|
|
|
+ </Modal>
|
|
|
+ )
|
|
|
+}
|