254 lines
9.4 KiB
Vue
254 lines
9.4 KiB
Vue
<template>
|
||
<view class="page" :class="{ big: isH5 }">
|
||
<view class="card">
|
||
<view class="card-title">查询</view>
|
||
<view class="field">
|
||
<input class="input" v-model="keyword" placeholder="请输入姓名 / 编号" />
|
||
</view>
|
||
<button class="btn primary" :disabled="loading" @click="onSearch">查询</button>
|
||
<view class="btn-row">
|
||
<button class="btn ghost" :disabled="!selectedUserId" @click="goUserTags">标签管理</button>
|
||
<button class="btn ghost" :disabled="!selectedUserId" @click="goCompare">历史对比</button>
|
||
</view>
|
||
<view v-if="errorMsg" class="error">{{ errorMsg }}</view>
|
||
</view>
|
||
|
||
<view class="card">
|
||
<view class="card-title">概览</view>
|
||
<view class="kv">
|
||
<view class="kv-item"><text class="k">姓名</text><text class="v">{{ summary.userName || summary.nickName || '—' }}</text></view>
|
||
<view class="kv-item"><text class="k">部门</text><text class="v">{{ summary.deptName || '—' }}</text></view>
|
||
<view class="kv-item"><text class="k">监区</text><text class="v">{{ summary.prisonAreaName || '—' }}</text></view>
|
||
<view class="kv-item"><text class="k">测评数</text><text class="v">{{ summary.totalAssessments || 0 }}</text></view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="card">
|
||
<view class="card-title">量表记录</view>
|
||
<view v-if="loading" class="empty">加载中...</view>
|
||
<view v-else>
|
||
<view v-if="(summary.scales || []).length === 0" class="empty">暂无数据</view>
|
||
<view v-else class="list">
|
||
<view class="item" v-for="(s, idx) in summary.scales" :key="idx" @click="openScaleReport(s)">
|
||
<view class="item-head">
|
||
<view class="item-title">{{ s.scaleName || ('量表#' + s.scaleId) }}</view>
|
||
<view class="pill">{{ s.latestReportStatus || '—' }}</view>
|
||
</view>
|
||
<view class="item-grid">
|
||
<view class="item-desc">次数:{{ (s.attempts || []).length }}</view>
|
||
<view class="item-desc">最近:{{ formatTime(s.latestSubmitTime) }}</view>
|
||
<view class="item-desc">分数:{{ s.latestTotalScore == null ? '—' : s.latestTotalScore }}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { getStudentOptions, getUserAssessmentSummary } from '../../api/psychology/assessment'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
isH5: false,
|
||
keyword: '',
|
||
loading: false,
|
||
errorMsg: '',
|
||
selectedUserId: null,
|
||
summary: {
|
||
scales: []
|
||
}
|
||
}
|
||
},
|
||
onLoad(query) {
|
||
try {
|
||
const info = uni.getSystemInfoSync()
|
||
this.isH5 = info && info.uniPlatform === 'web'
|
||
} catch (e) {
|
||
this.isH5 = false
|
||
}
|
||
const keyword = query && query.keyword ? String(query.keyword) : ''
|
||
if (keyword) {
|
||
this.keyword = keyword
|
||
}
|
||
const userId = query && query.userId ? query.userId : null
|
||
if (userId) {
|
||
this.selectedUserId = userId
|
||
this.fetchSummary(userId)
|
||
return
|
||
}
|
||
if (keyword) {
|
||
this.onSearch()
|
||
}
|
||
},
|
||
methods: {
|
||
openScaleReport(scale) {
|
||
if (!scale) return
|
||
const attempts = Array.isArray(scale.attempts) ? scale.attempts.slice() : []
|
||
attempts.sort((a, b) => {
|
||
const ta = a && (a.submitTime || a.startTime) ? new Date(a.submitTime || a.startTime).getTime() : 0
|
||
const tb = b && (b.submitTime || b.startTime) ? new Date(b.submitTime || b.startTime).getTime() : 0
|
||
return tb - ta
|
||
})
|
||
const withReport = attempts.find((a) => a && a.reportId)
|
||
if (!withReport || !withReport.reportId) {
|
||
uni.showToast({ title: '暂无可用报告', icon: 'none' })
|
||
return
|
||
}
|
||
uni.navigateTo({
|
||
url: `/pages/report/detail?reportId=${encodeURIComponent(withReport.reportId)}&sourceType=assessment`
|
||
})
|
||
},
|
||
fetchSummary(userId) {
|
||
if (!userId) return
|
||
this.errorMsg = ''
|
||
this.loading = true
|
||
this.summary = { scales: [] }
|
||
return getUserAssessmentSummary(userId)
|
||
.then((res) => {
|
||
this.loading = false
|
||
const data = res && res.data ? res.data : null
|
||
if (!data || data.code !== 200) {
|
||
this.errorMsg = (data && data.msg) ? data.msg : '获取画像失败'
|
||
return
|
||
}
|
||
this.summary = data.data || { scales: [] }
|
||
})
|
||
.catch((e) => {
|
||
this.loading = false
|
||
this.errorMsg = e && e.message ? e.message : '网络错误'
|
||
})
|
||
},
|
||
goUserTags() {
|
||
if (!this.selectedUserId) return
|
||
uni.navigateTo({ url: `/pages/profile/tags?userId=${encodeURIComponent(this.selectedUserId)}` })
|
||
},
|
||
goCompare() {
|
||
if (!this.selectedUserId) return
|
||
uni.navigateTo({ url: `/pages/profile/compare?userId=${encodeURIComponent(this.selectedUserId)}` })
|
||
},
|
||
formatTime(val) {
|
||
if (!val) return '—'
|
||
try {
|
||
const d = new Date(val)
|
||
if (isNaN(d.getTime())) return '—'
|
||
const y = d.getFullYear()
|
||
const m = String(d.getMonth() + 1).padStart(2, '0')
|
||
const day = String(d.getDate()).padStart(2, '0')
|
||
const hh = String(d.getHours()).padStart(2, '0')
|
||
const mm = String(d.getMinutes()).padStart(2, '0')
|
||
return `${y}-${m}-${day} ${hh}:${mm}`
|
||
} catch (e) {
|
||
return '—'
|
||
}
|
||
},
|
||
onSearch() {
|
||
this.errorMsg = ''
|
||
this.loading = true
|
||
this.summary = { scales: [] }
|
||
this.selectedUserId = null
|
||
|
||
getStudentOptions({ keyword: this.keyword || '', limit: 1 }).then((res) => {
|
||
const data = res && res.data ? res.data : null
|
||
if (!data || data.code !== 200) {
|
||
this.loading = false
|
||
this.errorMsg = (data && data.msg) ? data.msg : '查询失败'
|
||
return
|
||
}
|
||
const list = data.data || []
|
||
if (list.length === 0) {
|
||
this.loading = false
|
||
this.errorMsg = '未找到匹配人员'
|
||
return
|
||
}
|
||
this.selectedUserId = list[0].userId
|
||
this.fetchSummary(this.selectedUserId)
|
||
}).catch((e) => {
|
||
this.loading = false
|
||
this.errorMsg = e && e.message ? e.message : '网络错误'
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.page { min-height: 100vh; padding: 24rpx 24rpx 120rpx; box-sizing: border-box; background: #F4F6FB; }
|
||
|
||
.card { background: rgba(255, 255, 255, 0.95); border-radius: 18rpx; padding: 24rpx; border: 1px solid rgba(15, 23, 42, 0.06); margin-bottom: 18rpx; box-shadow: 0 10rpx 22rpx rgba(15, 23, 42, 0.05); }
|
||
.card-title { font-size: 28rpx; font-weight: 700; color: #111827; margin-bottom: 14rpx; }
|
||
|
||
.field { margin-bottom: 12rpx; }
|
||
.input { width: 100%; background: rgba(15, 23, 42, 0.04); border-radius: 16rpx; padding: 22rpx 20rpx; font-size: 28rpx; box-sizing: border-box; border: 1px solid rgba(15,23,42,0.06); min-height: 92rpx; line-height: 92rpx; }
|
||
|
||
.btn { width: 100%; height: 84rpx; line-height: 84rpx; border-radius: 18rpx; font-size: 28rpx; }
|
||
.btn.primary { background: #1677ff; color: #FFFFFF; }
|
||
.btn.ghost { background: #FFFFFF; color: #1F2937; border: 1px solid rgba(17,24,39,0.12); }
|
||
.btn-row { display: flex; justify-content: space-between; margin-top: 14rpx; }
|
||
.btn-row .btn { width: 48%; height: 78rpx; line-height: 78rpx; }
|
||
|
||
.kv-item { display: flex; justify-content: space-between; padding: 12rpx 0; border-bottom: 1px solid rgba(15, 23, 42, 0.06); }
|
||
.kv-item:last-child { border-bottom: 0; }
|
||
.k { color: #6B7280; font-size: 24rpx; }
|
||
.v { color: #111827; font-size: 24rpx; font-weight: 700; }
|
||
|
||
.list { margin-top: 8rpx; }
|
||
.item { background: #FFFFFF; border-radius: 20rpx; padding: 22rpx; border: 1px solid rgba(15, 23, 42, 0.06); margin-bottom: 18rpx; }
|
||
.item-head { display: flex; justify-content: space-between; align-items: center; }
|
||
.item-title { font-size: 28rpx; font-weight: 700; color: #111827; }
|
||
.pill { padding: 8rpx 14rpx; border-radius: 999rpx; font-size: 22rpx; color: #2B6BFF; background: rgba(43, 107, 255, 0.12); }
|
||
.item-grid { margin-top: 10rpx; display: flex; flex-wrap: wrap; justify-content: space-between; }
|
||
.item-desc { width: 48%; margin-top: 8rpx; font-size: 24rpx; color: #4B5563; }
|
||
|
||
.empty { height: 200rpx; border-radius: 20rpx; background: rgba(255, 255, 255, 0.85); border: 1px solid rgba(15, 23, 42, 0.06); display: flex; align-items: center; justify-content: center; color: #94A3B8; font-size: 24rpx; }
|
||
.error { margin-top: 14rpx; font-size: 24rpx; color: #EF4444; line-height: 36rpx; }
|
||
|
||
.page.big {
|
||
padding: 14rpx 14rpx 120rpx;
|
||
background-image:
|
||
radial-gradient(1100rpx 520rpx at 50% 14%, rgba(43, 107, 255, 0.30) 0%, rgba(6, 16, 40, 0.0) 65%),
|
||
linear-gradient(180deg, rgba(5, 11, 24, 0.90) 0%, rgba(8, 20, 45, 0.85) 42%, rgba(6, 16, 40, 0.92) 100%),
|
||
url('/static/bg.png');
|
||
background-size: auto, auto, cover;
|
||
background-position: center, center, center;
|
||
background-repeat: no-repeat, no-repeat, no-repeat;
|
||
}
|
||
.page.big .card,
|
||
.page.big .item,
|
||
.page.big .empty {
|
||
border: 1px solid rgba(116, 216, 255, 0.22);
|
||
background: linear-gradient(180deg, rgba(10, 18, 38, 0.75) 0%, rgba(5, 10, 22, 0.55) 100%);
|
||
box-shadow: 0 12rpx 24rpx rgba(0, 0, 0, 0.35);
|
||
}
|
||
.page.big .card-title,
|
||
.page.big .item-title,
|
||
.page.big .v {
|
||
color: rgba(235, 248, 255, 0.92);
|
||
}
|
||
.page.big .k,
|
||
.page.big .item-desc {
|
||
color: rgba(201, 242, 255, 0.65);
|
||
}
|
||
.page.big .input {
|
||
background: rgba(7, 13, 28, 0.35);
|
||
border-color: rgba(116, 216, 255, 0.18);
|
||
color: rgba(235, 248, 255, 0.92);
|
||
}
|
||
.page.big .btn.primary {
|
||
background: linear-gradient(90deg, rgba(116, 216, 255, 0.95) 0%, rgba(43, 107, 255, 0.92) 100%);
|
||
color: #0b1226;
|
||
}
|
||
.page.big .btn.ghost {
|
||
background: rgba(7, 13, 28, 0.35);
|
||
border-color: rgba(116, 216, 255, 0.18);
|
||
color: rgba(201, 242, 255, 0.86);
|
||
}
|
||
.page.big .pill {
|
||
color: rgba(201, 242, 255, 0.90);
|
||
background: rgba(116, 216, 255, 0.10);
|
||
border: 1px solid rgba(116, 216, 255, 0.18);
|
||
}
|
||
</style>
|