瀏覽代碼

feat: 完成任务详情页面基础数据请求

ZhaoJun 1 年之前
父節點
當前提交
c4857a3218

+ 6 - 1
.umirc.ts

@@ -71,9 +71,14 @@ export default defineConfig({
     },
     {
       name: '任务管理',
-      path: '/task-manage/:projectId',
+      path: '/task-manage/:projectID',
       component: './TaskManage',
     },
+    {
+      name: '任务管理-详情',
+      path: '/task-manage/detail',
+      component: './TaskManage/Detail/TaskDetail',
+    },
     // {
     //   name: '权限演示',
     //   path: '/access',

+ 1 - 0
package.json

@@ -16,6 +16,7 @@
     "@umijs/max": "^4.0.75",
     "antd": "^5.4.0",
     "echarts": "^5.4.3",
+    "md5": "^2.3.0",
     "qs": "^6.11.2",
     "react-zmage": "^0.8.5"
   },

+ 143 - 0
src/pages/TaskManage/Detail/TaskDetail.tsx

@@ -0,0 +1,143 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
+import {
+  MandateChildType,
+  MandateDetailType,
+  PropsType,
+  UserType,
+  WorkOrderType,
+} from '@/pages/TaskManage/Detail/detail.types';
+import {
+  MandateClass,
+  MandateStatus,
+  MandateType,
+  OrderStatus,
+  OrderType,
+} from '@/pages/TaskManage/constent';
+import {
+  dispatchOrder,
+  getMandateChildList,
+  getMandateDetail,
+  ignoreTask,
+  setTaskAutomation,
+} from '@/services/TaskManage';
+import { connect, useLocation, useRequest } from '@umijs/max';
+import React, { useEffect, useState } from 'react';
+
+const TaskDetail: React.FC<PropsType> = (props) => {
+  const { userList, dispatch } = props;
+  const md5 = require('md5');
+  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 [mandateDetail, setMandateDetail] = useState<MandateDetailType>();
+  const [handledWorkOrders, setHandledWorkOrders] = useState<WorkOrderType[]>(
+    [],
+  );
+  const [subMandateList, setSubMandateList] = useState<MandateChildType[]>([]);
+
+  const { run: getDetail, refresh: refreshDetail } = useRequest(
+    getMandateDetail,
+    {
+      defaultParams: [
+        {
+          project_id,
+          mandate_id,
+        },
+      ],
+      formatResult: (result) => {
+        const mandate: MandateDetailType = {
+          ...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,
+          ),
+        };
+        const workOrderList: WorkOrderType[] = result.data.Records.map(
+          (record: WorkOrderType) => {
+            return {
+              ...record,
+              Status: OrderStatus.find(
+                (item) => item.value === record.Status,
+              ),
+              RecordType: OrderType.find(
+                (item) => item.value === record.RecordType,
+              ),
+              Responsible: userList.find(
+                (item: UserType) => item.ID === record.Responsible,
+              ),
+            };
+          },
+        );
+        setMandateDetail(mandate);
+        setHandledWorkOrders(workOrderList);
+      },
+    },
+  );
+
+  const {
+    run: getMandateChild,
+    loading,
+    refresh: refreshMandateChild,
+  } = useRequest(getMandateChildList, {
+    defaultParams: [
+      {
+        mandateId: mandate_id,
+      },
+    ],
+    formatResult: (result) => {
+      setSubMandateList(result.data);
+    },
+  });
+
+  const { run: setAuto } = useRequest(setTaskAutomation, {
+    manual: true,
+    onSuccess: () => {
+      refreshDetail();
+      refreshMandateChild();
+    },
+  });
+
+  const { run: runIgnoreTask } = useRequest(ignoreTask, {
+    manual: true,
+    onSuccess: () => {
+      refreshDetail();
+      refreshMandateChild();
+    },
+  });
+
+  const { run: runDispatch } = useRequest(dispatchOrder, {
+    manual: true,
+    onSuccess: () => {
+      refreshDetail();
+      refreshMandateChild();
+    },
+  });
+
+  useEffect(() => {
+    if (userList.length === 0) {
+      dispatch({
+        type: 'taskUser/fetchUserList',
+        payload: { project_id },
+      });
+    }
+  }, []);
+
+  return (
+    <PageContent>
+      <PageTitle returnable>任务详情</PageTitle>
+
+    </PageContent>
+  );
+};
+
+export default connect(({ taskUser }: any): { userList: UserType[] } => {
+  return {
+    userList: taskUser.userList,
+  };
+})(TaskDetail);

+ 56 - 0
src/pages/TaskManage/Detail/detail.types.ts

@@ -0,0 +1,56 @@
+import User from "@/pages/TaskManage/models/user";
+
+export interface PropsType{
+  userList: UserType[],
+  dispatch: (args:{type:string, payload: object})=>{}
+}
+
+export interface MandateChildType {
+  Content: string;
+  CreateTime: string;
+  ExtendId: number;
+  Id: number;
+  MandateClass: number;
+  MandateId: number;
+  ProjectId: number;
+  Status: number;
+  Title: string;
+}
+
+export interface WorkOrderType {
+  ActualDoneTime: string;
+  CreateTime: string;
+  Detail: string;
+  Id: number;
+  Note: string;
+  PlanDoneTime: string;
+  RecordType: number;
+  Responsible: number;
+  Status: number;
+}
+
+export interface MandateDetailType {
+  Id: number;
+  ProjectId: number;
+  MandateType: number;
+  MandateClass: number;
+  ResponsiblePeople: number;
+  Detail: string;
+  MandateChild: MandateChildType[];
+  Records: WorkOrderType[];
+  Summary: string;
+  CreateTime: string;
+  Status: number;
+  Note: string;
+  OperationLog: string;
+  OperationPeople: number;
+  ExtendId: number;
+}
+
+export interface UserType {
+  CName: string;
+  ID: number;
+  RoleID: string;
+  RoleName: string;
+  UserName: string;
+}

+ 126 - 0
src/pages/TaskManage/constent.ts

@@ -0,0 +1,126 @@
+export const MandateClass = [
+  {
+    value: 1,
+    label: '生产调度类',
+  },
+  {
+    value: 2,
+    label: '成本节约类',
+  },
+  {
+    value: 3,
+    label: '设备自检',
+  },
+  {
+    value: 4,
+    label: '工艺自检',
+  },
+  {
+    value: 5,
+    label: '电气检测',
+  },
+  {
+    value: 6,
+    label: '环境检测',
+  },
+  {
+    value: 7,
+    label: '安防检测',
+  },
+  {
+    value: 8,
+    label: '密闭空间检测',
+  },
+  {
+    value: 9,
+    label: '设备保养',
+  },
+  {
+    value: 10,
+    label: '设备维修',
+  },
+  {
+    value: 11,
+    label: '故障上报',
+  },
+  {
+    value: 12,
+    label: '工艺数据',
+  },
+  {
+    value: 13,
+    label: '设备巡检',
+  },
+  {
+    value: 14,
+    label: '数据超限',
+  },
+];
+
+export const MandateType = [
+  {
+    value: 1,
+    label: '工况任务',
+  },
+  {
+    value: 2,
+    label: '系统自检',
+  },
+  {
+    value: 3,
+    label: '生产任务',
+  },
+];
+
+export const MandateStatus = [
+  {
+    value: 0,
+    label: '未处理',
+  },
+  {
+    value: 2,
+    label: '已完成',
+  },
+  {
+    value: 4,
+    label: '已忽略',
+  },
+  {
+    value: 5,
+    label: '已派遣',
+  },
+];
+
+export const OrderType = [
+  {
+    value: 1,
+    label: '工艺工单',
+  },
+  {
+    value: 2,
+    label: '维修工单',
+  },
+  {
+    value: 3,
+    label: '保养工单',
+  },
+];
+
+export const OrderStatus = [
+  {
+    value: 0,
+    label: '处理中',
+  },
+  {
+    value: 1,
+    label: '已提交',
+  },
+  {
+    value: 2,
+    label: '已完成',
+  },
+  {
+    value: 3,
+    label: '已拒绝',
+  },
+];

+ 2 - 26
src/pages/TaskManage/index.less

@@ -1,36 +1,12 @@
-.backgroundImage {
-}
-
-.container {
-  margin: 0;
-  padding: 0;
-  height: 100vh;
-  display: flex;
-  flex-direction: column;
-  background-color: rgba(255, 255, 255, 0.4);
-  backdrop-filter: blur(20px);
-}
-
-.title {
-  padding: 10px;
-  font-size: 20px;
-  font-weight: 500;
-
-  .delimiter {
-    margin: 0 10px 0 10px;
-    border-left: 5px solid #468ee1;
-  }
-}
-
 .taskList {
-  height: calc(100vh - 50px);
+  height: calc(100vh - 70px);
   overflow-y: scroll;
   border: none;
 
   .listItem {
     margin: 20px 10px;
     height: 10vh;
-    box-shadow: 0px 0px 6px 3px rgba(0, 150, 255, 0.1);
+    box-shadow: 0 0 6px 3px rgba(0, 150, 255, 10%);
 
     .itemCount {
       display: flex;

+ 89 - 27
src/pages/TaskManage/index.tsx

@@ -1,21 +1,71 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
+import {
+  MandateClass,
+  MandateStatus,
+  MandateType,
+} from '@/pages/TaskManage/constent';
 import styles from '@/pages/TaskManage/index.less';
-import { PropTypes } from '@/pages/TaskManage/index.types';
-import { List } from 'antd';
-import React, { useEffect } from 'react';
+import { PropTypes, mandateType } from '@/pages/TaskManage/index.types';
+import { getMandateList } from '@/services/TaskManage';
+import { RightOutlined } from '@ant-design/icons';
+import { useParams, useRequest } from '@umijs/max';
+import { List, Spin } from 'antd';
+import React, { useEffect, useState } from 'react';
+import { useNavigate } from 'umi';
 
 const TaskManage: React.FC<PropTypes> = (props) => {
-  const { projectID } = props;
+  const { projectID } = useParams();
+  console.log(projectID);
   const project_id = Number(projectID === '' ? '0' : projectID);
-  const arr = [];
-  for (let i = 0; i < 20; i++) {
-    arr.push({
-      title: '任务标题',
-      desc: '任务详情任务详情任务详情任务详情任务详情任务详情任务详情任务详情任务详情',
-    });
-  }
 
-  const goToDetail = (item: number) => {
-    console.log(item);
+  const navigate = useNavigate();
+
+  const [pagination, setPagination] = useState({
+    total: 0,
+    pageSize: 5,
+    current: 1,
+  });
+  const [mandateList, setMandateList] = useState<mandateType[]>([]);
+
+  const {
+    run: runGetMandateList,
+    loading,
+    refresh: refreshMandateList,
+  } = useRequest(getMandateList, {
+    defaultParams: [
+      {
+        project_id,
+        pageSize: pagination.pageSize,
+        currentPage: pagination.current,
+      },
+    ],
+    onSuccess: () => {},
+    formatResult: (result) => {
+      const mandates = result.data.list;
+      mandates.forEach((mandate: mandateType) => {
+        mandate.Status =
+          MandateStatus.find((status) => status.value === mandate.Status) || 0;
+        mandate.MandateClass =
+          MandateClass.find(
+            (classItem) => classItem.value === mandate.MandateClass,
+          ) || 0;
+        mandate.MandateType =
+          MandateType.find((type) => type.value === mandate.MandateType) || 0;
+      });
+      setMandateList(result.data.list);
+      setPagination(result.data.pagination);
+    },
+  });
+
+  const goToDetail = (item: mandateType) => {
+    navigate(
+      `/task-manage/detail?project_id=${project_id}&mandate_id=${item.Id}`,
+    );
+  };
+
+  const onPageChange = (page: number, pageSize: number) => {
+    runGetMandateList({ project_id, currentPage: page, pageSize });
   };
 
   useEffect(() => {
@@ -26,7 +76,7 @@ const TaskManage: React.FC<PropTypes> = (props) => {
     };
   }, []);
 
-  const makeList = (item: any, index: number) => {
+  const makeList = (item: mandateType, index: number) => {
     return (
       <List.Item
         className={styles.listItem}
@@ -34,34 +84,46 @@ const TaskManage: React.FC<PropTypes> = (props) => {
           goToDetail(item);
         }}
       >
-        <List.Item.Meta title={item.title} description={item.desc} />
+        <List.Item.Meta
+          title={
+            typeof item.MandateType === 'number' ? '' : item.MandateType.label
+          }
+          description={item.Detail}
+        />
         <div className={styles.itemCount}>
           <div className={styles.countNumber}>10</div>
           <div>任务数量</div>
         </div>
-        <div style={{ fontSize: '48px', color: 'gray', fontWeight: '200' }}>
-          {'>'}
-        </div>
+        <RightOutlined />
       </List.Item>
     );
   };
 
   return (
-    <div className={styles.backgroundImage}>
-      <div className={styles.container}>
-        <div className={styles.title}>
-          <span className={styles.delimiter}></span>
-          任务管理
-        </div>
+    <PageContent>
+      <PageTitle>任务管理</PageTitle>
+      <Spin spinning={loading}>
         <List
           className={styles.taskList}
           bordered
           itemLayout="horizontal"
-          dataSource={arr}
+          dataSource={mandateList}
           renderItem={makeList}
+          pagination={
+            mandateList.length
+              ? {
+                  position: 'bottom',
+                  align: 'end',
+                  simple: true,
+                  showSizeChanger: false,
+                  onChange: onPageChange,
+                  ...pagination,
+                }
+              : false
+          }
         />
-      </div>
-    </div>
+      </Spin>
+    </PageContent>
   );
 };
 

+ 23 - 2
src/pages/TaskManage/index.types.ts

@@ -1,3 +1,24 @@
 export interface PropTypes {
-  projectID: string
-}
+  projectID: string;
+}
+
+export interface selectOption {
+  value: number;
+  label: string;
+}
+
+export interface mandateType {
+  Id: number;
+  ProjectId: number;
+  MandateType: number | selectOption;
+  MandateClass: number | selectOption;
+  ResponsiblePeople: number;
+  Detail: string;
+  Summary: string;
+  CreateTime: string;
+  Status: number | selectOption;
+  Note: string;
+  OperationLog: string;
+  OperationPeople: number;
+  ExtendId: string;
+}

+ 28 - 0
src/pages/TaskManage/models/user.js

@@ -0,0 +1,28 @@
+import { queryUserList } from "../../../services/user";
+
+export default {
+    namespace: 'taskUser',
+  state: {
+    userList: [],
+  },
+  effects: {
+    *fetchUserList({ payload }, { call, put }) {
+      const response = yield call(queryUserList, payload);
+      if (response) {
+        yield put({
+          type: 'userListHandler',
+          payload: response.data,
+        });
+      }
+    },
+  },
+
+  reducers:{
+    userListHandler(state, { payload }) {
+      return {
+        ...state,
+        userList: payload,
+      };
+    },
+  }
+};

+ 79 - 0
src/services/TaskManage.js

@@ -0,0 +1,79 @@
+import {request} from "umi";
+import { stringify } from 'qs';
+
+const baseURL='/api'
+
+/**
+ * 获取任务列表
+ * @param data.project_id
+ * @returns {Promise<*>}
+ */
+export async function getMandateList(data) {
+  return request(`${baseURL}/v1/mandate/list?${stringify(data)}`);
+}
+
+/**
+ * 获取子任务列表
+ * @param params.project_id
+ * @param params.mandate_id
+ * @returns {Promise<*>}
+ */
+export async function getMandateChildList(params) {
+  return request(`${baseURL}/v1/mandate-child/list?${stringify(params)}`);
+}
+
+/**
+ * 获取任务详情
+ * @param params.mandate_idz
+ * @param params.project_id
+ * @returns {Promise<*>}
+ */
+export async function getMandateDetail(params) {
+  return request(`${baseURL}/v1/mandate/info?${stringify(params)}`);
+}
+
+/**
+ * 设置任务为自动
+ * @param params.mandate_id 任务id
+ * @param params.pw MD5加密的口令
+ * @returns {Promise<*>}
+ */
+export async function setTaskAutomation(params) {
+  return request(`${baseURL}/v1/mandate/automation`, {
+    method: 'POST',
+    body: params
+  });
+}
+
+/**
+ * 忽略任务
+ * @param params.Id 任务id
+ * @param params.Status 状态
+ * @param params.note 备注
+ * @returns {Promise<*>}
+ */
+export async function ignoreTask(params) {
+  const encodeParams = new URLSearchParams(params).toString()
+  return request(`${baseURL}/v1/mandate/edit`, {
+    method: 'POST',
+    headers: { ContentType: 'application/x-www-form-urlencoded' },
+    body: encodeParams
+  });
+}
+
+/**
+ * 派单
+ * @param params.m_id *主任务id
+ * @param params.mc_id *子任务id,多个以逗号分隔
+ * @param params.operator_id *操作员id
+ * @param params.plan_end_time *计划完成时间 YYYY:MM:DD HH:mm:ss
+ * @param params.type *工单类型:1:工艺工单,2:维修工单,3:保养工单
+ * @param params.note 备注
+ * @returns {Promise<*>}
+ */
+export async function dispatchOrder(params) {
+  return request(`${baseURL}/v1/work_order/save`, {
+    method: 'POST',
+    body: params
+  });
+}

+ 5 - 0
src/services/user.js

@@ -0,0 +1,5 @@
+import { request } from 'umi';
+
+export async function queryUserList(param) {
+  return request(`/api/v1/user/project/${param.project_id}`);
+}

+ 24 - 0
yarn.lock

@@ -3579,6 +3579,11 @@ chalk@^4.0.0, chalk@^4.1.2:
     ansi-styles "^4.1.0"
     supports-color "^7.1.0"
 
+charenc@0.0.2:
+  version "0.0.2"
+  resolved "https://registry.npmmirror.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
+  integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==
+
 chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.3:
   version "3.5.3"
   resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
@@ -3872,6 +3877,11 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
     shebang-command "^2.0.0"
     which "^2.0.1"
 
+crypt@0.0.2:
+  version "0.0.2"
+  resolved "https://registry.npmmirror.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
+  integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==
+
 crypto-browserify@^3.11.0:
   version "3.12.0"
   resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
@@ -5526,6 +5536,11 @@ is-boolean-object@^1.1.0, is-boolean-object@^1.1.2:
     call-bind "^1.0.2"
     has-tostringtag "^1.0.0"
 
+is-buffer@~1.1.6:
+  version "1.1.6"
+  resolved "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
+  integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
+
 is-callable@^1.0.4, is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4, is-callable@^1.2.7:
   version "1.2.7"
   resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
@@ -6238,6 +6253,15 @@ md5.js@^1.3.4:
     inherits "^2.0.1"
     safe-buffer "^5.1.2"
 
+md5@^2.3.0:
+  version "2.3.0"
+  resolved "https://registry.npmmirror.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
+  integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
+  dependencies:
+    charenc "0.0.2"
+    crypt "0.0.2"
+    is-buffer "~1.1.6"
+
 mdn-data@2.0.14:
   version "2.0.14"
   resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"