feat: 慰问、困难帮扶

This commit is contained in:
2026-10-30 17:49:45 +08:00
parent 16cae3ed2b
commit f8457386fd
22 changed files with 207 additions and 290 deletions
@@ -0,0 +1,98 @@
<template>
<div class="h5-user-select">
<van-field v-bind="$attrs" :value="displayName" readonly clickable is-link @click="open"></van-field>
<van-popup v-model="visible" position="bottom" round get-container="body" class="h5-user-select-popup">
<div class="h5-user-select-popup__header">
<van-button native-type="button" type="default" size="small" @click="visible = false">取消</van-button>
<strong>选择慰问对象</strong>
<van-button native-type="button" type="info" size="small" :disabled="!pendingUser" @click="confirm">确认</van-button>
</div>
<van-search v-model="keyword" placeholder="请输入姓名或工号查询" @input="scheduleSearch" @search="search" @clear="search"></van-search>
<div class="h5-user-select-popup__list">
<div v-if="loading" class="h5-user-select-popup__status"><van-loading size="24px">加载中</van-loading></div>
<div v-else-if="error" class="h5-user-select-popup__status"><span class="h5-user-select-popup__error">{{ error }}</span><van-button native-type="button" size="small" @click="search">重新加载</van-button></div>
<van-empty v-else-if="!options.length" description="未找到本工会人员"></van-empty>
<template v-else>
<van-cell v-for="person in options" :key="person.id" clickable
:class="{ 'h5-user-select-popup__selected': pendingUser && pendingUser.id === person.id }"
:title="person.userName + (person.loginName ? '(' + person.loginName + ')' : '')"
:label="[person.unitName, person.personType].filter(Boolean).join(' · ')"
@click="pendingUser = person">
<van-icon v-if="pendingUser && pendingUser.id === person.id" name="success" color="#1989fa"></van-icon>
</van-cell>
</template>
</div>
</van-popup>
</div>
</template>
<script>
module.exports = {
inheritAttrs: false,
model: { prop: 'value', event: 'change' },
props: {
value: { type: String, default: '' },
displayName: { type: String, default: '' },
api: { type: String, required: true }
},
data() {
return { visible: false, keyword: '', options: [], pendingUser: null, loading: false, error: '', searchTimer: null, requestId: 0 }
},
beforeDestroy() {
clearTimeout(this.searchTimer)
this.requestId++
},
methods: {
open() {
this.keyword = ''
this.pendingUser = null
this.visible = true
this.search()
},
scheduleSearch() {
clearTimeout(this.searchTimer)
this.requestId++
this.pendingUser = null
this.loading = true
this.searchTimer = setTimeout(() => this.search(), 250)
},
async search() {
clearTimeout(this.searchTimer)
const requestId = ++this.requestId
this.loading = true
this.error = ''
this.pendingUser = null
try {
const result = await this.$axios.post(this.api, { keyword: this.keyword })
if (requestId !== this.requestId) return
if (result.code !== 0) throw new Error(result.msg || '人员加载失败')
this.options = result.data || []
} catch (error) {
if (requestId !== this.requestId) return
this.options = []
this.error = error.message || '人员加载失败'
} finally {
if (requestId === this.requestId) this.loading = false
}
},
confirm() {
if (!this.pendingUser) return
const person = this.pendingUser
this.$emit('change', person.id)
this.$emit('selected', person, person.id)
this.visible = false
}
}
}
</script>
<style>
.h5-user-select-popup { display: flex; flex-direction: column; height: 72vh; max-height: 640px; padding-bottom: env(safe-area-inset-bottom); box-sizing: border-box; }
.h5-user-select-popup__header { display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; padding: 14px 16px; border-bottom: 1px solid #ebedf0; }
.h5-user-select-popup__header strong { font-size: 16px; color: #323233; }
.h5-user-select-popup__header .van-button { min-width: 56px; }
.h5-user-select-popup__list { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.h5-user-select-popup__selected { background: #edf6ff; }
.h5-user-select-popup__status { display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 12px; padding: 40px 16px; }
.h5-user-select-popup__error { color: #ee0a24; }
</style>
@@ -106,7 +106,9 @@ module.exports = {
}
},
onChange(val) {
const selected = this.options.find(item => String(item[this.option_value]) === String(val)) || null
this.$emit("change", val)
this.$emit("selected", selected, val)
},
clearOptions() {
@@ -114,7 +116,7 @@ module.exports = {
}
},
created() {
this.clearOptions()
this.options = this.option_list || []
console.log(this.placeholder)
}
}