123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797 |
- <template>
- <!-- 指数修匀计算弹窗 -->
- <el-dialog
- :visible.sync="isOpenSmooth"
- :close-on-click-modal="false"
- :modal-append-to-body="false"
- @close="cancelHandle"
- center
- width="1200px"
- top="3vh"
- v-dialogDrag
- class="smooth-edb-dialog"
- >
- <div slot="title" style="display: flex; align-items: center">
- <img
- :src="$icons.computed"
- style="color: #fff; width: 16px; height: 16px; margin-right: 5px"
- />
- <span style="font-size: 16px">指数修匀</span>
- </div>
- <div class="smooth-edb-dialog-wrap">
- <!-- 常规计算 -->
- <div class="normal-wrap" v-if="computedSource===1">
- <div class="min-top">
- <label >选择指标:</label>
- <el-select
- v-model="select_target"
- v-loadMore="searchLoad"
- :filterable="!select_target"
- clearable
- placeholder="请输入指标名称"
- style="width: 85%"
- remote
- :remote-method="getTarget"
- @click.native="inputFocusHandle"
- @change="chooseTarget"
- @blur="search_have_more = false"
- :disabled="operationForm.view"
- >
- <i slot="prefix" class="el-input__icon el-icon-search"></i>
- <el-option
- v-for="item in searchOptions"
- :key="item.EdbInfoId"
- :label="$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
- :value="item.EdbInfoId"
- >
- </el-option>
- </el-select>
- <i class="el-icon-tickets" style="color:#409EFF;font-size:18px" @click="handleSelectBtnClick" v-if="select_target"/>
-
- </div>
- <div class="middle">
- <label>已选指标:</label>
- <el-table
- :data="tableData"
- style="box-shadow: 0px 3px 6px rgba(155, 170, 219, 0.2);margin-top:10px;"
- border>
- <el-table-column
- v-for="item in tableColums"
- :key="item.label"
- :label="item.label"
- :width="item.widthsty"
- :min-width="item.minwidthsty"
- align="center"
- >
- <template slot-scope="scope">
- <span>{{ scope.row[item.key] }}</span>
- </template>
- </el-table-column>
- <el-table-column
- width="110"
- align="center"
- label="操作"
- v-if="!operationForm.view"
- >
- <template slot-scope="scope">
- <span class="deletesty" @click="delTarget">删除</span>
- </template>
- </el-table-column>
- <div slot="empty" style="padding:20px 0 30px;">
- <tableNoData text="暂无指标" size="mini"/>
- </div>
- </el-table>
- <ul
- class="data-ul"
- ref="dataUl"
- @scroll="scrollHandle"
- v-if="dataList.length">
- <li
- class="value-item"
- v-for="(item, index) in dataList"
- :key="item.EdbDataId"
- >
- <span class="value-label">
- <i class="new-tag" v-if="index === 0"></i>
- {{item.DataTime}}
- </span>
- <span class="value-label" style="min-width:200px;text-align:center;">{{item.Value}}</span>
- </li>
- </ul>
- <div class="form-cont">
- <el-form
- ref="form"
- label-position="right"
- inline
- label-width="80px"
- :model="formData"
- :rules="formRules"
- :disabled="operationForm.view"
- >
- <el-form-item label="指标名称" prop="targetName">
- <el-input
- v-model="formData.targetName"
- style="width: 340px"
- placeholder="请输入指标名称"
- />
- </el-form-item>
- <el-form-item label="单位" prop="unit">
- <selectUnit
- v-model="formData.unit"
- style="width: 340px"
- />
- </el-form-item>
- <el-form-item label="指标目录" prop="menu">
- <el-cascader v-if="isOpenSmooth"
- v-model="formData.menu"
- :options="catalogArr"
- :props="levelProps"
- clearable
- placeholder="请选择指标目录"
- />
- </el-form-item>
- <el-form-item label="频度" prop="frequency">
- <el-select
- v-model="formData.frequency"
- placeholder="请选择频度"
- style="width: 340px"
- clearable
- >
- <el-option
- v-for="item in frequencyArr"
- :key="item"
- :label="item"
- :value="item"
- >
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="alpha值" prop="alphaValue">
- <el-input
- v-model.trim="formData.alphaValue"
- style="width: 340px"
- placeholder="请输入alpha值"
- />
- </el-form-item>
- </el-form>
- </div>
- </div>
- </div>
- <!-- 批量计算 -->
- <div class="batch-wrap" v-else>
- <ul class="target-ul">
- <li class="target-li" v-for="(list, index) in targetList" :key="index">
- <span class="li-tag">{{ list.tag }}</span>
- <el-select v-model="list.target" v-loadMore="searchLoad" :filterable="!list.target" clearable
- placeholder="请输入指标名称" style="width: 400px" @change="(val)=>{chooseTargetList(val,index)}"
- @clear="clearHandle(index)" remote :remote-method="getTarget"
- @click.native="inputFocusHandle">
- <i slot="prefix" class="el-input__icon el-icon-search"></i>
- <el-option v-for="item in searchOptions" :key="item.EdbInfoId"
- :label="$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
- :value="item.EdbInfoId">
- </el-option>
- </el-select>
- <i class="el-icon-tickets" style="color:#409EFF;font-size:18px"
- @click="$emit('lookHistory',list.target)" v-if="list.target" />
- <i class="el-icon-error del-tag" v-if="index > 1" @click="delTargetList(index)" />
- <span class="target-date" v-if="list.start_date">{{
- `${list.start_date}至${list.end_date}`
- }}</span>
- </li>
- </ul>
- <span class="add-icon" @click="addTargetHandle">
- <i class="el-icon-circle-plus-outline" style="color: #5882ef; font-size: 16px" />
- 添加更多指标
- </span>
- <ul class="form-ul">
- <li class="form-li" v-for="(list, index) in targetList" :key="index">
- <span class="li-tag">{{ list.tag }}</span>
- <el-form :ref="`list_form_${index}`"
- label-position="right"
- inline
- label-width="0px"
- :model="targetList[index]"
- :rules="formRules"
- >
- <el-form-item prop="targetName">
- <el-input
- v-model="targetList[index].targetName"
- style="width: 240px"
- placeholder="请输入指标名称"
- />
- </el-form-item>
- <el-form-item prop="menu">
- <el-cascader v-if="isOpenSmooth"
- v-model="targetList[index].menu"
- :options="catalogArr"
- :props="levelProps"
- style="width: 200px"
- clearable
- placeholder="请选择指标目录"
- />
- </el-form-item>
- <el-form-item prop="unit">
- <selectUnit
- v-model="targetList[index].unit"
- style="width: 160px"
- />
- </el-form-item>
- <el-form-item prop="alphaValue">
- <el-input
- v-model.trim="targetList[index].alphaValue"
- style="width: 180px"
- placeholder="请输入alpha值"
- />
- </el-form-item>
- <el-form-item prop="frequency">
- <el-select
- v-model="targetList[index].frequency"
- placeholder="请选择频度"
- style="width: 180px"
- clearable
- >
- <el-option
- v-for="item in frequencyArr"
- :key="item"
- :label="item"
- :value="item"
- >
- </el-option>
- </el-select>
- </el-form-item>
-
- </el-form>
- </li>
- </ul>
- </div>
- <div class="dia-bot" v-if="!operationForm.view">
- <el-button
- type="primary"
- style="margin-right: 20px"
- @click="saveBtnClick"
- :loading="loading"
- >指数修匀计算</el-button
- >
- <el-button type="primary" plain @click="cancelHandle(operationForm.edb_id?'':'cancel')">取消</el-button>
- </div>
- <el-popover
- placement="top-start"
- width="500"
- trigger="click">
- <p style="padding:30px;line-height:25px;" v-html="$parent.tips.get('alpha')"/>
- <span slot="reference" class="tip-label">公式说明</span>
- </el-popover>
- </div>
- </el-dialog>
- </template>
- <script>
- import { dataBaseInterface } from '@/api/api.js';
- import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
- import { formRules } from './util';
- const tag_arr = [];
- for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
- export default {
- props:{
- isOpenSmooth:{
- type:Boolean,
- default:false
- },
- computedSource:{ //常规 or 批量
- type:Number,
- default:1
- },
- operationForm:{
- type:Object,
- default:()=>{return{
- edb_id:'',
- oldedb_id:''
- }}
- },
- isPredict:{ //是不是预测指标
- type:Boolean,
- default:false,
- }
- },
- data() {
- return {
- /* 常规 */
- formData:{
- targetName:'',
- unit:'',
- menu:'',
- frequency:'',
- alphaValue:''
- },
- formRules,
- frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
- catalogArr:[],
- levelProps: {
- label: 'ClassifyName',
- value: 'ClassifyId',
- children: 'Children',
- emitPath: false,
- checkStrictly: true
- },
- select_target:'',
- search_page:1,
- search_have_more:false,
- searchOptions:[],
- current_search:'',
- tableData:[],
- page_no:1,
- haveMore:false,
- tableColums:[
- {
- label: '指标ID',
- key: 'EdbCode',
- },
- {
- label: '指标名称',
- key: 'EdbName',
- },
- {
- label: '频度',
- key: 'Frequency',
- },
- {
- label: '单位',
- key: 'Unit',
- },
- {
- label: '起始时间',
- key: 'StartDate',
- minwidthsty: '100px'
- },
- {
- label: '更新时间',
- key: 'ModifyTime',
- minwidthsty: '110px'
- },
- {
- label: '来源',
- key: 'SourceName',
- },
- ],
- dataList:[],
- /* 批量 */
- targetList:[/* {
- tag:'A',
- target:123456 //edbid
- ...formData
- } */],
- formDataList:[],
- loading:false,
- };
- },
- watch:{
- isOpenSmooth(newVal){
- if(newVal){
- this.getMenu()
- if(this.operationForm.edb_id){
- this.select_target = this.operationForm.oldedb_id
- this.getDataList()
- this.setDefaultOption(this.operationForm,'edit')
- //回显时的默认options
- this.searchOptions = [
- {
- EdbInfoId: this.operationForm.oldedb_id,
- EdbName: this.operationForm.oldEdb_name,
- }
- ]
- }
- if(this.computedSource===2){
- this.addTargetHandle()
- this.addTargetHandle()
- }
- }
- }
- },
- methods: {
- init(){
- this.$refs.form&&(this.$refs.form.resetFields());
- Object.assign(this.$data, this.$options.data());
- },
- searchLoad() {
- if(!this.search_have_more) return;
- this.searchApi(this.current_search,++this.search_page)
- },
- async searchApi(query,page=1){
- const params = {
- KeyWord:query,
- CurrentIndex: page,
- }
- const res = this.isPredict
- ? await preDictEdbInterface.edbSearch(params)
- : await dataBaseInterface.targetSearchByPage(params)
- if(res.Ret !== 200) return
- const { List,Paging } = res.Data;
- this.search_have_more = page < Paging.Pages;
- let arr = page === 1 ? List : this.searchOptions.concat(List);
- this.searchOptions = arr;
- },
- /* 指标列表 */
- getTarget(query) {
- this.search_page = 1;
- this.current_search = query;
- this.searchApi(this.current_search);
- },
- /* 聚焦获取当前检索 */
- inputFocusHandle(e) {
- this.search_page = 1;
- this.current_search = e.target.value;
- this.searchApi(this.current_search);
- },
- /* 获取目录结构 */
- async getMenu() {
- const res = this.isPredict
- ? await preDictEdbInterface.classifyListV2()
- : await dataBaseInterface.menuListV3()
- if(res.Ret!==200) return
- // this.catalogArr = res.Data.AllNodes || [];
- if(!this.isPredict){
- this.filterNodes(res.Data.AllNodes||[]);
- this.catalogArr = res.Data.AllNodes || [];
- }else{
- this.catalogArr = res.Data.AllNodes || [];
- }
- },
- // 递归改变第三级目录结构
- filterNodes(arr) {
- arr.length &&
- arr.forEach((item) => {
- item.Children.length && this.filterNodes(item.Children);
- if (!item.Children.length) {
- delete item.Children;
- }
- });
- },
- /* 选择指标 */
- chooseTarget(val) {
- if(val) {
- let obj = this.searchOptions.find(item => item.EdbInfoId === val);
- //同步指标信息
- this.setDefaultOption(obj);
- this.page_no = 1;
- this.dataList.length ? this.$refs.dataUl.scrollTop = 0 : null;
- this.getDataList()
- }else {
- this.tableData = [];
- this.dataList = [];
- }
- },
- chooseTargetList(val,index){
- if(val){
- const obj = this.searchOptions.find(item => item.EdbInfoId === val);
- this.targetList[index].targetName = `${obj.EdbName}指数修匀`
- this.targetList[index].unit = obj.Unit
- this.targetList[index].frequency = obj.Frequency
- this.targetList[index].menu = obj.ClassifyId||''
- this.targetList[index].alphaValue =obj.Formula||''
- }
- },
- setDefaultOption(obj,type){
- this.formData = {
- targetName:`${obj.EdbName}${type==='edit'?'':'指数修匀'}`,
- unit:obj.Unit,
- frequency:obj.Frequency,
- menu:obj.ClassifyId||'',
- alphaValue:obj.Formula||''
- }
- },
- async getDataList(){
- const params = {
- PageSize: 10,
- CurrentIndex: this.page_no,
- EdbInfoId: this.select_target,
- }
- const res = this.isPredict
- ? await preDictEdbInterface.edbDataInfo(params)
- : await dataBaseInterface.targetList(params)
- if(res.Ret!==200) return
- if(res.Data){
- res.Data.Item.ModifyTime = res.Data.Item.ModifyTime.substr(0,10);
- this.tableData = [res.Data.Item] || [];
- this.haveMore = this.page_no < res.Data.Paging.Pages ? true : false;
- this.dataList = this.page_no === 1 ? (res.Data.Item.DataList || []) : this.dataList.concat(res.Data.Item.DataList);
- }else{
- this.tableData = [];
- this.dataList = [];
- }
- },
- handleSelectBtnClick(){
- //计算指标打开弹窗,基础指标打开新页面
- if(this.tableData[0].EdbType===2){
- this.$emit('lookHistory',this.select_target)
- }else{
- const {ClassifyId,UniqueCode,EdbInfoId} = this.tableData[0]
- let {href} = this.$router.resolve({path:`/database`,query:{code:UniqueCode,id:EdbInfoId,classifyId:ClassifyId}});
- window.open(href,'_blank');
- }
- },
- scrollHandle(e){
- const dom = e.target
- let scrollTop = dom.scrollTop; //滑入屏幕上方的高度
- let windowHeitht = dom.clientHeight; //页面的高度
- let scrollHeight = dom.scrollHeight; //整个div的高度
- let total = scrollTop + windowHeitht
- if(total >= scrollHeight && this.haveMore){
- this.page_no ++;
- this.getDataList();
- }
- },
- /* 删除已选指标 */
- delTarget() {
- this.tableData = [];
- this.dataList = [];
- this.select_target = '';
- this.page_no = 1;
- },
- delTargetList(index){
- this.targetList.splice(index, 1);
- },
- clearHandle(index){
- const item = {...{tag:tag_arr[index],target:''},..._.cloneDeep(this.formData)}
- this.targetList.splice(index,1,item)
- },
-
- addTargetHandle(){
- if(this.targetList.length >= 26){
- this.$message.warning('添加指标个数已达上限')
- return
- }
- let tag = 'A'
- let index = -1
- if(this.targetList.length>=1){
- tag = this.targetList[this.targetList.length-1].tag;
- index = tag_arr.findIndex(item => item === tag);
- }
- const item = {...{tag:tag_arr[index+1],target:''},..._.cloneDeep(this.formData)}
- this.targetList.push(item)
- },
- saveBtnClick(){
- this.computedSource===1?this.saveHandle():this.saveListHandle()
- },
- //常规编辑/保存指标
- async saveHandle(){
- if(!this.select_target){
- this.$message.warning('指标不能为空')
- return
- }
- await this.$refs.form.validate();
- this.loading = true;
- const {targetName,unit,menu,frequency,alphaValue} = this.formData
- let params = {
- Source:this.$route.path==='/database'?72:73,
- EdbName:targetName,
- Unit:unit,
- ClassifyId:menu,
- Frequency:frequency,
- Formula:alphaValue,
- FromEdbInfoId:this.select_target
- }
- let res = null
- if(this.isPredict){
- let edit_params = { ...params,EdbInfoId: this.operationForm.edb_id }
- res = await preDictEdbInterface.operateEdbSave(this.operationForm.edb_id ? edit_params : params)
- }else{
- res = this.operationForm.edb_id
- ? await dataBaseInterface.calculateTargetEdit({ ...params,EdbInfoId: this.operationForm.edb_id })
- : await dataBaseInterface.calculateTargetSave(params)
- }
- if(res.Ret!==200) return
- this.$message.success(res.Msg)
- this.operationForm.edb_id
- ? this.$emit('addCallBack','edit')
- : this.$emit('addCallBack','add',{ code:res.Data.UniqueCode,id:res.Data.EdbInfoId,classifyId:params.ClassifyId });
- this.init();
- this.loading = false;
- },
- //批量添加指标
- async saveListHandle(){
- //只添加选择了指标的
- const targetCheck = this.targetList.filter(item=>item.target)
- /* if(targetCheck.length!==this.targetList.length){
- this.$message.warning('请选择指标')
- return
- } */
- //只验证选择了指标的form-rules
- for(let i = 0;i<targetCheck.length;i++){
- const index = tag_arr.findIndex(item=>item===targetCheck[i].tag)
- await this.$refs[`list_form_${index}`][0].validate();
- }
- this.loading = true
- const params = targetCheck.map(item=>{
- return {
- CalculateId: item.tag,
- CalculateInfo: {
- ClassifyId: item.menu,
- EdbName: item.targetName,
- Formula: item.alphaValue,
- Frequency:item.frequency,
- FromEdbInfoId: item.target,
- Source:this.$route.path==='/database'?72:73,
- Unit: item.unit
- }
- }
- })
- const res = this.$route.path==='/database'
- ? await dataBaseInterface.batchCalculateTargetAdd(params)
- : await preDictEdbInterface.batchCalculateTargetAdd(params)
- if(res.Ret !== 200) return
- const { Fail,Success } = res.Data;
- if(Fail.length) {
- let message = '';
- Fail.forEach(item => {
- message+=`${item.CalculateId}:${item.Msg}</br>`
- })
- this.$message({
- dangerouslyUseHTMLString: true,
- message,
- type: 'error'
- })
- this.dealFailHandle(Fail)
- }else {
- this.$message.success('添加成功');
- this.init();
- this.$emit('addCallBack','add',{ code:Success[0].UniqueCode,id:Success[0].EdbInfoId,classifyId:Success[0].ClassifyId});
- this.loading = false;
- }
- },
- dealFailHandle(arr){
- //从targetList中剔除成功的指标,重新赋予剩下的指标tag
- const failTagArr = arr.map(_ =>_.CalculateId);
- this.targetList = this.targetList.filter(_ => failTagArr.includes(_.tag));
- this.targetList.forEach((item,index)=>{
- item.tag = tag_arr[index]
- })
- this.loading = false;
- },
- cancelHandle(type) {
- this.init();
- this.$emit('cancel');
- type==='cancel' && this.$emit('openPrev');
- },
- },
- };
- </script>
- <style lang="scss">
- .smooth-edb-dialog{
- .el-dialog__body{
- padding: 25px 25px 30px !important;
- padding-bottom: 5px !important;
- }
- }
- .smooth-edb-dialog-wrap{
- .el-cascader .el-input {
- width: 340px;
- }
- .min-top {
- padding: 20px 30px;
- border: 1px solid #ECECEC;
- box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
- border-radius:4px;
- }
- .middle {
- margin-top: 20px;
- .data-ul {
- margin-top: 5px;
- border-bottom: 1px solid #dcdfe6;
- max-height: 140px;
- overflow-y: auto;
- .value-item {
- padding: 14px 0;
- border: 1px solid #dcdfe6;
- border-bottom: none;
- display: flex;
- justify-content: space-around;
- .value-label {
- position: relative;
- color: #666;
- }
- .new-tag {
- width: 6px;
- height: 6px;
- display: inline-block;
- position: absolute;
- left: -12px;
- top: 50%;
- transform: translateY(-50%);
- border-radius: 50%;
- background: #f00;
- }
- }
- }
- .form-cont {
- padding-top: 30px;
- margin-top: 30px;
- border-top: 1px dashed #AAB4CC;
- input::-webkit-outer-spin-button,
- input::-webkit-inner-spin-button {
- -webkit-appearance: none;
- }
- input[type="number"]{
- -moz-appearance: textfield;
- }
- }
- }
- .dia-bot {
- padding: 20px 0 30px;
- display: flex;
- justify-content: center;
- }
- .tip-label {
- position: absolute;
- bottom: 30px;
- right: 30px;
- color: #409EFF;
- cursor: pointer;
- }
- .batch-wrap{
- padding:0 40px;
- .target-ul {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- .target-li {
- position: relative;
- margin-bottom: 30px;
- .li-tag {
- font-size: 16px;
- margin-right: 8px;
- }
- .del-tag {
- position: absolute;
- right: -30px;
- top: 12px;
- font-size: 16px;
- cursor: pointer;
- }
- .target-date {
- color: #5882ef;
- position: absolute;
- bottom: -25px;
- left: 24px;
- }
- }
- }
- .add-icon {
- font-size: 16px;
- color: #5882ef;
- cursor: pointer;
- }
- .form-ul {
- padding-top: 20px;
- margin-top: 20px;
- border-top: 1px dashed #AAB4CC;
- .form-li {
- display: flex;
- align-items: center;
- margin-bottom: 15px;
- .el-cascader>.el-input{
- width:100%;
- }
- .el-form-item{
- margin-bottom: 0;
- }
- .li-tag{
- margin-right: 20px;
- }
- }
- }
- }
-
- }
- </style>
|