From ab030d2487d4f61dc7fa60eb45fcbf126a1ded08 Mon Sep 17 00:00:00 2001 From: TianyangZhang Date: Thu, 12 Mar 2026 16:57:12 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:mpr-=E7=89=A9=E8=B5=84=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=89=8D=E7=AB=AF=EF=BC=88=E7=94=B3=E8=B4=AD=E5=8D=95?= =?UTF-8?q?=E3=80=81=E5=85=A5=E5=BA=93=E5=8D=95=E3=80=81=E7=89=A9=E6=96=99?= =?UTF-8?q?=E5=BA=93=E5=AD=98=E3=80=81=E9=A2=86=E7=94=A8=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 mpr API 接口定义(申购单、入库单、物料库存、领用单 CRUD) - 新增申购单列表页与表单页,支持明细内联编辑和一次性提交审批 - 新增入库单列表页与表单页,支持仓库下拉选择和入库明细管理 - 新增物料库存列表页,支持状态筛选(闲置/领用中/已领用/已领完) - 新增领用记录列表页与表单页,支持从库存选择物品和非清单物品两类领用 - 注册物资管理路由菜单(申购单管理、入库单管理、物料库存、领用记录) Made-with: Cursor --- src/api/model/mpr.js | 114 ++++++ src/config/route.js | 49 +++ src/views/mpr/material_requisition.vue | 128 +++++++ src/views/mpr/material_requisition_form.vue | 397 ++++++++++++++++++++ src/views/mpr/requisition.vue | 123 ++++++ src/views/mpr/requisition_form.vue | 279 ++++++++++++++ src/views/mpr/warehouse_entry.vue | 133 +++++++ src/views/mpr/warehouse_entry_form.vue | 304 +++++++++++++++ src/views/mpr/warehouse_stock.vue | 112 ++++++ 9 files changed, 1639 insertions(+) create mode 100644 src/api/model/mpr.js create mode 100644 src/views/mpr/material_requisition.vue create mode 100644 src/views/mpr/material_requisition_form.vue create mode 100644 src/views/mpr/requisition.vue create mode 100644 src/views/mpr/requisition_form.vue create mode 100644 src/views/mpr/warehouse_entry.vue create mode 100644 src/views/mpr/warehouse_entry_form.vue create mode 100644 src/views/mpr/warehouse_stock.vue diff --git a/src/api/model/mpr.js b/src/api/model/mpr.js new file mode 100644 index 00000000..c0a2b30b --- /dev/null +++ b/src/api/model/mpr.js @@ -0,0 +1,114 @@ +import config from "@/config" +import http from "@/utils/request" +export default { + requisition: { + list: { + name: "申购单列表", + req: async function(data){ + return await http.get(`${config.API_URL}/mpr/requisition/`, data); + } + }, + create: { + name: "创建申购单", + req: async function(data){ + return await http.post(`${config.API_URL}/mpr/requisition/`, data); + } + }, + item: { + name: "获取申购单详情", + req: async function(id){ + return await http.get(`${config.API_URL}/mpr/requisition/${id}/`); + } + }, + update: { + name: "更新申购单", + req: async function(id, data){ + return await http.put(`${config.API_URL}/mpr/requisition/${id}/`, data); + } + }, + delete: { + name: "删除申购单", + req: async function(id){ + return await http.delete(`${config.API_URL}/mpr/requisition/${id}/`); + } + }, + }, + warehouseStock: { + list: { + name: "物料库存列表", + req: async function(data){ + return await http.get(`${config.API_URL}/mpr/warehouse_stock/`, data); + } + }, + item: { + name: "获取库存详情", + req: async function(id){ + return await http.get(`${config.API_URL}/mpr/warehouse_stock/${id}/`); + } + }, + }, + materialRequisition: { + list: { + name: "领用单列表", + req: async function(data){ + return await http.get(`${config.API_URL}/mpr/material_requisition/`, data); + } + }, + create: { + name: "创建领用单", + req: async function(data){ + return await http.post(`${config.API_URL}/mpr/material_requisition/`, data); + } + }, + item: { + name: "获取领用单详情", + req: async function(id){ + return await http.get(`${config.API_URL}/mpr/material_requisition/${id}/`); + } + }, + update: { + name: "更新领用单", + req: async function(id, data){ + return await http.put(`${config.API_URL}/mpr/material_requisition/${id}/`, data); + } + }, + delete: { + name: "删除领用单", + req: async function(id){ + return await http.delete(`${config.API_URL}/mpr/material_requisition/${id}/`); + } + }, + }, + warehouseEntry: { + list: { + name: "入库单列表", + req: async function(data){ + return await http.get(`${config.API_URL}/mpr/warehouse_entry/`, data); + } + }, + create: { + name: "创建入库单", + req: async function(data){ + return await http.post(`${config.API_URL}/mpr/warehouse_entry/`, data); + } + }, + item: { + name: "获取入库单详情", + req: async function(id){ + return await http.get(`${config.API_URL}/mpr/warehouse_entry/${id}/`); + } + }, + update: { + name: "更新入库单", + req: async function(id, data){ + return await http.put(`${config.API_URL}/mpr/warehouse_entry/${id}/`, data); + } + }, + delete: { + name: "删除入库单", + req: async function(id){ + return await http.delete(`${config.API_URL}/mpr/warehouse_entry/${id}/`); + } + }, + } +} diff --git a/src/config/route.js b/src/config/route.js index ca8d1255..c776008b 100644 --- a/src/config/route.js +++ b/src/config/route.js @@ -2091,6 +2091,55 @@ const routes = [ }, ], }, + //物资申购 mpr + { + name: "mpr", + path: "/mpr", + meta: { + title: "物资管理", + icon: "el-icon-document", + type: "menu", + perms: ["mpr"], + }, + children: [ + { + name: "requisition", + path: "/mpr/requisition", + meta: { + title: "申购单管理", + perms: ["requisition"], + }, + component: "mpr/requisition", + }, + { + name: "warehouse_entry", + path: "/mpr/warehouse_entry", + meta: { + title: "入库单管理", + perms: ["warehouse_entry"], + }, + component: "mpr/warehouse_entry", + }, + { + name: "warehouse_stock", + path: "/mpr/warehouse_stock", + meta: { + title: "物料库存", + perms: ["warehouse_stock"], + }, + component: "mpr/warehouse_stock", + }, + { + name: "material_requisition", + path: "/mpr/material_requisition", + meta: { + title: "领用记录", + perms: ["material_requisition"], + }, + component: "mpr/material_requisition", + }, + ], + }, //采购 pum { name: "pum", diff --git a/src/views/mpr/material_requisition.vue b/src/views/mpr/material_requisition.vue new file mode 100644 index 00000000..4f39e661 --- /dev/null +++ b/src/views/mpr/material_requisition.vue @@ -0,0 +1,128 @@ + + + diff --git a/src/views/mpr/material_requisition_form.vue b/src/views/mpr/material_requisition_form.vue new file mode 100644 index 00000000..fdedf79f --- /dev/null +++ b/src/views/mpr/material_requisition_form.vue @@ -0,0 +1,397 @@ + + + diff --git a/src/views/mpr/requisition.vue b/src/views/mpr/requisition.vue new file mode 100644 index 00000000..fecb6112 --- /dev/null +++ b/src/views/mpr/requisition.vue @@ -0,0 +1,123 @@ + + + diff --git a/src/views/mpr/requisition_form.vue b/src/views/mpr/requisition_form.vue new file mode 100644 index 00000000..17b59d3a --- /dev/null +++ b/src/views/mpr/requisition_form.vue @@ -0,0 +1,279 @@ + + + diff --git a/src/views/mpr/warehouse_entry.vue b/src/views/mpr/warehouse_entry.vue new file mode 100644 index 00000000..232023a0 --- /dev/null +++ b/src/views/mpr/warehouse_entry.vue @@ -0,0 +1,133 @@ + + + diff --git a/src/views/mpr/warehouse_entry_form.vue b/src/views/mpr/warehouse_entry_form.vue new file mode 100644 index 00000000..fb8592fc --- /dev/null +++ b/src/views/mpr/warehouse_entry_form.vue @@ -0,0 +1,304 @@ + + + diff --git a/src/views/mpr/warehouse_stock.vue b/src/views/mpr/warehouse_stock.vue new file mode 100644 index 00000000..f7d8983b --- /dev/null +++ b/src/views/mpr/warehouse_stock.vue @@ -0,0 +1,112 @@ + + + From a994cbc10df5939d3ea4d7e032349b1d594f7bff Mon Sep 17 00:00:00 2001 From: TianyangZhang Date: Mon, 23 Mar 2026 09:50:09 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E5=85=89?= =?UTF-8?q?=E8=8A=AFOA=E5=AE=A1=E6=89=B9=E7=9A=84BUG=E4=B8=8E=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 24 +- package.json | 32 +- src/components/scExportBtn/index.vue | 80 +++++ src/views/asm/assetlog.vue | 21 +- src/views/hrm/empcontract.vue | 93 +++--- src/views/hrm/empjoin.vue | 78 +++-- src/views/hrm/empneed.vue | 102 ++++--- src/views/hrm/leave.vue | 232 +++++++------- src/views/hrm/leave_form.vue | 442 ++++++++++++++------------- src/views/hrm/probation.vue | 184 +++++------ src/views/hrm/resignation.vue | 106 +++---- src/views/hrm/transfer.vue | 122 ++++---- src/views/ofm/borrowfile.vue | 15 +- src/views/ofm/exportBtn.vue | 83 +++++ src/views/ofm/mroombooking.vue | 15 +- src/views/ofm/publicity.vue | 89 +++++- src/views/ofm/publicity_form.vue | 62 +++- src/views/ofm/seal.vue | 27 +- src/views/ofm/seal_form.vue | 42 ++- src/views/ofm/vehicle.vue | 21 +- src/views/pm/gantt.vue | 1 + src/views/pm/mtask2.vue | 1 + src/views/pm/utask.vue | 1 + src/views/pm/utask_dept10.vue | 1 + src/views/pm/utask_dept6.vue | 1 + src/views/pm/utask_dept7.vue | 1 + src/views/pum/supplieraudit.vue | 8 + 27 files changed, 1124 insertions(+), 760 deletions(-) create mode 100644 src/components/scExportBtn/index.vue create mode 100644 src/views/ofm/exportBtn.vue diff --git a/.env.development b/.env.development index a8c4e2a5..88d1f4fa 100644 --- a/.env.development +++ b/.env.development @@ -4,7 +4,7 @@ NODE_ENV = development # 标题 # VUE_APP_TITLE = '曲阳金隅安全智能管控平台' # VUE_APP_TITLE = '托克逊能源管理平台' -VUE_APP_TITLE = '中建材光子科技有限公司' +VUE_APP_TITLE = '中建材光芯科技有限公司' # VUE_APP_TITLE = '超低排放系统' VUE_APP_PJ = 'gx' @@ -21,20 +21,28 @@ VUE_APP_PJ = 'gx' # VUE_APP_BASEURL = http://10.50.211.228:2250/ -# VUE_APP_BASEURL = http://127.0.0.1:8887 -# VUE_APP_BASEURL = http://127.0.0.1:226 +VUE_APP_API_BASEURL = http://127.0.0.1:2226/api +VUE_APP_BASEURL = http://127.0.0.1:2226 -# #光子 -# VUE_APP_API_BASEURL = http://tkx.xxhhcty.xyz:8080/api -# VUE_APP_BASEURL = http://tkx.xxhhcty.xyz:8080 +# 托克逊 +# VUE_APP_API_BASEURL = http://10.50.211.228:2250/api +# VUE_APP_BASEURL = http://10.50.211.228:2250/ # 光芯 -VUE_APP_API_BASEURL = http://49.232.14.174:2226/api -VUE_APP_BASEURL = http://49.232.14.174:2226 +# VUE_APP_API_BASEURL = http://127.0.0.1:2226/api +# VUE_APP_BASEURL = http://127.0.0.1:2226 + +# 光芯线上 +# VUE_APP_API_BASEURL = http://gxerp.xxhhcty.xyz:8080/api +# VUE_APP_BASEURL = http://gxerp.xxhhcty.xyz:8080 # # 凌源 bh # VUE_APP_API_BASEURL = http://lybh.xxhhcty.xyz:8080/api # VUE_APP_BASEURL = http://lybh.xxhhcty.xyz:8080/ + +# 凌源 sl +# VUE_APP_API_BASEURL = http://lysl.xxhhcty.xyz:8080/api +# VUE_APP_BASEURL = http://lysl.xxhhcty.xyz:8080/ # 本地端口 VUE_APP_PORT = 2800 diff --git a/package.json b/package.json index ebf02feb..c66416ec 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,7 @@ "private": true, "scripts": { "serve": "vue-cli-service serve", - "build": "vue-cli-service build --report", - "lint": "vue-cli-service lint" + "build": "vue-cli-service build --report" }, "dependencies": { "@element-plus/icons-vue": "2.0.10", @@ -49,40 +48,11 @@ }, "devDependencies": { "@babel/core": "7.21.00", - "@babel/eslint-parser": "7.19.1", "@vue/cli-plugin-babel": "5.0.8", - "@vue/cli-plugin-eslint": "5.0.8", "@vue/cli-service": "5.0.8", - "eslint": "8.35.0", - "eslint-plugin-vue": "9.9.0", "sass": "1.58.3", "sass-loader": "10.1.1" }, - "eslintConfig": { - "root": true, - "env": { - "node": true - }, - "globals": { - "APP_CONFIG": true - }, - "extends": [ - "plugin:vue/vue3-essential" - ], - "parserOptions": { - "parser": "@babel/eslint-parser" - }, - "rules": { - "indent": 0, - "no-tabs": 0, - "no-mixed-spaces-and-tabs": 0, - "vue/no-unused-components": 0, - "vue/multi-word-component-names": 0, - "no-debugger": "off", - "no-console": "off", - "no-trailing-spaces": "off" - } - }, "browserslist": [ "> 1%", "last 2 versions", diff --git a/src/components/scExportBtn/index.vue b/src/components/scExportBtn/index.vue new file mode 100644 index 00000000..12bb6903 --- /dev/null +++ b/src/components/scExportBtn/index.vue @@ -0,0 +1,80 @@ + + + diff --git a/src/views/asm/assetlog.vue b/src/views/asm/assetlog.vue index e04270eb..7b53d92f 100644 --- a/src/views/asm/assetlog.vue +++ b/src/views/asm/assetlog.vue @@ -3,6 +3,7 @@
资产入库 +
\ No newline at end of file diff --git a/src/views/hrm/empcontract.vue b/src/views/hrm/empcontract.vue index 76b4c1e1..b591f826 100644 --- a/src/views/hrm/empcontract.vue +++ b/src/views/hrm/empcontract.vue @@ -1,47 +1,58 @@ \ No newline at end of file +import ExportBtn from '@/components/scExportBtn/index.vue' +import { actStateEnum } from "@/utils/enum.js" +const drawerVisible = ref(false) +const mode = ref('add') +const t_id = ref(null) +const handleAdd = () => { mode.value = 'add'; t_id.value = null; drawerVisible.value = true; } +const exportCols = [ + { header: "部门", key: "dept_need_name", wch: 15 }, + { header: "员工姓名", key: "employee_name", wch: 10 }, + { header: "岗位", key: "post_name", wch: 12 }, + { header: "入职日期", key: "join_date", wch: 12 }, + { header: "合同结束日期", key: "end_contract", wch: 14 }, + { header: "变更次数", key: "counts", wch: 8 }, + { header: "应续签", key: "plan_renewal", wch: 12 }, + { header: "正常续签", key: "normal_renewal", wch: 12 }, + { header: "续签/变更(年)", key: "change_date", wch: 12 }, + { header: "变更原因", key: "change_reason", wch: 25 }, + { header: "审批状态", key: "_act_state_text", wch: 10 }, +] + diff --git a/src/views/hrm/empjoin.vue b/src/views/hrm/empjoin.vue index 01bb1f0a..490d69d4 100644 --- a/src/views/hrm/empjoin.vue +++ b/src/views/hrm/empjoin.vue @@ -1,48 +1,42 @@ \ No newline at end of file +import ExportBtn from '@/components/scExportBtn/index.vue' +import { actStateEnum } from "@/utils/enum.js" +const drawerVisible = ref(false) +const mode = ref('add') +const t_id = ref(null) +const handleAdd = () => { mode.value = 'add'; t_id.value = null; drawerVisible.value = true; } +const exportCols = [ + { header: "部门", key: "dept_need_name", wch: 15 }, + { header: "入职日期", key: "join_date", wch: 12 }, + { header: "审批状态", key: "_act_state_text", wch: 10 }, +] + diff --git a/src/views/hrm/empneed.vue b/src/views/hrm/empneed.vue index b2c3b7d8..9c9aa6fb 100644 --- a/src/views/hrm/empneed.vue +++ b/src/views/hrm/empneed.vue @@ -1,56 +1,58 @@ \ No newline at end of file +import ExportBtn from '@/components/scExportBtn/index.vue' +import { actStateEnum } from "@/utils/enum.js" +const drawerVisible = ref(false) +const mode = ref('add') +const t_id = ref(null) +const handleAdd = () => { mode.value = 'add'; t_id.value = null; drawerVisible.value = true; } +const exportCols = [ + { header: "部门", key: "dept_need_name", wch: 15 }, + { header: "需求岗位", key: "post_need", wch: 12 }, + { header: "需求人数", key: "count_need", wch: 10 }, + { header: "工资报酬", key: "salary", wch: 10 }, + { header: "到岗日期", key: "arrival_date", wch: 12 }, + { header: "岗位职责", key: "duty", wch: 20 }, + { header: "性别要求", key: "gender", wch: 8 }, + { header: "学历要求", key: "education", wch: 10 }, + { header: "申请理由", key: "reason", wch: 20 }, + { header: "专业及技能要求", key: "professional_requirement", wch: 25 }, + { header: "审批状态", key: "_act_state_text", wch: 10 }, +] + diff --git a/src/views/hrm/leave.vue b/src/views/hrm/leave.vue index b1dd758f..538095d8 100644 --- a/src/views/hrm/leave.vue +++ b/src/views/hrm/leave.vue @@ -1,134 +1,116 @@ \ No newline at end of file + diff --git a/src/views/hrm/leave_form.vue b/src/views/hrm/leave_form.vue index 31019337..b22e30a5 100644 --- a/src/views/hrm/leave_form.vue +++ b/src/views/hrm/leave_form.vue @@ -1,218 +1,246 @@ \ No newline at end of file + filteredEmpOptions() { + if (!this.filterKeyword) return this.empOptions; + const kw = this.filterKeyword.toLowerCase(); + return this.empOptions.filter(e => + (e.name || '').toLowerCase().includes(kw) || + (e.belong_dept_name || '').toLowerCase().includes(kw) || + (e.post_name || '').toLowerCase().includes(kw) + ); + }, + }, + watch: { + mode(val) { this.localMode = val; }, + }, + mounted() { + if (this.t_id) { + this.getTid(); + } else { + this.initFormData(); + } + }, + methods: { + async getTid() { + try { + let res = await this.$API.hrm.leave.item.req(this.t_id); + this.formData = res; + if (res.ticket_ && res.ticket_.state_.type == 1 && res.create_by == this.$TOOL.data.get("USER_INFO").id) { + this.localMode = "edit"; + } + } catch (e) { + console.error('获取请假数据失败:', e); + } + }, + async initFormData() { + try { + let userInfo = this.$TOOL.data.get("USER_INFO"); + this.currentDeptId = userInfo.belong_dept; + // 获取当前用户员工信息 + let res = await this.$API.hrm.employee.read.req(); + this.formData.employee_name = res.name; + this.formData.belong_dept_name = res.belong_dept_name; + this.formData.post_name = res.post_name; + // 先加载本部门人员选项 + await this.loadDeptEmployees(); + // 切换为add模式,员工信息默认为空,由用户自行选择 + this.localMode = "add"; + } catch (e) { + console.error('初始化表单数据失败:', e); + } + }, + async loadDeptEmployees() { + if (!this.currentDeptId) return; + try { + let res = await this.$API.hrm.employee.list.req({ page: 0, belong_dept: this.currentDeptId }); + this.empOptions = Array.isArray(res) ? res : (res.results || []); + } catch (e) { + console.error(e); + } + }, + filterEmployee(keyword) { + this.filterKeyword = keyword; + }, + handleEmpChange(id) { + const emp = this.empOptions.find(e => e.id === id); + if (emp) { + this.formData.employee_name = emp.name; + this.formData.belong_dept_name = emp.belong_dept_name || ''; + this.formData.post_name = emp.post_name || ''; + } + }, + handleTypeChange(val) { + this.formData.leave_type_name = LEAVE_TYPE_NAME[val] || '' + }, + handleDel() { + this.$confirm('确定删除吗?', "提示", { type: "warning" }).then(() => { + this.$API.hrm.leave.delete.req(this.formData.id).then(() => { + this.$message.success("删除成功"); + this.$emit('success'); + }) + }) + }, + async handleSave() { + if (this.localMode == "add") { + try { + await this.$API.hrm.leave.create.req(this.formData); + this.$message.success("提交成功"); + this.$emit('success', this.localMode); + } catch (e) { + console.error('请假申请失败:', e); + throw e; + } + } + }, + fileUPSuccess(res) { + this.formData.file = res?.path || '' + }, + }, +}; + diff --git a/src/views/hrm/probation.vue b/src/views/hrm/probation.vue index babf9b03..9f737c87 100644 --- a/src/views/hrm/probation.vue +++ b/src/views/hrm/probation.vue @@ -1,119 +1,83 @@ \ No newline at end of file + diff --git a/src/views/hrm/resignation.vue b/src/views/hrm/resignation.vue index d7a53dcb..085422de 100644 --- a/src/views/hrm/resignation.vue +++ b/src/views/hrm/resignation.vue @@ -1,65 +1,55 @@ - + + + + \ No newline at end of file