From cd71a3a457bbd841c68ae50a825a06a34f6cc6d0 Mon Sep 17 00:00:00 2001 From: 86156 <823267011@qq.com> Date: Mon, 20 Apr 2026 15:56:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E5=8A=9E=E5=85=AC=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AE=A1=E6=89=B9=EF=BC=8C=E7=BC=BA=E5=B0=91?= =?UTF-8?q?=E7=94=B5=E5=AD=90=E7=AD=BE=E7=AB=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/hrm/flow.js | 8 + api/hrm/travel.js | 7 + components/hrm/CityPicker.vue | 187 ++++-- components/hrm/DateTimePicker.vue | 30 +- components/hrm/GlobalCityPicker.vue | 242 ++++---- components/hrm/RequestForm.vue | 556 ++++++++++++++---- components/hrm/detailPanels/appropriation.vue | 211 ++++--- components/hrm/detailPanels/leave.vue | 22 +- components/hrm/detailPanels/reimburse.vue | 10 +- manifest.json | 10 +- pages/hrm/approve/approve.vue | 173 +++++- pages/workbench/hrm/apply/apply.vue | 160 ++++- pages/workbench/hrm/approve/approve.vue | 4 - pages/workbench/hrm/detail/detail.vue | 223 ++++--- pages/workbench/hrm/leave/leave.vue | 2 +- pages/workbench/hrm/reimburse/reimburse.vue | 158 ++++- pages/workbench/hrm/seal/seal.vue | 4 +- pages/workbench/hrm/travel/travel.vue | 321 ++++++++-- 18 files changed, 1791 insertions(+), 537 deletions(-) diff --git a/api/hrm/flow.js b/api/hrm/flow.js index 2416c9e..f6740b9 100644 --- a/api/hrm/flow.js +++ b/api/hrm/flow.js @@ -42,6 +42,14 @@ export function getTodoTaskByBiz(bizType, bizId, assigneeUserId) { }) } +export function getFlowTaskDetailByBiz(bizType, bizId) { + return request({ + url: '/hrm/flow/task/detailByBiz', + method: 'get', + params: { bizType, bizId } + }) +} + export function approveFlowTask(taskId, data) { return request({ url: `/hrm/flow/task/${taskId}/approve`, diff --git a/api/hrm/travel.js b/api/hrm/travel.js index 16007b4..b49aa96 100644 --- a/api/hrm/travel.js +++ b/api/hrm/travel.js @@ -32,6 +32,13 @@ export function editTravelReq(data) { }) } +export function earlyEndTravelReq(bizId) { + return request({ + url: `/hrm/travel/earlyEnd/${bizId}`, + method: 'put' + }) +} + export function delTravelReq(bizIds) { return request({ url: `/hrm/travel/${bizIds}`, diff --git a/components/hrm/CityPicker.vue b/components/hrm/CityPicker.vue index 6f98548..f635b22 100644 --- a/components/hrm/CityPicker.vue +++ b/components/hrm/CityPicker.vue @@ -2,56 +2,175 @@ - 选择目的地 + 选择城市 关闭 - {{ pathLabel || '请选择目的地' }} - - - {{ item.name }} - - - {{ item.name }} - - - {{ item }} - - - + + + 仅精确到城市即可 + 如果列表里没有需要的城市,可以先补录到上方,再直接选择。 + + + + + + + + + {{ currentCountry && currentCity ? (currentCountry + ' / ' + currentCity) : '请选择城市' }} + + + + + + {{ item.name }} + + + + + {{ item.cityName }} + + + + + + - + \ No newline at end of file +.mask{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:1000;display:flex;align-items:flex-end}.sheet{width:100%;background:#fff;border-radius:24rpx 24rpx 0 0;padding:20rpx;box-sizing:border-box}.sheet-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16rpx}.sheet-title{font-size:30rpx;font-weight:800}.sheet-close{font-size:26rpx;color:#1677ff}.tip-box{padding:12rpx 16rpx;border-radius:16rpx;background:#eff6ff;margin-bottom:12rpx}.tip-main{display:block;font-size:26rpx;font-weight:700;color:#1d4ed8}.tip-sub{display:block;margin-top:6rpx;font-size:22rpx;color:#1e40af;line-height:1.5}.add-box{display:flex;gap:10rpx;flex-wrap:wrap;margin-bottom:12rpx}.add-input{flex:1;min-width:240rpx;height:72rpx;padding:0 16rpx;border:1px solid #e5e7eb;border-radius:16rpx;background:#fff}.add-btn{width:100%;height:72rpx;line-height:72rpx;border-radius:16rpx;background:#10b981;color:#fff;font-size:26rpx}.city-path{padding:12rpx 16rpx;margin-bottom:12rpx;border-radius:16rpx;background:#f8fafc;color:#334155;font-size:24rpx;line-height:1.5}.selector-wrap{height:420rpx;border:1px solid #eef2f7;border-radius:16rpx;overflow:hidden}.picker-view{height:100%}.picker-item{height:84rpx;line-height:84rpx;text-align:center;font-size:28rpx;color:#111827}.actions{display:flex;gap:12rpx;margin-top:16rpx}.btn{flex:1;border-radius:16rpx}.btn.ghost{background:#f3f4f6;color:#334155}.btn.primary{background:#1677ff;color:#fff}.btn.primary[disabled]{background:#9cc2ff;color:#fff} + diff --git a/components/hrm/DateTimePicker.vue b/components/hrm/DateTimePicker.vue index 59bff2a..d7e77b6 100644 --- a/components/hrm/DateTimePicker.vue +++ b/components/hrm/DateTimePicker.vue @@ -5,7 +5,7 @@ 选择时间 关闭 - + {{ d }} @@ -30,31 +30,41 @@ export default { dateOptions() { const res = []; const base = new Date(); base.setHours(0,0,0,0); for (let i = 0; i < this.days; i++) { const d = new Date(base); d.setDate(d.getDate() + i); res.push(this.formatYMD(d)) } return res }, hourOptions() { return Array.from({ length: 24 }, (_, i) => `${i < 10 ? '0' : ''}${i}时`) } }, - watch: { - visible(v) { if (v) setTimeout(() => this.initValue(), 100) } + watch: { + visible(v) { + if (v) { + this.$nextTick(() => { + setTimeout(() => this.initValue(), 50) + }) + } + } }, methods: { initValue() { if (this.value) { const v = String(this.value).replace('T', ' ') const parts = v.split(' ') - const ymd = parts[0].split('-') - const hm = parts[1]?.split(':') || [0, 0] - const hour = parseInt(hm[0]) || 0 - const dateIndex = this.dateOptions.indexOf(ymd.join('-')) + const ymd = (parts[0] || '').split('-') + const hm = (parts[1] || '00:00:00').split(':') + const hour = Math.max(0, Math.min(23, parseInt(hm[0], 10) || 0)) + const dateKey = ymd.length === 3 ? ymd.join('-') : this.dateOptions[0] + const dateIndex = this.dateOptions.indexOf(dateKey) this.pickerValue = [dateIndex >= 0 ? dateIndex : 0, hour] } else { this.pickerValue = [0, 0] } this.$nextTick(() => { const pv = this.$refs.picker - if (pv) pv.setValue(this.pickerValue) + if (pv && pv.setValue) pv.setValue(this.pickerValue) }) }, - onChange(e) { this.pickerValue = e.detail.value }, + onChange(e) { + const val = e.detail.value || [0, 0] + this.pickerValue = [Number(val[0]) || 0, Number(val[1]) || 0] + }, confirm() { const date = this.dateOptions[this.pickerValue[0]] || this.dateOptions[0] - let hour = this.pickerValue[1] || 0 + let hour = Number(this.pickerValue[1]) || 0 if (hour >= 24) hour = 23 this.$emit('change', `${date}T${hour < 10 ? '0' : ''}${hour}:00:00.000+08:00`) this.close() diff --git a/components/hrm/GlobalCityPicker.vue b/components/hrm/GlobalCityPicker.vue index 6964899..e54659c 100644 --- a/components/hrm/GlobalCityPicker.vue +++ b/components/hrm/GlobalCityPicker.vue @@ -2,151 +2,171 @@ - 选择目的地 + 选择城市 关闭 - {{ currentPath }} + + 仅精确到城市即可 + 如果列表里没有想要的城市,可以先在上方补录后再选择。 + - - - - {{ item.name }} - - - - - {{ item.name }} - - - - - {{ item.name }} - - - + + + + + + + {{ currentCountry && currentCity ? (currentCountry + ' / ' + currentCity) : '请选择城市' }} + + + + + {{ item.name }} + + + {{ item.cityName }} + + + - + \ No newline at end of file +.picker-mask{position:fixed;inset:0;background:rgba(15,23,42,.45);z-index:1000;display:flex;align-items:flex-end}.picker-sheet{width:100%;background:#fff;border-radius:24rpx 24rpx 0 0;padding:20rpx;box-sizing:border-box}.picker-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16rpx}.picker-title{font-size:30rpx;font-weight:800;color:#111827}.picker-close{font-size:26rpx;color:#1677ff}.tip-box{padding:12rpx 16rpx;border-radius:16rpx;background:#eff6ff;margin-bottom:12rpx}.tip-main{display:block;font-size:26rpx;font-weight:700;color:#1d4ed8}.tip-sub{display:block;margin-top:6rpx;font-size:22rpx;color:#1e40af;line-height:1.5}.add-box{display:flex;gap:10rpx;flex-wrap:wrap;margin-bottom:12rpx}.add-input{flex:1;min-width:240rpx;height:72rpx;padding:0 16rpx;border:1px solid #e5e7eb;border-radius:16rpx;background:#fff}.add-btn{width:100%;height:72rpx;line-height:72rpx;border-radius:16rpx;background:#10b981;color:#fff;font-size:26rpx}.city-path{padding:12rpx 16rpx;margin-bottom:12rpx;border-radius:16rpx;background:#f8fafc;color:#334155;font-size:24rpx;line-height:1.5}.selector-wrap{height:420rpx;border:1px solid #eef2f7;border-radius:16rpx;overflow:hidden}.picker-view{height:100%}.picker-item{height:84rpx;line-height:84rpx;text-align:center;font-size:28rpx;color:#111827}.picker-footer{display:flex;gap:12rpx;margin-top:16rpx}.btn{flex:1;border-radius:16rpx}.btn.ghost{background:#f3f4f6;color:#334155}.btn.primary{background:linear-gradient(135deg,#1677ff,#4f9dff);color:#fff}.btn.primary[disabled]{background:#9cc2ff;color:#fff} + diff --git a/components/hrm/RequestForm.vue b/components/hrm/RequestForm.vue index 675f616..3ebf73f 100644 --- a/components/hrm/RequestForm.vue +++ b/components/hrm/RequestForm.vue @@ -1,40 +1,167 @@