From 44b2dd9d0500d3fb5265a88aded8faa525a2be68 Mon Sep 17 00:00:00 2001 From: lzh Date: Thu, 16 Apr 2026 23:08:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(@vben/web-antd):=20=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=89=8D=E7=AB=AF=E9=A1=B5=E9=9D=A2=E5=92=8C?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E6=8B=A6=E6=88=AA=E5=99=A8=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/web-antd/src/api/request.ts | 4 + apps/web-antd/src/api/system/project/index.ts | 48 +++++ .../web-antd/src/views/system/project/data.ts | 171 ++++++++++++++++++ .../src/views/system/project/index.vue | 169 +++++++++++++++++ .../src/views/system/project/modules/form.vue | 84 +++++++++ packages/stores/src/modules/access.ts | 9 + 6 files changed, 485 insertions(+) create mode 100644 apps/web-antd/src/api/system/project/index.ts create mode 100644 apps/web-antd/src/views/system/project/data.ts create mode 100644 apps/web-antd/src/views/system/project/index.vue create mode 100644 apps/web-antd/src/views/system/project/modules/form.vue diff --git a/apps/web-antd/src/api/request.ts b/apps/web-antd/src/api/request.ts index 2568def87..cc1a6c98e 100644 --- a/apps/web-antd/src/api/request.ts +++ b/apps/web-antd/src/api/request.ts @@ -86,6 +86,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { config.headers['visit-tenant-id'] = tenantEnable ? accessStore.visitTenantId : undefined; + // 添加项目编号 + config.headers['project-id'] = accessStore.projectId; // 是否 API 加密 if ((config.headers || {}).isEncrypt) { @@ -182,6 +184,8 @@ baseRequestClient.addRequestInterceptor({ config.headers['visit-tenant-id'] = tenantEnable ? accessStore.visitTenantId : undefined; + // 添加项目编号 + config.headers['project-id'] = accessStore.projectId; return config; }, }); diff --git a/apps/web-antd/src/api/system/project/index.ts b/apps/web-antd/src/api/system/project/index.ts new file mode 100644 index 000000000..4d767fb74 --- /dev/null +++ b/apps/web-antd/src/api/system/project/index.ts @@ -0,0 +1,48 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace SystemProjectApi { + export interface Project { + id?: number; + name: string; + code: string; + status: number; + contactName?: string; + contactMobile?: string; + address?: string; + remark?: string; + createTime?: Date; + } +} + +export function getProjectPage(params: PageParam) { + return requestClient.get>( + '/system/project/page', + { params }, + ); +} + +export function getSimpleProjectList() { + return requestClient.get( + '/system/project/simple-list', + ); +} + +export function getProject(id: number) { + return requestClient.get( + `/system/project/get?id=${id}`, + ); +} + +export function createProject(data: SystemProjectApi.Project) { + return requestClient.post('/system/project/create', data); +} + +export function updateProject(data: SystemProjectApi.Project) { + return requestClient.put('/system/project/update', data); +} + +export function deleteProject(id: number) { + return requestClient.delete(`/system/project/delete?id=${id}`); +} diff --git a/apps/web-antd/src/views/system/project/data.ts b/apps/web-antd/src/views/system/project/data.ts new file mode 100644 index 000000000..d4eb1080a --- /dev/null +++ b/apps/web-antd/src/views/system/project/data.ts @@ -0,0 +1,171 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { z } from '#/adapter/form'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '项目名称', + component: 'Input', + componentProps: { + placeholder: '请输入项目名称', + }, + rules: 'required', + }, + { + fieldName: 'code', + label: '项目编码', + component: 'Input', + componentProps: { + placeholder: '请输入项目编码', + }, + rules: 'required', + }, + { + fieldName: 'status', + label: '项目状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + buttonStyle: 'solid', + optionType: 'button', + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'contactName', + label: '联系人', + component: 'Input', + componentProps: { + placeholder: '请输入联系人', + }, + }, + { + fieldName: 'contactMobile', + label: '联系手机', + component: 'Input', + componentProps: { + placeholder: '请输入联系手机', + }, + rules: 'mobile', + }, + { + fieldName: 'address', + label: '项目地址', + component: 'Input', + componentProps: { + placeholder: '请输入项目地址', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '项目名称', + component: 'Input', + componentProps: { + placeholder: '请输入项目名称', + allowClear: true, + }, + }, + { + fieldName: 'code', + label: '项目编码', + component: 'Input', + componentProps: { + placeholder: '请输入项目编码', + allowClear: true, + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + placeholder: '请选择状态', + allowClear: true, + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { + field: 'id', + title: '项目编号', + minWidth: 100, + }, + { + field: 'name', + title: '项目名称', + minWidth: 180, + }, + { + field: 'code', + title: '项目编码', + minWidth: 180, + }, + { + field: 'contactName', + title: '联系人', + minWidth: 100, + }, + { + field: 'contactMobile', + title: '联系手机', + minWidth: 180, + }, + { + field: 'status', + title: '项目状态', + minWidth: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 130, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/system/project/index.vue b/apps/web-antd/src/views/system/project/index.vue new file mode 100644 index 000000000..ecc5cf5b4 --- /dev/null +++ b/apps/web-antd/src/views/system/project/index.vue @@ -0,0 +1,169 @@ + + diff --git a/apps/web-antd/src/views/system/project/modules/form.vue b/apps/web-antd/src/views/system/project/modules/form.vue new file mode 100644 index 000000000..2619ab63a --- /dev/null +++ b/apps/web-antd/src/views/system/project/modules/form.vue @@ -0,0 +1,84 @@ + + diff --git a/packages/stores/src/modules/access.ts b/packages/stores/src/modules/access.ts index 785fffdff..69059a11a 100644 --- a/packages/stores/src/modules/access.ts +++ b/packages/stores/src/modules/access.ts @@ -51,6 +51,10 @@ interface AccessState { * 访问租户编号 */ visitTenantId: null | number; + /** + * 当前项目编号 + */ + projectId: null | number; } /** @@ -105,6 +109,9 @@ export const useAccessStore = defineStore('core-access', { setTenantId(tenantId: null | number) { this.tenantId = tenantId; }, + setProjectId(projectId: null | number) { + this.projectId = projectId; + }, setVisitTenantId(visitTenantId: number) { this.visitTenantId = visitTenantId; }, @@ -121,6 +128,7 @@ export const useAccessStore = defineStore('core-access', { 'accessCodes', 'tenantId', 'visitTenantId', + 'projectId', 'isLockScreen', 'lockScreenPassword', ], @@ -137,6 +145,7 @@ export const useAccessStore = defineStore('core-access', { refreshToken: null, tenantId: null, visitTenantId: null, + projectId: null, }), });