Kaynağa Gözat

项目编辑

xujunjie 1 yıl önce
ebeveyn
işleme
ef643b493f

+ 2 - 2
package.json

@@ -5,7 +5,7 @@
   "private": true,
   "scripts": {
     "presite": "cd functions && npm install",
-    "start": "cross-env APP_TYPE=site UMI_UI=none umi dev",
+    "start": "cross-env NODE_OPTIONS=--max-old-space-size=8000 APP_TYPE=site UMI_UI=none umi dev",
     "start:no-mock": "cross-env MOCK=none umi dev",
     "build": "umi build",
     "build-prod": "cross-env UMI_ENV=prod umi build umi build",
@@ -124,7 +124,7 @@
     "gh-pages": "^2.0.1",
     "husky": "^1.3.1",
     "jest-puppeteer": "^4.0.0",
-    "less": "^4.1.2",
+    "less": "3.13.1",
     "lint-staged": "^8.1.1",
     "merge-umi-mock-data": "^1.0.4",
     "mockjs": "^1.0.1-beta3",

+ 3 - 0
src/pages/PurchaseAdmin/PurchaseList/Approval/ApprovalModal.js

@@ -35,6 +35,9 @@ function AddModal(props) {
     version: '',
   });
   const [type, setType] = useState({});
+  const [list1, setList1] = useState([]);
+  const [list2, setList2] = useState([]);
+  const [list3, setList3] = useState([]);
   const [addFirmVisible, setAddFirmVisible] = useState(false);
 
   const handleOk = () => {

+ 105 - 26
src/pages/PurchaseAdmin/PurchaseList/Approval/DetailModal.js

@@ -1,5 +1,5 @@
 import React, { useState, useEffect, useMemo, useRef } from 'react';
-import { Button, Form, Modal, Select, Steps, Tabs, TreeSelect, Upload } from 'antd';
+import { Button, Form, Modal, Select, Steps, Tabs, TreeSelect, Upload, message } from 'antd';
 import styles from './DetailModal.less';
 import TableRender from './TableRender';
 import MemberModal from './MemberModal';
@@ -9,6 +9,7 @@ import { async } from '@antv/x6/lib/registry/marker/async';
 import { queryStatusHistory } from '@/services/approval';
 import { UploadOutlined } from '@ant-design/icons';
 import { startExecution, startOperate, startQuality } from '@/services/approval';
+import { connect } from 'dva';
 
 const { Step } = Steps;
 // 新建
@@ -25,6 +26,7 @@ function DetailModal(props) {
     disabled,
     currentUser,
     loading,
+    dispatch,
   } = props;
   const [codes, setCodes] = useState({
     type: '',
@@ -45,10 +47,10 @@ function DetailModal(props) {
       name: data.name,
       version: data.version,
     });
-    setParams({
-      project_status: data?.project_status,
-      // status: data?.status,
-    });
+    // setParams({
+    //   project_status: data?.project_status,
+    //   // status: data?.status,
+    // });
     if (data?.id) initStatueHistory(data.id);
   }, [data, visible]);
 
@@ -138,6 +140,32 @@ function DetailModal(props) {
 
     return { showModifyManager, showEditBtn, showMember, showStatus, showExecution };
   }, [currentUser, data, isEdit]);
+  const manager = useMemo(() => {
+    let manager = {};
+    switch (data.project_status) {
+      case 0:
+        // 售前
+        manager = data.AuditUser || {};
+        manager.DepID = data.author_dep_id;
+        break;
+      case 1:
+        // 执行
+        manager = data.Leader || {};
+        manager.DepID = data.leader_dep_id;
+        break;
+      case 2:
+        // 运营
+        manager = data.OptManager || {};
+        manager.DepID = data.opt_manager_dep_id;
+        break;
+      case 3:
+        // 质保
+        manager = data.WtyManager || {};
+        manager.DepID = data.wty_manager_dep_id;
+        break;
+    }
+    return manager;
+  }, [data]);
   const statusOptions = useMemo(() => {
     if (!data?.id) return [];
     const { showStatus, showExecution } = promise;
@@ -195,30 +223,25 @@ function DetailModal(props) {
     if (!label) return null;
     return (
       <>
-        <Form.Item
-          label={label}
-          name="managerID"
-          rules={[{ required: true, message: `请选择${label}` }]}
-        >
+        <Form.Item label={label} rules={[{ required: true, message: `请选择${label}` }]}>
           <TreeSelect
             showSearch
             allowClear
-            style={{ width: '100%' }}
             placeholder={`请选择${label}`}
             multiple={false}
             filterTreeNode={(input, option) => {
-              return option.props.title === input;
+              return option.props.title.industry(input);
             }}
+            onChange={value => setParams({ ...params, Manager: value })}
             treeData={depUserTree}
           />
         </Form.Item>
         {params.status == 11 && (
-          <Form.Item
-            label="合同状态"
-            name="contractStatus"
-            rules={[{ required: true, message: '请选择合同状态' }]}
-          >
-            <Select style={{ width: '100%' }}>
+          <Form.Item label="合同状态">
+            <Select
+              onChange={value => setParams({ ...params, contractStatus: value })}
+              placeholder="请选择有无合同"
+            >
               <Option key={0}>无合同</Option>
               <Option key={1}>有合同</Option>
             </Select>
@@ -245,13 +268,68 @@ function DetailModal(props) {
   };
 
   const onSave = () => {
+    let type = '';
+    let payload = null;
     if (params.status == 11) {
       // '项目经理'
+      if (!params.Manager) return message.error('请选择项目经理');
+      if (!params.contractStatus) return message.error('请选择有无合同');
+      type = 'approval/startExecution';
+      const [manager_id, dep_id] = params.Manager.split('||');
+      payload = {
+        project_code_id: data.id,
+        with_contract: Number(params.contractStatus),
+        dep_id: Number(dep_id),
+        exe_manager_id: Number(manager_id),
+      };
+      if (params.attach && params.attach.length > 0) {
+        try {
+          payload.attach = JSON.stringify(params.attach);
+        } catch (e) {
+          console.error(e);
+          payload.attach = '';
+        }
+      }
     } else if (params.status == 21) {
       // '运营经理'
+      if (!params.Manager) return message.error('请选择运营经理');
+      type = 'approval/startOperate';
+      const [manager_id, dep_id] = params.Manager.split('||');
+      payload = {
+        project_code_id: data.id,
+        dep_id: Number(dep_id),
+        opt_manager_id: Number(manager_id),
+      };
     } else if (params.status == 31) {
       // '质保经理'
+      type = 'approval/startQuality';
+      const [manager_id, dep_id] = params.Manager.split('||');
+      payload = {
+        project_code_id: data.id,
+        dep_id: Number(dep_id),
+        wty_manager_id: Number(manager_id),
+      };
+    } else {
+      type = 'approval/updateApproval';
+      payload = {
+        ...data,
+        ...params,
+        manager_id: manager.ID,
+      };
+      if (params.attach && params.attach.length > 0) {
+        try {
+          payload.attach = JSON.stringify(params.attach);
+        } catch (e) {
+          console.error(e);
+          payload.attach = '';
+        }
+      }
     }
+    dispatch({
+      type,
+      payload,
+      callback: () => onClose(),
+    });
   };
 
   const uploadProps = {
@@ -264,8 +342,8 @@ function DetailModal(props) {
     // defaultFileList: attachData?.attach_extend,
     onChange({ file, fileList }) {
       if (file.status !== 'uploading') {
-        const data = fileList.map(item => item.response?.data);
-        setParams({ ...params, attach: [...params.attach, data] });
+        const urlList = fileList.map(item => item.response?.data);
+        setParams({ ...params, attach: urlList });
       }
     },
   };
@@ -302,18 +380,19 @@ function DetailModal(props) {
         )}
         <Form.Item className={styles.formItem} label="项目经理">
           {!promise.showModifyManager ? (
-            data.AuthorUser?.CName
+            manager?.CName
           ) : (
             <TreeSelect
-              defaultValue={data.AuthorUser?.CName}
+              // defaultValue={`${manager.ID}||${manager.DepID}`}
+              placeholder={manager.CName || '请选择项目经理'}
               showSearch
               allowClear
               style={{ width: '60%' }}
-              placeholder="请选择项目经理"
               multiple={false}
               filterTreeNode={(input, option) => {
                 return option.props.title === input;
               }}
+              onChange={value => setParams({ ...params, manager_id: Number(value.split('||')[0]) })}
               treeData={depUserTree}
             />
           )}
@@ -339,7 +418,7 @@ function DetailModal(props) {
           </Form.Item>
         )}
         <Form.Item className={styles.formItem} label="项目阶段">
-          {STATUS.find(item => item.value == params?.project_status)?.label}
+          {STATUS.find(item => item.value == data?.project_status)?.label}
         </Form.Item>
         <Form.Item className={styles.formItem} label="现阶段状态">
           {isEdit ? (
@@ -366,7 +445,7 @@ function DetailModal(props) {
           <TableRender onlyShow={true} value={data.process_info} />
         </Form.Item>
         <Form.Item>
-          <Button type="primary" onClick={onSave}>
+          <Button type="primary" loading={loading} onClick={onSave}>
             保存
           </Button>
         </Form.Item>
@@ -428,4 +507,4 @@ function DetailModal(props) {
     </Modal>
   );
 }
-export default DetailModal;
+export default connect(({ loading }) => ({ loading: loading.models.approval }))(DetailModal);

+ 1 - 1
src/pages/PurchaseAdmin/PurchaseList/Approval/DetailModal.less

@@ -12,5 +12,5 @@
 }
 
 .formItem {
-  margin-bottom: 0;
+  margin-bottom: 11px;
 }

+ 39 - 8
src/pages/PurchaseAdmin/PurchaseList/Approval/StatusRender.js

@@ -2,18 +2,49 @@ import { Timeline } from 'antd';
 import styles from './index.less';
 import { STATUS, SUB_STATUS } from './List';
 import moment from 'moment';
+import { useMemo } from 'react';
 
 const StatusRender = ({ statusList }) => {
+  const list = useMemo(() => {
+    return statusList.map(item => {
+      let attach = [];
+      if (item.attach) {
+        try {
+          attach = JSON.parse(item.attach);
+        } catch (e) {
+          console.error(e);
+        }
+        attach = attach
+          .map(item => {
+            if (item instanceof Object) {
+              return (
+                <div>
+                  <a target="_blank" download={item.name} href={item.url}>
+                    {item.name}
+                  </a>
+                </div>
+              );
+            }
+          })
+          .filter(item => item);
+      }
+      return { ...item, attach };
+    });
+  });
   return (
     <Timeline>
-      {statusList?.map(item => (
-        <Timeline.Item dot={<div className={styles.icon}>1</div>}>
-          <div style={{ fontSize: '16px', color: '#1890ff' }}>{`${
-            STATUS.find(cur => cur.value == item.project_status)?.label
-          }-${SUB_STATUS.find(cur => cur.value == item.status)?.label}`}</div>
-          <div>{`持续时间:${item.continuously}    修改人员:${author_name}   修改时间:${moment(
-            item.c_time
-          ).format('YYYY-MM-DD')}`}</div>
+      {list?.map((item, index) => (
+        <Timeline.Item dot={<div className={styles.icon}>{index + 1}</div>}>
+          <div style={{ fontSize: '16px', color: '#1890ff' }}>
+            {STATUS.find(cur => cur.value == item.project_status)?.label}-
+            {SUB_STATUS.find(cur => cur.value == item.status)?.label}
+          </div>
+          <div>
+            持续时间:{item.continuously}
+            &nbsp;&nbsp;&nbsp;&nbsp; 修改人员:{item.author_name}
+            &nbsp;&nbsp;&nbsp;&nbsp; 修改时间:{moment(item.c_time).format('YYYY-MM-DD')}
+          </div>
+          {item.attach.length > 0 && <div>附件: {item.attach}</div>}
         </Timeline.Item>
       ))}
     </Timeline>

+ 2 - 2
src/services/approval.js

@@ -136,6 +136,6 @@ export async function modifyManager(params) {
 }
 
 //历史状态接口
-export async function queryStatusHistory() {
-  return request(`/api/v2/approval/status/history`);
+export async function queryStatusHistory({ id }) {
+  return request(`/api/v2/approval/status/history?id=${id}`);
 }