diff --git a/src/apis/common/common.ts b/src/apis/common/common.ts index fb68047..72a56da 100644 --- a/src/apis/common/common.ts +++ b/src/apis/common/common.ts @@ -36,6 +36,11 @@ export function listSiteOptionDict() { return http.get(`${BASE_URL}/dict/option/site`) } +/** @desc 查询菜单类型列表 */ +export function listMenuType() { + return http.get[]>(`${BASE_URL}/list/menu-type`) +} + /** @desc 上传文件 */ export function uploadFile(data: FormData) { return http.post(`${BASE_URL}/file`, data) diff --git a/src/apis/project/budget.ts b/src/apis/project/budget.ts new file mode 100644 index 0000000..689dc3b --- /dev/null +++ b/src/apis/project/budget.ts @@ -0,0 +1,116 @@ +import http from '@/utils/http' + +const BASE_URL = '/project/budget' + +/** 预算记录响应类型 */ +export interface BudgetRecordResp { + id: string + projectId: string + projectName: string + projectCode: string + projectAmount: number + projectManager: string + establishDate: string + deliveryDate: string + client: string + remark: string + applyBudgetAmount: number + applicant: string + applyTime: string + auditStatus: string // 'pending' | 'approved' | 'rejected' + auditStatusLabel: string + auditRemark: string + auditor: string + auditTime: string + budgetProgress: number + usedBudgetAmount: number + remainingBudgetAmount: number +} + +/** 预算项类型 */ +export interface BudgetItemResp { + id?: string + budgetName: string + budgetType: string + budgetAmount: number + budgetDescription: string + attachments?: Array<{ + id: string + name: string + url: string + }> +} + +/** 预算申请请求类型 */ +export interface BudgetApplyReq { + projectId: string + budgetItems: BudgetItemResp[] + totalAmount: number + applyReason?: string +} + +/** 预算审核请求类型 */ +export interface BudgetAuditReq { + auditStatus: 'approved' | 'rejected' + auditRemark: string +} + +/** 预算查询参数 */ +export interface BudgetQuery { + projectName?: string + projectCode?: string + auditStatus?: string + applicant?: string + applyTimeStart?: string + applyTimeEnd?: string +} + +export interface BudgetPageQuery extends BudgetQuery, PageQuery {} + +/** @desc 查询预算记录列表 */ +export function listBudgetRecord(query: BudgetPageQuery) { + return http.get>(`${BASE_URL}/record`, query) +} + +/** @desc 获取预算记录详情 */ +export function getBudgetRecord(id: string) { + return http.get(`${BASE_URL}/record/${id}`) +} + +/** @desc 申请预算 */ +export function applyBudget(data: BudgetApplyReq) { + return http.post(`${BASE_URL}/apply`, data) +} + +/** @desc 审核预算 */ +export function auditBudget(id: string, data: BudgetAuditReq) { + return http.put(`${BASE_URL}/audit/${id}`, data) +} + +/** @desc 获取预算类型选项 */ +export function getBudgetTypes() { + return http.get>(`${BASE_URL}/types`) +} + +/** @desc 上传预算附件 */ +export function uploadBudgetAttachment(file: File) { + const formData = new FormData() + formData.append('file', file) + return http.post<{ id: string; name: string; url: string }>(`${BASE_URL}/upload`, formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +/** @desc 删除预算附件 */ +export function deleteBudgetAttachment(id: string) { + return http.del(`${BASE_URL}/attachment/${id}`) +} + +/** @desc 导出预算记录 */ +export function exportBudgetRecord(query: BudgetQuery) { + return http.get(`${BASE_URL}/export`, query, { + responseType: 'blob' + }) +} \ No newline at end of file diff --git a/src/apis/project/index.ts b/src/apis/project/index.ts index 500aa17..bde6b8a 100644 --- a/src/apis/project/index.ts +++ b/src/apis/project/index.ts @@ -7,11 +7,11 @@ const BASE_URL = '/project' /** @desc 查询项目列表 */ export function listProject(query: T.ProjectPageQuery) { - return http.get>(`${BASE_URL}`, query) + return http.get>(`${BASE_URL}/list`, query) } /** @desc 获取项目详情 */ -export function getProject(id: number) { +export function getProject(id: string | number) { return http.get(`${BASE_URL}/${id}`) } @@ -21,17 +21,17 @@ export function addProject(data: any) { } /** @desc 修改项目 */ -export function updateProject(data: any, id: number) { +export function updateProject(data: any, id: string | number) { return http.put(`${BASE_URL}/${id}`, data) } /** @desc 修改项目状态 */ -export function updateProjectStatus(data: any, id: number) { +export function updateProjectStatus(data: any, id: string | number) { return http.patch(`${BASE_URL}/${id}/status`, data) } /** @desc 删除项目 */ -export function deleteProject(id: number) { +export function deleteProject(id: string | number) { return http.del(`${BASE_URL}/${id}`) } diff --git a/src/apis/project/type.ts b/src/apis/project/type.ts index fde5158..32bc3b7 100644 --- a/src/apis/project/type.ts +++ b/src/apis/project/type.ts @@ -1,26 +1,44 @@ /** 项目类型 */ export interface ProjectResp { - id: number - projectCode: string // 项目编号 + projectId: string // 项目ID (API返回的是字符串) + projectCode?: string // 项目编号 projectName: string // 项目名称 projectIntro?: string // 项目简介 - fieldName: string // 风场名称 - fieldLocation: string // 风场地址 - commissionUnit: string // 委托单位 - commissionContact: string // 委托单位联系人 - commissionPhone: string // 委托单位联系电话 - inspectionUnit: string // 检查单位 - inspectionContact: string // 检查单位联系人 - inspectionPhone: string // 检查单位联系电话 - projectScale: string // 项目规模 - orgNumber: string // 机组型号 - projectCategory: string // 项目类型/服务 - projectManager: string // 项目经理 - projectStaff: string[] // 施工人员 - projectPeriod: [string, string] // 项目周期 - status: string // 状态 + farmName: string // 风场名称 (API字段名是farmName) + farmAddress?: string // 风场地址 (API字段名是farmAddress) + client?: string // 委托单位 + clientContact?: string // 委托单位联系人 + clientPhone?: string // 委托单位联系电话 + inspectionContact?: string // 检查单位联系人 + inspectionPhone?: string // 检查单位联系电话 + inspectionUnit?: string // 检查单位 + projectScale?: string // 项目规模 + scale?: string // 项目规模 (API可能使用scale字段) + turbineModel?: string // 机组型号 (API字段名是turbineModel) + projectCategory?: string // 项目类型/服务 + projectManagerId?: string // 项目经理ID + projectManagerName?: string // 项目经理姓名 + projectStaff?: string[] // 施工人员 + startDate?: string // 开始日期 + endDate?: string // 结束日期 + status: number // 状态 (API返回数字类型) + statusLabel?: string // 状态标签 (API返回的状态文本) + constructorIds?: string // 施工人员ID + constructorName?: string // 施工人员姓名 + coverUrl?: string // 封面URL createDt?: Date updateDt?: Date + + // 为了保持向后兼容,添加一些别名字段 + id?: string // projectId的别名 + fieldName?: string // farmName的别名 + fieldLocation?: string // farmAddress的别名 + commissionUnit?: string // client的别名 + commissionContact?: string // clientContact的别名 + commissionPhone?: string // clientPhone的别名 + orgNumber?: string // turbineModel的别名 + projectManager?: string // projectManagerName的别名 + projectPeriod?: [string, string] // 项目周期 } export interface ProjectQuery { diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue index fccf84b..cccb4ea 100644 --- a/src/components/Breadcrumb/index.vue +++ b/src/components/Breadcrumb/index.vue @@ -16,6 +16,7 @@ diff --git a/src/layout/components/Menu/MenuItem.vue b/src/layout/components/Menu/MenuItem.vue index 2404830..22f94bf 100644 --- a/src/layout/components/Menu/MenuItem.vue +++ b/src/layout/components/Menu/MenuItem.vue @@ -45,13 +45,17 @@ interface Props { const onlyOneChild = ref(null) const isOneShowingChild = ref(false) -const handleFunction = () => { +// 使用watchEffect来响应props变化,避免在setup阶段直接调用 +watchEffect(() => { const children = props.item?.children?.length ? props.item.children : [] // 判断是否只有一个显示的子项 const showingChildren = children.filter((i) => i.meta?.hidden === false) + if (showingChildren.length) { // 保存子项最后一个hidden: false的元素 onlyOneChild.value = showingChildren[showingChildren.length - 1] + } else { + onlyOneChild.value = null } // 当只有一个要显示子路由时, 默认显示该子路由器 @@ -60,11 +64,11 @@ const handleFunction = () => { } // 如果没有要显示的子路由, 则显示父路由 - if (showingChildren.length === 0) { + else if (showingChildren.length === 0) { onlyOneChild.value = { ...props.item, meta: { ...props.item.meta, noShowingChildren: true } } as any isOneShowingChild.value = true + } else { + isOneShowingChild.value = false } -} - -handleFunction() +}) diff --git a/src/layout/components/Menu/index.vue b/src/layout/components/Menu/index.vue index 618942f..ea85dcb 100644 --- a/src/layout/components/Menu/index.vue +++ b/src/layout/components/Menu/index.vue @@ -11,6 +11,12 @@ @menu-item-click="onMenuItemClick" @collapse="onCollapse" > + + diff --git a/src/layout/components/WwAds.vue b/src/layout/components/WwAds.vue index 7cc9990..cea8c9d 100644 --- a/src/layout/components/WwAds.vue +++ b/src/layout/components/WwAds.vue @@ -5,10 +5,10 @@ import { useAppStore } from '@/stores' const appStore = useAppStore() onMounted(() => { - const s = document.createElement('script') - s.async = true - s.src = `https://cdn.wwads.cn/js/makemoney.js` - document.querySelector('.wwads-container')!.appendChild(s) + // const s = document.createElement('script') + // s.async = true + // s.src = `https://cdn.wwads.cn/js/makemoney.js` + // document.querySelector('.wwads-container')!.appendChild(s) }) diff --git a/src/router/route.ts b/src/router/route.ts index 456244c..abe0021 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -12,31 +12,350 @@ export const systemRoutes: RouteRecordRaw[] = [ meta: { hidden: true }, }, { - path: '/', - name: 'Dashboard', + path: '/company', + name: 'Company', component: Layout, - redirect: '/dashboard/workplace', - meta: { title: '仪表盘', icon: 'dashboard', hidden: false }, + redirect: '/company/overview', + meta: { title: '企业概览', icon: 'company', hidden: false, sort: 1 }, children: [ { - path: '/dashboard/workplace', - name: 'Workplace', - component: () => import('@/views/dashboard/workplace/index.vue'), - meta: { title: '工作台', icon: 'desktop', hidden: false, affix: true }, - }, - { - path: '/dashboard/analysis', - name: 'Analysis', - component: () => import('@/views/dashboard/analysis/index.vue'), - meta: { title: '分析页', icon: 'insert-chart', hidden: false }, - }, + path: '/company/overview', + name: 'CompanyOverview', + component: () => import('@/views/company/overview/index.vue'), + meta: { title: '企业概览', icon: 'overview', hidden: false }, + } ], }, { - path: '/project', + path: '/organization', + name: 'Organization', + component: Layout, + redirect: '/organization/hr/member', + meta: { title: '组织架构', icon: 'organization', hidden: false, sort: 2 }, + children: [ + { + path: '/organization/hr', + name: 'HRManagement', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/organization/hr/member', + meta: { title: '人员管理', icon: 'user', hidden: false }, + children: [ + { + path: '/organization/hr/member', + name: 'HRMember', + component: () => import('@/views/system/user/index.vue'), + meta: { title: '成员', icon: 'user', hidden: false }, + }, + { + path: '/organization/hr/dept', + name: 'HRDept', + component: () => import('@/views/system/dept/index.vue'), + meta: { title: '部门', icon: 'dept', hidden: false }, + }, + { + path: '/organization/hr/workload', + name: 'HRWorkload', + component: () => import('@/views/hr/workload/index.vue'), + meta: { title: '工作量', icon: 'workload', hidden: false }, + }, + { + path: '/organization/hr/attendance', + name: 'HRAttendance', + component: () => import('@/views/hr/attendance/index.vue'), + meta: { title: '考勤', icon: 'attendance', hidden: false }, + }, + { + path: '/organization/hr/performance', + name: 'HRPerformance', + component: () => import('@/views/hr/performance/index.vue'), + meta: { title: '绩效', icon: 'performance', hidden: false }, + }, + { + path: '/organization/hr/salary', + name: 'HRSalary', + component: () => import('@/views/hr/salary/index.vue'), + meta: { title: '工资', icon: 'salary', hidden: false }, + }, + { + path: '/organization/hr/contribution', + name: 'HRContribution', + component: () => import('@/views/hr/contribution/index.vue'), + meta: { title: '责献积分制度、与企业共同发展', icon: 'contribution', hidden: false }, + } + ] + }, + { + path: '/organization/role', + name: 'OrganizationRole', + component: () => import('@/views/system/role/index.vue'), + meta: { title: '角色管理', icon: 'role', hidden: false }, + }, + { + path: '/organization/log', + name: 'OrganizationLog', + component: () => import('@/views/monitor/log/index.vue'), + meta: { title: '操作日志', icon: 'log', hidden: false }, + } + ], + }, + { + path: '/products-services', + name: 'ProductsServices', + component: Layout, + redirect: '/products-services/products/hardware/tower-monitoring', + meta: { title: '产品与服务', icon: 'products', hidden: false, sort: 3 }, + children: [ + { + path: '/products-services/products', + name: 'Products', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/products-services/products/hardware/tower-monitoring', + meta: { title: '产品', icon: 'product', hidden: false }, + children: [ + { + path: '/products-services/products/hardware', + name: 'SmartHardware', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/products-services/products/hardware/tower-monitoring', + meta: { title: '智能硬件', icon: 'hardware', hidden: false }, + children: [ + { + path: '/products-services/products/hardware/tower-monitoring', + name: 'TowerMonitoring', + component: () => import('@/views/product/hardware/tower-monitoring/index.vue'), + meta: { title: '风电塔下监测系统', icon: 'monitor', hidden: false }, + }, + { + path: '/products-services/products/hardware/custom-drone', + name: 'CustomDrone', + component: () => import('@/views/product/hardware/custom-drone/index.vue'), + meta: { title: '定制无人机', icon: 'drone', hidden: false }, + }, + { + path: '/products-services/products/hardware/drone-basket', + name: 'DroneBasket', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '无人吊篮', icon: 'basket', hidden: false }, + }, + { + path: '/products-services/products/hardware/blade-robot', + name: 'BladeRobot', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '叶片维修机器人', icon: 'robot', hidden: false }, + } + ] + }, + { + path: '/products-services/products/software', + name: 'SmartSoftware', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/products-services/products/software/field-assistant', + meta: { title: '智能软件', icon: 'software', hidden: false }, + children: [ + { + path: '/products-services/products/software/field-assistant', + name: 'FieldAssistant', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '风电外业智能助手(外业数据实时处理)', icon: 'assistant', hidden: false }, + }, + { + path: '/products-services/products/software/blade-report', + name: 'BladeReportSystem', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '叶片检查报告生成系统', icon: 'report', hidden: false }, + }, + { + path: '/products-services/products/software/ground-station', + name: 'GroundStation', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '无人机地面站软件', icon: 'station', hidden: false }, + } + ] + } + ] + }, + { + path: '/products-services/services', + name: 'Services', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/products-services/services/lightning-detection', + meta: { title: '服务', icon: 'service', hidden: false }, + children: [ + { + path: '/products-services/services/lightning-detection', + name: 'LightningDetection', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '防雷检测', icon: 'lightning', hidden: false }, + }, + { + path: '/products-services/services/blade-internal-detection', + name: 'BladeInternalDetection', + component: () => import('@/views/service/blade-internal-detection/index.vue'), + meta: { title: '叶片内部检测', icon: 'internal', hidden: false }, + }, + { + path: '/products-services/services/blade-external-detection', + name: 'BladeExternalDetection', + component: () => import('@/views/service/blade-internal-detection/index.vue'), + meta: { title: '叶片外部检测', icon: 'external', hidden: false }, + }, + { + path: '/products-services/services/solar-inspection', + name: 'SolarInspection', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '太阳能光伏巡检', icon: 'solar', hidden: false }, + }, + { + path: '/products-services/services/cleaning', + name: 'CleaningService', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '清洗', icon: 'cleaning', hidden: false }, + }, + { + path: '/products-services/services/coating', + name: 'CoatingService', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '喷涂', icon: 'coating', hidden: false }, + }, + { + path: '/products-services/services/dam-crack-detection', + name: 'DamCrackDetection', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '大坝裂缝检测', icon: 'dam', hidden: false }, + }, + { + path: '/products-services/services/bridge-crack-detection', + name: 'BridgeCrackDetection', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '桥梁裂缝检测', icon: 'bridge', hidden: false }, + }, + { + path: '/products-services/services/blade-maintenance', + name: 'BladeMaintenance', + component: () => import('@/views/service/lightning-detection/index.vue'), + meta: { title: '叶片维修', icon: 'maintenance', hidden: false }, + } + ] + } + ], + }, + { + path: '/project-management', + name: 'ProjectManagement', + component: Layout, + redirect: '/project-management/bidding/tender-documents', + meta: { title: '项目管理', icon: 'project', hidden: false, sort: 4 }, + children: [ + { + path: '/project-management/bidding', + name: 'ProjectBidding', + meta: { + title: '项目投标', + icon: 'gavel' + }, + children: [ + { + path: '/project-management/bidding/tender-documents', + name: 'TenderDocuments', + component: () => import('@/views/project-management/bidding/tender-documents/index.vue'), + meta: { + title: '招标文件管理', + icon: 'file-text' + } + }, + { + path: '/project-management/bidding/bid-documents', + name: 'BidDocuments', + component: () => import('@/views/project-management/bidding/bid-documents/index.vue'), + meta: { + title: '投标文件管理', + icon: 'file-text' + } + }, + { + path: '/project-management/bidding/award-notice', + name: 'AwardNotice', + component: () => import('@/views/project-management/bidding/award-notice/index.vue'), + meta: { + title: '中标通知书管理', + icon: 'trophy' + } + } + ] + }, + { + path: '/project-management/contract', + name: 'ProjectContract', + meta: { + title: '合同管理', + icon: 'file-text' + }, + children: [ + { + path: '/project-management/contract/revenue-contract', + name: 'RevenueContract', + component: () => import('@/views/project-management/contract/revenue-contract/index.vue'), + meta: { + title: '收入合同管理', + icon: 'dollar' + } + }, + { + path: '/project-management/contract/expense-contract', + name: 'ExpenseContract', + component: () => import('@/views/project-management/contract/expense-contract/index.vue'), + meta: { + title: '支出合同管理', + icon: 'credit-card' + } + }, + { + path: '/project-management/contract/cost-management', + name: 'CostManagement', + component: () => import('@/views/project-management/contract/cost-management/index.vue'), + meta: { + title: '成本管理', + icon: 'bar-chart' + } + } + ] + }, + { + path: '/project-management/projects', + name: 'ProjectsManagement', + meta: { + title: '项目管理', + icon: 'briefcase' + }, + children: [ + { + path: '/project-management/projects/initiation', + name: 'ProjectInitiation', + component: () => import('@/views/project-management/projects/initiation/index.vue'), + meta: { + title: '立项管理', + icon: 'plus-circle' + } + }, + { + path: '/project-management/projects/management', + name: 'ProjectDetailManagement', + component: () => import('@/views/project-management/projects/management/index.vue'), + meta: { + title: '项目详细管理', + icon: 'settings' + } + } + ] + } + ], + }, + { + path: '/', name: 'Project', component: Layout, - meta: { title: '项目管理', icon: 'project', hidden: false, sort: 2 }, + redirect: '/project', + meta: { title: '项目管理(旧)', icon: 'project-old', hidden: true, sort: 5 }, children: [ { path: '/project', @@ -55,6 +374,18 @@ export const systemRoutes: RouteRecordRaw[] = [ name: 'TaskBoard', component: () => import('@/views/project/task/index.vue'), meta: { title: '任务看板', icon: 'table', hidden: false }, + }, + { + path: '/project/kanban', + name: 'ProjectKanban', + component: () => import('@/views/project/kanban/index.vue'), + meta: { title: '项目进度', icon: 'kanban', hidden: false }, + }, + { + path: '/project/budget', + name: 'ProjectBudget', + component: () => import('@/views/project/budget/index.vue'), + meta: { title: '项目预算', icon: 'budget', hidden: false }, } ], }, @@ -69,72 +400,98 @@ export const systemRoutes: RouteRecordRaw[] = [ meta: { hidden: true }, }, { - path: '/user', - name: 'User', - component: Layout, - meta: { hidden: true }, + path: '/enterprise-settings', + name: 'EnterpriseSettings', + meta: { + title: '企业设置', + icon: 'building' + }, children: [ { - path: '/user/profile', - name: 'UserProfile', - component: () => import('@/views/user/profile/index.vue'), - meta: { title: '个人中心', showInTabs: false }, + path: '/enterprise-settings/company-info', + name: 'CompanyInfo', + component: () => import('@/views/enterprise-settings/company-info/index.vue'), + meta: { + title: '企业信息', + icon: 'info-circle' + } }, { - path: '/user/message', - name: 'UserMessage', - component: () => import('@/views/user/message/index.vue'), - meta: { title: '消息中心', showInTabs: false }, + path: '/enterprise-settings/admin-permissions', + name: 'AdminPermissions', + component: () => import('@/views/enterprise-settings/admin-permissions/index.vue'), + meta: { + title: '管理员权限', + icon: 'user-switch' + } }, { - path: '/user/notice', - name: 'UserNotice', - component: () => import('@/views/user/message/components/view/index.vue'), - meta: { title: '查看公告' }, + path: '/enterprise-settings/data-migration', + name: 'DataMigration', + component: () => import('@/views/enterprise-settings/data-migration/index.vue'), + meta: { + title: '数据迁移', + icon: 'swap' + } }, - ], + { + path: '/enterprise-settings/version-upgrade', + name: 'VersionUpgrade', + component: () => import('@/views/enterprise-settings/version-upgrade/index.vue'), + meta: { + title: '版本升级提醒', + icon: 'arrow-up' + } + } + ] }, { - path: '/about', - name: 'About', - component: Layout, - meta: { title: '关于项目', icon: 'apps', hidden: false, sort: 999 }, - redirect: '/about/document/api', + path: '/system-resource', + name: 'SystemResource', + meta: { + title: '系统资源管理', + icon: 'cluster' + }, children: [ { - path: '/about/document/api', - component: () => import('@/views/about/document/api/index.vue'), - meta: { title: '接口文档', icon: 'swagger', hidden: false, keepAlive: true }, + path: '/system-resource/device-management', + name: 'DeviceManagement', + component: () => import('@/views/system-resource/device-management/index.vue'), + meta: { + title: '设备管理', + icon: 'desktop' + } }, { - path: 'https://continew.top', - meta: { title: '在线文档', icon: 'continew', hidden: false }, - }, - { - path: 'https://arco.design/vue/component/button', - meta: { title: 'Arco Design文档', icon: 'arco', hidden: false }, - }, - { - path: '/about/source', - name: 'AboutSource', - meta: { title: '开源地址', icon: 'github', hidden: false }, + path: '/system-resource/information-system', + name: 'InformationSystem', + meta: { + title: '信息化系统管理', + icon: 'code' + }, children: [ { - path: 'https://gitee.com/continew/continew-admin', - meta: { title: 'Gitee', icon: 'gitee', hidden: false }, + path: '/system-resource/information-system/software-management', + name: 'SoftwareManagement', + component: () => import('@/views/system-resource/information-system/software-management/index.vue'), + meta: { + title: '软件管理', + icon: 'appstore' + } }, { - path: 'https://gitcode.com/continew/continew-admin', - meta: { title: 'GitCode', icon: 'gitcode', hidden: false }, - }, - { - path: 'https://github.com/continew-org/continew-admin', - meta: { title: 'GitHub', icon: 'github', hidden: false }, - }, - ], - }, - ], - }, + path: '/system-resource/information-system/system-backup', + name: 'SystemBackup', + component: () => import('@/views/system-resource/information-system/system-backup/index.vue'), + meta: { + title: '系统备份管理', + icon: 'save' + } + } + ] + } + ] + } ] // 固定路由(默认路由) @@ -161,3 +518,4 @@ export const constantRoutes: RouteRecordRaw[] = [ meta: { hidden: true }, }, ] + diff --git a/src/stores/modules/app.ts b/src/stores/modules/app.ts index 286834f..ccab78d 100644 --- a/src/stores/modules/app.ts +++ b/src/stores/modules/app.ts @@ -1,5 +1,5 @@ import { defineStore } from 'pinia' -import { computed, reactive, toRefs } from 'vue' +import { computed, reactive, toRefs, watch, watchEffect } from 'vue' import { generate, getRgbStr } from '@arco-design/color' import { type BasicConfig, listSiteOptionDict } from '@/apis' import { getSettings } from '@/config/setting' @@ -58,21 +58,21 @@ const storeSetup = () => { const siteConfig = reactive({}) as BasicConfig // 初始化系统配置 const initSiteConfig = () => { - listSiteOptionDict().then((res) => { - const resMap = new Map() - res.data.forEach((item) => { - resMap.set(item.label, item.value) - }) - siteConfig.SITE_FAVICON = resMap.get('SITE_FAVICON') - siteConfig.SITE_LOGO = resMap.get('SITE_LOGO') - siteConfig.SITE_TITLE = resMap.get('SITE_TITLE') - siteConfig.SITE_COPYRIGHT = resMap.get('SITE_COPYRIGHT') - siteConfig.SITE_BEIAN = resMap.get('SITE_BEIAN') - document.title = resMap.get('SITE_TITLE') - document - .querySelector('link[rel="shortcut icon"]') - ?.setAttribute('href', resMap.get('SITE_FAVICON') || '/favicon.ico') - }) + // listSiteOptionDict().then((res) => { + // const resMap = new Map() + // res.data.forEach((item) => { + // resMap.set(item.label, item.value) + // }) + // siteConfig.SITE_FAVICON = resMap.get('SITE_FAVICON') + // siteConfig.SITE_LOGO = resMap.get('SITE_LOGO') + // siteConfig.SITE_TITLE = resMap.get('SITE_TITLE') + // siteConfig.SITE_COPYRIGHT = resMap.get('SITE_COPYRIGHT') + // siteConfig.SITE_BEIAN = resMap.get('SITE_BEIAN') + // document.title = resMap.get('SITE_TITLE') + // document + // .querySelector('link[rel="shortcut icon"]') + // ?.setAttribute('href', resMap.get('SITE_FAVICON') || '/favicon.ico') + // }) } // 设置系统配置 @@ -81,26 +81,24 @@ const storeSetup = () => { document.title = config.SITE_TITLE || '' document.querySelector('link[rel="shortcut icon"]')?.setAttribute('href', config.SITE_FAVICON || '/favicon.ico') } - // 监听 色弱模式 和 哀悼模式 - watch([ - () => settingConfig.enableMourningMode, - () => settingConfig.enableColorWeaknessMode, - ], ([mourningMode, colorWeaknessMode]) => { + + // 使用watchEffect优化监听,避免递归更新 + watchEffect(() => { const filters = [] as string[] - if (mourningMode) { + + if (settingConfig.enableMourningMode) { filters.push('grayscale(100%)') } - if (colorWeaknessMode) { + if (settingConfig.enableColorWeaknessMode) { filters.push('invert(80%)') } + // 如果没有任何滤镜条件,移除 `filter` 样式 if (filters.length === 0) { document.documentElement.style.removeProperty('filter') } else { document.documentElement.style.setProperty('filter', filters.join(' ')) } - }, { - immediate: true, }) const getFavicon = () => { diff --git a/src/views/company/overview/index.vue b/src/views/company/overview/index.vue new file mode 100644 index 0000000..d20426f --- /dev/null +++ b/src/views/company/overview/index.vue @@ -0,0 +1,76 @@ + + + + + \ No newline at end of file diff --git a/src/views/enterprise-settings/admin-permissions/index.vue b/src/views/enterprise-settings/admin-permissions/index.vue new file mode 100644 index 0000000..7c7dce7 --- /dev/null +++ b/src/views/enterprise-settings/admin-permissions/index.vue @@ -0,0 +1,363 @@ + + + + + \ No newline at end of file diff --git a/src/views/enterprise-settings/company-info/index.vue b/src/views/enterprise-settings/company-info/index.vue new file mode 100644 index 0000000..1683602 --- /dev/null +++ b/src/views/enterprise-settings/company-info/index.vue @@ -0,0 +1,271 @@ + + + + + \ No newline at end of file diff --git a/src/views/enterprise-settings/data-migration/index.vue b/src/views/enterprise-settings/data-migration/index.vue new file mode 100644 index 0000000..399c7b8 --- /dev/null +++ b/src/views/enterprise-settings/data-migration/index.vue @@ -0,0 +1,382 @@ + + + + + \ No newline at end of file diff --git a/src/views/enterprise-settings/version-upgrade/index.vue b/src/views/enterprise-settings/version-upgrade/index.vue new file mode 100644 index 0000000..1f4c18f --- /dev/null +++ b/src/views/enterprise-settings/version-upgrade/index.vue @@ -0,0 +1,336 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/attendance/index.vue b/src/views/hr/attendance/index.vue new file mode 100644 index 0000000..c805f2b --- /dev/null +++ b/src/views/hr/attendance/index.vue @@ -0,0 +1,241 @@ + + + \ No newline at end of file diff --git a/src/views/hr/contribution/index.vue b/src/views/hr/contribution/index.vue new file mode 100644 index 0000000..1eeabe2 --- /dev/null +++ b/src/views/hr/contribution/index.vue @@ -0,0 +1,309 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/performance/index.vue b/src/views/hr/performance/index.vue new file mode 100644 index 0000000..bb5bcad --- /dev/null +++ b/src/views/hr/performance/index.vue @@ -0,0 +1,254 @@ + + + \ No newline at end of file diff --git a/src/views/hr/salary/index.vue b/src/views/hr/salary/index.vue new file mode 100644 index 0000000..591e228 --- /dev/null +++ b/src/views/hr/salary/index.vue @@ -0,0 +1,292 @@ + + + \ No newline at end of file diff --git a/src/views/hr/workload/index.vue b/src/views/hr/workload/index.vue new file mode 100644 index 0000000..818f4df --- /dev/null +++ b/src/views/hr/workload/index.vue @@ -0,0 +1,182 @@ + + + \ No newline at end of file diff --git a/src/views/product/hardware/custom-drone/index.vue b/src/views/product/hardware/custom-drone/index.vue new file mode 100644 index 0000000..51e573a --- /dev/null +++ b/src/views/product/hardware/custom-drone/index.vue @@ -0,0 +1,274 @@ + + + \ No newline at end of file diff --git a/src/views/product/hardware/tower-monitoring/index.vue b/src/views/product/hardware/tower-monitoring/index.vue new file mode 100644 index 0000000..63a02bb --- /dev/null +++ b/src/views/product/hardware/tower-monitoring/index.vue @@ -0,0 +1,244 @@ + + + \ No newline at end of file diff --git a/src/views/project-management/bidding/award-notice/index.vue b/src/views/project-management/bidding/award-notice/index.vue new file mode 100644 index 0000000..9e2315c --- /dev/null +++ b/src/views/project-management/bidding/award-notice/index.vue @@ -0,0 +1,282 @@ + + + \ No newline at end of file diff --git a/src/views/project-management/bidding/bid-documents/index.vue b/src/views/project-management/bidding/bid-documents/index.vue new file mode 100644 index 0000000..8ebd588 --- /dev/null +++ b/src/views/project-management/bidding/bid-documents/index.vue @@ -0,0 +1,285 @@ + + + \ No newline at end of file diff --git a/src/views/project-management/bidding/tender-documents/index.vue b/src/views/project-management/bidding/tender-documents/index.vue new file mode 100644 index 0000000..ce56429 --- /dev/null +++ b/src/views/project-management/bidding/tender-documents/index.vue @@ -0,0 +1,277 @@ + + + \ No newline at end of file diff --git a/src/views/project-management/contract/cost-management/index.vue b/src/views/project-management/contract/cost-management/index.vue new file mode 100644 index 0000000..3763cf8 --- /dev/null +++ b/src/views/project-management/contract/cost-management/index.vue @@ -0,0 +1,328 @@ + + + \ No newline at end of file diff --git a/src/views/project-management/contract/expense-contract/index.vue b/src/views/project-management/contract/expense-contract/index.vue new file mode 100644 index 0000000..18a5d8d --- /dev/null +++ b/src/views/project-management/contract/expense-contract/index.vue @@ -0,0 +1,299 @@ + + + \ No newline at end of file diff --git a/src/views/project-management/contract/revenue-contract/index.vue b/src/views/project-management/contract/revenue-contract/index.vue new file mode 100644 index 0000000..aac0ba4 --- /dev/null +++ b/src/views/project-management/contract/revenue-contract/index.vue @@ -0,0 +1,295 @@ + + + \ No newline at end of file diff --git a/src/views/project-management/projects/initiation/index.vue b/src/views/project-management/projects/initiation/index.vue new file mode 100644 index 0000000..4c602fa --- /dev/null +++ b/src/views/project-management/projects/initiation/index.vue @@ -0,0 +1,330 @@ + + + \ No newline at end of file diff --git a/src/views/project-management/projects/management/index.vue b/src/views/project-management/projects/management/index.vue new file mode 100644 index 0000000..394035f --- /dev/null +++ b/src/views/project-management/projects/management/index.vue @@ -0,0 +1,372 @@ + + + \ No newline at end of file diff --git a/src/views/project/budget/components/BudgetApplyModal.vue b/src/views/project/budget/components/BudgetApplyModal.vue new file mode 100644 index 0000000..e9208cb --- /dev/null +++ b/src/views/project/budget/components/BudgetApplyModal.vue @@ -0,0 +1,422 @@ + + + + + + \ No newline at end of file diff --git a/src/views/project/budget/components/BudgetAuditModal.vue b/src/views/project/budget/components/BudgetAuditModal.vue new file mode 100644 index 0000000..6182605 --- /dev/null +++ b/src/views/project/budget/components/BudgetAuditModal.vue @@ -0,0 +1,303 @@ + + + + + + \ No newline at end of file diff --git a/src/views/project/budget/components/BudgetDetailModal.vue b/src/views/project/budget/components/BudgetDetailModal.vue new file mode 100644 index 0000000..bb55d8f --- /dev/null +++ b/src/views/project/budget/components/BudgetDetailModal.vue @@ -0,0 +1,348 @@ + + + + + + \ No newline at end of file diff --git a/src/views/project/budget/index.vue b/src/views/project/budget/index.vue new file mode 100644 index 0000000..857fcf7 --- /dev/null +++ b/src/views/project/budget/index.vue @@ -0,0 +1,332 @@ + + + + + + \ No newline at end of file diff --git a/src/views/project/index.vue b/src/views/project/index.vue index 0c3124a..b9cbb7a 100644 --- a/src/views/project/index.vue +++ b/src/views/project/index.vue @@ -1,3 +1,15 @@ + -