forked from gzzfw/frontEnd/gzDyh

dminyi
2024-09-07 d2280c384e4b8f6acef1e01f400e3c61c97d82d9
Merge branch 'master' of http://120.79.193.119:9090/r/gzzfw/frontEnd/gzDyh into master
10 files modified
860 ■■■■■ changed files
gz-customerSystem/src/components/ProgressStep/VisitStep.jsx 155 ●●●●● patch | view | raw | blame | history
gz-customerSystem/src/components/ProgressStep/index.less 25 ●●●●● patch | view | raw | blame | history
gz-customerSystem/src/components/SelectObjModal/selectPerson.jsx 151 ●●●● patch | view | raw | blame | history
gz-customerSystem/src/router/router.js 2 ●●● patch | view | raw | blame | history
gz-customerSystem/src/views/register/eventFlow/component/AssignedModel.jsx 110 ●●●● patch | view | raw | blame | history
gz-customerSystem/src/views/register/eventFlow/component/BackModel.jsx 77 ●●●●● patch | view | raw | blame | history
gz-customerSystem/src/views/register/eventFlow/component/EscalationModel.jsx 68 ●●●● patch | view | raw | blame | history
gz-customerSystem/src/views/register/eventFlow/component/EventFlow.jsx 162 ●●●● patch | view | raw | blame | history
gz-customerSystem/src/views/register/eventFlow/index.jsx 97 ●●●● patch | view | raw | blame | history
gz-customerSystem/src/views/register/matterDetail/index.jsx 13 ●●●● patch | view | raw | blame | history
gz-customerSystem/src/components/ProgressStep/VisitStep.jsx
@@ -7,117 +7,100 @@
 * @Description: 来访登记步骤条
 */
import React, { useEffect, useState } from 'react';
import { Tooltip, Space } from 'antd';
import Icon, { PaperClipOutlined, RollbackOutlined, EllipsisOutlined } from '@ant-design/icons';
import React, { Fragment, useEffect, useState } from 'react';
import { Tooltip } from 'antd';
import { ledger_8, ledger_7, ledger_12, ledger_13 } from '../../assets/images';
import NameCard from '../NameCard';
import * as $$ from '../../utils/utility';
import FilesDrawer from '../FilesDrawer';
import './index.less';
/**
 * progressData:'', // 流程数据
 * progressData: {
 * assistCaseFlowList: [],//配合部门流程数组
 * handleCaseFlowList: [],//承办部门流程数组
 * }, // 流程数据
 * hasTab: false,//是否有部门切换
 */
const ProgressStep = ({ progressData }) => {
const ProgressStep = ({ progressData, hasTab }) => {
  const [proType, setProType] = useState('handleCaseFlowList')
  const iconMap = {
    1: ledger_8,
    2: ledger_7,
    3: ledger_12,
    4: ledger_13
    1: ledger_7,//完成
    2: ledger_12,//回退
    3: ledger_13//上报
  }
  const btnList = [
    {
      value: 'handleCaseFlowList',
      label: '承办部门'
    },
    {
      value: 'assistCaseFlowList',
      label: '配合部门'
    },
  ]
  // 已处理列表第一个元素
  const dom1 = (x) => (
  useEffect(() => {
    setProType('handleCaseFlowList')
  }, [progressData])
  return (
    <Fragment>
      {hasTab &&
        <div className='tabBtn'>
          {btnList.map((item, index) => {
            return <div
              className={`tabBtn-btn ${proType === item.value ? 'tabBtn-active' : ''}`}
              key={item.value}
              onClick={() => { setProType(item.value) }}
              style={{ marginRight: (index + 1) !== btnList.length ? '20px' : '0' }}
            >{item.label}</div>
          })}
        </div>
      }
      {progressData[proType] && progressData[proType].length !== 0
        ? progressData[proType].map((x, t) => {
          return (
            <div key={t + 1}>
              <div className="myStep-item">
                {t === progressData[proType].length - 1 ? null : <div className={`${!x.handleContent ? 'myStep-item-divider' : x.fileInfoList?.length > 0 ? 'myStep-item-divider2' : "myStep-item-divider1"} ${x.status === '2' && 'myStep-item-divider-success'}`} />}
                <div className={`myStep-item-icon1 myStep-item-${x.status === 1 ? 'noStarted1' : 'success1'}`}>
                  <div className="myStep-item-title">{x.nodeShowName || '事件流转'}</div>
                  <img className='myStep-item-img' src={x.status === 1 ? ledger_8 : iconMap[x.taskType]} alt="" />
                </div>
                <div className="myStep-item-right">
                  {t === progressData[proType].length - 1 ?
                    <div>
                      <div className="myStep-item-p" style={{ color: 'rgba(0,0,0,0.50)' }}>
                        {x.processName}
                      </div>
                      <div className="myStep-item-p">
                        <span>{x.handleUnitName || '-'}</span>
                      </div>
                    </div>
                    :
    <div>
      <div className="myStep-item-p">
        <span>{x.handlerUserName || '-'}</span>
                        <span>{x.handleUnitName || '-'}</span>
      </div>
                      {x.handleUserName &&
      <div className="myStep-item-p" style={{ color: 'rgba(0,0,0,0.50)' }}>
        <span>操作人:</span>
        <span>{x.operationName}</span>
      </div>
      <div className="myStep-item-p" style={{ color: 'rgba(0,0,0,0.50)' }}>
        <span>经办时间:</span>
        <span>{$$.timeFormat(x.finishTime)}</span>
      </div>
    </div>
  );
  // 已处理列表后面 元素
  const dom2 = (x) => (
    <div>
      <div className="myStep-item-p">
        <span>{x.handlerUserName || '-'}</span>
      </div>
      {x.operationName &&
        <div className="myStep-item-p" style={{ color: 'rgba(0,0,0,0.50)' }}>
          <span>操作人:</span>
          <span>{x.operationName}</span>
                          <span>{x.handleUserName}</span>
        </div>
      }
      <div className="myStep-item-p" style={{ color: 'rgba(0,0,0,0.50)' }}>
        <span>操作时间:</span>
        <span>{$$.timeFormat(x.finishTime)}</span>
                        <span>{$$.timeFormat(x.handleTime)}</span>
      </div>
      {
        x.handleContent &&
                        x.handleNotes &&
        <div className='myStep-item-p-yy' style={{ width: '200px' }}>
          <span className='myStep-item-p-yy-l'>
            {x.handleResult == '2' ?
              <span>退回<Tooltip placement="top" title={x.handleContent || ''}><span>{`(${x.handleContent})` || '-'}</span></Tooltip></span>
              : x.taskNode == 'F22_00019-3' && x.handleResult == '1' ?
                // 22_00025-1:调解成功,22_00025-2:调解不成功
                <span>调解结果:<Tooltip placement="top" title={x.mediResult == '22_00025-1' ? '调解成功' : x.mediResult == '22_00025-2' ? '调解不成功' : '-'}><span>{`${x.mediResult == '22_00025-1' ? '调解成功' : x.mediResult == '22_00025-2' ? '调解不成功' : '-'}` || '-'}</span></Tooltip></span>
                : <Tooltip placement="top" title={x.handleContent || ''}><span>{x.handleContent || '-'}</span></Tooltip>}
                            <span><Tooltip placement="top" title={x.handleNotes || ''}><span>{x.handleNotes || '-'}</span></Tooltip></span>
          </span>
          {
            x.fileInfoList?.length > 0 &&
            <div style={{ marginTop: '4px' }}>
              <FilesDrawer name={<>
                <PaperClipOutlined style={{ marginRight: '4px' }} />
                <span>{x.taskNode == 'F22_00019-3' && x.handleResult == '1' ? '调解协议书' : '处理附件'}</span>
              </>} filesData={x.fileInfoList} title="经办附件" />
            </div>
          }
        </div>
      }
    </div>
  );
  // 办理中
  const dom3 = (x) => (
    <div>
      <div className="myStep-item-p">
        <span style={{ color: 'rgba(0,0,0,0.50)' }}>待受理</span>
      </div>
      <div className="myStep-item-p">
        <span>{x.handlerUserName}</span>
      </div>
    </div>
  );
  return (
    <>
      {progressData.length !== 0
        ? progressData.map((x, t) => {
          return (
            <div key={t + 1}>
              <div className="myStep-item">
                {t === progressData.length - 1 ? null : <div className={`${!x.handleContent ? 'myStep-item-divider' : x.fileInfoList?.length > 0 ? 'myStep-item-divider2' : "myStep-item-divider1"} ${x.status === '2' && 'myStep-item-divider-success'}`} />}
                <div className={`myStep-item-icon1 myStep-item-${x.status === '1' ? 'noStarted1' : 'success1'}`}>
                  <div className="myStep-item-title">{x.taskNodeName}</div>
                  <img className='myStep-item-img' src={iconMap[x.status]} alt="" />
                </div>
                <div className="myStep-item-right">
                  {
                    t === 0 && dom1(x || {})
                  }
                  {
                    t !== 0 && <>
                      {
                        x.status === '1' ?  dom3(x || {}) : dom2(x || {})
                      }
                    </>
                  }
                </div>
              </div>
@@ -125,7 +108,7 @@
          );
        })
        : <div style={{ padding: '100px 0' }}>{$$.MyEmpty()}</div>}
    </>
    </Fragment>
  );
};
gz-customerSystem/src/components/ProgressStep/index.less
@@ -12,6 +12,7 @@
                border-color: #bfbfbf;
            }
        }
        &-success1 {
            background-color: @main-color;
@@ -158,18 +159,21 @@
            margin-top: 4px;
            display: flex;
            align-items: flex-start;
            &-flex {
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: center;
                margin-top: 8px;
                &-title {
                    font-size: 12px;
                    line-height: 20px;
                    color: @text-color-secondary;
                }
            }
            &-yy {
                display: flex;
                flex-direction: column;
@@ -178,6 +182,7 @@
                border-radius: 5px;
                padding: 4px 8px;
                color: rgba(0, 0, 0, 0.5);
                &-l {
                    overflow: hidden;
                    white-space: nowrap;
@@ -197,3 +202,23 @@
        }
    }
}
.tabBtn {
    display: flex;
    margin-bottom: 12px;
    &-btn {
        height: 32px;
        background: #ffffff;
        border: 1px solid #e5e6eb;
        border-radius: 4px;
        color: #e5e6eb;
        padding: 4px 8px;
        cursor: pointer;
    }
    &-active {
        color: #1a6fb8;
        border-color: #1a6fb8;
    }
}
gz-customerSystem/src/components/SelectObjModal/selectPerson.jsx
@@ -18,7 +18,20 @@
// 获取人员,组织,部门数据
function getDataApi(type, searchData) {
    const url = type === 'person' ? 'ctUser/userChoose' : type === 'unit' ? 'ctUser/unitList' : 'ctUser/deptList';
    let url
    switch (type) {
        case 'dept':
            url = `ctUnit/unitChoose`
            break;
        case 'person':
            url = 'ctUser/userChoose'
            break
        case 'unit':
            url = 'ctUser/unitList'
            break
        default:
            break;
    }
    return $$.ax.request({ url, type: 'get', data: searchData, service: 'cust' });
}
@@ -31,36 +44,37 @@
 * onClose, // 关闭
 * onOk, // 点击确定的回调
 */
const SelectObjModal = ({ visible = false, checkKeys = [], type = 'person', isCheckbox = false, searchData = {}, onClose, onOk, }) => {
const SelectObjModal = ({ visible = false, checkKeys = [], type = 'dept', isCheckbox = false, searchData = {}, onClose, onOk, }) => {
    const nameStr = type === 'person' ? '人员' : type === 'unit' ? '组织' : '部门';
    // 默认调解员查询'22_00024-4'
    const searchRole = type === 'person' ? { roleCode: '22_00024-4' } : {};
    const [data, setData] = useState([]);
    const [checkedKeys, setCheckedKeys] = useState({ keys: [], items: [] });
    const [expandedKeys, setExpandedKeys] = useState([]);
    const [searchValue, setSearchValue] = useState('');
    const [autoExpandParent, setAutoExpandParent] = useState(true);
    const [dataList, setDataList] = useState([]);
    // tree复选框选择
    function handleCheck(checkedKeys, e) {
        if (!isCheckbox && checkedKeys.checked.length > 1) {
            $$.info({ type: 'warning', content: '当前选择只可单选' });
            return;
    useEffect(() => {
        if (!visible) return;
        // 获取数据
        async function getData() {
            // global.setSpinning(true);
            const res = await getDataApi(type, { ...searchRole, ...searchData });
            // global.setSpinning(false);
            if (res.type) {
                setData(res.data || []);
        }
        let checkedNodes = e.checkedNodes;
        checkedNodes.forEach((x) => delete x.children);
        setCheckedKeys({ keys: checkedKeys.checked, items: checkedNodes });
    }
    // 删除选项
    function handleDelete(t) {
        checkedKeys.keys.splice(t, 1);
        checkedKeys.items.splice(t, 1);
        setCheckedKeys({ ...checkedKeys });
        if (checkKeys.length !== 0) {
            let keys = [];
            checkKeys.forEach((x) => keys.push(x.value));
            setCheckedKeys({ keys, items: checkKeys });
        } else {
            setCheckedKeys({ keys: [], items: [] });
    }
        getData();
    }, [type, visible]);
    // 搜索
    useEffect(() => {
@@ -80,35 +94,6 @@
        setDataList(arr);
        handleSearch('', arr);
    }, [data]);
    const getParentKey = (key, tree) => {
        let parentKey;
        for (let i = 0; i < tree.length; i++) {
            const node = tree[i];
            if (node.children) {
                if (node.children.some((item) => item.value === key)) {
                    parentKey = node.value;
                } else if (getParentKey(key, node.children)) {
                    parentKey = getParentKey(key, node.children);
                }
            }
        }
        return parentKey;
    };
    function handleSearch(value, dataList) {
        const newExpandedKeys = dataList
            .map((item) => {
                if (item.label.indexOf(value) > -1) {
                    return getParentKey(item.value, data);
                }
                return null;
            })
            .filter((item, i, self) => item && self.indexOf(item) === i);
        setExpandedKeys(newExpandedKeys);
        setSearchValue(value);
        setAutoExpandParent(true);
    }
    const treeData = useMemo(() => {
        const loop = (data) =>
@@ -146,32 +131,52 @@
        return loop(data);
    }, [searchValue, data]);
    // 默认调解员查询'22_00024-4'
    const searchRole = type === 'person' ? { roleCode: '22_00024-4' } : {};
    // tree复选框选择
    function handleCheck(checkedKeys, e) {
        if (!isCheckbox && checkedKeys.checked.length > 1) {
            $$.info({ type: 'warning', content: '当前选择只可单选' });
            return;
        }
        let checkedNodes = e.checkedNodes;
        checkedNodes.forEach((x) => delete x.children);
        setCheckedKeys({ keys: checkedKeys.checked, items: checkedNodes });
    }
    console.log(checkedKeys.keys,'checkedKeys.keyscheckedKeys.keys')
    useEffect(() => {
        if (!visible) return;
        // 获取数据
        async function getData() {
            global.setSpinning(true);
            const res = await getDataApi(type, { ...searchRole, ...searchData });
            global.setSpinning(false);
            if (res.type) {
                setData(res.data || []);
    // 删除选项
    function handleDelete(t) {
        checkedKeys.keys.splice(t, 1);
        checkedKeys.items.splice(t, 1);
        setCheckedKeys({ ...checkedKeys });
            }
        }
        if (checkKeys.length !== 0) {
            let keys = [];
            checkKeys.forEach((x) => keys.push(x.value));
            setCheckedKeys({ keys, items: checkKeys });
        } else {
            setCheckedKeys({ keys: [], items: [] });
        }
        getData();
    }, [type, visible]);
    const nameStr = type === 'person' ? '人员' : type === 'unit' ? '组织' : '部门';
    const getParentKey = (key, tree) => {
        let parentKey;
        for (let i = 0; i < tree.length; i++) {
            const node = tree[i];
            if (node.children) {
                if (node.children.some((item) => item.value === key)) {
                    parentKey = node.value;
                } else if (getParentKey(key, node.children)) {
                    parentKey = getParentKey(key, node.children);
                }
            }
        }
        return parentKey;
    };
    function handleSearch(value, dataList) {
        const newExpandedKeys = dataList
            .map((item) => {
                if (item.label.indexOf(value) > -1) {
                    return getParentKey(item.value, data);
                }
                return null;
            })
            .filter((item, i, self) => item && self.indexOf(item) === i);
        setExpandedKeys(newExpandedKeys);
        setSearchValue(value);
        setAutoExpandParent(true);
    }
    return (
        <Modal
gz-customerSystem/src/router/router.js
@@ -217,7 +217,7 @@
                        <Route path="judicialOverview" element={<JudicialOverview />} />
                        {/* 来访登记*/}
                        <Route path="visit/:id?" element={<Visit />} />
                        <Route path="visit/eventFlow" element={<EventFlow />} />
                        <Route path="visit/eventFlow/:caseTaskId?/:caseId?" element={<EventFlow />} />
                        <Route path="visit/handleFeedback" element={<HandleFeedback />} />
                        <Route path="visit/fileMessage" element={<FileMessage />} />
                        <Route path="visit/closingReview" element={<ClosingReview />}/>
gz-customerSystem/src/views/register/eventFlow/component/AssignedModel.jsx
@@ -1,37 +1,84 @@
import React, { useRef, useState } from 'react'
import React, { useRef, useState, useEffect } from 'react'
import { Row, Col } from 'antd';
import { Form, Input, Button, Select } from '@arco-design/web-react';
import ArcoUpload from '@/components/ArcoUpload';
import { Scrollbars } from "react-custom-scrollbars";
import SelectObjModal from '@/components/SelectObjModal/selectPerson';
import { useParams } from 'react-router-dom';
import * as $$ from '@/utils/utility';
const FormItem = Form.Item;
const TextArea = Input.TextArea;
const Option = Select.Option;
const options = ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Chengdu', 'Wuhan'];
const appUrl = $$.appUrl;
function assign(data) {
  return $$.ax.request({ url: `caseTask/assign`, type: 'post', service: 'mediate', data });
}
function delFile(id) {
  return $$.ax.request({ url: `fileInfo/deleteFileById`, type: 'get', service: 'sys', data: { id } });
}
export default function BackModel(props) {
  const routeData = useParams();
  const formRef = useRef();
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [wantUser, setWantUser] = useState({});
  const [mainDept, setMainDept] = useState('handleUnit');//判断打开弹窗的是承办部门还是配合部门
  const [selectOptions, setSelectOptions] = useState({});//两个部门选择的options
  useEffect(() => {
  }, [])
  const handleSubmit = () => {
    formRef.current.validate(undefined, (errors, values) => {
      console.log(errors, values);
      if (!errors) {
        handleAssign({
          caseTaskId: routeData.caseTaskId,
          assignContent: values.assignContent,
          handleUnitId: wantUser['handleUnit'][0].value,
          handleUnitName: wantUser['handleUnit'][0].name,
          assistUnitList: wantUser['assistUnit'] && wantUser['assistUnit'].map(item => {
            return {
              uitId: item.value,
              uitName: item.name
            }
          })
        })
      }
    })
  }
  const handleTemplate = (type) => {
    if (type === 1) {
      formRef.current.setFieldValue('trueName', '本事项经初步核实,认为属于贵部门职责范围内的矛盾纠纷化解工作。请组织专门人员负责此事,尽快查明事实真相,依法依规进行处理,并在处理过程中充分考虑当事人的合理诉求,确保公平公正,维护当事人的合法权益。同时,请务必保持与当事人的沟通畅通,及时反馈办理进展,以增强矛盾纠纷化解工作的透明度和公信力。')
      formRef.current.setFieldValue('assignContent', '本事项经初步核实,认为属于贵部门职责范围内的矛盾纠纷化解工作。请组织专门人员负责此事,尽快查明事实真相,依法依规进行处理,并在处理过程中充分考虑当事人的合理诉求,确保公平公正,维护当事人的合法权益。同时,请务必保持与当事人的沟通畅通,及时反馈办理进展,以增强矛盾纠纷化解工作的透明度和公信力。')
    } else {
      formRef.current.setFieldValue('trueName', '')
      formRef.current.setFieldValue('assignContent', '')
    }
  }
  const handleFocus = (e) => {
    e.stopPropagation()
    setIsModalVisible(true)
  //交办请求
  const handleAssign = async (data) => {
    const res = await assign(data)
    if (res.type) {
      $$.infoSuccess({ content: '交办成功!' });
      props.onCancel()
    }
  }
  //删除文件
  const handleDelFile = async (id) => {
    const res = await delFile(id)
    if (res.type) {
      $$.infoSuccess({ content: '删除成功!' });
    }
  }
  //form数据同步要提交的数据
  const handleSync = (field, value) => {
    wantUser[field] = wantUser[field].filter(item => value.indexOf(item.value) != -1)
    setWantUser(wantUser);
  }
  return (
@@ -49,13 +96,20 @@
            <Col span={24}>
              <FormItem
                label={(<div style={{ display: 'flex' }}>承办部门<div className="must">必填</div></div>)}
                field='bumen'
                field='handleUnit'
                rules={[{ required: true, message: '请选择承办部门' }]}
              >
                <Select
                  mode='multiple'
                  placeholder='请选择承办部门'
                  allowClear
                  onFocus={handleFocus}
                  onFocus={(e) => {
                    e.stopPropagation()
                    setIsModalVisible(true)
                    setMainDept('handleUnit')
                  }}
                  options={selectOptions['handleUnit']}
                  onChange={(v) => { handleSync('handleUnit', v) }}
                >
                </Select>
              </FormItem>
@@ -63,18 +117,20 @@
            <Col span={24}>
              <FormItem
                label={(<div style={{ display: 'flex' }}>配合部门<div style={{ color: '#86909C' }}>(可多选)</div></div>)}
                field='peihe'
                field='assistUnit'
              >
                <Select
                  mode='multiple'
                  placeholder='请选择配合部门'
                  allowClear
                  onFocus={(e) => {
                    e.stopPropagation()
                    setIsModalVisible(true)
                    setMainDept('assistUnit')
                  }}
                  options={selectOptions['assistUnit']}
                  onChange={(v) => { handleSync('assistUnit', v) }}
                >
                  {options.map((option) => (
                    <Option key={option} value={option}>
                      {option}
                    </Option>
                  ))}
                </Select>
              </FormItem>
            </Col>
@@ -85,7 +141,7 @@
              </div>
              <FormItem
                label={(<div style={{ display: 'flex' }}>交办意见<div className="must">必填</div></div>)}
                field='trueName'
                field='assignContent'
                rules={[{ required: true, message: '请选择回退理由' }]}
              >
                <TextArea
@@ -98,10 +154,11 @@
            <Col span={24} className="doubleFile">
              <ArcoUpload
                params={{
                  action: ``,
                  action: `${appUrl.fileUrl}/${appUrl.sys}/api/web/fileInfo/upload?mainId=${props.caseId}&ownerId=${routeData.caseTaskId}&ownerType=22_00018-501`,
                }}
                field='file'
                label='附件材料'
                handleDelFile={handleDelFile}
              />
            </Col>
          </Row>
@@ -118,12 +175,23 @@
      </div>
      <SelectObjModal
        visible={isModalVisible}
        checkKeys={wantUser.wantUserId ? [{ label: wantUser.wantUserName, value: wantUser.wantUserId }] : undefined}
        checkKeys={wantUser[mainDept]}
        onOk={(value) => {
          console.log(value);
          setIsModalVisible(false);
          setWantUser({ wantUserId: value.keys[0], wantUserName: value.items[0].name });
          wantUser[mainDept] = value.items
          setWantUser(wantUser);
          selectOptions[mainDept] = value.items.map(item => ({
            label: item.name,
            value: item.value
          }))
          setSelectOptions(selectOptions)
          formRef.current.setFieldValue(mainDept, value.items.map(item => item.value))
        }}
        onClose={() => setIsModalVisible(false)}
        type='dept'
        isCheckbox={mainDept === 'handleUnit' ? false : true}
      />
    </div>
  )
gz-customerSystem/src/views/register/eventFlow/component/BackModel.jsx
@@ -1,15 +1,30 @@
import React, { useRef } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { Row, Col } from 'antd';
import { Form, Input, Button, Radio } from '@arco-design/web-react';
import ArcoUpload from '@/components/ArcoUpload';
import { Scrollbars } from "react-custom-scrollbars";
import * as $$ from '@/utils/utility';
const RadioGroup = Radio.Group;
const FormItem = Form.Item;
const TextArea = Input.TextArea;
const appUrl = $$.appUrl;
function getId() {
  return $$.ax.request({ url: `caseUtils/getNewTimeId`, type: 'get', service: 'utils' });
}
function delFile(id) {
  return $$.ax.request({ url: `fileInfo/deleteFileById`, type: 'get', service: 'sys', data: { id } });
}
function returnApply(data) {
  return $$.ax.request({ url: `caseTask/returnApply`, type: 'post', service: 'mediate', data });
}
export default function BackModel(props) {
  const formRef = useRef();
  const [id, setId] = useState();
  const options = [
    {
      label: '不属于本部门的职能范围',
@@ -32,9 +47,50 @@
      value: 5
    },
  ]
  const handleSubmit = () => {
  useEffect(() => {
    getAppId()
  }, [])
  //获取id
  const getAppId = async () => {
    const res = await getId()
    if (res.type) {
      setId(res.data)
  }
  }
  const handleSubmit = () => {
    if (formRef.current) {
      formRef.current.validate(undefined, (errors, values) => {
        if (!errors) {
          handleReturn({
            id,
            caseId: props.caseId,
            returnContent: values.returnContent
          })
        }
      })
    }
  }
  //删除文件
  const handleDelFile = async (id) => {
    const res = await delFile(id)
    if (res.type) {
      $$.infoSuccess({ content: '删除成功!' });
    }
  }
  //回退请求
  const handleReturn = async (data) => {
    const res = await returnApply(data)
    if (res.type) {
      $$.infoSuccess({ content: '提交申请成功!' });
      props.onCancel()
    }
  }
  return (
    <div>
      <Scrollbars style={{ height: '550px' }} autoHide>
@@ -50,17 +106,23 @@
            <Col span={24}>
              <FormItem
                label={(<div style={{ display: 'flex' }}>回退理由<div className="must">必填</div></div>)}
                field='trueName'
                field='backType'
                rules={[{ required: true, message: '请选择回退理由' }]}
              >
                <RadioGroup direction='vertical' options={options}>
                </RadioGroup>
                <RadioGroup
                  direction='vertical'
                  options={options}
                  onChange={(value) => {
                    const obj = options.find(item => item.value === value)
                    formRef.current.setFieldValue('returnContent', obj.label)
                  }}
                />
              </FormItem>
            </Col>
            <Col span={24}>
              <FormItem
                label=' '
                field='luyou'
                field='returnContent'
                rules={[{ required: true, message: '回退理由不能为空' }]}
              >
                <TextArea
@@ -72,10 +134,11 @@
            <Col span={24} className="doubleFile">
              <ArcoUpload
                params={{
                  action: ``,
                  action: `${appUrl.fileUrl}/${appUrl.sys}/api/web/fileInfo/upload?mainId=${props.caseId}&ownerId=${id}&ownerType=22_00018-520`,
                }}
                field='file'
                label='附件材料'
                handleDelFile={handleDelFile}
              />
            </Col>
          </Row>
gz-customerSystem/src/views/register/eventFlow/component/EscalationModel.jsx
@@ -1,27 +1,81 @@
import React, { useRef } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { Row, Col } from 'antd';
import { Form, Input, Button } from '@arco-design/web-react';
import ArcoUpload from '@/components/ArcoUpload';
import { Scrollbars } from "react-custom-scrollbars";
import { escalation } from '@/assets/images/icon';
import * as $$ from '@/utils/utility';
const FormItem = Form.Item;
const TextArea = Input.TextArea;
const appUrl = $$.appUrl;
function getId() {
  return $$.ax.request({ url: `caseUtils/getNewTimeId`, type: 'get', service: 'utils' });
}
function delFile(id) {
  return $$.ax.request({ url: `fileInfo/deleteFileById`, type: 'get', service: 'sys', data: { id } });
}
function appearApply(data) {
  return $$.ax.request({ url: `caseTask/appearApply`, type: 'post', service: 'mediate', data });
}
export default function BackModel(props) {
  const formRef = useRef();
  const [id, setId] = useState()
  useEffect(() => {
    getAppId()
  }, [])
  //获取id
  const getAppId = async () => {
    const res = await getId()
    if (res.type) {
      setId(res.data)
    }
  }
  const handleSubmit = () => {
    formRef.current.validate(undefined, (errors, values) => {
      console.log(errors, values);
      if (formRef.current) {
        formRef.current.validate(undefined, (errors, values) => {
          if (!errors) {
            handleEscala({
              id,
              caseId: props.caseId,
              returnContent: values.returnContent
            })
          }
        })
      }
    })
  }
  const handleTemplate = (type) => {
    if(type === 1) {
      formRef.current.setFieldValue('trueName', '经初步核查,该事项较为复杂,且涉及多个相关部门的协调配合,为确保能够高效、妥善地解决当事人的问题,特此请求上级给予指导和支持。')
      formRef.current.setFieldValue('returnContent', '经初步核查,该事项较为复杂,且涉及多个相关部门的协调配合,为确保能够高效、妥善地解决当事人的问题,特此请求上级给予指导和支持。')
    } else {
      formRef.current.setFieldValue('trueName', '')
      formRef.current.setFieldValue('returnContent', '')
    }
  }
  //上报请求
  const handleEscala = async (data) => {
    const res = await appearApply(data)
    if (res.type) {
      $$.infoSuccess({ content: '提交申请成功!' });
      props.onCancel()
    }
  }
  //删除文件
  const handleDelFile = async (id) => {
    const res = await delFile(id)
    if (res.type) {
      $$.infoSuccess({ content: '删除成功!' });
    }
  }
@@ -54,10 +108,9 @@
              </div>
              <FormItem
                label={(<div style={{ display: 'flex' }}>上报意见<div className="must">必填</div></div>)}
                field='trueName'
                field='returnContent'
                rules={[{ required: true, message: '请选择回退理由' }]}
              >
                <TextArea
                  autoSize={{ minRows: 4, maxRows: 8 }}
                  placeholder='请填写回退的具体理由'
@@ -68,10 +121,11 @@
            <Col span={24} className="doubleFile">
              <ArcoUpload
                params={{
                  action: ``,
                  action: `${appUrl.fileUrl}/${appUrl.sys}/api/web/fileInfo/upload?mainId=${props.caseId}&ownerId=${id}&ownerType=22_00018-512`,
                }}
                field='file'
                label='附件材料'
                handleDelFile={handleDelFile}
              />
            </Col>
          </Row>
gz-customerSystem/src/views/register/eventFlow/component/EventFlow.jsx
@@ -9,82 +9,86 @@
import AssignedModel from './AssignedModel';
import MatterDetail from '../../matterDetail';
import SupervisingView from "../../matterDetail/Supervising";
import * as $$ from '@/utils/utility';
const TabPane = Tabs.TabPane;
const Step = Steps.Step;
const fakeData = [
  {
    handlerUserName: '天河区棠下街综治中心',
    finishTime: new Date().getTime() - 24 * 60 * 60 * 1000, // 一天前的时间
    handleResult: '1',
    status: '2',
    taskNodeName: '来访登记',
    mediResult: '22_00025-1',
    handleContent: '调解成功,双方达成一致意见。',
    operationName: '李晓明'
  },
  {
    handlerUserName: '系统派单',
    finishTime: new Date().getTime() - 12 * 60 * 60 * 1000, // 半天前的时间
    handleResult: '1',
    status: '2',
    taskNodeName: '事件流转',
    mediResult: '22_00025-1',
    handleContent: '派单至:白云区新市街市场监管所',
  },
  {
    handlerUserName: '白云区新市街市场监管所',
    finishTime: new Date().getTime() - 11 * 60 * 60 * 1000, // 半天前的时间
    handleResult: '1',
    status: '2',
    taskNodeName: '事件流转',
    mediResult: '22_00025-1',
    handleContent: '已签收',
    operationName: '赵菲菲'
  },
  {
    handlerUserName: '白云区新市街市场监管所',
    finishTime: new Date().getTime() - 10 * 60 * 60 * 1000, // 半天前的时间
    handleResult: '1',
    status: '3',
    taskNodeName: '事件回退',
    mediResult: '22_00025-1',
    // handleContent: '已签收',
    operationName: '赵菲菲'
  },
  {
    handlerUserName: '白云区新市街综治中心',
    finishTime: new Date().getTime() - 9 * 60 * 60 * 1000, // 半天前的时间
    handleResult: '1',
    status: '2',
    taskNodeName: '回退审核',
    mediResult: '22_00025-1',
    handleContent: '通过',
    operationName: '赵菲菲'
  },
  {
    handlerUserName: '天河区棠下街综治中心',
    finishTime: new Date().getTime() - 6 * 60 * 60 * 1000, // 6小时前的时间
    handleResult: '2',
    status: '1',
    taskNodeName: '事件流转',
    mediResult: '22_00025-1',
    handleContent: '案件已被签收,准备开始调解。',
    operationName: '李晓明'
  },
];
function getListCaseFlow(data) {
    return $$.ax.request({ url: `caseTask/listCaseFlow`, type: 'get', service: 'mediate', data });
}
export default function EventFlow(props) {
  const myButton = [
    {
      label: '受理',
      type: 'primary',
      click: () => { },
      key: 'sl',
    },
    {
      label: '提交',
      type: 'primary',
      click: () => { },
      key: 'tj',
    },
    {
      label: '自行受理',
      type: 'primary',
      click: () => { },
      key: 'zxsl',
    },
    {
      label: '回退',
      type: 'outline',
      click: () => setBackVisible(true),
      key: 'ht',
      status: 'danger'
    },
    {
      label: '交办',
      type: 'outline',
      click: () => setAssignedVisible(true),
      key: 'jb',
    },
    {
      label: '上报',
      type: 'outline',
      click: () => setEscalationVisible(true),
      key: 'sb',
    },
  ]
  const scrollRef = useRef(null)
  const [backVisible, setBackVisible] = useState(false)
  const [height, setHeight] = useState(500)
  const [escalationVisible, setEscalationVisible] = useState(false)
  const [assignedVisible, setAssignedVisible] = useState(false)
  const [staticButtonList, setStaticButtonList] = useState([])
  const [progressData, setProgressData] = useState({})
  useEffect(() => {
    if (props.authorData) {
      const { buttonList } = props.authorData;
      setStaticButtonList(myButton.filter(item => {
        const flag = buttonList.some(result => {
          if (result.id === item.key) {
            return true
          }
        })
        return flag
      }))
    }
  }, [props.authorData])
  useEffect(() => {
    getData()
    onWindowResize()
    window.addEventListener("resize", onWindowResize);
    // 返回一个函数,该函数会在组件卸载前执行
    return () => {
      // 组件销毁时执行
      window.removeEventListener("resize", onWindowResize);
    };
  }, [])
  const onWindowResize = () => {
@@ -96,6 +100,16 @@
    }
    setHeight(getSize().windowH - offsetTop - 16)
  };
  //获取流程信息
  const getData = async () => {
    const res = await getListCaseFlow({
      caseId: props.caseId
    })
    if(res.type) {
      setProgressData(res.data)
    }
  }
  return (
    <Fragment>
@@ -116,7 +130,7 @@
          ref={scrollRef}
          autoHide
        >
          <MatterDetail />
          <MatterDetail caseId={props.caseId}/>
          <div className='dataSync-hasTabPage' style={{ marginTop: '-8px' }}>
            <Tabs defaultActiveTab='1' >
              <TabPane
@@ -127,7 +141,7 @@
                  </span>
                }
              >
                <ProgressStep progressData={fakeData} />
                <ProgressStep progressData={progressData} />
              </TabPane>
              <TabPane
                key='2'
@@ -150,26 +164,22 @@
          visible={backVisible}
          onOk={() => setBackVisible(false)}
          onCancel={() => { setBackVisible(false) }}
          autoFocus={false}
          focusLock={true}
          footer={null}
          unmountOnExit={true}
          maskClosable={false}
        >
          <BackModel />
          <BackModel caseId={props.caseId} onCancel={() => { setBackVisible(false) }}/>
        </Modal>
        <Modal
          title='上报'
          visible={escalationVisible}
          onOk={() => setEscalationVisible(false)}
          onCancel={() => { setEscalationVisible(false) }}
          autoFocus={false}
          focusLock={true}
          footer={null}
          unmountOnExit={true}
          maskClosable={false}
        >
          <EscalationModel />
          <EscalationModel caseId={props.caseId} onCancel={() => { setEscalationVisible(false) }}/>
        </Modal>
        <Modal
          title='交办'
@@ -179,17 +189,17 @@
          footer={null}
          unmountOnExit={true}
          maskClosable={false}
          autoFocus={false}
          focusLock={false}
        >
          <AssignedModel />
          <AssignedModel caseId={props.caseId} onCancel={() => { setAssignedVisible(false) }}/>
        </Modal>
        <div className="dataSync-excel">
          <Space size="large" style={{ margin: '4px 14px' }}>
            <Button type="primary"  >受理</Button>
            <Button type="primary"  >提交</Button>
            <Button type="primary"  >自行受理</Button>
            <Button type='outline' status='danger' onClick={() => setBackVisible(true)}>回退</Button>
            <Button type='outline' onClick={() => setAssignedVisible(true)}>交办</Button>
            <Button type='outline' onClick={() => setEscalationVisible(true)}>上报</Button>
            {staticButtonList?.map(item => {
              const { label, key, click, ...rest } = item;
              return <Button key={key} onClick={click} {...rest} >{label}</Button>
            })}
            <Button type='secondary' >返回上级页面</Button>
          </Space>
        </div>
gz-customerSystem/src/views/register/eventFlow/index.jsx
@@ -7,7 +7,7 @@
 * @Description: 来访登记
 */
import React, { useState, useRef, Fragment } from "react";
import React, { useState, useRef, Fragment, useEffect } from "react";
import NewPage from '@/components/NewPage';
import * as $$ from '@/utils/utility';
import "@arco-themes/react-gzzz/css/arco.css";
@@ -17,33 +17,100 @@
import EventFlow from './component/EventFlow';
import Examine from "./component/Examine";
import ApplyInfo from "../matterDetail/ApplyInfo";
import { useParams } from 'react-router-dom';
const Step = Steps.Step;
const TabPane = Tabs.TabPane;
function getTabButton(data) {
    return $$.ax.request({ url: `caseTask/getTabButton`, type: 'get', service: 'mediate', data });
}
const Organization = () => {
    const [current, setCurrent] = useState(2);
    const [tabsActive, setTabsActive] = useState('1');
    const [tabsList, setTabList] = useState([
const myTab = [
        {
            img: Matter,
            label: '详情',
            key: '1'
        key: 'dslxq',
    },
    {
        img: Matter,
        label: '事项详情',
        key: 'sxxq',
        },
        {
            img: applyRecord,
            label: '申请记录',
            key: '2',
        key: 'sqjl',
        },
        {
            img: examine,
            label: '审核',
            key: '3',
        label: '回退审核',
        key: 'htsh',
        },
    ])
    const [disTab, setDisTab] = useState(true)
    {
        img: examine,
        label: '上报审核',
        key: 'sbsh',
    },
    {
        img: examine,
        label: '结案审核',
        key: 'jash',
    },
    {
        img: examine,
        label: '联合处置申请审核',
        key: 'lhczsh',
    },
]
const Organization = () => {
    const routeData = useParams();
    const [authorData, setAuthorData] = useState({});
    const [tabsList, setTabsList] = useState([]);
    const [tabsActive, setTabsActive] = useState();
    const [disTab, setDisTab] = useState(true);
    useEffect(() => {
        getAuthor()
    }, [])
    //获取权限tab和按钮权限
    const getAuthor = async () => {
        const res = await getTabButton({
            caseTaskId: routeData.caseTaskId
        })
        if (res.type) {
            const { tabList } = res.data
            setAuthorData(res.data)
            if (tabList.length === 0) {
                //没有tab就不展示
                setDisTab(false)
            } else {
                setTabsList(myTab.filter(item => {
                    const flag = tabList.some(result => {
                        if (result.id === item.key) {
                            return true
                        }
                    })
                    return flag
                }))
                setTabsActive(tabList[0].id)
            }
        }
    }
    //根据id定义组件
    const getTypeDom = (key) => {
        if (key === 'dslxq' || key === 'sxxq') {
            return <EventFlow authorData={authorData} caseId={routeData.caseId} />
        }
        if (key === 'sqjl') {
            return <ApplyInfo />
        }
        if (key === 'htsh' || key === 'sbsh' || key === 'jash' || key === 'lhczsh') {
            return <Examine type={key} />
        }
    }
    return (
        <div style={{ position: 'relative' }}>
@@ -53,9 +120,9 @@
                }
            >
                {disTab ? <Tabs
                    defaultActiveTab='1'
                    onChange={(v) => setTabsActive(v)}
                    className='myTabContent'
                    activeTab={tabsActive}
                >
                    {tabsList?.map(item => {
                        return <TabPane
@@ -67,12 +134,10 @@
                                </span>
                            }
                        >
                            {tabsActive === '1' && <EventFlow />}
                            {tabsActive === '2' && <ApplyInfo />}
                            {tabsActive === '3' && <Examine />}
                            {getTypeDom(item.key)}
                        </TabPane>
                    })}
                </Tabs> : <EventFlow />
                </Tabs> : <EventFlow authorData={authorData} />
                }
            </NewPage>
        </div>
gz-customerSystem/src/views/register/matterDetail/index.jsx
@@ -144,10 +144,14 @@
    // 更多数据...
  ];
  useEffect(() => {
    console.log(props);
    getCaseInfo(props.caseId)
  }, [props.caseId])
  //获取id
  const getCaseInfo = async () => {
    const res = await getCaseInfoApi('24083010062110001')
  const getCaseInfo = async (id) => {
    const res = await getCaseInfoApi(id)
    if (res.type) {
      let data = res.data
@@ -160,11 +164,6 @@
    }
  }
  // useEffect(() => {
  //   getCaseInfo()
  // }, [])
  return (
    <div style={{ position: 'relative' }}>