From 476b9f79cb21a5d1372c32a956c5d6f300015cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9C002001lixiaobang=E2=80=9D?= <2547956374@qq.com> Date: Thu, 29 Jan 2026 10:37:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/index.js | 5 +- src/api/modules/user.js | 6 +- src/api/modules/workTicket.js | 199 +++ src/api/request.js | 165 ++- src/manifest.json | 8 +- src/pages/WorkOrderApproval/index.vue | 234 +++- src/pages/WorkOrderDetails/index.vue | 1021 ++++++++++++++- .../compoents/ApplyForMachine.vue | 124 +- .../WorkOrderEdit/compoents/BasicsInfo.vue | 104 +- .../WorkOrderEdit/compoents/GatePassInfo.vue | 513 ++++++-- .../WorkOrderEdit/compoents/RiskControl.vue | 327 ++++- .../WorkOrderEdit/compoents/WorkNote.vue | 451 ++++++- src/pages/WorkOrderEdit/index.vue | 1166 ++++++++++++++++- src/pages/login/index.vue | 47 +- vite.config.js | 12 + 15 files changed, 4069 insertions(+), 313 deletions(-) create mode 100644 src/api/modules/workTicket.js diff --git a/src/api/index.js b/src/api/index.js index 74f0b02..dd76417 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -1,2 +1,3 @@ -export * from './auth' -export * from './user' +export * from './modules/auth' +export * from './modules/user' +export * from './modules/workTicket' \ No newline at end of file diff --git a/src/api/modules/user.js b/src/api/modules/user.js index 4ba51dd..c125904 100644 --- a/src/api/modules/user.js +++ b/src/api/modules/user.js @@ -17,9 +17,13 @@ export function bindPhone(phone, smsCode) { } export function getUserList(params) { - return get('/user/list', params) + return get('/system/user/list', params) } export function getUserDetail(id) { return get(`/user/detail/${id}`) } + +export function getUserInfo() { + return get('/system/user/getInfo') +} diff --git a/src/api/modules/workTicket.js b/src/api/modules/workTicket.js new file mode 100644 index 0000000..910b19b --- /dev/null +++ b/src/api/modules/workTicket.js @@ -0,0 +1,199 @@ +import { post, get, del, put, uploadFile } from '../request' + +/** + * 新增工作票申请 + * @param {Object} data - 工作票数据 + * @param {Number} data.projectId - 所属项目ID(必填) + * @param {String} data.workLocation - 作业地点 + * @param {Number} data.supervisorId - 作业负责人ID + * @param {String} data.supervisorName - 作业负责人姓名 + * @param {String} data.supervisorPosition - 作业负责人职位 + * @param {String} data.workContent - 作业内容 + * @param {String} data.riskType - 风险类型(如:高风险、中风险、低风险) + * @param {String} data.workStartTime - 作业开始时间(格式:yyyy-MM-dd HH:mm:ss) + * @param {String} data.workEndTime - 作业结束时间(格式:yyyy-MM-dd HH:mm:ss) + * @param {Array} data.safetyMeasuresList - 安全措施列表 + * @param {Array} data.qualificationList - 作业班成员资质列表 + * @param {String} data.needMonitoringCamera - 是否需申领移动监控球机("0"否,"1"是) + * @param {Number} data.cameraApplicationId - 监控球机申请ID(如果需要监控球机时填写) + * @param {String} data.remark - 备注 + * @returns {Promise} 返回工作票ID + */ +export function createWorkTicket(data) { + return post('/manage/contractor/workTicket', data) +} + +/** + * 出入证申请 + * @param {Object} data - 出入证申请数据 + * @returns {Promise} + */ +export function applyAccessPermit(data) { + return post('/manage/contractor/accessPermit', data) +} + +/** + * 新增工作计划 + * @param {Object} data - 工作计划数据 + * @returns {Promise} + */ +export function createWorkPlan(data) { + return post('/manage/contractor/workPlan', data) +} + +/** + * 球机申领新增接口 + * @param {Object} data - 球机申领数据 + * @param {Number} data.projectId - 项目ID(必填) + * @param {Number} data.needCameraCnt - 申领数量(必填,必须大于0) + * @param {String} data.installationLocation - 安装位置(必填) + * @param {String} data.contactPerson - 联系人(必填) + * @param {String} data.contactPhone - 联系方式(必填) + * @param {String} data.remark - 备注(可选) + * @returns {Promise} 返回申领单ID + */ +export function createCameraApplication(data) { + return post('/manage/project/cameraApplication', data) +} + +/** + * 查询工作计划列表 + * @param {Object} params - 查询参数 + * @param {Number} params.pageNum - 页码(可选) + * @param {Number} params.pageSize - 每页数量(可选) + * @param {String} params.status - 状态(可选) + * @param {Number} params.projectId - 项目ID(可选) + * @returns {Promise} 返回工作计划列表 { total: number, rows: array } + */ +export function getWorkPlanList(params) { + return get('/manage/contractor/workPlan/list', params) +} + +/** + * 删除工作计划 + * @param {Number|String|Array|Array} projectIds - 项目ID,可以是单个ID、ID数组或逗号分隔的字符串 + * @returns {Promise} + */ +export function deleteWorkPlan(projectIds) { + // 处理不同的输入格式 + let ids = projectIds + if (Array.isArray(projectIds)) { + ids = projectIds.join(',') + } + return del(`/manage/contractor/workPlan/${ids}`) +} + +/** + * 提交工作计划 + * @param {Number|String} projectId - 项目ID(必填) + * @returns {Promise} + */ +export function submitWorkPlan(projectId) { + return put(`/manage/contractor/workPlan/submit/${projectId}`) +} + +/** + * 上传文件 + * @param {String} filePath - 文件路径(本地临时文件路径) + * @param {String} name - 文件对应的 key,默认为 'file' + * @param {Object} formData - 额外的表单数据 + * @param {Object} options - 其他配置选项 + * @returns {Promise<{name: string, url: string}>} 返回上传后的文件信息,包含 name(文件名)和 url(文件访问地址) + */ +export function uploadFileApi(filePath, name = 'file', formData = {}, options = {}) { + return uploadFile('/file/upload', filePath, name, formData, options) +} + +/** + * 查询风险管控卡模板列表 + * @param {Object} params - 查询参数(可选) + * @returns {Promise} 返回风险管控卡模板列表 + */ +export function getRiskCardTemplateList(params = {}) { + return get('/manage/logistics/riskCard/template/list', params) +} + +/** + * 获取风险管控卡模板详细信息 + * @param {Number|String} templateId - 模板ID(必填) + * @returns {Promise} 返回风险管控卡模板详细信息 + */ +export function getRiskCardTemplateDetail(templateId) { + return get(`/manage/logistics/riskCard/template/${templateId}`) +} + +/** + * 获取工作计划详细信息 + * @param {Number|String} projectId - 项目ID(必填) + * @returns {Promise} 返回工作计划详细信息 + */ +export function getWorkPlanDetail(projectId) { + return get(`/manage/contractor/workPlan/${projectId}`) +} + +/** + * 获取工作票详细信息 + * @param {Number|String} ticketId - 工作票ID(必填) + * @returns {Promise} 返回工作票详细信息 + */ +export function getWorkTicketDetail(ticketId) { + return get(`/manage/contractor/workTicket/${ticketId}`) +} + +/** + * 提交风险管控卡监理审核 + * @param {Object} data - 风险管控卡数据 + * @param {Number} data.ticketId - 工作票ID(必填) + * @param {Number} data.templateId - 模板ID(必填) + * @param {String} data.ticketNumber - 票证编号(必填) + * @param {String} data.operatingUnit - 所属单位(必填) + * @param {String} data.workContent - 工作内容(必填) + * @param {String} data.supervisorName - 工作负责人姓名(必填) + * @param {String} data.supervisorPosition - 工作负责人职位 + * @param {String} data.contactMethod - 联系方式 + * @param {String} data.inspectionTime - 检查时间(格式:yyyy-MM-ddTHH:mm) + * @param {Array} data.checkItems - 检查项列表 + * @param {Number} data.checkItems[].templateItemId - 模板项ID + * @param {String} data.checkItems[].itemDescription - 检查项描述 + * @param {String} data.checkItems[].checkResult - 检查结果 + * @param {Number} data.checkItems[].sortOrder - 排序顺序 + * @param {Array} data.attachmentList - 附件URL列表 + * @returns {Promise} 返回风险管控卡ID(cardId) + */ +export function submitRiskControlCard(data) { + return post('/manage/contractor/riskControlCard', data) +} + +/** + * 提交工作票 + * @param {Number|String} ticketId - 工作票ID(必填) + * @param {Number|String} cardId - 风险管控卡ID(可选,高等风险时必填) + * @returns {Promise} + */ +export function submitWorkTicket(ticketId, cardId = null) { + let url = `/manage/contractor/workTicket/submit/${ticketId}`; + if (cardId) { + url += `?cardId=${cardId}`; + } + return put(url) +} + +/** + * 提交工作票(承包商接口) + * @param {Number|String} ticketId - 工作票ID(必填) + * @returns {Promise} + */ +export function submitWorkTicketForContractor(ticketId) { + return put(`/manage/contractor/workTicket/submit/${ticketId}`) +} + +/** + * 提交实施 + * @param {Number|String} projectId - 项目ID(必填) + * @returns {Promise} + */ +export function submitImplementation(projectId) { + return put(`/manage/contractor/projectImplementation/submitImplementation?projectId=${projectId}`) +} + + diff --git a/src/api/request.js b/src/api/request.js index 6ad81e1..41adc73 100644 --- a/src/api/request.js +++ b/src/api/request.js @@ -1,21 +1,28 @@ import { useUserStore } from '@/store/user' -const BASE_URL = 'https://api.example.com' +// 根据平台配置不同的基础URL +// H5 开发环境使用代理路径 /api,通过 vite 代理解决跨域问题 +// H5 生产环境和小程序、App 使用完整URL +let BASE_URL = '/api' + +// #ifdef H5 + +// #endif const requestInterceptor = (config) => { const userStore = useUserStore() - - if (config.header) { - config.header = { - ...config.header, - 'Content-Type': 'application/json', - 'Authorization': userStore.token ? `Bearer ${userStore.token}` : '' - } - } else { - config.header = { - 'Content-Type': 'application/json', - 'Authorization': userStore.token ? `Bearer ${userStore.token}` : '' - } + + // 初始化 header 对象 + if (!config.header) { + config.header = {} + } + + // 设置 Content-Type + config.header['Content-Type'] = config.header['Content-Type'] || 'application/json' + + // 如果有 token,添加 authorization header + if (userStore.token) { + config.header['authorization'] = `Bearer ${userStore.token}` } return config @@ -25,11 +32,11 @@ const responseInterceptor = (response) => { const { statusCode, data } = response if (statusCode === 200) { - if (data.code === 0 || data.success) { - return data.data || data.result + if (data.code === 0 || data.code === 200 || data.success) { + return data.data || data.result || data } else { uni.showToast({ - title: data.message || '请求失败', + title: data.msg || data.message || '请求失败', icon: 'none' }) return Promise.reject(data) @@ -81,10 +88,13 @@ function request(options) { url: url.startsWith('http') ? url : `${BASE_URL}${url}`, method, data, - header: requestInterceptor({ header }), + header, timeout: 15000 } + // 通过拦截器处理 header + requestInterceptor(config) + return new Promise((resolve, reject) => { if (loading) { uni.showLoading({ @@ -96,8 +106,17 @@ function request(options) { uni.request({ ...config, success: (res) => { - const result = responseInterceptor(res) - resolve(result) + try { + const result = responseInterceptor(res) + // 如果 result 是 Promise,需要正确处理 + if (result instanceof Promise) { + result.then(resolve).catch(reject) + } else { + resolve(result) + } + } catch (error) { + reject(error) + } }, fail: (err) => { uni.showToast({ @@ -160,4 +179,112 @@ export function patch(url, data, options) { }) } +/** + * 文件上传 + * @param {String} url - 上传接口地址 + * @param {String} filePath - 文件路径(本地临时文件路径) + * @param {String} name - 文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容 + * @param {Object} formData - HTTP 请求中其他额外的 form data + * @param {Object} options - 其他配置选项 + * @param {Boolean} options.loading - 是否显示加载提示,默认 true + * @param {String} options.loadingText - 加载提示文字,默认 '上传中...' + * @returns {Promise} + */ +export function uploadFile(url, filePath, name = 'file', formData = {}, options = {}) { + const { loading = true, loadingText = '上传中...' } = options + const userStore = useUserStore() + + // 构建完整的 URL + const fullUrl = url.startsWith('http') ? url : `${BASE_URL}${url}` + + // 构建请求头 + const header = {} + if (userStore.token) { + header['authorization'] = `Bearer ${userStore.token}` + } + + return new Promise((resolve, reject) => { + if (loading) { + uni.showLoading({ + title: loadingText, + mask: true + }) + } + + uni.uploadFile({ + url: fullUrl, + filePath: filePath, + name: name, + formData: formData, + header: header, + success: (res) => { + try { + // uni.uploadFile 返回的是字符串,需要解析 + const data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data + + if (res.statusCode === 200) { + if (data.code === 0 || data.code === 200 || data.success) { + resolve(data.data || data.result || data) + } else { + uni.showToast({ + title: data.msg || data.message || '上传失败', + icon: 'none' + }) + reject(data) + } + } else if (res.statusCode === 401) { + uni.showToast({ + title: '登录已过期,请重新登录', + icon: 'none' + }) + userStore.clearUser() + setTimeout(() => { + uni.reLaunch({ + url: '/pages/login/index' + }) + }, 1500) + reject(res) + } else if (res.statusCode === 403) { + uni.showToast({ + title: '没有权限访问', + icon: 'none' + }) + reject(res) + } else if (res.statusCode >= 500) { + uni.showToast({ + title: '服务器错误,请稍后重试', + icon: 'none' + }) + reject(res) + } else { + uni.showToast({ + title: '上传失败', + icon: 'none' + }) + reject(res) + } + } catch (error) { + uni.showToast({ + title: '上传响应解析失败', + icon: 'none' + }) + reject(error) + } + }, + fail: (err) => { + uni.showToast({ + title: '上传失败,请检查网络', + icon: 'none' + }) + reject(err) + }, + complete: () => { + if (loading) { + uni.hideLoading() + } + } + }) + }) +} + export default request diff --git a/src/manifest.json b/src/manifest.json index db4b2a5..ed20d46 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -43,7 +43,13 @@ "minified": true, "postcss": true }, - "usingComponents": true + "usingComponents": true, + "requiredPrivateInfos": [], + "permission": { + "scope.userLocation": { + "desc": "您的位置信息将用于小程序位置接口的效果展示" + } + } }, "mp-alipay": { "usingComponents": true diff --git a/src/pages/WorkOrderApproval/index.vue b/src/pages/WorkOrderApproval/index.vue index 4d42264..57ad791 100644 --- a/src/pages/WorkOrderApproval/index.vue +++ b/src/pages/WorkOrderApproval/index.vue @@ -4,7 +4,7 @@ + @update:current="handleTypeChange($event)"> 新建工单 @@ -12,31 +12,32 @@ - - - - - + + + + {{ item.projectName || '未命名项目' }} + 详情 + + 项目编号:{{ item.projectCode }} + + + + + + + + + + + + \ No newline at end of file diff --git a/src/pages/WorkOrderEdit/compoents/ApplyForMachine.vue b/src/pages/WorkOrderEdit/compoents/ApplyForMachine.vue index 7c888da..021e38b 100644 --- a/src/pages/WorkOrderEdit/compoents/ApplyForMachine.vue +++ b/src/pages/WorkOrderEdit/compoents/ApplyForMachine.vue @@ -5,7 +5,7 @@ 作业地点 - + @@ -13,11 +13,11 @@ - + - + @@ -35,9 +35,21 @@ - 联系人+联系方式 + 联系人 - + + + + + 联系方式 + + + + + + 备注 + + @@ -46,7 +58,7 @@ diff --git a/src/pages/WorkOrderEdit/compoents/RiskControl.vue b/src/pages/WorkOrderEdit/compoents/RiskControl.vue index 22961dc..754da28 100644 --- a/src/pages/WorkOrderEdit/compoents/RiskControl.vue +++ b/src/pages/WorkOrderEdit/compoents/RiskControl.vue @@ -4,53 +4,48 @@ 基础信息 - - 所属单位 - 选择 - + 所属单位 - - 请选择所属单位 - {{ formData.unitName }} - - + 票证编号 - + 工作内容 - + 工作负责人 - 选择 + 选择 请选择工作负责人 {{ formData.workResponsible }} - 检查内容 - - - {{ index + 1 }}: {{ item.name }} + + + 第{{ index + 1 }}项: {{ item.itemDescription }} + + 暂无检查内容 + 附件上传 @@ -65,13 +60,16 @@ - + {{ item.name }} {{ item.size }} + 上传中... - + + @@ -80,14 +78,21 @@