| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- <template>
- <div class="health-energy-config admin-page">
- <el-card>
- <div slot="header">
- <span>七维健康能量配置</span>
- <el-button style="float: right" type="primary" size="small" @click="handleSave" :loading="submitting">保存配置</el-button>
- </div>
- <el-form ref="form" :model="form" label-width="140px" v-loading="loading">
- <!-- 维度权重配置 -->
- <el-divider content-position="left">各维度权重配置</el-divider>
- <el-row :gutter="20">
- <el-col :span="12" v-for="dim in dimensions" :key="dim.code">
- <el-form-item :label="dim.label + ' 权重'">
- <el-slider
- v-model="form.weights[dim.code]"
- :min="0"
- :max="100"
- :step="1"
- show-input
- :format-tooltip="val => val + '%'"
- @change="onWeightChange(dim.code)"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-alert
- v-if="weightSum !== 100"
- :title="'权重总和不等于 100%(当前: ' + weightSum + '%)'"
- type="warning"
- :closable="false"
- style="margin-bottom: 20px;"
- />
- <el-alert
- v-else
- title="权重总和 = 100%,配置有效"
- type="success"
- :closable="false"
- style="margin-bottom: 20px;"
- />
- <el-divider content-position="left">同步系数配置</el-divider>
- <el-form-item label="能量同步系数">
- <el-slider
- v-model="form.syncFactor"
- :min="0"
- :max="100"
- :step="1"
- show-input
- :format-tooltip="val => (val / 100).toFixed(2)"
- style="max-width: 400px;"
- />
- <div style="color: #909399; font-size: 12px; margin-top: 4px;">
- 系数决定七维评分转换为身能量的比例(当前: {{ (form.syncFactor / 100).toFixed(2) }})
- 公式: 身能量 = 加权评分 × 系数
- </div>
- </el-form-item>
- <el-divider content-position="left">配置说明</el-divider>
- <el-alert
- title="计算逻辑"
- type="info"
- :closable="false"
- style="margin-bottom: 10px;"
- >
- <template slot>
- <ul style="margin: 8px 0 0 0; padding-left: 20px; font-size: 13px; color: #606266; line-height: 1.8;">
- <li>每次录入七维健康评分后,系统计算加权评分:<code>加权评分 = Σ(各维度评分 × 权重) / 权重总和</code></li>
- <li>然后转换为身能量值:<code>身能量 = 加权评分 × 同步系数</code></li>
- <li>权重越高,该维度评分对身能量的影响越大</li>
- <li>同步系数控制能量发放速度(系数越大,每次同步获得的能量越多)</li>
- </ul>
- </template>
- </el-alert>
- </el-form>
- </el-card>
- </div>
- </template>
- <script>
- export default {
- name: 'HealthEnergyConfig',
- data() {
- return {
- loading: false,
- submitting: false,
- form: {
- weights: {
- growth: 20,
- sleep: 15,
- vision: 10,
- immunity: 15,
- nutrition: 15,
- gut: 10,
- exercise: 15
- },
- syncFactor: 50
- },
- dimensions: [
- { code: 'growth', label: '生长发育' },
- { code: 'sleep', label: '睡眠质量' },
- { code: 'vision', label: '视力健康' },
- { code: 'immunity', label: '免疫力' },
- { code: 'nutrition', label: '营养均衡' },
- { code: 'gut', label: '肠胃健康' },
- { code: 'exercise', label: '运动活力' }
- ]
- }
- },
- computed: {
- weightSum() {
- return Object.values(this.form.weights).reduce((sum, v) => sum + v, 0)
- }
- },
- mounted() {
- this.loadConfig()
- },
- methods: {
- loadConfig() {
- this.loading = true
- this.$axios.post('/api/admin/config/all').then(res => {
- if (res.data.code === 200) {
- const config = res.data.data || {}
- // 加载权重配置
- const weightsJson = config['health_dimension_weights']
- if (weightsJson) {
- try {
- const weights = JSON.parse(weightsJson)
- if (weights && typeof weights === 'object') {
- for (const key of Object.keys(this.form.weights)) {
- if (weights[key] !== undefined) {
- this.form.weights[key] = Math.round(weights[key] * 100)
- }
- }
- }
- } catch (e) {
- this.$message.warning('权重配置解析失败,使用默认值')
- }
- }
- // 加载同步系数
- const factorStr = config['health_dimension_sync_factor']
- if (factorStr) {
- const factor = parseFloat(factorStr)
- if (!isNaN(factor)) {
- this.form.syncFactor = Math.round(factor * 100)
- }
- }
- }
- }).catch(() => {
- this.$message.error('加载配置失败')
- }).finally(() => {
- this.loading = false
- })
- },
- onWeightChange() {
- // 归一化处理:如果总和超过100,等比例压缩
- const sum = this.weightSum
- if (sum > 0 && sum !== 100) {
- const ratio = 100 / sum
- for (const key of Object.keys(this.form.weights)) {
- this.form.weights[key] = Math.round(this.form.weights[key] * ratio)
- }
- }
- },
- handleSave() {
- if (this.weightSum !== 100) {
- this.$message.warning('权重总和必须等于 100%')
- return
- }
- this.submitting = true
- // 将 0-100 的权重值转换为 0-1 的小数
- const normalizedWeights = {}
- for (const key of Object.keys(this.form.weights)) {
- normalizedWeights[key] = this.form.weights[key] / 100
- }
- const promises = [
- this.$axios.post('/api/admin/config/update', {
- configKey: 'health_dimension_weights',
- configValue: JSON.stringify(normalizedWeights)
- }),
- this.$axios.post('/api/admin/config/update', {
- configKey: 'health_dimension_sync_factor',
- configValue: (this.form.syncFactor / 100).toFixed(2)
- })
- ]
- Promise.all(promises).then(res => {
- const allSuccess = res.every(r => r.data.code === 200)
- if (allSuccess) {
- this.$message.success('保存成功')
- } else {
- this.$message.error('部分配置保存失败')
- }
- }).catch(() => {
- this.$message.error('保存失败')
- }).finally(() => {
- this.submitting = false
- })
- }
- }
- }
- </script>
- <style scoped>
- .health-energy-config {
- padding: 20px;
- }
- .health-energy-config .el-col {
- margin-bottom: 0;
- }
- </style>
|