diff --git a/api/hrm/attendance.js b/api/hrm/attendance.js
new file mode 100644
index 0000000..7e06afb
--- /dev/null
+++ b/api/hrm/attendance.js
@@ -0,0 +1,127 @@
+import request from "@/util/oaRequest"
+
+// 班次
+export function listShift(query) {
+ return request({
+ url: '/hrm/shift/list',
+ method: 'get',
+ params: query
+ })
+}
+export function addShift(data) {
+ return request({
+ url: '/hrm/shift',
+ method: 'post',
+ data
+ })
+}
+export function updateShift(data) {
+ return request({
+ url: '/hrm/shift',
+ method: 'put',
+ data
+ })
+}
+export function delShift(shiftIds) {
+ return request({
+ url: `/hrm/shift/${shiftIds}`,
+ method: 'delete'
+ })
+}
+
+// 排班
+export function listSchedule(query) {
+ return request({
+ url: '/hrm/schedule/list',
+ method: 'get',
+ params: query
+ })
+}
+export function addSchedule(data) {
+ return request({
+ url: '/hrm/schedule',
+ method: 'post',
+ data
+ })
+}
+export function updateSchedule(data) {
+ return request({
+ url: '/hrm/schedule',
+ method: 'put',
+ data
+ })
+}
+export function delSchedule(scheduleIds) {
+ return request({
+ url: `/hrm/schedule/${scheduleIds}`,
+ method: 'delete'
+ })
+}
+
+// 打卡
+export function listPunch(query) {
+ return request({
+ url: '/hrm/punch/list',
+ method: 'get',
+ params: query
+ })
+}
+export function addPunch(data) {
+ return request({
+ url: '/hrm/punch',
+ method: 'post',
+ data
+ })
+}
+export function updatePunch(data) {
+ return request({
+ url: '/hrm/punch',
+ method: 'put',
+ data
+ })
+}
+export function delPunch(punchIds) {
+ return request({
+ url: `/hrm/punch/${punchIds}`,
+ method: 'delete'
+ })
+}
+
+// 考勤结果
+export function listAttendCalc(query) {
+ return request({
+ url: '/hrm/attend/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 假期余额
+export function listLeaveBalance(query) {
+ return request({
+ url: '/hrm/leave/balance/list',
+ method: 'get',
+ params: query
+ })
+}
+export function addLeaveBalance(data) {
+ return request({
+ url: '/hrm/leave/balance',
+ method: 'post',
+ data
+ })
+}
+export function updateLeaveBalance(data) {
+ return request({
+ url: '/hrm/leave/balance',
+ method: 'put',
+ data
+ })
+}
+export function delLeaveBalance(balIds) {
+ return request({
+ url: `/hrm/leave/balance/${balIds}`,
+ method: 'delete'
+ })
+}
+
diff --git a/api/hrm/cc.js b/api/hrm/cc.js
new file mode 100644
index 0000000..a55c970
--- /dev/null
+++ b/api/hrm/cc.js
@@ -0,0 +1,35 @@
+import request from "@/util/oaRequest"
+
+// 查询抄送记录列表
+export function listCc(query) {
+ return request({
+ url: '/hrm/flow/cc/my',
+ method: 'get',
+ params: query
+ })
+}
+
+// 标记抄送为已读
+export function readCc(ccId) {
+ return request({
+ url: `/hrm/flow/cc/${ccId}/read`,
+ method: 'post'
+ })
+}
+
+// 手动抄送
+export function addCc(data) {
+ return request({
+ url: '/hrm/flow/cc',
+ method: 'post',
+ data: data
+ })
+}
+
+// 查询抄送记录详细
+export function getCc(ccId) {
+ return request({
+ url: `/hrm/flow/cc/${ccId}`,
+ method: 'get'
+ })
+}
diff --git a/api/hrm/certContract.js b/api/hrm/certContract.js
new file mode 100644
index 0000000..6da3a13
--- /dev/null
+++ b/api/hrm/certContract.js
@@ -0,0 +1,66 @@
+import request from "@/util/oaRequest"
+
+// 证书
+export function listCertificate(query) {
+ return request({
+ url: '/hrm/certificate/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function addCertificate(data) {
+ return request({
+ url: '/hrm/certificate',
+ method: 'post',
+ data
+ })
+}
+
+export function updateCertificate(data) {
+ return request({
+ url: '/hrm/certificate',
+ method: 'put',
+ data
+ })
+}
+
+export function delCertificate(certIds) {
+ return request({
+ url: `/hrm/certificate/${certIds}`,
+ method: 'delete'
+ })
+}
+
+// 合同
+export function listContract(query) {
+ return request({
+ url: '/hrm/contract/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function addContract(data) {
+ return request({
+ url: '/hrm/contract',
+ method: 'post',
+ data
+ })
+}
+
+export function updateContract(data) {
+ return request({
+ url: '/hrm/contract',
+ method: 'put',
+ data
+ })
+}
+
+export function delContract(contractIds) {
+ return request({
+ url: `/hrm/contract/${contractIds}`,
+ method: 'delete'
+ })
+}
+
diff --git a/api/hrm/empOrgPosition.js b/api/hrm/empOrgPosition.js
new file mode 100644
index 0000000..2b2fa93
--- /dev/null
+++ b/api/hrm/empOrgPosition.js
@@ -0,0 +1,33 @@
+import request from "@/util/oaRequest"
+// 员工组织岗位关系
+export function listEmpOrgPosition(query) {
+ return request({
+ url: '/hrm/empOrg/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function addEmpOrgPosition(data) {
+ return request({
+ url: '/hrm/empOrg',
+ method: 'post',
+ data
+ })
+}
+
+export function updateEmpOrgPosition(data) {
+ return request({
+ url: '/hrm/empOrg',
+ method: 'put',
+ data
+ })
+}
+
+export function delEmpOrgPosition(relIds) {
+ return request({
+ url: `/hrm/empOrg/${relIds}`,
+ method: 'delete'
+ })
+}
+
diff --git a/api/hrm/employee.js b/api/hrm/employee.js
new file mode 100644
index 0000000..7f9d19c
--- /dev/null
+++ b/api/hrm/employee.js
@@ -0,0 +1,56 @@
+import request from "@/util/oaRequest"
+
+// 员工
+export function listEmployee(query) {
+ return request({
+ url: '/hrm/employee/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function allEmployee(query) {
+ return request({
+ url: '/hrm/employee/all',
+ method: 'get',
+ params: query
+ })
+}
+
+export function addEmployee(data) {
+ return request({
+ url: '/hrm/employee',
+ method: 'post',
+ data
+ })
+}
+
+export function updateEmployee(data) {
+ return request({
+ url: '/hrm/employee',
+ method: 'put',
+ data
+ })
+}
+
+export function delEmployee(empIds) {
+ return request({
+ url: `/hrm/employee/${empIds}`,
+ method: 'delete'
+ })
+}
+
+export function getEmployee(empId) {
+ return request({
+ url: `/hrm/employee/${empId}`,
+ method: 'get'
+ })
+}
+
+// 根据用户ID获取员工信息
+export function getEmployeeByUserId(userId) {
+ return request({
+ url: `/hrm/employee/byUserId/${userId}`,
+ method: 'get'
+ })
+}
diff --git a/api/hrm/flow.js b/api/hrm/flow.js
new file mode 100644
index 0000000..7880b75
--- /dev/null
+++ b/api/hrm/flow.js
@@ -0,0 +1,220 @@
+import request from "@/util/oaRequest"
+
+// 流程任务
+export function listFlowTask(query) {
+ return request({
+ url: '/hrm/flow/task/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function updateFlowInstance(data) {
+ return request({
+ url: '/hrm/flow/instance',
+ method: 'put',
+ data
+ })
+}
+
+export function listTodoFlowTask(assigneeUserId) {
+ return request({
+ url: '/hrm/flow/task/todo',
+ method: 'get',
+ params: { assigneeUserId }
+ })
+}
+
+// 业务维度:按 bizType + bizId 查询当前待办任务(后端需提供)
+export function getTodoTaskByBiz(bizType, bizId, assigneeUserId) {
+ return request({
+ url: '/hrm/flow/task/todoByBiz',
+ method: 'get',
+ params: { bizType, bizId, assigneeUserId }
+ })
+}
+
+export function approveFlowTask(taskId, data) {
+ return request({
+ url: `/hrm/flow/task/${taskId}/approve`,
+ method: 'post',
+ data
+ })
+}
+
+export function rejectFlowTask(taskId, data) {
+ return request({
+ url: `/hrm/flow/task/${taskId}/reject`,
+ method: 'post',
+ data
+ })
+}
+
+export function withdrawFlowTask(taskId, data) {
+ return request({
+ url: `/hrm/flow/task/${taskId}/withdraw`,
+ method: 'post',
+ data
+ })
+}
+
+export function transferFlowTask(taskId, data) {
+ return request({
+ url: `/hrm/flow/task/${taskId}/transfer`,
+ method: 'post',
+ params: data
+ })
+}
+
+export function ccFlowTask(data) {
+ return request({
+ url: '/hrm/flow/cc',
+ method: 'post',
+ data
+ })
+}
+
+// 流程动作/表单
+export function listFlowAction(query) {
+ return request({
+ url: '/hrm/flow/action/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function listFlowFormData(query) {
+ return request({
+ // 后端 Controller: HrmFlowFormDataController
+ // @RequestMapping("/hrm/flow/form") + @GetMapping("/list")
+ url: '/hrm/flow/form/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 流程实例
+export function listFlowInstance(query) {
+ return request({
+ url: '/hrm/flow/instance/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 我的申请(我发起的流程实例)
+export function listMyFlowInstance(query) {
+ return request({
+ url: '/hrm/flow/instance/myList',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getFlowInstance(instId) {
+ return request({
+ url: `/hrm/flow/instance/${instId}`,
+ method: 'get'
+ })
+}
+
+export function queryInstanceByBiz(bizType, bizId) {
+ return request({
+ url: '/hrm/flow/instance/all',
+ method: 'get',
+ params: { bizType, bizId }
+ })
+}
+
+export function listFlowForm(query) {
+ return request({
+ url: '/hrm/flow/form/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getFlowForm(formId) {
+ return request({
+ url: `/hrm/flow/form/${formId}`,
+ method: 'get'
+ })
+}
+
+// 流程模板
+export function listFlowTemplate(query) {
+ return request({
+ url: '/hrm/flow/template/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getFlowTemplate(tplId) {
+ return request({
+ url: `/hrm/flow/template/${tplId}`,
+ method: 'get'
+ })
+}
+
+export function addFlowTemplate(data) {
+ return request({
+ url: '/hrm/flow/template',
+ method: 'post',
+ data
+ })
+}
+
+export function updateFlowTemplate(data) {
+ return request({
+ url: '/hrm/flow/template',
+ method: 'put',
+ data
+ })
+}
+
+export function delFlowTemplate(tplIds) {
+ return request({
+ url: `/hrm/flow/template/${tplIds}`,
+ method: 'delete'
+ })
+}
+
+// 流程节点
+export function listFlowNode(query) {
+ return request({
+ url: '/hrm/flow/node/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getFlowNode(nodeId) {
+ return request({
+ url: `/hrm/flow/node/${nodeId}`,
+ method: 'get'
+ })
+}
+
+export function addFlowNode(data) {
+ return request({
+ url: '/hrm/flow/node',
+ method: 'post',
+ data
+ })
+}
+
+export function updateFlowNode(data) {
+ return request({
+ url: '/hrm/flow/node',
+ method: 'put',
+ data
+ })
+}
+
+export function delFlowNode(nodeIds) {
+ return request({
+ url: `/hrm/flow/node/${nodeIds}`,
+ method: 'delete'
+ })
+}
diff --git a/api/hrm/gradePosition.js b/api/hrm/gradePosition.js
new file mode 100644
index 0000000..3aadd95
--- /dev/null
+++ b/api/hrm/gradePosition.js
@@ -0,0 +1,66 @@
+import request from "@/util/oaRequest"
+
+// 职级
+export function listGrade(query) {
+ return request({
+ url: '/hrm/grade/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function addGrade(data) {
+ return request({
+ url: '/hrm/grade',
+ method: 'post',
+ data
+ })
+}
+
+export function updateGrade(data) {
+ return request({
+ url: '/hrm/grade',
+ method: 'put',
+ data
+ })
+}
+
+export function delGrade(gradeIds) {
+ return request({
+ url: `/hrm/grade/${gradeIds}`,
+ method: 'delete'
+ })
+}
+
+// 岗位
+export function listPosition(query) {
+ return request({
+ url: '/hrm/position/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function addPosition(data) {
+ return request({
+ url: '/hrm/position',
+ method: 'post',
+ data
+ })
+}
+
+export function updatePosition(data) {
+ return request({
+ url: '/hrm/position',
+ method: 'put',
+ data
+ })
+}
+
+export function delPosition(positionIds) {
+ return request({
+ url: `/hrm/position/${positionIds}`,
+ method: 'delete'
+ })
+}
+
diff --git a/api/hrm/index.js b/api/hrm/index.js
new file mode 100644
index 0000000..f45bf75
--- /dev/null
+++ b/api/hrm/index.js
@@ -0,0 +1,12 @@
+// 导出所有 HRM 模块 API
+export * from './employee'
+export * from './org'
+export * from './certContract'
+export * from './empOrgPosition'
+export * from './gradePosition'
+export * from './attendance'
+export * from './leave'
+export * from './travel'
+export * from './seal'
+export * from './reimburse'
+export * from './flow'
diff --git a/api/hrm/leave.js b/api/hrm/leave.js
new file mode 100644
index 0000000..4826b53
--- /dev/null
+++ b/api/hrm/leave.js
@@ -0,0 +1,48 @@
+import request from "@/util/oaRequest"
+
+// 请假单
+export function listLeaveReq(query) {
+ return request({
+ url: '/hrm/leave/req/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getLeaveReq(bizId) {
+ return request({
+ url: `/hrm/leave/req/${bizId}`,
+ method: 'get'
+ })
+}
+
+export function addLeaveReq(data) {
+ return request({
+ url: '/hrm/leave/req',
+ method: 'post',
+ data
+ })
+}
+
+export function editLeaveReq(data) {
+ return request({
+ url: '/hrm/leave/req',
+ method: 'put',
+ data
+ })
+}
+
+export function delLeaveReq(bizIds) {
+ return request({
+ url: `/hrm/leave/req/${bizIds}`,
+ method: 'delete'
+ })
+}
+
+export function allLeaveReq(query) {
+ return request({
+ url: '/hrm/leave/req/all',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/api/hrm/org.js b/api/hrm/org.js
new file mode 100644
index 0000000..4d55ee6
--- /dev/null
+++ b/api/hrm/org.js
@@ -0,0 +1,49 @@
+import request from "@/util/oaRequest"
+
+// 组织
+export function listOrg(query) {
+ return request({
+ url: '/hrm/org/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function allOrg(query) {
+ return request({
+ url: '/hrm/org/all',
+ method: 'get',
+ params: query
+ })
+}
+
+export function addOrg(data) {
+ return request({
+ url: '/hrm/org',
+ method: 'post',
+ data
+ })
+}
+
+export function updateOrg(data) {
+ return request({
+ url: '/hrm/org',
+ method: 'put',
+ data
+ })
+}
+
+export function delOrg(orgIds) {
+ return request({
+ url: `/hrm/org/${orgIds}`,
+ method: 'delete'
+ })
+}
+
+export function getOrg(orgId) {
+ return request({
+ url: `/hrm/org/${orgId}`,
+ method: 'get'
+ })
+}
+
diff --git a/api/hrm/reimburse.js b/api/hrm/reimburse.js
new file mode 100644
index 0000000..ac26548
--- /dev/null
+++ b/api/hrm/reimburse.js
@@ -0,0 +1,49 @@
+import request from "@/util/oaRequest"
+
+// 日常报销单
+export function listReimburseReq(query) {
+ return request({
+ url: '/hrm/reimburse/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getReimburseReq(bizId) {
+ return request({
+ url: `/hrm/reimburse/${bizId}`,
+ method: 'get'
+ })
+}
+
+export function addReimburseReq(data) {
+ return request({
+ url: '/hrm/reimburse',
+ method: 'post',
+ data
+ })
+}
+
+export function editReimburseReq(data) {
+ return request({
+ url: '/hrm/reimburse',
+ method: 'put',
+ data
+ })
+}
+
+export function delReimburseReq(bizIds) {
+ return request({
+ url: `/hrm/reimburse/${bizIds}`,
+ method: 'delete'
+ })
+}
+
+export function allReimburseReq(query) {
+ return request({
+ url: '/hrm/reimburse/all',
+ method: 'get',
+ params: query
+ })
+}
+
diff --git a/api/hrm/seal.js b/api/hrm/seal.js
new file mode 100644
index 0000000..28a014a
--- /dev/null
+++ b/api/hrm/seal.js
@@ -0,0 +1,99 @@
+import request from "@/util/oaRequest"
+
+// 用印申请
+export function listSealReq(query) {
+ return request({
+ url: '/hrm/seal/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getSealReq(bizId) {
+ return request({
+ url: `/hrm/seal/${bizId}`,
+ method: 'get'
+ })
+}
+
+export function addSealReq(data) {
+ return request({
+ url: '/hrm/seal',
+ method: 'post',
+ data
+ })
+}
+
+export function editSealReq(data) {
+ return request({
+ url: '/hrm/seal',
+ method: 'put',
+ data
+ })
+}
+
+export function delSealReq(bizIds) {
+ return request({
+ url: `/hrm/seal/${bizIds}`,
+ method: 'delete'
+ })
+}
+
+export function approveSealReq(bizId) {
+ return request({
+ url: `/hrm/seal/${bizId}/approve`,
+ method: 'post'
+ })
+}
+
+export function rejectSealReq(bizId) {
+ return request({
+ url: `/hrm/seal/${bizId}/reject`,
+ method: 'post'
+ })
+}
+
+export function cancelSealReq(bizId) {
+ return request({
+ url: `/hrm/seal/${bizId}/cancel`,
+ method: 'post'
+ })
+}
+
+export function stampSealJava(bizId, data) {
+ // 确保数据正确序列化,特别是 0 值
+ const payload = {
+ targetFileUrl: String(data.targetFileUrl || ''),
+ stampImageUrl: String(data.stampImageUrl || ''),
+ pageNo: Number(data.pageNo) || 1,
+ xPx: Number(data.xPx) || 0,
+ yPx: Number(data.yPx) || 0,
+ viewportWidth: data.viewportWidth !== undefined && data.viewportWidth !== null ? Number(data.viewportWidth) : undefined,
+ viewportHeight: data.viewportHeight !== undefined && data.viewportHeight !== null ? Number(data.viewportHeight) : undefined
+ }
+ // 可选字段
+ if (data.widthPx !== undefined && data.widthPx !== null) {
+ payload.widthPx = Number(data.widthPx)
+ }
+ if (data.heightPx !== undefined && data.heightPx !== null) {
+ payload.heightPx = Number(data.heightPx)
+ }
+ // viewportWidth/Height:如果是 undefined 则不传(兼容后端校验)
+ if (payload.viewportWidth === undefined) delete payload.viewportWidth
+ if (payload.viewportHeight === undefined) delete payload.viewportHeight
+ console.log('stampSealJava API call, payload:', JSON.stringify(payload, null, 2))
+ console.log('yPx in API:', typeof payload.yPx, payload.yPx)
+ return request({
+ url: `/hrm/seal/${bizId}/stamp/java`,
+ method: 'post',
+ data: payload
+ })
+}
+
+export function stampSealPython(bizId, data) {
+ return request({
+ url: `/hrm/seal/${bizId}/stamp/python`,
+ method: 'post',
+ data
+ })
+}
diff --git a/api/hrm/travel.js b/api/hrm/travel.js
new file mode 100644
index 0000000..16007b4
--- /dev/null
+++ b/api/hrm/travel.js
@@ -0,0 +1,48 @@
+import request from "@/util/oaRequest"
+
+// 出差单
+export function listTravelReq(query) {
+ return request({
+ url: '/hrm/travel/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getTravelReq(bizId) {
+ return request({
+ url: `/hrm/travel/${bizId}`,
+ method: 'get'
+ })
+}
+
+export function addTravelReq(data) {
+ return request({
+ url: '/hrm/travel',
+ method: 'post',
+ data
+ })
+}
+
+export function editTravelReq(data) {
+ return request({
+ url: '/hrm/travel',
+ method: 'put',
+ data
+ })
+}
+
+export function delTravelReq(bizIds) {
+ return request({
+ url: `/hrm/travel/${bizIds}`,
+ method: 'delete'
+ })
+}
+
+export function allTravelReq(query) {
+ return request({
+ url: '/hrm/travel/all',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/components/hrm/detailPanels/leave.vue b/components/hrm/detailPanels/leave.vue
new file mode 100644
index 0000000..834e863
--- /dev/null
+++ b/components/hrm/detailPanels/leave.vue
@@ -0,0 +1,132 @@
+
+
+
+
+ 请假类型:
+ {{ detail.leaveType || '无' }}
+
+
+
+ 开始时间:
+ {{ formatTime(detail.startTime) || '无' }}
+
+
+
+ 结束时间:
+ {{ formatTime(detail.endTime) || '无' }}
+
+
+
+ 请假时长:
+ {{ detail.hours || '0' }} 小时
+
+
+
+ 请假原因:
+ {{ detail.reason || '无' }}
+
+
+
+ 申请人:
+ {{ detail.createBy || '无' }}
+
+
+
+ 申请时间:
+ {{ formatTime(detail.createTime) || '无' }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/hrm/detailPanels/reimburse.vue b/components/hrm/detailPanels/reimburse.vue
new file mode 100644
index 0000000..276705f
--- /dev/null
+++ b/components/hrm/detailPanels/reimburse.vue
@@ -0,0 +1,161 @@
+
+
+
+ 报销申请:
+ {{ detail.createBy || '无' }}
+
+
+
+ 报销类型:
+ {{ detail.reimburseType || '无' }}
+
+
+ 总金额:
+ {{ detail.totalAmount || '无' }}
+
+
+
+ 报销原因:
+ {{ detail.reason || '无' }}
+
+
+
+ 备注:
+ {{ detail.remark || '无' }}
+
+
+
+ 申请人:
+ {{ detail.createBy || '无' }}
+
+
+
+ 申请时间:
+ {{ formatTime(detail.createTime) || '无' }}
+
+
+
+ 更新人:
+ {{ detail.updateBy || '无' }}
+
+
+
+ 更新时间:
+ {{ formatTime(detail.updateTime) || '无' }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/hrm/detailPanels/seal.vue b/components/hrm/detailPanels/seal.vue
new file mode 100644
index 0000000..6d93154
--- /dev/null
+++ b/components/hrm/detailPanels/seal.vue
@@ -0,0 +1,113 @@
+
+
+
+ 报销申请
+ {{ detail.createBy }}
+
+
+
+ 用印类型
+ {{ detail.sealType || '无' }}
+
+
+
+ 原因
+ {{ detail.purpose || '无' }}
+
+
+
+ 备注
+ {{ detail.remark || '无' }}
+
+
+
+ 创建人
+ {{ detail.createBy || '无' }}
+
+
+
+ 创建时间
+ {{ detail.createTime || '无' }}
+
+
+
+ 更新人
+ {{ detail.updateBy || '无' }}
+
+
+
+ 更新时间
+ {{ detail.updateTime || '无' }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/hrm/detailPanels/travel.vue b/components/hrm/detailPanels/travel.vue
new file mode 100644
index 0000000..c2ba1af
--- /dev/null
+++ b/components/hrm/detailPanels/travel.vue
@@ -0,0 +1,148 @@
+
+
+
+
+
+ 开始时间
+ {{ detail.startTime || '无' }}
+
+
+
+ 结束时间
+ {{ detail.endTime || '无' }}
+
+
+
+ 出差类型
+ {{ detail.travelType || '无' }}
+
+
+
+ 出差目的地
+ {{ detail.destination || '无' }}
+
+
+
+ 出差原因
+ {{ detail.reason || '无' }}
+
+
+
+ 收款人姓名
+ {{ detail.payeeName || '无' }}
+
+
+
+ 预估费用
+ {{ detail.estimatedCost || 0 }} 元
+
+
+
+ 开户银行
+ {{ detail.bankName || '无' }}
+
+
+
+ 银行账号
+ {{ detail.bankAccount || '无' }}
+
+
+
+ 备注
+ {{ detail.remark || '无' }}
+
+
+
+ 创建人
+ {{ detail.createBy || '无' }}
+
+
+
+ 创建时间
+ {{ detail.createTime || '无' }}
+
+
+
+ 更新人
+ {{ detail.updateBy || '无' }}
+
+
+
+ 更新时间
+ {{ detail.updateTime || '无' }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages.json b/pages.json
index ce9f362..9a44fa4 100644
--- a/pages.json
+++ b/pages.json
@@ -557,6 +557,34 @@
"navigationBarTitleText" : "采购需求",
"navigationStyle": "default"
}
+ },
+ {
+ "path": "pages/workbench/hrm/approve/approve",
+ "style": {
+ "navigationBarTitleText": "办公审批",
+ "navigationStyle": "default"
+ }
+ },
+ {
+ "path": "pages/workbench/hrm/cc/cc",
+ "style": {
+ "navigationBarTitleText": "抄送我的",
+ "navigationStyle": "default"
+ }
+ },
+ {
+ "path": "pages/workbench/hrm/detail/detail",
+ "style": {
+ "navigationBarTitleText": "申请详情",
+ "navigationStyle": "default"
+ }
+ },
+ {
+ "path": "pages/workbench/hrm/apply/apply",
+ "style": {
+ "navigationBarTitleText": "我的申请",
+ "navigationStyle": "default"
+ }
}
],
"tabBar": {
diff --git a/pages/workbench/hrm/apply/apply.vue b/pages/workbench/hrm/apply/apply.vue
new file mode 100644
index 0000000..f175399
--- /dev/null
+++ b/pages/workbench/hrm/apply/apply.vue
@@ -0,0 +1,627 @@
+
+
+
+
+
+ 申请类型:
+
+ {{ bizTypeList[bizTypeIndex].label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 暂无待审批任务
+
+
+
+
+
+
+ {{ getBizTypeText(item.bizType) }}
+
+
+
+
+
+
+ {{ item.bizTitle || '暂未标识' }}
+
+
+
+ {{ formatDate(item.createTime) }}
+
+
+
+
+ {{ statusText(item.status) }}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/workbench/hrm/approve/approve.vue b/pages/workbench/hrm/approve/approve.vue
new file mode 100644
index 0000000..3ecd07b
--- /dev/null
+++ b/pages/workbench/hrm/approve/approve.vue
@@ -0,0 +1,604 @@
+
+
+
+
+
+ 审批中心
+ 集中查看与处理待办审批
+
+
+
+ {{ todoCount }}
+ 待审批
+
+
+
+
+
+
+
+ 申请类型:
+
+ {{ bizTypeList[bizTypeIndex].label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 暂无待审批任务
+
+
+
+
+
+
+ {{ getBizTypeText(item.bizType) }}
+
+
+
+
+
+
+ {{ formatApplicant(item) }}
+
+ {{ formatRequestInfo(item) }}
+
+ {{ formatDate(item.createTime) }}
+
+
+
+
+ {{ statusText(item.status) }}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/workbench/hrm/cc/cc.vue b/pages/workbench/hrm/cc/cc.vue
new file mode 100644
index 0000000..6540cd2
--- /dev/null
+++ b/pages/workbench/hrm/cc/cc.vue
@@ -0,0 +1,587 @@
+
+
+
+
+
+ 申请类型:
+
+ {{ bizTypeList[bizTypeIndex].label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 暂无待审批任务
+
+
+
+
+
+
+ {{ getBizTypeText(item.bizType) }}
+
+
+
+
+
+
+ {{ item.bizTitle }}
+
+ {{ item.createBy }}
+
+ {{ formatDate(item.createTime) }}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/workbench/hrm/detail/detail.vue b/pages/workbench/hrm/detail/detail.vue
new file mode 100644
index 0000000..3c43b17
--- /dev/null
+++ b/pages/workbench/hrm/detail/detail.vue
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/workbench/hrm/leave/leave.vue b/pages/workbench/hrm/leave/leave.vue
new file mode 100644
index 0000000..1f29314
--- /dev/null
+++ b/pages/workbench/hrm/leave/leave.vue
@@ -0,0 +1,946 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ detail.leaveType || '请假申请' }}
+
+ 申请编号:{{ detail.bizId || '-' }} ·
+ 状态:{{ statusText }}
+
+
+
+
+ 申请人
+ {{ detail.createBy || '-' }}({{ detail.empNo }})
+
+
+ 请假时长
+ {{ detail.hours || '0' }} 小时
+
+
+
+
+
+ 请假日期
+
+
+
+ 开始时间
+ {{ formatDate(detail.startTime) }}
+
+
+ 结束时间
+ {{ formatDate(detail.endTime) }}
+
+
+ 请假类型
+ {{ detail.leaveType || '-' }}
+
+
+ 时长(小时)
+ {{ detail.hours || '0' }} 小时
+
+
+ 创建时间
+ {{ formatDate(detail.createTime) }}
+
+
+ 更新时间
+ {{ formatDate(detail.updateTime) }}
+
+
+
+
+
+ 请假理由说明
+
+
+ 事由
+ {{ detail.reason || '未填写' }}
+
+
+ 工作交接
+ {{ detail.handover }}
+
+
+ 备注
+ {{ detail.remark }}
+
+
+
+
+ 申请附件
+
+
+
+
+
+
+
+
+
+
+
+ {{ file.originalName || file.fileName || `文件${file.ossId}` }}
+
+ {{ formatFileSize(file.fileSize) }}
+ {{ formatDate(file.createTime) }}
+
+
+
+
+
+
+
+
+
+ 暂无附件
+
+
+
+
+ 审批意见
+
+
+
+
+
+
+
+
+
+
+
+
+ 流转历史
+
+
+
+
+
+
+ {{ formatDate(item.createTime) }}
+
+ {{ getActionText(item.action) }}
+ 处理人: {{ item.createBy || '系统' }}
+
+
+
+
+
+ 暂无流转记录
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/workbench/hrm/reimburse/reimburse.vue b/pages/workbench/hrm/reimburse/reimburse.vue
new file mode 100644
index 0000000..87b6899
--- /dev/null
+++ b/pages/workbench/hrm/reimburse/reimburse.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/workbench/hrm/seal/seal.vue b/pages/workbench/hrm/seal/seal.vue
new file mode 100644
index 0000000..87b6899
--- /dev/null
+++ b/pages/workbench/hrm/seal/seal.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/workbench/hrm/travel/travel.vue b/pages/workbench/hrm/travel/travel.vue
new file mode 100644
index 0000000..87b6899
--- /dev/null
+++ b/pages/workbench/hrm/travel/travel.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/workbench/index/index.vue b/pages/workbench/index/index.vue
index 9fb0bbf..b9007cb 100644
--- a/pages/workbench/index/index.vue
+++ b/pages/workbench/index/index.vue
@@ -121,6 +121,24 @@ export default {
url: '/pages/workbench/notice/notice',
category: '信息中心'
},
+ {
+ text: '我的代办',
+ icon: '/static/images/todo.png',
+ url: '/pages/workbench/hrm/approve/approve',
+ category: '办公管理'
+ },
+ {
+ text: '抄送我的',
+ icon: '/static/images/cc.png',
+ url: '/pages/workbench/hrm/cc/cc',
+ category: '办公管理'
+ },
+ {
+ text: '我的申请',
+ icon: '/static/images/hrm_apply.png',
+ url: '/pages/workbench/hrm/apply/apply',
+ category: '办公管理'
+ },
{
text: '库存盘点',
icon: '/static/images/stock.png',
@@ -171,12 +189,7 @@ export default {
url: '/pages/workbench/wms/out',
category: '库房管理',
},
- // {
- // text: '我的申请',
- // icon: '/static/images/apply.png',
- // url: '/pages/workbench/workflow/apply/apply',
- // category: '办公流程'
- // },
+
// {
// text: '代办任务',
// icon: '/static/images/todo.png',
@@ -234,9 +247,11 @@ export default {
uni.showLoading()
console.log('开始调用getUserProfile API');
const response = await getUserProfile();
+ //
console.log('用户个人信息:', response);
// 从接口返回数据中提取用户权限(roleKey)
const roles = response.data.user?.roles?.map(item => item.roleKey) || [];
+ this.$store.commit('oa/SET_STATE', response.data.user)
console.log('用户权限字段', roles);
this.roleGroup = roles;
uni.hideLoading()
diff --git a/static/images/cc.png b/static/images/cc.png
new file mode 100644
index 0000000..d55b90a
Binary files /dev/null and b/static/images/cc.png differ
diff --git a/static/images/hrm_apply.png b/static/images/hrm_apply.png
new file mode 100644
index 0000000..b4fc452
Binary files /dev/null and b/static/images/hrm_apply.png differ
diff --git a/store/getters.js b/store/getters.js
index df90596..458675c 100644
--- a/store/getters.js
+++ b/store/getters.js
@@ -19,4 +19,6 @@ export default {
storeReinstall: (state) => state.user.reinstall,
storeProgress: (state) => state.user.progress,
storeAuthData: (state) => state.user.authData,
+ storeOaId: (state) => state.oa.id,
+ storeOaName: (state) => state.oa.userName,
};
diff --git a/store/index.js b/store/index.js
index c967061..cb79da2 100644
--- a/store/index.js
+++ b/store/index.js
@@ -6,6 +6,7 @@ import conversation from "./modules/conversation";
import message from "./modules/message";
import cache from './modules/cache.js'
import getters from "./getters";
+import oa from './modules/oa.js'
Vue.use(Vuex);
@@ -15,7 +16,8 @@ const store = new Vuex.Store({
contact,
conversation,
message,
- cache
+ cache,
+ oa
},
getters,
});
diff --git a/store/modules/oa.js b/store/modules/oa.js
new file mode 100644
index 0000000..d4b1659
--- /dev/null
+++ b/store/modules/oa.js
@@ -0,0 +1,24 @@
+const state = {
+ id: undefined,
+ nickName: undefined,
+ userName: undefined,
+ roles: [],
+ dept: undefined,
+}
+
+const mutations = {
+ SET_STATE(state, value) {
+ state.id = value.userId;
+ state.nickName = value.nickName;
+ state.userName = value.userName;
+ state.dept = value.dept.deptName;
+ },
+}
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+};
+
+