فهرست منبع

【oa审批】新需求删除审批流/关联选项需求

Renxy 2 سال پیش
والد
کامیت
291264751b

+ 2 - 1
src/app.tsx

@@ -80,6 +80,7 @@ export const request: RequestConfig = {
         const errorInfo: any = error.info;
         if (errorInfo) {
           message.error(errorInfo.msg || errorInfo.data);
+          return error.info;
         }
       } else if (error.response) {
         // http错误,校验token是否失效
@@ -109,7 +110,7 @@ export const request: RequestConfig = {
       const resData = res.data;
       const { code, msg, data } = resData;
       if (code !== 200) {
-        const error: any = new Error(msg);
+        let error: any = {};
         error.name = 'AjaxError';
         error.info = { code, msg, data };
         // throw error;

+ 19 - 3
src/components/AuditForm/FormContent.js

@@ -1,5 +1,5 @@
 import { Form } from 'antd';
-import React, { useState } from 'react';
+import React, { useState, useMemo } from 'react';
 import {
   ArrowUpOutlined,
   ArrowDownOutlined,
@@ -9,6 +9,18 @@ import {
 function FormContent(props) {
   const { list, onChange, onSelect } = props;
   const [currentItem, setCurrentItem] = useState(null);
+
+  const linkedList = useMemo(() => {
+    const result = list
+      ?.map((item) => {
+        const linked = item.props.linked;
+        return linked ? Object.values(linked).flat() : [];
+      })
+      .flat();
+    console.log(result);
+    return result;
+  }, [list]);
+
   const handleDelete = (index) => {
     let _list = [...list];
     _list.splice(index, 1);
@@ -59,6 +71,9 @@ function FormContent(props) {
         return (
           <FormItem
             key={item.props?.id}
+            islinked={
+              linkedList?.findIndex((id) => id == item.props?.id) !== -1
+            } //不等于-1表示是被单选框关联的组件需要置灰
             active={index == currentItem}
             onClick={() => handleSelect(index)}
             item={item}
@@ -71,14 +86,15 @@ function FormContent(props) {
 }
 
 function FormItem(props) {
-  const { item, btns, active, onClick } = props;
+  const { item, btns, active, onClick, islinked = false } = props;
   const { label, placeholder, required } = item.props;
   return (
     <div
       style={{
+        backgroundColor: islinked ? '#e4dfdf' : '#fff',
         marginBottom: 20,
         padding: '4px 12px',
-        border: '1px solid #666',
+        border: islinked ? '1px solid #bebcbc' : '1px solid #666',
         borderLeft: active ? '10px solid #1890FF' : '1px solid #666',
       }}
       onClick={onClick}

+ 20 - 7
src/components/AuditForm/ItemAttribute.js

@@ -2,7 +2,7 @@ import { Form, Button, Switch, Input, Radio, Space, Row } from 'antd';
 import React, { useMemo, useState, useEffect } from 'react';
 import { DeleteOutlined } from '@ant-design/icons';
 function ItemAttribute(props) {
-  const { item, onChange } = props;
+  const { item, onChange, onRelClick } = props;
 
   const renderForm = () => {
     let FormContent;
@@ -37,7 +37,7 @@ function ItemAttribute(props) {
         FormContent = <TextareaField {...formProps} />;
         break;
       case 'DDSelectField':
-        FormContent = <DDSelectField {...formProps} />;
+        FormContent = <DDSelectField onRelClick={onRelClick} {...formProps} />;
         break;
       case 'DDMultiSelectField':
         FormContent = <DDMultiSelectField {...formProps} />;
@@ -299,7 +299,7 @@ function TextareaField(props) {
   );
 }
 function DDSelectField(props) {
-  const { item, btns, onFinish } = props;
+  const { item, btns, onFinish, onRelClick } = props;
   const [form] = Form.useForm();
   const handleFinish = (value) => {
     let tempValue = { ...value };
@@ -331,7 +331,7 @@ function DDSelectField(props) {
         <Input />
       </Form.Item>
       <Form.Item label="选项" name="options" wrapperCol={{ span: 24 }}>
-        <SelectItem />
+        <SelectItem onRelClick={onRelClick} />
       </Form.Item>
       <Form.Item label="必填" valuePropName="checked" name="required">
         <Switch />
@@ -383,7 +383,7 @@ function DDMultiSelectField(props) {
 }
 
 function SelectItem(props) {
-  const { value, onChange } = props;
+  const { value, onChange, onRelClick } = props;
   const [localValue, setLocalValue] = useState([]);
   const pushItem = (item) => {
     let tempValue = [
@@ -423,7 +423,7 @@ function SelectItem(props) {
         flexDirection: 'column',
       }}
     >
-      <div>
+      <Space>
         <div
           style={{
             fontSize: 4,
@@ -437,7 +437,20 @@ function SelectItem(props) {
         >
           添加选项
         </div>
-      </div>
+        {onRelClick && (
+          <div
+            style={{
+              fontSize: 4,
+              color: '#40a9ff',
+              cursor: 'pointer',
+              lineHeight: '32px',
+            }}
+            onClick={onRelClick}
+          >
+            选项关联
+          </div>
+        )}
+      </Space>
       <div style={{ minHeight: 20 }}>
         {localValue.map((item, index) => (
           <div

+ 77 - 0
src/components/AuditForm/RelModal.js

@@ -0,0 +1,77 @@
+import { useEffect, useMemo, useState } from 'react';
+import { Modal, Select, Table } from 'antd';
+
+const RelModal = (props) => {
+  const { item, formList = [], visible, onCancel, onChange } = props;
+  // const [linked, setLined] = useState([]);
+  const [data, setData] = useState([]);
+
+  useEffect(() => {
+    let result = [];
+    if (!item) {
+      result = [];
+    } else {
+      const { componentName, props } = item;
+      const selects = formList
+        .filter(
+          (curItem) => curItem.props?.required && curItem.props.id !== props.id,
+        )
+        .map((item) => item.props);
+      result = props.options?.map((cur) => {
+        const linked = props.linked[cur] || [];
+        return { name: cur, selects, linked };
+      });
+    }
+    setData(result);
+  }, [item, formList]);
+
+  const columns = [
+    {
+      title: '当选项为',
+      dataIndex: 'name',
+      key: 'name',
+      width: '30%',
+    },
+    {
+      title: '显示以下控件',
+      render: (record) => (
+        <Select
+          value={record.linked}
+          mode="multiple"
+          placeholder="请选择"
+          style={{ width: '100%' }}
+          onChange={(value) => {
+            const item = { ...record, linked: value };
+            const newData = JSON.parse(JSON.stringify(data));
+            const index = data.findIndex((item) => item.name == record.name);
+            newData[index] = item;
+            setData(newData);
+          }}
+          options={record.selects.map((item) => {
+            return { label: item.label, value: item.id };
+          })}
+        />
+      ),
+    },
+  ];
+  return (
+    <Modal
+      title="单选框-选项关联"
+      open={visible}
+      onCancel={onCancel}
+      onOk={() => {
+        const linked = {};
+        data?.forEach((cur) => {
+          linked[cur.name] = cur.linked;
+        });
+        onChange?.({ linked });
+      }}
+      width={1000}
+      pagination={false}
+    >
+      <div>根据选择的选项,显示其他控件,当前控件和上级选项不能被关联显示</div>
+      <Table dataSource={data} columns={columns}></Table>
+    </Modal>
+  );
+};
+export default RelModal;

+ 15 - 2
src/components/AuditForm/index.js

@@ -1,15 +1,17 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, useMemo } from 'react';
 import FormContent from './FormContent';
 import ComponentLibrary from './ComponentLibrary';
 import ItemAttribute from './ItemAttribute';
 import { uuidv4 } from '@antv/xflow';
 import { Button } from 'antd';
+import RelModal from './RelModal';
 
 function AuditForm(props) {
   const { value, onChange } = props;
   const [formList, setFormList] = useState([]);
   const [select, setSelect] = useState(-1);
   const [visible, setVisible] = useState(false);
+  const [relVisible, setRelVisible] = useState(false); //关联选项弹窗
 
   const handleAddItem = (item) => {
     const formItem = generateItem(item);
@@ -64,6 +66,7 @@ function AuditForm(props) {
         <ItemAttribute
           key={select}
           item={formList[select]}
+          onRelClick={() => setRelVisible(true)}
           onChange={onChangeAttribute}
         ></ItemAttribute>
       </div>
@@ -71,7 +74,17 @@ function AuditForm(props) {
         onOk={handleAddItem}
         visible={visible}
         onCancel={() => setVisible(false)}
-      ></ComponentLibrary>
+      />
+      <RelModal
+        item={formList[select]}
+        formList={formList}
+        visible={relVisible}
+        onCancel={() => setRelVisible(false)}
+        onChange={(value) => {
+          setRelVisible(false);
+          onChangeAttribute(value);
+        }}
+      />
     </div>
   );
 }

+ 28 - 38
src/pages/Flow/components/AuditDetailed.js

@@ -5,35 +5,23 @@ import { Button, Form } from 'antd';
 const AuditDetailed = (props) => {
   // const [form] = Form.useForm();
   const { items, form, onValuesChange } = props;
-
-  const behavior = useMemo(() => {
-    let data = {};
+  const data = useMemo(() => {
+    let linkedData = {};
     items.forEach((d) => {
       const item = d.props;
-      if (item.behaviorLinkage) {
-        const key = item.id;
-        const options = item.options.map((o) => {
-          let data;
-          try {
-            data = JSON.parse(o);
-          } catch (error) {
-            data = { key: o, value: o };
-          }
-          return data;
-        });
-        item.behaviorLinkage.forEach((b) => {
-          const value = b.value;
-          b.targets.forEach((t) => {
-            data[t.fieldId] = {
-              key,
-              value: options.find((o) => o.key == value)?.value,
-            };
-          });
-        });
+      if (item.linked) {
+        linkedData = { ...linkedData, [item.id]: item.linked };
       }
     });
-
-    return data;
+    const linkedList =
+      items
+        ?.map((item) => {
+          const linked = item.props.linked;
+          return linked ? Object.values(linked).flat() : [];
+        })
+        .flat() || [];
+    console.log(linkedData, linkedList);
+    return { linkedData, linkedList };
   }, [items]);
 
   const onFinish = (values) => {
@@ -42,20 +30,22 @@ const AuditDetailed = (props) => {
 
   const GetComponent = (item) => {
     const { id, label, bizAlias, required, notUpper } = item.props;
-    // 判断是否属于关联项
-    if (behavior[id]) {
-      const { key, value } = behavior[id];
-      let currentValue = form.getFieldValue(key);
-      try {
-        currentValue = JSON.parse(currentValue);
-      } catch (error) {}
-      // 判断是否需要渲染
-      if (currentValue instanceof Array) {
-        if (currentValue?.indexOf(value) == -1) return null;
-      } else {
-        if (currentValue != value) return null;
-      }
+    //判断是否关联项
+    if (data.linkedList.findIndex((curId) => curId == id) !== -1) {
+      let control = null; //当前空间是否显示的条件 当id为control.id的组件选择的选项值为control.value 时显示
+      Object.keys(data.linkedData).forEach((ctlIs) => {
+        const linked = data.linkedData[ctlIs];
+        Object.keys(linked).forEach((value) => {
+          const ids = linked[value];
+          if (ids.findIndex((curId) => curId == id) !== -1) {
+            control = { id: ctlIs, value };
+          }
+        });
+      });
+      let currentValue = form.getFieldValue(control?.id);
+      if (currentValue != control?.value) return null;
     }
+
     let formLabel;
     if (bizAlias !== undefined) {
       formLabel = bizAlias;

+ 33 - 2
src/pages/Flow/index.js

@@ -1,13 +1,18 @@
 import React, { useState, useEffect, useRef } from 'react';
-import { Button, Space, Table, message } from 'antd';
+import { Button, Space, Table, message, Modal } from 'antd';
 import { connect, useNavigate } from 'umi';
 import AuditModal from './AuditModal';
 import PageContent from '@/components/PageContent';
-import { queryProcessFlows, saveAuditFlowInfo } from '@/services/boom';
+import {
+  queryProcessFlows,
+  saveAuditFlowInfo,
+  queryFlowDelete,
+} from '@/services/boom';
 
 function Audit(props) {
   const { list = [], classify = [], dispatch, loading } = props;
   let navigate = useNavigate();
+  const [modal, contextHolder] = Modal.useModal();
   const [data, setData] = useState();
   const [visible, setVisible] = useState({
     audit: false,
@@ -44,6 +49,7 @@ function Audit(props) {
           >
             复制
           </a>
+          <a onClick={() => handleDel(item)}>删除</a>
         </Space>
       ),
     },
@@ -55,6 +61,30 @@ function Audit(props) {
     }
   };
 
+  const handleDel = (item) => {
+    console.log(item);
+    modal.confirm({
+      title: '提示',
+      content: `确定删除改审批流【${item.name}】删除后不能复原!`,
+      onOk: async () => {
+        //删除审批流
+        await queryFlowDelete(item.id)
+          .then((data) => {
+            if (data?.code == 200) {
+              message.success('删除成功');
+              dispatch({
+                type: 'flow/queryAuditList',
+                payload: {
+                  flow_type: 1,
+                },
+              });
+            }
+          })
+          .catch((e) => console.log(e));
+      },
+    });
+  };
+
   const handleCopy = async (values) => {
     dispatch({
       type: 'flow/addAudit',
@@ -149,6 +179,7 @@ function Audit(props) {
         onCancel={() => changeVisible('audit', false)}
         classify={classify}
       />
+      {contextHolder}
     </PageContent>
   );
 }

+ 5 - 0
src/services/boom.js

@@ -240,6 +240,11 @@ export async function queryApproval(data) {
   return request(`/api/v2/approval/record?${stringify(data)}`);
 }
 
+//删除审批流
+export async function queryFlowDelete(id) {
+  return request(`/api/v1/oa/flow/delete/${id}`);
+}
+
 // /**
 //   project_id
 //   version_id	大版本id