Prechádzať zdrojové kódy

Merge branch 'develop' of http://120.55.44.4:10080/xujunjie/gt_client_pad into develop

Renxy 1 rok pred
rodič
commit
e7205a806f

+ 26 - 1
.umirc.ts

@@ -236,10 +236,35 @@ export default defineConfig({
     },
     //个人中心
     {
-      name: '',
+      name: '个人中心',
       path: '/center/:projectId',
       component: './Center/index',
     },
+    {
+      name: '我的任务',
+      path: '/center/my-task/:projectId',
+      component: './Center/MyTask',
+    },
+    {
+      name: '我的任务列表',
+      path: '/center/my-task/task-list',
+      component: './Center/MyTask/List/TaskList',
+    },
+    {
+      name: '我的工单列表',
+      path: '/center/my-task/work-order-list',
+      component: './Center/MyTask/List/WorkOrderList',
+    },
+    {
+      name: '我的任务详情',
+      path: '/center/my-task/task-detail',
+      component: './Center/MyTask/Detail/TaskDetail',
+    },
+    {
+      name: '我的工单详情',
+      path: '/center/my-task/work-order-detail',
+      component: './Center/MyTask/Detail/WorkOrderDetail',
+    },
     //智慧运营报告
     {
       name: '',

+ 378 - 0
src/pages/Center/MyTask/Detail/TaskDetail.js

@@ -0,0 +1,378 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
+import {
+  MandateClass,
+  MandateStatus,
+  MandateType,
+  OrderStatus,
+  OrderType,
+} from '@/pages/TaskManage/constent';
+import { getDiagnosticDetail, getMandateDetail } from '@/services/TaskManage';
+import { useLocation } from '@@/exports';
+import { UpOutlined } from '@ant-design/icons';
+import { connect, useRequest } from '@umijs/max';
+import { Col, Collapse, Divider, Row, Table } from 'antd';
+import dayjs from 'dayjs';
+import { useEffect, useState } from 'react';
+// @ts-ignore
+import ReactZmage from 'react-zmage';
+import { useNavigate } from 'umi';
+import styles from './taskDetail.less';
+
+function TaskDetail(props) {
+  const { userList, dispatch } = props;
+
+  const location = useLocation();
+  const queryParams = new URLSearchParams(location.search);
+  const project_id = Number(queryParams.get('project_id'));
+  const mandate_id = Number(queryParams.get('mandate_id'));
+
+  const navigate = useNavigate();
+
+  const [mandateDetail, setMandateDetail] = useState();
+  const [mandateChild, setMandateChild] = useState([]);
+  const [handledWorkOrder, setHandledWorkOrder] = useState([]);
+  const [mandateTable, setMandateTable] = useState([]);
+
+  const columnDef = [
+    {
+      title: '详情',
+      dataIndex: 'detail',
+      key: 'key',
+      render: (value, record) => {
+        return (
+          <div style={{ display: 'flex', alignItems: 'center' }}>
+            <div style={{ width: '100%' }}>{value.text}</div>
+          </div>
+        );
+      },
+    },
+  ];
+
+  const base64ToImageUrl = (base64String) => {
+    const byteCharacters = atob(base64String);
+    const byteArrays = [];
+
+    for (let i = 0; i < byteCharacters.length; i++) {
+      byteArrays.push(byteCharacters.charCodeAt(i));
+    }
+
+    const byteArray = new Uint8Array(byteArrays);
+    const blob = new Blob([byteArray], { type: 'image/png' });
+    return URL.createObjectURL(blob);
+  };
+
+  const { refresh: refreshDetail } = useRequest(getMandateDetail, {
+    defaultParams: [
+      {
+        mandate_id,
+        project_id,
+      },
+    ],
+    formatResult: async (result) => {
+      const tempMandate = {
+        ...result.data,
+        Status: MandateStatus.find((item) => item.value === result.data.Status),
+        MandateClass: MandateClass.find(
+          (item) => item.value === result.data.MandateClass,
+        ),
+        MandateType: MandateType.find(
+          (item) => item.value === result.data.MandateType,
+        ),
+        ResponsiblePeople: userList.find(
+          (item) => item.ID === result.data.ResponsiblePeople,
+        ),
+        CreateTime: dayjs(result.data.CreateTime).format('YYYY-MM-DD HH:mm'),
+      };
+      const workOrder = result.data.Records.map((item) => {
+        return {
+          ...item,
+          CreateTime: dayjs(item.CreateTime).format('YYYY-MM-DD HH:mm'),
+          Status: OrderStatus.find((status) => status.value === item.Status),
+          RecordType: OrderType.find((type) => type.value === item.RecordType),
+          Responsible: userList.find((user) => user.ID === item.Responsible),
+        };
+      });
+      const children = result.data.MandateChild;
+
+      const tempOrder = [
+        {
+          key: '1',
+          label: (
+            <span style={{ color: '#5697e4' }}>
+              关联工单({workOrder.length})
+            </span>
+          ),
+          children: workOrder.map((record) => {
+            return (
+              <div key={record.Id} className={styles.workOrderCard}>
+                <div className={styles.leftInfo}>
+                  <Row style={{ marginBottom: '15px' }}>
+                    <Col className={styles.fontS24} span={12}>
+                      <>
+                        工单类型:
+                        {record.RecordType?.label?.replace('工单', '')}
+                      </>
+                    </Col>
+                    <Col className={styles.fontS24} span={12}>
+                      时间:{record.CreateTime || '-'}
+                    </Col>
+                  </Row>
+                  <Row>
+                    <Col className={styles.fontS24} span={12}>
+                      工单状态:
+                      <span style={{ color: '#5697e4' }}>
+                        {typeof record.Status === 'number'
+                          ? '-'
+                          : record.Status?.label}
+                      </span>
+                    </Col>
+                    <Col className={styles.fontS24} span={12}>
+                      工单负责人:
+                      {typeof record.Responsible === 'number'
+                        ? '-'
+                        : record.Responsible?.CName}
+                    </Col>
+                  </Row>
+                </div>
+                <Divider type="vertical" style={{ height: '40px' }} />
+                <div
+                  className={styles.rightButton}
+                  style={{ color: '#5697e4' }}
+                  onClick={() => {
+                    if (typeof record.RecordType === 'number') {
+                      return;
+                    }
+                    // @ts-ignore
+                    goTaskOrder(
+                      record.Id,
+                      record.RecordType?.value,
+                      tempMandate?.MandateClass.value,
+                    );
+                  }}
+                >
+                  查看工单
+                </div>
+              </div>
+            );
+          }),
+        },
+      ];
+
+      if (
+        tempMandate.MandateClass &&
+        tempMandate.ExtendId &&
+        /* @ts-ignore */
+        tempMandate.MandateClass.value === 7
+      ) {
+        const image = await getDiagnosticDetail(tempMandate.ExtendId);
+        if (image?.event_bg) {
+          tempMandate.img = base64ToImageUrl(image.event_bg);
+        }
+      }
+      setMandateDetail(tempMandate);
+      setHandledWorkOrder(tempOrder);
+      if (children && children.length) {
+        setMandateChild(children);
+      }
+    },
+  });
+
+  useEffect(() => {
+    if (userList.length === 0) {
+      dispatch({
+        type: 'taskUser/fetchUserList',
+        payload: { project_id },
+      });
+    }
+  }, []);
+
+  useEffect(() => {
+    if (!mandateChild.length) {
+      return;
+    }
+
+    if (mandateDetail?.MandateClass?.value === 2) {
+      const dataSource = [];
+      dataSource.push({
+        detail: {
+          text: mandateChild[0].Title,
+          key: 'title',
+        },
+      });
+      dataSource.push(
+        ...Object.entries(JSON.parse(mandateChild[0].Content)).map((item) => {
+          const [key, value] = item;
+          return {
+            detail: {
+              text:
+                value['item_alias'] +
+                ' 现有数值:' +
+                value['old_value'] +
+                ' 建议调整数值' +
+                value['new_value'],
+              key: key,
+            },
+          };
+        }),
+      );
+      setMandateTable(dataSource);
+      return;
+    }
+
+    const dataSource = mandateChild.map((item, index) => {
+      if (item.MandateClass === 2) {
+      }
+
+      return {
+        detail: {
+          text: item.Title + item.Content,
+          key: item.Title + index + item.Content,
+        },
+      };
+    });
+    setMandateTable(dataSource);
+  }, [mandateChild]);
+
+  const goTaskOrder = (orderID, orderType, mandateClass) => {
+    navigate(
+      `/task-manage/list/order-detail?project_id=${project_id}&order_id=${orderID}&order_type=${orderType}&mandate_class=${mandateClass}`,
+    );
+  };
+
+  return (
+    <PageContent closeable={false}>
+      <PageTitle returnable>任务详情</PageTitle>
+      <div className={`${styles.cardContainer} card-box`}>
+        <div className={styles.normalInfo}>
+          <Row className={styles.infoRow} justify="space-between">
+            <Col className={styles.fontS24}>
+              时间:{mandateDetail?.CreateTime}
+            </Col>
+            {/*// @ts-ignore*/}
+            <Col className={styles.fontS24}>
+              {/*//@ts-ignore*/}
+              任务类别:{mandateDetail?.MandateClass?.label}
+            </Col>
+          </Row>
+          <Row justify="space-between">
+            <Col className={styles.fontS24}>
+              {/*//@ts-ignore*/}
+              任务状态:{mandateDetail?.Status?.label}
+            </Col>
+            <Col className={styles.fontS24}>
+              {/*// @ts-ignore*/}
+              任务负责人:{mandateDetail?.ResponsiblePeople?.CName}
+            </Col>
+          </Row>
+        </div>
+        <div className={styles.detailInfo}>
+          <Row className={styles.infoRow}>
+            <Col className={styles.fontS24} span={4}>
+              任务总结
+            </Col>
+            <Col className={styles.fontS24}>
+              {mandateDetail?.Summary ||
+                '根据水质相关数据.建议您调节以下参数,水厂运行可达较优状态'}
+            </Col>
+          </Row>
+          {mandateDetail?.img && (
+            <Row className={styles.infoRow}>
+              <Col className={styles.fontS24} span={4}>
+                预警图片
+              </Col>
+              <Col className={styles.fontS24}>
+                <ReactZmage
+                  controller={{
+                    // 关闭按钮
+                    close: true,
+                    // 缩放按钮
+                    zoom: false,
+                    // 下载按钮
+                    download: false,
+                    // 翻页按钮
+                    flip: false,
+                    // 多页指示
+                    pagination: false,
+                  }}
+                  backdrop="rgba(255,255,255,0.5)"
+                  style={{ width: '350px' }}
+                  src={mandateDetail?.img}
+                />
+              </Col>
+            </Row>
+          )}
+
+          {mandateDetail?.Files.length > 0 && (
+            <Row className={styles.infoRow}>
+              <Col className={styles.fontS24} span={4}>
+                截图
+              </Col>
+              <Col className={styles.fontS24}>
+                <ReactZmage
+                  controller={{
+                    // 关闭按钮
+                    close: true,
+                    // 缩放按钮
+                    zoom: false,
+                    // 下载按钮
+                    download: false,
+                    // 翻页按钮
+                    flip: true,
+                    // 多页指示
+                    pagination: true,
+                  }}
+                  backdrop="rgba(255,255,255,0.5)"
+                  style={{ width: '350px' }}
+                  src={mandateDetail?.Files[0].url}
+                  set={mandateDetail?.Files.map((item) => {
+                    if (item) {
+                      return {
+                        src: item.url,
+                      };
+                    }
+                    return {};
+                  })}
+                />
+              </Col>
+            </Row>
+          )}
+
+          <Row>
+            <Col className={styles.fontS24} span={4}>
+              任务内容
+            </Col>
+            <Col className={styles.fontS24} span={20}>
+              {/*{mandateDetail?.Detail}*/}
+              <Table
+                rowKey="key"
+                columns={columnDef}
+                dataSource={mandateTable}
+                pagination={false}
+              />
+            </Col>
+          </Row>
+        </div>
+        <div className={styles.relatedOrder}>
+          <Collapse
+            className={styles.collapseLabel}
+            ghost
+            expandIcon={({ isActive }) => (
+              <UpOutlined
+                style={{ color: '#5697e4' }}
+                rotate={isActive ? 180 : 0}
+              />
+            )}
+            items={handledWorkOrder}
+          />
+        </div>
+      </div>
+    </PageContent>
+  );
+}
+
+export default connect(({ taskUser }) => {
+  return {
+    userList: taskUser.userList,
+  };
+})(TaskDetail);

+ 431 - 0
src/pages/Center/MyTask/Detail/WorkOrderDetail.js

@@ -0,0 +1,431 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
+import SubTitle from '@/pages/TaskManage/components/SubTitle';
+import { OrderStatus, OrderType } from '@/pages/TaskManage/constent';
+import {
+  getCraftRecordList,
+  getMaintainRecordList,
+  getPatrolMandateRecord,
+  getRepairRecordList,
+  getWorkOrderFlow,
+  queryReagentDetail,
+} from '@/services/TaskManage';
+import { useLocation } from '@@/exports';
+import { connect, useRequest } from '@umijs/max';
+import { Col, Row, Steps } from 'antd';
+import dayjs from 'dayjs';
+import { useEffect, useState } from 'react';
+import 'react-photo-view/dist/react-photo-view.css';
+import styles from './workOrderDetail.less';
+
+import { PhotoProvider, PhotoView } from 'react-photo-view';
+
+const WorkOrderDetail = (props) => {
+  const { userList, dispatch } = props;
+
+  const location = useLocation();
+  const queryParams = new URLSearchParams(location.search);
+  const project_id = Number(queryParams.get('project_id'));
+  const order_id = Number(queryParams.get('order_id'));
+  const order_type = Number(queryParams.get('order_type'));
+  // const mandate_class = Number(queryParams.get('mandate_class'));
+
+  const [orderInfo, setOrderInfo] = useState();
+  const [additionalInfo, setAdditionalInfo] = useState({});
+  const [stepInfo, setStepInfo] = useState();
+
+  // 根据type请求详情
+  const { run: getMaintainDetail } = useRequest(getMaintainRecordList, {
+    manual: true,
+    formatResult: (result) => {
+      const temp = result.data.list[0];
+      const tempDetail = {
+        CreateTime: temp?.CreateTime
+          ? dayjs(temp?.CreateTime).format('YYYY-MM-DD HH:mm')
+          : '-',
+        PlanTime: temp?.PlanTime
+          ? dayjs(temp.PlanTime).format('YYYY-MM-DD HH:mm')
+          : '-',
+        RepairTime: temp?.RepairTime
+          ? dayjs(temp.RepairTime).format('YYYY-MM-DD HH:mm')
+          : '-',
+        Reason: temp.Note,
+        Lubrication: temp.Lubrication,
+        Fasten: temp.Fasten,
+        RustRemoval: temp.RustRemoval,
+        AntiCorrosive: temp.Anticorrosive,
+        Clean: temp.Clean,
+        Check: temp.Check,
+        Repairman:
+          userList.find((item) => item.ID === temp.MaintenancePerson) || '-',
+        DispatchMan:
+          userList.find(
+            (item) => (item.ID = temp.Operators[0]?.Operator?.ID),
+          ) || '-',
+        OrderStatus:
+          OrderStatus.find((item) => item.value === temp.Status) || '-',
+        MandateImages:
+          temp?.mandate_images?.length > 0
+            ? temp.mandate_images.map((item) => {
+                if (item.type === 2) {
+                  return {
+                    src: item.val,
+                  };
+                }
+                return {
+                  src: `data:image/png;base64,${item.val}`,
+                };
+              })
+            : [],
+      };
+      setOrderInfo(tempDetail);
+    },
+  });
+
+  // 根据type请求详情
+  const { run: getRepairDetail } = useRequest(getRepairRecordList, {
+    manual: true,
+    formatResult: (result) => {
+      const temp = result.data.list[0];
+      if (temp === undefined) {
+        return;
+      }
+      const tempDetail = {
+        CreateTime: temp.CreateTime
+          ? dayjs(temp.CreateTime).format('YYYY-MM-DD HH:mm')
+          : '-',
+        PlanTime: temp.PlanTime
+          ? dayjs(temp.PlanTime).format('YYYY-MM-DD HH:mm')
+          : '-',
+        RepairTime: temp.RepairTime
+          ? dayjs(temp.RepairTime).format('YYYY-MM-DD HH:mm')
+          : '-',
+        Reason: temp.Reason,
+        Repairman: userList.find((item) => item.ID === temp.Repairman) || '-',
+        DispatchMan:
+          userList.find((item) => item.ID === temp.operator_id) || '-',
+        OrderStatus:
+          OrderStatus.find((item) => item.value === temp.AcceptanceStatus) ||
+          '-',
+        MandateImages:
+          temp?.mandate_images?.length > 0
+            ? temp.mandate_images.map((item) => {
+                console.log(item);
+                if (item.type === 2) {
+                  return {
+                    src: item.val,
+                  };
+                }
+                return {
+                  src: `data:image/png;base64,${item.val}`,
+                };
+              })
+            : [],
+      };
+      setOrderInfo(tempDetail);
+    },
+  });
+
+  // 根据type请求详情
+  const { run: getCraftDetail } = useRequest(getCraftRecordList, {
+    manual: true,
+    formatResult: (result) => {
+      const temp = result.data.list[0];
+      const tempDetail = {
+        CreateTime: dayjs(temp.start_time).format('YYYY-MM-DD HH:mm'),
+        PlanTime: dayjs(temp.plan_end_time).format('YYYY-MM-DD HH:mm'),
+        RepairTime:
+          (temp.actual_end_time &&
+            dayjs(temp.actual_end_time).format('YYYY-MM-DD HH:mm')) ||
+          '-',
+        Reason: temp.detail,
+        Repairman: userList.find((item) => item.ID === temp.checker_id) || '-',
+        DispatchMan:
+          userList.find((item) => item.ID === temp.operator_id) || '-',
+        OrderStatus:
+          OrderStatus.find((item) => item.value === temp.status) || '-',
+        MandateImages:
+          temp?.mandate_images?.length > 0
+            ? temp.mandate_images.map((item) => {
+                console.log(item);
+                if (item.type === 2) {
+                  return {
+                    src: item.val,
+                  };
+                }
+                return {
+                  src: `data:image/png;base64,${item.val}`,
+                };
+              })
+            : [],
+      };
+
+      setOrderInfo(tempDetail);
+    },
+  });
+
+  const { run: getDosingOrder } = useRequest(queryReagentDetail, {
+    manual: true,
+    formatResult: (result) => {
+      const temp = {
+        ...result,
+        CreateTime: result?.start_time?.Valid
+          ? dayjs(result?.start_time?.Time).format('YYYY-MM-DD HH:mm')
+          : '-',
+        PlanTime: result?.plan_end_time?.Valid
+          ? dayjs(result.plan_end_time.Time).format('YYYY-MM-DD HH:mm')
+          : '-',
+        RepairTime: result?.actual_end_time?.Valid
+          ? dayjs(result.actual_end_time.Time).format('YYYY-MM-DD HH:mm')
+          : '-',
+        Reason: result.note,
+        Repairman: '-',
+        DispatchMan:
+          userList.find((user) => user.ID === result.operator_id) || '-',
+        OrderStatus:
+          OrderStatus.find((status) => status.value === result.status) || '-',
+      };
+      setOrderInfo(temp);
+      setAdditionalInfo(temp);
+    },
+  });
+
+  const { run: getPatrolOrderList } = useRequest(getPatrolMandateRecord, {
+    manual: true,
+    formatResult: (result) => {
+      if (result?.data?.list) {
+        const temp = result.data.list[0];
+        const tempDetail = {
+          ...temp,
+          CreateTime: temp?.CreatedTime
+            ? dayjs(temp.CreatedTime).format('YYYY-MM-DD HH:mm')
+            : '-',
+          PlanTime: temp.plan_end_time
+            ? dayjs(temp.plan_end_time).format('YYYY-MM-DD HH:mm')
+            : '-',
+          RepairTime: temp?.actual_end_time
+            ? dayjs(temp.actual_end_time).format('YYYY-MM-DD HH:mm')
+            : '-',
+          Reason: temp.detail,
+          Repairman: '-',
+          DispatchMan:
+            userList.find((user) => user.ID === temp.operator_id) || '-',
+          OrderStatus:
+            OrderStatus.find((status) => status.value === temp.status) || '-',
+        };
+        setOrderInfo(tempDetail);
+      }
+    },
+  });
+
+  // 获取工单流程信息
+  useRequest(getWorkOrderFlow, {
+    // manual: true,
+    defaultParams: [{ work_type: order_type, work_id: order_id }],
+    formatResult(res) {
+      if (res && res?.length) {
+        setStepInfo(res);
+      }
+    },
+  });
+
+  useEffect(() => {
+    if (userList.length === 0) {
+      dispatch({
+        type: 'taskUser/fetchUserList',
+        payload: { project_id },
+      });
+    }
+    switch (order_type) {
+      // 工艺
+      case 1:
+      case 6:
+        getCraftDetail({ project_id, work_id: order_id });
+        break;
+      // 维修
+      case 2:
+        getRepairDetail({ project_id, id: order_id });
+        break;
+      // 保养
+      case 3:
+        getMaintainDetail({ project_id, id: order_id });
+        break;
+      // 巡检
+      case 4:
+        getPatrolOrderList({ project_id, id: order_id });
+        break;
+      // 加药
+      case 5:
+        getDosingOrder({ id: order_id });
+        break;
+    }
+  }, []);
+
+  const renderImg = () => {
+    return (
+      <PhotoProvider>
+        <Col className={styles.fontS28} span={18}>
+          {orderInfo?.MandateImages?.map((photo, index) => (
+            <PhotoView key={index} src={photo.src}>
+              <img
+                style={{
+                  maxWidth: `${Math.floor(
+                    100 / (orderInfo?.MandateImages?.length || 1),
+                  )}%`,
+                }}
+                src={photo.src}
+                alt=""
+              />
+            </PhotoView>
+          ))}
+        </Col>
+      </PhotoProvider>
+    );
+  };
+
+  return (
+    <PageContent closeable={false}>
+      <PageTitle returnable>工单详情</PageTitle>
+      <div className={styles.selfCardBox}>
+        <div className={styles.orderInfo}>
+          <SubTitle
+            title="工单信息"
+            // @ts-ignore
+            showStatus={orderInfo?.OrderStatus.value === 2}
+            radius
+          />
+          <div style={{ padding: '15px', letterSpacing: '1.5px' }}>
+            <Row className={styles.rowMargin}>
+              <Col className={styles.fontS28} span={15}>
+                {/* @ts-ignore */}
+                工单类型:
+                {OrderType.find((item) => item.value === order_type)?.label ||
+                  '-'}
+              </Col>
+              <Col className={styles.fontS28} span={9}>
+                {/* @ts-ignore */}
+                工单负责人:{orderInfo?.Repairman?.CName || '-'}
+              </Col>
+            </Row>
+            <Row className={styles.rowMargin}>
+              <Col className={styles.fontS28} span={15}>
+                {/*  @ts-ignore */}
+                工单状态:{orderInfo?.OrderStatus?.label}
+              </Col>
+              <Col className={styles.fontS28} span={9}>
+                {/* @ts-ignore */}
+                派单人员:{orderInfo?.DispatchMan?.CName || '-'}
+              </Col>
+            </Row>
+            <Row className={styles.rowMargin}>
+              <Col className={styles.fontS28}>
+                派单时间:{orderInfo?.CreateTime || '-'}
+              </Col>
+            </Row>
+            <Row className={styles.rowMargin}>
+              <Col className={styles.fontS28}>
+                计划完成时间:{orderInfo?.PlanTime || '-'}
+              </Col>
+            </Row>
+            <Row className={styles.rowMargin}>
+              <Col className={styles.fontS28}>
+                实际完成时间:{orderInfo?.RepairTime || '-'}
+              </Col>
+            </Row>
+            <Row>
+              <Col className={styles.fontS28}>工单详情:</Col>
+              <Col className={styles.fontS28} span={18}>
+                {orderInfo?.Reason}
+              </Col>
+            </Row>
+
+            {/* @ts-ignore */}
+            {orderInfo?.MandateImages?.length > 0 && (
+              <Row className={styles.rowMarginTop}>
+                <Col className={styles.fontS28}>任务图片:</Col>
+                {renderImg()}
+              </Row>
+            )}
+          </div>
+        </div>
+        {order_type === 3 && (
+          <div>
+            <SubTitle title="维修内容" />
+            <div style={{ padding: '15px' }}>
+              <Row className={styles.rowMargin} justify={'space-around'}>
+                <Col className={styles.fontS28} span={8}>
+                  是否润滑/加油:{orderInfo?.Lubrication === 1 ? '是' : '否'}
+                </Col>
+                <Col className={styles.fontS28} span={8}>
+                  是否拆检:{orderInfo?.Check === 1 ? '是' : '否'}
+                </Col>
+                <Col className={styles.fontS28} span={8}>
+                  是否清洁:{orderInfo?.Clean === 1 ? '是' : '否'}
+                </Col>
+              </Row>
+              <Row justify={'space-around'}>
+                <Col className={styles.fontS28} span={8}>
+                  是否紧固:{orderInfo?.Fasten === 1 ? '是' : '否'}
+                </Col>
+                <Col className={styles.fontS28} span={8}>
+                  是否除锈:{orderInfo?.AntiCorrosive === 1 ? '是' : '否'}
+                </Col>
+                <Col className={styles.fontS28} span={8}>
+                  是否防腐:{orderInfo?.RustRemoval === 1 ? '是' : '否'}
+                </Col>
+              </Row>
+            </div>
+          </div>
+        )}
+
+        {order_type === 5 && (
+          <div>
+            <SubTitle title="加药详情" />
+            <div style={{ padding: '15px' }}>
+              <Row>
+                <Col className={styles.fontS28} span={8}>
+                  药剂名称:{additionalInfo?.name || '-'}
+                </Col>
+                <Col className={styles.fontS28} span={8}>
+                  加药量:{additionalInfo?.dosage || '-'}升
+                </Col>
+                <Col className={styles.fontS28} span={8}>
+                  浓度:{additionalInfo?.concentration || '-'}
+                </Col>
+              </Row>
+            </div>
+          </div>
+        )}
+        {/* @ts-ignore */}
+        {stepInfo?.length > 0 && (
+          <div>
+            <SubTitle title="工单流程" />
+            <div style={{ padding: '15px 20px' }}>
+              <Steps
+                direction="vertical"
+                current={stepInfo?.length ? stepInfo.length - 1 : 0}
+                progressDot
+                items={stepInfo?.map((item) => {
+                  return {
+                    title: (
+                      <span className={styles.fontS28}>{item.content}</span>
+                    ),
+                    description: (
+                      <span className={styles.fontS24}>{item.time}</span>
+                    ),
+                  };
+                })}
+              />
+            </div>
+          </div>
+        )}
+      </div>
+    </PageContent>
+  );
+};
+
+export default connect(({ taskUser }) => {
+  return {
+    userList: taskUser.userList,
+  };
+})(WorkOrderDetail);

+ 125 - 0
src/pages/Center/MyTask/Detail/taskDetail.less

@@ -0,0 +1,125 @@
+.cardContainer {
+  margin-top: 15px;
+  padding: 20px 20px;
+  background-color: white;
+
+  .normalInfo {
+    padding: 25px 15px;
+    background-color: #fdf2df;
+  }
+
+  .infoRow {
+    margin-bottom: 25px;
+  }
+
+  .detailInfo {
+    padding: 25px 15px;
+    border-bottom: 1px solid rgba(0, 0, 0, 10%);
+  }
+
+  .relatedOrder {
+    padding: 0 15px;
+    margin-top: 15px;
+
+    .collapseLabel {
+      width: 100%;
+
+      .ant-collapse-arrow {
+        font-size: 24px;
+      }
+
+      :global {
+        .ant-collapse-item {
+          margin-bottom: 0;
+        }
+
+        .ant-collapse-header {
+          justify-content: center;
+          flex-direction: row-reverse;
+          align-items: center;
+          margin-top: 10px;
+
+          .ant-collapse-header-text {
+            font-size: 24px;
+            flex: unset;
+            margin-inline-end: unset;
+          }
+
+          .ant-collapse-arrow {
+            font-size: 24px;
+          }
+        }
+      }
+
+      .workOrderCard {
+        margin-bottom: 20px;
+        padding: 20px 10px;
+        border-radius: 8px;
+        background-color: #e5effa;
+        display: flex;
+        align-items: center;
+
+        .leftInfo {
+          width: 80%;
+        }
+
+        .rightButton {
+          flex: auto;
+          color: #5697e4;
+          font-size: 24px;
+          text-align: center;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+        }
+      }
+    }
+  }
+
+  .workOrderCard {
+    margin-bottom: 25px;
+    padding: 20px 10px;
+    border-radius: 8px;
+    background-color: #e5effa;
+    display: flex;
+    align-items: center;
+
+    .leftInfo {
+      width: 80%;
+    }
+
+    .rightButton {
+      flex: auto;
+      color: #5697e4;
+      font-size: 24px;
+      text-align: center;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+    }
+  }
+}
+
+.fontS28 {
+  font-size: 28px;
+}
+
+.fontS24 {
+  font-size: 24px;
+}
+
+.fontS22 {
+  font-size: 22px;
+}
+
+.fontS20 {
+  font-size: 20px;
+}
+
+.fontS18 {
+  font-size: 18px;
+}
+
+.fontS16 {
+  font-size: 16px;
+}

+ 47 - 0
src/pages/Center/MyTask/Detail/workOrderDetail.less

@@ -0,0 +1,47 @@
+.selfCardBox {
+  margin-top: 15px;
+  border-radius: 8px;
+  box-shadow: 2px 0 8px 0 rgba(0, 0, 0, 30%);
+  background-color: white;
+}
+
+.orderInfo {
+  border: 0;
+  margin: 0;
+}
+
+.rowMargin {
+  margin-bottom: 30px;
+}
+
+.rowMarginTop {
+  margin-top: 30px;
+}
+
+.fontS28 {
+  font-size: 28px;
+}
+
+.fontS26 {
+  font-size: 26px;
+}
+
+.fontS24 {
+  font-size: 24px;
+}
+
+.fontS22 {
+  font-size: 22px;
+}
+
+.fontS20 {
+  font-size: 20px;
+}
+
+.fontS18 {
+  font-size: 18px;
+}
+
+.fontS16 {
+  font-size: 16px;
+}

+ 308 - 0
src/pages/Center/MyTask/List/TaskList.js

@@ -0,0 +1,308 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
+import ScrollLoading from '@/components/ScrollLoading';
+import TopFilter from '@/pages/TaskManage/components/TopFilter';
+import {
+  MandateClass,
+  MandateStatus,
+  MandateType,
+  OrderStatus,
+  OrderType,
+} from '@/pages/TaskManage/constent';
+import { getMandateList } from '@/services/TaskManage';
+import { DownOutlined } from '@ant-design/icons';
+import { connect, useLocation, useNavigate, useRequest } from '@umijs/max';
+import { Col, Collapse, Divider, List, Row } from 'antd';
+import dayjs from 'dayjs';
+import { useEffect, useState } from 'react';
+import styles from './taskList.less';
+
+const MyTaskList = (props) => {
+  const { userList, loading, dispatch } = props;
+
+  const location = useLocation();
+
+  const queryParams = new URLSearchParams(location.search);
+  const project_id = Number(queryParams.get('project_id'));
+  const mandateType = Number(queryParams.get('mandateType'));
+  const userID = queryParams.get('user_id');
+
+  const navigate = useNavigate();
+
+  const [currentParams, setCurrentParams] = useState({
+    project_id,
+    mandate_type: mandateType,
+    pageSize: 20,
+    currentPage: 1,
+    responsible_people: userID !== null ? Number(userID) : '',
+  });
+  const [pagination, setPagination] = useState({
+    current: 1,
+    total: 0,
+    pageSize: 20,
+  });
+  const [topFiltersConfig, setTopFiltersConfig] = useState([]);
+  const [mandateList, setMandateList] = useState([]);
+
+  // 获取用户
+  useEffect(() => {
+    if (userList.length === 0) {
+      dispatch({
+        type: 'taskUser/fetchUserList',
+        payload: { project_id },
+      });
+    }
+  }, []);
+
+  // 配置顶部下拉过滤器
+  useEffect(() => {
+    const filters = [];
+    filters.push({
+      key: 'mandate_class',
+      placeholder: '任务类别',
+      // @ts-ignore
+      options: MandateClass.map((item) => {
+        if (item.MandateType === mandateType) {
+          return {
+            value: item.value,
+            label: item.label,
+            key: item.value + '任务类别',
+          };
+        }
+        return undefined;
+      }).filter((item) => item),
+    });
+
+    filters.push({
+      key: 'status',
+      placeholder: '任务状态',
+      options: MandateStatus.map((item) => {
+        return {
+          ...item,
+        };
+      }),
+    });
+
+    setTopFiltersConfig(filters);
+  }, [mandateType]);
+
+  const { run: getList, loading: loadData } = useRequest(getMandateList, {
+    defaultParams: [currentParams],
+    formatResult: (result) => {
+      const pageInfo = result.data.pagination;
+      if (result.data.pagination.current === 1) {
+        setMandateList(result.data.list);
+      } else {
+        if (mandateList.length < pageInfo.total) {
+          setMandateList([...mandateList, ...result.data.list]);
+        }
+      }
+      setPagination(pageInfo);
+    },
+  });
+
+  const onTopFilterChange = (value) => {
+    if (topFiltersConfig.length === 0) {
+      return;
+    }
+    const params = {
+      project_id,
+      mandate_type: mandateType,
+      pageSize: 20,
+      currentPage: 1,
+    };
+
+    if (userID !== null) {
+      params.responsible_people = Number(userID);
+    }
+
+    for (let i = 0; i < value.length; i++) {
+      if (value[i] !== null && topFiltersConfig[i] !== undefined) {
+        params[topFiltersConfig[i].key] = value[i];
+      }
+    }
+    setCurrentParams(params);
+    getList(params);
+  };
+
+  const goMyTaskDetail = (mandate) => {
+    navigate(
+      `/center/my-task/task-detail?project_id=${project_id}&mandate_id=${mandate.Id}`,
+    );
+  };
+
+  const goMyWorkOrder = (orderID, orderType, mandateClass) => {
+    if (orderType === undefined) {
+      return;
+    }
+    navigate(
+      `/center/my-task/work-order-detail?project_id=${project_id}&order_id=${orderID}&order_type=${orderType}&mandate_class=${mandateClass}`,
+    );
+  };
+
+  const buildTaskList = (item) => {
+    const formatItem = {
+      ...item,
+      Status: MandateStatus.find((status) => status.value === item.Status),
+      MandateType: MandateType.find((type) => type.value === item.MandateType),
+      MandateClass: MandateClass.find(
+        (itemClass) => itemClass.value === item.MandateClass,
+      ),
+      ResponsiblePeople: userList.find(
+        (user) => user.ID === item.ResponsiblePeople,
+      ),
+      CreateTime: dayjs(item.CreateTime).format('YYYY-MM-DD HH:mm'),
+    };
+
+    const workOrder = item.Records.map((record) => {
+      return {
+        ...record,
+        key: record.Id,
+        Status: OrderStatus.find((status) => status.value === record.Status),
+        RecordType: OrderType.find((type) => type.value === record.RecordType),
+        Responsible: userList.find((user) => user.ID === record.Responsible),
+        CreateTime: dayjs(record.CreateTime).format('YYYY-MM-DD HH:mm'),
+      };
+    });
+
+    const collapseData = [
+      {
+        key: '1',
+        label: (
+          <span style={{ color: '#5697e4' }}>关联工单({workOrder.length})</span>
+        ),
+        children: workOrder.map((order) => {
+          return (
+            <div key={order.Id} className={styles.workOrderCard}>
+              <div className={styles.leftInfo}>
+                <Row style={{ marginBottom: '15px' }}>
+                  <Col className={styles.fontS24} span={12}>
+                    工单类型:{order.RecordType?.label || '-'}
+                  </Col>
+                  <Col className={styles.fontS24} span={12}>
+                    时间:{order.CreateTime}
+                  </Col>
+                </Row>
+                <Row>
+                  <Col className={styles.fontS24} span={12}>
+                    工单状态:
+                    <span style={{ color: '#5697e4' }}>
+                      {order.Status?.label}
+                    </span>
+                  </Col>
+                  <Col className={styles.fontS24} span={12}>
+                    工单负责人:{order.Responsible?.CName}
+                  </Col>
+                </Row>
+              </div>
+              <Divider type="vertical" style={{ height: '40px' }} />
+              <div
+                className={styles.rightButton}
+                style={{ color: '#5697e4' }}
+                onClick={() => {
+                  goMyWorkOrder(
+                    order.Id,
+                    order.RecordType?.value,
+                    item.MandateClass,
+                  );
+                }}
+              >
+                查看工单
+              </div>
+            </div>
+          );
+        }),
+      },
+    ];
+
+    return (
+      <List.Item style={{ borderBottom: '0' }}>
+        <div className={`${styles.cardContainer} card-box`}>
+          <Row justify="space-between" style={{ marginBottom: '20px' }}>
+            <Col className={styles.fontS24}>时间:{formatItem.CreateTime}</Col>
+            <Col className={styles.fontS24}>
+              任务类别:{formatItem.MandateClass?.label}
+            </Col>
+            <Col className={styles.fontS24}>
+              任务负责人:{formatItem.ResponsiblePeople?.CName || '-'}
+            </Col>
+          </Row>
+          <Row
+            justify="space-between"
+            style={{
+              paddingBottom: '10px',
+              borderBottom: '1px solid #D5D5D5',
+            }}
+          >
+            <Col className={styles.fontS24}>
+              任务状态:{formatItem.Status?.label || '-'}
+            </Col>
+            <Col>
+              <div
+                className={styles.fontS24}
+                style={{
+                  backgroundColor: '#f5a623',
+                  color: 'white',
+                  width: '150px',
+                  height: '50px',
+                  display: 'flex',
+                  justifyContent: 'center',
+                  alignItems: 'center',
+                }}
+                onClick={() => {
+                  goMyTaskDetail(item);
+                }}
+              >
+                任务详情
+              </div>
+            </Col>
+          </Row>
+          <Row>
+            <Collapse
+              className={styles.collapseLabel}
+              ghost
+              expandIcon={({ isActive }) => (
+                <DownOutlined
+                  style={{ color: '#5697e4' }}
+                  rotate={isActive ? 180 : 0}
+                />
+              )}
+              items={collapseData}
+            />
+          </Row>
+        </div>
+      </List.Item>
+    );
+  };
+
+  return (
+    <PageContent closeable={false}>
+      <PageTitle returnable>
+        {MandateType.find((item) => item.value === mandateType)?.label}
+      </PageTitle>
+      <TopFilter filters={topFiltersConfig} onChange={onTopFilterChange} />
+
+      <ScrollLoading
+        height={180}
+        loading={loading || loadData}
+        pagination={pagination}
+        handleLoadData={(current) => {
+          getList({ ...currentParams, currentPage: current });
+        }}
+      >
+        <List
+          itemLayout="horizontal"
+          dataSource={mandateList}
+          renderItem={buildTaskList}
+        />
+      </ScrollLoading>
+    </PageContent>
+  );
+};
+
+export default connect(({ taskUser, loading }) => {
+  return {
+    userList: taskUser.userList,
+    loading: loading.models['taskUser'],
+  };
+})(MyTaskList);

+ 162 - 0
src/pages/Center/MyTask/List/WorkOrderList.js

@@ -0,0 +1,162 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
+import { OrderStatus, OrderType } from '@/pages/TaskManage/constent';
+import { getUserWorkOrderList } from '@/services/TaskManage';
+import { connect, useLocation, useNavigate, useRequest } from '@umijs/max';
+import { Button, Col, Empty, Row, Tabs } from 'antd';
+import dayjs from 'dayjs';
+import { useEffect, useState } from 'react';
+import styles from './WorkOrderList.less';
+
+const { TabPane } = Tabs;
+
+const WorkOrderList = (props) => {
+  const { userList, dispatch } = props;
+  const location = useLocation();
+  const queryParams = new URLSearchParams(location.search);
+  const project_id = Number(queryParams.get('project_id'));
+  const order_type = Number(queryParams.get('order_type'));
+  const userID = queryParams.get('user_id');
+
+  const navigate = useNavigate();
+
+  // 请求用户列表
+  useEffect(() => {
+    if (userList.length === 0) {
+      dispatch({
+        type: 'taskUser/fetchUserList',
+        payload: { project_id },
+      });
+    }
+  }, []);
+
+  const [activedStatus, setActivedStatus] = useState();
+
+  const [workOrderList, setWorkOrderList] = useState(null);
+
+  const goWorkOrderDetail = (order) => {
+    const orderID = order.id || order.Id;
+    navigate(
+      `/center/my-task/work-order-detail?project_id=${project_id}&order_id=${orderID}&order_type=${order_type}`,
+    );
+  };
+
+  const renderTabPannal = (list) => {
+    if (list?.length === 0) {
+      setWorkOrderList(<Empty />);
+      return;
+    }
+    const tempNode = list.map((workOrder) => {
+      return (
+        <div
+          key={workOrder.id || workOrder.Id}
+          className={styles.workOrderCard}
+        >
+          <Row justify="space-between" style={{ marginBottom: '20px' }}>
+            <Col className={styles.fontS24}>{workOrder?.CreateTime}</Col>
+            <Col className={styles.fontS24}>
+              工单负责人:{workOrder?.Repairman?.CName || '-'}
+            </Col>
+          </Row>
+          <Row justify="space-between">
+            <Col className={styles.fontS24}>
+              工单状态:{workOrder?.OrderStatus?.label}
+            </Col>
+            <Col className={styles.detailBtnContainer}>
+              <Button
+                type="primary"
+                style={{ height: '40px', fontSize: '24px' }}
+                onClick={() => goWorkOrderDetail(workOrder)}
+              >
+                工单详情
+              </Button>
+            </Col>
+          </Row>
+        </div>
+      );
+    });
+    setWorkOrderList(tempNode);
+  };
+
+  const formatCreateTime = (order) => {
+    if (order_type === 1 || order_type === 6 || order_type === 7) {
+      if (order?.start_time) {
+        return dayjs(order.start_time).format('YYYY-MM-DD HH:mm');
+      }
+    } else if (order_type === 2 || order_type === 3) {
+      if (order?.CreateTime) {
+        return dayjs(order.CreateTime).format('YYYY-MM-DD HH:mm');
+      }
+    } else if (order_type === 5) {
+      if (order?.start_time?.Valid) {
+        return dayjs(order.start_time.Time).format('YYYY-MM-DD HH:mm');
+      }
+    }
+    return '-';
+  };
+
+  const { run: getWorkOrderList } = useRequest(
+    (status) => {
+      return getUserWorkOrderList({
+        project_id,
+        work_type: order_type,
+        status: status || 0,
+        user_id: Number(userID),
+      });
+    },
+    {
+      throwOnError: true,
+      formatResult: (result) => {
+        if (result) {
+          const temp = result.map((item) => {
+            return {
+              ...item,
+              CreateTime: item.CreateTime
+                ? dayjs(item.CreateTime).format('YYYY-MM-DD HH:mm')
+                : '-',
+              Repairman: userList.find((user) => item.Responsible === user.ID),
+              OrderStatus: OrderStatus.find(
+                (status) => status.value === item.Status,
+              ),
+            };
+          });
+          renderTabPannal(temp);
+        }
+      },
+    },
+  );
+
+  const onTabChange = (key) => {
+    setActivedStatus(key);
+    getWorkOrderList(Number(key));
+  };
+
+  return (
+    <PageContent closeable={false}>
+      <PageTitle returnable>
+        {OrderType.find((item) => item.value === order_type)?.label || ''}
+      </PageTitle>
+      <Tabs
+        size="large"
+        activeKey={activedStatus}
+        defaultActiveKey={String(OrderStatus[0].value)}
+        className={styles.identifyTab}
+        onChange={onTabChange}
+      >
+        {OrderStatus.map((item) => {
+          return (
+            <TabPane tab={item.label} key={String(item.value)}>
+              {workOrderList}
+            </TabPane>
+          );
+        })}
+      </Tabs>
+    </PageContent>
+  );
+};
+
+export default connect(({ taskUser }) => {
+  return {
+    userList: taskUser.userList,
+  };
+})(WorkOrderList);

+ 26 - 0
src/pages/Center/MyTask/List/WorkOrderList.less

@@ -0,0 +1,26 @@
+.identifyTab :global {
+  .ant-tabs-nav-list {
+    justify-content: space-around;
+    width: 100%;
+    .ant-tabs-tab-btn {
+      font-size: 24px;
+    }
+  }
+}
+
+.workOrderCard {
+  padding: 20px;
+  margin-bottom: 10px;
+  border-radius: 10px;
+  box-shadow: 0px 0px 8px 2px rgba(191, 191, 191, 0.2);
+}
+
+.detailBtnContainer {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.fontS24 {
+  font-size: 24px;
+}

+ 90 - 0
src/pages/Center/MyTask/List/taskList.less

@@ -0,0 +1,90 @@
+.cardContainer {
+  width: 100%;
+  padding: 20px 20px 10px 20px;
+  background-color: white;
+
+  .collapseLabel {
+    width: 100%;
+    .ant-collapse-arrow {
+      font-size: 24px;
+    }
+    :global {
+      .ant-collapse-item {
+        margin-bottom: 0;
+      }
+      .ant-collapse-header {
+        justify-content: center;
+        flex-direction: row-reverse;
+        align-items: center;
+        margin-top: 10px;
+
+        .ant-collapse-header-text {
+          font-size: 24px;
+          flex: unset;
+          margin-inline-end: unset;
+        }
+        .ant-collapse-arrow {
+          font-size: 24px;
+        }
+      }
+    }
+
+    .workOrderCard {
+      margin-bottom: 20px;
+      padding: 20px 10px;
+      border-radius: 8px;
+      background-color: #e5effa;
+      display: flex;
+      align-items: center;
+
+      .leftInfo {
+        width: 80%;
+      }
+
+      .rightButton {
+        flex: auto;
+        color: #5697e4;
+        font-size: 24px;
+        text-align: center;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+  }
+}
+
+.topContainer {
+  // height: 120px;
+  .fixedTop {
+    position: fixed;
+    top: 0;
+    width: 100%;
+    z-index: 10;
+    background-color: #ffffff;
+  }
+}
+
+.fontS28 {
+  font-size: 28px;
+}
+
+.fontS26 {
+  font-size: 26px;
+}
+
+.fontS24 {
+  font-size: 24px;
+}
+
+.fontS20 {
+  font-size: 20px;
+}
+
+.fontS18 {
+  font-size: 18px;
+}
+
+.fontS16 {
+  font-size: 16px;
+}

+ 164 - 0
src/pages/Center/MyTask/index.js

@@ -0,0 +1,164 @@
+import PageContent from '@/components/PageContent';
+import TabsContent from '@/components/TabsContent';
+import { MandateType, OrderType } from '@/pages/TaskManage/constent';
+import { getMandateList } from '@/services/TaskManage';
+import { RightOutlined } from '@ant-design/icons';
+import { useLocation, useNavigate, useParams } from '@umijs/max';
+import { List, Spin } from 'antd';
+import { useEffect, useState } from 'react';
+import styles from './index.less';
+
+const MyTask = () => {
+  const { projectId } = useParams();
+  const project_id = Number(projectId === '' ? '0' : projectId);
+
+  const location = useLocation();
+  const queryParams = new URLSearchParams(location.search);
+  const userID = queryParams.get('user_id');
+
+  const navigate = useNavigate();
+
+  const [mandateCount, setMandateCount] = useState([0, 0, 0]);
+  const [loading, setLoading] = useState(false);
+  const [tab, setTab] = useState(localStorage.taskTab || '1');
+
+  useEffect(() => {
+    const requests = [];
+    for (let i = 0; i < 4; i++) {
+      requests.push(
+        getMandateList({
+          project_id,
+          pageSize: 1,
+          currentPage: 1,
+          mandate_type: i + 1,
+          responsible_people: userID !== null ? Number(userID) : '',
+        }),
+      );
+    }
+    setLoading(true);
+    Promise.all(requests)
+      .then((resList) => {
+        if (resList.filter((item) => item.code !== 200).length) {
+          throw new Error('请求错误');
+        }
+        const typeCount = [0, 0, 0, 0];
+        resList.forEach((item, index) => {
+          typeCount[index] = item.data.pagination?.total;
+        });
+        setMandateCount(typeCount);
+      })
+      .catch((err) => {
+        console.log(err);
+      })
+      .finally(() => {
+        setLoading(false);
+      });
+  }, []);
+
+  const onTabChange = (key) => {
+    setTab(key);
+    localStorage.setItem('taskTab', key);
+  };
+
+  const goTaskList = (item) => {
+    navigate(
+      `/center/my-task/task-list?project_id=${project_id}&mandateType=${item}${
+        userID !== null ? '&user_id=' + userID : ''
+      }`,
+    );
+  };
+  const goWorkOrderList = (item) => {
+    navigate(
+      `/center/my-task/work-order-list?project_id=${project_id}&order_type=${item}${
+        userID !== null ? '&user_id=' + userID : ''
+      }`,
+    );
+  };
+
+  const makeTaskList = (item, index) => {
+    return (
+      <List.Item
+        className={styles.listItem}
+        onClick={() => {
+          goTaskList(item.value);
+        }}
+      >
+        <List.Item.Meta
+          title={<span className={styles.fontS28}>{item.label}</span>}
+        />
+
+        <div className={styles.itemCount}>
+          <div className={styles.countNumber}>{mandateCount[index]}</div>
+          <div className={styles.fontS22}>任务数量</div>
+        </div>
+
+        <RightOutlined />
+      </List.Item>
+    );
+  };
+
+  const makeWorkOrderList = (item) => {
+    return (
+      <List.Item
+        className={styles.listItem}
+        onClick={() => {
+          goWorkOrderList(item.value);
+        }}
+      >
+        <List.Item.Meta
+          title={<span className={styles.fontS28}>{item.label}</span>}
+        />
+        {/* <div className={styles.itemCount}>
+          <div className={styles.countNumber}>{mandateCount[index]}</div>
+          <div className={styles.fontS22}>任务数量</div>
+        </div> */}
+        <RightOutlined />
+      </List.Item>
+    );
+  };
+
+  return (
+    <PageContent tabs closeable={false}>
+      <TabsContent
+        defaultActiveKey={tab}
+        onChange={onTabChange}
+        items={[
+          {
+            label: `我的任务`,
+            key: '1',
+            children: (
+              <Spin spinning={loading}>
+                <List
+                  className={styles.taskList}
+                  bordered
+                  itemLayout="horizontal"
+                  dataSource={MandateType}
+                  renderItem={makeTaskList}
+                  pagination={false}
+                />
+              </Spin>
+            ),
+          },
+          {
+            label: `我的工单`,
+            key: '2',
+            children: (
+              <Spin spinning={false}>
+                <List
+                  className={styles.taskList}
+                  bordered
+                  itemLayout="horizontal"
+                  dataSource={OrderType}
+                  renderItem={makeWorkOrderList}
+                  pagination={false}
+                />
+              </Spin>
+            ),
+          },
+        ]}
+      />
+    </PageContent>
+  );
+};
+
+export default MyTask;

+ 79 - 0
src/pages/Center/MyTask/index.less

@@ -0,0 +1,79 @@
+.taskList {
+  border: none;
+  max-height: calc(100vh - 140px);
+  overflow-y: scroll;
+
+  .listItem {
+    margin: 20px 20px 20px 0;
+    height: 120px;
+    box-shadow: 0 0 6px 3px rgba(0, 150, 255, 10%);
+    border-radius: 10px;
+    background-color: #ffffff;
+
+    .itemCount {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      margin-right: 30px;
+
+      .countNumber {
+        color: #f5a623;
+        font-size: 32px;
+        font-weight: 500;
+        margin-bottom: 6px;
+      }
+    }
+  }
+}
+
+.ant-select-clear {
+  opacity: 1 !important;
+  margin-top: -12px !important;
+  width: 24px !important;
+  height: 24px !important;
+  font-size: 24px !important;
+  color: black !important;
+}
+
+.antdSelect .ant-select-selection-item,
+.antdSelect .ant-select-selection-placeholder,
+.ant-select-item-option-content {
+  font-size: 28px;
+  color: black;
+  margin-right: 10px;
+}
+.ant-select-item-option {
+  padding: 8px !important;
+}
+.ant-select-arrow {
+  font-size: 24px !important;
+  color: black !important;
+}
+
+.fontS28 {
+  font-size: 28px;
+}
+
+.fontS26 {
+  font-size: 26px;
+}
+
+.fontS24 {
+  font-size: 24px;
+}
+
+.fontS22 {
+  font-size: 22px;
+}
+
+.fontS20 {
+  font-size: 20px;
+}
+
+.fontS18 {
+  font-size: 18px;
+}
+
+.fontS16 {
+  font-size: 16px;
+}

+ 2 - 1
src/pages/Center/index.js

@@ -20,7 +20,8 @@ const Center = () => {
     UnityAction.sendMsg('Logout');
   };
   const toMyTask = (type) => {
-    navigate(`/task-manage/${projectId}?user_id=${user.ID}&tab=${type}`);
+    localStorage.taskTab = type;
+    navigate(`/center/my-task/${projectId}?user_id=${user.ID}`);
   };
 
   return (

+ 1 - 12
src/pages/TaskManage/Detail/TaskList/TaskList.tsx

@@ -33,7 +33,6 @@ const TaskList: React.FC<IPropsType> = (props) => {
   const queryParams = new URLSearchParams(location.search);
   const project_id = Number(queryParams.get('project_id'));
   const mandateType = Number(queryParams.get('mandateType'));
-  const userID = queryParams.get('user_id');
 
   const navigate = useNavigate();
 
@@ -45,7 +44,6 @@ const TaskList: React.FC<IPropsType> = (props) => {
     mandate_type: mandateType,
     pageSize: 20,
     currentPage: 1,
-    responsible_people: userID !== null ? Number(userID) : '',
   });
   const [pagination, setPagination] = useState({
     current: 1,
@@ -54,11 +52,7 @@ const TaskList: React.FC<IPropsType> = (props) => {
   });
 
   const { run: getList, loading: loadData } = useRequest(getMandateList, {
-    defaultParams: [
-      {
-        ...currentParams,
-      },
-    ],
+    defaultParams: [currentParams],
     formatResult: (result) => {
       const pageInfo = result.data.pagination;
       if (result.data.pagination.current === 1) {
@@ -129,10 +123,6 @@ const TaskList: React.FC<IPropsType> = (props) => {
       currentPage: 1,
     };
 
-    if (userID !== null) {
-      params.responsible_people = Number(userID);
-    }
-
     for (let i = 0; i < value.length; i++) {
       if (value[i] !== null && topFiltersConfig[i] !== undefined) {
         params[topFiltersConfig[i].key] = value[i];
@@ -323,7 +313,6 @@ const TaskList: React.FC<IPropsType> = (props) => {
 export default connect(
   ({
     taskUser,
-    mandate,
     loading,
   }: any): {
     userList: IUserType[];

+ 48 - 19
src/pages/TaskManage/Detail/TaskOrder/TaskOrder.tsx

@@ -6,7 +6,7 @@ import { OrderStatus, OrderType } from '@/pages/TaskManage/constent';
 import {
   getCraftRecordList,
   getMaintainRecordList,
-  getReagentOrderDetail,
+  getPatrolMandateRecord,
   getRepairRecordList,
   getWorkOrderFlow,
   queryReagentDetail,
@@ -193,7 +193,7 @@ const TaskOrder: React.FC<IPropsType> = (props) => {
     },
   });
 
-  const { run: getDosingOrder } = useRequest(getReagentOrderDetail, {
+  const { run: getDosingOrder } = useRequest(queryReagentDetail, {
     manual: true,
     formatResult: (result) => {
       const temp = {
@@ -215,13 +215,35 @@ const TaskOrder: React.FC<IPropsType> = (props) => {
           OrderStatus.find((status) => status.value === result.status) || '-',
       };
       setOrderInfo(temp);
-      queryReagentDetail({ id: temp.id })
-        .then((res) => {
-          if (res) {
-            setAdditionalInfo(res);
-          }
-        })
-        .catch((err) => console.log(err));
+      setAdditionalInfo(temp);
+    },
+  });
+
+  const { run: getPatrolOrderList } = useRequest(getPatrolMandateRecord, {
+    manual: true,
+    formatResult: (result) => {
+      if (result?.data?.list) {
+        const temp = result.data.list[0];
+        const tempDetail = {
+          ...temp,
+          CreateTime: temp?.CreatedTime
+            ? dayjs(temp.CreatedTime).format('YYYY-MM-DD HH:mm')
+            : '-',
+          PlanTime: temp.plan_end_time
+            ? dayjs(temp.plan_end_time).format('YYYY-MM-DD HH:mm')
+            : '-',
+          RepairTime: temp?.actual_end_time
+            ? dayjs(temp.actual_end_time).format('YYYY-MM-DD HH:mm')
+            : '-',
+          Reason: temp.detail,
+          Repairman: '-',
+          DispatchMan:
+            userList.find((user) => user.ID === temp.operator_id) || '-',
+          OrderStatus:
+            OrderStatus.find((status) => status.value === temp.status) || '-',
+        };
+        setOrderInfo(tempDetail);
+      }
     },
   });
 
@@ -246,7 +268,6 @@ const TaskOrder: React.FC<IPropsType> = (props) => {
     switch (order_type) {
       // 工艺
       case 1:
-
       case 6:
         getCraftDetail({ project_id, work_id: order_id });
         break;
@@ -258,8 +279,13 @@ const TaskOrder: React.FC<IPropsType> = (props) => {
       case 3:
         getMaintainDetail({ project_id, id: order_id });
         break;
+      // 巡检
+      case 4:
+        getPatrolOrderList({ project_id, id: order_id });
+        break;
+      // 加药
       case 5:
-        getDosingOrder(order_id);
+        getDosingOrder({ id: order_id });
         break;
     }
   }, []);
@@ -317,7 +343,7 @@ const TaskOrder: React.FC<IPropsType> = (props) => {
               </Col>
               <Col className={styles.fontS28} span={9}>
                 {/* @ts-ignore */}
-                派单人员:{orderInfo?.DispatchMan?.CName}
+                派单人员:{orderInfo?.DispatchMan?.CName || '-'}
               </Col>
             </Row>
             <Row className={styles.rowMargin}>
@@ -386,11 +412,14 @@ const TaskOrder: React.FC<IPropsType> = (props) => {
             <SubTitle title="加药详情" />
             <div style={{ padding: '15px' }}>
               <Row>
-                <Col className={styles.fontS28}>加药详情:</Col>
-                <Col className={styles.fontS28} span={18}>
-                  {`药剂名称:${additionalInfo?.name || '-'} 加药量:${
-                    additionalInfo?.dosage || '-'
-                  }升 浓度:${additionalInfo?.concentration || '-'}`}
+                <Col className={styles.fontS28} span={8}>
+                  药剂名称:{additionalInfo?.name || '-'}
+                </Col>
+                <Col className={styles.fontS28} span={8}>
+                  加药量:{additionalInfo?.dosage || '-'}升
+                </Col>
+                <Col className={styles.fontS28} span={8}>
+                  浓度:{additionalInfo?.concentration || '-'}
                 </Col>
               </Row>
             </div>
@@ -408,10 +437,10 @@ const TaskOrder: React.FC<IPropsType> = (props) => {
                 items={stepInfo?.map((item) => {
                   return {
                     title: (
-                      <span className={styles.fontS24}>{item.content}</span>
+                      <span className={styles.fontS28}>{item.content}</span>
                     ),
                     description: (
-                      <span className={styles.fontS20}>{item.time}</span>
+                      <span className={styles.fontS24}>{item.time}</span>
                     ),
                   };
                 })}

+ 59 - 83
src/pages/TaskManage/Detail/WorkOrderList/WorkOrderList.js

@@ -3,9 +3,9 @@ import PageTitle from '@/components/PageTitle';
 import {
   getCraftRecordList,
   getMaintainRecordList,
+  getPatrolMandateRecord,
   getReagentOrderList,
   getRepairRecordList,
-  getUserWorkOrderList,
 } from '@/services/TaskManage';
 import { connect, useLocation, useNavigate, useRequest } from '@umijs/max';
 import { Button, Col, Empty, Row, Tabs } from 'antd';
@@ -22,7 +22,6 @@ const WorkOrderList = (props) => {
   const queryParams = new URLSearchParams(location.search);
   const project_id = Number(queryParams.get('project_id'));
   const order_type = Number(queryParams.get('order_type'));
-  const userID = queryParams.get('user_id');
 
   const navigate = useNavigate();
 
@@ -96,6 +95,10 @@ const WorkOrderList = (props) => {
       if (order?.CreateTime) {
         return dayjs(order.CreateTime).format('YYYY-MM-DD HH:mm');
       }
+    } else if (order_type === 4) {
+      if (order?.CreatedTime) {
+        return dayjs(order.CreatedTime).format('YYYY-MM-DD HH:mm');
+      }
     } else if (order_type === 5) {
       if (order?.start_time?.Valid) {
         return dayjs(order.start_time.Time).format('YYYY-MM-DD HH:mm');
@@ -106,92 +109,65 @@ const WorkOrderList = (props) => {
 
   const { run: getWorkOrderList } = useRequest(
     (status) => {
-      if (userID !== null) {
-        return getUserWorkOrderList({
-          project_id,
-          work_type: order_type,
-          status: status || 0,
-          user_id: Number(userID),
-        });
-      } else {
-        switch (order_type) {
-          case 1:
-          case 6:
-          case 7:
-            return getCraftRecordList({
-              project_id,
-              status: status || 0,
-              work_type: order_type,
-            });
-          case 2:
-            return getRepairRecordList({
-              project_id,
-              acceptanceStatus: status || 0,
-            });
-          case 3:
-            return getMaintainRecordList({ project_id, status: status || 0 });
-          case 4:
-            return;
-          case 5:
-            return getReagentOrderList({ project_id, status: status || 0 });
-        }
+      switch (order_type) {
+        case 1:
+        case 6:
+        case 7:
+          return getCraftRecordList({
+            project_id,
+            status: status || 0,
+            types: order_type === 1 ? 0 : order_type === 6 ? 1 : 2,
+          });
+        case 2:
+          return getRepairRecordList({
+            project_id,
+            acceptanceStatus: status || 0,
+          });
+        case 3:
+          return getMaintainRecordList({ project_id, status: status || 0 });
+        case 4:
+          return getPatrolMandateRecord({ project_id, status: status || 0 });
+        case 5:
+          return getReagentOrderList({ project_id, status: status || 0 });
       }
     },
     {
       throwOnError: true,
       formatResult: (result) => {
-        if (userID !== null) {
-          if (result) {
-            const temp = result.map((item) => {
-              return {
-                ...item,
-                CreateTime: item.CreateTime
-                  ? dayjs(item.CreateTime).format('YYYY-MM-DD HH:mm')
-                  : '-',
-                Repairman: userList.find(
-                  (user) => item.Responsible === user.ID,
-                ),
-                OrderStatus: OrderStatus.find(
-                  (status) => status.value === item.Status,
-                ),
-              };
-            });
-            renderTabPannal(temp);
-          }
-        } else {
-          if (result?.data?.list) {
-            const temp = result.data.list.map((item) => {
-              return {
-                ...item,
-                CreateTime: formatCreateTime(item),
-                Repairman: userList.find((user) => {
-                  let temp = -1;
-                  if (order_type === 2) {
-                    temp = item.Repairman;
-                  } else if (order_type === 3) {
-                    temp = item.MaintenancePerson;
-                  } else if (order_type === 5) {
-                    temp = '-';
-                  } else {
-                    temp = item.checker_id;
-                  }
-                  return temp === user.ID;
-                }),
-                OrderStatus: OrderStatus.find((status) => {
-                  let temp = -1;
-                  if (order_type === 2) {
-                    temp = item.AcceptanceStatus;
-                  } else if (order_type === 3) {
-                    temp = item.Status;
-                  } else {
-                    temp = item.status;
-                  }
-                  return status.value === temp;
-                }),
-              };
-            });
-            renderTabPannal(temp);
-          }
+        if (result?.data?.list) {
+          const temp = result.data.list.map((item) => {
+            return {
+              ...item,
+              CreateTime: formatCreateTime(item),
+              Repairman: userList.find((user) => {
+                let temp = -1;
+                if (order_type === 2) {
+                  temp = item.Repairman;
+                } else if (order_type === 3) {
+                  temp = item.MaintenancePerson;
+                } else if (order_type === 4) {
+                  temp = '-';
+                } else if (order_type === 5) {
+                  temp = '-';
+                } else {
+                  temp = item.checker_id;
+                }
+                return temp === user.ID;
+              }),
+              OrderStatus: OrderStatus.find((status) => {
+                let temp = -1;
+                if (order_type === 2) {
+                  temp = item.AcceptanceStatus;
+                } else if (order_type === 3) {
+                  temp = item.Status;
+                } else {
+                  temp = item.status;
+                }
+                return status.value === temp;
+              }),
+            };
+          });
+          renderTabPannal(temp);
         }
 
         if (result?.data?.pagination) {

+ 3 - 3
src/pages/TaskManage/components/MandateDetail.js

@@ -174,7 +174,10 @@ const MandateDetail = (props) => {
         mandateChild.find((mandate) => mandate.Id === Number(params.mc_id))
           ?.Content
       } ${params?.note || ''}`;
+    } else {
+      params.note = mandateDetail.Summary;
     }
+
     const result = await dispatchTask(params);
     if (result) {
       setDispatchModalOpen(false);
@@ -576,9 +579,6 @@ const DispatchTaskModal = (props) => {
         >
           <DatePicker style={{ width: '100%' }} placeholder="请选择完成时间" />
         </Form.Item>
-        <Form.Item label="备注" name="note">
-          <Input.TextArea placeholder="备注" />
-        </Form.Item>
       </Form>
     </Modal>
   );

+ 6 - 18
src/pages/TaskManage/index.tsx

@@ -3,7 +3,7 @@ import TabsContent from '@/components/TabsContent';
 import styles from '@/pages/TaskManage/index.less';
 import { getMandateList } from '@/services/TaskManage';
 import { RightOutlined } from '@ant-design/icons';
-import { useLocation, useParams } from '@umijs/max';
+import { useParams } from '@umijs/max';
 import { List, Spin } from 'antd';
 import { BaseOptionType } from 'rc-select/es/Select';
 import { useEffect, useState } from 'react';
@@ -14,16 +14,11 @@ const TaskManage = () => {
   const { projectID } = useParams();
   const project_id = Number(projectID === '' ? '0' : projectID);
 
-  const location = useLocation();
-  const queryParams = new URLSearchParams(location.search);
-  const userID = queryParams.get('user_id');
-  const specifiedTab = queryParams.get('tab');
-
   const navigate = useNavigate();
 
   const [mandateCount, setMandateCount] = useState<number[]>([0, 0, 0]);
   const [loading, setLoading] = useState(false);
-  const [tab, setTab] = useState(specifiedTab || localStorage.taskTab || '1');
+  const [tab, setTab] = useState(localStorage.taskTab || '1');
 
   useEffect(() => {
     const requests = [];
@@ -34,7 +29,6 @@ const TaskManage = () => {
           pageSize: 1,
           currentPage: 1,
           mandate_type: i + 1,
-          responsible_people: userID !== null ? Number(userID) : '',
         }),
       );
     }
@@ -59,17 +53,11 @@ const TaskManage = () => {
   }, []);
 
   const goTaskList = (item: number) => {
-    navigate(
-      `/task-manage/list?project_id=${project_id}&mandateType=${item}${
-        userID !== null ? '&user_id=' + userID : ''
-      }`,
-    );
+    navigate(`/task-manage/list?project_id=${project_id}&mandateType=${item}`);
   };
   const goWorkOrderList = (item: number) => {
     navigate(
-      `/task-manage/work-order/list?project_id=${project_id}&order_type=${item}${
-        userID !== null ? '&user_id=' + userID : ''
-      }`,
+      `/task-manage/work-order/list?project_id=${project_id}&order_type=${item}`,
     );
   };
 
@@ -127,7 +115,7 @@ const TaskManage = () => {
         onChange={onTabChange}
         items={[
           {
-            label: `${userID === null ? '任务管理' : '我的任务'}`,
+            label: `任务管理`,
             key: '1',
             children: (
               <Spin spinning={loading}>
@@ -143,7 +131,7 @@ const TaskManage = () => {
             ),
           },
           {
-            label: `${userID === null ? '工单管理' : '我的工单'}`,
+            label: `工单管理`,
             key: '2',
             children: (
               <Spin spinning={loading}>

+ 24 - 3
src/services/TaskManage.js

@@ -12,7 +12,6 @@ export async function getMandateList(data) {
   if (data.responsible_people === '') {
     delete data.responsible_people;
   }
-  console.log(data);
   return request(`${baseURL}/v1/mandate/list?${stringify(data)}`);
 }
 
@@ -136,7 +135,12 @@ export async function getDiagnosticDetail(detailId) {
   return res.data;
 }
 
-//加药详情接口
+/**
+ * 获取加药工单详情
+ * @param {object} data
+ * @param {number} data.id
+ * @returns {Promise<*>}
+ */
 export async function queryReagentDetail(data) {
   const res = await request(`/api/v1/reagent/detail?${stringify(data)}`);
   return res.data;
@@ -147,6 +151,7 @@ export async function queryReagentDetail(data) {
  * @param {object} params
  * @param {number} params.work_type 工单类型:1-工艺工单,2-维修工单,3-保养工单,4-巡检,5-加药,6-备品备件,7-盘点
  * @param {number} params.work_id 工单id
+ * @returns {Promise<*>}
  */
 export async function getWorkOrderFlow(params) {
   const res = await request(`/api/v1/work_order/flow?${stringify(params)}`);
@@ -189,6 +194,7 @@ export async function getUserWorkOrderList(params) {
  * @param {string} params.end_time
  * @param {string} params.name
  * @param {number} params.status
+ * @returns {Promise<*>}
  */
 export async function getReagentOrderList(params) {
   const res = await request(`/api/v1/reagent/list?${stringify(params)}`);
@@ -198,9 +204,24 @@ export async function getReagentOrderList(params) {
 /**
  * 获取加药工单详情
  * @param {number} id
- * @returns
+ * @returns {Promise<*>}
  */
 export async function getReagentOrderDetail(id) {
   const res = await request(`/api/v1/reagent/detail?id=${id}`);
   return res.data;
 }
+
+/**
+ * 获取巡检工单列表
+ * @param {object} params
+ * @param {number | string} params.id
+ * @param {number | string} params.project_id
+ * @param {number | string} [params.status]
+ * @returns {Promise<*>}
+ */
+export async function getPatrolMandateRecord(params) {
+  const res = await request(
+    `/api/v1/patrol_mandate_record/list?${stringify(params)}`,
+  );
+  return res;
+}