diff --git a/src/apis/bussiness/index.ts b/src/apis/bussiness/index.ts index f912656..71803d4 100644 --- a/src/apis/bussiness/index.ts +++ b/src/apis/bussiness/index.ts @@ -58,7 +58,8 @@ export function getFilesApi(params?: FileListParams) { params: { page: params?.page || 1, pageSize: params?.pageSize || 10, - folderId: params?.folderId || '0' + folderId: params?.folderId || '0', + fileName: params?.fileName } }) } @@ -167,8 +168,19 @@ export function previewFileApi(fileId: string) { }) } -// 重命名文件(后端没有提供重命名接口,需要先删除再上传) +// 重命名文件 +export function renameFileApi(fileId: string, newFileName: string) { + return request({ + url: '/businessData/file/rename', + method: 'put', + params: { + fileId: fileId, + newFileName: newFileName + } + }) +} + +// 重命名文件(兼容旧接口) export function updateFileNameApi(fileId: string, data: RenameFileParams) { - // 注意:后端没有提供文件重命名接口,这里返回一个Promise.reject - return Promise.reject(new Error('后端暂不支持文件重命名功能')) + return renameFileApi(fileId, data.newFileName) } \ No newline at end of file diff --git a/src/apis/bussiness/type.ts b/src/apis/bussiness/type.ts index e41bbeb..6fa269a 100644 --- a/src/apis/bussiness/type.ts +++ b/src/apis/bussiness/type.ts @@ -30,6 +30,7 @@ export interface FileListParams { page?: number pageSize?: number folderId?: string + fileName?: string } /** 文件夹列表响应 */ @@ -91,5 +92,5 @@ export interface PreviewFileParams { /** 重命名文件请求参数 */ export interface RenameFileParams { fileId: string - newName: string + newFileName: string } \ No newline at end of file diff --git a/src/apis/contract/index.ts b/src/apis/contract/index.ts new file mode 100644 index 0000000..d9974d3 --- /dev/null +++ b/src/apis/contract/index.ts @@ -0,0 +1,64 @@ +import request from '@/utils/http' + +// 合同查询参数类型 +export interface ContractQueryParams { + page?: number + pageSize?: number + code?: string + customer?: string + contractStatus?: string + type?: string + signDate?: string + paymentDate?: string + performanceDeadline?: string + salespersonId?: string + departmentId?: string + projectId?: string +} + +// 合同响应数据类型 +export interface ContractData { + accountNumber: string + amount: number + code: string + contractId: string + contractStatus: string + contractText: string + customer: string + departmentId: string + duration: string + notes: string + page: number + pageSize: number + paymentAddress: string + paymentDate: string + performanceDeadline: string + productService: string + projectId: string + projectName: string + receivedAmount: number + salespersonDeptName: string + salespersonId: string + salespersonName: string + settlementAmount: number + signDate: string + type: string +} + +// 合同列表响应类型 +export interface ContractListResponse { + code: number + msg: string + rows: ContractData[] + total: number +} + +const BASE_URL = '/contract' + +/** + * 获取合同列表 + * @param params 查询参数 + */ +export function getContractList(params: ContractQueryParams) { + return request.get(`${BASE_URL}/list`, params) +} diff --git a/src/router/route.ts b/src/router/route.ts index 3ef2fee..ba06fd2 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -26,53 +26,52 @@ export const systemRoutes: RouteRecordRaw[] = [ // } // ], // }, - { - path: '/regulation', - name: 'Regulation', - component: Layout, - redirect: '/regulation/system-regulation', - meta: { title: '制度管理', icon: 'file-text', hidden: false, sort: 1.5 }, - children: [ - { - path: '/regulation/system-regulation', - name: 'SystemRegulation', - component: () => import('@/views/regulation/repository.vue'), - meta: { title: '制度公告', icon: 'file-text', hidden: false }, - }, - { - path: '/regulation/process-management', - name: 'ProcessManagement', - component: () => import('@/views/regulation/confirm.vue'), - meta: { title: '制度公示', icon: 'workflow', hidden: false }, - }, - { - path: '/regulation/proposal', - name: 'RegulationProposal', - component: () => import('@/views/regulation/proposal/index.vue'), - meta: { title: '制度提案', icon: 'edit', hidden: false }, - }, - { - path: '/regulation/type', - name: 'RegulationType', - component: () => import('@/views/regulation/type/index.vue'), - meta: { title: '制度类型', icon: 'tag', hidden: false }, - }, - - ], - }, + // { + // path: '/regulation', + // name: 'Regulation', + // component: Layout, + // redirect: '/regulation/system-regulation', + // meta: { title: '制度管理', icon: 'file-text', hidden: false, sort: 1.5 }, + // children: [ + // { + // path: '/regulation/system-regulation', + // name: 'SystemRegulation', + // component: () => import('@/views/regulation/repository.vue'), + // meta: { title: '制度公告', icon: 'file-text', hidden: false }, + // }, + // { + // path: '/regulation/process-management', + // name: 'ProcessManagement', + // component: () => import('@/views/regulation/confirm.vue'), + // meta: { title: '制度公示', icon: 'workflow', hidden: false }, + // }, + // { + // path: '/regulation/proposal', + // name: 'RegulationProposal', + // component: () => import('@/views/regulation/proposal/index.vue'), + // meta: { title: '制度提案', icon: 'edit', hidden: false }, + // }, + // { + // path: '/regulation/type', + // name: 'RegulationType', + // component: () => import('@/views/regulation/type/index.vue'), + // meta: { title: '制度类型', icon: 'tag', hidden: false }, + // }, + // ], + // }, { path: '/organization', name: 'Organization', component: Layout, redirect: '/organization/dept', - meta: { title: '组织架构', icon: 'user-group', hidden: false, sort: 2 }, + meta: { title: '企业管理', icon: 'user-group', hidden: false, sort: 2 }, children: [ - { - path: '/organization/user', - name: 'OrganizationUser', - component: () => import('@/views/system/user/index.vue'), - meta: { title: '用户管理', icon: 'user', hidden: false, sort: 2.25 }, - }, + // { + // path: '/organization/user', + // name: 'OrganizationUser', + // component: () => import('@/views/system/user/index.vue'), + // meta: { title: '用户管理', icon: 'user', hidden: false, sort: 2.25 }, + // }, { path: '/organization/dept', name: 'OrganizationDept', @@ -85,6 +84,39 @@ export const systemRoutes: RouteRecordRaw[] = [ component: () => import('@/views/system/post/index.vue'), meta: { title: '岗位管理', icon: 'nav', hidden: false, sort: 2.75 }, }, + { + path: '/regulation', + name: 'Regulation', + // component: Layout, + redirect: '/regulation/system-regulation', + meta: { title: '制度管理', icon: 'file-text', hidden: false, sort: 1.5 }, + children: [ + { + path: '/regulation/system-regulation', + name: 'SystemRegulation', + component: () => import('@/views/regulation/repository.vue'), + meta: { title: '制度公告', icon: 'file-text', hidden: false }, + }, + { + path: '/regulation/process-management', + name: 'ProcessManagement', + component: () => import('@/views/regulation/confirm.vue'), + meta: { title: '制度公示', icon: 'workflow', hidden: false }, + }, + { + path: '/regulation/proposal', + name: 'RegulationProposal', + component: () => import('@/views/regulation/proposal/index.vue'), + meta: { title: '制度提案', icon: 'edit', hidden: false }, + }, + { + path: '/regulation/type', + name: 'RegulationType', + component: () => import('@/views/regulation/type/index.vue'), + meta: { title: '制度类型', icon: 'tag', hidden: false }, + }, + ], + }, // { // path: '/organization/hr/workload', // name: 'HRWorkload', @@ -435,99 +467,86 @@ export const systemRoutes: RouteRecordRaw[] = [ ], }, { - path: '/project-management', - name: 'ProjectManagement', + path: '/project-marketing', + name: 'Projectmarketing', component: Layout, - redirect: '/project-management/project-template/project-management', - meta: { title: '项目管理', icon: 'apps', hidden: false, sort: 4 }, + redirect: '/project-marketing/project-marketing', + meta: { title: '营销管理', icon: 'file-text', hidden: false, sort: 3 }, children: [ { - path: '/project-management/contract/project-source', - name: 'ProjectSource', + path: '/project-marketing/contract/revenue-contract2', + name: 'RevenueContract2', + component: () => import('@/views/default/error/404.vue'), + meta: { + title: '市场营销(N)', + icon: 'dollar', + hidden: false, + }, + }, + { + path: '/project-marketing/contract/procurement-business', + name: 'ProcurementBusiness', component: () => import('@/components/ParentView/index.vue'), meta: { - title: '项目来源', + title: '招采业务', icon: 'dollar', hidden: false, }, children: [ { - path: '/project-management/contract/procurement-business', - name: 'ProcurementBusiness', - component: () => import('@/components/ParentView/index.vue'), + path: '/project-marketing/project-template/tender-documents', + name: 'TenderDocuments', + component: () => import('@/views/project-management/bidding/tender-documents/index.vue'), meta: { - title: '招采业务', - icon: 'dollar', - hidden: false, - }, - children: [ - { - path: '/project-management/project-template/tender-documents', - name: 'TenderDocuments', - component: () => import('@/views/project-management/bidding/tender-documents/index.vue'), - meta: { - title: '招标文件', - icon: 'file-text', - hidden: false, - }, - }, - { - path: '/project-management/project-template/bid-documents', - name: 'BidDocuments', - component: () => import('@/views/project-management/bidding/bid-documents/index.vue'), - meta: { - title: '投标文件', - icon: 'file-text', - hidden: false, - }, - }, - { - path: '/project-management/project-template/award-notice', - name: 'AwardNotice', - component: () => import('@/views/project-management/bidding/award-notice/index.vue'), - meta: { - title: '中标通知书', - icon: 'trophy', - hidden: false, - }, - }, - { - path: '/project-management/project-template/information-retrieval', - name: 'InformationRetrieval', - component: () => import ('@/views/project-management/bidding/information-retrieval/index.vue'), - meta: { - title: '信息检索(N)', - icon: 'trophy', - hidden: false, - }, - }, - - ], - }, - { - path: '/project-management/contract/revenue-contract2', - name: 'RevenueContract2', - component: () => import('@/views/default/error/404.vue'), - meta: { - title: '市场营销(N)', - icon: 'dollar', + title: '招标文件', + icon: 'file-text', hidden: false, }, }, { - path: '/project-management/project-source/privateproject', - name: 'PrivateProject', - component: () => import('@/views/default/error/404.vue'), + path: '/project-marketing/project-template/bid-documents', + name: 'BidDocuments', + component: () => import('@/views/project-management/bidding/bid-documents/index.vue'), meta: { - title: '自建项目(N)', - icon: 'dollar', + title: '投标文件', + icon: 'file-text', + hidden: false, + }, + }, + { + path: '/project-marketing/project-template/award-notice', + name: 'AwardNotice', + component: () => import('@/views/project-management/bidding/award-notice/index.vue'), + meta: { + title: '中标通知书', + icon: 'trophy', + hidden: false, + }, + }, + { + path: '/project-marketing/project-template/information-retrieval', + name: 'InformationRetrieval', + component: () => import ('@/views/project-management/bidding/information-retrieval/index.vue'), + meta: { + title: '信息检索(N)', + icon: 'trophy', hidden: false, }, }, ], }, + { + path: '/project-marketing/order-management/order-management', + name: 'OrderManagement', + component: () => import('@/views/project-management/order-management/index.vue'), + meta: { + title: '订单管理', + icon: 'file-text', + hidden: false, + }, + }, { path: '/project-management/contract', name: 'ProjectContract', component: () => import('@/components/ParentView/index.vue'), redirect: '/project-management/contract/revenue-contract', meta: { - title: '项目合同', + title: '合同管理', icon: 'file-text', hidden: false, }, children: [ @@ -562,6 +581,136 @@ export const systemRoutes: RouteRecordRaw[] = [ }, }, ] }, + ], + }, + { + path: '/project-management', + name: 'ProjectManagement', + component: Layout, + redirect: '/project-management/project-template/project-management', + meta: { title: '项目管理', icon: 'apps', hidden: false, sort: 4 }, + children: [ + { + path: '/project-management/contract/project-source', + name: 'ProjectSource', + component: () => import('@/components/ParentView/index.vue'), + meta: { + title: '项目来源', + icon: 'dollar', + hidden: false, + }, + children: [ + // { + // path: '/project-management/contract/procurement-business', + // name: 'ProcurementBusiness', + // component: () => import('@/components/ParentView/index.vue'), + // meta: { + // title: '招采业务', + // icon: 'dollar', + // hidden: false, + // }, + // children: [ + // { + // path: '/project-management/project-template/tender-documents', + // name: 'TenderDocuments', + // component: () => import('@/views/project-management/bidding/tender-documents/index.vue'), + // meta: { + // title: '招标文件', + // icon: 'file-text', + // hidden: false, + // }, + // }, + // { + // path: '/project-management/project-template/bid-documents', + // name: 'BidDocuments', + // component: () => import('@/views/project-management/bidding/bid-documents/index.vue'), + // meta: { + // title: '投标文件', + // icon: 'file-text', + // hidden: false, + // }, + // }, + // { + // path: '/project-management/project-template/award-notice', + // name: 'AwardNotice', + // component: () => import('@/views/project-management/bidding/award-notice/index.vue'), + // meta: { + // title: '中标通知书', + // icon: 'trophy', + // hidden: false, + // }, + // }, + // { + // path: '/project-management/project-template/information-retrieval', + // name: 'InformationRetrieval', + // component: () => import ('@/views/project-management/bidding/information-retrieval/index.vue'), + // meta: { + // title: '信息检索(N)', + // icon: 'trophy', + // hidden: false, + // }, + // }, + // + // ], + // }, + // { + // path: '/project-management/contract/revenue-contract2', + // name: 'RevenueContract2', + // component: () => import('@/views/default/error/404.vue'), + // meta: { + // title: '市场营销(N)', + // icon: 'dollar', + // hidden: false, + // }, + // }, + { + path: '/project-management/project-source/privateproject', + name: 'PrivateProject', + component: () => import('@/views/default/error/404.vue'), + meta: { + title: '自建项目(N)', + icon: 'dollar', + hidden: false, + }, + }, + ], + }, + // { path: '/project-management/contract', name: 'ProjectContract', component: () => import('@/components/ParentView/index.vue'), redirect: '/project-management/contract/revenue-contract', meta: { + // title: '项目合同', + // icon: 'file-text', + // hidden: false, + // }, children: [ + // { + // path: '/project-management/contract/revenue-contract', + // name: 'RevenueContract', + // component: () => import('@/views/project-management/contract/revenue-contract/index.vue'), + // meta: { + // title: '收入合同', + // icon: 'dollar', + // hidden: false, + // }, + // }, + // { + // path: '/project-management/contract/expense-contract', + // name: 'ExpenseContract', + // component: () => import('@/views/project-management/contract/expense-contract/index.vue'), + // meta: { + // title: '支出合同', + // icon: 'credit-card', + // hidden: false, + // }, + // }, + // { + // path: '/project-management/contract/cost-management', + // name: 'CostManagement', + // component: () => import('@/views/project-management/contract/cost-management/index.vue'), + // meta: { + // title: '成本费用', + // icon: 'bar-chart', + // hidden: false, + // }, + // }, + // ] }, { path: '/project-management/project-template/project-aproval', name: 'ProjectTemplate', @@ -934,15 +1083,15 @@ export const systemRoutes: RouteRecordRaw[] = [ // }, // 商务数据库信息模块 { - path: '/business-knowledge', - name: 'BusinessKnowledge', + path: '/bussiness-knowledge', + name: 'bussinesskonwledge', component: Layout, - redirect: '/business-knowledge/data', - meta: { title: '商务数据库信息', icon: 'database', hidden: false, sort: 5.5 }, + redirect: '/bussiness-knowledge/data', + meta: { title: '商务资料知识库', icon: 'database', hidden: false, sort: 5.5 }, children: [ { - path: '/business-knowledge/data', - name: 'BusinessKnowledgeData', + path: '/bussiness-konwledge/data', + name: 'bussiness-knowledge', component: () => import('@/views/bussiness-data/bussiness.vue'), meta: { title: '商务数据库信息', @@ -971,30 +1120,30 @@ export const systemRoutes: RouteRecordRaw[] = [ // } ], }, - { - path: '/user/profile', - name: 'UserProfile', - component: Layout, - redirect: '/user/profile', - meta: { - title: '个人中心', - icon: 'user', - hidden: false, - sort: 100, - }, - children: [ - { - path: '/user/profile', - name: 'UsersProfile', - component: () => import('@/views/user/profile/index.vue'), - meta: { - title: '个人中心', - icon: 'user', - hidden: false, - }, - }, - ], - }, + // { + // path: '/user/profile', + // name: 'UserProfile', + // component: Layout, + // redirect: '/user/profile', + // meta: { + // title: '个人中心', + // icon: 'user', + // hidden: false, + // sort: 100, + // }, + // children: [ + // { + // path: '/user/profile', + // name: 'UsersProfile', + // component: () => import('@/views/user/profile/index.vue'), + // meta: { + // title: '个人中心', + // icon: 'user', + // hidden: false, + // }, + // }, + // ], + // }, { path: '/enterprise-settings', name: 'EnterpriseSettings', @@ -1093,25 +1242,6 @@ export const systemRoutes: RouteRecordRaw[] = [ }, ], }, - { - path: '/training', - name: 'Training', - component: Layout, - redirect: '/training/plan', - meta: { title: '培训管理', icon: 'book', hidden: false, sort: 9 }, - children: [ - { - path: '/training/plan', - name: 'TrainingPlan', - component: () => import('@/views/training/plan/index.vue'), - meta: { - title: '培训计划', - icon: 'calendar', - hidden: false, - }, - }, - ], - }, { path: '/system-resource', name: 'SystemResource', diff --git a/src/stores/modules/route.ts b/src/stores/modules/route.ts index 5a474bd..909490b 100644 --- a/src/stores/modules/route.ts +++ b/src/stores/modules/route.ts @@ -149,6 +149,20 @@ const storeSetup = () => { isHidden: false, sort: 3, }, + { + id: 1070, + parentId: 1000, + title: '个人中心', + type: 2, + path: '/user/profile', + name: 'UserProfile', + component: 'user/profile/index', + icon: 'user', + isExternal: false, + isCache: false, + isHidden: false, + sort: 4, + }, ], }, { diff --git a/src/types/auto-imports.d.ts b/src/types/auto-imports.d.ts index 369aad4..9026869 100644 --- a/src/types/auto-imports.d.ts +++ b/src/types/auto-imports.d.ts @@ -57,7 +57,6 @@ declare global { const useCssVars: typeof import('vue')['useCssVars'] const useId: typeof import('vue')['useId'] const useLink: typeof import('vue-router')['useLink'] - const useModel: typeof import('vue')['useModel'] const useRoute: typeof import('vue-router')['useRoute'] const useRouter: typeof import('vue-router')['useRouter'] const useSlots: typeof import('vue')['useSlots'] diff --git a/src/types/components.d.ts b/src/types/components.d.ts index 7fa6b1b..19a4246 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -7,7 +7,66 @@ export {} declare module 'vue' { export interface GlobalComponents { + Avatar: typeof import('./../components/Avatar/index.vue')['default'] + Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default'] + CellCopy: typeof import('./../components/CellCopy/index.vue')['default'] + Chart: typeof import('./../components/Chart/index.vue')['default'] + ColumnSetting: typeof import('./../components/GiTable/src/components/ColumnSetting.vue')['default'] + CronForm: typeof import('./../components/GenCron/CronForm/index.vue')['default'] + CronModal: typeof import('./../components/GenCron/CronModal/index.vue')['default'] + DateRangePicker: typeof import('./../components/DateRangePicker/index.vue')['default'] + DayForm: typeof import('./../components/GenCron/CronForm/component/day-form.vue')['default'] + FilePreview: typeof import('./../components/FilePreview/index.vue')['default'] + GiCellAvatar: typeof import('./../components/GiCell/GiCellAvatar.vue')['default'] + GiCellGender: typeof import('./../components/GiCell/GiCellGender.vue')['default'] + GiCellStatus: typeof import('./../components/GiCell/GiCellStatus.vue')['default'] + GiCellTag: typeof import('./../components/GiCell/GiCellTag.vue')['default'] + GiCellTags: typeof import('./../components/GiCell/GiCellTags.vue')['default'] + GiCodeView: typeof import('./../components/GiCodeView/index.vue')['default'] + GiDot: typeof import('./../components/GiDot/index.tsx')['default'] + GiEditTable: typeof import('./../components/GiEditTable/GiEditTable.vue')['default'] + GiFooter: typeof import('./../components/GiFooter/index.vue')['default'] + GiForm: typeof import('./../components/GiForm/src/GiForm.vue')['default'] + GiIconBox: typeof import('./../components/GiIconBox/index.vue')['default'] + GiIconSelector: typeof import('./../components/GiIconSelector/index.vue')['default'] + GiIframe: typeof import('./../components/GiIframe/index.vue')['default'] + GiOption: typeof import('./../components/GiOption/index.vue')['default'] + GiOptionItem: typeof import('./../components/GiOptionItem/index.vue')['default'] + GiPageLayout: typeof import('./../components/GiPageLayout/index.vue')['default'] + GiSpace: typeof import('./../components/GiSpace/index.vue')['default'] + GiSplitButton: typeof import('./../components/GiSplitButton/index.vue')['default'] + GiSplitPane: typeof import('./../components/GiSplitPane/index.vue')['default'] + GiSplitPaneFlexibleBox: typeof import('./../components/GiSplitPane/components/GiSplitPaneFlexibleBox.vue')['default'] + GiSvgIcon: typeof import('./../components/GiSvgIcon/index.vue')['default'] + GiTable: typeof import('./../components/GiTable/src/GiTable.vue')['default'] + GiTag: typeof import('./../components/GiTag/index.tsx')['default'] + GiThemeBtn: typeof import('./../components/GiThemeBtn/index.vue')['default'] + HourForm: typeof import('./../components/GenCron/CronForm/component/hour-form.vue')['default'] + Icon403: typeof import('./../components/icons/Icon403.vue')['default'] + Icon404: typeof import('./../components/icons/Icon404.vue')['default'] + Icon500: typeof import('./../components/icons/Icon500.vue')['default'] + IconBorders: typeof import('./../components/icons/IconBorders.vue')['default'] + IconTableSize: typeof import('./../components/icons/IconTableSize.vue')['default'] + IconTreeAdd: typeof import('./../components/icons/IconTreeAdd.vue')['default'] + IconTreeReduce: typeof import('./../components/icons/IconTreeReduce.vue')['default'] + ImageImport: typeof import('./../components/ImageImport/index.vue')['default'] + ImageImportWizard: typeof import('./../components/ImageImportWizard/index.vue')['default'] + IndustrialImageList: typeof import('./../components/IndustrialImageList/index.vue')['default'] + JsonPretty: typeof import('./../components/JsonPretty/index.vue')['default'] + MinuteForm: typeof import('./../components/GenCron/CronForm/component/minute-form.vue')['default'] + MonthForm: typeof import('./../components/GenCron/CronForm/component/month-form.vue')['default'] + ParentView: typeof import('./../components/ParentView/index.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] + SecondForm: typeof import('./../components/GenCron/CronForm/component/second-form.vue')['default'] + SplitPanel: typeof import('./../components/SplitPanel/index.vue')['default'] + TextCopy: typeof import('./../components/TextCopy/index.vue')['default'] + TurbineGrid: typeof import('./../components/TurbineGrid/index.vue')['default'] + UserSelect: typeof import('./../components/UserSelect/index.vue')['default'] + Verify: typeof import('./../components/Verify/index.vue')['default'] + VerifyPoints: typeof import('./../components/Verify/Verify/VerifyPoints.vue')['default'] + VerifySlide: typeof import('./../components/Verify/Verify/VerifySlide.vue')['default'] + WeekForm: typeof import('./../components/GenCron/CronForm/component/week-form.vue')['default'] + YearForm: typeof import('./../components/GenCron/CronForm/component/year-form.vue')['default'] } } diff --git a/src/views/bussiness-data/bussiness.vue b/src/views/bussiness-data/bussiness.vue index 0119ea2..e0e0fac 100644 --- a/src/views/bussiness-data/bussiness.vue +++ b/src/views/bussiness-data/bussiness.vue @@ -158,6 +158,20 @@ + + +
+ +
+ @@ -534,6 +582,7 @@ import { downloadFileApi, uploadFileApi, updateFileNameApi, + renameFileApi, previewFileApi } from '@/apis/bussiness' @@ -583,10 +632,10 @@ const folderColor = '#165DFF'; const refreshing = ref(false); const folderSubmitting = ref(false); const uploading = ref(false); -const allowedFileTypes = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.zip,.txt'; -const allowedFileTypesText = 'PDF, Word, Excel, PPT, 压缩文件, 文本文件'; -const maxFileSize = 100 * 1024 * 1024; // 100MB -const maxFileSizeText = '100MB'; +const allowedFileTypes = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.zip,.txt,.jpg,.jpeg,.png,.gif,.bmp,.webp'; +const allowedFileTypesText = 'PDF, Word, Excel, PPT, 压缩文件, 文本文件, 图片文件'; +const maxFileSize = 1000 * 1024 * 1024; // 1000MB +const maxFileSizeText = '1000MB'; const cancelTokens = ref({}); // 计算属性:是否有文件可上传 @@ -614,7 +663,8 @@ const canUpload = computed(() => { }); // 搜索相关 -const searchKeyword = ref(''); +const searchKeyword = ref(''); // 文件夹搜索关键词 +const fileSearchKeyword = ref(''); // 文件搜索关键词 const searchTimeout = ref(null); // 初始化文件夹数据 @@ -735,13 +785,61 @@ const handleSearchClear = () => { initData(); }; +// 文件搜索相关函数 +const handleFileSearch = () => { + console.log('=== 执行文件搜索 ==='); + console.log('文件搜索关键词:', fileSearchKeyword.value); + // 重置到第一页并搜索 + fileCurrentPage.value = 1; + console.log('重置文件页码为:', fileCurrentPage.value); + if (currentFolderId.value) { + loadFiles(currentFolderId.value); + } +}; + +const handleFileSearchInput = (value) => { + console.log('=== 文件搜索输入 ==='); + console.log('输入值:', value); + fileSearchKeyword.value = value; + console.log('设置文件搜索关键词为:', fileSearchKeyword.value); + // 防抖搜索:300ms后自动搜索 + if (searchTimeout.value) { + clearTimeout(searchTimeout.value); + console.log('清除之前的文件搜索定时器'); + } + searchTimeout.value = setTimeout(() => { + console.log('=== 防抖文件搜索执行 ==='); + fileCurrentPage.value = 1; + console.log('重置文件页码为:', fileCurrentPage.value); + if (currentFolderId.value) { + loadFiles(currentFolderId.value); + } + }, 300); +}; + +const handleFileSearchClear = () => { + console.log('=== 清除文件搜索 ==='); + fileSearchKeyword.value = ''; + console.log('清空文件搜索关键词'); + if (searchTimeout.value) { + clearTimeout(searchTimeout.value); + console.log('清除文件搜索定时器'); + } + fileCurrentPage.value = 1; + console.log('重置文件页码为:', fileCurrentPage.value); + if (currentFolderId.value) { + loadFiles(currentFolderId.value); + } +}; + const loadFiles = async (folderId) => { try { loading.value = true; const res = await getFilesApi({ folderId: folderId, page: fileCurrentPage.value, - pageSize: filePageSize.value + pageSize: filePageSize.value, + fileName: fileSearchKeyword.value || undefined }); // 根据后端返回的数据结构处理 @@ -777,6 +875,8 @@ const handleFolderClick = (folderId) => { const id = String(folderId); if (currentFolderId.value !== id) { fileCurrentPage.value = 1; + // 切换文件夹时清空文件搜索关键词 + fileSearchKeyword.value = ''; } currentFolderId.value = id; }; @@ -790,6 +890,14 @@ const renameForm = reactive({ isRoot: false }); +// 重命名文件对话框状态 +const renameFileModalVisible = ref(false); +const renameFileForm = reactive({ + fileId: '', + newName: '', + fileExtension: '' +}); + // 文件夹重命名处理函数 const handleRenameFolder = (folder, folderId, currentName) => { console.log('handleRenameFolder 被调用:', { folder, folderId, currentName }); @@ -971,7 +1079,21 @@ const handleFileChange = (info) => { console.log('文件列表:', fileList); console.log('文件列表长度:', fileList.length); - // 处理新选择的文件 + // 每次选择文件时,强制清空所有状态 + fileListTemp.value = []; + console.log('已清空之前的文件列表'); + + // 强制重置上传组件状态 + if (uploadRef.value) { + try { + uploadRef.value.reset(); + console.log('已强制重置上传组件'); + } catch (error) { + console.log('重置上传组件时出错:', error); + } + } + + // 处理新选择的文件 - 只处理当前选择的文件 fileList.forEach((file, index) => { console.log(`处理第${index + 1}个文件:`, file); console.log('文件名称:', file.name); @@ -990,35 +1112,22 @@ const handleFileChange = (info) => { originFileObj: file.file || file // 保存原始File对象 }; - // 只处理新选择的文件,避免重复添加 - if (!fileListTemp.value.find(f => f.uid === fileObj.uid)) { - console.log('这是新文件,开始验证...'); - - // 验证文件 - const isValid = validateFile(fileObj); - console.log('文件验证结果:', isValid); - - if (isValid) { - fileListTemp.value.push(fileObj); - console.log('✅ 成功添加文件到列表:', fileObj.name); - } else { - console.log('❌ 文件验证失败:', fileObj.name, '错误:', fileObj.error); - } + console.log('开始验证新文件...'); + + // 验证文件 + const isValid = validateFile(fileObj); + console.log('文件验证结果:', isValid); + + if (isValid) { + // 确保只添加当前选择的文件 + fileListTemp.value = [fileObj]; // 只保留当前文件 + console.log('✅ 成功设置文件到列表:', fileObj.name); } else { - console.log('文件已存在,跳过:', fileObj.name); + console.log('❌ 文件验证失败:', fileObj.name, '错误:', fileObj.error); } }); - // 清理已移除的文件 - const beforeCleanCount = fileListTemp.value.length; - fileListTemp.value = fileListTemp.value.filter(file => - fileList.some(f => f.uid === file.uid) - ); - const afterCleanCount = fileListTemp.value.length; - - if (beforeCleanCount !== afterCleanCount) { - console.log(`清理了 ${beforeCleanCount - afterCleanCount} 个已移除的文件`); - } + // 文件列表已在上方清空并重新填充,无需额外清理 console.log('=== 当前文件列表状态 ==='); console.log('fileListTemp长度:', fileListTemp.value.length); @@ -1081,7 +1190,14 @@ const fileColor = (extension) => { ppt: '#faad14', pptx: '#faad14', zip: '#722ed1', - txt: '#8c8c8c' + txt: '#8c8c8c', + // 图片格式颜色 + jpg: '#52c41a', + jpeg: '#52c41a', + png: '#1890ff', + gif: '#faad14', + bmp: '#722ed1', + webp: '#13c2c2' }; return colorMap[extension.toLowerCase()] || '#8c8c8c'; }; @@ -1171,42 +1287,47 @@ const handleUploadSubmit = async () => { fileItem.error = result.msg || '上传失败'; hasError = true; } - } - - // 根据结果显示相应的消息 - if (hasFileExists && !hasError) { - Message.warning('文件已存在'); - } else if (hasError) { - Message.error('上传失败'); - } else { - Message.success('上传成功'); - // 刷新当前文件夹文件列表 - if (currentFolderId.value === uploadForm.folderId) { - loadFiles(currentFolderId.value); - } - } - - resetUpload(); + } - uploading.value = false; + // 根据结果显示相应的消息 + if (hasFileExists && !hasError) { + Message.warning('文件已存在'); + } else if (hasError) { + Message.error('上传失败'); + } else { + Message.success('上传成功'); + // 刷新当前文件夹文件列表 + if (currentFolderId.value === uploadForm.folderId) { + loadFiles(currentFolderId.value); + } + } + + resetUpload(); }; // 重置上传表单 const resetUpload = () => { + console.log('=== 重置上传表单 ==='); + // 取消所有正在进行的上传 Object.values(cancelTokens.value).forEach(source => { source.cancel('上传已取消'); }); + // 重置所有状态 uploadDialogVisible.value = false; uploadForm.folderId = currentFolderId.value || ''; fileListTemp.value = []; cancelTokens.value = {}; + uploading.value = false; // 清空上传组件 if (uploadRef.value) { uploadRef.value.reset(); + console.log('已重置上传组件'); } + + console.log('上传表单重置完成'); }; // 预览文件 @@ -1261,11 +1382,87 @@ const handleDownload = async (file) => { // 重命名文件 const handleEditFile = (file) => { - Modal.warning({ - title: '功能提示', - content: '后端暂不支持文件重命名功能,如需重命名请先删除文件再重新上传。', - okText: '知道了' + console.log('=== 重命名文件函数被调用 ==='); + console.log('重命名文件 - 文件对象:', file); + console.log('文件对象的所有属性:', Object.keys(file)); + console.log('文件属性详情:', { + fileId: file.fileId, + fileName: file.fileName, + name: file.name, + originalName: file.originalName, + displayName: file.displayName, + title: file.title }); + + // 尝试多种可能的文件名字段 + let fileName = ''; + if (file.fileName) { + fileName = file.fileName; + console.log('使用 fileName 字段:', fileName); + } else if (file.name) { + fileName = file.name; + console.log('使用 name 字段:', fileName); + } else if (file.originalName) { + fileName = file.originalName; + console.log('使用 originalName 字段:', fileName); + } else if (file.displayName) { + fileName = file.displayName; + console.log('使用 displayName 字段:', fileName); + } else if (file.title) { + fileName = file.title; + console.log('使用 title 字段:', fileName); + } + + console.log('最终获取到的文件名:', fileName); + + if (!fileName) { + console.error('无法获取文件名,文件对象:', file); + Message.error('无法获取文件名,请检查文件数据'); + return; + } + + const fileExtension = getFileExtension(fileName); + const fileNameWithoutExtension = fileExtension ? fileName.substring(0, fileName.lastIndexOf('.')) : fileName; + + console.log('处理后的文件名信息:', { + originalName: fileName, + extension: fileExtension, + nameWithoutExtension: fileNameWithoutExtension + }); + + // 设置重命名表单数据 + renameFileForm.fileId = file.fileId; + renameFileForm.newName = fileNameWithoutExtension; + renameFileForm.fileExtension = fileExtension; + + console.log('设置的重命名表单数据:', renameFileForm); + + // 显示重命名弹窗 + renameFileModalVisible.value = true; +}; + +// 确认重命名文件 +const confirmRenameFile = async () => { + if (!renameFileForm.newName.trim()) { + Message.warning('请输入文件名称'); + return; + } + + // 使用用户输入的文件名,不添加任何扩展名 + const newFileName = renameFileForm.newName.trim(); + + try { + await renameFileApi(renameFileForm.fileId, newFileName); + Message.success('文件重命名成功'); + renameFileModalVisible.value = false; + // 刷新当前文件夹的文件列表 + if (currentFolderId.value) { + loadFiles(currentFolderId.value); + } + } catch (error) { + console.error('重命名文件失败:', error); + Message.error('重命名失败'); + } }; // 删除文件夹 @@ -1344,6 +1541,13 @@ const fileTypeText = (type) => { pptx: 'PPT演示', zip: '压缩文件', txt: '文本文件', + // 图片格式 + jpg: 'JPG图片', + jpeg: 'JPEG图片', + png: 'PNG图片', + gif: 'GIF图片', + bmp: 'BMP图片', + webp: 'WebP图片', unknown: '未知类型' }; @@ -2330,5 +2534,64 @@ onMounted(() => { 100% { transform: translateX(100%); } } +/* 文件搜索样式 */ +.file-search-container { + margin: 16px 0; + display: flex; + align-items: center; + gap: 12px; +} +.file-search-input { + max-width: 300px; + transition: all 0.3s ease; + + &:focus-within { + box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.1); + } +} + +/* 文件分页样式 */ +.file-pagination { + margin-top: 24px; + padding: 16px 0; + display: flex; + justify-content: center; + border-top: 1px solid var(--color-border); + background: var(--color-bg-1); + + .arco-pagination { + .arco-pagination-total { + color: var(--color-text-2); + font-size: 14px; + } + + .arco-pagination-item { + border-radius: 6px; + transition: all 0.2s ease; + + &:hover { + border-color: var(--color-primary); + color: var(--color-primary); + } + + &.arco-pagination-item-active { + background: var(--color-primary); + border-color: var(--color-primary); + color: white; + } + } + + .arco-pagination-prev, + .arco-pagination-next { + border-radius: 6px; + transition: all 0.2s ease; + + &:hover { + border-color: var(--color-primary); + color: var(--color-primary); + } + } + } +} diff --git a/src/views/project-management/order-management/index.vue b/src/views/project-management/order-management/index.vue new file mode 100644 index 0000000..89b1f33 --- /dev/null +++ b/src/views/project-management/order-management/index.vue @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/src/views/system/post/PostDetailDrawer.vue b/src/views/system/post/PostDetailDrawer.vue index 61d3ffa..c671039 100644 --- a/src/views/system/post/PostDetailDrawer.vue +++ b/src/views/system/post/PostDetailDrawer.vue @@ -29,7 +29,7 @@
所属部门
-
{{ primaryInfo?.department || '技术部' }}
+
{{ primaryInfo?.deptName || '技术部' }}
直接上级岗位
@@ -52,7 +52,7 @@
{{ primaryInfo?.location || '上海/远程' }}
- +
岗位目的
@@ -68,18 +68,18 @@
主要职责与工作任务
    -
  • {{ task }}
  • +
  • {{ task }}
- +
工作权限
    -
  • {{ perm }}
  • +
  • {{ perm }}
- +
汇报关系
@@ -167,7 +167,7 @@
{{ primaryInfo?.performance || '根据项目按时交付率、代码质量、产品性能指标提升情况进行评估。' }}
- +
薪酬范围
@@ -184,7 +184,7 @@
{{ primaryInfo?.culture || '客户第一、创新、诚信、合作' }}
- +
职业发展路径
@@ -244,7 +244,7 @@ const getDetail = async (id: string) => { id: data.postId ?? data.id ?? '10001', name: data.postName ?? data.name ?? '-', status: data.status, - department: data.department ?? '技术部', + department: data.department ?? data.deptName ?? '技术部', superior: data.superior ?? '技术总监', level: data.level ?? 'P5', version: data.version ?? '2024-06-01 / V1.0', @@ -252,11 +252,11 @@ const getDetail = async (id: string) => { summary: data.summary ?? '负责公司核心产品开发,支撑业务增长。', tasks: data.tasks ?? [ '负责XXX产品的需求分析、架构设计、核心模块编码和单元测试。', - '制定并执行季度社交媒体营销计划,提升品牌曝光度和用户互动率。' + '制定并执行季度社交媒体营销计划,提升品牌曝光度和用户互动率。', ], permissions: data.permissions ?? [ '有权审批部门内5000元以下的采购申请。', - '有权对项目团队成员的工作任务进行分配和调整。' + '有权对项目团队成员的工作任务进行分配和调整。', ], subordinates: data.subordinates ?? '无', collaboration: data.collaboration ?? '与产品部、销售部、客服部紧密合作',