EnergySandbox.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <template>
  2. <div class="page-container admin-page">
  3. <el-card>
  4. <div slot="header">
  5. <span>五维能量沙盘</span>
  6. <el-button
  7. type="primary"
  8. size="small"
  9. style="float: right"
  10. @click="loadData"
  11. :loading="loading"
  12. >
  13. 刷新
  14. </el-button>
  15. </div>
  16. <p class="page-desc">展示家庭在身、心、智、行、富五个维度的能量评分及综合指数</p>
  17. </el-card>
  18. <!-- 家庭能量总览 -->
  19. <el-card class="section-card" v-loading="loading">
  20. <div slot="header">
  21. <span>家庭能量总览</span>
  22. </div>
  23. <el-row :gutter="16">
  24. <el-col :span="4" v-for="item in dimensionList" :key="item.key">
  25. <div class="metric-card" :style="{ borderTopColor: item.color }">
  26. <div class="metric-name">{{ item.label }}</div>
  27. <div class="metric-score">
  28. <el-tag :color="item.color" effect="dark" size="medium" class="score-tag">
  29. {{ sandboxData[item.key] != null ? sandboxData[item.key] : '-' }}
  30. </el-tag>
  31. </div>
  32. </div>
  33. </el-col>
  34. </el-row>
  35. </el-card>
  36. <!-- 家庭成员数据 -->
  37. <el-card class="section-card" v-loading="loading">
  38. <div slot="header">
  39. <span>家庭成员数据</span>
  40. <el-input v-model="memberKeyword" placeholder="搜索成员姓名..." prefix-icon="el-icon-search" size="small" clearable style="float: right; width: 200px;" />
  41. </div>
  42. <el-table :data="filteredMembers" border style="width: 100%" :max-height="tableHeight">
  43. <el-table-column prop="memberType" label="成员类型" width="100"></el-table-column>
  44. <el-table-column prop="name" label="姓名" width="120"></el-table-column>
  45. <el-table-column prop="bodyScore" label="身" width="80" align="center">
  46. <template slot-scope="scope">
  47. <el-tag size="small" color="#67C23A" effect="dark">{{ scope.row.bodyScore != null ? scope.row.bodyScore : '-' }}</el-tag>
  48. </template>
  49. </el-table-column>
  50. <el-table-column prop="mindScore" label="心" width="80" align="center">
  51. <template slot-scope="scope">
  52. <el-tag size="small" color="#9B59B6" effect="dark">{{ scope.row.mindScore != null ? scope.row.mindScore : '-' }}</el-tag>
  53. </template>
  54. </el-table-column>
  55. <el-table-column prop="wisdomScore" label="智" width="80" align="center">
  56. <template slot-scope="scope">
  57. <el-tag size="small" color="#409EFF" effect="dark">{{ scope.row.wisdomScore != null ? scope.row.wisdomScore : '-' }}</el-tag>
  58. </template>
  59. </el-table-column>
  60. <el-table-column prop="actionScore" label="行" width="80" align="center">
  61. <template slot-scope="scope">
  62. <el-tag size="small" color="#E6A23C" effect="dark">{{ scope.row.actionScore != null ? scope.row.actionScore : '-' }}</el-tag>
  63. </template>
  64. </el-table-column>
  65. <el-table-column prop="wealthScore" label="富" width="80" align="center">
  66. <template slot-scope="scope">
  67. <el-tag size="small" color="#F0C929" effect="dark">{{ scope.row.wealthScore != null ? scope.row.wealthScore : '-' }}</el-tag>
  68. </template>
  69. </el-table-column>
  70. <el-table-column prop="overallScore" label="综合" width="80" align="center">
  71. <template slot-scope="scope">
  72. <el-tag size="small" color="#6366F1" effect="dark">{{ scope.row.overallScore != null ? scope.row.overallScore : '-' }}</el-tag>
  73. </template>
  74. </el-table-column>
  75. <template slot="empty">
  76. <span>暂无数据</span>
  77. </template>
  78. </el-table>
  79. </el-card>
  80. </div>
  81. </template>
  82. <script>
  83. import { getFamilyEnergySandbox } from '@/api/energy'
  84. export default {
  85. name: 'EnergySandbox',
  86. data() {
  87. return {
  88. loading: false,
  89. memberKeyword: '',
  90. sandboxData: {
  91. bodyScore: null,
  92. mindScore: null,
  93. wisdomScore: null,
  94. actionScore: null,
  95. wealthScore: null,
  96. overallScore: null,
  97. members: []
  98. },
  99. dimensionList: [
  100. { key: 'bodyScore', label: '身', color: '#67C23A' },
  101. { key: 'mindScore', label: '心', color: '#9B59B6' },
  102. { key: 'wisdomScore', label: '智', color: '#409EFF' },
  103. { key: 'actionScore', label: '行', color: '#E6A23C' },
  104. { key: 'wealthScore', label: '富', color: '#F0C929' },
  105. { key: 'overallScore', label: '综合', color: '#6366F1' }
  106. ]
  107. }
  108. },
  109. computed: {
  110. tableHeight() {
  111. return window.innerHeight - 280
  112. },
  113. filteredMembers() {
  114. const members = this.sandboxData.members || []
  115. if (!this.memberKeyword) return members
  116. const kw = this.memberKeyword.toLowerCase()
  117. return members.filter(m => m.name && m.name.toLowerCase().includes(kw))
  118. }
  119. },
  120. mounted() {
  121. this.loadData()
  122. },
  123. methods: {
  124. async loadData() {
  125. this.loading = true
  126. try {
  127. const res = await getFamilyEnergySandbox()
  128. if (res.data) {
  129. this.sandboxData = {
  130. bodyScore: res.data.bodyScore,
  131. mindScore: res.data.mindScore,
  132. wisdomScore: res.data.wisdomScore,
  133. actionScore: res.data.actionScore,
  134. wealthScore: res.data.wealthScore,
  135. overallScore: res.data.overallScore,
  136. members: res.data.members || []
  137. }
  138. }
  139. } catch (error) {
  140. this.$message.error(error.message || '加载五维能量数据失败')
  141. } finally {
  142. this.loading = false
  143. }
  144. }
  145. }
  146. }
  147. </script>
  148. <style scoped>
  149. .page-desc {
  150. color: #909399;
  151. font-size: 13px;
  152. margin: 0;
  153. }
  154. .section-card {
  155. margin-top: 16px;
  156. }
  157. .metric-card {
  158. background: #f8fafc;
  159. border-radius: 8px;
  160. border-top: 3px solid #ddd;
  161. padding: 16px 8px;
  162. text-align: center;
  163. }
  164. .metric-name {
  165. font-size: 16px;
  166. font-weight: 600;
  167. color: #303133;
  168. margin-bottom: 10px;
  169. }
  170. .metric-score {
  171. display: flex;
  172. justify-content: center;
  173. }
  174. .score-tag {
  175. font-size: 18px;
  176. font-weight: 700;
  177. min-width: 48px;
  178. text-align: center;
  179. }
  180. </style>