手机端社团、工会报销bug整改

This commit is contained in:
2026-09-02 10:39:56 +08:00
parent c84b387765
commit 0b44f36c83
9 changed files with 78 additions and 29 deletions
@@ -218,6 +218,10 @@ public class ClubUserJoinApplyController {
}
ProcessInstance processInstance = dao.fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", userApply.getId()));
// 申请记录存在但没有流程实例时,说明用户仅保存了申请草稿,需提示其先到“我的申请”继续提交。
if (processInstance == null) {
return Result.error(99, "您有该社团的申请记录尚未提交,请到我的申请里查看!");
}
if (!List.of(ProcessInstanceStateEnum.REJECT.getCode(), ProcessInstanceStateEnum.FINISHED.getCode()).contains(processInstance.getState())) {
return Result.error(99, "您有该社团的申请记录尚未完成,请到我的申请里查看!");
}
@@ -128,7 +128,7 @@ layout("/layouts/platform_h5.html"){
<van-field v-model="formData.tf_opinion" class="club-audit-field" name="tf_opinion" type="textarea" rows="6" label="" placeholder="请输入审批意见" :rules="[{ required: true, message: '请填写审批意见' }]" maxlength="100" show-word-limit></van-field>
</van-form>
</section>
<div class="club-audit-actions"><van-button :loading="formLoading" type="danger" block @click="handleTaskAction(6)">退回</van-button><van-button :loading="formLoading" type="danger" block @click="handleTaskAction(2)">不同意</van-button><van-button :loading="formLoading" type="primary" block @click="handleTaskAction(1)">同意</van-button></div>
<div class="club-audit-actions"><van-button :loading="formLoading" type="primary" block @click="handleTaskAction(1)">同意</van-button><van-button :loading="formLoading" type="danger" block @click="handleTaskAction(2)">拒绝</van-button><van-button :loading="formLoading" type="danger" block @click="handleTaskAction(6)">退回</van-button></div>
</template>
</info>
<van-dialog :value="confirmVisible" title="提示" :message="confirmMessage" show-cancel-button :confirm-button-loading="formLoading" @confirm="confirmPendingAction" @cancel="closeConfirm"></van-dialog>
@@ -62,22 +62,48 @@ layout("/layouts/platform_h5.html"){
</template>
</table-list>
</main>
<info ref="infoRef" page-key="club-mineclub" :merge-apply-info="true"></info>
<van-popup v-model="clubDetailVisible" position="right" :style="{ width: '100%', height: '100%' }" get-container="#app" class="club-user-join-popup" :close-on-click-overlay="false">
<div class="club-user-join-detail">
<van-nav-bar title="社团详情" left-text="返回" left-arrow fixed @click-left="closeClubDetail"></van-nav-bar>
<div class="club-user-join-detail__scroll">
<main class="club-user-join-detail__content">
<section class="club-user-join-card club-user-join-info-card">
<h3 class="club-user-join-card__title">社团基础信息</h3>
<van-cell-group :border="false">
<van-cell title="社团名称">{{ clubDetail.clubName || '--' }}</van-cell>
<van-cell title="成立时间">{{ clubDetail.foundTime || '--' }}</van-cell>
<van-cell title="社团编码">{{ clubDetail.clubCode || '--' }}</van-cell>
<van-cell title="社团类型"><dict-tag :options="dict.type.CLUB_REGISTER_TYPE" :value="clubDetail.clubType"></dict-tag></van-cell>
<van-cell title="会长">{{ clubDetail.clubLeader || '--' }}</van-cell>
<van-cell title="秘书长">{{ clubDetail.clubSecretary || '--' }}</van-cell>
<van-cell title="当前人数">{{ clubDetail.currentPeopleNum || 0 }} 人</van-cell>
<van-cell title="会费标准">{{ clubDetail.due || '--' }}</van-cell>
<van-cell title="社团介绍" class="club-user-join-info-long-cell"><div v-if="hasClubContent(clubDetail.introduce)" v-html="clubDetail.introduce"></div><span v-else>暂无</span></van-cell>
<van-cell title="社团宗旨" class="club-user-join-info-long-cell"><div v-if="hasClubContent(clubDetail.purpose)" v-html="clubDetail.purpose"></div><span v-else>暂无</span></van-cell>
<van-cell title="社团章程" class="club-user-join-info-long-cell"><file-preview v-if="clubDetail.rulesFile && clubDetail.rulesFile.length" :files="clubDetail.rulesFile" complete_result></file-preview><span v-else>暂无</span></van-cell>
<van-cell title="年度活动计划" class="club-user-join-info-long-cell"><file-preview v-if="clubDetail.yearPlanFile && clubDetail.yearPlanFile.length" :files="clubDetail.yearPlanFile" complete_result></file-preview><span v-else>暂无</span></van-cell>
</van-cell-group>
</section>
</main>
</div>
</div>
</van-popup>
<van-dialog :value="confirmVisible" title="提示" :message="confirmMessage" show-cancel-button :confirm-button-loading="formLoading" @confirm="confirmExit" @cancel="closeConfirm"></van-dialog>
</div>
<script nonce="${cspNonce!}">
<!--#include('../common/clubUserJoin.js'){}#-->
new Vue({
el: "#app", store, components: {info: clubUserJoin},
data() { return {pageForm: {pageNumber: 1, pageSize: 10, totalCount: 0, clubName: ''}, listLoading: true, formLoading: false, confirmVisible: false, currentRow: null, historyLayerUnsubscribe: null} },
el: "#app", store, dicts: ['CLUB_REGISTER_TYPE'],
data() { return {pageForm: {pageNumber: 1, pageSize: 10, totalCount: 0, clubName: ''}, listLoading: true, formLoading: false, clubDetailVisible: false, clubDetail: {}, confirmVisible: false, currentRow: null, historyLayerUnsubscribe: null} },
computed: { confirmMessage() { return this.currentRow ? '您确定要申请退出“' + this.currentRow.clubName + '”吗?' : '您确定要申请退出该社团吗?'; } },
created() { const manager = window.h5HistoryLayerManager; if (manager) { manager.ensureRegistered('club-mineclub'); this.historyLayerUnsubscribe = manager.subscribe((layers) => { this.$set(this, 'confirmVisible', layers.includes('club-mineclub-confirm')); }); } },
created() { const manager = window.h5HistoryLayerManager; if (manager) { manager.ensureRegistered('club-mineclub'); this.historyLayerUnsubscribe = manager.subscribe((layers) => { this.$set(this, 'clubDetailVisible', layers.includes('club-mineclub-detail')); this.$set(this, 'confirmVisible', layers.includes('club-mineclub-confirm')); }); } },
beforeDestroy() { if (this.historyLayerUnsubscribe) { this.historyLayerUnsubscribe(); } const manager = window.h5HistoryLayerManager; if (manager) { manager.unregister('club-mineclub'); } },
methods: {
onNavBack() { const manager = window.h5HistoryLayerManager; if (manager && manager.stack.length) { manager.close(); return; } historyBack(); },
onLoadingChange(state) { this.$set(this, 'listLoading', state.loading); },
onView(row) { this.$refs.infoRef.onOpen(Object.assign({}, row, {id: row.applyId}), '社团申请详情'); },
onView(row) { this.$set(this, 'clubDetail', Object.assign({}, row || {})); const manager = window.h5HistoryLayerManager; if (manager) { manager.open('club-mineclub-detail'); return; } this.$set(this, 'clubDetailVisible', true); },
closeClubDetail(afterClose) { const manager = window.h5HistoryLayerManager; if (manager) { manager.close('club-mineclub-detail', afterClose); return; } this.$set(this, 'clubDetailVisible', false); if (afterClose) { afterClose(); } },
hasClubContent(value) { return value !== null && value !== undefined && String(value).replace(/<[^>]*>/g, '').replace(/&nbsp;/gi, '').trim().length > 0; },
onExit(row) { this.$set(this, 'currentRow', row); const manager = window.h5HistoryLayerManager; if (manager) { manager.open('club-mineclub-confirm'); return; } this.$set(this, 'confirmVisible', true); },
closeConfirm(afterClose) { const manager = window.h5HistoryLayerManager; if (manager) { manager.close('club-mineclub-confirm', afterClose); return; } this.$set(this, 'confirmVisible', false); if (afterClose) { afterClose(); } },
confirmExit() { const row = this.currentRow; this.closeConfirm(() => { this.$set(this, 'formLoading', true); this.$axios.post('/platform/club/join/apply/submit', {data: JSON.stringify(row), mode: false}).then((res) => { if (res.code === 0) { this.$toast(res.msg); const manager = window.h5HistoryLayerManager; if (manager) { manager.closeAll(() => { this.$pjaxReplace('/platform/club/join/mine/h5'); }); } else { this.$pjaxReplace('/platform/club/join/mine/h5'); } } }).finally(() => { this.$set(this, 'formLoading', false); }); }); },
@@ -805,8 +805,13 @@ layout("/layouts/platform_h5.html"){
</van-popup>
</template>
<van-field class="more-text" name="files" required
label="附件" :rules="[{ required: true, message: '请上传附件' }]">
</van-cell-group>
</section>
<section class="form-section">
<h2 class="form-section__title">附件信息</h2>
<van-cell-group :border="false">
<van-field class="more-text reimburse-upload-field" name="files" required
label="" :rules="[{ required: true, message: '请上传附件' }]">
<template #input>
<h5-file-upload
slot="input"
@@ -1003,7 +1008,7 @@ layout("/layouts/platform_h5.html"){
</div>
</van-form>
</div>
<van-popup v-model:show="invoiceDialogVisible" position="bottom" round :close-on-click-overlay="true" class="invoice-popup">
<van-popup v-model:show="invoiceDialogVisible" position="bottom" round :close-on-click-overlay="true" get-container="#app" class="invoice-popup">
<van-nav-bar :title="invoiceDialogMode === 'edit' ? '编辑发票明细' : '新增发票明细'"
left-text="取消"
left-arrow
@@ -1013,7 +1018,7 @@ layout("/layouts/platform_h5.html"){
<van-loading type="spinner" color="#1677ff" size="24px">发票识别中...</van-loading>
</div>
<van-cell-group class="invoice-popup-card">
<van-field class="more-text" label="发票文件" required>
<van-field class="more-text invoice-popup-file-field" label="发票文件" required>
<template #input>
<h5-file-upload
slot="input"
@@ -143,7 +143,7 @@ layout("/layouts/platform_h5.html"){
return isNaN(amount) ? value : amount.toFixed(2) + "元"
},
onView(row) {
this.$refs.unionReimburseInfoRef.onOpen(row, "报销统计详情")
this.$refs.unionReimburseInfoRef.onOpen(row, "报销详情")
},
onEdit(row) {
this.$pjaxReplace("/platform/unionReimburse/apply/h5?bizId=" + row.id + "&taskId=" + row.startTaskId)
@@ -258,6 +258,15 @@
background: #f7f9fd;
}
/* 附件上传区域与困难帮扶申请页保持一致,避免上传控件被文本域样式包裹。 */
.union-reimburse-form .form-section .reimburse-upload-field .van-field__control {
min-height: 0;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
}
.union-reimburse-form .payment-section,
.union-reimburse-form .invoice-section { padding: 0 0 14px; }
.union-reimburse-form .payment-toolbar,
@@ -388,6 +397,15 @@
border-radius: 10px;
background: #f7f9fd;
}
/* 发票文件只保留上传控件本身,移除报销文本域的边框、背景和内边距。 */
.union-reimburse-form .invoice-popup-card .more-text.invoice-popup-file-field .van-field__control {
min-height: 0;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
}
.union-reimburse-form .invoice-popup-tip {
margin: 10px 0 0;
padding: 9px 11px;
@@ -15,7 +15,7 @@ const UNION_REIMBURSE_INFO = {
</div>
<div class="union-info-row">
<div class="union-info-label">经办人</div>
<div class="union-info-value union-info-link">{{ viewData.userName }}</div>
<div class="union-info-value">{{ viewData.userName }}</div>
</div>
<div class="union-info-row">
<div class="union-info-label">联系方式</div>
@@ -186,7 +186,7 @@ const UNION_REIMBURSE_INFO = {
<div class="union-info-section-title">活动信息</div>
<div class="union-info-row">
<div class="union-info-label">活动名称</div>
<div class="union-info-value union-info-link">{{ viewData.activityName }}</div>
<div class="union-info-value">{{ viewData.activityName }}</div>
</div>
<div class="union-info-row">
<div class="union-info-label">活动人数</div>
@@ -346,17 +346,6 @@ 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
@@ -386,12 +375,19 @@ const UNION_REIMBURSE_INFO = {
onOpen(row, title) {
this.$set(this, "row", row)
this.$set(this, "detailTitle", title || "报销详情")
this.$set(this, "visible", true)
this.$set(this, "currentPaymentIndex", 0)
// 详情弹层的显示状态由全局历史栈统一同步,确保系统返回键与页面返回按钮关闭同一层。
const manager = window.h5HistoryLayerManager
if (manager && manager.open(this.historyLayerName)) {
this.getInfo()
this.getDoneTasks()
return
}
this.$set(this, "visible", true)
this.getInfo()
this.getDoneTasks()
},
// 由全局历史栈关闭详情,保证遮罩、关闭按钮和浏览器返回键遵循同一顺序
// 只关闭当前详情对应的历史层,避免误关闭审核确认弹框等上层业务弹框
onClose() {
const manager = window.h5HistoryLayerManager
if (manager && manager.close(this.historyLayerName)) return
@@ -144,7 +144,7 @@ layout("/layouts/platform_h5.html"){
return value && this.$moment(value).isValid() ? this.$moment(value).format("YYYY-MM-DD HH:mm:ss") : ""
},
onView(row) {
this.$refs.unionReimburseInfoRef.onOpen(row, "报销申请详情")
this.$refs.unionReimburseInfoRef.onOpen(row, "报销详情")
},
onEdit(row) {
this.$pjaxReplace('/platform/unionReimburse/apply/h5?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
@@ -166,7 +166,7 @@ layout("/layouts/platform_h5.html"){
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.$set(this, "showApprovalForm", false)
this.$refs.unionReimburseInfoRef.onOpen(row, "报销申请详情")
this.$refs.unionReimburseInfoRef.onOpen(row, "报销详情")
},
onAudit(row) {
this.$set(this, "showApprovalForm", true)