diff --git a/mes-ui/src/api/concessionApply.ts b/mes-ui/src/api/concessionApply.ts new file mode 100644 index 0000000..042db53 --- /dev/null +++ b/mes-ui/src/api/concessionApply.ts @@ -0,0 +1,82 @@ +import { request } from '@/utils/request' + +// 让步接收申请表 类型定义 +export interface ConcessionApply { + id?: number + + qcId?: number + + concessionQty?: number + + applyRemark?: string + + applyContent?: string + + applyFile?: string + + applyUserId?: number + + deptId?: number + + instanceId?: string + + approveStatus?: number + + createTime?: string + + updateTime?: string + +} + +// 让步接收申请表 API +export const concessionApplyApi = { + // 分页查询 + page(params: { page: number; pageSize: number; id?: number }) { + return request({ url: '/biz/concessionApply/page', method: 'get', params }) + }, + + // 获取详情 + detail(id: string) { + return request({ url: `/biz/concessionApply/${id}`, method: 'get' }) + }, + + // 新增 + create(data: ConcessionApply) { + return request({ url: '/biz/concessionApply', method: 'post', data }) + }, + + // 修改 + update(data: ConcessionApply) { + return request({ url: '/biz/concessionApply', method: 'put', data }) + }, + + // 删除 + delete(ids: string[]) { + return request({ url: `/biz/concessionApply/${ids.join(',')}`, method: 'delete' }) + }, + + // 导出 + export(params?: { ids?: string[]; id?: number }) { + const p: Record = {} + if (params?.ids?.length) p.ids = params.ids.join(',') + if (params?.id !== undefined && params?.id !== null) p.id = params.id + return request({ url: `/biz/concessionApply/export`, method: 'get', params: p, responseType: 'blob' }) + }, + + // 导入 + importData(file: File) { + const formData = new FormData() + formData.append('file', file) + return request<{ success: number; fail: number; errors: string[] }>({ + url: `/biz/concessionApply/import`, + method: 'post', + data: formData, + headers: { 'Content-Type': 'multipart/form-data' } + }) + }, + + // 下载导入模板 + downloadTemplate() { + return request({ url: `/biz/concessionApply/template`, method: 'get', responseType: 'blob' }) + } +} diff --git a/mes-ui/src/views/biz/concessionApply/index.vue b/mes-ui/src/views/biz/concessionApply/index.vue new file mode 100644 index 0000000..f6415ae --- /dev/null +++ b/mes-ui/src/views/biz/concessionApply/index.vue @@ -0,0 +1,427 @@ + + + + + diff --git a/src/api/ConcessionApply.ts b/src/api/ConcessionApply.ts new file mode 100644 index 0000000..7049991 --- /dev/null +++ b/src/api/ConcessionApply.ts @@ -0,0 +1,98 @@ +import { request } from '@/utils/request' + +// 让步接收申请表 类型定义 +export interface ConcessionApply { + id?: number + + qcId?: number + + concessionQty?: number + + applyRemark?: string + + applyContent?: string + + applyFile?: string + + applyUserId?: number + + deptId?: number + + instanceId?: string + + approveStatus?: number + + createTime?: string + + updateTime?: string + +} + + +export interface DetailModel { + + businessId:string, + title:string, + deptName:string, + approveResult:string, + approveRecord:[] +} + +// 让步接收申请表 API +export const concessionApplyApi = { + // 分页查询 + page(params: { page: number; pageSize: number; id?: number }) { + return request({ url: '/biz/concessionApply/page', method: 'get', params }) + }, + + // 获取详情 + detail(id: string) { + return request({ url: `/biz/concessionApply/${id}`, method: 'get' }) + }, + + // 新增 + create(data: ConcessionApply) { + return request({ url: '/biz/concessionApply', method: 'post', data }) + }, + + // 修改 + update(data: ConcessionApply) { + return request({ url: '/biz/concessionApply', method: 'put', data }) + }, + + // 删除 + delete(ids: string[]) { + return request({ url: `/biz/concessionApply/${ids.join(',')}`, method: 'delete' }) + }, + + // 导出 + export(params?: { ids?: string[]; id?: number }) { + const p: Record = {} + if (params?.ids?.length) p.ids = params.ids.join(',') + if (params?.id !== undefined && params?.id !== null) p.id = params.id + return request({ url: `/biz/concessionApply/export`, method: 'get', params: p, responseType: 'blob' }) + }, + + // 导入 + importData(file: File) { + const formData = new FormData() + formData.append('file', file) + return request<{ success: number; fail: number; errors: string[] }>({ + url: `/biz/concessionApply/import`, + method: 'post', + data: formData, + headers: { 'Content-Type': 'multipart/form-data' } + }) + }, + + // 下载导入模板 + downloadTemplate() { + return request({ url: `/biz/concessionApply/template`, method: 'get', responseType: 'blob' }) + }, + + //撤回审批申请 + approveCancel(params?:{id?:number}){ + return request({url:`/biz/concessionApply/approveCancel`,method:'get',params}) + } + +} \ No newline at end of file diff --git a/src/api/orderItem.ts b/src/api/orderItem.ts index 18acab9..7c48db9 100644 --- a/src/api/orderItem.ts +++ b/src/api/orderItem.ts @@ -44,9 +44,56 @@ export interface OrderItem { assingWorkOperationTime?: string starter?: number + + orderCode?: string + routeCode?: string + + proWorkshop?: string } +export interface KingdeePrdMo { + productionOrderNo: string + billNo: string + workShopName: string + materialCode: string + quantity: number | null + specModel: string | null + unit: string | null + materialName: string | null + routingNo: string | null + planStartTime: string | null + planFinishTime: string | null + pickMtrlStatus: string | null + children: KingdeeProcessRoute[] +} + + +/** 金蝶工艺路线工序(树子节点) */ +export interface KingdeeProcessRoute { + /** 工序号 FOperNumber */ + operNumber: number | null + /** 工作中心 FWorkCenterId.FName */ + workCenterName: string | null + /** 生产车间 FDepartmentId.FName */ + departmentName: string | null + /** 工序名称 FProcessProperty */ + processName: string | null + /** 工序说明 FOperDescription */ + operDescription: string | null + /** 活动单位 FActivity1UnitID.FName */ + activityUnit: string | null + /** 工序控制码 FOptCtrlCodeId.FName */ + optCtrlCodeName: string | null + /** 活动量 FActivity1Qty */ + activityQty: number | null + /** 计划开始时间 yyyy-MM-dd HH:mm:ss */ + planStartTime: string | null + /** 计划结束时间 yyyy-MM-dd HH:mm:ss */ + planFinishTime: string | null +} + + // 生产订单 API export const orderItemApi = { // 分页查询 @@ -81,6 +128,10 @@ export const orderItemApi = { preCreation(data: any) { return request({ url: '/biz/orderItem/preCreation', method: 'post', data }) }, + //根据生产编号查询预生产订单 + preCreationInfo(id: number, params:any) { + return request({ url: `/biz/orderItem/preCreation/${id}`, method: 'get', params}) + }, //查询项目名称 xmoptions(params: any) { @@ -91,13 +142,32 @@ export const orderItemApi = { wloptions(params: any) { //projectId return request({ url: '/biz/orderItem/options', method: 'get', params }) }, - + + holdTemporarilySave(id: number, data: KingdeePrdMo[]){ + return request({ url: `/biz/orderItem/kingdee/temporarily/save/${id}`, method: 'post', data }) + }, + // 同步订单和计划表 + synchronizationSave(id: number, data: KingdeePrdMo[]) { + return request({ url: `/biz/orderItem/kingdee/order/create/${id}`, method: 'post', data }) + }, // 导出 - export(params?: { ids?: string[]; code?: string; projectId?: number; beginTime?: string; endTime?: string }) { + export(params?: { + ids?: string[] + code?: string + projectName?: string + orderCode?: string + routeCode?: string + proWorkshop?: string + beginTime?: string + endTime?: string + }) { const p: Record = {} if (params?.ids?.length) p.ids = params.ids.join(',') if (params?.code !== undefined && params?.code !== null) p.code = params.code - if (params?.projectId !== undefined && params?.projectId !== null) p.projectId = params.projectId + if (params?.projectName !== undefined && params?.projectName !== null) p.projectName = params.projectName + if (params?.orderCode !== undefined && params?.orderCode !== null) p.orderCode = params.orderCode + if (params?.routeCode !== undefined && params?.routeCode !== null) p.routeCode = params.routeCode + if (params?.proWorkshop !== undefined && params?.proWorkshop !== null) p.proWorkshop = params.proWorkshop if (params?.beginTime !== undefined && params?.beginTime !== null) p.beginTime = params.beginTime if (params?.endTime !== undefined && params?.endTime !== null) p.endTime = params.endTime return request({ url: `/biz/orderItem/export`, method: 'get', params: p, responseType: 'blob' }) diff --git a/src/api/orderProject.ts b/src/api/orderProject.ts index 7cea8aa..d304ad9 100644 --- a/src/api/orderProject.ts +++ b/src/api/orderProject.ts @@ -69,18 +69,57 @@ export interface KingdeePrdMo { /** 金蝶工艺路线工序(树子节点) */ export interface KingdeeProcessRoute { + /** 工序号 FOperNumber */ operNumber: number | null + /** 工作中心 FWorkCenterId.FName */ workCenterName: string | null + /** 生产车间 FDepartmentId.FName */ departmentName: string | null - processProperty: string | null + /** 工序名称 FProcessProperty */ + processName: string | null + /** 工序说明 FOperDescription */ operDescription: string | null + /** 活动单位 FActivity1UnitID.FName */ activityUnit: string | null + /** 工序控制码 FOptCtrlCodeId.FName */ optCtrlCodeName: string | null + /** 活动量 FActivity1Qty */ activityQty: number | null + /** 计划开始时间 yyyy-MM-dd HH:mm:ss */ planStartTime: string | null + /** 计划结束时间 yyyy-MM-dd HH:mm:ss */ planFinishTime: string | null } +/** 解析工序名称,兼容旧字段及后端误映射 */ +export function resolveProcessName(route: Partial & { processProperty?: string | null }) { + const legacyName = typeof route.processProperty === 'string' ? route.processProperty.trim() : '' + const processName = route.processName?.trim() || legacyName || '' + const operDescription = route.operDescription?.trim() || '' + + if (processName) return processName + // 兼容:FProcessProperty 被写入 operDescription 而 processName 为空 + if (operDescription) return operDescription + return '' +} + +/** 归一化金蝶工序字段,保证 processName / operDescription 各归其位 */ +export function normalizeKingdeeProcessRoute( + route: KingdeeProcessRoute & { processProperty?: string | null } +): KingdeeProcessRoute { + const legacyName = typeof route.processProperty === 'string' ? route.processProperty.trim() : '' + const processName = route.processName?.trim() || legacyName || '' + const operDescription = route.operDescription?.trim() || '' + + if (processName) { + return { ...route, processName, operDescription: operDescription || null } + } + if (operDescription) { + return { ...route, processName: operDescription, operDescription: null } + } + return { ...route, processName: null, operDescription: null } +} + // 项目表 API export const orderProjectApi = { // 分页查询 @@ -136,8 +175,8 @@ export const orderProjectApi = { }, // 查询金蝶生产订单 (支持优先读取本地暂存) - getKingdeeOrder(id: number) { - return request({ url: `/biz/orderProject/kingdee/order/${id}`, method: 'get' }) + getKingdeeOrder(id: number, params:any) { + return request({ url: `/biz/orderProject/kingdee/order/${id}`, method: 'get', params }) }, // 暂存金蝶生产订单数据(草稿) diff --git a/src/api/production.ts b/src/api/production.ts index 3709567..0374a9c 100644 --- a/src/api/production.ts +++ b/src/api/production.ts @@ -59,7 +59,7 @@ export function workload(params?:any) { export function inspectio(data:any) { return request({ url: `/mes/dispatch/qc`, - method: 'put', + method: 'post', data }) } \ No newline at end of file diff --git a/src/api/qcResultDetail.ts b/src/api/qcResultDetail.ts index 713b2f1..331347e 100644 --- a/src/api/qcResultDetail.ts +++ b/src/api/qcResultDetail.ts @@ -24,6 +24,12 @@ export interface QcResultDetail { updateTime?: string + files?:any[], + + title?:string, + images?:any[], + attachments?:any[] + } // 质检结果明细表 API diff --git a/src/api/qualityTesting.ts b/src/api/qualityTesting.ts index fd5d34d..42bca4d 100644 --- a/src/api/qualityTesting.ts +++ b/src/api/qualityTesting.ts @@ -68,6 +68,10 @@ export const qualityTestingApi = { submit(data: QcResultDetail[]) { return request({ url: '/mes/qc/judge', method: 'put', data }) }, + + submitBF(data: QcResultDetail[]) { + return request({ url: '/mes/qc/partial', method: 'post', data }) + }, //质检撤回 cancel(id: number) { return request({ url: `/mes/dispatch/revoke/${id}`, method: 'put' }) diff --git a/src/api/submitLog.ts b/src/api/submitLog.ts index 74bdf87..2bfbcf7 100644 --- a/src/api/submitLog.ts +++ b/src/api/submitLog.ts @@ -71,5 +71,11 @@ export const submitLogApi = { //汇报统计 statistics(params?: {time?:string; type?:string}){ return request({url:'/mes/report/statistics',method:'get',params}) + }, + + + //按派工单id查询汇报 + getByDispatch(dispatchId:number){ + return request({url:`/mes/report/bydispatch/${dispatchId}`,method:"get"}) } } diff --git a/src/api/system.ts b/src/api/system.ts index d1f97bb..282dc6d 100644 --- a/src/api/system.ts +++ b/src/api/system.ts @@ -126,6 +126,14 @@ export const userApi = { method: 'get', responseType: 'blob' }) + }, + + //查询全部用户 + getPathList() { + return request({ + url:"sys/user/list", + method:'get' + }) } } diff --git a/src/api/system1.ts b/src/api/system1.ts index 146412c..a821139 100644 --- a/src/api/system1.ts +++ b/src/api/system1.ts @@ -1,4 +1,5 @@ import { request } from '@/utils/request' +import { F } from 'vue-router/dist/router-CWoNjPRp.mjs' // 分页结果 export interface PageResult { @@ -371,6 +372,34 @@ export interface SysFile { remark?: string } + +export interface DingTalkImage{ + id?:number + mainId?:number + fileName?:string + fileSuffix?:string + fileSize?:number + localFilePath?:string + fileUrl?:string + sortNum?:number + createTime?:string +} + +export interface DingTalkAttachment{ + id?:number + mainId?:number + fileName?:string + fileSuffix?:string + fileSize?:number + localFilePath?:string + ddSpaceId?:string + ddFileId?:string + uploadDdStatus?:string + sortNum?:number + createTime?:string + +} + export const fileApi = { page(params: { page: number; pageSize: number; originalName?: string; fileType?: string }): Promise> { return request({ url: '/sys/file/page', method: 'get', params }) @@ -402,8 +431,53 @@ export const fileApi = { return request({ url: '/sys/file/upload', method: 'post', - data: formData, - headers: { 'Content-Type': 'multipart/form-data' } + data: formData + // headers: { 'Content-Type': 'multipart/form-data' } + }) + }, + + uploadDingImage(file: File):Promise { + const formData = new FormData() + formData.append("file",file) + return request({ + url:"/sys/file/uploadDingImage", + method:'post', + data:formData + }) + }, + + uploadDingAttachment(file: File):Promise { + const formData = new FormData() + formData.append("file",file) + + return request({ + url:"/sys/file/uploadDingAttachment", + method:"post", + data:formData + }) + }, + + + uploadAndDingding(file: File, path?: string, groupId?: number | null): Promise{ + const formData = new FormData() + formData.append('file', file) + if (path) { + formData.append('path', path) + } + if (groupId !== undefined && groupId !== null && groupId > 0) { + formData.append('groupId', groupId.toString()) + } + return request({ + url: '/sys/file/uploadAndDingding', + method: 'post', + data: formData + }) + }, + + getApprovalSpaceId() { + return request({ + url:'sys/file/getApprovalSpaceId', + method:'get', }) }, @@ -418,6 +492,8 @@ export const fileApi = { }) }, + + getDownloadUrl(id: number): string { return `/api/sys/file/download/${id}` }, diff --git a/src/components/SiteLogoMark.vue b/src/components/SiteLogoMark.vue new file mode 100644 index 0000000..a19d00a --- /dev/null +++ b/src/components/SiteLogoMark.vue @@ -0,0 +1,36 @@ + + + + diff --git a/src/composables/useSiteLogo.ts b/src/composables/useSiteLogo.ts new file mode 100644 index 0000000..4123ade --- /dev/null +++ b/src/composables/useSiteLogo.ts @@ -0,0 +1,30 @@ +import { computed, ref, watch } from 'vue' +import { useSiteStore } from '@/stores/site' + +/** + * 站点 Logo:图片加载失败时回退为站点名称首字母 + */ +export function useSiteLogo(src?: () => string | undefined) { + const siteStore = useSiteStore() + const siteName = computed(() => siteStore.siteName || 'MES系统') + const siteLogo = computed(() => src?.() ?? siteStore.siteLogo) + const logoLoadFailed = ref(false) + const showSiteLogoImg = computed(() => !!siteLogo.value && !logoLoadFailed.value) + const fallbackLetter = computed(() => siteName.value.charAt(0) || 'M') + + watch(siteLogo, () => { + logoLoadFailed.value = false + }) + + function handleLogoError() { + logoLoadFailed.value = true + } + + return { + siteName, + siteLogo, + showSiteLogoImg, + fallbackLetter, + handleLogoError, + } +} diff --git a/src/layout/index.vue b/src/layout/index.vue index 681acb5..880415d 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -17,8 +17,11 @@ >