|
|
@@ -0,0 +1,278 @@
|
|
|
+<template>
|
|
|
+ <div class="page-container">
|
|
|
+ <el-card>
|
|
|
+ <PageHeader slot="header" title="家庭数据汇总方式配置" :count="tableData.length">
|
|
|
+ <el-button type="primary" size="small" icon="el-icon-plus" @click="handleAdd">新增配置</el-button>
|
|
|
+ <el-button size="small" @click="loadList" :loading="loading">刷新</el-button>
|
|
|
+ </PageHeader>
|
|
|
+
|
|
|
+ <div class="adm-table-wrap">
|
|
|
+ <el-table
|
|
|
+ :data="tableData"
|
|
|
+ border
|
|
|
+ v-loading="loading"
|
|
|
+ class="full-width"
|
|
|
+ height="100%"
|
|
|
+ >
|
|
|
+ <el-table-column prop="metricKey" label="数据项标识" min-width="140"></el-table-column>
|
|
|
+ <el-table-column prop="metricName" label="名称" min-width="140"></el-table-column>
|
|
|
+ <el-table-column label="所属维度" width="100">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ dimensionCodeText(scope.row.dimensionCode) }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="汇总方式" width="100">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <StatusTag :type="aggTypeTagType(scope.row.aggType)" :text="aggTypeText(scope.row.aggType)" size="small" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="值类型" width="100">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ valueTypeText(scope.row.valueType) }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="sortOrder" label="排序" width="80"></el-table-column>
|
|
|
+ <el-table-column label="状态" width="90">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <StatusTag
|
|
|
+ size="small"
|
|
|
+ :type="scope.row.status === 'active' ? 'success' : 'info'"
|
|
|
+ :text="scope.row.status === 'active' ? '启用' : '停用'"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="230" fixed="right">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-button size="mini" type="primary" @click="handleEdit(row)">编辑</el-button>
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ :type="row.status === 'active' ? 'warning' : 'success'"
|
|
|
+ @click="handleToggleStatus(row)"
|
|
|
+ >{{ row.status === 'active' ? '停用' : '启用' }}</el-button>
|
|
|
+ <el-button size="mini" type="danger" @click="handleDelete(row)">删除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 新增/编辑配置弹窗 -->
|
|
|
+ <el-dialog
|
|
|
+ :title="form.id ? '编辑配置' : '新增配置'"
|
|
|
+ :visible.sync="dialogVisible"
|
|
|
+ width="560px"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ >
|
|
|
+ <el-form :model="form" :rules="formRules" ref="form" label-width="100px">
|
|
|
+ <el-form-item label="数据项标识" prop="metricKey">
|
|
|
+ <el-input v-model="form.metricKey" :disabled="!!form.id" placeholder="请输入数据项标识,如 height"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="名称" prop="metricName">
|
|
|
+ <el-input v-model="form.metricName" placeholder="请输入名称,如 身高"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="所属维度" prop="dimensionCode">
|
|
|
+ <el-select v-model="form.dimensionCode" placeholder="请选择维度" class="full-width">
|
|
|
+ <el-option v-for="item in dimensionOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="汇总方式" prop="aggType">
|
|
|
+ <el-select v-model="form.aggType" placeholder="请选择汇总方式" class="full-width">
|
|
|
+ <el-option v-for="item in aggTypeOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="值类型" prop="valueType">
|
|
|
+ <el-select v-model="form.valueType" placeholder="请选择值类型" class="full-width">
|
|
|
+ <el-option v-for="item in valueTypeOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="展示模式" prop="displayMode">
|
|
|
+ <el-input v-model="form.displayMode" placeholder="展示模式标识,如 chart / percent(可选)"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="排序" prop="sortOrder">
|
|
|
+ <el-input-number v-model="form.sortOrder" :min="0" :max="9999" :step="1"></el-input-number>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="状态" prop="status">
|
|
|
+ <el-select v-model="form.status" class="full-width">
|
|
|
+ <el-option label="启用" value="active"></el-option>
|
|
|
+ <el-option label="停用" value="disabled"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="备注" prop="remark">
|
|
|
+ <el-input type="textarea" v-model="form.remark" :rows="2" placeholder="备注说明(可选)"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="submitForm" :loading="submitting">确定</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getFamilyMetricAggList, saveFamilyMetricAgg, deleteFamilyMetricAgg, updateFamilyMetricAggStatus } from '@/api/admin'
|
|
|
+
|
|
|
+const DIMENSION_OPTIONS = [
|
|
|
+ { value: 'body', label: '身' },
|
|
|
+ { value: 'mind', label: '心' },
|
|
|
+ { value: 'wisdom', label: '智' },
|
|
|
+ { value: 'action', label: '行' },
|
|
|
+ { value: 'wealth', label: '富' },
|
|
|
+ { value: 'common', label: '通用' }
|
|
|
+]
|
|
|
+const DIMENSION_TEXT = { body: '身', mind: '心', wisdom: '智', action: '行', wealth: '富', common: '通用' }
|
|
|
+const AGG_TYPE_OPTIONS = [
|
|
|
+ { value: 'SUM', label: '合计' },
|
|
|
+ { value: 'AVG', label: '平均' },
|
|
|
+ { value: 'COLLECT', label: '汇集' }
|
|
|
+]
|
|
|
+const AGG_TYPE_TEXT = { SUM: '合计', AVG: '平均', COLLECT: '汇集' }
|
|
|
+const VALUE_TYPE_OPTIONS = [
|
|
|
+ { value: 'NUMBER', label: '数值' },
|
|
|
+ { value: 'COLLECTION', label: '集合' }
|
|
|
+]
|
|
|
+const VALUE_TYPE_TEXT = { NUMBER: '数值', COLLECTION: '集合' }
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'FamilyMetricAggConfig',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ loading: false,
|
|
|
+ submitting: false,
|
|
|
+ tableData: [],
|
|
|
+ dialogVisible: false,
|
|
|
+ form: this.emptyForm(),
|
|
|
+ formRules: {
|
|
|
+ metricKey: [{ required: true, message: '请输入数据项标识', trigger: 'blur' }],
|
|
|
+ metricName: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
|
|
+ aggType: [{ required: true, message: '请选择汇总方式', trigger: 'change' }],
|
|
|
+ valueType: [{ required: true, message: '请选择值类型', trigger: 'change' }]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.loadList()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ loadList() {
|
|
|
+ this.loading = true
|
|
|
+ return getFamilyMetricAggList()
|
|
|
+ .then(res => {
|
|
|
+ this.tableData = res.data || []
|
|
|
+ })
|
|
|
+ .catch(error => {
|
|
|
+ this.$message.error(error.message || '加载汇总方式配置失败')
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ this.loading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ dimensionCodeText(code) {
|
|
|
+ return DIMENSION_TEXT[code] || code || '-'
|
|
|
+ },
|
|
|
+ aggTypeText(type) {
|
|
|
+ return AGG_TYPE_TEXT[type] || type || '-'
|
|
|
+ },
|
|
|
+ aggTypeTagType(type) {
|
|
|
+ if (type === 'SUM') return 'primary'
|
|
|
+ if (type === 'AVG') return 'warning'
|
|
|
+ return 'info'
|
|
|
+ },
|
|
|
+ valueTypeText(type) {
|
|
|
+ return VALUE_TYPE_TEXT[type] || type || '-'
|
|
|
+ },
|
|
|
+ emptyForm() {
|
|
|
+ return {
|
|
|
+ id: null,
|
|
|
+ metricKey: '',
|
|
|
+ metricName: '',
|
|
|
+ dimensionCode: 'common',
|
|
|
+ aggType: 'SUM',
|
|
|
+ valueType: 'NUMBER',
|
|
|
+ displayMode: '',
|
|
|
+ sortOrder: 0,
|
|
|
+ status: 'active',
|
|
|
+ remark: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleAdd() {
|
|
|
+ this.form = this.emptyForm()
|
|
|
+ this.dialogVisible = true
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.form) this.$refs.form.clearValidate()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleEdit(row) {
|
|
|
+ this.form = {
|
|
|
+ id: row.id,
|
|
|
+ metricKey: row.metricKey,
|
|
|
+ metricName: row.metricName,
|
|
|
+ dimensionCode: row.dimensionCode,
|
|
|
+ aggType: row.aggType,
|
|
|
+ valueType: row.valueType,
|
|
|
+ displayMode: row.displayMode || '',
|
|
|
+ sortOrder: row.sortOrder,
|
|
|
+ status: row.status || 'active',
|
|
|
+ remark: row.remark || ''
|
|
|
+ }
|
|
|
+ this.dialogVisible = true
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.form) this.$refs.form.clearValidate()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ submitForm() {
|
|
|
+ this.$refs.form.validate(valid => {
|
|
|
+ if (!valid) return
|
|
|
+ this.submitting = true
|
|
|
+ saveFamilyMetricAgg(this.form)
|
|
|
+ .then(() => {
|
|
|
+ this.$message.success('保存成功')
|
|
|
+ this.dialogVisible = false
|
|
|
+ this.loadList()
|
|
|
+ })
|
|
|
+ .catch(error => {
|
|
|
+ this.$message.error(error.message || '保存失败')
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ this.submitting = false
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleToggleStatus(row) {
|
|
|
+ const newStatus = row.status === 'active' ? 'disabled' : 'active'
|
|
|
+ const action = newStatus === 'active' ? '启用' : '停用'
|
|
|
+ this.$confirm(`确定${action}数据项「${row.metricName}」吗?`, '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ return updateFamilyMetricAggStatus({ id: row.id, status: newStatus })
|
|
|
+ }).then(() => {
|
|
|
+ this.$message.success(`${action}成功`)
|
|
|
+ this.loadList()
|
|
|
+ }).catch(() => {})
|
|
|
+ },
|
|
|
+ handleDelete(row) {
|
|
|
+ this.$confirm(`确定删除数据项「${row.metricName}」吗?删除后不可恢复。`, '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ return deleteFamilyMetricAgg({ id: row.id })
|
|
|
+ }).then(() => {
|
|
|
+ this.$message.success('删除成功')
|
|
|
+ this.loadList()
|
|
|
+ }).catch(() => {})
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.page-container {
|
|
|
+ padding: var(--spacing-lg);
|
|
|
+}
|
|
|
+.full-width {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+</style>
|