Files
zhgh_cqgmy/src/main/resources/static/components/plugins/sysUserSelect/h5Index.vue
T
2026-10-30 17:49:45 +08:00

99 lines
4.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>