Files
UNION_NSI/target/classes/views/mobile/condolence/apply.html
T
2026-09-08 19:49:21 +08:00

517 lines
24 KiB
HTML

<!--#
layout("/mobile/platform.html"){
#-->
<div id="app" v-cloak>
<van-nav-bar title="填写慰问申请" left-arrow placeholder fixed
@click-left="history.back()"></van-nav-bar>
<van-form ref="addForm" :show-error-message="false" input-align="right">
<van-cell-group inset class="mt10">
<van-field readonly value="${@shiro.getPrincipalProperty('username')}" name="manager_name"
label="申请人"></van-field>
<van-field readonly :value="formData.apply_time" name="apply_time"
label="申请时间"
></van-field>
<van-field @input="userRemoteMethod" name="be_user_name"
required
v-model="formData.be_user_name" label="慰问对象" placeholder="请输入慰问对象"
:rules="[{ required: true, message: '请填写慰问对象' }]"></van-field>
<van-field v-model="formData.mobile" name="mobile" type="tel"
label="联系电话" placeholder="输入慰问对象后自动获取" maxlength="11" required
:rules="[{ required: true, message: '请输入慰问对象联系电话' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' }]"></van-field>
<van-action-sheet v-model="sheetShow"
:actions="userList"
cancel-text="重新输入姓名或工号查询"
@cancel="userList = [];formData.be_user_name=null;"
:close-on-click-overlay="false"
@select="onUserSelect">
</van-action-sheet>
<van-field @input="payeeUserRemoteMethod" name="payee_name"
required
v-model="formData.payee_name" label="收款人" placeholder="请输入收款人"
:rules="[{ required: true, message: '请填写收款人' }]"></van-field>
<van-action-sheet v-model="payeeSheetShow"
:actions="payeeUserList"
cancel-text="重新输入姓名或工号查询"
@cancel="payeeOnCancel"
:close-on-click-overlay="false"
@select="payeeOnUserSelect">
</van-action-sheet>
<van-field v-model="formData.payee_bank_number" name="payee_bank_number" type="number"
label="收款人银行卡" placeholder="请输入收款人银行卡" required
:rules="[{ required: true, message: '请输入收款人银行卡' }]"></van-field>
<van-field v-model="formData.payee_bank_name" name="payee_bank_name"
label="收款人开户行" placeholder="请输入收款人开户行" required
:rules="[{ required: true, message: '请输入收款人开户行' }]"></van-field>
<van-field readonly clickable name="type" :value="formData.typeName"
required
label="慰问类型"
@click="showTypePicker = true" placeholder="点击选择慰问类型"
:rules="[{ required:true, message: '请选择慰问类型'}]"></van-field>
<van-popup v-model:show="showTypePicker" position="bottom" round>
<van-picker show-toolbar :columns="typeColumns" @confirm="onTypeConfirm"
@cancel="showTypePicker = false">
</van-picker>
</van-popup>
<van-field readonly clickable name="way" :value="formData.wayName"
label="慰问方式"
required
placeholder="点击选择慰问方式"
:rules="[{ required:true, message: '请选择慰问方式'}]"></van-field>
<van-popup v-model:show="showWayPicker" position="bottom" round>
<van-picker show-toolbar :columns="wayColumns" @confirm="onWayConfirm"
@cancel="showWayPicker = false">
</van-picker>
</van-popup>
<van-field v-model="formData.money" name="money" type="number" label="慰问金额" readonly
placeholder="选择慰问类型自动匹配金额"
:rules="[{ required:true, message: '请填写慰问金额' }]"></van-field>
<van-field
required
:rules="[{ required:true, message: '请填写慰问时间' }]"
readonly
clickable
name="occur_time"
:value="formData.occur_time"
label="慰问时间"
placeholder="点击选择慰问时间"
@click="showOccurTime = true"
></van-field>
<van-calendar v-model="showOccurTime"
@confirm="onOccurTimeConfirm"
:min-date="minDate"
:max-date="maxDate"
:color="themeColor"></van-calendar>
<van-field v-if="formData.way === '慰问品 (C)'"
v-model="formData.goods_desc" name="goods_desc" label="慰问品"
placeholder="请输入选择的慰问品的名称、编号、规格等" required
:rules="[{ required:true, message: '请输入慰问品名称、编号、规格等' }]">
<template #button>
<van-button size="small" type="primary" @click.stop="previewGoodsAlbum">预览</van-button>
</template>
</van-field>
<!--生育(孩次),与 PC 端保持相同的类型显示逻辑。-->
<van-field v-if="formData.type === '29cf78eea88d40128f639b9ae7b6aaaa'"
readonly clickable required
:value="formData.birth_child_num"
name="birth_child_num" label="孩次"
placeholder="请选择孩次"
@click="showChildPicker = true"
:rules="[{ required:true, message: '请选择孩次' }]">
</van-field>
<van-popup v-model:show="showChildPicker" position="bottom" round>
<van-picker show-toolbar :columns="childColumns" @confirm="onChildConfirm"
@cancel="showChildPicker = false">
</van-picker>
</van-popup>
<template
v-if="['c7175af55693441e8233be4552cef9d5','0872ea0b95aa463fb8d98c46bdf72537'].includes(formData.type)">
<van-field :value="formData.hospital_stay"
readonly clickable required
@click="hospital_stay = true"
name="hospital_stay" label="住院时间"
placeholder="请选择住院时间"
:rules="[{ required:true, message: '请选择住院时间' }]"></van-field>
<van-calendar v-model="hospital_stay" type="range" @confirm="onConfirm"
:min-date="new Date('1999-01-01')"
:color="themeColor"></van-calendar>
<van-field v-model="formData.the_hospital" name="the_hospital" name="type" label="所在医院"
placeholder="请填写所在医院" required
:rules="[{ required:true, message: '请填写所在医院' }]"></van-field>
</template>
<van-field v-if="['0872ea0b95aa463fb8d98c46bdf72537'].includes(formData.type)"
v-model="formData.inpatientSurgicalName"
name="inpatientSurgicalName" label="手术名称"
placeholder="请填写手术名称"
required
:rules="[{ required:true, message: '请填写手术名称' }]">
</van-field>
<!--直系亲属去世-->
<van-field v-if="['925020dd63754aaea985c5672982a7f4'].includes(formData.type)"
v-model="formData.deadImmediateFamily"
name="deadImmediateFamily" label="直系亲属"
placeholder="配偶、父亲、母亲、子女"
required
:rules="[{ required:true, message: '请填写直系亲属' }]">
</van-field>
<van-field v-model="formData.remark" name="remark" label="申请事由" style="flex-flow: column"
required
:rules="[{ required:true, message: '请填写申请事由' }]"
placeholder="请填写申请事由"
input-align="left"
rows="3" maxlength="200" type="textarea" show-word-limit autosize>
<template #label>
<div class="mb10">申请事由</div>
</template>
</van-field>
</van-cell-group>
<van-cell-group inset class="mt10">
<van-field name="files" label="附&emsp;&emsp;件" required
style="flex-flow: column" input-align="left">
<template #label>
<div class="mb10">&emsp;&emsp;</div>
</template>
<template #input>
<vant-file-upload :files.sync="formData.files"></vant-file-upload>
<div v-if="uploadFileDesc" class="text-danger" style="color: #da3e16;">上传附件说明:{{uploadFileDesc}}</div>
</template>
</van-field>
</van-cell-group>
<van-cell-group inset class="mt10">
<van-field label="签字" required style="flex-flow: column">
<template #label>
<div class="mb10">&emsp;&emsp;</div>
</template>
<template #input>
<mobile-sign ref="signature" :my_sign.sync="formData.sign"></mobile-sign>
</template>
</van-field>
</van-cell-group>
<div style="display: flex; gap: 10px; margin: 20px 20px 10px 20px">
<van-button @click="saveDraft()" style="border-radius: 10px; flex: 1" block plain type="primary"
:color="themeColor" text="保存"></van-button>
<van-button @click="onSubmit()" style="border-radius: 10px; flex: 1" block type="info"
:color="themeColor">
提交
</van-button>
</div>
</van-form>
</div>
<script>
var vue = new Vue({
el: '#app',
mixins: [mobileMixins],
data() {
return {
goods: [],
payeeSheetShow: false,
payeeUserList: [],
hospital_stay: false,
userList: [],
formData: {
mobile: '',
goodsAlbum: [],
goods_desc: ''
},
showTypePicker: false,
showWayPicker: false,
showChildPicker: false,
sheetShow: false,
typeColumns: [],
wayColumns: [],
childColumns: [
{value: '一孩', text: '一孩'},
{value: '二孩', text: '二孩'},
{value: '三孩', text: '三孩'}
],
files: [],
showOccurTime: false,
// minDate: moment().subtract(5, 'year')._d,
minDate: new Date(2010, 1, 1),
maxDate: new Date(),
money: 0,
uploadFileDesc: '',
editId: ''
}
},
watch: {
"formData.money"(val) {
if (val > this.money) {
this.$notify({
title: '警告',
message: '金额超过规定金额' + this.money + "(元)",
type: 'warning'
});
this.$set(this.formData, "money", this.money)
}
}
},
components: {
'mobile-sign': httpVueLoader('/components/sign/mobileSign.vue?v=' + new Date().getTime()),
},
methods: {
priceInput() {
let num = 0
this.goods.forEach(v => {
num += parseFloat(v.price)
})
this.$set(this.formData, "money", num)
},
onOccurTimeConfirm(val) {
this.$set(this.formData, "occur_time", moment(val).format("YYYY-MM-DD"))
this.showOccurTime = false
},
onConfirm(date) {
const [start, end] = date;
this.hospital_stay = false;
this.formData.hospital_stay = moment(start).format('YYYY-MM-DD') + "-" + moment(end).format('YYYY-MM-DD');
this.$set(this.formData, "hospital_stay_1", moment(start).format('YYYY-MM-DD'))
this.$set(this.formData, "hospital_stay_2", moment(end).format('YYYY-MM-DD'))
},
async userRemoteMethod(event) {
if (event) {
const arr = await this.queryUser(event)
this.userList = arr.map(v => {
return {
name: v.username + "(" + v.loginname + ")", id: v.id
}
})
this.sheetShow = true
}
},
async payeeUserRemoteMethod(event) {
if (event) {
const arr = await this.queryUser(event)
this.payeeUserList = arr.map(v => {
return {
name: v.username + "(" + v.loginname + ")", id: v.id
}
})
this.payeeSheetShow = true
}
},
async queryUser(query) {
const {data} = await $.get("/platform/fw/condolence/apply/queryUser", {query})
return data
},
// 选择慰问对象后读取其联系电话,避免提交时使用申请人的手机号。
async getUserData(userId) {
if (!userId) {
return {}
}
const {data} = await $.get("/platform/fw/condolence/apply/getUserData", {userId})
return data || {}
},
async onUserSelect(u) {
this.$set(this.formData, 'be_user', u.id)
this.$set(this.formData, 'be_user_name', u.name)
const userData = await this.getUserData(u.id)
this.$set(this.formData, 'mobile', userData.mobile || '')
this.sheetShow = false
},
payeeOnCancel(){
if (!this.formData.payee){
this.$set(this.formData, 'payee_name', '')
}
this.payeeUserList = []
},
payeeOnUserSelect(u) {
this.$set(this.formData, 'payee', u.id)
this.$set(this.formData, 'payee_name', u.name)
this.payeeSheetShow = false
},
async onTypeConfirm(val) {
this.$set(this.formData, "typeName", val.text)
this.$set(this.formData, "type", val.value)
const {data, code, msg} = await $.get("/platform/condolence/type/findOne", {id: val.value})
this.$set(this, "money", data.money)
await this.moneyChange(val.value)
this.showTypePicker = false;
},
onWayConfirm(val) {
this.$set(this.formData, "wayName", val.text)
this.$set(this.formData, "way", val.value)
this.showWayPicker = false;
},
onChildConfirm(val) {
this.$set(this.formData, "birth_child_num", val.value)
this.showChildPicker = false
},
async moneyChange(id) {
const {data, code, msg} = await $.get("/platform/condolence/type/findOne", {id})
if (data) {
// 编辑回填时先同步金额上限,避免金额监听器因上限仍为 0 将金额重置为 0。
this.$set(this, "money", data.money)
this.$set(this.formData, "money", data.money)
this.$set(this.formData, "wayName", data.way)
this.$set(this.formData, "way", data.way)
this.$set(this.formData, "goodsAlbum", data.goodsAlbum || [])
this.$set(this, "uploadFileDesc", data.uploadFileDesc || '')
}
},
// 预览慰问品画册,未配置 PDF 时给出明确提示。
previewGoodsAlbum() {
const goodsAlbum = this.formData.goodsAlbum
if (!goodsAlbum || !goodsAlbum.length) {
vant.Toast('暂无慰问品画册')
return
}
const pdfStreamUrl = encodeURIComponent(FILE_STREAM_PREVIEW_ADDRESS + '?id=' + goodsAlbum[0].id)
window.location.href = '/mobile/condolence/apply/preview?file=' + pdfStreamUrl
},
async loadEditData(id) {
const resp = await $.get('/platform/fw/condolence/findOne', {id: id})
if (!resp.data) {
this.$toast.fail('获取申请信息失败')
return
}
const data = resp.data
condolence.toFormData(data)
this.$set(data, 'typeName', data.typename)
this.$set(data, 'wayName', data.way)
this.$set(data, 'be_user_name', data.be_username)
this.$set(data, 'payee_name', data.payee_username)
// 编辑时回填当前申请保存的签字图片,交由签字组件导入画布。
this.$set(data, 'sign', data.manager_sign_data || '')
this.$set(data, 'goods', data.Goods || data.goods || [])
if (data.starting_time && data.end_time) {
this.$set(data, 'hospital_stay', data.starting_time + '-' + data.end_time)
this.$set(data, 'hospital_stay_1', data.starting_time)
this.$set(data, 'hospital_stay_2', data.end_time)
}
// 先设置金额上限,再回填表单,避免金额监听器使用初始值 0 校验编辑数据。
const typeResp = await $.get('/platform/condolence/type/findOne', {id: data.type})
if (typeResp.data) {
this.$set(this, 'money', typeResp.data.money)
}
this.$set(this, 'formData', data)
this.$set(this, 'goods', data.goods || [])
this.$set(this, 'editId', id)
await this.moneyChange(data.type)
// 编辑数据和签字画布均为异步初始化,下一次渲染后再次导入原申请签字,确保画布完成回显。
if (data.manager_sign_data) {
this.$nextTick(() => {
if (this.$refs.signature) {
this.$refs.signature.importSign(data.manager_sign_data)
}
})
}
},
async onSubmit() {
if (!this.formData.files) {
vant.Toast('请上传附件材料!')
return
}
// 签字组件不是 Vant 原生表单控件,提交前单独校验画布,避免空签字绕过表单校验。
if (this.$refs.signature.checkNull()) {
this.$toast.fail('请签字!')
return
}
this.$refs.signature.submitSign()
/* if (this.$refs.signature.checkNull()) {
vant.Toast('请签名!')
return
}*/
await this.$refs.signature.updateSign()
const formData = clone(this.formData)
formData.files = JSON.stringify(formData.files)
formData.goods = this.goods
this.$refs['addForm'].validate().then(async () => {
this.$toast.loading('提交中...')
const url = this.editId ? '/platform/fw/condolence/apply/doEdit' : '/platform/fw/condolence/apply/doAdd'
const res = await $.post(url, {
data: JSON.stringify(formData),
sign: formData.sign,
hospital_stay_1: formData.hospital_stay_1,
hospital_stay_2: formData.hospital_stay_2
})
if (res.code === 0) {
this.$toast.success(this.editId ? '修改成功' : '申请成功');
setTimeout(() => {
location.replace('/mobile/condolence/apply')
}, 1000)
} else {
this.$toast.fail('申请失败');
}
})
},
async saveDraft() {
// 保存草稿前先读取当前画布签字,否则签字只停留在画布中,不会写入申请数据。
if (this.$refs.signature) {
this.$refs.signature.submitSign()
}
const formData = clone(this.formData)
formData.files = JSON.stringify(formData.files || [])
formData.goods = this.goods
this.$toast.loading({message: '保存中...', forbidClick: true})
const res = await $.post('/platform/fw/condolence/apply/doSave', {
data: JSON.stringify(formData),
sign: formData.sign || '',
hospital_stay_1: formData.hospital_stay_1,
hospital_stay_2: formData.hospital_stay_2
})
if (res.code === 0) {
this.$toast.success('保存成功')
setTimeout(() => {
location.replace('/mobile/condolence/apply')
}, 1000)
} else {
this.$toast.fail(res.msg || '保存失败')
}
},
},
mounted() {
this.$nextTick(() => {
// 新增申请加载用户默认签字,编辑申请由详情数据回填原申请签字。
if (this.$refs.signature && !GetQueryString('id')) {
this.$refs.signature.getMySign()
}
})
},
async created() {
const {code, data} = await $.get("/platform/condolence/type/getAll")
data.forEach(v => {
this.typeColumns.push({value: v.id, text: v.name + "(" + v.code + ")"})
})
for (let i in condolence.way) {
this.wayColumns.push({value: condolence.way[i], text: condolence.way[i]})
}
const id = GetQueryString('id')
if (id) {
await this.loadEditData(id)
} else {
this.$set(this.formData, 'apply_time', moment().format('YYYY-MM-DD'))
}
}
})
</script>
<style>
.up_down > .van-cell {
flex-flow: column;
}
.up_down > .van-cell > .van-field__label {
width: 100%;
}
.van-cell, .van-picker button, .submit .van-button--normal {
font-size: 16px;
}
.van-divider {
margin: 10px 0;
}
</style>
<!--#
}
#-->