From 494e8947ef6081055fb977f27fa3f43815b1c04b Mon Sep 17 00:00:00 2001
From: LiuJiaNan <15703339975@163.com>
Date: Tue, 4 Aug 2026 17:51:42 +0800
Subject: [PATCH] =?UTF-8?q?=E8=A7=92=E8=89=B2=E9=85=8D=E7=BD=AE=E3=80=81?=
=?UTF-8?q?=E5=8D=95=E4=BD=8D=E7=B1=BB=E5=9E=8B=E9=85=8D=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
package.json | 8 +-
src/api/role/index.js | 14 +
src/api/unitTypeConfig/index.js | 34 ++
src/enumerate/namespace/index.js | 2 +
src/pages/Container/Role/index.js | 61 ++++
src/pages/Container/UnitTypeConfig/index.js | 356 ++++++++++++++++++++
6 files changed, 471 insertions(+), 4 deletions(-)
create mode 100644 src/api/role/index.js
create mode 100644 src/api/unitTypeConfig/index.js
create mode 100644 src/pages/Container/Role/index.js
create mode 100644 src/pages/Container/UnitTypeConfig/index.js
diff --git a/package.json b/package.json
index fae475f..574b43a 100644
--- a/package.json
+++ b/package.json
@@ -6,8 +6,8 @@
"license": "MIT",
"main": "index.js",
"scripts": {
- "serve": "node node_modules/@cqsjjb/scripts/rspack.dev.server.js",
- "build": "node node_modules/@cqsjjb/scripts/rspack.build.js",
+ "serve": "node node_modules/@cqsjjb/scripts/webpack.dev.server.js",
+ "build": "node node_modules/@cqsjjb/scripts/webpack.build.js",
"push": "jjb-cmd push java production",
"clean-cache": "rimraf node_modules/.cache/webpack",
"serve:development": "cross-env NODE_ENV=development npm run serve",
@@ -31,12 +31,12 @@
"lodash-es": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "zy-react-library": "^1.2.6"
+ "zy-react-library": "^1.3.29"
},
"devDependencies": {
"@antfu/eslint-config": "^5.4.1",
"@babel/plugin-proposal-decorators": "^7.19.3",
- "@cqsjjb/scripts": "latest",
+ "@cqsjjb/scripts": "2.0.0",
"@eslint-react/eslint-plugin": "^2.2.2",
"cross-env": "^7.0.3",
"eslint": "^9.37.0",
diff --git a/src/api/role/index.js b/src/api/role/index.js
new file mode 100644
index 0000000..5c2820a
--- /dev/null
+++ b/src/api/role/index.js
@@ -0,0 +1,14 @@
+import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
+
+export const getRoles = declareRequest(
+ "roleLoading",
+ "Get > /system/operation/roles",
+);
+export const getRoleUnits = declareRequest(
+ "roleLoading",
+ "Get > /appmenu/roleUnit/listAll",
+);
+export const updateRole = declareRequest(
+ "roleLoading",
+ "Put > @/appmenu/roleUnit/edit",
+);
diff --git a/src/api/unitTypeConfig/index.js b/src/api/unitTypeConfig/index.js
new file mode 100644
index 0000000..8f0f063
--- /dev/null
+++ b/src/api/unitTypeConfig/index.js
@@ -0,0 +1,34 @@
+import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
+
+export const getUnitTypeConfigList = declareRequest(
+ "unitTypeConfigLoading",
+ "Post > @/appmenu/tenantTypeConfig/list",
+);
+export const saveUnitTypeConfig = declareRequest(
+ "unitTypeConfigLoading",
+ "Post > @/appmenu/tenantTypeConfig/save",
+);
+export const editUnitTypeConfig = declareRequest(
+ "unitTypeConfigLoading",
+ "Put > @/appmenu/tenantTypeConfig/edit",
+);
+export const getUnitTypeConfigDetail = declareRequest(
+ "unitTypeConfigLoading",
+ "Get > /appmenu/tenantTypeConfig/{id}",
+);
+export const deleteUnitTypeConfig = declareRequest(
+ "unitTypeConfigLoading",
+ "Delete > @/appmenu/tenantTypeConfig/{id}",
+);
+export const verifyUnitTypeConfig = declareRequest(
+ "unitTypeConfigLoading",
+ "Put > @/appmenu/tenantTypeConfig/verify",
+);
+export const getFullServiceMenu = declareRequest(
+ "unitTypeConfigLoading",
+ "Get > /base/menus/full-service",
+);
+export const getTenantTypes = declareRequest(
+ "unitTypeConfigLoading",
+ "Get > /system/operation/tenant-types",
+);
diff --git a/src/enumerate/namespace/index.js b/src/enumerate/namespace/index.js
index 5d2c564..e3aace7 100644
--- a/src/enumerate/namespace/index.js
+++ b/src/enumerate/namespace/index.js
@@ -10,3 +10,5 @@ export const NS_NOTICE = defineNamespace("Notice");
export const NS_NoticeReadRecord = defineNamespace("NoticeReadRecord");
export const NS_CORPINFO = defineNamespace("corpInfo");
export const NS_TODO_LIST = defineNamespace("toDoList");
+export const NS_ROLE = defineNamespace("role");
+export const NS_UNIT_TYPE_CONFIG = defineNamespace("unitTypeConfig");
diff --git a/src/pages/Container/Role/index.js b/src/pages/Container/Role/index.js
new file mode 100644
index 0000000..bd19652
--- /dev/null
+++ b/src/pages/Container/Role/index.js
@@ -0,0 +1,61 @@
+import { Connect } from "@cqsjjb/jjb-dva-runtime";
+import { message } from "antd";
+import { useEffect, useState } from "react";
+import FormBuilder from "zy-react-library/components/FormBuilder";
+import Page from "zy-react-library/components/Page";
+import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
+import { NS_ROLE } from "~/enumerate/namespace";
+
+function Role(props) {
+ const [roles, setRoles] = useState([]);
+ const [form] = FormBuilder.useForm();
+
+ const getRoles = async () => {
+ const { data } = await props.getRoles({ pageIndex: 1, pageSize: 1000 });
+ setRoles(data);
+ };
+ const getRoleUnits = async () => {
+ const { data } = await props.getRoleUnits();
+ form.setFieldValue("roleId", data.map(item => item.roleId));
+ };
+
+ useEffect(() => {
+ getRoles();
+ getRoleUnits();
+ }, []);
+
+ const onSubmit = async (values) => {
+ const { success } = await props.updateRole({
+ roles: roles.filter(item => values.roleId.includes(item.id)).map(item => ({
+ roleId: item.id,
+ roleName: item.roleName,
+ })),
+ });
+ if (success) {
+ message.success("保存成功");
+ getRoleUnits();
+ }
+ };
+
+ return (
+
+
+
+ );
+}
+
+export default Connect([NS_ROLE], true)(Role);
diff --git a/src/pages/Container/UnitTypeConfig/index.js b/src/pages/Container/UnitTypeConfig/index.js
new file mode 100644
index 0000000..0ec3f69
--- /dev/null
+++ b/src/pages/Container/UnitTypeConfig/index.js
@@ -0,0 +1,356 @@
+import useUrlState from "@ahooksjs/use-url-state";
+import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
+import { Connect } from "@cqsjjb/jjb-dva-runtime";
+import { Button, message, Modal, Space } from "antd";
+import { useEffect, useState } from "react";
+import FormBuilder from "zy-react-library/components/FormBuilder";
+import AddIcon from "zy-react-library/components/Icon/AddIcon";
+import BackIcon from "zy-react-library/components/Icon/BackIcon";
+import Page from "zy-react-library/components/Page";
+import DictionarySelect from "zy-react-library/components/Select/Dictionary";
+import BasicSelectTree from "zy-react-library/components/SelectTree/Basic";
+import Table from "zy-react-library/components/Table";
+import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
+import useTable from "zy-react-library/hooks/useTable";
+import { STRONG_PASSWORD } from "zy-react-library/regular";
+import { getLabelName } from "zy-react-library/utils";
+import { NS_UNIT_TYPE_CONFIG } from "~/enumerate/namespace";
+
+function List(props) {
+ const [addModalVisible, setAddModalVisible] = useState(false);
+ const [currentId, setCurrentId] = useState("");
+
+ const [urlState, setUrlState] = useUrlState({
+ parentId: "0",
+ parentName: "",
+ }, {
+ navigateMode: "replace",
+ });
+
+ const { tableProps, getData } = useTable(props["getUnitTypeConfigList"], {
+ params: () => ({ parentId: urlState.parentId }),
+ manual: true,
+ });
+
+ useEffect(() => {
+ getData();
+ }, [urlState.parentId]);
+
+ const onDelete = (record) => {
+ Modal.confirm({
+ title: "删除确认",
+ content: `确定要删除【${record.tenantTypeName}】吗`,
+ onOk: async () => {
+ const { success } = await props["deleteUnitTypeConfig"]({ id: record.id });
+ if (success) {
+ message.success("删除成功");
+ getData();
+ }
+ },
+ });
+ };
+
+ return (
+
+ (
+
+ {
+ urlState.parentId !== "0" && (
+ }
+ onClick={() => {
+ setUrlState({
+ parentId: "0",
+ parentName: "",
+ });
+ }}
+ type="primary"
+ ghost
+ >
+ 返回
+
+ )
+ }
+ )}
+ onClick={() => {
+ setAddModalVisible(true);
+ }}
+ >
+ 新增
+
+
+ )}
+ columns={[
+ {
+ title: "单位类型",
+ dataIndex: "tenantTypeName",
+ render: (_, record) => (
+ urlState.parentId === "0"
+ ? (
+
+ )
+ : record.tenantTypeName
+ ),
+ },
+ { title: "编码", dataIndex: "code" },
+ {
+ title: "操作",
+ width: 150,
+ fixed: "right",
+ render: (_, record) => (
+
+
+
+
+ ),
+ },
+ ]}
+ {...tableProps}
+ />
+ {
+ addModalVisible && (
+ {
+ setAddModalVisible(false);
+ setCurrentId("");
+ }}
+ />
+ )
+ }
+
+ );
+}
+
+const AddModalComponent = (props) => {
+ const { parentId, id } = props;
+
+ const [tenantTypes, setTenantTypes] = useState([]);
+ const [fullServiceMenu, setFullServiceMenu] = useState([]);
+ const [form] = FormBuilder.useForm();
+
+ const getData = async () => {
+ if (id) {
+ const { data } = await props["getUnitTypeConfigDetail"]({ id });
+ form.setFieldsValue({
+ ...data,
+ menuIds: data.menuIds?.split(",") || [],
+ });
+ }
+ };
+
+ const getTenantTypes = async () => {
+ if (parentId !== "0") {
+ const { data } = await props["getTenantTypes"]({ pageIndex: 1, pageSize: 1000 });
+ setTenantTypes(data);
+ }
+ };
+
+ const getFullServiceMenu = async () => {
+ if (parentId !== "0") {
+ const { data } = await props["getFullServiceMenu"]();
+ const appList = data[0].appList;
+ for (let i = 0; i < appList.length; i++) {
+ appList[i].menuName = appList[i].appName;
+ appList[i].children = appList[i].menuList;
+ }
+ setFullServiceMenu(appList);
+ }
+ };
+
+ useEffect(() => {
+ getData();
+ getTenantTypes();
+ getFullServiceMenu();
+ }, []);
+
+ const onActualSubmission = async (values) => {
+ const { success } = await props[id ? "editUnitTypeConfig" : "saveUnitTypeConfig"]({
+ ...values,
+ id,
+ level: parentId === "0" ? 1 : 2,
+ parentId,
+ menuIds: values.menuIds?.join(","),
+ });
+ if (success) {
+ message.success(`${id ? "编辑" : "添加"}成功`);
+ props.onCancel();
+ props.getData();
+ }
+ };
+
+ const onSubmit = async (values) => {
+ if (parentId !== "0") {
+ const { data } = await props["verifyUnitTypeConfig"]({
+ defaultType: values.defaultType,
+ id,
+ });
+ if (!data.available) {
+ Modal.confirm({
+ title: "温馨提示",
+ content: data.msg,
+ onOk: async () => {
+ onActualSubmission(values);
+ },
+ });
+ return;
+ }
+ }
+ onActualSubmission(values);
+ };
+
+ return (
+
+ {
+ if (value) {
+ const { data } = await props["verifyUnitTypeConfig"]({
+ tenantTypeId: value,
+ id,
+ });
+ return data.available ? Promise.resolve() : Promise.reject(new Error(data.msg));
+ }
+ else {
+ Promise.resolve();
+ }
+ },
+ validateTrigger: "onChange",
+ },
+ ],
+ formItemProps: { validateTrigger: ["onChange"] },
+ componentProps: {
+ onChange: (value) => {
+ form.setFieldValue("tenantTypeName", getLabelName({
+ list: tenantTypes,
+ status: value,
+ nameKey: "tenantTypeName",
+ idKey: "id",
+ }));
+ },
+ },
+ },
+ { name: "tenantTypeName", label: "单位类型名称", onlyForLabel: true },
+ {
+ name: "code",
+ label: "编码",
+ render: FORM_ITEM_RENDER_ENUM.INTEGER,
+ rules: [
+ {
+ validator: async (_, value) => {
+ if (value) {
+ const { data } = await props["verifyUnitTypeConfig"]({
+ code: value,
+ id,
+ });
+ return data.available ? Promise.resolve() : Promise.reject(new Error(data.msg));
+ }
+ else {
+ Promise.resolve();
+ }
+ },
+ validateTrigger: "onBlur",
+ },
+ ],
+ formItemProps: { validateTrigger: ["onChange", "onBlur"] },
+ },
+ {
+ name: "defaultType",
+ label: "默认单位类型",
+ required: false,
+ render: (
+ {
+ form.setFieldValue("defaultTypeName", label);
+ }}
+ />
+ ),
+ },
+ { name: "defaultTypeName", label: "默认单位类型名称", onlyForLabel: true },
+ {
+ name: "password",
+ label: "初始密码",
+ rules: [{ pattern: STRONG_PASSWORD, message: "密码至少8个字符,包含大小写字母、数字和特殊字符" }],
+ },
+ {
+ name: "menuIds",
+ label: "关联菜单",
+ render: (
+
+ ),
+ },
+ ]}
+ labelCol={{ span: 10 }}
+ span={24}
+ showActionButtons={false}
+ form={form}
+ onFinish={onSubmit}
+ />
+
+ );
+};
+
+const AddModal = Connect([NS_UNIT_TYPE_CONFIG], true)(AddModalComponent);
+export default Connect([NS_UNIT_TYPE_CONFIG], true)(Permission(List));