一,原型展示

新增:
image.png
编辑:
image.png
详情展示:
image.png

二,实现思路

对于表单项较多,新增、编辑和详情展示表单展示内容基本一致,只是展示形式有所不同,考虑可以共用一个组件,加一个pageType字段区分是新增、编辑还是详情展示;利用数据驱动视图的思想,我们可以把页面内容抽象成数据(例如,每一个输入框可能的所有属性可以定义到一个对象中 { id: 'metricsName', name: '中文名称', type: 'text', required: true, group: 'base', value: '', valueshow: '', editDisabled: true, isValidate: true, isLength: 32, tip: '' },)id作为后端接口的返回字段,name是表单项的显示名称,type,required,value,valueshow,editDisabled,isValidate,isLength,tip都是控制input框需要的元素(抽象成可控的属性),还有一个group,这个字段是用来给输入框分类的,group的值相同的说明是在同一组,显示在同一组下。

三,代码实现

<template>
    <div v-if="isLoading">
        <!-- <Modal v-model="flag"> -->
        <div v-for="(t,index) in titleArr" :key="index" >
            <div class="item-title">{{t.name}}</div>
            <Form inline label-colon ref="formInline" >
                <template v-for="(item, index) in datas"  >
                    <FormItem v-if="t.group === item.group" :key="index" :class="['item-container',pageType !==0 ? 'fixed-height':'']"  :label="item.name" :label-width="100"  :required="item.required">
                        <template v-if='pageType'>
                            <Input v-if="item.type ==='text'" :id="item.id" v-model="item.value" placeholder="" :disabled="pageType === 2 ? item.editDisabled : false"></Input>
                            <Select v-else-if="item.type ==='select'" v-model="item.value" placeholder="" :disabled="item.editDisabled">
                                <Option v-for="(option,i) in item.options" :key="i" :value="option.id">{{option.data}}</Option>
                            </Select>
                            <Select v-else-if="item.type ==='multiple'" multiple v-model="item.value" placeholder="">
                                <Option v-for="(option,i) in item.options" :key="i" :value="option.id">{{option.data}}</Option>
                            </Select>
                            <Input v-else-if="item.type==='number'" v-model.number="item.value" type="number"></Input>
                        <span class="tip" v-show="(item.isValidate ||item.isLength>0) && item.tip">{{item.tip}}</span>
                        </template>
                        <template v-if="!pageType">
                            <span>
                                {{item.valueshow}}
                            </span>
                        </template>
                    </FormItem>
                </template>
            </Form>
        </div>
        <div v-if="pageType" class="bottom-footer">
            <Button type="primary" size="large" style="" @click="onSubmit">提交</Button>
            <Button size="large"  @click="onCancel">取消</Button>
        </div>
        <!-- </Modal> -->
    </div>
</template>
<script>
import template from '../portrait-manager/template/template.vue';
import axios from '@/libs/api.request';
export default{
  components: { template },
    data () {
        return {
            pageType: 1, // 1新增,2编辑,0,详情
            titleArr: [{ group: 'base', name: '基础属性' }, { group: 'business', name: '业务属性' }, { group: 'technology', name: '技术属性' }, { group: 'manage', name: '管理属性' }],
            datas: [
                    // 基础属性
                    // { id: 'metricsCode', isHide: true, name: '指标编码', type: 'text', required: true, group: 'base', value: '', valueshow: '', editDisabled: true, isValidate: true, tip: '' },
                    { id: 'metricsName', name: '中文名称', type: 'text', required: true, group: 'base', value: '', valueshow: '', editDisabled: true, isValidate: true, isLength: 32, tip: '' },
                    { id: 'metricsAlias', name: '中文别名', type: 'text', required: false, group: 'base', value: '', valueshow: '', editDisabled: false },
                    { id: 'metricsClass', name: '指标层级', type: 'select', group: 'base', required: true, value: '', valueshow: '', options: [{ id: '战略层', data: '战略层' }, { id: '策略层', data: '策略层' }, { id: '执行层', data: '执行层' }], isValidate: true, tip: '' },
                    { id: 'englishName', name: '英文名称', type: 'text', group: 'base', required: true, value: '', valueshow: '', editDisabled: true, isValidate: true, tip: '' },
                    { id: 'englishShort', name: '英文简称', type: 'text', group: 'base', required: false, value: '', valueshow: '' },
                    { id: 'metricsType', name: '指标类型', type: 'select', group: 'base', required: true, value: '', valueshow: '', isValidate: true, options: [{ id: 1, data: '基础指标' }, { id: 2, data: '复合指标' }] },
                    { id: 'importantClass', name: '重要等级', type: 'select', group: 'base', required: true, value: '', valueshow: '', options: [{ id: '0', data: '0' }, { id: '1', data: '1' }, { id: '2', data: '2' }, { id: '3', data: '3' }, { id: '4', data: '4' }, { id: '5', data: '5' }], isValidate: true, tip: '' },
                    { id: 'versionCode', name: '版本编号', type: 'text', group: 'base', required: false, value: '', valueshow: '' },
                    // // 业务属性
                    { id: 'business', name: '所属业务', type: 'select', group: 'business', required: true, value: '', valueshow: '', options: [], editDisabled: false, isValidate: true, tip: '' }, // 支持拓展
                    { id: 'subBusiness', name: '子业务', type: 'text', group: 'business', required: false, value: '', valueshow: '', editDisabled: false },
                    { id: 'topicField', name: '主题领域', type: 'select', group: 'business', required: true, value: '', valueshow: '', isValidate: true, editDisabled: false }, // 支持拓展
                    { id: 'calculationObject', name: '计算对象', type: 'select', group: 'business', options: [], required: true, value: '', valueshow: '', editDisabled: false, isValidate: true, tip: '' }, // 支持拓展
                    { id: 'metricDefine', name: '指标定义', type: 'text', group: 'business', required: true, value: '', valueshow: '', editDisabled: false, isValidate: true, tip: '', isLength: 255 },
                    { id: 'calculationCondition', name: '计算条件', type: 'text', group: 'business', required: true, value: '', valueshow: '', editDisabled: false, isValidate: true, tip: '', isLength: 255 },
                    { id: 'calculationCycle', name: '统计周期', type: 'select', group: 'business', options: [], required: true, value: '', valueshow: '', editDisabled: false, isValidate: true, tip: '' }, // 支持拓展
                    { id: 'isAdd', name: '是否可加', type: 'select', group: 'business', required: true, value: '', valueshow: '0', options: [{ id: 1, data: '是' }, { id: 0, data: '否' }], editDisabled: false, isValidate: true, tip: '' },
                    { id: 'metricsPurpose', name: '指标用途', type: 'text', group: 'business', required: true, value: '', valueshow: '', editDisabled: false, isValidate: true, tip: '', isLength: 255 },
                    // // 技术属性
                    { id: 'unit', name: '计量单位', type: 'text', group: 'technology', value: '', valueshow: '', required: false },
                    { id: 'dataAccuracy', name: '统计精度', type: 'number', group: 'technology', value: '', valueshow: '', required: false },
                    { id: 'dataRange', name: '数据值域', type: 'text', group: 'technology', value: '', valueshow: '', required: false },
                    { id: 'calculateCycle', name: '计算周期', type: 'select', group: 'technology', value: '', valueshow: '', options: [{ id: '分钟', data: '分钟' }, { id: '小时', data: '小时' }, { id: '日', data: '日' }, { id: '周', data: '周' }, { id: '月', data: '月' }, { id: '季', data: '季' }, { id: '年', data: '年' }], required: false },
                    { id: 'storeType', name: '存储类型', type: 'select', group: 'technology', value: '', valueshow: '', options: [{ id: 'string', data: 'string' }, { id: 'bigint', data: 'bigint' }, { id: 'double', data: 'double' }, { id: 'decimal', data: 'decimal' }, { id: 'datetime', data: 'datetime' }, { id: 'boolean', data: 'boolean' }], required: false },
                    // { id: 'metricDimension', name: '常用维度', type: 'multiple', group: 'technology', value: '', valueshow: '', options: [{ id: '时间', data: '时间' }, { id: '渠道', data: '渠道' }, { id: '省份', data: '省份' }, { id: '产品', data: '产品' }] }, // 支持多选,支持扩展
                    { id: 'metricDimension', name: '常用维度', type: 'multiple', group: 'technology', value: '', valueshow: '', options: [] }, // 支持多选,支持扩展

                    { id: 'dataSource', name: '数据来源', type: 'text', group: 'technology', value: '', valueshow: '', required: false },
                    { id: 'calculateCode', name: '计算代码', type: 'text', group: 'technology', value: '', valueshow: '', required: false }, // 支持较多的字符,动态字符支持
                    { id: 'processLevel', name: '加工层级', type: 'select', group: 'technology', value: '', valueshow: '', options: [{ id: 'ODS', data: 'ODS' }, { id: 'DWD', data: 'DWD' }, { id: 'DWS', data: 'DWS' }, { id: 'ADS', data: 'ADS' }], required: false },
                    // // 管理属性
                    { id: 'defineDept', name: '指标定义部门', type: 'text', required: false, group: 'manage', value: '', valueshow: '', editDisabled: false },
                    { id: 'defineUser', name: '指标定义人', type: 'text', required: false, group: 'manage', value: '', valueshow: '', editDisabled: false },
                    { id: 'defineTime', name: '定义时间', type: 'text', required: false, group: 'manage', value: '', valueshow: '', editDisabled: false },
                    { id: 'developmentDept', name: '指标开发部门', type: 'text', group: 'manage', value: '', valueshow: '', required: false },
                    // { id: 'developmentUser', name: '指标开发人', type: 'text', group: 'manage', value: '', valueshow: '', required: false, editDisabled: true },
                    { id: 'developmentTime', name: '开发时间', type: 'text', group: 'manage', value: '', valueshow: '', required: false },
                    { id: 'auditDept', name: '指标审核部门', type: 'text', group: 'manage', value: '', valueshow: '', required: false },
                    { id: 'auditUser', name: '指标审核人', type: 'text', group: 'manage', value: '', valueshow: '' },
                    { id: 'auditTime', name: '审核时间', type: 'text', group: 'manage', value: '', valueshow: '', required: false },
                    { id: 'metricsExplain', name: '指标说明', type: 'text', group: 'manage', value: '', valueshow: '', required: false },
                    { id: 'calculateEquation', name: '计算公式', type: 'text', group: 'manage', value: '', valueshow: '' }
                    // { id: 'status', name: '指标状态', type: 'select', group: 'manage', value: '', valueshow: '', required: false, editDisabled: true, options: [{ id: 1, data: '审核通过' }, { id: 0, data: '未审核' }, { id: -1, data: '已删除' }] }
                ],
            quotaSearch: '',
            detailDatas: {},
            metricDimensionVal: [],
            isLoading: false

        };
    },
    created () {
        let query = this.$route.query;
         if (query.type === 'add') {
             this.getDictionary();
             this.isLoading = true;
        }
        if (query.type === 'edit') {
            this.pageType = 2;
        } else if (query.type === 'detail') {
            this.pageType = 0;
        } else if (query.type === 'add') {
            this.pageType = 1;
            this.clearForm();
        }
        if (query.type === 'edit' || query.type === 'detail') {
            this.datas.unshift({ id: 'metricsCode', name: '指标编码', type: 'text', required: true, group: 'base', value: '', valueshow: '', editDisabled: true, isValidate: true, tip: '' });
            let row = JSON.parse(sessionStorage.getItem('Quota'));
                this.detailDatas = row;
                this.getDictionary().then(() => {
                    this.isLoading = true;
                    for (let key in this.detailDatas) {
                    if (key === 'developmentUser') {
                        this.datas.splice(31, 0, { id: 'developmentUser', name: '指标开发人', type: 'text', group: 'manage', value: '', valueshow: '', required: false, editDisabled: true }
);
                    }
                    if (key === 'status') {
                        this.datas.push({ id: 'status', name: '指标状态', type: 'select', group: 'manage', value: '', valueshow: '', required: false, editDisabled: true, options: [{ id: 1, data: '审核通过' }, { id: 0, data: '未审核' }, { id: -1, data: '已删除' }] }
);
                    }
                    for (let i = 0; i < this.datas.length; ++i) {
                        if (key === this.datas[i].id) {
                            this.datas[i].value = this.detailDatas[key];
                                //  console.log('this.data[i].value', this.datas[i].value);
                            // 需要数据转换的
                            let validateKey = ['business', 'calculationObject', 'topicField', 'calculationCycle', 'isAdd', 'metricsType', 'status'];
                            // var flag = key === 'business' || key === 'calculationObject' || key === 'topicField' || key === 'calculationCycle' || key === 'metricDimension' || key === 'isAdd' || key === 'metricsType' ||
                            if (validateKey.indexOf(key) >= 0) {
                                this.datas[i].valueshow = this.transForm(key, this.detailDatas[key]);
                            } else {
                                this.datas[i].valueshow = this.detailDatas[key];// 展示
                                if (key === 'metricDimension') {
                                    if (this.detailDatas[key].indexOf(',')) {
                                        var arr = [];
                                        this.datas[i].value = this.detailDatas[key].split(',');
                                        this.datas[i].value.map((item) => {
                                            this.datas[i].options.map((eachOpt) => {
                                                if (eachOpt.data === item) {
                                                    arr.push(eachOpt.id);
                                                }
                                            });
                                        });
                                            this.datas[i].value = arr;
                                    }
                                }
                            }
                        }
                    }
                }
                });
        }
    },
    methods: {
        getDictionary () {
             let a = axios.request({
                    url: 'enum/attribute',
                    method: 'GET'
                }).then(res => {
                    // console.log('business', res);
                     this.datas.map((item) => {
                        if (item.id === 'business') {
                            item.options = res;
                        }
                    });
                });
             let b = axios.request({
                    url: 'enum/compute_object',
                    method: 'GET'
                }).then(res => {
                        // console.log('calculationObject', res);
                     this.datas.map((item) => {
                        if (item.id === 'calculationObject') {
                            item.options = res;
                        }
                    });
                });
              let c = axios.request({
                    url: 'enum/thene_domain',
                    method: 'GET'
                }).then(res => {
                        // console.log('topicField', res);
                     this.datas.map((item) => {
                        if (item.id === 'topicField') {
                            item.options = res;
                        }
                    });
                });
              let d = axios.request({
                    url: 'enum/compute_cycle',
                    method: 'GET'
                }).then(res => {
                    // console.log('calculationCycle', res);
                     this.datas.map((item) => {
                        if (item.id === 'calculationCycle') {
                            item.options = res;
                        }
                    });
                });
               let e = axios.request({
                    url: 'enum/metric_dimension',
                    method: 'GET'
                }).then(res => {
                    // console.log('metricDimension', res);
                     this.datas.map((item) => {
                        if (item.id === 'metricDimension') {
                             item.options = res;
                        }
                    });
                });
                ;
            return Promise.all([a, b, c, d, e]);
        },
        validate () {
                for (let i = 0; i < this.datas.length; i++) {
                    //   console.log('this.datas[i].value', this.datas[i].id, this.datas[i].value);
                    if (this.datas[i].isValidate) { // 空校验
                        if (this.datas[i].value === '' || this.datas[i].value === null) {
                            this.datas[i].tip = this.datas[i].name + '不能为空';
                        } else {
                             let item = this.datas[i];
                            // 长度校验
                             item.tip = '';
                            if (item.id === 'metricsName' || item.id === 'englishName' || item.id === 'metricsPurpose' || item.id === 'metricDefine' || item.id === 'calculationCondition') {
                                if (item.value && (item.value.length > item.isLength)) {
                                    item.tip = '最多支持' + item.isLength + '个字符';
                                } else {
                                    item.tip = '';
                                }
                            }
                        }
                    }
                }
            var flag = this.datas.every((item) => {
                 return !item.tip;
            });
            // console.log('flag', flag);
            return flag;
        },
        clearForm () {
            this.datas.map((item) => {
                item.value = '';
            });
        },
        onSubmit () {
             var isValidate = this.validate();
             console.log('isValidate', isValidate, this.datas);
            if (isValidate) {
                let str = '';
                for (let i = 0; i < this.datas.length; ++i) {
                    if (this.datas[i].id === 'metricDimension' && this.datas[i].value) {
                        let a = this.datas[i].value;
                        for (let j = 0; j < a.length; j++) {
                           str += this.transForm('metricDimension', a[j]) + ',';
                        }
                          str = str.substr(0, str.length - 1);
                        this.detailDatas[this.datas[i].id] = str;
                        // this.detailDatas[this.datas[i].id] = this.datas[i].value.join(',');
                    } else {
                        this.detailDatas[this.datas[i].id] = this.datas[i].value;
                    }
                }

                if (this.pageType === 2) { // 编辑
                   console.log('this.detailDatas编辑', this.detailDatas);
                    axios.request({
                        url: 'metrics',
                        method: 'PUT',
                        data: this.detailDatas
                    }).then(res => {
                        console.log('编辑成功==', res);
                            this.$router.push({
                                path: `/quota_manage/quota_list`
                            });
                    });
                } else if (this.pageType === 1) { // 新增
                console.log('this.detailDatas新增', this.detailDatas);
                    axios.request({
                        url: 'metrics',
                        method: 'POST',
                        data: this.detailDatas
                    }).then(res => {
                        console.log('新增成功==', res);
                          if (res.msg !== 'success') {
                            this.$Message.error(res.msg);
                         } else {
                            this.$router.push({
                                path: `/quota_manage/quota_list`
                            });
                         }
                    });
                }
            }
        },
        onCancel () {
             this.$router.push({
                path: `/quota_manage/quota_list`
            });
        },
        transForm (key, value) {
            // console.log('转换', key, value);
            if (key === 'business') { // 所属业务
                switch (value) {
                    case 1 :
                        value = '微爱业务中心';
                        break;
                    case 2 :
                        value = '保险业务中心';
                        break;
                    case 3 :
                        value = '健康业务中心';
                        break;
                    case 4 :
                        value = '会员业务中心';
                        break;
                    case 5 :
                        value = '内容运营中心';
                        break;
                    case 6 :
                        value = '客服运营中心';
                        break;
                    case 7 :
                        value = '智能营销中心';
                        break;
                    case 8 :
                        value = '增长合作中心';
                        break;
                    default :
                        value = '';
                }
            }
            if (key === 'calculationObject') { // 计算对象
                switch (value) {
                    case 1 :
                        value = '用户';
                        break;
                    case 2 :
                        value = '订单';
                        break;
                    case 3 :
                        value = '项目';
                        break;
                    case 4 :
                        value = '粉丝';
                        break;
                    case 5 :
                        value = '保单';
                        break;
                    default :
                        value = '';
                }
            }
            if (key === 'topicField') { // 主题领域
                switch (value) {
                    case 1 :
                        value = '用户';
                        break;
                    case 2 :
                        value = '流量';
                        break;
                    case 3 :
                        value = '交易订单';
                        break;
                    case 4 :
                        value = '项目';
                        break;
                    case 5 :
                        value = '保单';
                        break;
                    default :
                        value = '';
                }
            }
            if (key === 'calculationCycle') { // 统计周期
                switch (value) {
                    case 1 :
                        value = '五分钟';
                        break;
                    case 2 :
                        value = '一小时';
                        break;
                    case 3 :
                        value = '7日';
                        break;
                    case 4 :
                        value = '两个周';
                        break;
                    case 5 :
                        value = '一个月';
                        break;
                    case 6:
                        value = '一季';
                        break;
                    case 7:
                        value = '一年';
                        break;
                    default :
                        value = '';
                }
            }
            if (key === 'metricDimension') { // 常用维度
                switch (value) {
                    case 1 :
                        value = '时间';
                        break;
                    case 2 :
                        value = '渠道';
                        break;
                    case 3 :
                        value = '省份';
                        break;
                    case 4 :
                        value = '产品';
                        break;
                    default :
                        value = '';
                }
            }
            if (key === 'isAdd') {
                switch (value) {
                    case 1 :
                        value = '是';
                        break;
                    case 0 :
                        value = '否';
                        break;
                    default :
                        value = '';
                }
            }
            if (key === 'metricsType') {
                switch (value) {
                    case 1 :
                        value = '基础指标';
                        break;
                    case 2 :
                        value = '复合指标';
                        break;
                    default :
                        value = '';
                }
            }
            if (key === 'status') {
                switch (value) {
                    case 1 :
                        value = '审核通过';
                        break;
                    case 0 :
                        value = '未审核';
                        break;
                    case -1 :
                        value = '已删除';
                        break;
                    default :
                        value = '';
                }
            }
            // status;
            return value;
        }

    }
};
</script>
<style lang="less" scoped>
.item-title{
    background-color:rgba(215, 215, 215, 1);
    width:100%;
    height:27px;
    line-height: 27px;
    padding-left: 5px;
    margin-bottom: 20px;
    font-weight: 700px;
    font-size: 13px;
    color:#333333;
}
.fixed-height{
        height:32px;
    }
.item-container{
    width:30%;
    .tip{
        position: relative;
        top: -10px;
        color:red;
    }
}
.bottom-footer{
margin:0 auto;
text-align: center;
padding:20px 0px;
/deep/button{
    width:120px;
    margin-left:20px;
}
}
</style>

四,实现意义

将数据和页面结构及样式分离,可剥离成组件,代码简洁,易于阅读,容易维护,有较强的可扩展性。


Delia
75 声望3 粉丝

路漫漫其修远兮,吾将上下而求索。