chenlei 7 meses atrás
pai
commit
c789e1ec9c

+ 17 - 1
src/api/management.ts

@@ -1,4 +1,4 @@
-import { IManageIndexDetail } from "@/types";
+import { IManageAssessmentIndex, IManageIndexDetail } from "@/types";
 import { requestByGet, requestByPost } from "@dage/service";
 
 export const getManageIndexListApi = (params: any) => {
@@ -16,3 +16,19 @@ export const deleteManageIndexApi = (ids: string | number) => {
 export const getManageIndexDetailApi = (id: string | number) => {
   return requestByGet<IManageIndexDetail>(`/api/cms/assess/detail/${id}`);
 };
+
+export const getManageAssFixedList = (
+  id: number | string,
+  searchKey?: string
+) => {
+  return requestByGet(`/api/cms/assessFixed/getList/${id}`, {
+    searchKey,
+  });
+};
+
+export const setManageAssFixed = (id: string | number, indexIds: string[]) => {
+  return requestByPost<IManageAssessmentIndex[]>(
+    `/api/cms/assessFixed/save/${id}`,
+    indexIds
+  );
+};

+ 31 - 34
src/components/AddIndexModal/index.tsx

@@ -1,45 +1,43 @@
-import { FC, Key, useEffect, useState } from "react";
+import { FC, Key, useState } from "react";
 import { Form, Modal, ModalProps, Tree } from "antd";
-import { getSelectedNodes } from "@/utils";
 import style from "./index.module.scss";
+import { getAssIndexTreeApi } from "@/api";
+import { AssIndexTreeItemType, ASS_INDEX_TYPE } from "@/types";
+import { useParams } from "react-router-dom";
+import { DageLoading } from "@dage/pc-components";
 
 export interface AddIndexModalProps extends Omit<ModalProps, "onOk"> {
-  checkedKeys: Key[];
   onCancel?: () => void;
-  onOk?: (keys: Key[], items: any) => void;
+  onOk?: (keys: string[]) => void;
+  // onOk?: (keys: Key[], items: AssIndexTreeItemType[]) => void;
 }
 
-const treeData: any[] = [
-  {
-    name: "0-0",
-    id: "0-0",
-    children: [
-      {
-        name: "0-0-0",
-        id: "0-0-0",
-        children: [
-          { id: "0-0-0-0", level: 1, name: "指标名称1" },
-          { id: "0-0-0-1", level: 1, name: "指标名称2" },
-          { id: "0-0-0-2", level: 1, name: "指标名称3" },
-        ],
-      },
-    ],
-  },
-];
-
 export const AddIndexModal: FC<AddIndexModalProps> = ({
   open,
-  checkedKeys,
   onOk,
   onCancel,
   ...rest
 }) => {
+  const params = useParams();
   const [form] = Form.useForm<any>();
   const [_checkedKeys, setCheckedKeys] = useState<Key[]>([]);
+  const [treeData, setTreeData] = useState<AssIndexTreeItemType[]>([]);
+  const [loading, setLoading] = useState(false);
+
+  const getAssIndexTree = async () => {
+    try {
+      setLoading(true);
+      const data = await getAssIndexTreeApi(params.type as ASS_INDEX_TYPE);
+      setTreeData(data);
+    } finally {
+      setLoading(false);
+    }
+  };
 
   const handleCancel = () => {
-    form.resetFields();
     onCancel?.();
+    form.resetFields();
+    setCheckedKeys([]);
   };
 
   const handleConfirm = () => {
@@ -47,15 +45,14 @@ export const AddIndexModal: FC<AddIndexModalProps> = ({
   };
 
   const handleSubmit = async (values: any) => {
-    onOk?.(values.checkedKeys, getSelectedNodes(values.checkedKeys, treeData));
+    onOk?.(values.checkedKeys.map((i: number) => String(i)));
+    // onOk?.(values.checkedKeys, getSelectedNodes(values.checkedKeys, treeData));
     handleCancel();
   };
 
-  useEffect(() => {
-    if (open) {
-      setCheckedKeys(checkedKeys);
-    }
-  }, [open, checkedKeys]);
+  const handleAfterOpenChange = (open: boolean) => {
+    if (open && !treeData.length) getAssIndexTree();
+  };
 
   return (
     <Modal
@@ -71,6 +68,7 @@ export const AddIndexModal: FC<AddIndexModalProps> = ({
       onOk={handleConfirm}
       onCancel={handleCancel}
       {...rest}
+      afterOpenChange={handleAfterOpenChange}
     >
       <Form
         labelCol={{ span: 4, offset: 2 }}
@@ -86,10 +84,7 @@ export const AddIndexModal: FC<AddIndexModalProps> = ({
           <Tree
             checkable
             defaultExpandAll
-            fieldNames={{
-              key: "id",
-              title: "name",
-            }}
+            fieldNames={{ title: "name", key: "id" }}
             checkedKeys={_checkedKeys}
             treeData={treeData}
             onCheck={(checkedKeys) => {
@@ -101,6 +96,8 @@ export const AddIndexModal: FC<AddIndexModalProps> = ({
           />
         </Form.Item>
       </Form>
+
+      {loading && <DageLoading />}
     </Modal>
   );
 };

+ 55 - 19
src/components/AddIndexTemplateModal/index.tsx

@@ -1,35 +1,66 @@
-import { FC, useRef } from "react";
+import { FC, Key, useState } from "react";
 import { Modal, ModalProps, Table } from "antd";
 import style from "../AddIndexModal/index.module.scss";
+import { ASS_INDEX_TYPE, IAssTemplateDetail } from "@/types";
+import { getAssTemplateListApi } from "@/api";
+import { useParams } from "react-router-dom";
+// import { getSelectedNodes } from "@/utils";
 
 export interface AddIndexTemplateModalProps extends Omit<ModalProps, "onOk"> {
   onCancel?: () => void;
-  onOk?: (rows: any) => void;
+  onOk?: (keys: string[]) => void;
+  // onOk?: (keys: Key[], rows: AssIndexTreeItemType[]) => void;
 }
 
-const data = [
-  {
-    id: 1,
-    name: "name",
-    description: "description",
-  },
-];
-
 export const AddIndexTemplateModal: FC<AddIndexTemplateModalProps> = ({
   open,
   onOk,
   onCancel,
   ...rest
 }) => {
-  const selectedRows = useRef<null | typeof data>(null);
+  const params = useParams();
+  const [loading, setLoading] = useState(false);
+  const [submitLoading, setSubmitLoading] = useState(false);
+  const [selectedRows, setSelectedRows] = useState<IAssTemplateDetail[]>([]);
+  const [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([]);
+  const [list, setList] = useState<IAssTemplateDetail[]>([]);
+
+  const getList = async () => {
+    try {
+      setLoading(true);
+      const data = await getAssTemplateListApi(params.type as ASS_INDEX_TYPE);
+      setList(data);
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  // 获取已选中的指标
+  // const getCheckedAssIndexs = async (checkedKeys: number[]) => {
+  //   const data = await getAssIndexTreeApi(params.type as ASS_INDEX_TYPE);
+  //   return getSelectedNodes(checkedKeys, data);
+  // };
 
   const handleCancel = () => {
     onCancel?.();
+    setSelectedRows([]);
+    setSelectedRowKeys([]);
   };
 
-  const handleConfirm = () => {
-    onOk?.(selectedRows);
-    onCancel?.();
+  const handleConfirm = async () => {
+    try {
+      setSubmitLoading(true);
+      // const keys = selectedRows[0].normIds.split(",").map((i) => Number(i));
+      // const rows = await getCheckedAssIndexs(keys);
+      onOk?.(selectedRows[0].normIds.split(","));
+      handleCancel();
+    } finally {
+      setSubmitLoading(false);
+    }
+  };
+
+  const handleAfterOpenChange = (open: boolean) => {
+    if (open && !list.length) getList();
   };
 
   return (
@@ -41,21 +72,26 @@ export const AddIndexTemplateModal: FC<AddIndexTemplateModalProps> = ({
       open={open}
       width={640}
       okButtonProps={{
-        disabled: false,
+        disabled: !selectedRows.length,
+        loading: submitLoading,
       }}
       onOk={handleConfirm}
       onCancel={handleCancel}
       {...rest}
+      afterOpenChange={handleAfterOpenChange}
     >
       <Table
+        loading={loading}
         className="cus-table"
         rowSelection={{
           type: "radio",
-          onChange: (selectedRowKeys, _selectedRows) => {
-            selectedRows.current = _selectedRows;
+          selectedRowKeys: selectedRowKeys,
+          onChange: (_selectedRowKeys, _selectedRows) => {
+            setSelectedRows(_selectedRows);
+            setSelectedRowKeys(_selectedRowKeys);
           },
         }}
-        dataSource={data}
+        dataSource={list}
         rowKey="id"
         columns={[
           {
@@ -64,7 +100,7 @@ export const AddIndexTemplateModal: FC<AddIndexTemplateModalProps> = ({
           },
           {
             title: "说明",
-            dataIndex: "description",
+            dataIndex: "remark",
           },
         ]}
       />

+ 8 - 0
src/pages/Management/Index/SettingIndex/index.module.scss

@@ -0,0 +1,8 @@
+.settingForm {
+  :global {
+    .ant-input-number-borderless.ant-input-number-status-error
+      input::placeholder {
+      color: #ff4d4f;
+    }
+  }
+}

+ 102 - 58
src/pages/Management/Index/SettingIndex/index.tsx

@@ -1,46 +1,83 @@
-import { FC, Key, useRef, useState } from "react";
-import { Button, Form, InputNumber, Radio, Space, Tag, Tooltip } from "antd";
-import { useNavigate } from "react-router-dom";
-import {
-  ActionType,
-  EditableFormInstance,
-  EditableProTable,
-} from "@ant-design/pro-components";
+import { FC, Key, useEffect, useRef, useState } from "react";
+import { Button, Form, Space } from "antd";
+import { useParams } from "react-router-dom";
+import { ActionType, EditableProTable } from "@ant-design/pro-components";
 import { PlusOutlined } from "@ant-design/icons";
 import {
   AddIndexModal,
   AddIndexTemplateModal,
-  FormPageFooter,
   PageContainer,
   Search,
 } from "@/components";
-import { TableIndexType } from "../../types";
+// import { uniq, uniqBy } from "lodash";
+import {
+  AssIndexTreeItemType,
+  ASS_INDEX_TYPE,
+  IManageAssessmentIndex,
+} from "@/types";
+import style from "./index.module.scss";
+import { getManageAssFixedList, setManageAssFixed } from "@/api";
+import { DageLoading, DageTableActions } from "@dage/pc-components";
 
 const SettingIndexPage: FC = () => {
-  const navigate = useNavigate();
+  const params = useParams();
   const [form] = Form.useForm();
   const actionRef = useRef<ActionType>();
-  const tableRef = useRef<EditableFormInstance<TableIndexType>>();
+  // const tableRef = useRef<EditableFormInstance<TableIndexType>>();
   const [keyword, setKeyword] = useState("");
   const [indexModalVisible, setIndexModalVisible] = useState(false);
   const [indexTemplateModalVisible, setIndexTemplateModalVisible] =
     useState(false);
   const [editableKeys, setEditableKeys] = useState<Key[]>([]);
+  const [loading, setLoading] = useState(false);
+  // 设置定级指标
+  const isFixed = params.type === ASS_INDEX_TYPE.FIXED;
 
-  const handleSubmit = async () => {
-    if (!(await form.validateFields())) return;
-
-    console.log(form.getFieldsValue());
+  const getList = async () => {
+    try {
+      setLoading(true);
+      const data = await (isFixed
+        ? getManageAssFixedList
+        : getManageAssFixedList)(params.id!);
+      form.setFieldValue("list", data);
+    } finally {
+      setLoading(false);
+    }
   };
 
-  const handleAddIndexItem = (keys: Key[], list: TableIndexType[]) => {
-    form.setFieldValue("list", [...list]);
-    setEditableKeys([...keys]);
+  const handleAddIndexItem = async (keys: string[]) => {
+    if (isFixed) {
+      await setManageAssFixed(params.id!, keys);
+    }
+    getList();
   };
+  // const handleAddIndexItem = async (
+  //   keys: Key[],
+  //   rows: AssIndexTreeItemType[]
+  // ) => {
+  //   form.setFieldValue(
+  //     "list",
+  //     uniqBy([...(form.getFieldValue("list") || []), ...rows], "id")
+  //   );
+  //   setEditableKeys(uniq([...editableKeys, ...keys]));
+  // };
+
+  const handleSearch = () => {};
+
+  const handleDelete = (item: IManageAssessmentIndex) => {};
+
+  useEffect(() => {
+    getList();
+  }, []);
 
   return (
     <PageContainer title="设置指标">
-      <Form labelCol={{ span: 4, offset: 3 }} form={form} size="large">
+      <Form
+        labelCol={{ span: 4, offset: 3 }}
+        form={form}
+        size="large"
+        className={style.settingForm}
+      >
         <Form.Item label="指标总分值">
           <Button type="primary">计算</Button>
 
@@ -48,10 +85,10 @@ const SettingIndexPage: FC = () => {
         </Form.Item>
         <Form.Item required label="考核指标">
           <Form.Item noStyle name="list">
-            <EditableProTable<TableIndexType>
+            <EditableProTable<IManageAssessmentIndex>
               className="custom-pro-table mw650"
               actionRef={actionRef}
-              editableFormRef={tableRef}
+              // editableFormRef={tableRef}
               rowKey="id"
               style={{ marginTop: -15 }}
               recordCreatorProps={false}
@@ -70,49 +107,54 @@ const SettingIndexPage: FC = () => {
                 },
                 {
                   title: "填报方式",
-                  dataIndex: "type",
+                  dataIndex: "fill",
                   align: "center",
                   width: "230px",
-                  renderFormItem: () => (
-                    <Radio.Group>
-                      <Radio value="point">手动填报</Radio>
-                      <Radio value="api">
-                        API{" "}
-                        <Tooltip title="以 type,start_date,end_date请求API数据。当API获取数据失败时,将自动转为手动填报">
-                          <Tag bordered={false} color="warning">
-                            注
-                          </Tag>
-                        </Tooltip>
-                      </Radio>
-                    </Radio.Group>
-                  ),
+                  // renderFormItem: () => (
+                  //   <Radio.Group>
+                  //     <Radio value="point">手动填报</Radio>
+                  //     <Radio value="api">
+                  //       API{" "}
+                  //       <Tooltip title="以 type,start_date,end_date请求API数据。当API获取数据失败时,将自动转为手动填报">
+                  //         <Tag bordered={false} color="warning">
+                  // 
+                  //         </Tag>
+                  //       </Tooltip>
+                  //     </Radio>
+                  //   </Radio.Group>
+                  // ),
                 },
                 {
                   title: "分值",
-                  dataIndex: "num",
+                  dataIndex: "score",
                   align: "center",
                   width: "130px",
-                  formItemProps: () => {
-                    return {
-                      rules: [{ required: true, message: "此项为必填项" }],
-                    };
-                  },
-                  renderFormItem: () => (
-                    <InputNumber
-                      variant="borderless"
-                      size="small"
-                      precision={0}
-                      placeholder="请填入正整数"
-                      className="w100"
-                    />
-                  ),
+                  // formItemProps: () => {
+                  //   return {
+                  //     rules: [{ required: true, message: "此项为必填项" }],
+                  //   };
+                  // },
+                  // renderFormItem: () => (
+                  //   <InputNumber
+                  //     variant="borderless"
+                  //     size="small"
+                  //     precision={0}
+                  //     placeholder="请填入正整数"
+                  //     className="w100"
+                  //   />
+                  // ),
                 },
                 {
                   title: "操作",
                   align: "center",
                   valueType: "option",
-                  render: () => {
-                    return null;
+                  render: (node, row) => {
+                    return (
+                      <DageTableActions
+                        showEdit={false}
+                        onDelete={handleDelete.bind(undefined, row)}
+                      />
+                    );
                   },
                 },
               ]}
@@ -136,10 +178,11 @@ const SettingIndexPage: FC = () => {
               }
               toolBarRender={() => [
                 <Search
+                  value={keyword}
                   placeholder="请输入要搜索的指标名称"
                   style={{ maxWidth: 335 }}
                   onChange={(v) => setKeyword(v.target.value)}
-                  onSearch={() => {}}
+                  onSearch={handleSearch}
                   onReset={() => {}}
                 />,
               ]}
@@ -150,26 +193,27 @@ const SettingIndexPage: FC = () => {
                   return [defaultDoms.delete];
                 },
                 onValuesChange: (record, recordList) => {
-                  form.setFieldValue("deduction", recordList);
+                  // form.setFieldValue("list", recordList);
+                  setEditableKeys(recordList.map((i) => i.id));
                 },
               }}
             />
           </Form.Item>
         </Form.Item>
-        <FormPageFooter onSubmit={handleSubmit} onCancel={() => navigate(-1)} />
       </Form>
 
       <AddIndexModal
-        checkedKeys={editableKeys}
         open={indexModalVisible}
         onOk={handleAddIndexItem}
         onCancel={() => setIndexModalVisible(false)}
       />
       <AddIndexTemplateModal
         open={indexTemplateModalVisible}
-        onOk={() => {}}
+        onOk={handleAddIndexItem}
         onCancel={() => setIndexTemplateModalVisible(false)}
       />
+
+      {loading && <DageLoading />}
     </PageContainer>
   );
 };

+ 3 - 1
src/pages/Management/Index/index.tsx

@@ -226,7 +226,9 @@ const ManagementIndexPage = () => {
                           type="text"
                           className={style.button}
                           onClick={() =>
-                            navigate("/management/index/setting-index")
+                            navigate(
+                              `/management/index/setting-index/${item.type}/${item.id}`
+                            )
                           }
                         >
                           设置指标

+ 1 - 1
src/router/index.tsx

@@ -90,7 +90,7 @@ export const DEFAULT_MENU: DageRouteItem[] = [
           },
           {
             hide: true,
-            path: "/management/index/setting-index",
+            path: "/management/index/setting-index/:type/:id",
             title: "设置指标",
             Component: React.lazy(
               () => import("../pages/Management/Index/SettingIndex")

+ 10 - 0
src/types/management.ts

@@ -1,3 +1,4 @@
+import { YES_OR_NO } from ".";
 import { ASS_INDEX_TYPE } from "./assessment";
 
 /**
@@ -29,3 +30,12 @@ export interface IManageIndexDetail {
     suffix: string;
   }[];
 }
+
+export interface IManageAssessmentIndex {
+  id: number;
+  score: number;
+  level: number;
+  isPoint: YES_OR_NO;
+  fill: string;
+  name: string;
+}

+ 8 - 4
src/utils/index.ts

@@ -1,6 +1,7 @@
 import { removeTokenInfo } from "@dage/pc-components";
 import { logoutApi } from "@/api";
 import { Key } from "react";
+import { AssIndexTreeItemType } from "@/types";
 
 export const logout = async () => {
   await logoutApi();
@@ -9,12 +10,15 @@ export const logout = async () => {
   globalThis.location.href = "#/login";
 };
 
-export const getSelectedNodes = (selectedKeys: Key[], treeData: any[]) => {
-  let selectedNodes: any[] = [];
+export const getSelectedNodes = (
+  selectedKeys: Key[],
+  treeData: AssIndexTreeItemType[]
+) => {
+  let selectedNodes: AssIndexTreeItemType[] = [];
 
-  const findNodes = (keys: Key[], data: any[]) => {
+  const findNodes = (keys: Key[], data: AssIndexTreeItemType[]) => {
     data.forEach((node) => {
-      if (keys.includes(node.id) && !node.children) {
+      if (keys.includes(node.id) && !node.children?.length) {
         selectedNodes.push(node);
       }
       if (node.children) {