|
|
@@ -0,0 +1,154 @@
|
|
|
+<template>
|
|
|
+ <view class="page">
|
|
|
+ <!-- 成员切换 -->
|
|
|
+ <picker :range="memberNames" @change="onMemberChange">
|
|
|
+ <view class="member-picker">{{ currentMemberName }} ▾</view>
|
|
|
+ </picker>
|
|
|
+
|
|
|
+ <!-- 分类 Tab -->
|
|
|
+ <scroll-view scroll-x class="cat-scroll">
|
|
|
+ <view class="cat-tab" :class="activeCategory === '' ? 'cat-active' : ''" @tap="onCatTap('')">全部</view>
|
|
|
+ <view
|
|
|
+ class="cat-tab"
|
|
|
+ :class="activeCategory === c.name ? 'cat-active' : ''"
|
|
|
+ v-for="c in categories"
|
|
|
+ :key="getCatKey(c)"
|
|
|
+ @tap="onCatTap(c.name)"
|
|
|
+ >{{ c.name }}({{ c.total }})</view>
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+ <!-- 指标列表 -->
|
|
|
+ <view class="item-list" v-if="items.length > 0">
|
|
|
+ <view class="ql-item" v-for="item in items" :key="getItemKey(item)" @tap="goCurve(getItemId(item))">
|
|
|
+ <view class="ql-name-row">
|
|
|
+ <text class="ql-name">{{ item.name }}</text>
|
|
|
+ <text :class="'ql-trend ' + item._cssClass">{{ item._arrow }} {{ item._trendLabel }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="ql-value-row">
|
|
|
+ <text class="ql-value">{{ item.value }}{{ item.unit || '' }}</text>
|
|
|
+ <text class="ql-ref">参考: {{ item.refRange || '--' }}</text>
|
|
|
+ <text class="ql-status" :class="item._statusClass">{{ item.status || '' }}</text>
|
|
|
+ </view>
|
|
|
+ <text class="ql-date">{{ item._dateText }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="empty-tip" v-else>暂无数据</view>
|
|
|
+
|
|
|
+ <!-- 分页 -->
|
|
|
+ <view class="pager" v-if="totalPages > 1">
|
|
|
+ <view class="pager-btn" :class="page <= 1 ? 'pager-disabled' : ''" @tap="onPrevPage">上一页</view>
|
|
|
+ <text class="pager-info">{{ page }} / {{ totalPages }}</text>
|
|
|
+ <view class="pager-btn" :class="page >= totalPages ? 'pager-disabled' : ''" @tap="onNextPage">下一页</view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 五维/七维评分小节 -->
|
|
|
+ <view class="dim-section" v-if="dimensionScores.length > 0">
|
|
|
+ <view class="section-title">维度评分趋势</view>
|
|
|
+ <view class="dim-list">
|
|
|
+ <view class="dim-row" v-for="d in dimensionScores" :key="getDimKey(d)">
|
|
|
+ <text class="dim-name">{{ d.name }}</text>
|
|
|
+ <text class="dim-score">{{ d.score }}</text>
|
|
|
+ <text :class="'dim-trend ' + d._cssClass">{{ d._arrow }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getIndicatorQuickLookup } from '@/utils/api'
|
|
|
+import { getFamilyMemberList } from '@/utils/api'
|
|
|
+import { resolveChangeStyle, formatDelta, colorClassFor } from '@/utils/indicator-change'
|
|
|
+
|
|
|
+export default {
|
|
|
+ data: function() { return { members: [], currentMemberId: null, categories: [], activeCategory: '', items: [], dimensionScores: [], page: 1, pageSize: 30, totalPages: 1, _onLoadFired: false, _loading: false } },
|
|
|
+ computed: {
|
|
|
+ memberNames: function() { return this.members.map(function(m) { return m.name || m.nickname || '' }) },
|
|
|
+ currentMemberName: function() {
|
|
|
+ var self = this
|
|
|
+ var m = this.members.find(function(x) { return x.id === self.currentMemberId })
|
|
|
+ return (m && (m.name || m.nickname)) || '选择成员'
|
|
|
+ },
|
|
|
+ categoriesComputed: function() {
|
|
|
+ var self = this
|
|
|
+ return this.categories || []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ onLoad: function() { this.loadMembers(); this._onLoadFired = true },
|
|
|
+ onShow: function() { if (this._onLoadFired) { this._onLoadFired = false } else if (this.currentMemberId) { this.reload() } },
|
|
|
+ goCurve: function(definitionId) {
|
|
|
+ uni.navigateTo({ url: '/pages/health/indicator-curve?definitionId=' + definitionId })
|
|
|
+ },
|
|
|
+ loadMembers: function() {
|
|
|
+ var self = this
|
|
|
+ getFamilyMemberList({ visibleOnly: true }).then(function(res) {
|
|
|
+ var arr = (res.data && res.data.list) || (res.data instanceof Array ? res.data : [])
|
|
|
+ self.members = arr
|
|
|
+ if (!self.currentMemberId && arr.length > 0) { self.currentMemberId = arr[0].id; self.reload() }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ reload: function() { this.page = 1; this.loadData() },
|
|
|
+ loadData: function() {
|
|
|
+ var self = this
|
|
|
+ if (!this.currentMemberId || this._loading) return
|
|
|
+ this._loading = true
|
|
|
+ getIndicatorQuickLookup({ subjectId: this.currentMemberId, category: this.activeCategory || undefined, page: this.page, pageSize: this.pageSize }).then(function(res) {
|
|
|
+ self._loading = false
|
|
|
+ var data = res.data || {}
|
|
|
+ // 预计算展示字段,避免小程序 :class 中调用方法(微信模板编译器不支持带参方法调用)
|
|
|
+ self.rankItems = (data && data.items) || []
|
|
|
+ self.rankItems.forEach(function(it) {
|
|
|
+ var st = resolveChangeStyle(it.goodDirection, it.movement || 'flat')
|
|
|
+ it._cssClass = colorClassFor(st.cssClass)
|
|
|
+ it._arrow = st.arrow
|
|
|
+ it._trendLabel = st.trendLabel
|
|
|
+ it._statusClass = 'status-' + (it._cssClass || 'normal')
|
|
|
+ it._dateText = it.latestReportDate ? String(it.latestReportDate).slice(0, 10) : '--'
|
|
|
+ })
|
|
|
+ self.categories = data.categories || []
|
|
|
+ self.items = data.items || []
|
|
|
+ self.dimensionScores = data.dimensionScores || []
|
|
|
+ var total = data.total !== undefined ? data.total : self.items.length
|
|
|
+ self.totalPages = Math.max(1, Math.ceil(total / self.pageSize))
|
|
|
+ }).catch(function() { self._loading = false })
|
|
|
+ },
|
|
|
+ onCatTap: function(name) { this.activeCategory = name; this.reload() },
|
|
|
+ onPrevPage: function() { if (this.page > 1) { this.page--; this.loadData() } },
|
|
|
+ onNextPage: function() { if (this.page < this.totalPages) { this.page++; this.loadData() } },
|
|
|
+ formatDate: function(s) { if (!s) return '--'; return String(s).slice(0, 10) },
|
|
|
+ getCatKey: function(c) { return c.name },
|
|
|
+ getItemKey: function(item) { return item.definitionId },
|
|
|
+ getItemId: function(item) { return item.definitionId },
|
|
|
+ getDimKey: function(d) { return d.name }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.member-picker { font-size: 24rpx; color: #666; }
|
|
|
+.cat-scroll { height: 40rpx; line-height: 40rpx; overflow-x: scroll; }
|
|
|
+.cat-tab { float: left; margin-right: 20rpx; padding: 0 12rpx; height: 32rpx; line-height: 32rpx; font-size: 22rpx; color: #999; }
|
|
|
+.cat-tab.cat-active { color: #4A9BD7; border-bottom: 2rpx solid #4A9BD7; }
|
|
|
+.item-list { padding: 20rpx; }
|
|
|
+.ql-item { margin-bottom: 20rpx; }
|
|
|
+.ql-name-row { display: flex; justify-content: space-between; margin-bottom: 8rpx; }
|
|
|
+.ql-name { font-size: 26rpx; }
|
|
|
+.ql-trend { font-size: 20rpx; color: #666; }
|
|
|
+.ql-value-row { display: flex; justify-content: space-between; margin-bottom: 8rpx; }
|
|
|
+.ql-value { font-size: 24rpx; }
|
|
|
+.ql-ref { font-size: 16rpx; color: #999; }
|
|
|
+.ql-status { font-size: 20rpx; }
|
|
|
+.ql-date { font-size: 16rpx; color: #999; margin-top: 4rpx; }
|
|
|
+.pager { height: 40rpx; line-height: 40rpx; padding: 0 20rpx; font-size: 20rpx; }
|
|
|
+.pager-btn { float: left; margin-right: 10rpx; padding: 0 12rpx; height: 32rpx; line-height: 32rpx; font-size: 20rpx; color: #999; }
|
|
|
+.pager-btn.pager-disabled { color: #ccc; }
|
|
|
+.pager-info { float: left; margin: 0 20rpx; }
|
|
|
+.dim-section { padding: 20rpx; }
|
|
|
+.section-title { font-size: 26rpx; margin-bottom: 12rpx; }
|
|
|
+.dim-list { display: flex; flex-wrap: wrap; }
|
|
|
+.dim-row { margin-bottom: 12rpx; }
|
|
|
+.dim-name { font-size: 22rpx; width: 60rpx; }
|
|
|
+.dim-score { font-size: 22rpx; color: #666; }
|
|
|
+.dim-trend { font-size: 18rpx; color: #999; }
|
|
|
+</style>
|