Merge remote-tracking branch 'origin/feature_工会报销UI优化' into release_20260831

This commit is contained in:
2026-08-31 11:14:13 +08:00
7 changed files with 1075 additions and 530 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

@@ -4,12 +4,12 @@ layout("/layouts/platform_h5.html"){
<style>
body {
background: #f5f6fa;
background: #f3f7fd;
}
#app {
min-height: 100vh;
background: #f5f6fa;
background: #f3f7fd;
}
.custom-nav {
@@ -394,17 +394,22 @@ layout("/layouts/platform_h5.html"){
}
</style>
<div id="app" v-cloak>
<van-nav-bar title="报销申请" left-text="返回" left-arrow @click-left="historyBack" placeholder fixed z-index="999"
<style id="style-union-reimburse-h5">
<!--#include('../common/unionReimburse.css'){}#-->
</style>
<div id="app" v-cloak class="union-reimburse-page union-reimburse-form">
<van-nav-bar title="报销申请" left-text="返回" left-arrow @click-left="onNavBack" placeholder fixed z-index="999"
class="custom-nav"></van-nav-bar>
<div class="form-container">
<van-form ref="formRef">
<van-cell-group title="信息填报" class="form-section">
<section class="form-section">
<h2 class="form-section__title">基本信息</h2>
<van-cell-group :border="false">
<van-field label="工号" v-model="formData.loginName" placeholder="从信息中心获取" readonly></van-field>
<van-field label="经办人" v-model="formData.userName" placeholder="从信息中心获取" readonly></van-field>
<!-- 联系方式 -->
<van-field label="联系方式" v-model="formData.mobile" required placeholder="请输入联系方式"
<!-- 经办人联系方式,使用当前登录用户的 mobile 初始化。 -->
<van-field label="联系方式" name="mobile" v-model="formData.mobile" required placeholder="请输入联系方式"
:rules="[
{ required: true, message: '请输入联系方式' },
{ pattern: /^(1[3-9]\d{9}|0\d{2,3}-?\d{7,8})$/, message: '请输入正确的联系方式' }
@@ -422,7 +427,7 @@ layout("/layouts/platform_h5.html"){
required
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showReimburseFundSourcePicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showReimburseFundSourcePicker">
<van-picker :columns="reimburseFundSourceColumns" @cancel="closePopup('showReimburseFundSourcePicker')"
@confirm="onReimburseFundSourceConfirm" show-toolbar></van-picker>
</van-popup>
@@ -444,7 +449,7 @@ layout("/layouts/platform_h5.html"){
<span style="color: #ee0a24; text-align: left;">报销提示:{{getProjectTipByProject(formData.reimburseProject)}}</span>
</template>
</van-cell>
<van-popup position="bottom" round v-model:show="showReimburseProjectPicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showReimburseProjectPicker">
<van-picker :columns="reimburseProjectColumns" @cancel="closePopup('showReimburseProjectPicker')"
@confirm="onReimburseProjectConfirm" show-toolbar></van-picker>
</van-popup>
@@ -461,7 +466,7 @@ layout("/layouts/platform_h5.html"){
required
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showClubPicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showClubPicker">
<van-picker :columns="clubColumns" @cancel="closePopup('showClubPicker')"
@confirm="onClubConfirm" show-toolbar></van-picker>
</van-popup>
@@ -532,8 +537,11 @@ layout("/layouts/platform_h5.html"){
</van-action-sheet>
-->
</van-cell-group>
<van-cell-group :title="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1' ? '慰问信息' : '活动信息'" class="form-section">
</van-cell-group>
</section>
<section class="form-section">
<h2 class="form-section__title">{{!formData.reimburseProject ? '报销信息' : (formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1' ? '慰问信息' : '活动信息')}}</h2>
<van-cell-group :border="false">
<template v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<van-field
@@ -548,7 +556,7 @@ layout("/layouts/platform_h5.html"){
required
is-link
></van-field>
<van-action-sheet v-model="showCondolenceSearch" title="慰问对象" class="height100">
<van-action-sheet v-model="showCondolenceSearch" :close-on-click-overlay="true" title="慰问对象" class="height100">
<van-search
v-model="condolenceSearchKeyword"
:show-action="false"
@@ -587,7 +595,7 @@ layout("/layouts/platform_h5.html"){
required
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showCondolenceTypePicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showCondolenceTypePicker">
<van-picker :columns="condolenceTypeColumns" @cancel="closePopup('showCondolenceTypePicker')"
@confirm="onCondolenceTypeConfirm" show-toolbar></van-picker>
</van-popup>
@@ -604,7 +612,7 @@ layout("/layouts/platform_h5.html"){
required
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showCondolenceWayPicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showCondolenceWayPicker">
<van-picker :columns="condolenceWayColumns" @cancel="closePopup('showCondolenceWayPicker')"
@confirm="onCondolenceWayConfirm" show-toolbar></van-picker>
</van-popup>
@@ -627,7 +635,7 @@ layout("/layouts/platform_h5.html"){
required
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showCondolenceTimePicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showCondolenceTimePicker">
<van-datetime-picker type="date" title="选择慰问时间" :min-date="minDate" :max-date="maxDate"
@cancel="closePopup('showCondolenceTimePicker')"
@confirm="onCondolenceTimeConfirm"></van-datetime-picker>
@@ -644,7 +652,7 @@ layout("/layouts/platform_h5.html"){
clickable
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showMarryTimePicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showMarryTimePicker">
<van-datetime-picker type="date" title="选择结婚时间" :min-date="minDate" :max-date="maxDate"
@cancel="closePopup('showMarryTimePicker')"
@confirm="onDateConfirm('marryTime', 'showMarryTimePicker', $event)"></van-datetime-picker>
@@ -661,7 +669,7 @@ layout("/layouts/platform_h5.html"){
clickable
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showFertilityTimePicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showFertilityTimePicker">
<van-datetime-picker type="date" title="选择生育时间" :min-date="minDate" :max-date="maxDate"
@cancel="closePopup('showFertilityTimePicker')"
@confirm="onDateConfirm('fertilityTime', 'showFertilityTimePicker', $event)"></van-datetime-picker>
@@ -681,7 +689,7 @@ layout("/layouts/platform_h5.html"){
clickable
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showHospitalizationStartTimePicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showHospitalizationStartTimePicker">
<van-datetime-picker type="date" title="选择住院开始时间" :min-date="minDate" :max-date="maxDate"
@cancel="closePopup('showHospitalizationStartTimePicker')"
@confirm="onDateConfirm('hospitalizationStartTime', 'showHospitalizationStartTimePicker', $event)"></van-datetime-picker>
@@ -696,7 +704,7 @@ layout("/layouts/platform_h5.html"){
clickable
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showHospitalizationEndTimePicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showHospitalizationEndTimePicker">
<van-datetime-picker type="date" title="选择住院结束时间" :min-date="minDate" :max-date="maxDate"
@cancel="closePopup('showHospitalizationEndTimePicker')"
@confirm="onDateConfirm('hospitalizationEndTime', 'showHospitalizationEndTimePicker', $event)"></van-datetime-picker>
@@ -716,7 +724,7 @@ layout("/layouts/platform_h5.html"){
clickable
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showDeathTimePicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showDeathTimePicker">
<van-datetime-picker type="date" title="选择去世时间" :min-date="minDate" :max-date="maxDate"
@cancel="closePopup('showDeathTimePicker')"
@confirm="onDateConfirm('deathTime', 'showDeathTimePicker', $event)"></van-datetime-picker>
@@ -731,13 +739,13 @@ layout("/layouts/platform_h5.html"){
clickable
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showRelationshipPicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showRelationshipPicker">
<van-picker :columns="relationshipColumns" @cancel="closePopup('showRelationshipPicker')"
@confirm="onRelationshipConfirm" show-toolbar></van-picker>
</van-popup>
</template>
<van-field label="参加随行人员"
<van-field class="more-text" label="参加随行人员"
v-model="formData.participants"
placeholder="请填写参加随行人员"
type="textarea"
@@ -745,13 +753,13 @@ layout("/layouts/platform_h5.html"){
autosize
:rules="[{ required: true, message: '请填写参加随行人员' }]"
required></van-field>
<van-field label="报销事由"
<van-field class="more-text" label="报销事由"
v-model="formData.paymentNotes"
placeholder="请填写报销事由"
type="textarea"
rows="2"
autosize></van-field>
<van-field label="备注"
<van-field class="more-text" label="备注"
v-model="formData.notes"
placeholder="需要填写:发票编号、开具方、金额"
type="textarea"
@@ -790,7 +798,7 @@ layout("/layouts/platform_h5.html"){
required
is-link
></van-field>
<van-popup position="bottom" round v-model:show="showActivityTimePicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showActivityTimePicker">
<van-datetime-picker type="date" title="选择活动时间" :min-date="minDate" :max-date="maxDate"
@cancel="closePopup('showActivityTimePicker')"
@confirm="onActivityTimeConfirm"></van-datetime-picker>
@@ -811,7 +819,8 @@ layout("/layouts/platform_h5.html"){
></h5-file-upload>
</template>
</van-field>
</van-cell-group>
</van-cell-group>
</section>
<van-cell-group class="form-section">
<div class="payment-section">
<div class="payment-toolbar">
@@ -900,11 +909,11 @@ layout("/layouts/platform_h5.html"){
<span class="payment-dot" :class="{active: index === currentPaymentIndex}" v-for="(item, index) in paymentInfoRows"></span>
</div>
</div>
<van-popup position="bottom" round v-model:show="showPaymentWayPicker">
<van-popup position="bottom" round :close-on-click-overlay="true" v-model:show="showPaymentWayPicker">
<van-picker :columns="paymentWayColumns" @cancel="closePopup('showPaymentWayPicker')"
@confirm="onPaymentWayConfirm" show-toolbar></van-picker>
</van-popup>
<van-action-sheet v-model="payerSelectShow" title="付款人" class="height100">
<van-action-sheet v-model="payerSelectShow" :close-on-click-overlay="true" title="付款人" class="height100">
<van-search
v-model="payerSearchKeyword"
:show-action="false"
@@ -926,7 +935,8 @@ layout("/layouts/platform_h5.html"){
<van-empty description="暂无数据" v-else></van-empty>
</van-action-sheet>
</van-cell-group>
<van-cell-group title="电子发票" class="form-section" v-if="formData.reimburseProject">
<van-cell-group class="form-section" v-if="formData.reimburseProject">
<div class="form-section__title">电子发票</div>
<van-field label="报销金额"
v-model="formData.money"
placeholder="自动汇总发票金额"
@@ -936,7 +946,7 @@ layout("/layouts/platform_h5.html"){
placeholder="自动统计发票数量"
readonly></van-field>
<!-- 支付内容 -->
<van-field label="支付内容"
<van-field class="more-text" label="支付内容"
v-model="formData.paymentNotes"
placeholder="请填写支付内容"
type="textarea"
@@ -952,6 +962,8 @@ layout("/layouts/platform_h5.html"){
<template #right-icon>
<van-switch v-model="formData.invoiceVerifyEnabled"
size="22px"
active-color="#1989fa"
inactive-color="#d8e0ea"
@change="handleVerifySwitchChange"></van-switch>
</template>
</van-cell>
@@ -966,9 +978,9 @@ layout("/layouts/platform_h5.html"){
<div class="invoice-detail-line">项目名称:{{item.itemName || '未填写'}}</div>
<div class="invoice-detail-line" v-if="getInvoiceFile(item)">文件:{{getInvoiceFile(item).name || getInvoiceFile(item).filename || '已上传'}}</div>
<div class="invoice-detail-actions">
<van-button native-type="button" size="mini" plain type="info" @click="previewInvoiceFile(item)">预览</van-button>
<van-button native-type="button" size="mini" plain type="primary" @click="openInvoiceDialog('edit', item, index)">编辑</van-button>
<van-button native-type="button" size="mini" plain type="danger" @click="removeInvoiceDetail(index)">删除</van-button>
<van-button native-type="button" size="mini" plain type="info" icon="eye-o" @click="previewInvoiceFile(item)">预览</van-button>
<van-button native-type="button" size="mini" plain type="primary" icon="edit" @click="openInvoiceDialog('edit', item, index)">编辑</van-button>
<van-button native-type="button" size="mini" plain type="danger" icon="delete-o" @click="removeInvoiceDetail(index)">删除</van-button>
</div>
</div>
</template>
@@ -985,22 +997,22 @@ layout("/layouts/platform_h5.html"){
<!-- 提交按钮 -->
<div class="form-actions">
<van-button plain @click="onSave" type="info">保存</van-button>
<van-button @click="onSubmit" type="primary" v-if="!taskId">提交</van-button>
<van-button @click="onSubmitAgain" type="primary" v-else>提交</van-button>
<van-button plain @click="onSave" type="info">保存申请</van-button>
<van-button @click="onSubmit" type="primary" v-if="!taskId">提交申请</van-button>
<van-button @click="onSubmitAgain" type="primary" v-else>提交申请</van-button>
</div>
</van-form>
</div>
<van-popup v-model:show="invoiceDialogVisible" position="bottom" round class="invoice-popup">
<van-popup v-model:show="invoiceDialogVisible" position="bottom" round :close-on-click-overlay="true" class="invoice-popup">
<van-nav-bar :title="invoiceDialogMode === 'edit' ? '编辑发票明细' : '新增发票明细'"
left-text="取消"
left-arrow
@click-left="invoiceDialogVisible = false"></van-nav-bar>
@click-left="closePopup('invoiceDialogVisible')"></van-nav-bar>
<div class="invoice-popup-body">
<div class="invoice-recognizing-mask" v-if="recognizingInvoice">
<van-loading type="spinner" color="#1677ff" size="24px">发票识别中...</van-loading>
</div>
<van-cell-group>
<van-cell-group class="invoice-popup-card">
<van-field class="more-text" label="发票文件" required>
<template #input>
<h5-file-upload
@@ -1040,13 +1052,15 @@ layout("/layouts/platform_h5.html"){
rows="2"
autosize></van-field>
</van-cell-group>
<div class="invoice-tip" style="padding: 8px 16px;">上传发票文件后会自动识别发票信息;开启自动校验时会同步校验发票是否重复。</div>
<div class="invoice-tip invoice-popup-tip">上传发票文件后会自动识别发票信息;开启自动校验时会同步校验发票是否重复。</div>
</div>
<div class="invoice-popup-actions">
<van-button native-type="button" block plain @click="invoiceDialogVisible = false">取消</van-button>
<van-button native-type="button" block plain type="info" @click="closePopup('invoiceDialogVisible')">取消</van-button>
<van-button native-type="button" block type="primary" @click="saveInvoiceDetail">保存</van-button>
</div>
</van-popup>
<van-dialog :value="submitConfirmVisible" title="温馨提示" message="您确定要提交吗?审核通过后可前往 PC 端我的报销打印。" show-cancel-button :confirm-button-loading="formLoading" @confirm="submitConfirmed" @cancel="closeSubmitConfirm"></van-dialog>
<van-dialog :value="removeInvoiceConfirmVisible" title="提示" message="确定删除这条发票明细吗?" show-cancel-button @confirm="confirmRemoveInvoiceDetail" @cancel="closeRemoveInvoiceConfirm"></van-dialog>
</div>
<script nonce="${cspNonce!}">
new Vue({
@@ -1127,6 +1141,20 @@ layout("/layouts/platform_h5.html"){
files: []
},
invoiceDialogVisible: false,
submitConfirmVisible: false,
removeInvoiceConfirmVisible: false,
formLoading: false,
pendingSubmitAction: "",
pendingPaymentDetails: [],
pendingInvoiceRemoveIndex: -1,
historyLayerUnsubscribe: null,
popupKeys: [
"showReimburseFundSourcePicker", "showReimburseProjectPicker", "showClubPicker", "showCondolenceSearch",
"showCondolenceTypePicker", "showCondolenceWayPicker", "showCondolenceTimePicker", "showMarryTimePicker",
"showFertilityTimePicker", "showHospitalizationStartTimePicker", "showHospitalizationEndTimePicker",
"showDeathTimePicker", "showRelationshipPicker", "showActivityTimePicker", "showPaymentWayPicker",
"payerSelectShow", "invoiceDialogVisible"
],
invoiceDialogMode: "add",
detailFormIndex: -1,
lastRecognizedFileId: "",
@@ -1239,7 +1267,7 @@ layout("/layouts/platform_h5.html"){
const file = newVal && newVal.length ? newVal[0] : null
const currentFileId = this.getInvoiceFileId(file)
if (!currentFileId) {
this.lastRecognizedFileId = ""
this.$set(this, "lastRecognizedFileId", "")
return
}
if (currentFileId === this.lastRecognizedFileId) {
@@ -1298,6 +1326,49 @@ layout("/layouts/platform_h5.html"){
closePopup(key) {
this.$set(this, key, false)
},
// 所有选择器与发票弹窗共用全局历史栈,遮罩关闭和浏览器返回键都只关闭当前弹层。
syncPopupHistory(key, visible) {
const manager = window.h5HistoryLayerManager
if (!manager) return
const layerName = "union-reimburse-apply-" + key
if (visible) { manager.open(layerName); return }
manager.close(layerName)
},
onNavBack() {
const manager = window.h5HistoryLayerManager
if (manager && manager.stack.length) { manager.close(); return }
historyBack()
},
openSubmitConfirm(action, paymentDetails) {
this.$set(this, "pendingSubmitAction", action)
this.$set(this, "pendingPaymentDetails", paymentDetails)
const manager = window.h5HistoryLayerManager
if (manager) { manager.open("union-reimburse-apply-submit-confirm"); return }
this.$set(this, "submitConfirmVisible", true)
},
closeSubmitConfirm(afterClose) {
const manager = window.h5HistoryLayerManager
if (manager) { manager.close("union-reimburse-apply-submit-confirm", afterClose); return }
this.$set(this, "submitConfirmVisible", false)
if (afterClose) afterClose()
},
openRemoveInvoiceConfirm(index) {
this.$set(this, "pendingInvoiceRemoveIndex", index)
const manager = window.h5HistoryLayerManager
if (manager) { manager.open("union-reimburse-apply-remove-invoice-confirm"); return }
this.$set(this, "removeInvoiceConfirmVisible", true)
},
closeRemoveInvoiceConfirm(afterClose) {
const manager = window.h5HistoryLayerManager
if (manager) { manager.close("union-reimburse-apply-remove-invoice-confirm", afterClose); return }
this.$set(this, "removeInvoiceConfirmVisible", false)
if (afterClose) afterClose()
},
navigateToMine() {
const manager = window.h5HistoryLayerManager
if (manager && manager.closeAllAndNavigate("/platform/unionReimburse/mine/h5")) return
this.$pjaxReplace("/platform/unionReimburse/mine/h5")
},
openDatePicker(key) {
this.openPopup(key)
},
@@ -1740,10 +1811,11 @@ layout("/layouts/platform_h5.html"){
})
},
removeInvoiceDetail(index) {
this.$dialog.confirm({
title: "提示",
message: "确定删除这条发票明细吗?"
}).then(() => {
this.openRemoveInvoiceConfirm(index)
},
confirmRemoveInvoiceDetail() {
const index = this.pendingInvoiceRemoveIndex
this.closeRemoveInvoiceConfirm(() => {
this.formData.invoiceDetails.splice(index, 1)
this.rebuildInvoiceSummary()
})
@@ -1815,11 +1887,12 @@ layout("/layouts/platform_h5.html"){
this.$set(this, "searchKeyword", "")
this.$set(this, "userOptions", [])
},
async userRemoteMethod(event) {
userRemoteMethod(event) {
if (event) {
const userOptions = await this.selectQueryUser(event)
this.$set(this, "userOptions", userOptions)
this.$set(this, "certifierUserSelectShow", true)
this.selectQueryUser(event).then((userOptions) => {
this.$set(this, "userOptions", userOptions)
this.$set(this, "certifierUserSelectShow", true)
})
}
},
selectQueryUser(keyword) {
@@ -1991,29 +2064,29 @@ layout("/layouts/platform_h5.html"){
}
})
},
async onSave() {
onSave() {
this.normalizeContactFields()
this.normalizeCondolenceDateFields()
this.rebuildInvoiceSummary()
const paymentDetails = this.preparePaymentDetailsForSubmit()
this.$set(this, "formLoading", true)
this.$axios.post("/platform/unionReimburse/apply/save", { data: JSON.stringify(this.buildSubmitFormData(paymentDetails)) })
.then((res) => {
this.$toast.clear()
if (res.code === 0) {
this.$toast.success(res.msg)
this.$pjaxReplace("/platform/unionReimburse/mine/h5")
this.navigateToMine()
} else {
this.$toast.fail(res.msg || "保存失败")
}
})
.catch(err => {
this.$toast.clear()
this.$toast.fail(this.getRequestErrorMessage(err, "保存失败"))
}).catch((err) => {
this.$toast.clear(); this.$toast.fail(this.getRequestErrorMessage(err, "保存失败"))
}).finally(() => {
this.$set(this, "formLoading", false)
})
},
// 提交
async onSubmit() {
onSubmit() {
this.normalizeContactFields()
this.normalizeCondolenceDateFields()
this.rebuildInvoiceSummary()
@@ -2029,30 +2102,11 @@ layout("/layouts/platform_h5.html"){
if (!this.validateInvoiceDetailsBeforeSubmit()) {
return
}
this.$dialog.confirm({
title: "温馨提示",
message: "您确定要提交吗?审核通过后可前往pc端我的报销打印!"
}).then(() => {
this.$axios.post("/platform/unionReimburse/apply/submit", { data: JSON.stringify(this.buildSubmitFormData(paymentDetails)) })
.then(res => {
this.$toast.clear()
if (res.code === 0) {
this.$toast.success("提交成功")
this.$pjaxReplace("/platform/unionReimburse/mine/h5")
} else {
this.$toast.fail(res.msg || "提交失败")
}
})
.catch(err => {
this.$toast.clear()
this.$toast.fail(this.getRequestErrorMessage(err, "提交失败"))
})
})
this.openSubmitConfirm("submit", paymentDetails)
})
},
// 再次提交
async onSubmitAgain() {
onSubmitAgain() {
this.normalizeContactFields()
this.normalizeCondolenceDateFields()
this.rebuildInvoiceSummary()
@@ -2068,27 +2122,24 @@ layout("/layouts/platform_h5.html"){
if (!this.validateInvoiceDetailsBeforeSubmit()) {
return
}
this.$dialog.confirm({
title: "温馨提示",
message: "您确定要提交吗?审核通过后可前往pc端我的报销打印!"
}).then(() => {
this.$axios.post("/platform/unionReimburse/apply/submitAgain", {
data: JSON.stringify(this.buildSubmitFormData(paymentDetails)),
taskId: GetQueryString("taskId")
}).then(res => {
this.$toast.clear()
if (res.code === 0) {
this.$toast.success("提交成功")
setTimeout(() => {
this.$pjaxReplace("/platform/unionReimburse/mine/h5")
}, 1500)
} else {
this.$toast.fail(res.msg || "提交失败")
}
}).catch(err => {
this.$toast.clear()
this.$toast.fail(this.getRequestErrorMessage(err, "提交失败"))
})
this.openSubmitConfirm("submitAgain", paymentDetails)
})
},
submitConfirmed() {
const action = this.pendingSubmitAction
const paymentDetails = this.pendingPaymentDetails
this.closeSubmitConfirm(() => {
this.$set(this, "formLoading", true)
const api = action === "submitAgain" ? "/platform/unionReimburse/apply/submitAgain" : "/platform/unionReimburse/apply/submit"
const params = {data: JSON.stringify(this.buildSubmitFormData(paymentDetails))}
if (action === "submitAgain") params.taskId = GetQueryString("taskId")
this.$axios.post(api, params).then((res) => {
this.$toast.clear()
if (res.code === 0) { this.$toast.success("提交成功"); this.navigateToMine() } else { this.$toast.fail(res.msg || "提交失败") }
}).catch((err) => {
this.$toast.clear(); this.$toast.fail(this.getRequestErrorMessage(err, "提交失败"))
}).finally(() => {
this.$set(this, "formLoading", false)
})
})
},
@@ -2218,46 +2269,34 @@ layout("/layouts/platform_h5.html"){
const project = this.descOptions.find(item => item.reimburseProject === projectCode)
return project ? project.projectTip : ""
},
async initDictOptions() {
// 报销类别
const reimburseTypeData = await this.$businessTool.getDictOptions("UNION_REIMBURSE_TYPE")
this.reimburseTypeColumns = reimburseTypeData.map(item => {
return { value: item.code, text: item.name }
initDictOptions() {
return this.$businessTool.getDictOptions("UNION_REIMBURSE_TYPE").then((reimburseTypeData) => {
this.$set(this, "reimburseTypeColumns", reimburseTypeData.map(item => ({value: item.code, text: item.name})))
return this.$businessTool.getDictOptions("UNION_REIMBURSE_PAYMENT_WAY")
}).then((paymentWayData) => {
this.$set(this, "paymentWayColumns", paymentWayData.map(item => ({value: item.code, text: item.name})))
return this.$businessTool.getDictOptions("UNION_REIMBURSE_PROJECT")
}).then((reimburseProjectData) => {
this.$set(this, "reimburseProjectColumns", reimburseProjectData.map(item => ({value: item.code, text: item.name})))
this.$set(this, "reimburseProjectList", reimburseProjectData)
return this.$businessTool.getDictOptions("UNION_REIMBURSE_FUND_SOURCE")
}).then((reimburseFundSourceData) => {
this.$set(this, "reimburseFundSourceColumns", reimburseFundSourceData.map(item => ({value: item.code, text: item.name})))
this.filterReimburseFundSources()
})
// 支付方式
const paymentWayData = await this.$businessTool.getDictOptions("UNION_REIMBURSE_PAYMENT_WAY")
this.paymentWayColumns = paymentWayData.map(item => {
return { value: item.code, text: item.name }
})
// 报销项目
const reimburseProjectData = await this.$businessTool.getDictOptions("UNION_REIMBURSE_PROJECT")
this.reimburseProjectColumns = reimburseProjectData.map(item => {
return { value: item.code, text: item.name }
})
this.reimburseProjectList = reimburseProjectData // 保存原始数据
// 报销经费来源
const reimburseFundSourceData = await this.$businessTool.getDictOptions("UNION_REIMBURSE_FUND_SOURCE")
this.reimburseFundSourceColumns = reimburseFundSourceData.map(item => {
return { value: item.code, text: item.name }
})
// 添加经费来源区分
await this.filterReimburseFundSources()
},
// 查询慰问对象
queryCondolence(keyword) {
this.$axios.post("/platform/UnionReimburse/apply/listUser", { keyword: keyword }).then((res) => {
if (res.code === 0) {
this.condolenceOptions = res.data
this.condolenceColumns = res.data.map(item => {
this.$set(this, "condolenceOptions", res.data)
this.$set(this, "condolenceColumns", res.data.map(item => {
return {
text: item.userName + "" + item.loginName + "" + "" + item.unitName + "" + "" + item.sex + "",
value: item.id
}
})
}))
}
})
},
@@ -2305,10 +2344,10 @@ layout("/layouts/platform_h5.html"){
queryCondolenceType() {
return this.$axios.post("/platform/unionReimburse/apply/queryCondolenceType")
.then((resp) => {
this.typeOptions = resp.data
this.condolenceTypeColumns = resp.data.map(item => {
this.$set(this, "typeOptions", resp.data)
this.$set(this, "condolenceTypeColumns", resp.data.map(item => {
return { text: item.name, value: item.id }
})
}))
})
},
// 慰问时间确认事件
@@ -2328,10 +2367,10 @@ layout("/layouts/platform_h5.html"){
// 查询社团
queryClubs() {
return this.$businessTool.listClubByRole().then((res) => {
this.clubOptions = res
this.clubColumns = res.map(item => {
this.$set(this, "clubOptions", res)
this.$set(this, "clubColumns", res.map(item => {
return { text: item.clubName, value: item.id }
})
}))
if (res && res.length === 1 && this.formData.reimburseFundSource === "UNION_REIMBURSE_FUND_SOURCE_3" && !this.formData.clubId) {
this.$set(this.formData, "clubId", res[0].id)
this.$set(this.formData, "clubName", res[0].clubName)
@@ -2404,7 +2443,7 @@ layout("/layouts/platform_h5.html"){
})
},
// 添加经费来源区分
async filterReimburseFundSources() {
filterReimburseFundSources() {
const filteredSources = []
// 原角色过滤逻辑保留如下,手机端现统一改为按权限控制,与 PC 端保持一致
@@ -2459,16 +2498,16 @@ layout("/layouts/platform_h5.html"){
}
// 更新经费来源选项
this.reimburseFundSourceColumns = filteredSources
this.$set(this, "reimburseFundSourceColumns", filteredSources)
},
init() {
this.bizId = GetQueryString("bizId")
this.$set(this, "bizId", GetQueryString("bizId"))
if (this.bizId) {
this.$axios.post("/platform/unionReimburse/apply/info", { id: this.bizId }).then((res) => {
if (res.code === 0) {
// 先保存原始数据
const originalData = { ...res.data }
this.formData = this.ensureFormData(res.data)
this.$set(this, "formData", this.ensureFormData(res.data))
this.normalizeLoadedFormData(originalData)
// 处理报销类别显示
@@ -2560,7 +2599,7 @@ layout("/layouts/platform_h5.html"){
const user = this.$store.state.user
this.$set(this.formData, "userName", user.username)
this.$set(this.formData, "loginName", user.loginname)
this.$set(this.formData, "mobile", user.mobile)
this.$set(this.formData, "mobile", user.mobile || "")
this.$set(this.formData, "userId", user.id)
this.$set(this.formData, "unitId", user.unitId)
this.$set(this.formData, "unitName", user.unit.name)
@@ -2579,12 +2618,27 @@ layout("/layouts/platform_h5.html"){
}
},
async created() {
await this.initDictOptions()
await this.queryProjectDesc()
await this.queryCondolenceType()
await this.queryClubs()
await this.init()
created() {
const manager = window.h5HistoryLayerManager
if (manager) {
manager.ensureRegistered("union-reimburse-apply")
this.$set(this, "historyLayerUnsubscribe", manager.subscribe((layers) => {
this.popupKeys.forEach((key) => {
this.$set(this, key, layers.includes("union-reimburse-apply-" + key))
})
this.$set(this, "submitConfirmVisible", layers.includes("union-reimburse-apply-submit-confirm"))
this.$set(this, "removeInvoiceConfirmVisible", layers.includes("union-reimburse-apply-remove-invoice-confirm"))
}))
}
this.popupKeys.forEach((key) => {
this.$watch(key, (visible) => { this.syncPopupHistory(key, visible) })
})
this.initDictOptions().then(() => this.queryProjectDesc()).then(() => this.queryCondolenceType()).then(() => this.queryClubs()).then(() => this.init())
},
beforeDestroy() {
if (this.historyLayerUnsubscribe) this.historyLayerUnsubscribe()
const manager = window.h5HistoryLayerManager
if (manager) manager.unregister("union-reimburse-apply")
}
})
</script>
@@ -2,71 +2,57 @@
layout("/layouts/platform_h5.html"){
#-->
<style>
.state-primary {
color: #409eff;
}
.state-success {
color: #67c23a;
}
.state-danger {
color: #f56c6c;
}
<style id="style-union-reimburse-h5">
<!--#include('../common/unionReimburse.css'){}#-->
</style>
<div id="app" v-cloak>
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="报销统计" placeholder fixed></van-nav-bar>
<div id="app" v-cloak class="union-reimburse-page">
<van-nav-bar @click-left="onNavBack" left-arrow left-text="返回" title="报销统计" placeholder fixed></van-nav-bar>
<van-sticky offset-top="46px">
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
<van-dropdown-item :options="yearList" @change="doSearch" v-model="pageForm.year"></van-dropdown-item>
</van-dropdown-menu>
<van-search
:reverse-color="false"
:show-action="false"
@search="doSearch"
input-align="left"
placeholder="请输入经办人搜索"
v-model="pageForm.userName"
></van-search>
<div class="union-reimburse-sticky">
<van-search class="union-reimburse-search" :reverse-color="false" :show-action="false" @search="doSearch" @clear="doSearch" input-align="left" placeholder="请输入姓名或工号搜索" v-model="pageForm.searchKeyword"></van-search>
<van-dropdown-menu class="union-reimburse-filter" :close-on-click-outside="false" :close-on-click-overlay="false">
<van-dropdown-item :options="yearList" @change="doSearch" v-model="pageForm.year"></van-dropdown-item>
<van-dropdown-item :options="reimburseProjectOptions" @change="doSearch" v-model="pageForm.reimburseProject"></van-dropdown-item>
</van-dropdown-menu>
</div>
</van-sticky>
<table-list api="/platform/unionReimburse/collect/pageData" :page_form.sync="pageForm" ref="tableListRef"
@ready="doSearch" >
<main class="union-reimburse-list-content">
<table-list api="/platform/unionReimburse/collect/pageData" :page_form.sync="pageForm" ref="tableListRef" :show_loading_overlay="false"
@ready="doSearch" @loading-change="onLoadingChange">
<template #header="{row}"><div v-if="row" class="union-reimburse-card-header"><div class="union-reimburse-card-header__heading"><div class="union-reimburse-card-header__title">{{row.userName || '--'}}</div><div class="union-reimburse-card-header__sub">工号:{{row.loginName || '--'}}</div></div><van-tag :class="['union-reimburse-card-header__status', getStatusClass(row.stateId)]">{{getStateName(row.stateId)}}</van-tag></div></template>
<template v-slot="{index,row}">
<table-column label="经办人工号">{{row.loginName}}</table-column>
<table-column label="姓名">{{row.userName}}</table-column>
<table-column label="所属工会">{{row.unionName}}</table-column>
<table-column label="所属单位">{{row.unitName}}</table-column>
<table-column label="申请时间">{{formatCreateTime(row.createTime)}}</table-column>
<table-column label="报销项目">{{getReimburseProjectName(row.reimburseProject)}}</table-column>
<table-column label="备注">{{getRemarkText(row)}}</table-column>
<table-column label="申请状态">
<span :class="getStateClass(row.stateId)">{{getStateName(row.stateId)}}</span>
</table-column>
<table-column label="报销项目">{{getReimburseProjectName(row.reimburseProject) || '--'}}</table-column>
<table-column label="" label_suffix="">{{getRemarkText(row) || '--'}}</table-column>
<table-column label="所属工会">{{row.unionName || '--'}}</table-column>
<table-column label="所属单位">{{row.unitName || '--'}}</table-column>
<table-column label="申请时间">{{formatCreateTime(row.createTime) || '--'}}</table-column>
<table-column label="申请金额">{{formatMoney(row.money)}}</table-column>
</template>
<template #actions="{index,row}">
<div class="action-btn" @click="onView(row)">
<i class="fa fa-eye"></i>
<van-icon name="eye-o"></van-icon>
<span>查看</span>
</div>
<!-- <div class="action-btn" @click="onEdit(row)" v-if="row.taskKey === 'startTask' || !row.instanceId">-->
<!-- <i class="fa fa-edit"></i>-->
<!-- <span>编辑</span>-->
<!-- </div>-->
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(item)">
<i class="fa fa-undo"></i>
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
<van-icon name="revoke"></van-icon>
<span>撤回</span>
</div>
<div class="action-btn delete" @click="onDelete(row)" v-if="row.taskKey === 'startTask' || !row.instanceId">
<i class="fa fa-trash"></i>
<van-icon name="delete-o"></van-icon>
<span>删除</span>
</div>
</template>
<template #empty><div v-if="listLoading" class="union-reimburse-list-skeleton"><div v-for="item in 2" :key="item" class="union-reimburse-skeleton-card"><div class="union-reimburse-skeleton-line union-reimburse-skeleton-line--title"></div><div class="union-reimburse-skeleton-line"></div><div class="union-reimburse-skeleton-line union-reimburse-skeleton-line--short"></div></div></div><div v-else class="union-reimburse-empty"><img src="/assets/mobile/img/unionReimburse/union-reimburse-empty.png" alt="暂无报销统计记录插画"><div class="union-reimburse-empty__title">暂无报销统计记录</div><div class="union-reimburse-empty__hint">当前筛选条件下暂时没有报销记录</div></div></template>
</table-list>
</main>
<union-reimburse-info ref="unionReimburseInfoRef"></union-reimburse-info>
<union-reimburse-info ref="unionReimburseInfoRef" history-layer-name="union-reimburse-collect-info"></union-reimburse-info>
<van-dialog :value="confirmVisible" title="提示" :message="confirmMessage" show-cancel-button :confirm-button-loading="formLoading" @confirm="confirmPendingAction" @cancel="closeConfirm"></van-dialog>
</div>
<script nonce="${cspNonce!}">
@@ -80,18 +66,32 @@ layout("/layouts/platform_h5.html"){
},
data() {
return {
viewShow: false,
listLoading: true,
formLoading: false,
confirmVisible: false,
pendingAction: "",
pendingRow: null,
historyLayerUnsubscribe: null,
yearList: [],
reimburseProjectOptions: [
{text: "全部项目", value: ""},
{text: "慰问", value: "UNION_REIMBURSE_PROJECT_1"},
{text: "文体活动", value: "UNION_REIMBURSE_PROJECT_2"},
{text: "日常活动", value: "UNION_REIMBURSE_PROJECT_3"},
{text: "专项活动", value: "UNION_REIMBURSE_PROJECT_4"}
],
pageForm: {
pageNumber: 1,
pageSize: 10,
totalCount: 0,
searchKeyword: "",
year: "",
reimburseProject: ""
},
infoShow: false
}
},
computed: { confirmMessage() { return this.pendingAction === "revoke" ? "您确定要撤回申请吗?" : "您确定要删除吗?" } },
methods: {
// 手机端统计列表字段展示与我的报销列表保持一致。
getReimburseProjectName(reimburseProject) {
@@ -133,58 +133,35 @@ layout("/layouts/platform_h5.html"){
}
return stateId || ""
},
getStateClass(stateId) {
if (stateId == 3) {
return "state-success"
}
if (stateId == 4) {
return "state-danger"
}
return "state-primary"
},
getStatusClass(stateId) { if (stateId == 3) return "union-reimburse-card-header__status--success"; if (stateId == 4 || stateId == 5) return "union-reimburse-card-header__status--danger"; return "union-reimburse-card-header__status--pending" },
formatCreateTime(value) {
return value && this.$moment(value).isValid() ? this.$moment(value).format("YYYY-MM-DD HH:mm:ss") : ""
},
formatMoney(value) {
if (value === null || value === undefined || value === "") return "--"
const amount = Number(value)
return isNaN(amount) ? value : amount.toFixed(2) + "元"
},
onView(row) {
this.showApprovalForm = false
this.$refs.unionReimburseInfoRef.onOpen(row)
this.$refs.unionReimburseInfoRef.onOpen(row, "报销统计详情")
},
onEdit(row) {
this.$pjaxReplace("/platform/unionReimburse/apply/h5?bizId=" + row.id + "&taskId=" + row.startTaskId)
},
onRevoke(row){
this.$dialog
.confirm({
title: "提示",
message: "您确定要撤销申请吗?"
})
.then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.startTaskId}).then((resp) => {
this.$toast.success(resp.msg)
this.doSearch()
})
})
},
onDelete(row) {
this.$dialog
.confirm({
title: "提示",
message: "您确定要删除吗?"
})
.then(() => {
this.$axios.post("/platform/unionReimburse/mine/delete", {id: row.id}).then((resp) => {
if (resp.code === 0) {
this.$toast.success(resp.msg)
this.doSearch()
}
})
})
},
onLoadingChange(state) { this.$set(this, "listLoading", state.loading) },
onNavBack() { const manager = window.h5HistoryLayerManager; if (manager && manager.stack.length) { manager.close(); return } historyBack() },
openConfirm(action, row) { this.$set(this, "pendingAction", action); this.$set(this, "pendingRow", row); const manager = window.h5HistoryLayerManager; if (manager) { manager.open("union-reimburse-collect-confirm"); return } this.$set(this, "confirmVisible", true) },
closeConfirm(afterClose) { const manager = window.h5HistoryLayerManager; if (manager) { manager.close("union-reimburse-collect-confirm", afterClose); return } this.$set(this, "confirmVisible", false); if (afterClose) afterClose() },
confirmPendingAction() { const action = this.pendingAction; const row = this.pendingRow; this.closeConfirm(() => { if (action === "revoke") { this.revoke(row) } else { this.deleteApplication(row) } }) },
onRevoke(row) { this.openConfirm("revoke", row) },
revoke(row) { this.$set(this, "formLoading", true); this.$axios.post("/flow/common/revokeTask", {taskId: row.startTaskId}).then((resp) => { if (resp.code === 0) { this.$toast.success(resp.msg); this.doSearch() } else { this.$toast.fail(resp.msg) } }).finally(() => { this.$set(this, "formLoading", false) }) },
onDelete(row) { this.openConfirm("delete", row) },
deleteApplication(row) { this.$set(this, "formLoading", true); this.$axios.post("/platform/unionReimburse/mine/delete", {id: row.id}).then((resp) => { if (resp.code === 0) { this.$toast.success(resp.msg); this.doSearch() } else { this.$toast.fail(resp.msg) } }).finally(() => { this.$set(this, "formLoading", false) }) },
doSearch() {
this.$nextTick(() => {
this.pageForm.pageNumber = 1
this.pageForm.totalCount = 0
this.$set(this.pageForm, "pageNumber", 1)
this.$set(this.pageForm, "totalCount", 0)
this.$refs.tableListRef.doSearch()
})
},
@@ -198,7 +175,13 @@ layout("/layouts/platform_h5.html"){
},
created() {
this.initData()
const manager = window.h5HistoryLayerManager
if (manager) { manager.ensureRegistered("union-reimburse-collect"); this.$set(this, "historyLayerUnsubscribe", manager.subscribe((layers) => { this.$set(this, "confirmVisible", layers.includes("union-reimburse-collect-confirm")) })) }
},
beforeDestroy() {
if (this.historyLayerUnsubscribe) this.historyLayerUnsubscribe()
const manager = window.h5HistoryLayerManager
if (manager) manager.unregister("union-reimburse-collect")
}
})
</script>
@@ -0,0 +1,472 @@
.union-reimburse-page {
min-height: 100vh;
padding-bottom: calc(24px + env(safe-area-inset-bottom));
box-sizing: border-box;
background: #f3f7fd;
color: #40526a;
}
.union-reimburse-page .van-nav-bar,
.union-reimburse-page .van-sticky--fixed { background: #fff; }
.union-reimburse-page .van-nav-bar__title {
color: #172033;
font-size: 16px;
font-weight: 600;
}
.union-reimburse-page .van-nav-bar .van-icon,
.union-reimburse-page .van-nav-bar .van-nav-bar__text { color: #1989fa; }
.union-reimburse-sticky {
padding: 22px 12px 1px;
box-sizing: border-box;
background: #f3f7fd;
}
.union-reimburse-search {
margin: 0 0 8px;
padding: 0;
overflow: hidden;
border-radius: 12px;
background: #fff;
box-shadow: 0 5px 16px rgba(43, 73, 112, .1);
}
.union-reimburse-search .van-search__content {
height: 42px;
padding-left: 12px;
align-items: center;
border-radius: 12px;
background: #fff;
}
.union-reimburse-search .van-field__control { color: #263548; font-size: 14px; }
.union-reimburse-search .van-field__control::placeholder { color: #a7b0bf; }
.union-reimburse-filter {
margin-bottom: 8px;
overflow: hidden;
border-radius: 10px;
background: #fff;
box-shadow: 0 5px 16px rgba(43, 73, 112, .08);
}
.union-reimburse-filter .van-dropdown-menu__bar { height: 44px; box-shadow: none; }
.union-reimburse-filter .van-dropdown-menu__item,
.union-reimburse-filter .van-dropdown-menu__title { height: 44px; }
.union-reimburse-filter .van-dropdown-menu__item { align-items: center; justify-content: center; }
.union-reimburse-filter .van-dropdown-menu__title {
display: inline-flex;
align-items: center;
color: #66758a;
font-size: 14px;
line-height: 20px;
}
.union-reimburse-filter .van-dropdown-menu__title--active,
.union-reimburse-filter .van-dropdown-item__option--active,
.union-reimburse-filter .van-dropdown-item__option--active .van-dropdown-item__icon { color: #1989fa; }
.union-reimburse-filter .van-dropdown-item__content {
width: calc(100% - 24px);
margin: 0 12px;
overflow: hidden;
box-sizing: border-box;
border-radius: 0 0 12px 12px;
box-shadow: 0 10px 24px rgba(31, 65, 108, .14);
}
.union-reimburse-filter .van-dropdown-item__option {
display: flex;
min-height: 48px;
padding: 0 16px;
align-items: center;
color: #46566c;
font-size: 14px;
}
.union-reimburse-list-content { padding: 0 12px; }
.union-reimburse-page .table-list-container { margin-top: 0; padding-bottom: 2px; }
.union-reimburse-page .table-list-container .table-list-item {
margin-bottom: 12px;
padding: 14px;
border: 1px solid #e9eff7;
border-radius: 12px;
box-shadow: 0 5px 16px rgba(43, 73, 112, .08);
}
.union-reimburse-card-header { display: flex; margin-bottom: 8px; align-items: flex-start; justify-content: space-between; }
.union-reimburse-card-header__heading { min-width: 0; padding-right: 10px; flex: 1; }
.union-reimburse-card-header__title {
overflow: hidden;
color: #253247;
font-size: 15px;
font-weight: 600;
line-height: 22px;
text-overflow: ellipsis;
white-space: nowrap;
}
.union-reimburse-card-header__sub { margin-top: 1px; color: #9ba6b6; font-size: 12px; line-height: 18px; }
.union-reimburse-card-header__status { display: inline-flex; flex: none; }
.union-reimburse-card-header__status.van-tag,
.union-reimburse-card-header__status .van-tag {
min-height: 24px;
padding: 3px 9px;
border: 0;
border-radius: 12px;
box-sizing: border-box;
font-size: 12px;
line-height: 18px;
}
.union-reimburse-card-header__status--pending { color: #1989fa; background: #eaf4ff; }
/* 报销成功与社团审核页 ProcessInstanceStateEnum 的“已完成”保持一致。 */
.union-reimburse-card-header__status--success { color: #67c23a; background: #f0f9eb; }
.union-reimburse-card-header__status--danger { color: #e35d5d; background: #fff0f0; }
.union-reimburse-page .table-list-container .table-list-item .item-actions {
margin-top: 10px;
padding-top: 10px;
border-top-color: #edf1f6;
}
.union-reimburse-page .table-list-container .table-list-item .action-btn {
min-height: 28px;
padding: 4px 11px;
border-radius: 14px;
color: #1989fa;
background: #eaf4ff;
font-size: 12px;
line-height: 18px;
}
.union-reimburse-page .table-list-container .table-list-item .action-btn.delete { color: #f04444; background: #fff0f0; }
.union-reimburse-page .table-list-container .table-list-item .action-btn.review { color: #1989fa; background: #eaf4ff; }
.union-reimburse-page .table-list-container .table-list-item .action-btn .van-icon { margin-right: 5px; font-size: 13px; }
.union-reimburse-page .empty-state { padding: 0; }
.union-reimburse-list-skeleton { padding: 0; }
.union-reimburse-skeleton-card {
margin-bottom: 12px;
padding: 14px;
border: 1px solid #e9eff7;
border-radius: 12px;
background: #fff;
}
.union-reimburse-skeleton-line {
height: 13px;
margin-bottom: 12px;
border-radius: 7px;
background: linear-gradient(90deg, #f2f3f5 25%, #e6e8eb 37%, #f2f3f5 63%);
background-size: 400% 100%;
animation: union-reimburse-skeleton-loading 1.4s ease infinite;
}
.union-reimburse-skeleton-line--title { width: 46%; height: 16px; }
.union-reimburse-skeleton-line--short { width: 60%; }
.union-reimburse-empty {
display: flex;
min-height: 280px;
padding: 46px 18px 36px;
align-items: center;
justify-content: center;
box-sizing: border-box;
flex-direction: column;
text-align: center;
}
.union-reimburse-empty img { display: block; width: 86%; max-width: 290px; height: auto; object-fit: contain; }
.union-reimburse-empty__title { margin-top: 14px; color: #50627a; font-size: 15px; font-weight: 600; line-height: 22px; }
.union-reimburse-empty__hint { margin-top: 5px; color: #9aa7b8; font-size: 12px; line-height: 18px; }
/* 申请页沿用社团申请的卡片层级,保留报销业务原有字段与交互。 */
.union-reimburse-form { padding-bottom: 0; }
.union-reimburse-form .custom-nav { box-shadow: none; }
.union-reimburse-form .form-container { padding: 12px 15px calc(86px + env(safe-area-inset-bottom)); }
.union-reimburse-form .form-section {
margin: 0 0 11px;
overflow: hidden;
border: 1px solid #e9eff7;
border-radius: 10px;
background: #fff;
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
}
.union-reimburse-form .form-section .van-cell-group__title,
.union-reimburse-form .payment-toolbar,
.union-reimburse-form .invoice-toolbar {
position: relative;
min-height: 42px;
margin: 0;
padding: 12px 14px 8px 21px;
box-sizing: border-box;
color: #354255;
font-size: 15px;
font-weight: 600;
line-height: 22px;
background: #fff;
}
.union-reimburse-form .form-section__title {
position: relative;
min-height: 41px;
margin: 0;
padding: 13px 15px 8px 24px;
box-sizing: border-box;
color: #1f2d3d;
font-size: 14px;
font-weight: 600;
line-height: 20px;
background: #fff;
}
.union-reimburse-form .form-section__title::before {
position: absolute;
top: 16px;
left: 15px;
width: 3px;
height: 14px;
border-radius: 2px;
background: #1989fa;
content: '';
}
.union-reimburse-form .form-section .van-cell-group__title::before,
.union-reimburse-form .payment-toolbar::before,
.union-reimburse-form .invoice-toolbar::before {
position: absolute;
top: 15px;
bottom: 11px;
left: 12px;
width: 2px;
border-radius: 2px;
background: #1989fa;
content: '';
}
.union-reimburse-form .form-section .van-cell { min-height: 46px; padding: 11px 15px; background: transparent; }
.union-reimburse-form .form-section .van-cell::after { right: 15px; left: 15px; border-color: #eef2f7; }
.union-reimburse-form .form-section .van-field__label { width: 105px; color: #596779; font-size: 13px; line-height: 24px; }
.union-reimburse-form .payment-detail-item .van-cell--required::before { left: 6px; color: #f06464; }
.union-reimburse-form .form-section .van-field__control { color: #40526a; font-size: 14px; line-height: 24px; }
.union-reimburse-form .form-section .van-field__control::placeholder { color: #a7b0bf; }
.union-reimburse-form .more-text { display: block; }
.union-reimburse-form .more-text .van-field__label { width: auto; margin-bottom: 7px; }
.union-reimburse-form .more-text .van-field__control {
min-height: 88px;
padding: 10px 12px;
box-sizing: border-box;
border: 1px solid #c9d5e5;
border-radius: 10px;
background: #f7f9fd;
}
.union-reimburse-form .payment-section,
.union-reimburse-form .invoice-section { padding: 0 0 14px; }
.union-reimburse-form .payment-toolbar,
.union-reimburse-form .invoice-toolbar { display: flex; align-items: center; justify-content: space-between; }
.union-reimburse-form .payment-toolbar .van-button,
.union-reimburse-form .invoice-toolbar .van-button {
height: 28px;
padding: 0 12px;
border: 0;
border-radius: 14px;
color: #1989fa;
background: #eaf4ff;
}
.union-reimburse-form .payment-detail-item,
.union-reimburse-form .invoice-detail-item {
margin: 8px 14px 0;
overflow: hidden;
border: 1px solid #e6ebf2;
border-radius: 10px;
background: #fff;
box-shadow: none;
}
.union-reimburse-form .invoice-detail-item { padding: 0; }
.union-reimburse-form .invoice-detail-title {
min-height: 38px;
padding: 0 12px;
box-sizing: border-box;
color: #40526a;
font-size: 14px;
font-weight: 600;
line-height: 22px;
background: #f7f9fd;
border-bottom: 1px solid #eef2f7;
}
.union-reimburse-form .invoice-detail-line {
margin: 0;
padding: 8px 12px 0;
color: #718096;
font-size: 13px;
line-height: 20px;
word-break: break-all;
}
.union-reimburse-form .invoice-detail-line:last-of-type { padding-bottom: 8px; }
.union-reimburse-form .invoice-detail-actions,
.union-reimburse-form .payment-detail-actions {
min-height: 28px;
margin-top: 8px;
padding: 9px 12px;
box-sizing: border-box;
border-top: 1px solid #eef2f7;
background: #fff;
}
.union-reimburse-form .invoice-detail-actions { justify-content: flex-end; gap: 6px; }
.union-reimburse-form .invoice-detail-actions .van-button,
.union-reimburse-form .payment-detail-actions .payment-delete-btn {
height: 28px;
min-width: 52px;
padding: 0 10px;
border: 0;
border-radius: 14px;
font-size: 12px;
line-height: 18px;
}
.union-reimburse-form .invoice-detail-actions .van-button--info,
.union-reimburse-form .invoice-detail-actions .van-button--primary {
color: #1989fa;
background: #eaf4ff;
}
.union-reimburse-form .invoice-detail-actions .van-button--danger,
.union-reimburse-form .payment-detail-actions .payment-delete-btn {
color: #f04444;
background: #fff0f0;
}
.union-reimburse-form .invoice-detail-actions .van-icon,
.union-reimburse-form .payment-detail-actions .payment-delete-btn .van-icon {
margin-right: 4px;
font-size: 13px;
}
.union-reimburse-form .payment-detail-item .van-cell { padding-right: 12px; padding-left: 12px; }
.union-reimburse-form .payment-detail-title {
min-height: 38px;
padding: 0 12px;
color: #40526a;
background: #f7f9fd;
border-bottom-color: #eef2f7;
}
.union-reimburse-form .invoice-tip { margin: 8px 14px 10px; border-color: #dce9f8; color: #718096; background: #f5f9ff; }
.union-reimburse-form .form-actions {
gap: 10px;
padding: 10px 15px calc(10px + env(safe-area-inset-bottom));
box-shadow: 0 -2px 12px rgba(43, 73, 112, .09);
}
.union-reimburse-form .form-actions .van-button { height: 40px; border-radius: 8px; font-size: 14px; font-weight: 500; }
.union-reimburse-form .form-actions .van-button--primary { border-color: #1989fa; background: #1989fa; box-shadow: none; }
.union-reimburse-form .form-actions .van-button--info.van-button--plain { color: #1989fa; border-color: #1989fa; }
/* 新增、编辑发票弹框与申请页共用卡片、字段和操作按钮视觉规范。 */
.union-reimburse-form .invoice-popup {
overflow: hidden;
background: #f3f7fd;
}
.union-reimburse-form .invoice-popup .van-nav-bar { flex: none; box-shadow: 0 1px 6px rgba(43, 73, 112, .08); }
.union-reimburse-form .invoice-popup .van-nav-bar__title { color: #1f2d3d; font-size: 16px; font-weight: 600; }
.union-reimburse-form .invoice-popup-body {
padding: 12px 15px;
box-sizing: border-box;
background: #f3f7fd;
}
.union-reimburse-form .invoice-popup-card {
overflow: hidden;
border: 1px solid #e9eff7;
border-radius: 10px;
background: #fff;
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
}
.union-reimburse-form .invoice-popup-card .van-cell { min-height: 46px; padding: 11px 15px; background: transparent; }
.union-reimburse-form .invoice-popup-card .van-cell::after { right: 15px; left: 15px; border-color: #eef2f7; }
.union-reimburse-form .invoice-popup-card .van-field__label { width: 105px; color: #596779; font-size: 13px; line-height: 24px; }
.union-reimburse-form .invoice-popup-card .van-field__control { color: #40526a; font-size: 14px; line-height: 24px; }
.union-reimburse-form .invoice-popup-card .van-field__control::placeholder { color: #a7b0bf; }
.union-reimburse-form .invoice-popup-card .more-text { display: block; }
.union-reimburse-form .invoice-popup-card .more-text .van-field__label { width: auto; margin-bottom: 7px; }
.union-reimburse-form .invoice-popup-card .more-text .van-field__control {
min-height: 88px;
padding: 10px 12px;
box-sizing: border-box;
border: 1px solid #c9d5e5;
border-radius: 10px;
background: #f7f9fd;
}
.union-reimburse-form .invoice-popup-tip {
margin: 10px 0 0;
padding: 9px 11px;
border-color: #dce9f8;
color: #718096;
background: #f5f9ff;
}
.union-reimburse-form .invoice-popup-actions {
flex: none;
gap: 10px;
padding: 10px 15px calc(10px + env(safe-area-inset-bottom));
box-shadow: 0 -2px 12px rgba(43, 73, 112, .09);
}
.union-reimburse-form .invoice-popup-actions .van-button { height: 40px; border-radius: 8px; font-size: 14px; font-weight: 500; }
.union-reimburse-form .invoice-popup-actions .van-button--primary { border-color: #1989fa; background: #1989fa; box-shadow: none; }
.union-reimburse-form .invoice-popup-actions .van-button--info.van-button--plain { color: #1989fa; border-color: #1989fa; background: #fff; }
/* 审核卡片与社团审核保持相同的标题、必填标记和按钮规格。 */
.union-reimburse-approval { padding: 0; background: #f3f7fd; }
.union-reimburse-approval-card {
margin: 0 0 11px;
overflow: hidden;
border: 1px solid #e9eff7;
border-radius: 10px;
background: #fff;
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
}
.union-reimburse-approval-card__title {
position: relative;
margin: 0;
padding: 12px 14px 8px 21px;
color: #354255;
font-size: 15px;
font-weight: 600;
line-height: 22px;
}
.union-reimburse-approval-card__title::before {
position: absolute;
top: 15px;
bottom: 11px;
left: 12px;
width: 2px;
border-radius: 2px;
background: #1989fa;
content: '';
}
.union-reimburse-approval-field-label {
position: relative;
margin: 0;
padding: 10px 14px 6px;
color: #596779;
font-size: 12px;
line-height: 24px;
}
.union-reimburse-approval-required { position: absolute; left: 6px; color: #ee0a24; font-size: 12px; }
.union-reimburse-approval-card .van-field.union-reimburse-approval-field {
width: calc(100% - 28px);
margin: 0 14px 14px;
padding: 12px;
box-sizing: border-box;
border: 1px solid #c9d5e5;
border-radius: 10px;
background: #f7f9fd;
}
.union-reimburse-approval-card .van-field.union-reimburse-approval-field .van-field__control {
min-height: 150px;
color: #253247;
font-size: 12px;
line-height: 22px;
}
.union-reimburse-approval-card .van-field.union-reimburse-approval-field::after { display: none; }
.union-reimburse-approval-actions {
display: flex;
column-gap: 10px;
padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
}
.union-reimburse-approval-actions .van-button { height: 40px; border-radius: 14px; font-size: 14px; }
@keyframes union-reimburse-skeleton-loading {
0% { background-position: 100% 50%; }
100% { background-position: 0 50%; }
}
@@ -2,14 +2,10 @@ const UNION_REIMBURSE_INFO = {
template:
/*language=HTML*/
`
<van-action-sheet v-model="visible" class="union-reimburse-info-sheet">
<div class="union-info-header">
<div class="union-info-header-title">查看详情</div>
<div class="union-info-close" @click="onClose">
<van-icon name="cross"></van-icon>
</div>
</div>
<div class="detail-container">
<van-popup v-model="visible" position="right" :style="{width: '100%', height: '100%'}" get-container="#app" :close-on-click-overlay="false" class="union-reimburse-info-sheet">
<div class="union-reimburse-info-detail">
<van-nav-bar :title="detailTitle" left-text="返回" left-arrow fixed @click-left="onClose"></van-nav-bar>
<div class="detail-container">
<div class="union-info-scroll">
<div class="union-info-section">
<div class="union-info-section-title">报销申请</div>
@@ -59,6 +55,8 @@ const UNION_REIMBURSE_INFO = {
</div>
<van-swipe ref="paymentInfoSwipe" :loop="false" :show-indicators="false" @change="handlePaymentSwipeChange">
<van-swipe-item v-for="(item, index) in paymentInfoRows" :key="index">
<div class="union-payment-card">
<div class="union-payment-card-title">支付信息{{ index + 1 }}</div>
<div class="union-info-row">
<div class="union-info-label">支付方式</div>
<div class="union-info-value">{{ getPaymentWayText(item.paymentWay) }}</div>
@@ -85,6 +83,7 @@ const UNION_REIMBURSE_INFO = {
<div class="union-info-value">{{ item.bankCardNumber }}</div>
</div>
</template>
</div>
</van-swipe-item>
</van-swipe>
</template>
@@ -272,12 +271,12 @@ const UNION_REIMBURSE_INFO = {
<!-- </van-cell-group>-->
<template v-for="(task,index) in doneTasks">
<div class="union-info-section">
<div class="process-title">{{ task.displayName }}</div>
<template v-if="task.ext.isFirstTaskNode">
<section class="union-info-section union-info-task-card">
<h3 class="union-info-section-title union-info-task-card__title">{{ task.displayName || '审核节点' }}</h3>
<template v-if="task.ext && task.ext.isFirstTaskNode">
<div class="union-info-row">
<div class="union-info-label">申请用户</div>
<div class="union-info-value">{{ task.ext.initiatorName}}({{task.ext.initiatorAccount}})</div>
<div class="union-info-value">{{ task.ext.initiatorName || '--' }}{{task.ext.initiatorAccount || '--'}}</div>
</div>
<div class="union-info-row">
<div class="union-info-label">申请时间</div>
@@ -286,14 +285,14 @@ const UNION_REIMBURSE_INFO = {
<div class="union-info-row">
<div class="union-info-label">办理结果</div>
<div class="union-info-value">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext && task.ext.submitType"></dict-tag>
</div>
</div>
</template>
<template v-else>
<div class="union-info-row">
<div class="union-info-label">办理用户</div>
<div class="union-info-value">{{ task.taskFormData.userName}}({{task.taskFormData.loginName}})</div>
<div class="union-info-value">{{ getTaskUserText(task) }}</div>
</div>
<div class="union-info-row">
<div class="union-info-label">办理时间</div>
@@ -302,36 +301,44 @@ const UNION_REIMBURSE_INFO = {
<div class="union-info-row">
<div class="union-info-label">办理结果</div>
<div class="union-info-value">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext && task.ext.submitType"></dict-tag>
</div>
</div>
<div class="union-info-row" v-if="!task.ext.isFirstTaskNode">
<div class="union-info-row">
<div class="union-info-label">办理意见</div>
<div class="union-info-value">{{ task.taskFormData.opinion }}</div>
<div class="union-info-value">{{ getTaskOpinion(task) }}</div>
</div>
<div class="union-info-row" v-if="!task.ext.isFirstTaskNode && task.ext.tf_userSign">
<div class="union-info-row" v-if="task.ext && task.ext.tf_userSign">
<div class="union-info-label">签字</div>
<div class="union-info-value">
<van-image :src="task.ext.tf_userSign" class="signature-image"></van-image>
</div>
</div>
</template>
</div>
</section>
</template>
<slot></slot>
</div>
</div>
<slot></slot>
</van-action-sheet>
</div>
</van-popup>
`,
dicts: ["UNION_REIMBURSE_TYPE", "UNION_REIMBURSE_PAYMENT_WAY", "UNION_REIMBURSE_FUND_SOURCE", "UNION_REIMBURSE_PROJECT", "PROCESS_TASK_SUBMIT_TYPE"],
props: {
historyLayerName: {
type: String,
default: "union-reimburse-info"
}
},
data() {
return {
visible: false,
viewData: {},
doneTasks: [],
row: null,
currentPaymentIndex: 0
currentPaymentIndex: 0,
detailTitle: "报销详情",
historyLayerUnsubscribe: null
}
},
computed: {
@@ -339,8 +346,29 @@ const UNION_REIMBURSE_INFO = {
return this.viewData.paymentDetails || []
}
},
watch: {
visible(value) {
const manager = window.h5HistoryLayerManager
if (!manager) return
if (value) {
manager.open(this.historyLayerName)
return
}
manager.close(this.historyLayerName)
}
},
mounted() {
this.injectInfoStyle()
const manager = window.h5HistoryLayerManager
if (manager) {
manager.ensureRegistered("union-reimburse-info")
this.$set(this, "historyLayerUnsubscribe", manager.subscribe((layers) => {
this.$set(this, "visible", layers.includes(this.historyLayerName))
}))
}
},
beforeDestroy() {
if (this.historyLayerUnsubscribe) this.historyLayerUnsubscribe()
},
methods: {
injectInfoStyle() {
@@ -355,16 +383,19 @@ const UNION_REIMBURSE_INFO = {
styleNode.appendChild(document.createTextNode(this.$options.style))
document.head.appendChild(styleNode)
},
onOpen(row) {
this.row = row
this.visible = true
this.currentPaymentIndex = 0
onOpen(row, title) {
this.$set(this, "row", row)
this.$set(this, "detailTitle", title || "报销详情")
this.$set(this, "visible", true)
this.$set(this, "currentPaymentIndex", 0)
this.getInfo()
this.getDoneTasks()
},
// 关闭
// 由全局历史栈关闭详情,保证遮罩、关闭按钮和浏览器返回键遵循同一顺序。
onClose() {
this.visible = false
const manager = window.h5HistoryLayerManager
if (manager && manager.close(this.historyLayerName)) return
this.$set(this, "visible", false)
},
formatCreateTime(value) {
return value && this.$moment(value).isValid() ? this.$moment(value).format("YYYY-MM-DD HH:mm:ss") : ""
@@ -386,6 +417,16 @@ const UNION_REIMBURSE_INFO = {
const matchedPaymentWay = this.dict.type.UNION_REIMBURSE_PAYMENT_WAY.find(item => item.code === paymentWay)
return matchedPaymentWay ? matchedPaymentWay.name : ""
},
getTaskUserText(task) {
const formData = task && task.taskFormData ? task.taskFormData : {}
const userName = formData.userName || formData.username || "--"
const loginName = formData.loginName || formData.loginname || "--"
return userName + "" + loginName + ""
},
getTaskOpinion(task) {
const formData = task && task.taskFormData ? task.taskFormData : {}
return formData.reviewOpinion || formData.opinion || formData.tf_opinion || "--"
},
buildViewData(data) {
const viewData = Object.assign({
files: [],
@@ -425,15 +466,15 @@ const UNION_REIMBURSE_INFO = {
}
},
handlePaymentSwipeChange(index) {
this.currentPaymentIndex = index
this.$set(this, "currentPaymentIndex", index)
},
swipeToPayment(index) {
if (!this.paymentInfoRows.length) {
this.currentPaymentIndex = 0
this.$set(this, "currentPaymentIndex", 0)
return
}
const targetIndex = Math.max(0, Math.min(index, this.paymentInfoRows.length - 1))
this.currentPaymentIndex = targetIndex
this.$set(this, "currentPaymentIndex", targetIndex)
this.$nextTick(() => {
if (this.$refs.paymentInfoSwipe && this.$refs.paymentInfoSwipe.swipeTo) {
this.$refs.paymentInfoSwipe.swipeTo(targetIndex)
@@ -456,8 +497,8 @@ const UNION_REIMBURSE_INFO = {
getInfo() {
this.$axios.post("/platform/unionReimburse/apply/info", { id: this.row.id }).then((res) => {
if (res.code === 0) {
this.viewData = this.buildViewData(res.data)
this.currentPaymentIndex = 0
this.$set(this, "viewData", this.buildViewData(res.data))
this.$set(this, "currentPaymentIndex", 0)
}
})
},
@@ -471,120 +512,131 @@ const UNION_REIMBURSE_INFO = {
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", { bizId: this.row.id }).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
this.$set(this, "doneTasks", res.data || [])
}
})
}
},
style: /*language=CSS*/ `
.union-reimburse-info-sheet {
height: 92vh;
display: flex;
flex-direction: column;
overflow: hidden;
background: #f3f7fd;
}
.union-reimburse-info-sheet .van-action-sheet__content {
.union-reimburse-info-detail {
height: 100%;
display: flex;
padding-top: 46px;
box-sizing: border-box;
flex-direction: column;
overflow: hidden;
background: #f3f7fd;
}
.union-info-header {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: space-between;
height: 56px;
padding: 0 20px;
.union-reimburse-info-detail > .van-nav-bar {
z-index: 20;
background: #fff;
border-top: 4px solid #1677ff;
border-bottom: 1px solid #e7ebf0;
}
.union-info-header-title {
color: #111827;
.union-reimburse-info-detail > .van-nav-bar .van-nav-bar__title {
color: #172033;
font-size: 16px;
font-weight: 700;
font-weight: 600;
}
.union-info-close {
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
color: #8b95a3;
font-size: 20px;
.union-reimburse-info-detail > .van-nav-bar .van-icon,
.union-reimburse-info-detail > .van-nav-bar .van-nav-bar__text {
color: #1989fa;
}
.detail-container {
flex: 1;
overflow: hidden;
background: #f2f4f7;
background: #f3f7fd;
}
.union-info-scroll {
height: 100%;
overflow-y: auto;
padding-bottom: 16px;
padding: 12px 15px calc(18px + env(safe-area-inset-bottom));
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
.union-info-section {
overflow: hidden;
margin-bottom: 11px;
border: 1px solid #e9eff7;
border-radius: 10px;
background: #fff;
margin-bottom: 10px;
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
}
.union-info-section-title {
display: flex;
align-items: center;
height: 44px;
padding: 0 16px;
color: #1f2937;
font-size: 14px;
font-weight: 700;
background: #f5f7fa;
border-bottom: 1px solid #e7ebf0;
position: relative;
margin: 0;
padding: 12px 14px 8px 21px;
color: #354255;
font-size: 15px;
font-weight: 600;
line-height: 22px;
}
.union-info-section-title::before {
content: "";
width: 4px;
height: 16px;
margin-right: 8px;
position: absolute;
top: 15px;
bottom: 11px;
left: 12px;
width: 2px;
border-radius: 2px;
background: #1677ff;
background: #1989fa;
content: "";
}
.union-info-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
min-height: 44px;
padding: 12px 20px;
border-bottom: 1px solid #edf0f4;
min-height: 43px;
padding: 10px 14px;
border-bottom: 1px solid #eef2f7;
box-sizing: border-box;
}
/* 查看详情中的流程节点字段与社团审核详情卡片保持一致的行高和内边距。 */
.union-info-task-card > .union-info-task-card__title {
margin: 0;
padding: 12px 14px 8px 21px;
}
.union-info-task-card .union-info-row {
min-height: 44px;
padding: 10px 14px;
}
.union-info-task-card .union-info-label,
.union-info-task-card .union-info-value {
line-height: 24px;
}
.union-info-row:last-child {
border-bottom: 0;
}
.union-info-label {
flex: 0 0 96px;
color: #8a94a6;
font-size: 14px;
line-height: 20px;
flex: 0 0 102px;
color: #596779;
font-size: 12px;
line-height: 22px;
}
.union-info-value {
flex: 1;
min-width: 0;
color: #1f2937;
font-size: 14px;
line-height: 20px;
text-align: right;
color: #4f5d70;
font-size: 12px;
line-height: 22px;
text-align: left;
word-break: break-all;
white-space: pre-line;
}
@@ -597,7 +649,7 @@ const UNION_REIMBURSE_INFO = {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 12px 20px 4px;
padding: 10px 14px 3px;
background: #fff;
}
@@ -617,21 +669,44 @@ const UNION_REIMBURSE_INFO = {
background: #1677ff;
}
.union-payment-card {
margin: 8px 12px 12px;
overflow: hidden;
border: 1px solid #e6ebf2;
border-radius: 9px;
background: #fff;
}
.union-payment-card-title {
padding: 9px 12px;
color: #40526a;
font-size: 13px;
font-weight: 600;
line-height: 20px;
background: #f7f9fd;
border-bottom: 1px solid #eef2f7;
}
.union-payment-card .union-info-row {
padding-right: 12px;
padding-left: 12px;
}
.union-empty-text {
padding: 14px 20px;
padding: 12px 14px;
color: #9aa3af;
font-size: 13px;
}
.union-file-preview {
padding: 12px 20px 16px;
padding: 10px 14px 14px;
}
.union-invoice-subtitle {
display: flex;
align-items: center;
height: 40px;
padding: 0 20px;
padding: 0 14px;
color: #6b7280;
font-size: 13px;
background: #f5f7fa;
@@ -640,13 +715,13 @@ const UNION_REIMBURSE_INFO = {
}
.union-invoice-card-list {
padding: 12px 16px 4px;
padding: 10px 12px 0;
}
.union-invoice-card {
margin-bottom: 12px;
padding: 14px 14px 12px;
border-radius: 12px;
padding: 12px 12px 10px;
border-radius: 9px;
border: 1px solid #e6ebf2;
background: #fff;
box-shadow: 0 1px 3px rgba(31, 35, 41, 0.05);
@@ -663,17 +738,6 @@ const UNION_REIMBURSE_INFO = {
padding: 12px 0 0;
}
.process-title {
display: flex;
align-items: center;
height: 40px;
padding: 0 20px;
color: #1f2937;
font-size: 14px;
font-weight: 700;
background: #f5f7fa;
}
.signature-image {
width: 100%;
height: 120px;
@@ -2,63 +2,65 @@
layout("/layouts/platform_h5.html"){
#-->
<style>
.state-primary {
color: #409eff;
}
.state-success {
color: #67c23a;
}
.state-danger {
color: #f56c6c;
}
<style id="style-union-reimburse-h5">
<!--#include('../common/unionReimburse.css'){}#-->
</style>
<div id="app" v-cloak>
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="我的报销" placeholder fixed></van-nav-bar>
<div id="app" v-cloak class="union-reimburse-page">
<van-nav-bar @click-left="onNavBack" left-arrow left-text="返回" title="我的报销" placeholder fixed></van-nav-bar>
<van-sticky offset-top="46px">
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
<van-dropdown-item :options="yearList" @change="doSearch" v-model="pageForm.year"></van-dropdown-item>
</van-dropdown-menu>
<div class="union-reimburse-sticky">
<van-search v-model="pageForm.searchKeyword" class="union-reimburse-search" placeholder="请输入姓名或工号搜索" shape="round" clearable @search="doSearch" @clear="doSearch"></van-search>
<van-dropdown-menu class="union-reimburse-filter" :close-on-click-outside="false" :close-on-click-overlay="false">
<van-dropdown-item :options="yearList" @change="doSearch" v-model="pageForm.year"></van-dropdown-item>
</van-dropdown-menu>
</div>
</van-sticky>
<table-list api="/platform/unionReimburse/mine/pageData" :page_form.sync="pageForm" ref="tableListRef"
@ready="doSearch" >
<main class="union-reimburse-list-content">
<table-list api="/platform/unionReimburse/mine/pageData" :page_form.sync="pageForm" ref="tableListRef" :show_loading_overlay="false"
@ready="doSearch" @loading-change="onLoadingChange">
<template #header="{row}">
<div v-if="row" class="union-reimburse-card-header">
<div class="union-reimburse-card-header__heading"><div class="union-reimburse-card-header__title">{{row.userName || '--'}}</div><div class="union-reimburse-card-header__sub">工号:{{row.loginName || '--'}}</div></div>
<enum-tag class="union-reimburse-card-header__status" v-if="row.instanceState" :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
<van-tag v-else :class="['union-reimburse-card-header__status', getStatusClass(row.stateId)]">{{getStateName(row.stateId)}}</van-tag>
</div>
</template>
<template v-slot="{index,row}">
<table-column label="经办人工号">{{row.loginName}}</table-column>
<table-column label="姓名">{{row.userName}}</table-column>
<table-column label="所属工会">{{row.unionName}}</table-column>
<table-column label="所属单位">{{row.unitName}}</table-column>
<table-column label="申请时间">{{formatCreateTime(row.createTime)}}</table-column>
<table-column label="报销项目">{{getReimburseProjectName(row.reimburseProject)}}</table-column>
<table-column label="备注">{{getRemarkText(row)}}</table-column>
<table-column label="申请状态">
<span :class="getStateClass(row.stateId)">{{getStateName(row.stateId)}}</span>
</table-column>
<table-column label="报销项目">{{getReimburseProjectName(row.reimburseProject) || '--'}}</table-column>
<table-column label="" label_suffix="">{{getRemarkText(row) || '--'}}</table-column>
<table-column label="所属工会">{{row.unionName || '--'}}</table-column>
<table-column label="所属单位">{{row.unitName || '--'}}</table-column>
<table-column label="申请时间">{{formatCreateTime(row.createTime) || '--'}}</table-column>
<table-column label="当前节点">{{row.taskName || '--'}}</table-column>
</template>
<template #actions="{index,row}">
<div class="action-btn" @click="onView(row)">
<i class="fa fa-eye"></i>
<van-icon name="eye-o"></van-icon>
<span>查看</span>
</div>
<div class="action-btn" @click="onEdit(row)" v-if="row.stateId == 1 || row.stateId == 5">
<i class="fa fa-edit"></i>
<van-icon name="edit"></van-icon>
<span>编辑</span>
</div>
<div class="action-btn delete" v-if="row.stateId == 2" @click="onRevoke(row)">
<i class="fa fa-undo"></i>
<van-icon name="revoke"></van-icon>
<span>撤回</span>
</div>
<div class="action-btn delete" @click="onDelete(row)" v-if="row.stateId == 1">
<i class="fa fa-trash"></i>
<van-icon name="delete-o"></van-icon>
<span>删除</span>
</div>
</template>
<template #empty>
<div v-if="listLoading" class="union-reimburse-list-skeleton"><div v-for="item in 2" :key="item" class="union-reimburse-skeleton-card"><div class="union-reimburse-skeleton-line union-reimburse-skeleton-line--title"></div><div class="union-reimburse-skeleton-line"></div><div class="union-reimburse-skeleton-line union-reimburse-skeleton-line--short"></div></div></div>
<div v-else class="union-reimburse-empty"><img src="/assets/mobile/img/unionReimburse/union-reimburse-empty.png" alt="暂无报销记录插画"><div class="union-reimburse-empty__title">暂无报销记录</div><div class="union-reimburse-empty__hint">当前筛选条件下暂时没有报销申请</div></div>
</template>
</table-list>
</main>
<union-reimburse-info ref="unionReimburseInfoRef"></union-reimburse-info>
<union-reimburse-info ref="unionReimburseInfoRef" history-layer-name="union-reimburse-mine-info"></union-reimburse-info>
<van-dialog :value="confirmVisible" title="提示" :message="confirmMessage" show-cancel-button :confirm-button-loading="formLoading" @confirm="confirmPendingAction" @cancel="closeConfirm"></van-dialog>
</div>
<script nonce="${cspNonce!}">
@@ -66,13 +68,18 @@ layout("/layouts/platform_h5.html"){
const vue = new Vue({
el: "#app",
store,
dicts: ["UNION_REIMBURSE_PROJECT"],
dicts: ["UNION_REIMBURSE_PROJECT", "PROCESS_INSTANCE_STATE"],
components: {
"union-reimburse-info":UNION_REIMBURSE_INFO
},
data() {
return {
viewShow: false,
listLoading: true,
formLoading: false,
confirmVisible: false,
pendingAction: "",
pendingRow: null,
historyLayerUnsubscribe: null,
yearList: [],
pageForm: {
pageNumber: 1,
@@ -84,6 +91,9 @@ layout("/layouts/platform_h5.html"){
infoShow: false
}
},
computed: {
confirmMessage() { return this.pendingAction === "revoke" ? "您确定要撤销申请吗?" : "您确定要删除吗?" }
},
methods: {
// 手机端列表的报销项目、备注、状态文案与 PC 端 mine 列表保持一致。
getReimburseProjectName(reimburseProject) {
@@ -125,58 +135,34 @@ layout("/layouts/platform_h5.html"){
}
return stateId || ""
},
getStateClass(stateId) {
if (stateId == 3) {
return "state-success"
}
if (stateId == 4) {
return "state-danger"
}
return "state-primary"
getStatusClass(stateId) {
if (stateId == 3) return "union-reimburse-card-header__status--success"
if (stateId == 4 || stateId == 5) return "union-reimburse-card-header__status--danger"
return "union-reimburse-card-header__status--pending"
},
formatCreateTime(value) {
return value && this.$moment(value).isValid() ? this.$moment(value).format("YYYY-MM-DD HH:mm:ss") : ""
},
onView(row) {
this.showApprovalForm = false
this.$refs.unionReimburseInfoRef.onOpen(row)
this.$refs.unionReimburseInfoRef.onOpen(row, "报销申请详情")
},
onEdit(row) {
this.$pjaxReplace('/platform/unionReimburse/apply/h5?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
},
onRevoke(row){
this.$dialog
.confirm({
title: "提示",
message: "您确定要撤销申请吗?"
})
.then(() => {
this.$axios.post("/platform/unionReimburse/mine/revokeTask", {id: row.id}).then((resp) => {
this.$toast.success(resp.msg)
this.doSearch()
})
})
},
onDelete(row) {
this.$dialog
.confirm({
title: "提示",
message: "您确定要删除吗?"
})
.then(() => {
this.$axios.post("/platform/unionReimburse/mine/delete", {id: row.id}).then((resp) => {
if (resp.code === 0) {
this.$toast.success(resp.msg)
this.doSearch()
}
})
})
},
onLoadingChange(state) { this.$set(this, "listLoading", state.loading) },
onNavBack() { const manager = window.h5HistoryLayerManager; if (manager && manager.stack.length) { manager.close(); return } historyBack() },
openConfirm(action, row) { this.$set(this, "pendingAction", action); this.$set(this, "pendingRow", row); const manager = window.h5HistoryLayerManager; if (manager) { manager.open("union-reimburse-mine-confirm"); return } this.$set(this, "confirmVisible", true) },
closeConfirm(afterClose) { const manager = window.h5HistoryLayerManager; if (manager) { manager.close("union-reimburse-mine-confirm", afterClose); return } this.$set(this, "confirmVisible", false); if (afterClose) afterClose() },
confirmPendingAction() { const action = this.pendingAction; const row = this.pendingRow; this.closeConfirm(() => { if (action === "revoke") { this.revoke(row) } else { this.deleteApplication(row) } }) },
onRevoke(row){ this.openConfirm("revoke", row) },
revoke(row) { this.$set(this, "formLoading", true); this.$axios.post("/platform/unionReimburse/mine/revokeTask", {id: row.id}).then((resp) => { if (resp.code === 0) { this.$toast.success(resp.msg); this.doSearch() } else { this.$toast.fail(resp.msg) } }).finally(() => { this.$set(this, "formLoading", false) }) },
onDelete(row) { this.openConfirm("delete", row) },
deleteApplication(row) { this.$set(this, "formLoading", true); this.$axios.post("/platform/unionReimburse/mine/delete", {id: row.id}).then((resp) => { if (resp.code === 0) { this.$toast.success(resp.msg); this.doSearch() } else { this.$toast.fail(resp.msg) } }).finally(() => { this.$set(this, "formLoading", false) }) },
doSearch() {
this.$nextTick(() => {
this.pageForm.pageNumber = 1
this.pageForm.totalCount = 0
this.$set(this.pageForm, "pageNumber", 1)
this.$set(this.pageForm, "totalCount", 0)
this.$refs.tableListRef.doSearch()
})
},
@@ -190,7 +176,13 @@ layout("/layouts/platform_h5.html"){
},
created() {
this.initData()
const manager = window.h5HistoryLayerManager
if (manager) { manager.ensureRegistered("union-reimburse-mine"); this.$set(this, "historyLayerUnsubscribe", manager.subscribe((layers) => { this.$set(this, "confirmVisible", layers.includes("union-reimburse-mine-confirm")) })) }
},
beforeDestroy() {
if (this.historyLayerUnsubscribe) this.historyLayerUnsubscribe()
const manager = window.h5HistoryLayerManager
if (manager) manager.unregister("union-reimburse-mine")
}
})
</script>
@@ -2,100 +2,64 @@
layout("/layouts/platform_h5.html"){
#-->
<style>
.state-primary {
color: #409eff;
}
.state-success {
color: #67c23a;
}
.state-danger {
color: #f56c6c;
}
<style id="style-union-reimburse-h5">
<!--#include('../common/unionReimburse.css'){}#-->
</style>
<div id="app" v-cloak>
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="报销审核" placeholder fixed></van-nav-bar>
<div id="app" v-cloak class="union-reimburse-page">
<van-nav-bar @click-left="onNavBack" left-arrow left-text="返回" title="报销审核" placeholder fixed></van-nav-bar>
<van-sticky offset-top="46px">
<van-search
:reverse-color="false"
:show-action="false"
@search="doSearch"
input-align="left"
placeholder="请输入经办人搜索"
v-model="pageForm.searchKeyword"
></van-search>
<van-tabs v-model="pageForm.approvalText"
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
<van-tab title="已审核" name="1"></van-tab>
<van-tab title="未审核" name="0"></van-tab>
</van-tabs>
<div class="union-reimburse-sticky">
<van-search class="union-reimburse-search" :reverse-color="false" :show-action="false" @search="doSearch" @clear="doSearch" input-align="left" placeholder="请输入姓名或工号搜索" v-model="pageForm.searchKeyword"></van-search>
<van-dropdown-menu class="union-reimburse-filter" :close-on-click-outside="false" :close-on-click-overlay="false">
<van-dropdown-item :options="yearList" @change="doSearch" v-model="pageForm.year"></van-dropdown-item>
<van-dropdown-item :options="reimburseProjectOptions" @change="doSearch" v-model="pageForm.reimburseProject"></van-dropdown-item>
<van-dropdown-item :options="approvalOptions" @change="onApprovalFilterChange" v-model="pageForm.approvalText"></van-dropdown-item>
</van-dropdown-menu>
</div>
</van-sticky>
<table-list api="/platform/unionReimburse/review/pageData" :page_form.sync="pageForm" ref="tableListRef"
@ready="doSearch">
<main class="union-reimburse-list-content">
<table-list api="/platform/unionReimburse/review/pageData" :page_form.sync="pageForm" ref="tableListRef" :show_loading_overlay="false"
@ready="doSearch" @loading-change="onLoadingChange">
<template #header="{row}"><div v-if="row" class="union-reimburse-card-header"><div class="union-reimburse-card-header__heading"><div class="union-reimburse-card-header__title">{{row.userName || '--'}}</div><div class="union-reimburse-card-header__sub">工号:{{row.loginName || '--'}}</div></div><van-tag :class="['union-reimburse-card-header__status', getStatusClass(row.stateId)]">{{getStateName(row.stateId)}}</van-tag></div></template>
<template v-slot="{index,row}">
<table-column label="经办人工号">{{row.loginName}}</table-column>
<table-column label="姓名">{{row.userName}}</table-column>
<table-column label="所属工会">{{row.unionName}}</table-column>
<table-column label="所属单位">{{row.unitName}}</table-column>
<table-column label="申请时间">{{formatCreateTime(row.createTime)}}</table-column>
<table-column label="报销项目">{{getReimburseProjectName(row.reimburseProject)}}</table-column>
<table-column label="备注">{{getRemarkText(row)}}</table-column>
<table-column label="申请状态">
<span :class="getStateClass(row.stateId)">{{getStateName(row.stateId)}}</span>
</table-column>
<table-column label="报销项目">{{getReimburseProjectName(row.reimburseProject) || '--'}}</table-column>
<table-column label="" label_suffix="">{{getRemarkText(row) || '--'}}</table-column>
<table-column label="所属工会">{{row.unionName || '--'}}</table-column>
<table-column label="所属单位">{{row.unitName || '--'}}</table-column>
<table-column label="申请时间">{{formatCreateTime(row.createTime) || '--'}}</table-column>
</template>
<template #actions="{index,row}">
<div class="action-btn" @click="onView(row)">
<i class="fa fa-eye"></i>
<van-icon name="eye-o"></van-icon>
<span>查看</span>
</div>
<div class="action-btn" v-if="row.stateId == 2" @click="onAudit(row)">
<i class="fa fa-edit"></i>
<div class="action-btn review" v-if="row.stateId == 2" @click="onAudit(row)">
<van-icon name="edit"></van-icon>
<span>审核</span>
</div>
</template>
<template #empty><div v-if="listLoading" class="union-reimburse-list-skeleton"><div v-for="item in 2" :key="item" class="union-reimburse-skeleton-card"><div class="union-reimburse-skeleton-line union-reimburse-skeleton-line--title"></div><div class="union-reimburse-skeleton-line"></div><div class="union-reimburse-skeleton-line union-reimburse-skeleton-line--short"></div></div></div><div v-else class="union-reimburse-empty"><img src="/assets/mobile/img/unionReimburse/union-reimburse-empty.png" alt="暂无报销审核记录插画"><div class="union-reimburse-empty__title">暂无报销审核记录</div><div class="union-reimburse-empty__hint">当前筛选条件下暂时没有待办申请</div></div></template>
</table-list>
</main>
<union-reimburse-info ref="unionReimburseInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
校工会审核
</div>
<div class="form-container">
<union-reimburse-info ref="unionReimburseInfoRef" history-layer-name="union-reimburse-review-info">
<template v-if="showApprovalForm">
<section class="union-reimburse-approval-card">
<h2 class="union-reimburse-approval-card__title">{{formData.taskName || '校工会审核'}}</h2>
<van-form ref="formRef">
<van-cell-group title="审批意见">
<van-field label=""
:rules="[{ required: true,message:'请填审批意见' }]"
v-model="formData.reviewOpinion"
required
type="textarea"
name="reviewOpinion"
rows="4"
autosize
class="more-text"
placeholder="请填审批意见"></van-field>
</van-cell-group>
<!-- <van-cell-group title="电子签名" class="form-section">-->
<!-- <van-field class="more-text" name="tf_userSign" label="" required-->
<!-- v-model="formData.reviewOpinion" :rules="[{ required: true,message:'请签名' }]">-->
<!-- <template #input>-->
<!-- <h5-signature v-model="formData.tf_userSign" slot="input"></h5-signature>-->
<!-- </template>-->
<!-- </van-field>-->
<!-- </van-cell-group>-->
<div class="form-actions">
<van-button type="primary" @click="handleTaskAction(3)">同意申请</van-button>
<van-button type="danger" @click="handleTaskAction(4)">拒绝申请</van-button>
<van-button type="danger" @click="handleTaskAction(5)">退回到发起人</van-button>
</div>
<p class="union-reimburse-approval-field-label"><span class="union-reimburse-approval-required">*</span>审批意见</p>
<van-field v-model="formData.reviewOpinion" class="union-reimburse-approval-field" name="reviewOpinion" type="textarea" rows="6" label="" placeholder="请输入审批意见" :rules="[{required: true, message: '请填写审批意见'}]" maxlength="100" show-word-limit></van-field>
</van-form>
</section>
<div class="union-reimburse-approval-actions">
<van-button :loading="formLoading" type="danger" block @click="handleTaskAction(5)">退回</van-button>
<van-button :loading="formLoading" type="danger" block @click="handleTaskAction(4)">不同意</van-button>
<van-button :loading="formLoading" type="primary" block @click="handleTaskAction(3)">同意</van-button>
</div>
</div>
</template>
</union-reimburse-info>
<van-dialog :value="submitConfirmVisible" title="温馨提示" message="您确定要提交审核结果吗?" show-cancel-button :confirm-button-loading="formLoading" @confirm="submitTaskAction" @cancel="closeSubmitConfirm"></van-dialog>
</div>
<script nonce="${cspNonce!}">
@@ -116,11 +80,26 @@ layout("/layouts/platform_h5.html"){
searchKeyword: "",
approvalText: "0",
approval: false,
year: new Date().getFullYear()
year: new Date().getFullYear(),
reimburseProject: ""
},
yearList: [],
reimburseProjectOptions: [
{text: "全部项目", value: ""},
{text: "慰问", value: "UNION_REIMBURSE_PROJECT_1"},
{text: "文体活动", value: "UNION_REIMBURSE_PROJECT_2"},
{text: "日常活动", value: "UNION_REIMBURSE_PROJECT_3"},
{text: "专项活动", value: "UNION_REIMBURSE_PROJECT_4"}
],
approvalOptions: [{text: "未审核", value: "0"}, {text: "已审核", value: "1"}],
formData: {},
showApprovalForm: false,
infoShow: false
infoShow: false,
listLoading: true,
formLoading: false,
submitConfirmVisible: false,
pendingSubmitType: null,
historyLayerUnsubscribe: null
}
},
methods: {
@@ -164,62 +143,63 @@ layout("/layouts/platform_h5.html"){
}
return stateId || ""
},
getStateClass(stateId) {
if (stateId == 3) {
return "state-success"
}
if (stateId == 4) {
return "state-danger"
}
return "state-primary"
},
getStatusClass(stateId) { if (stateId == 3) return "union-reimburse-card-header__status--success"; if (stateId == 4 || stateId == 5) return "union-reimburse-card-header__status--danger"; return "union-reimburse-card-header__status--pending" },
formatCreateTime(value) {
return value && this.$moment(value).isValid() ? this.$moment(value).format("YYYY-MM-DD HH:mm:ss") : ""
},
handleTaskAction(val) {
const opinion = (this.formData.reviewOpinion || "").trim()
if (!opinion) {
this.$toast("请填写审批意见")
this.$refs.formRef.validate("reviewOpinion").catch(() => {})
return
}
this.$set(this.formData, "reviewOpinion", opinion)
this.$refs.formRef.validate().then(() => {
this.$dialog.confirm({
title: "温馨提示",
message: "您确定要提交吗?"
}).then(() => {
this.$axios.post("/platform/unionReimburse/review/reviewTask", {
data: JSON.stringify(Object.assign({}, this.formData)),
submitType: val
}).then(res => {
if (res.code === 0) {
this.$toast.success("提交成功")
this.doSearch()
this.$refs.unionReimburseInfoRef.onClose()
}
})
}).catch(() => {
})
}).catch()
this.$set(this, "pendingSubmitType", val)
const manager = window.h5HistoryLayerManager
if (manager) { manager.open("union-reimburse-review-confirm"); return }
this.$set(this, "submitConfirmVisible", true)
}).catch(() => {})
},
closeSubmitConfirm(afterClose) { const manager = window.h5HistoryLayerManager; if (manager) { manager.close("union-reimburse-review-confirm", afterClose); return } this.$set(this, "submitConfirmVisible", false); if (afterClose) afterClose() },
submitTaskAction() { const submitType = this.pendingSubmitType; this.closeSubmitConfirm(() => { this.$set(this, "formLoading", true); this.$axios.post("/platform/unionReimburse/review/reviewTask", {data: JSON.stringify(Object.assign({}, this.formData)), submitType: submitType}).then((res) => { if (res.code === 0) { this.$toast.success("提交成功"); this.doSearch(); this.$refs.unionReimburseInfoRef.onClose() } else { this.$toast.fail(res.msg) } }).finally(() => { this.$set(this, "formLoading", false) }) }) },
onView(row) {
this.showApprovalForm = false
this.$refs.unionReimburseInfoRef.onOpen(row)
this.$set(this, "showApprovalForm", false)
this.$refs.unionReimburseInfoRef.onOpen(row, "报销申请详情")
},
onAudit(row) {
this.showApprovalForm = true
this.formData = {
this.$set(this, "showApprovalForm", true)
this.$set(this, "formData", {
id: row.id,
reviewOpinion: "通过"
}
this.$refs.unionReimburseInfoRef.onOpen(row)
taskName: "校工会审核",
reviewOpinion: ""
})
this.$refs.unionReimburseInfoRef.onOpen(row, "报销审核")
},
onLoadingChange(state) { this.$set(this, "listLoading", state.loading) },
onNavBack() { const manager = window.h5HistoryLayerManager; if (manager && manager.stack.length) { manager.close(); return } historyBack() },
onApprovalFilterChange(val) { this.$set(this.pageForm, "approval", val === "1"); this.doSearch() },
doSearch() {
this.$nextTick(() => {
this.pageForm.pageNumber = 1
this.pageForm.totalCount = 0
this.$set(this.pageForm, "pageNumber", 1)
this.$set(this.pageForm, "totalCount", 0)
this.$refs.tableListRef.doSearch()
})
}
},
created() {
for (let i = new Date().getFullYear() - 10; i <= new Date().getFullYear(); i++) {
this.yearList.unshift({value: i, text: i + "年"})
}
const manager = window.h5HistoryLayerManager
if (manager) { manager.ensureRegistered("union-reimburse-review"); this.$set(this, "historyLayerUnsubscribe", manager.subscribe((layers) => { this.$set(this, "submitConfirmVisible", layers.includes("union-reimburse-review-confirm")) })) }
},
beforeDestroy() {
if (this.historyLayerUnsubscribe) this.historyLayerUnsubscribe()
const manager = window.h5HistoryLayerManager
if (manager) manager.unregister("union-reimburse-review")
}
})
</script>