chenlei 9 ヶ月 前
コミット
94cb524ad5

+ 29 - 0
src/App.scss

@@ -40,6 +40,7 @@ ul {
 body {
   font-family: Source Han Sans CN-Regular;
   font-size: 16px;
+  color: #242424;
 }
 
 .limit-line {
@@ -56,6 +57,14 @@ body {
   -webkit-line-clamp: 2;
 }
 
+.w100 {
+  width: 100%;
+}
+
+.w160 {
+  width: 160px;
+}
+
 .w220 {
   width: 220px;
 }
@@ -64,6 +73,10 @@ body {
   width: 450px;
 }
 
+.mw650 {
+  max-width: 650px;
+}
+
 * {
   box-sizing: border-box;
 }
@@ -91,3 +104,19 @@ body {
 .page-table {
   margin-top: 20px;
 }
+
+.cus-table {
+  .ant-table-content {
+    .ant-table-thead {
+      .ant-table-cell {
+        background: rgba(46, 175, 255, 0.15);
+      }
+    }
+    .ant-table-cell {
+      padding: 6px 16px;
+    }
+    .ant-table-tbody {
+      background: rgba(217, 217, 217, 0.1);
+    }
+  }
+}

ファイルの差分が大きいため隠しています
+ 5 - 0
src/assets/icons/icon_achievements.svg


ファイルの差分が大きいため隠しています
+ 13 - 0
src/assets/icons/icon_check.svg


ファイルの差分が大きいため隠しています
+ 6 - 0
src/assets/icons/icon_management.svg


ファイルの差分が大きいため隠しています
+ 8 - 0
src/assets/icons/systems.svg


BIN
src/assets/images/logo.png


+ 15 - 0
src/components/PageContainer/index.scss

@@ -0,0 +1,15 @@
+.page-container {
+  &-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: 25px;
+    margin-bottom: 20px;
+    height: 76px;
+    border-bottom: 1px solid #ececec;
+
+    h3 {
+      font-size: 20px;
+    }
+  }
+}

+ 25 - 0
src/components/PageContainer/index.tsx

@@ -0,0 +1,25 @@
+import { FC, ReactNode } from "react";
+import "./index.scss";
+
+export interface PageContainerProps {
+  title: string;
+  headerSlot?: ReactNode;
+  children?: ReactNode;
+}
+
+export const PageContainer: FC<PageContainerProps> = ({
+  title,
+  headerSlot,
+  children,
+}) => {
+  return (
+    <div className="page-container">
+      <div className="page-container-header">
+        <h3>{title}</h3>
+
+        {headerSlot}
+      </div>
+      <div className="page-container-main">{children}</div>
+    </div>
+  );
+};

+ 1 - 0
src/components/index.ts

@@ -1 +1,2 @@
 export * from "./FormPageFooter";
+export * from "./PageContainer";

+ 22 - 0
src/pages/Assessment/Index/CreateOrEdit/index.module.scss

@@ -0,0 +1,22 @@
+.panel {
+  padding: 10px 0;
+  background: rgba(217, 217, 217, 0.3);
+
+  :global {
+    .ant-form-item {
+      margin: 0;
+
+      &:not(:last-child) {
+        margin-bottom: 10px;
+      }
+    }
+  }
+}
+
+.tips {
+  color: rgba(36, 36, 36, 0.4);
+}
+.required {
+  color: #ff5858;
+  line-height: 32px;
+}

+ 218 - 0
src/pages/Assessment/Index/CreateOrEdit/index.tsx

@@ -0,0 +1,218 @@
+import { FC, useState } from "react";
+import classNames from "classnames";
+import { Col, Form, Input, InputNumber, Radio, Row, Select, Table } from "antd";
+import { DageTableActions } from "@dage/pc-components";
+import { PageContainer } from "@/components";
+import style from "./index.module.scss";
+
+const { TextArea } = Input;
+const CONFIRM_OPTIONS = [
+  {
+    label: "是",
+    value: 1,
+  },
+  {
+    label: "否",
+    value: 0,
+  },
+];
+
+const CreateOrEditIndex: FC = () => {
+  const [form] = Form.useForm();
+  const [fields, setFields] = useState<any[]>([
+    {
+      name: "dfd",
+      value: 1,
+    },
+    {
+      name: "gjqz",
+      value: 1,
+    },
+  ]);
+
+  return (
+    <PageContainer title="新增指标">
+      <Form
+        fields={fields}
+        labelCol={{ span: 4 }}
+        form={form}
+        onFieldsChange={(_, newFields) => {
+          setFields(newFields);
+        }}
+      >
+        <Form.Item label="父级指标">
+          <Select className="mw650" placeholder="请选择" options={[]} />
+        </Form.Item>
+        <Form.Item label="指标名称" required>
+          <Input
+            className="mw650"
+            placeholder="请输入内容,最多20字"
+            showCount
+            maxLength={20}
+          />
+        </Form.Item>
+        <Form.Item label="指标编号">
+          <Input
+            className="mw650"
+            placeholder="请输入内容,最多20字"
+            showCount
+            maxLength={20}
+          />
+        </Form.Item>
+        <Form.Item label="指标说明">
+          <TextArea
+            className="mw650"
+            showCount
+            maxLength={500}
+            placeholder="请输入内容,最多500字"
+            style={{ height: 120, resize: "none" }}
+          />
+        </Form.Item>
+
+        <Form.Item label="打分点" name="dfd">
+          <Radio.Group
+            options={CONFIRM_OPTIONS}
+            optionType="button"
+            buttonStyle="solid"
+          />
+        </Form.Item>
+        <Form.Item label=" " colon={false} style={{ marginTop: -14 }}>
+          <div className={classNames("mw650", style.panel)}>
+            {fields[0].value ? (
+              <>
+                <Form.Item required label="指标分值" labelCol={{ span: 4 }}>
+                  <InputNumber
+                    precision={0}
+                    placeholder="请输入正整数"
+                    className="w160"
+                  />
+                </Form.Item>
+                <Form.Item label="数据API" labelCol={{ span: 4 }}>
+                  <Input placeholder="请输入地址" style={{ width: 427 }} />
+                </Form.Item>
+                <Form.Item label="加分项" labelCol={{ span: 4 }} colon={false}>
+                  <span className={style.tips}>
+                    注:设为加分项后,该指标的分值不会参与父级指标的计算
+                  </span>
+                </Form.Item>
+              </>
+            ) : (
+              <Form.Item label="分值:0" labelCol={{ span: 4 }} colon={false}>
+                <span className={style.tips}>
+                  注:当指标不作为打分点时,分值=该指标各分项分值(除加分项)之和
+                </span>
+              </Form.Item>
+            )}
+          </div>
+        </Form.Item>
+
+        <Form.Item label="告警阈值" name="gjqz">
+          <Radio.Group
+            options={CONFIRM_OPTIONS}
+            optionType="button"
+            buttonStyle="solid"
+          />
+        </Form.Item>
+        {fields[1].value ? (
+          <Form.Item label=" " colon={false} style={{ marginTop: -14 }}>
+            <div
+              className={classNames("mw650", style.panel)}
+              style={{ padding: "10px 30px" }}
+            >
+              <Row gutter={10}>
+                <Col span={8}>
+                  <Select placeholder="请选择" options={[]} />
+                </Col>
+                <Col span={12}>
+                  <InputNumber
+                    precision={0}
+                    placeholder="请输入正整数"
+                    className="w100"
+                  />
+                </Col>
+                <Col span={4}>
+                  <span className={style.required}>(必填)</span>
+                </Col>
+              </Row>
+
+              <Radio.Group
+                options={[
+                  {
+                    label: "与",
+                    value: 0,
+                  },
+                  {
+                    label: "否",
+                    value: 1,
+                  },
+                ]}
+                style={{ margin: "3px 0" }}
+              />
+
+              <Row gutter={10}>
+                <Col span={8}>
+                  <Select placeholder="请选择" options={[]} />
+                </Col>
+                <Col span={12}>
+                  <InputNumber
+                    precision={0}
+                    placeholder="请输入正整数"
+                    className="w100"
+                  />
+                </Col>
+                <Col span={4}></Col>
+              </Row>
+            </div>
+          </Form.Item>
+        ) : (
+          ""
+        )}
+
+        <Form.Item label="需上传资料">
+          <Table
+            className="cus-table mw650"
+            columns={[
+              {
+                title: "资料名称",
+                dataIndex: "name",
+                key: "name",
+                align: "center",
+              },
+              {
+                title: "必须上传",
+                dataIndex: "age",
+                key: "age",
+                align: "center",
+              },
+              {
+                title: "模板",
+                dataIndex: "address",
+                key: "address",
+                align: "center",
+              },
+              {
+                title: "操作",
+                align: "center",
+                render: (item: any) => {
+                  return <DageTableActions />;
+                },
+              },
+            ]}
+          />
+        </Form.Item>
+
+        <Form.Item required label="排序值">
+          <InputNumber
+            precision={0}
+            min={1}
+            max={999}
+            placeholder="请输入1~999的数字。数字越小,排序越靠前"
+            className="mw650 w100"
+          />
+        </Form.Item>
+      </Form>
+    </PageContainer>
+  );
+};
+
+export default CreateOrEditIndex;

+ 104 - 0
src/pages/Assessment/Index/components/Container/index.tsx

@@ -0,0 +1,104 @@
+import { FC } from "react";
+import { Table } from "antd";
+import style from "../../index.module.scss";
+
+const dataSource = [
+  {
+    key: "1",
+    name: "胡彦斌",
+    age: 32,
+    address: "西湖区湖底公园1号",
+  },
+  {
+    key: "2",
+    name: "胡彦祖",
+    age: 42,
+    address: "西湖区湖底公园1号",
+  },
+];
+
+export const Container: FC = () => {
+  return (
+    <div className={style.container}>
+      <h4 className={style.containerTitle}>指标详情</h4>
+
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>指标名称</p>
+        <div className={style.tableItemInner}>0-0-0-0</div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>指标编号</p>
+        <div className={style.tableItemInner}>0-0-0-0</div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>指标说明</p>
+        <div className={style.tableItemInner}>
+          善良和谦虚是永远不应令人厌恶的两种品德。 —— 斯蒂文生
+        </div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>是否为打分点</p>
+        <div className={style.tableItemInner}>是</div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>数据API</p>
+        <div className={style.tableItemInner}>数据API</div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>是否为加分项</p>
+        <div className={style.tableItemInner}>是</div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>告警阈值</p>
+        <div className={style.tableItemInner}>
+          {">"}50 或 {"<"}20
+        </div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>分值</p>
+        <div className={style.tableItemInner}>100</div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>需上传资料</p>
+        <div className={style.tableItemInner}>
+          <Table
+            className="cus-table"
+            dataSource={dataSource}
+            columns={[
+              {
+                title: "资料名称",
+                dataIndex: "name",
+                key: "name",
+                align: "center",
+              },
+              {
+                title: "必须上传",
+                dataIndex: "age",
+                key: "age",
+                align: "center",
+              },
+              {
+                title: "模板",
+                dataIndex: "address",
+                key: "address",
+                align: "center",
+              },
+            ]}
+          />
+        </div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>排序值</p>
+        <div className={style.tableItemInner}>88</div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>编辑时间</p>
+        <div className={style.tableItemInner}>2020-02-02 12:12</div>
+      </div>
+      <div className={style.tableItem}>
+        <p className={style.tableItemLabel}>编辑人</p>
+        <div className={style.tableItemInner}>张三</div>
+      </div>
+    </div>
+  );
+};

+ 70 - 0
src/pages/Assessment/Index/components/Sidebar/index.tsx

@@ -0,0 +1,70 @@
+import { FC } from "react";
+import { Button, TreeDataNode } from "antd";
+import { DataNode } from "antd/es/tree";
+import { useNavigate } from "react-router-dom";
+import { DageTreeActions } from "@dage/pc-components";
+import { PlusOutlined } from "@ant-design/icons";
+import style from "../../index.module.scss";
+
+const treeData: TreeDataNode[] = [
+  {
+    title: "parent 1",
+    key: "0-0",
+    children: [
+      {
+        title: "leaf",
+        key: "0-0-0",
+      },
+      {
+        title: "leaf",
+        key: "0-0-1",
+        children: [
+          {
+            title: "leaf leaf",
+            key: "0-1-1",
+          },
+        ],
+      },
+    ],
+  },
+];
+
+let key = 0;
+
+export const Sidebar: FC = () => {
+  const navigate = useNavigate();
+
+  const handleAddNode = async (item: DataNode) => {
+    return new Promise((res) => {
+      setTimeout(() => {
+        if (!item.children) {
+          item.children = [
+            {
+              title: "leaf",
+              key: "0-0-0" + key++,
+            },
+          ];
+        }
+        res(true);
+      }, 1000);
+    });
+  };
+
+  return (
+    <div className={style.sidebar}>
+      <div className={style.sidebarHeader}>
+        <h4>指标列表</h4>
+
+        <Button
+          type="primary"
+          icon={<PlusOutlined />}
+          onClick={() => navigate("/assessment/index/create")}
+        >
+          新增指标
+        </Button>
+      </div>
+
+      <DageTreeActions treeData={treeData} onAdd={handleAddNode} />
+    </div>
+  );
+};

+ 64 - 1
src/pages/Assessment/Index/index.module.scss

@@ -1,11 +1,74 @@
 .page {
   display: flex;
-  min-height: 100%;
+  gap: 40px;
+  min-height: calc(100vh - 60px - 50px - 96px);
+}
+
+.pageTools {
+  flex: 1;
+
+  :global {
+    .ant-btn {
+      font-size: 12px;
+      border-radius: 5px;
+
+      & + .ant-btn {
+        margin-left: 10px;
+      }
+    }
+  }
 }
 
 .sidebar {
+  flex-shrink: 0;
   width: 338px;
   min-height: 100%;
   border-radius: 2px;
   background: rgba(165, 181, 210, 0.1);
+
+  :global {
+    .ant-tree {
+      background: none;
+    }
+    .ant-tree-treenode {
+      padding: 0 15px;
+    }
+  }
+}
+
+.sidebarHeader {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 17px 20px;
+  font-size: 16px;
+
+  :global {
+    .ant-btn {
+      font-size: 12px;
+      background: var(--second-color);
+    }
+  }
+}
+
+.container {
+  padding-right: 40px;
+}
+.containerTitle {
+  font-size: 16px;
+}
+
+.tableItem {
+  display: flex;
+  gap: 30px;
+  margin-top: 30px;
+  line-height: 30px;
+}
+.tableItemLabel {
+  flex-shrink: 0;
+  width: 210px;
+  text-align: right;
+}
+.tableItemInner {
+  min-width: 600px;
 }

+ 23 - 51
src/pages/Assessment/Index/index.tsx

@@ -1,58 +1,30 @@
-import { TreeDataNode } from "antd";
-import { DataNode } from "antd/es/tree";
-import { DageTreeActions } from "@dage/pc-components";
+import { Button } from "antd";
+import { PageContainer } from "@/components";
+import { Sidebar } from "./components/Sidebar";
+import { Container } from "./components/Container";
 import style from "./index.module.scss";
 
-const treeData: TreeDataNode[] = [
-  {
-    title: "parent 1",
-    key: "0-0",
-    children: [
-      {
-        title: "leaf",
-        key: "0-0-0",
-      },
-      {
-        title: "leaf",
-        key: "0-0-1",
-        children: [
-          {
-            title: "leaf leaf",
-            key: "0-1-1",
-          },
-        ],
-      },
-    ],
-  },
-];
-
-let key = 0;
-
 const IndexPage = () => {
-  const handleAddNode = async (item: DataNode) => {
-    return new Promise((res) => {
-      setTimeout(() => {
-        if (!item.children) {
-          item.children = [
-            {
-              title: "leaf",
-              key: "0-0-0" + key++,
-            },
-          ];
-        }
-        res(true);
-      }, 1000);
-    });
-  };
-
   return (
-    <div className={style.page}>
-      <DageTreeActions
-        className={style.sidebar}
-        treeData={treeData}
-        onAdd={handleAddNode}
-      />
-    </div>
+    <PageContainer
+      title="指标管理"
+      headerSlot={
+        <div className={style.pageTools}>
+          <Button type="primary" size="large">
+            定级评估指标
+          </Button>
+          <Button type="primary" ghost size="large">
+            运行评估指标
+          </Button>
+        </div>
+      }
+    >
+      <div className={style.page}>
+        <Sidebar />
+
+        <Container />
+      </div>
+    </PageContainer>
   );
 };
 

+ 28 - 2
src/pages/Layout/components/Menu/index.tsx

@@ -3,7 +3,7 @@ import { FC, memo, useCallback, useMemo } from "react";
 import { useLocation, useNavigate } from "react-router-dom";
 // import { CaretDownOutlined } from "@ant-design/icons";
 import { DageRouteItem } from "@/router";
-import { findRouteByPath } from "../../utils";
+import { findRouteByPath, findVisibleRouteParent } from "../../utils";
 
 export interface LayoutMenuProps extends Omit<MenuProps, "mode" | "items"> {
   /** 菜单内容 */
@@ -15,6 +15,19 @@ export interface LayoutMenuProps extends Omit<MenuProps, "mode" | "items"> {
   maxShowLevel?: number;
 }
 
+const findSelectedKey = (
+  menuData: DageRouteItem[],
+  item: DageRouteItem
+): string | null => {
+  if (!item?.hide) {
+    return item.path;
+  } else {
+    const parent = findVisibleRouteParent(menuData, item.path);
+
+    return parent ? findSelectedKey(menuData, parent) : null;
+  }
+};
+
 export const LayoutMenu: FC<LayoutMenuProps> = memo(
   ({ menuData, maxShowLevel = 2, ...rest }) => {
     const location = useLocation();
@@ -33,6 +46,18 @@ export const LayoutMenu: FC<LayoutMenuProps> = memo(
       return stack;
     }, [menuData, location]);
 
+    const selectedKeys = useMemo(() => {
+      const stack = [];
+      const item = findRouteByPath(menuData, location.pathname);
+
+      if (item) {
+        const target = findSelectedKey(menuData, item);
+        target && stack.push(target);
+      }
+
+      return stack;
+    }, [menuData, location]);
+
     const renderMenuItems = useCallback(
       (list: DageRouteItem[], level = 1): any[] => {
         const stack: DageRouteItem[] = [];
@@ -75,10 +100,11 @@ export const LayoutMenu: FC<LayoutMenuProps> = memo(
 
     return menuData.length ? (
       <Menu
+        key={menuData.length}
         mode="inline"
         // expandIcon={<CaretDownOutlined />}
         items={renderMenuItems(menuData)}
-        selectedKeys={location.pathname.split("/").map((i) => `/${i}`)}
+        selectedKeys={selectedKeys}
         defaultOpenKeys={defaultOpenKeys}
         onClick={handleMenu}
         {...rest}

+ 5 - 2
src/pages/Layout/index.scss

@@ -2,7 +2,7 @@
   min-height: 100vh;
 
   .logo {
-    padding: 20px 20px 0;
+    padding: 12px 0 0;
 
     img {
       width: 100%;
@@ -53,7 +53,7 @@
       background: inherit !important;
 
       .ant-menu-title-content {
-        padding-left: 15px;
+        padding-left: 25px;
       }
       .ant-menu-item {
         margin-inline: 0;
@@ -75,4 +75,7 @@
       line-height: inherit !important;
     }
   }
+  .ant-menu-item-icon {
+    font-size: 30px !important;
+  }
 }

+ 2 - 2
src/pages/Layout/index.tsx

@@ -68,10 +68,10 @@ export default function CustomLayout() {
           <Content
             style={{
               margin: "15px",
-              overflow: "initial",
+              overflow: "auto",
               position: "relative",
               background: "#ffffff",
-              padding: 20,
+              padding: "0 25px 25px",
               borderRadius: 4,
             }}
           >

+ 51 - 24
src/pages/Layout/utils.ts

@@ -1,39 +1,66 @@
-import { DageRouteItem } from "@/router";
+import { DageRouteItem, DEFAULT_MENU, DEFAULT_ADMIN_MENU } from "@/router";
 
-export const getParentMenuItem = (
-  menuItems: DageRouteItem[],
-  path: string
-): null | DageRouteItem => {
-  for (const menuItem of menuItems) {
-    if (path.startsWith(menuItem.path || "")) {
-      return menuItem;
-    }
-    if (menuItem.children) {
-      const parentMenuItem = getParentMenuItem(menuItem.children, path);
-      if (parentMenuItem) {
-        return parentMenuItem;
+const routes = [...DEFAULT_MENU, ...DEFAULT_ADMIN_MENU];
+
+export const findRouteParent = (
+  route: DageRouteItem | null,
+  list: DageRouteItem[]
+): DageRouteItem | null => {
+  if (!route) return null;
+
+  for (const r of list) {
+    if (r.children && r.children.includes(route)) {
+      if (r.hide) {
+        return findRouteParent(r, list);
       }
+      return r;
+    }
+    if (r.children) {
+      const parent = findRouteParent(route, r.children);
+      if (parent) return parent;
     }
   }
   return null;
 };
 
+export const findVisibleRouteParent = (
+  list: DageRouteItem[],
+  targetPath: string
+): DageRouteItem | null => {
+  let result: DageRouteItem | null = null;
+
+  function search(list: DageRouteItem[], path: string): DageRouteItem | null {
+    for (const route of list) {
+      if (route.path === path) {
+        return route;
+      }
+      if (route.children) {
+        const found = search(route.children, path);
+        if (found) {
+          return found;
+        }
+      }
+    }
+    return null;
+  }
+
+  const targetNode = search(list, targetPath);
+  if (targetNode) {
+    result = findRouteParent(targetNode, list);
+  }
+
+  return result;
+};
+
 export const findRouteByPath = (
-  routes: DageRouteItem[],
+  list = routes,
   path: string
 ): DageRouteItem | null => {
-  const temp = path.split("/");
-
-  for (const route of routes) {
-    if (route.path.replace(/\/:[^/]+/g, "") === path) {
+  for (const route of list) {
+    if (route.path === path) {
       return route;
     }
-    if (
-      // 首层没必要向下遍历
-      temp.length !== 2 &&
-      route.path.indexOf(temp[1]) > -1 &&
-      route.children
-    ) {
+    if (route.children) {
       const subRoute = findRouteByPath(route.children, path);
       if (subRoute) {
         return subRoute;

+ 38 - 35
src/pages/Log/index.tsx

@@ -4,6 +4,7 @@ import { Button, DatePicker, Form, FormInstance, Input, Table } from "antd";
 import { debounce } from "lodash";
 import { useCallback, useEffect, useMemo, useRef, useState } from "react";
 import { formatDate } from "@dage/utils";
+import { PageContainer } from "@/components";
 
 const DEFAULT_PARAMS: GetLogListParams = {
   pageNum: 1,
@@ -101,41 +102,43 @@ export default function IndustrialMeta() {
   }, [params]);
 
   return (
-    <div className="log">
-      <Form ref={formRef} layout="inline" onValuesChange={debounceSearch}>
-        <Form.Item label="账号" name="searchKey">
-          <Input
-            className="w220"
-            placeholder="请输入关键字"
-            maxLength={30}
-            showCount
-            allowClear
-          />
-        </Form.Item>
-        <Form.Item label="操作日期" name="date">
-          <RangePicker />
-        </Form.Item>
-        <Form.Item>
-          <Button onClick={handleReset}>重置</Button>
-        </Form.Item>
-      </Form>
+    <PageContainer title="操作日志">
+      <div className="log">
+        <Form ref={formRef} layout="inline" onValuesChange={debounceSearch}>
+          <Form.Item label="账号" name="searchKey">
+            <Input
+              className="w220"
+              placeholder="请输入关键字"
+              maxLength={30}
+              showCount
+              allowClear
+            />
+          </Form.Item>
+          <Form.Item label="操作日期" name="date">
+            <RangePicker />
+          </Form.Item>
+          <Form.Item>
+            <Button onClick={handleReset}>重置</Button>
+          </Form.Item>
+        </Form>
 
-      <Table
-        loading={loading}
-        className="page-table"
-        dataSource={list}
-        columns={COLUMNS}
-        rowKey="id"
-        pagination={{
-          showQuickJumper: true,
-          position: ["bottomCenter"],
-          showSizeChanger: true,
-          current: params.pageNum,
-          pageSize: params.pageSize,
-          total,
-          onChange: paginationChange(),
-        }}
-      />
-    </div>
+        <Table
+          loading={loading}
+          className="page-table"
+          dataSource={list}
+          columns={COLUMNS}
+          rowKey="id"
+          pagination={{
+            showQuickJumper: true,
+            position: ["bottomCenter"],
+            showSizeChanger: true,
+            current: params.pageNum,
+            pageSize: params.pageSize,
+            total,
+            onChange: paginationChange(),
+          }}
+        />
+      </div>
+    </PageContainer>
   );
 }

BIN
src/pages/Login/images/bg-min.jpg


BIN
src/pages/Login/images/bg.jpg


BIN
src/pages/Login/images/icon_ac-min.png


BIN
src/pages/Login/images/icon_account.png


BIN
src/pages/Login/images/icon_password.png


BIN
src/pages/Login/images/icon_pw-min.png


BIN
src/pages/Login/images/logo_black-min.png


+ 19 - 58
src/pages/Login/index.scss

@@ -1,64 +1,28 @@
 .login {
+  display: flex;
   width: 100vw;
   height: 100vh;
   overflow: hidden;
-  background-image: url("./images/bg.jpg");
-  background-size: cover;
 
-  &::before {
-    content: "";
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    background-color: rgba(0, 0, 0, 0.4);
-    z-index: 1;
-  }
   .icon-account,
   .icon-password {
-    margin-right: 24px;
-    width: 26px;
+    margin-right: 15px;
+    width: 40px;
   }
 
-  &-logo {
-    display: flex;
-    flex-direction: column;
-    position: absolute;
-    top: 17.5vh;
-    left: 15vw;
-    z-index: 1;
-
-    &__txt {
-      display: flex;
-      justify-content: space-between;
-      margin-top: 23px;
-      font-size: 24px;
-      color: #ffffff;
-      opacity: 0.6;
-    }
+  &-img {
+    flex: 1;
+    background: url("./images/bg-min.jpg") no-repeat center / cover;
   }
 
   &-form {
-    position: absolute;
-    top: 52%;
-    right: 12vw;
-    width: 550px;
-    height: 646px;
-    padding: 66px 75px;
-    background: rgba(176, 161, 121, 0.2);
-    box-shadow: inset 0px 4px 4px 0px rgba(255, 255, 255, 0.25);
-    border-radius: 3px;
-    transform: translateY(-50%);
-    z-index: 2;
-
-    &__title {
-      margin-bottom: 20px;
-      font-size: 40px;
-      font-family: Source Han Serif CN-Bold;
-      font-weight: bold;
-      color: white;
-    }
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    flex-shrink: 0;
+    width: 795px;
+    height: 100%;
 
     &__input {
       $inputHeight: 85px;
@@ -68,11 +32,11 @@
       .ant-input {
         width: 100%;
         height: $inputHeight;
-        color: #ffffff;
+        color: #464646;
         background-color: transparent;
 
         &::-webkit-input-placeholder {
-          color: #ffffff;
+          color: #464646;
           opacity: 0.6;
         }
         &:-webkit-autofill {
@@ -87,14 +51,14 @@
         width: 100%;
         height: $inputHeight;
         border: none;
-        color: #ffffff;
+        color: #464646;
         font-size: 24px;
-        border-bottom: 1px solid #ffffff;
+        border-bottom: 1px solid #464646;
         border-radius: 0;
         background-color: transparent;
       }
       .ant-input-password-icon {
-        color: #ffffff !important;
+        color: #a3a3a3 !important;
         opacity: 0.6;
       }
     }
@@ -105,10 +69,7 @@
       .ant-btn {
         font-size: 24px;
         width: 100%;
-        height: 66px;
-        border-radius: 3px;
-        border: 0;
-        background: var(--second-color);
+        height: 70px;
       }
     }
   }

+ 16 - 17
src/pages/Login/index.tsx

@@ -1,14 +1,14 @@
 import { useState } from "react";
 import { Button, Form, Input } from "antd";
 import { useNavigate } from "react-router-dom";
-import { LoginRequest } from "@/types";
-import { login } from "@/api";
 import { Base64 } from "@dage/utils";
 import { encodeStr, setTokenInfo } from "@dage/pc-components";
-import IconAccount from "./images/icon_account.png";
-import IconPassword from "./images/icon_password.png";
-import LogoImage from "../../assets/images/logo.png";
+import { login } from "@/api";
+import { LoginRequest } from "@/types";
 import { DEFAULT_ADMIN_MENU, DEFAULT_MENU } from "@/router";
+import IconAccount from "./images/icon_ac-min.png";
+import IconPassword from "./images/icon_pw-min.png";
+import LogoIcon from "./images/logo_black-min.png";
 import "./index.scss";
 
 export default function Login() {
@@ -41,17 +41,15 @@ export default function Login() {
 
   return (
     <div className="login">
-      <div className="login-logo">
-        <img alt="logo" src={LogoImage} />
-        <div className="login-logo__txt">
-          {"上海工业博物馆后台界面".split("").map((t) => (
-            <span key={t}>{t}</span>
-          ))}
-        </div>
-      </div>
+      <div className="login-img" />
 
       <div className="login-form">
-        <div className="login-form__title">登 录</div>
+        <img
+          alt="logo"
+          className="login-form__logo"
+          src={LogoIcon}
+          draggable={false}
+        />
 
         <Form className="login-form__input" onFinish={handleLogin}>
           <Form.Item
@@ -64,7 +62,7 @@ export default function Login() {
               }
               placeholder="请输入用户名"
               maxLength={15}
-              bordered={false}
+              variant="filled"
             />
           </Form.Item>
           <Form.Item
@@ -75,15 +73,16 @@ export default function Login() {
               prefix={
                 <img className="icon-password" src={IconPassword} alt="密码" />
               }
+              autoComplete="new-password"
               placeholder="请输入用户密码"
               maxLength={15}
-              bordered={false}
+              variant="filled"
             />
           </Form.Item>
 
           {/* 登录按钮 */}
           <div className="login-form__btn">
-            <Button htmlType="submit" loading={loading}>
+            <Button type="primary" htmlType="submit" loading={loading}>
               登 录
             </Button>
           </div>

+ 51 - 48
src/pages/User/index.tsx

@@ -11,9 +11,10 @@ import {
   message,
 } from "antd";
 import { debounce } from "lodash";
+import { DageTableActions } from "@dage/pc-components";
 import { useCallback, useEffect, useMemo, useRef, useState } from "react";
 import UserAdd from "./components/UserAdd";
-import { DageTableActions } from "@dage/pc-components";
+import { PageContainer } from "@/components";
 
 const DEFAULT_PARAMS: GetLogListParams = {
   pageNum: 1,
@@ -175,53 +176,55 @@ export default function IndustrialMeta() {
   }, [delTableFu, isEnabledClickFu, resetPassFu, openEditPageFu]);
 
   return (
-    <div className="user">
-      <Form ref={formRef} layout="inline" onValuesChange={debounceSearch}>
-        <Form.Item label="账号" name="searchKey">
-          <Input
-            className="w220"
-            placeholder="请输入关键字"
-            maxLength={30}
-            showCount
-            allowClear
-          />
-        </Form.Item>
-        <Form.Item>
-          <Button type="primary" onClick={openEditPageFu.bind(undefined, 0)}>
-            新增
-          </Button>
-        </Form.Item>
-        <Form.Item>
-          <Button onClick={handleReset}>重置</Button>
-        </Form.Item>
-      </Form>
-
-      <Table
-        loading={loading}
-        className="page-table"
-        dataSource={list}
-        columns={COLUMNS}
-        rowKey="id"
-        pagination={{
-          showQuickJumper: true,
-          position: ["bottomCenter"],
-          showSizeChanger: true,
-          current: params.pageNum,
-          pageSize: params.pageSize,
-          total,
-          onChange: paginationChange(),
-        }}
-      />
-
-      {/* 点击新增或者编辑 */}
-      {editPageShow ? (
-        <UserAdd
-          id={editId.current}
-          closePage={() => setEditPageShow(false)}
-          upTableList={getList}
-          addTableList={handleReset}
+    <PageContainer title="用户管理">
+      <div className="user">
+        <Form ref={formRef} layout="inline" onValuesChange={debounceSearch}>
+          <Form.Item label="账号" name="searchKey">
+            <Input
+              className="w220"
+              placeholder="请输入关键字"
+              maxLength={30}
+              showCount
+              allowClear
+            />
+          </Form.Item>
+          <Form.Item>
+            <Button type="primary" onClick={openEditPageFu.bind(undefined, 0)}>
+              新增
+            </Button>
+          </Form.Item>
+          <Form.Item>
+            <Button onClick={handleReset}>重置</Button>
+          </Form.Item>
+        </Form>
+
+        <Table
+          loading={loading}
+          className="page-table"
+          dataSource={list}
+          columns={COLUMNS}
+          rowKey="id"
+          pagination={{
+            showQuickJumper: true,
+            position: ["bottomCenter"],
+            showSizeChanger: true,
+            current: params.pageNum,
+            pageSize: params.pageSize,
+            total,
+            onChange: paginationChange(),
+          }}
         />
-      ) : null}
-    </div>
+
+        {/* 点击新增或者编辑 */}
+        {editPageShow ? (
+          <UserAdd
+            id={editId.current}
+            closePage={() => setEditPageShow(false)}
+            upTableList={getList}
+            addTableList={handleReset}
+          />
+        ) : null}
+      </div>
+    </PageContainer>
   );
 }

+ 19 - 6
src/router/index.tsx

@@ -1,17 +1,30 @@
-import { SettingOutlined } from "@ant-design/icons";
 import React from "react";
+import Icon from "@ant-design/icons";
 import { DageRouteItem } from "./types";
+import { ReactComponent as SettingIcon } from "@/assets/icons/systems.svg";
+import { ReactComponent as AssessmentIcon } from "@/assets/icons/icon_check.svg";
 
 export const DEFAULT_MENU: DageRouteItem[] = [
   {
     path: "/assessment",
     title: "考核设置",
-    icon: <SettingOutlined />,
+    icon: <Icon component={AssessmentIcon} />,
+    redirect: "/assessment/index",
     children: [
       {
-        path: "/index",
+        path: "/assessment/index",
         title: "指标设置",
         Component: React.lazy(() => import("../pages/Assessment/Index")),
+        children: [
+          {
+            hide: true,
+            path: "/assessment/index/create",
+            title: "新增指标",
+            Component: React.lazy(
+              () => import("../pages/Assessment/Index/CreateOrEdit")
+            ),
+          },
+        ],
       },
     ],
   },
@@ -21,15 +34,15 @@ export const DEFAULT_ADMIN_MENU: DageRouteItem[] = [
   {
     path: "/setting",
     title: "系统设置",
-    icon: <SettingOutlined />,
+    icon: <Icon component={SettingIcon} />,
     children: [
       {
-        path: "/user",
+        path: "/setting/user",
         title: "用户管理",
         Component: React.lazy(() => import("../pages/User")),
       },
       {
-        path: "/log",
+        path: "/setting/log",
         title: "操作日志",
         Component: React.lazy(() => import("../pages/Log")),
       },