Browse Source

merge master

bding 1 year ago
parent
commit
00e34d8914
28 changed files with 2036 additions and 112 deletions
  1. 21 0
      src/api/modules/aiApi.js
  2. 13 0
      src/api/modules/chartApi.js
  3. 4 5
      src/api/modules/setApi.js
  4. BIN
      src/assets/img/eta_base_config/ETA_title.png
  5. BIN
      src/assets/img/icons/ai-upload.png
  6. BIN
      src/assets/img/icons/file-upload.png
  7. BIN
      src/assets/img/icons/file_type_pdf.png
  8. BIN
      src/assets/img/icons/file_type_ppt.png
  9. BIN
      src/assets/img/icons/file_type_unknown.png
  10. 29 19
      src/views/Login.vue
  11. 2 1
      src/views/dataEntry_manage/chartSetting.vue
  12. 356 0
      src/views/dataEntry_manage/databaseComponents/batchComputedSave.vue
  13. 982 0
      src/views/dataEntry_manage/databaseComponents/batchComputedV2.vue
  14. 93 6
      src/views/dataEntry_manage/databaseComponents/computedDialog.vue
  15. 14 10
      src/views/dataEntry_manage/databaseComponents/diffusionIndexDia.vue
  16. 7 0
      src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue
  17. 14 0
      src/views/dataEntry_manage/databaseComponents/jointTargetDia.vue
  18. 71 13
      src/views/dataEntry_manage/databaseComponents/operationDialog.vue
  19. 69 1
      src/views/dataEntry_manage/databaseComponents/util.js
  20. 64 9
      src/views/dataEntry_manage/databaseList.vue
  21. 4 3
      src/views/dataEntry_manage/thirdBase/icpiConsumption.vue
  22. 176 23
      src/views/operation_manage/AIQA/AIQA.vue
  23. 42 4
      src/views/operation_manage/AIQA/components/messageItem.vue
  24. 21 2
      src/views/ppt_manage/newVersion/pptEnPublish.vue
  25. 18 8
      src/views/ppt_manage/newVersion/pptPublish.vue
  26. 3 3
      src/views/ppt_manage/newVersion/utils/config.js
  27. 25 4
      src/views/system_manage/enAuthManage.vue
  28. 8 1
      src/views/system_manage/etaBaseConfig.vue

+ 21 - 0
src/api/modules/aiApi.js

@@ -47,5 +47,26 @@ export const aiQAInterence = {
      */
     editTopicName:params=>{
         return http.post('/ai/topic/edit',params)
+    },
+    /**
+     * AI文件上传
+     * @param {FormData} params
+     * @param {Object} params.File 文件
+     * @param {Number} params.AiChatTopicId 窗口Id
+     * @returns 
+    */
+    fileUpload:params=>{
+        return http.post('/ai/file/upload',params)
+    },
+    /**
+     * AI文件检索
+     * @param {Object} params
+     * @param {Number} params.AiChatTopicId
+     * @param {String} params.Ask
+     * @param {Array} params.OpenaiFileId [String]
+     * @returns 
+    */
+    fileRetrieve:params=>{
+        return http.post('/ai/file/retrieve',params)
     }
 }

+ 13 - 0
src/api/modules/chartApi.js

@@ -410,6 +410,14 @@ const dataBaseInterface = {
 	edbAddBatch: params => {
 		return http.post('/datamanage/edb_info/batch/add',params)
 	},
+	// 批量计算指标时获取当前筛选条件下选择的指标
+	getBatchFilterAddEdbList:params=>{
+		return http.get('/datamanage/edb_info/calculate/multi/choice',params)
+	},
+	//批量计算指标时待选指标的搜索列表
+	getBatchAddEdbSearchList:params=>{
+		return http.get('/datamanage/edb_info/calculate/multi/search',params)
+	},
 	//========================================chart
 	// /**
 	//  * 
@@ -839,6 +847,11 @@ const dataBaseInterface = {
 		return http.post('/datamanage/edb_info/calculate/batch/save/batch',params)
 	},
 
+	//批量计算编辑
+	batchCalculateTargetEdit: params => {
+		return http.post('/datamanage/edb_info/calculate/batch/edit/batch',params)
+	},
+
 	/**
 	 * 获取计算指标与基础指标关联信息
 	 * @param EdbInfoId

+ 4 - 5
src/api/modules/setApi.js

@@ -339,13 +339,12 @@ const departInterence = {
 		return http.get('/user_login/area_code/list',params)
 	},
 	/**
-	 * 获取备案信息
-	 * @returns 
+	 * 获取登录页的信息 
+	 * @returns ETATitle登录标题 Icp备案信息
 	*/
-	getICPLicense:params=>{
-		return http.get('/user_login/icp_license',params)
+	getBaseInfo:params=>{
+		return http.get('/user_login/base_info',params)
 	}
-
 }
 
 /* 视频管理 */

BIN
src/assets/img/eta_base_config/ETA_title.png


BIN
src/assets/img/icons/ai-upload.png


BIN
src/assets/img/icons/file-upload.png


BIN
src/assets/img/icons/file_type_pdf.png


BIN
src/assets/img/icons/file_type_ppt.png


BIN
src/assets/img/icons/file_type_unknown.png


+ 29 - 19
src/views/Login.vue

@@ -3,7 +3,7 @@
 		<div id="login_wrapper">
       
             <img class="login-bg" :src="$setting.login_bg" alt />
-            <img class="login-icon" :src="$setting.login_logo" />
+            <!-- <img class="login-icon" :src="$setting.login_logo" /> -->
 			<!-- <el-form
 				:model="ruleForm"
 				:rules="rules"
@@ -66,7 +66,8 @@
 			</el-form>  -->
 			<div class="login-box" id="login-container" v-if="activeModel!=='forgetPassModel'">
                 <div class="fixed-login-cont">
-                    <span class="login-title">ETA — 让投研领先市场半步</span>
+                    <span class="login-title">{{ loginTitle }}</span>
+                    <span class="login-sub-title">ETA — 让投研领先市场半步</span>
                     <el-tabs v-model="activeModel" >
                         <!-- <el-tab-pane label="账号登录" name="ordinaryModel">
                             <OrdinaryModel ref="ordinaryModel"
@@ -135,7 +136,8 @@
 			</div>
 		</div>
         <div class="record-info">
-            <span v-for="(item,index) in recordInformation" :key="index">{{ item }}</span>
+            <a v-for="(item,index) in recordInformation" :key="index" target="_blank"
+            href="https://beian.miit.gov.cn/#/Integrated/index">{{item}}</a>
         </div>
 		<!-- 验证弹窗 -->
 		<el-dialog
@@ -292,7 +294,8 @@ export default {
                         </defs></svg>`
                 },
             ],
-            recordInformation:[]
+            recordInformation:[],
+            loginTitle:''
         };
     },
     created() {
@@ -406,9 +409,10 @@ export default {
             })
         },
         getRecordInfo(){
-            departInterence.getICPLicense().then(res=>{
+            departInterence.getBaseInfo().then(res=>{
                 if(res.Ret == 200){
-                    this.recordInformation = res.Data.ConfVal.split(/\s{2,}/)
+                    this.recordInformation = res.Data.Icp?res.Data.Icp.ConfVal.split(/\s{2,}/):[]
+                    this.loginTitle = res.Data.ETATitle?res.Data.ETATitle.ConfVal:''
                 }
             })
         },
@@ -675,19 +679,25 @@ export default {
 			height: 90%;
 		}
 
-		.login-icon {
-			position: absolute;
-			top: 40px;
-			right: 40px;
-		}
+		// .login-icon {
+		// 	position: absolute;
+		// 	top: 40px;
+		// 	right: 40px;
+		// }
 		.login-title {
-			color: #333;
-			font-size: 32px;
+			color: #0052D9;
+			font-size: 28px;
 			display: block;
 			text-align: center;
-			margin-bottom: 60px;
+			margin-bottom: 25px;
+		}
+		.login-sub-title {
+			color: #7780B1;
+			font-size: 18px;
+			display: block;
+			text-align: center;
+			margin-bottom: 20px;
 		}
-
 		#login-container ,.login-box{
 			box-sizing: border-box;
 			border-radius: 10px;
@@ -825,10 +835,10 @@ export default {
         flex-wrap: wrap;
         justify-content: center;
         width: 100%;
-        font-size: 15px;
-        color: #C0C4CC;
-        text-align: center;
-        span{
+        a{
+            font-size: 15px;
+            color: #C0C4CC;
+            text-align: center;
             margin: 0 6px;
         }
     }

+ 2 - 1
src/views/dataEntry_manage/chartSetting.vue

@@ -1373,7 +1373,8 @@ export default {
 
 			if(targetIndex===0){
 				PrevClassifyId=0
-				NextClassifyId=list[targetIndex+1].data.ChartClassifyId
+        // i=='inner'时,list里面只有一个Node时会数组越界,后面会对'inner'的重新处理,这里不报错就行
+				NextClassifyId=list[targetIndex+1] ? list[targetIndex+1].data.ChartClassifyId : 0
 			}else if(targetIndex===list.length-1){
 				PrevClassifyId=list[targetIndex-1].data.ChartClassifyId
 				NextClassifyId=0

+ 356 - 0
src/views/dataEntry_manage/databaseComponents/batchComputedSave.vue

@@ -0,0 +1,356 @@
+<template>
+    <div class="batch-computed-save-wrap">
+        <el-table 
+            :data="list" 
+            border 
+            height="500px"
+        >
+            <el-table-column label="指标全称" align="center" prop="EdbName"/>
+            <el-table-column label="生成指标名称" align="center">
+                <template slot-scope="scope">
+                    <el-input :disabled="operationForm.view" v-model="scope.row.name" placeholder="请填写指标名称" style="width:100%"/>
+                </template>
+            </el-table-column>
+            <el-table-column label="单位" align="center" width="200px">
+                <template slot-scope="scope">
+                    <selectUnit :disabled="operationForm.view||[6].includes(sourceTypeVal)" v-model="scope.row.unit"/>
+                </template>
+            </el-table-column>
+            <el-table-column label="频度" align="center" width="200px">
+                <template slot-scope="scope">
+                    <el-select
+						v-model="scope.row.frequency"
+						placeholder="请选择频率"
+                        @change="handleFrequencyChange(scope)"
+                        :disabled="operationForm.view||[5,6,14,61,63].includes(sourceTypeVal)"
+					>
+						<el-option
+							v-for="item in frequencyArr"
+							:key="item"
+							:label="item"
+							:value="item"
+						>
+						</el-option>
+					</el-select>
+                </template>
+            </el-table-column>
+            <el-table-column align="center" width="300px">
+                <template slot="header" slot-scope="scope">
+                    <span style="margin-right:40px;display:inline-block">目录</span>
+                    <el-radio-group :disabled="operationForm.view" v-model="classifyType" @change="handleClassifyTypeChange">
+                        <el-radio :label="0">分目录</el-radio>
+                        <el-radio :label="1">同目录</el-radio>
+                    </el-radio-group>
+                </template>
+                <template slot-scope="{row,$index}">
+                    <el-cascader
+						v-model="row.classify"
+						:options="classifyOpt"
+						:props="levelProps"
+						placeholder="请选择指标目录"
+                        :disabled="(classifyType===1&&$index>0)||operationForm.view"
+                        @change="handleClassifyChange(row,$index)"
+					/>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div style="text-align:center;margin:60px 0 40px 0" v-if="!operationForm.view">
+            <el-button type="primary" plain @click="handleClose">取消</el-button>
+            <el-button type="primary" @click="handleSubmit" :loading="loading">{{loading ? '批量计算中...' : '批量计算'}}</el-button>
+        </div>
+    </div>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import {generateSeriesArray} from './util'
+const tag_arr = generateSeriesArray();
+export default {
+    props:{
+        computedType:null,
+        subComputedType:null,
+        selectList:null,
+        formData:null,
+        select_target:null,
+        operationForm:null,
+        isEdit:false
+    },
+    computed: {
+        sourceTypeVal(){
+            if(!this.computedType) return 0
+            if(this.subComputedType) return this.subComputedType
+            return ['withNum','withEDB'].includes(this.computedType)?4:this.computedType
+        }
+    },
+    data() {
+        return {
+            frequencyArr: ['日度', '周度','旬度','月度', '季度', '年度'],
+
+            list:[],
+
+            classifyType:0,
+            classifyOpt: [],
+			levelProps: {
+				label: 'ClassifyName',
+				value: 'ClassifyId',
+				children: 'Children',
+				checkStrictly: true,
+                emitPath:false
+			},
+
+            loading:false,
+
+            computedArr:[],//多指标求和\平均的指标数组
+        }
+    },
+    mounted() {
+        this.initData()
+        this.getClassifyOpt()
+    },
+    methods: {
+        // 初始化数据
+        initData(){
+            let arr=[]
+
+            // 如果是多指标求和\平均
+            if(this.computedType==='multipleEDB'){
+                this.computedArr=this.selectList
+                // 如果是编辑时
+                if(this.isEdit){
+                    this.list=[{
+                        EdbName:this.operationForm.EdbInfoDetail.EdbName,
+                        EdbInfoId:this.operationForm.EdbInfoDetail.EdbInfoId,
+                        name:this.operationForm.EdbInfoDetail.EdbName,
+                        unit:this.operationForm.EdbInfoDetail.Unit,
+                        frequency:this.operationForm.EdbInfoDetail.Frequency,
+                        classify:this.operationForm.EdbInfoDetail.ClassifyId
+                    }]
+                    return
+                }
+                arr=[{...this.selectList[0]}]
+            }else{
+                arr=this.selectList
+            }
+            
+            
+            arr.forEach(item=>{
+                this.setDefaultVal(item)
+            })
+            
+        },
+        // 设置默认值
+        setDefaultVal(item){
+            const obj={
+                EdbName:item.EdbName,
+                EdbInfoId:item.EdbInfoId,
+                name:'',
+                unit:'',
+                frequency:'',
+                classify:''
+            }
+            const tMap=new Map([
+				['日度','D'],
+				['周度','W'],
+				['旬度','T'],
+				['月度','M'],
+				['季度','Q'],
+				['年度','Y'],
+			])
+			const name_map = {
+                4:item.EdbName,
+				5: `${item.EdbName}转月值`,
+				8: `${item.EdbName}/${this.formData.nNum}${tMap.get(item.Frequency)}MA`,
+				14: `${item.EdbName}/日频`,
+				6: `${item.EdbName}同比`,
+				7: `${item.EdbName}同差`,
+				12: `${item.EdbName}${this.formData.nNum}${item.Frequency.slice(0,1)}环比`,
+				13: `${item.EdbName}${this.formData.nNum}${item.Frequency.slice(0,1)}环差`,
+				35: `${item.EdbName}超季节性/${this.formData.nNum}年${this.formData.calendarType==='公历'?'':'/'+this.formData.calendarType}`,
+				52: `${item.EdbName}年化值`,
+				51: `${item.EdbName}/${this.formData.frequency.substr(0,1)}频`,
+				61:  `${item.EdbName}转季值`,
+				62:  `${item.EdbName}累计值/${this.formData.frequency}`,
+				63:  `${item.EdbName}年初至今累计值`,
+                72:`${item.EdbName}指数修匀`,
+				75: `${item.EdbName}日均值`,
+                81:item.EdbName,
+                82:item.EdbName,
+			}
+			
+			let frequerncyMap = {
+				14: '日度',
+				61: '季度',
+                62:this.formData.frequency,
+                51:this.formData.frequency,
+			}
+
+            obj.name=name_map[this.sourceTypeVal] || ''
+            obj.frequency=frequerncyMap[this.sourceTypeVal]|| item.Frequency
+            obj.classify=item.ClassifyId||''
+
+            if([5,8,14,7,35,75].includes(this.sourceTypeVal)){
+                obj.unit=item.Unit
+            }else if([4].includes(this.sourceTypeVal)){
+                obj.unit=''
+            }else{
+                obj.unit='无'
+            }
+            
+
+            this.list.push(obj)
+        },
+        // 频度变化 修改指标名
+		handleFrequencyChange(e){
+			if(!this.sourceTypeVal||![51,62].includes(this.sourceTypeVal)) return;
+            const obj=this.list[e.$index]
+			const name_map = {
+				51: `${obj.EdbName}/${obj.frequency.substr(0,1)}频`,
+				62:  `${obj.EdbName}累计值/${obj.frequency}`,
+			}
+			this.list[e.$index].name=name_map[this.sourceTypeVal]
+		},
+
+        // 同目录修改
+        handleClassifyChange(e,index){
+            if(this.classifyType===1){
+                // 修改所有的指标的目录为第一个
+                this.list.forEach(item=>{
+                    item.classify=e.classify
+                })
+            }
+        },
+
+        handleClassifyTypeChange(){
+            this.handleClassifyChange(this.list[0])
+        },
+
+        // 提交计算
+        async handleSubmit(){
+            const edbList=this.list.map((item,index)=>{
+                return{
+                    CalculateId:tag_arr[index],
+                    ClassifyId:item.classify,
+                    EdbName:item.name,
+                    Frequency:item.frequency,
+                    Unit:item.unit,
+                    FromEdbInfoId:this.isEdit?0:item.EdbInfoId,
+                    EdbInfoId:this.isEdit?item.EdbInfoId:0
+                }
+            })
+            const valueMap = {
+				51: 'valueType',
+                72:'alphaValue'
+			}
+            const params={
+                EdbList:edbList,
+                Formula:valueMap[this.sourceTypeVal] ? String(this.formData[valueMap[this.sourceTypeVal]]) : String(this.formData.nNum),
+                Source:this.sourceTypeVal,
+                CalculateFormula:this.sourceTypeVal===4? JSON.stringify([{f:this.formData.formula,d:''}]) : this.formData.formula,
+                EdbInfoIdArr:this.select_target?[{EdbInfoId:this.select_target,FromTag:'B'}]:[],
+                MoveType:0,
+                MoveFrequency:'',
+                Calendar:this.formData.calendarType,
+                EmptyType: this.formData.nullValueWay,
+				MaxEmptyType: this.formData.maxNullWay,
+                Extra:JSON.stringify({
+                    LastValType:this.formData.newValue,
+                    DateTag:this.formData.timeSeriesVal
+                })
+            }
+            // 处理多指标求和\平均 情况的数据
+            if(this.computedType==='multipleEDB'){
+                const arr=this.computedArr.map((item,index)=>{
+                    return{
+                        EdbInfoId:item.EdbInfoId,
+                        FromTag:tag_arr[index]
+                    }
+                })
+                params.EdbInfoIdArr=arr
+            }
+            console.log(params);
+
+            let isEnough = params.EdbList.every(item => item.EdbName&&item.Unit&&item.ClassifyId&&item.Frequency)
+            if(!isEnough) return this.$message.warning('请填写完整信息');
+
+            this.loading=true
+            const tipMsg=setTimeout(() => {
+                this.$message.success('请等待计算完成,该过程可能持续2-3分钟')
+            }, 500);
+            const res=this.isEdit?await dataBaseInterface.batchCalculateTargetEdit(params) : await dataBaseInterface.batchCalculateTargetAdd(params)
+            this.loading=false
+            clearTimeout(tipMsg)
+            
+            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});
+            }
+
+        },
+
+        // 处理批量添加失败的指标
+        dealFailHandle(data){
+            let temarr=[]
+            data.forEach(item=>{
+                const index=tag_arr.indexOf(item.CalculateId)
+                temarr.push(this.list[index])
+            })
+            this.list=temarr
+        },
+
+
+        handleClose(){
+            this.$emit('close')
+        },
+        filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (!item.Children.length) {
+						delete item.Children;
+					}
+				});
+		},
+        // 获取指标分类
+        async getClassifyOpt(){
+            const res=await dataBaseInterface.menuListV3()
+            if (res.Ret !== 200) return
+            this.filterNodes(res.Data.AllNodes||[]);
+			this.classifyOpt = res.Data.AllNodes || [];
+        },
+    },
+}
+</script>
+
+<style lang="scss">
+.batch-computed-save-wrap{
+    .el-input{
+        input{
+            border: none;
+            text-align: center;
+        }
+    }
+    .el-table tr{
+        background-color: #fff !important;
+        &:hover>td{
+            background-color: transparent !important; /* 或者其他想要的颜色值 */
+        }
+    }
+}
+</style>

+ 982 - 0
src/views/dataEntry_manage/databaseComponents/batchComputedV2.vue

@@ -0,0 +1,982 @@
+<template>
+    <el-dialog
+		:visible.sync="isShow"
+		:close-on-click-modal="false"
+		:modal-append-to-body="false"
+		@close="handleClose"
+		custom-class="batch-computed-dialog fit-screen-dialog"
+		center
+		top="5vh"
+		v-dialogDrag
+        :title="showSave?'批量计算-结果保存':'批量计算-选择指标和计算公式'"
+	>
+        <div class="batch-computed-wrap" v-if="!showSave">
+            <el-form inline :disabled="operationForm.view">
+            <div class="type-wrap">
+                <div style="margin-right:50px">
+                    <span>计算公式</span>
+                    <el-select :disabled="isEdit" v-model="computedType" @change="handleComputedTypeChange" placeholder="请选择">
+                        <el-option 
+                            v-for="opt in computedBatchTypes" 
+                            :key="opt.type" 
+                            :label="opt.name"
+                            :value="opt.type"
+                        />
+                    </el-select>
+                </div>
+                <div style="flex:1">
+                    <!-- 累计值转月/季值 -->
+                    <el-form-item v-if="computedType=='toMonthSeason'">
+                        <el-radio-group v-model="subComputedType" @change="handleComputedSubTypeChange">
+                            <el-radio :label="5">转月值</el-radio>
+                            <el-radio :label="61">转季值</el-radio>
+                        </el-radio-group>
+                    </el-form-item>
+
+                    <!-- N期移动均值、N期环比值、N期环差值 -->
+                    <el-form-item required v-if="[8,12,13].includes(computedType)" label="N等于" style="width:280px">
+                        <el-input v-model="formData.nNum" placeholder="请输入N数值" type="number" style="width:200px"></el-input>
+                    </el-form-item>
+
+                    <!-- 超级季节性 -->
+                    <template v-if="computedType==35">
+                    <el-form-item required label="N等于" style="width:280px">
+                        <el-input v-model="formData.nNum" placeholder="请输入N数值" type="number" style="width:200px"></el-input>
+                    </el-form-item>
+                    <el-form-item label="日历"  style="width:180px">
+                        <el-select v-model="formData.calendarType" style="width:120px">
+                            <el-option label="公历" value="公历"></el-option>
+                            <el-option label="农历" value="农历"></el-option>
+                        </el-select>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 降频 -->
+                    <template v-if="computedType==51">
+                    <el-form-item required label="频度" style="width:180px">
+                        <el-select v-model="formData.frequency" style="width:120px">
+                            <el-option v-for="opt in frequencyArr" :key="opt" :label="opt" :value="opt"></el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="数据取值"  style="width:200px">
+                        <el-select v-model="formData.valueType" style="width:120px">
+                            <el-option key="期末值" label="期末值" value="期末值"/>
+							<el-option key="平均值" label="平均值" value="平均值"/>
+                        </el-select>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 累计值 -->
+                    <template v-if="computedType=='accumulate'">
+                    <el-form-item>
+                        <el-radio v-model="subComputedType" :label="62">累计值</el-radio>
+                    </el-form-item>
+                    <el-form-item required label="频度" style="width:180px" v-if="subComputedType==62">
+                        <el-select v-model="formData.frequency" style="width:120px">
+                            <el-option v-for="opt in frequencyArr" :key="opt" :label="opt" :value="opt"></el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="最新值处理"  style="width:210px" v-if="subComputedType==62">
+                        <el-select v-model="formData.newValue" style="width:120px">
+                            <el-option label="默认" :value="0"/>
+							<el-option label="均值填充" :value="1"/>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item>
+                        <el-radio v-model="subComputedType" :label="63">年初至今累计值</el-radio>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 指数修匀 -->
+                    <template v-if="computedType==72">
+                    <el-form-item required label="alpha值" style="width:220px">
+                        <el-input v-model.trim="formData.alphaValue" style="width:140px" placeholder="请输入alpha值"></el-input>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 与常数计算 -->
+                    <template v-if="computedType=='withNum'">
+                    <el-form-item required label="公式">
+                        <el-input v-model="formData.formula" placeholder="请输入公式" clearable style="width: 200px"/>
+                        <span>公式示例:A+100,或A*2</span>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 与单指标计算 -->
+                    <template v-if="computedType=='withEDB'">
+                    <el-form-item required label="指标B">
+                        <el-select
+                            v-model="select_target"
+                            v-loadMore="searchLoad"
+                            :filterable="!select_target"
+                            clearable
+                            placeholder="请输入指标名称"
+                            style="width: 250px"
+                            remote
+                            :remote-method="getTarget"
+                            @click.native="inputFocusHandle"
+                            @change="chooseTarget"
+                            @blur="search_have_more = false"
+                        >
+                            <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-select>
+                    </el-form-item>
+                    <el-form-item required label="公式">
+                        <el-input v-model="formData.formula" placeholder="请输入公式" clearable style="width: 200px"/>
+                        <span>公式示例:A+B,或A/B,A/(A+B)</span>
+                    </el-form-item>
+                    <el-form-item label="生成指标时间序列">
+                        <el-cascader
+							v-model="formData.timeSeriesVal"
+							style="width:180px"
+							:options="timeSeriesOpt"
+							:props="{emitPath:false}"
+							:show-all-levels="false"
+							placeholder="请选择"
+						></el-cascader>
+                    </el-form-item>
+                    <el-form-item label="空值处理">
+                        <el-select
+							v-model="formData.nullValueWay"
+							placeholder="请选择"
+                            style="width:180px"
+						>
+							<el-option
+								v-for="item in nullWayOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							>
+							</el-option>
+						</el-select>
+                    </el-form-item>
+                    <el-form-item label="MAX、MIN空值处理" v-if="showMaxNullDeal">
+                        <el-select
+							v-model="formData.maxNullWay"
+							placeholder="请选择"
+						>
+							<el-option label="等于0" :value="1" />
+							<el-option label="跳过空值" :value="2" />
+						</el-select>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 多指标求和/平均 -->
+                    <template v-if="computedType=='multipleEDB'">
+                    <el-form-item style="margin-right:30px">
+                    <el-radio-group :disabled="isEdit" v-model="subComputedType">
+                        <el-radio :label="81">求和</el-radio>
+                        <el-radio :label="82">求平均</el-radio>
+                    </el-radio-group>
+                    </el-form-item>
+                    <el-form-item label="生成指标时间序列">
+                        <el-cascader
+							v-model="formData.timeSeriesVal"
+							style="width:180px"
+							:options="timeSeriesOpt"
+							:props="{emitPath:false}"
+							:show-all-levels="false"
+							placeholder="请选择"
+						></el-cascader>
+                    </el-form-item>
+                    <el-form-item label="空值处理">
+                        <el-select
+							v-model="formData.nullValueWay"
+							placeholder="请选择"
+                            style="width:180px"
+						>
+							<el-option
+								v-for="item in nullWayOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							>
+							</el-option>
+						</el-select>
+                    </el-form-item>
+                    </template>
+
+
+                </div>
+            </div>
+            </el-form>
+            <div class="filter-wrap" style="margin-top:20px">
+                <p style="margin-bottom:10px">待选指标(选择指标数量不超过{{MAXAddNUM}})</p>
+                <div>
+                    <el-cascader
+						v-model="filter.classify"
+						:options="classifyOpt"
+						:props="classifyProps"
+						clearable
+                        collapse-tags
+						placeholder="指标分类"
+                        style="width: 240px"
+                        @change="handleFilter"
+					/>
+                    <el-select
+						v-model="filter.frequency"
+						placeholder="请选择频率"
+						style="width: 140px"
+						clearable
+                        multiple
+                        collapse-tags
+                        @change="handleFilter"
+                        :disabled="[5,61].includes(subComputedType)"
+					>
+						<el-option
+							v-for="item in frequencyArr"
+							:key="item"
+							:label="item"
+							:value="item"
+						>
+						</el-option>
+					</el-select>
+                    <el-cascader
+                        v-model="filter.user"
+                        placeholder="创建人"
+                        :options="sysUserOpts"
+                        :props="sysUserProps"
+                        collapse-tags
+                        :show-all-levels="false"
+                        clearable
+                        filterable
+                        style="width:240px"
+                        @change="handleFilter"
+                    />
+                    <el-input 
+                        placeholder="指标ID/指标名称" 
+                        v-model="filter.keyword"
+                        style="width: 200px"
+                        @keydown.enter.native="handleFilter"
+                    >
+                        <i slot="prefix" class="el-input__icon el-icon-search"></i>
+                    </el-input>
+                    <el-checkbox 
+                        label="列表全选" 
+                        v-model="isCheckAll" 
+                        :indeterminate="isCheckIndeterminate" 
+                        style="margin-left:10px"
+                        @change="listCheckAllChange"
+                        :disabled="operationForm.view"
+                    />
+                </div>
+            </div>
+            <div class="table-wrap">
+                <div class="left-box">
+                    <el-table 
+                        :data="list" 
+                        border 
+                        @sort-change="sortChange"  
+                        @selection-change="selectionChange"
+                        ref="edbDataRef" 
+                        @select="selectHandle" 
+                        @select-all="selectAllHandle"
+                        height="500px"
+                        v-loading="listLoading"
+                    >
+                        <el-table-column type="selection" min-width="50" align="center"/>
+                        <el-table-column label="指标全称" show-overflow-tooltip align="center" prop="EdbName"/>
+                        <el-table-column label="最新日期" align="center" prop="EndDate" width="120px" />
+                        <el-table-column label="最新值" align="center" show-overflow-tooltip prop="EndValue" width="80px"/>
+                        <el-table-column label="创建人" align="center" show-overflow-tooltip prop="SysUserRealName" width="80px"/>
+                        <el-table-column label="频度" align="center" prop="Frequency" width="50px"/>
+                        <el-table-column label="单位" show-overflow-tooltip align="center" prop="Unit" width="50px"/>
+                    </el-table>
+                    <m-page 
+                        style="margin-top:10px"
+                        class="table-page" 
+                        v-show="total"
+                        :total="total" 
+                        :pageSize="pageSize"
+                        :page_no="page"
+                        :pagercount="5"
+                        @handleCurrentChange="pageNumberChange"
+                    />
+                </div>
+                <div style="padding-top:200px;margin:0 30px">
+                    <el-button type="primary" :disabled="operationForm.view" :loading="addLoading" @click="getAddEdbListData">加入已选指标</el-button>
+                </div>
+                <div class="right-box">
+                    <el-table 
+                        :data="selectList" 
+                        border 
+                        height="500px"
+                    >
+                        <el-table-column label="序号" width="50px" align="center" prop="No" v-if="computedType=='multipleEDB'">
+                            <template slot-scope="scope">
+                                {{scope.$index|getNoText}}
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="指标全称" show-overflow-tooltip align="center" prop="EdbName"/>
+                        <el-table-column width="50px" align="center" v-if="!operationForm.view">
+                            <template slot="header" slot-scope="scope">
+                                <img @click="handleDelSelect('all')" style="width:15px;height:15px;cursor: pointer;" src="~@/assets/img/ai_m/delete.png" alt="">
+                            </template>
+                            <template slot-scope="scope">
+                                <img @click="handleDelSelect(scope)" style="width:15px;height:15px;cursor: pointer;" src="~@/assets/img/ai_m/delete.png" alt="">
+                            </template>
+                        </el-table-column>
+                    </el-table>
+                </div>
+            </div>
+            <div style="text-align:center;margin:60px 0 40px 0">
+                <el-button type="primary" plain @click="handleCloseSelf">取消</el-button>
+                <el-button type="primary" @click="handleNextStep">下一步</el-button>
+            </div>
+        </div>
+        <!-- 结果保存 -->
+        <batchComputedSave 
+            :select_target="select_target"
+            :computedType="computedType" 
+            :subComputedType="subComputedType" 
+            :selectList="selectList" 
+            :formData="formData" 
+            :isEdit="isEdit"
+            :operationForm="operationForm"
+            @close="showSave=false" 
+            @addCallBack="handleAddSuccess"
+            v-else
+        />
+    </el-dialog>
+</template>
+
+<script>
+import mPage from '@/components/mPage.vue'
+import {computedBatchTypesV2} from './util'
+import { dataBaseInterface,departInterence } from '@/api/api.js';
+import batchComputedSave from './batchComputedSave.vue';
+import {generateSeriesArray} from './util'
+const tag_arr = generateSeriesArray();
+export default {
+    components:{mPage,batchComputedSave},
+    props:{
+        isShow:{
+            type: Boolean
+        },
+        operationForm: {
+			type: Object,
+		},
+        type: {
+			type: Number
+		},
+    },
+    filters:{
+        getNoText(e){
+            return tag_arr[e]
+        }
+    },
+    computed:{
+        // 最大添加指标的上限
+        MAXAddNUM(){
+            let num=50
+            if(this.computedType=='multipleEDB'){
+                num=100
+            }
+            return num
+        },
+        /* max空值处理显示 当输入的公式包含MAX、MIN且空值处理为0时,输入公式失焦后出现右侧选项; */
+		showMaxNullDeal() {
+			let haveMaxOrMin =  this.formData.formula.toUpperCase().includes('MAX') || this.formData.formula.toUpperCase().includes('MIN')
+
+			return haveMaxOrMin && this.formData.nullValueWay===4
+		},
+        timeSeriesOpt(){
+            let arr=[
+                {
+                    label:`指标A`,
+                    value:'A'
+                },
+                {
+                    label:`指标B`,
+                    value:'B'
+                }
+            ]
+            if(this.computedType=='multipleEDB'){
+                arr=this.selectList.map((item,index)=>{
+                    return{
+                        label:`指标${tag_arr[index]}`,
+                        value:tag_arr[index]
+                    }
+                })
+            }
+            return [
+                {
+                    label:'指定指标时间序列',
+					value:'0',
+                    children:arr
+                },
+                {
+					label:'所有指标时间序列并集',
+					value:'all',
+				}
+            ]
+        },
+
+        frequencyArr(){
+            if(this.computedType==75){
+                return ['周度','旬度','月度', '季度', '年度']
+            }
+            return ['日度', '周度','旬度','月度', '季度', '年度']
+        }
+    },
+    watch: {
+        isShow(n){
+            if(!n){
+                this.subComputedType=''
+                this.select_target=''
+                this.selectList=[]
+                this.tableDataCheckedList=[]
+                this.tableDataIds=[]
+                this.isCheckAll=false
+                this.isCheckIndeterminate=false
+                this.checkAllStatus=false
+                this.selectionReactCancel=false
+                this.isEdit=false
+                this.showSave=false
+                this.computedType=computedBatchTypesV2[0].type
+                this.filter={
+                    classify:'',
+                    frequency:'',
+                    user:'',
+                    keyword:''
+                }
+                this.formData={
+                    nNum:1,
+                    calendarType:'公历',
+                    frequency:'',
+                    valueType:'期末值',
+                    newValue:0,
+                    alphaValue:'',
+                    formula:'',
+                    timeSeriesVal:'A',
+                    nullValueWay:0,
+                    maxNullWay:1,
+                }
+            }else{
+                // 编辑多指标求和\平均
+                if([81,82].includes(this.type)){
+                    this.initData()
+                }
+                this.handleFilter()
+            }
+        }
+    },
+    data() {
+        return {
+            showSave:false,//显示结果保存模块
+            computedBatchTypes:computedBatchTypesV2,//计算类型筛选项
+            computedType:computedBatchTypesV2[0].type,//当前选中的计算类型
+            subComputedType:'',//二级计算类型
+            formData:{
+                nNum:1,
+                calendarType:'公历',
+                frequency:'',
+                valueType:'期末值',
+                newValue:0,
+                alphaValue:'',
+                formula:'',
+                timeSeriesVal:'A',
+                nullValueWay:0,
+                maxNullWay:1,
+            },
+
+            select_target:'',
+			searchOptions:[],//指标列表
+            search_have_more:false,
+            search_page: 1,
+			current_search: '',
+
+            filter:{
+                classify:'',
+                frequency:'',
+                user:'',
+                keyword:''
+            },
+
+            // frequencyArr: ['日度', '周度','旬度','月度', '季度', '年度'],
+            classifyOpt: [],
+			classifyProps: {
+				label: 'ClassifyName',
+				value: 'ClassifyId',
+				children: 'Children',
+				multiple: true,
+                emitPath:false
+			},
+            sysUserOpts:[],
+            sysUserProps:{
+                value: "AdminId",
+                label: "RealName",
+                children: "ChildrenList",
+                multiple: true,
+                emitPath:false
+            },
+
+            nullWayOptions: [
+				{ label: '查找前后35天最近值',value: 0 },
+				{ label: '不计算',value: 1 },
+				{ label: '前值填充',value: 2 },
+				{ label: '后值填充',value: 3 },
+				{ label: '等于0',value: 4 },
+			],
+
+            isCheckAll:false,//是否全选
+            isCheckIndeterminate:false,// 标志列表当前是全选状态还是不是全选状态和 isCheckAll不一样
+            checkAllStatus:false,
+            selectionReactCancel:false,// 是否不触发 selection的逻辑
+
+            listLoading:false,
+            page:1,
+            pageSize:20,
+            total:0,
+            list:[],
+
+            tableDataCheckedList:[],
+            tableDataIds:[],
+
+            selectList:[],//添加到右侧的数据
+            addLoading:false,
+
+            isEdit:false,//是否为多指标求和等编辑
+
+        }
+    },
+    mounted() {
+        this.getClassifyOpt()
+        this.getEDBList()
+        this.getSysUserList()
+    },
+    
+    methods: {
+        // 编辑时初始化数据
+        initData(){
+            this.isEdit=true
+            const arr=this.operationForm.CalculateList||[]
+            this.selectList=arr.map(item=>{
+                return {
+                    ClassifyId:item.ClassifyId,
+                    EdbInfoId:item.FromEdbInfoId,
+                    EdbName:item.FromEdbName,
+                    Frequency:item.Frequency,
+                    Unit:item.Unit
+                }
+            })
+            this.computedType='multipleEDB'
+            this.subComputedType=this.type
+            this.formData.timeSeriesVal=this.operationForm.EdbInfoDetail.Extra?JSON.parse(this.operationForm.EdbInfoDetail.Extra).DateTag:'A'
+            this.formData.nullValueWay=this.operationForm.EdbInfoDetail.EmptyType||0
+
+        },
+        //批量计算成功回调
+        handleAddSuccess(type,params){
+            this.$emit('addCallBack',type,params)
+        },
+        // 跳转下一步
+        handleNextStep(){
+            if(this.selectList.length===0){
+                this.$message.warning('请选择指标')
+                return
+            }
+            if([8,12,13,35].includes(this.computedType) && !this.formData.nNum){
+                this.$message.warning('请输入N数值')
+                return
+            }
+            if([51].includes(this.computedType)&& !this.formData.frequency){
+                this.$message.warning('请选择频度')
+                return
+            }
+            if(['accumulate'].includes(this.computedType)&&this.subComputedType==62&& !this.formData.frequency){
+                this.$message.warning('请选择频度')
+                return
+            }
+            if(this.computedType==72&&!this.formData.alphaValue){
+                this.$message.warning('请输入alpha值')
+                return
+            }
+            if(this.computedType==72&&(Number(this.formData.alphaValue)<=0||Number(this.formData.alphaValue)>=1)){
+                this.$message.warning('请输入>0,<1的数值的alpha值')
+                return
+            }
+            if(this.computedType=='withEDB'&&!this.select_target){
+                this.$message.warning('请选择指标B')
+                return
+            }
+            if(['withNum','withEDB'].includes(this.computedType)&&!this.formData.formula){
+                this.$message.warning('请输入公式')
+                return
+            }
+
+            this.isCheckAll=false
+            this.isCheckIndeterminate=false
+            this.checkAllStatus=false
+            this.tableDataCheckedList=[]
+            this.tableDataIds=[]
+
+            this.showSave=true
+        },
+
+        // 点击加入已选指标库
+        async getAddEdbListData(){
+            if(!(this.isCheckAll || this.isCheckIndeterminate ) || (!(this.list && this.list.length>0))){
+                this.$message.warning('请选择指标')
+                return
+            }
+            if(this.selectList.length>=this.MAXAddNUM){
+                this.$message.warning('已达批量添加指标数量上限')
+                return
+            }
+            const params={
+                SysUserIds:this.filter.user?this.filter.user.join(','):'',
+                ClassifyIds:this.filter.classify?this.filter.classify.join(','):'',
+                Keyword:this.filter.keyword,
+                Frequency:this.filter.frequency?this.filter.frequency.join(','):'',
+                SelectAll:this.checkAllStatus,
+                EdbInfoIds:this.tableDataCheckedList.join(',')
+            }
+            this.addLoading=true
+            const res=await dataBaseInterface.getBatchFilterAddEdbList(params)
+            this.addLoading=false
+            if(res.Ret!=200) return
+            // 加入到已选指标中 要去重
+            const arr=res.Data.SearchItem||[]
+            const temArr=this.mergeAndDistinct(this.selectList,arr)
+            // 截取数组 防止数量溢出
+            this.selectList=temArr.slice(0,this.MAXAddNUM)
+        },
+        mergeAndDistinct(arr1, arr2) {
+            // 合并两个数组
+            const mergedArray = arr1.concat(arr2);
+
+            // 根据 EdbInfoId 字段进行去重
+            const distinctArray = mergedArray.filter((item, index, self) => {
+                return index === self.findIndex(t => t.EdbInfoId === item.EdbInfoId);
+            });
+
+            return distinctArray;
+        },
+
+        // 删除已选指标库指标
+        handleDelSelect(e){
+            if(this.operationForm.view) return
+            if(e==='all'){
+                this.selectList=[]
+                return
+            }
+            const index=e.$index
+            this.selectList.splice(index,1)
+        },
+
+        // 切换计算类型
+        handleComputedTypeChange(){
+            this.subComputedType=''
+            this.select_target=''
+            this.formData={
+                nNum:1,
+                calendarType:'公历',
+                frequency:'',
+                valueType:'期末值',
+                newValue:0,
+                alphaValue:'',
+                formula:'',
+                timeSeriesVal:'A',
+                nullValueWay:0,
+                maxNullWay:1,
+            }
+            this.filter={
+                classify:'',
+                frequency:'',
+                user:'',
+                keyword:''
+            }
+            this.selectList=[]
+            if(this.computedType=='toMonthSeason'){
+                this.subComputedType=5
+                this.filter.frequency=['月度']
+            }else if(this.computedType=='accumulate'){
+                this.subComputedType=62
+            }else if(this.computedType=='multipleEDB'){
+                this.subComputedType=81
+            }
+            this.handleFilter()
+        },
+        handleComputedSubTypeChange(){
+            if(this.subComputedType==61){
+                this.filter.frequency=['季度']
+            }
+            if(this.subComputedType==5){
+                this.filter.frequency=['月度']
+            }
+            this.selectList=[]
+            this.handleFilter()
+        },
+
+        /* 指标列表 */
+		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);
+		},
+
+		searchApi(query,page=1) {
+			dataBaseInterface.targetSearchByPage({
+				KeyWord:query,
+				CurrentIndex: page,
+				FilterSource:  1,
+				Frequency: ''
+			}).then(res => {
+				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;
+					
+			})
+		},
+
+		searchLoad() {
+			if(!this.search_have_more) return;
+			this.searchApi(this.current_search,++this.search_page)
+		},
+
+        handleClose(){
+            this.showSave=false
+            this.$emit('close')
+        },
+        handleCloseSelf(){//仅仅关闭批量计算弹窗
+            this.$emit('closeSelf')
+        },
+
+        filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (!item.Children.length) {
+						delete item.Children;
+					}
+				});
+		},
+        // 获取指标分类
+        async getClassifyOpt(){
+            const res=await dataBaseInterface.menuListV3()
+            if (res.Ret !== 200) return
+            this.filterNodes(res.Data.AllNodes||[]);
+			this.classifyOpt = res.Data.AllNodes || [];
+        },
+
+        // 获取所有系统用户
+        async getSysUserList() {
+            const res = await departInterence.getQuestionAdminList();
+            if (res.Ret === 200) {
+                this.sysUserOpts = res.Data.List||[];
+            }
+        },
+
+        // 获取指标列表
+        async getEDBList(type){
+            this.listLoading=true
+            const res=await dataBaseInterface.getBatchAddEdbSearchList({
+                CurrentIndex:this.page,
+                PageSize: this.pageSize,
+                SysUserIds:this.filter.user?this.filter.user.join(','):'',
+                ClassifyIds:this.filter.classify?this.filter.classify.join(','):'',
+                Keyword:this.filter.keyword,
+                Frequency:this.filter.frequency?this.filter.frequency.join(','):'',
+                NotFrequency:this.computedType==75?'日度':''
+            })
+            this.listLoading=false
+            if(res.Ret===200){
+                this.list=res.Data.SearchItem||[]
+                this.total=res.Data.Paging.Totals||0
+
+                if(this.list.length>0){
+                    this.tableDataIds = this.list.map(it => it.EdbInfoId)
+                }else{
+                    this.tableDataIds = []
+                }
+
+                if(type == 'adjustSelection'){
+                    this.adjustSelection()
+                }else{
+                    
+                    this.isCheckAll=false
+                    this.checkAllStatus=false
+                    this.isCheckIndeterminate=false
+                    
+                    this.listCheckAllChange(this.isCheckAll)
+                }
+            }
+        },
+
+        pageNumberChange(e){
+            this.page=e
+            this.getEDBList('adjustSelection')
+        },
+
+        handleFilter(e){
+            this.page=1
+            this.list=[]
+            this.getEDBList()
+        },
+
+        // 切换列表全选按钮状态
+        listCheckAllChange(check){
+            this.tableDataCheckedList=[]
+            this.checkAllStatus=check
+            if(check){
+                // 全选
+                this.$refs.edbDataRef && this.$refs.edbDataRef.clearSelection()
+                this.$refs.edbDataRef && this.$refs.edbDataRef.toggleAllSelection()
+            }else{
+                //全不选
+                this.$refs.edbDataRef && this.$refs.edbDataRef.clearSelection()
+            }
+        },
+
+        selectionChange(val){
+            if(this.selectionReactCancel) return 
+        
+            // selectAllHandle的触发在selectionChange后面,将selectionChange的逻辑延迟一下
+            setTimeout(()=>{
+                // 去重
+                let duplicateArr = Array.from(new Set(this.tableDataCheckedList))
+                
+                if((duplicateArr.length == this.total && (!this.checkAllStatus))
+                    || (duplicateArr.length == 0 && this.checkAllStatus)){
+                    this.isCheckAll = true
+                    this.isCheckIndeterminate=false
+                }else if((duplicateArr.length == 0 && (!this.checkAllStatus))
+                    || (duplicateArr.length == this.total && this.checkAllStatus)){
+                    this.isCheckAll = false
+                    this.isCheckIndeterminate=false
+                }else{
+                    this.isCheckAll = false
+                    this.isCheckIndeterminate=true
+                }
+            },1)
+
+        },
+
+        //用户手动勾选数据行的 Checkbox 时触发的事件	
+        selectHandle(selection, row){
+            if(this.selectionReactCancel) return 
+
+            let check=false
+            if(selection.some(it => it.EdbInfoId == row.EdbInfoId)){
+                // 勾选
+                // 勾选
+                if(this.checkAllStatus){
+                    check=false
+                }else{
+                    check=true
+                }
+            }else{
+                // 取消勾选
+                if(this.checkAllStatus){
+                    check=true
+                }else{
+                    check=false
+                }
+            }
+            if(check){
+                this.tableDataCheckedList.push(row.EdbInfoId)
+            }else{
+                this.tableDataCheckedList=this.tableDataCheckedList.filter(it => it!=row.EdbInfoId)
+            }
+        },
+
+        // 用户手动勾选全选 Checkbox 时触发的事件
+        selectAllHandle(selection){
+            if(this.selectionReactCancel) return 
+            let check = false; // 从tableDataCheckedList 添加还是删除
+            if(selection && selection.length>0){
+                // 全选
+                if(this.checkAllStatus){
+                    check=false
+                }else{
+                    check=true
+                }
+            }else{
+                // 全不选
+                if(this.checkAllStatus){
+                    check=true
+                }else{
+                    check=false
+                }
+            }
+            if(check){
+                this.tableDataCheckedList =  [...this.tableDataCheckedList,...this.tableDataIds]
+            }else{
+                this.tableDataCheckedList = this.tableDataCheckedList.filter(it => !this.tableDataIds.includes(it))
+            }
+        },
+
+        adjustSelection(){
+            this.selectionReactCancel=true
+            if(!this.checkAllStatus){
+                this.tableDataCheckedList.map(it =>{
+                    let row = this.list.find(da => da.EdbInfoId==it)
+                    if(row){
+                        setTimeout(()=>{
+                            this.$refs.edbDataRef.toggleRowSelection(row,true)
+                        },10)
+                    }
+                })
+            }else{
+                this.$refs.edbDataRef.toggleAllSelection()
+                this.tableDataCheckedList.map(it =>{
+                    let row = this.list.find(da => da.EdbInfoId==it)
+                    if(row){
+                        setTimeout(()=>{
+                            this.$refs.edbDataRef.toggleRowSelection(row,false)
+                        },50)
+                    }
+                })
+            }
+            setTimeout(()=>{
+                this.selectionReactCancel=false
+            },50)
+        },
+
+
+
+    },
+}
+</script>
+
+<style lang="scss">
+.batch-computed-dialog{
+    max-width: 1200px;
+    width:90vw;
+	overflow: hidden;
+}
+.batch-computed-wrap{
+    .type-wrap{
+        display: flex;
+    }
+    .table-wrap{
+        margin-top: 20px;
+        display: flex;
+        justify-content: space-between;
+        .left-box{
+            width: 50%;
+        }
+        .right-box{
+            flex: 1;
+            flex-shrink: 0;
+        }
+    }
+}
+</style>

+ 93 - 6
src/views/dataEntry_manage/databaseComponents/computedDialog.vue

@@ -70,6 +70,24 @@
 				<!-- 添加更多参数 -->{{$t('EtaBasePage.add_more_param')}}
 			</span>
 			<div class="computed-min">
+				<div class="computed-section" v-if="edbSource !== 'predict'">
+					<div>
+						<label class="label">生成指标时间序列</label>
+						<div style="width:200px;display: inline-block;">
+							<el-cascader
+								v-model="selectTimeSeriesVal"
+								style="width:100%"
+								:options="timeSeriesOpt"
+								:props="{emitPath:false}"
+								:show-all-levels="false"
+								placeholder="请选择"
+								:disabled="calulateForm.view"
+							></el-cascader>
+						</div>
+						
+					</div>
+				</div>
+
 				<div class="computed-section">
 					<div>
 						<label class="label"><!-- 空值处理 -->{{$t('EtaBasePage.null_val_deal')}}
@@ -121,7 +139,7 @@
 					</el-input> -->
 					<ul class="formula-list">
 						<li style="margin-bottom: 15px;">
-							<el-input :placeholder="$t('EtaBasePage.input_formula_msg')" v-model="formulaList[0].formula" clearable :disabled="calulateForm.view" style="width: 220px"/>
+							<el-input :placeholder="$t('EtaBasePage.input_formula_msg')" v-model="formulaList[0].formula" clearable :disabled="calulateForm.view" style="width: 600px"/>
 							
 							<span v-if="formulaDateArr.length" class="date-section-text">{{formulaDateArr[formulaDateArr.length-1]}}(含)之后</span>
 
@@ -243,8 +261,11 @@ import { dataBaseInterface } from '@/api/api.js';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
 import { formRules,frequencyArr } from '../databaseComponents/util';
 import { unitArr } from '@/utils/defaultOptions';
-const tag_arr = [];
-for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
+import {generateSeriesArray} from './util'
+const MAXEDBNUM=50//最大可添加的指标数量
+const tag_arr = generateSeriesArray();
+
+// for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
 export default {
 	name: '',
 	props: {
@@ -280,6 +301,28 @@ export default {
 
 		formulaDateArr() {
 			return this.formulaList.map(_ => _.date).filter(_ => _).sort((a,b) => new Date(a)-new Date(b))
+		},
+
+		timeSeriesOpt(){
+			const arr=[
+				{
+					label:'指定指标时间序列',
+					value:'0',
+					children:[]
+				},
+				{
+					label:'所有指标时间序列并集',
+					value:'all',
+				}
+			]
+			arr[0].children=this.addList.filter(item=>item.target).map(item=>{
+				return {
+					label:`指标${item.tag}`,
+					value:item.tag
+				}
+			})
+
+			return arr
 		}
 	},
 	watch: {
@@ -310,9 +353,43 @@ export default {
 					EdbName: item.edb_name,
 				}))
 
+				if(this.calulateForm.Extra){
+					const ExtraObj=JSON.parse(this.calulateForm.Extra)
+					this.selectTimeSeriesVal=ExtraObj.DateTag
+				}
+				
+
+
 				this.getNewestDate();
 			}
 		},
+
+		'addList':{
+			handler(n){
+				if(this.selectTimeSeriesVal=='all') return
+				const arr=this.addList.filter(item=>item.target).map(item=>{
+					return {
+						label:`指标${item.tag}`,
+						value:item.tag
+					}
+				})
+				if(!arr.length) return
+				if(!this.selectTimeSeriesVal){
+					this.selectTimeSeriesVal=arr[0].value
+				}else{//已经有选择的值了
+					let flag=false
+					arr.forEach(item=>{
+						if(item.value==this.selectTimeSeriesVal){
+							flag=true
+						}
+					})
+					if(!flag){
+						this.selectTimeSeriesVal=arr[0].value
+					}
+				}
+			},
+			deep:true
+		}
 	},
 	data() {
 		return {
@@ -381,6 +458,9 @@ export default {
 				{ label: '后值填充',value: 3 },
 				{ label: '等于0',value: 4 },
 			],
+
+			selectTimeSeriesVal:'',
+
 			formTips: {
 				'null-val': `1、查找前后35天最近值:在参与计算的日期序列上某指标无值时,该指标往前/往后找距离最近的值作为当天的值进行计算,遍历允许跨年,往前最多35天,往后最多35天<br>
 				2、不计算:只要有一个指标在某个日期没有值(即空值),则计算指标在该日期没有值 <br>
@@ -421,7 +501,8 @@ export default {
 		},
 		/* 添加额外的指标列 */
 		addTargetHandle() {
-			if(this.addList.length >= 26) return this.$message.warning(/* '添加指标个数已达上限' */this.$t('EtaBasePage.num_overrun_msg'))
+			const MAXNUM=this.edbSource === 'predict'?26:MAXEDBNUM
+			if(this.addList.length >=MAXNUM) return this.$message.warning(this.$t('EtaBasePage.num_overrun_msg'))
 			let tag = this.addList[this.addList.length-1].tag;
 			let index = tag_arr.findIndex(item => item === tag);
 			const item = {
@@ -535,7 +616,10 @@ export default {
 					Unit: this.formData.unit,
 					EdbInfoIdArr,
 					EmptyType: nullValueWay,
-					MaxEmptyType: maxNullWay
+					MaxEmptyType: maxNullWay,
+					Extra:JSON.stringify({
+						DateTag:this.selectTimeSeriesVal
+					})
 				};
 				this.dataloading = true;
 
@@ -655,7 +739,7 @@ export default {
 		width: 6px !important;
 	}
 	.el-dialog__body {
-		max-height: 700px;
+		max-height: 840px;
 		overflow: auto;
 	}
 	.dialog-main {
@@ -709,6 +793,9 @@ export default {
 			.computed-section {
 				display: flex;
 				margin-top: 20px;
+				.el-cascader .el-input {
+					width: 100%;
+				}
 			}
 			.label {
 				padding:10px 10px 10px 0;

+ 14 - 10
src/views/dataEntry_manage/databaseComponents/diffusionIndexDia.vue

@@ -93,11 +93,11 @@
             />
           </el-form-item>
           <el-form-item :label="$t('Edb.Detail.e_unit')" prop="unit">
-						<selectUnit 
-								v-model="formData.unit" 
-							style="width:340px" 
-							:disabled="!operationForm.edb_id&&[6,7].includes(type)"
-						/>
+			<selectUnit 
+			  	v-model="formData.unit" 
+				style="width:340px" 
+				:disabled="type===53"
+			/>
           </el-form-item>
           <el-form-item :label="$t('Edb.Detail.e_menu')" prop="menu" style="margin-right: 40px;">
             <el-cascader
@@ -150,12 +150,12 @@
 
 <script>
 import { dataBaseInterface } from '@/api/api.js';
-import { formRules } from './util';
+import { formRules,generateSeriesArray } from './util';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
 import { unitArr } from '@/utils/defaultOptions';
-import { frequencyArr } from './util'
-const tag_arr = [];
-for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
+const MAXEDBNUM=50//最大可添加的指标数量
+const tag_arr = generateSeriesArray();
+// for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
 export default {
 	name:'',
 	props: {
@@ -206,6 +206,9 @@ export default {
 
 				this.formData.select_date.length && this.formData.date_type === 2 && this.setConcatDate()
 			}
+			if(newval&&this.type===53&&!this.operationForm.edb_id){
+				this.formData.unit='无'
+			}
 		}
 	},
 	data () {
@@ -369,7 +372,8 @@ export default {
 
 		/* 添加指标 */
 		addTargetHandle() {
-			if(this.targetList.length === 26) return this.$message.warning(this.$t('EtaBasePage.num_overrun_msg'))
+			const NUM=this.isPredict?26:MAXEDBNUM
+			if(this.targetList.length === NUM) return this.$message.warning(this.$t('EtaBasePage.num_overrun_msg'))
 			let tag = this.targetList[this.targetList.length-1].tag;
 			let index = tag_arr.findIndex(item => item === tag);
 			const item = {

+ 7 - 0
src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue

@@ -391,6 +391,13 @@ export default {
 					? this.formData.self_edb_date = [choose_obj.StartDate,choose_obj.EndDate]
 					: this.formData.depend_edb_date = [choose_obj.StartDate,choose_obj.EndDate]
 
+				// 设置目录、频度、单位
+				if(type==='self'){
+					this.formData.menu=choose_obj.ClassifyId
+					this.formData.unit=choose_obj.Unit
+					this.formData.frequency=choose_obj.Frequency
+				}
+				
 			}
 			this.getCorrelationIndex();
 		},

+ 14 - 0
src/views/dataEntry_manage/databaseComponents/jointTargetDia.vue

@@ -79,6 +79,7 @@
 							:remote-method="query=>{searchHandle(query)}"
 							@click.native="inputFocusHandle"
 							@blur="search_have_more = false"
+							@change="chooseTarget(formData.after_edb,'searchOptions')"
 						>
 							<i slot="prefix" class="el-input__icon el-icon-search"></i>
 							<el-option
@@ -106,6 +107,7 @@
 						:remote-method="query=>{searchHandle(query,'month')}"
 						@click.native="e => {inputFocusHandle(e,'month')} "
 						@blur="search_have_more = false"
+						@change="chooseTarget(formData.old_stay_edb,'searchMonthOptions')"
 						>
 							<i slot="prefix" class="el-input__icon el-icon-search"></i>
 							<el-option
@@ -400,6 +402,18 @@ export default {
 		};
 	},
 	methods: {
+		// 选中指标更新默认值
+		chooseTarget(val,key){
+			if(!val) return
+			const arr=key==='searchMonthOptions'?this.searchMonthOptions:this.searchOptions
+			let obj = arr.find(item => item.EdbInfoId === val);
+			console.log(obj);
+			this.formData.edb_name=`${obj.EdbName}/拼接`
+			this.formData.menu=obj.ClassifyId||''
+			this.formData.frequency=obj.Frequency
+			this.formData.unit=obj.Unit
+		},
+
 		/* 搜索 */
 		searchHandle(query,type) {
 			this.search_page = 1;

+ 71 - 13
src/views/dataEntry_manage/databaseComponents/operationDialog.vue

@@ -133,6 +133,7 @@
 								min="0"
 								size="mini"
 								v-model="formData.moveVal"
+								@change="refreshTarget"
 								@keyup.native="filterCode(formData)"
 							></el-input>
 							<el-select
@@ -181,6 +182,7 @@
 								style="width: 340px"
 								clearable
 								:disabled="[5,14,61,63].includes(type)||(!operationForm.edb_id&&[6,7,75].includes(type))"
+								@change="handleFrequencyChange"
 							>
 								<el-option
 									v-for="item in frequencyArr"
@@ -226,6 +228,12 @@
 								<el-option :label="$t('EtaBasePage.val_type_average')" value="平均值"/>
 							</el-select>
 						</el-form-item>
+						<el-form-item label="最新值处理" prop="new_value" v-if="type===62">
+							<el-select v-model="formData.new_value" placeholder="请选择" style="width: 340px">
+								<el-option label="默认" value=""></el-option>
+								<el-option label="均值填充" :value="'均值填充'" v-if="hasNewValueOpt"></el-option> 
+							</el-select>
+						</el-form-item>
 					</el-form>
 				</div>
 			</div>
@@ -267,6 +275,12 @@ export default {
 			type: Object,
 		}
 	},
+	computed: {
+		// 累计值计算时 均值填充判断标识
+		frequencyChangeFlag(){
+			return this.tableData[0]?`${this.tableData[0].Frequency}转${this.formData.frequency}`:''
+		}
+	},
 	watch: {
 		isOperation(newval) {
 			newval && this.getMenu();
@@ -298,10 +312,16 @@ export default {
 					moveType,
 					moveUnit,
 					moveVal,
-					calendar_type
+					calendar_type,
+					new_value:''
 				}
 				this.getDataList();
 
+				if(backData.Extra){
+					const ExtraObj=JSON.parse(backData.Extra)
+					this.formData.new_value=ExtraObj.LastValType==1?'均值填充':''
+				}
+
 				//回显时的默认options
 				this.searchOptions = [
 					{
@@ -316,6 +336,15 @@ export default {
 				: [62,63].includes(this.type)
 				? [{ label: /* '累计值' */this.$t('Edb.CalculatesAll.cumulate'),key: 62 },{ label: /* '年初至今累计值' */this.$t('Edb.CalculatesAll.cumulate_oneyear'),key: 63 }]
 				: []
+		},
+		frequencyChangeFlag(n){
+			const arr=['日度转周度','日度转旬度','周度转旬度']
+			if(n&&arr.includes(n)){
+				this.hasNewValueOpt=false
+				this.formData.new_value=''
+			}else{
+				this.hasNewValueOpt=true
+			}
 		}
 	},
 	computed: {
@@ -413,7 +442,8 @@ export default {
 				moveUnit: '天',
 				moveVal: '',
 				calendar_type: '公历',
-				value_type: '期末值'
+				value_type: '期末值',
+				new_value:'',
 			},
 			options: [],
 			levelProps: {
@@ -447,6 +477,8 @@ export default {
 
 			sourceList: [],
 
+			hasNewValueOpt:true,//最新值处理的选项
+
 		};
 	},
 	methods: {
@@ -593,7 +625,8 @@ export default {
 				moveUnit: '天',
 				moveVal: '',
 				calendar_type: '公历',
-				value_type: '期末值'
+				value_type: '期末值',
+				new_value:''
 			};
 			this.$refs.form.resetFields();
 		},
@@ -621,6 +654,9 @@ export default {
 					MoveFrequency: this.formData.moveUnit,
 					MoveType: this.formData.moveType, 
 					Calendar: this.formData.calendar_type,
+					Extra:JSON.stringify({
+						LastValType:this.formData.new_value==='均值填充'?1:0
+					})
 				}
 
 				const res = this.operationForm.edb_id 
@@ -663,6 +699,26 @@ export default {
 			this.formData.targetName = name_map[this.type] || '';
 		},
 
+		// 频度变化 修改指标名
+		handleFrequencyChange(){
+			if(!this.select_target||this.operationForm.edb_id) return;
+			let obj = this.searchOptions.find(item => item.EdbInfoId === this.select_target);
+			const name_map = {
+				51: `${obj.EdbName}/${this.formData.frequency.substr(0,1)}频`,
+				62:  `${obj.EdbName}累计值/${this.formData.frequency}`,
+			}
+			this.formData.targetName=name_map[this.type] || ''
+		},
+
+		// 时间位移-移动方式修改 修改指标名
+		refreshTarget(){
+			if(this.type==22){
+				if(!this.select_target||this.operationForm.edb_id) return;
+				let obj = this.searchOptions.find(item => item.EdbInfoId === this.select_target);
+				this.formData.targetName=`${obj.EdbName}${this.moveTypeOpions.filter(item=>item.key===this.formData.moveType)[0].label}${this.formData.moveVal}${this.formData.moveUnit}`
+			}
+		},
+
 		/* 单位默认同步基础指标
 		同比 同差 频度同步 单位无 
 		转月 平均值 频度单位同步
@@ -684,20 +740,21 @@ export default {
 				['年度','Y'],
 			])
 			const name_map = {
-				5: obj.EdbName,
+				5: `${obj.EdbName}转月值`,
 				8: `${obj.EdbName}/${this.formData.n_num}${tMap.get(obj.Frequency)}MA`,
-				14: `${obj.EdbName}/${obj.Frequency}升频`,
+				14: `${obj.EdbName}/频`,
 				6: `${obj.EdbName}同比`,
 				7: `${obj.EdbName}同差`,
 				12: `${obj.EdbName}${this.formData.n_num}${obj.Frequency.slice(0,1)}环比`,
 				13: `${obj.EdbName}${this.formData.n_num}${obj.Frequency.slice(0,1)}环差`,
 				35: `${obj.EdbName}超季节性/${this.formData.n_num}年${this.formData.calendar_type==='公历'?'':'/'+this.formData.calendar_type}`,
-				52: `${obj.EdbName}年化`,
-				51: `${obj.EdbName}/${obj.Frequency}降频`,
-				61:  obj.EdbName,
-				62:  obj.EdbName,
-				63:  obj.EdbName,
-				75: `${obj.EdbName}日均值`
+				52: `${obj.EdbName}年化值`,
+				51: `${obj.EdbName}/${obj.Frequency.substr(0,1)}频`,
+				61:  `${obj.EdbName}转季值`,
+				62:  `${obj.EdbName}累计值/${obj.Frequency}`,
+				63:  `${obj.EdbName}年初至今累计值`,
+				75: `${obj.EdbName}日均值`,
+				22:	`${obj.EdbName}${this.moveTypeOpions.filter(item=>item.key===this.formData.moveType)[0].label}${this.formData.moveVal}${this.formData.moveUnit}`
 			}
 			
 			let frequerncyMap = {
@@ -710,13 +767,14 @@ export default {
 				targetName: name_map[this.type] || '',
 				frequency: frequerncyMap[this.type] || obj.Frequency,
 				unit: [5,8,14,7,35,75].includes(this.type) ? obj.Unit : '无',
-				menu: this.type===75 ? obj.ClassifyId : '',
+				menu: obj.ClassifyId || '',
 				n_num: 1,
 				moveType: 1,
 				moveUnit: '天',
 				moveVal: '',
 				calendar_type: this.formData.calendar_type,
-				value_type: this.formData.value_type
+				value_type: this.formData.value_type,
+				new_value:''
 			}
 		},
         handleSelectBtnClick(){

+ 69 - 1
src/views/dataEntry_manage/databaseComponents/util.js

@@ -155,6 +155,74 @@ export const computedBatchTypes = [
 	}
 ]
 
+//批量指标类型
+export const computedBatchTypesV2=[
+	{
+		name:'同比值',
+		type:6
+	},
+	{
+		name:'同差值',
+		type:7
+	},
+	{
+		name:'累计值转月/季值',
+		type:'toMonthSeason'
+	},
+	{
+		name:'N期移动均值',
+		type:8
+	},
+	{
+		name:'N期环比值',
+		type:12
+	},
+	{
+		name:'N期环差值',
+		type:13
+	},
+	{
+		name:'升频',
+		type:14
+	},
+	{
+		name:'超级季节性',
+		type:35
+	},
+	{
+		name:'年化值',
+		type:52
+	},
+	{
+		name:'降频',
+		type:51
+	},
+	{
+		name: '累计值',
+		type: 'accumulate'
+	},
+	{
+		name:'指数修匀',
+		type:72
+	},
+	{
+		name:'日均值',
+		type: 75
+	},
+	{
+		name:'与常数计算',
+		type:'withNum'
+	},
+	{
+		name:'与单指标计算',
+		type:'withEDB'
+	},
+	{
+		name:'多指标求和/平均',
+		type:'multipleEDB',//81求和 82求平均
+	},
+]
+
 //频度
 export const frequencyArr = ['日度','周度','旬度','月度','季度','年度'];
 
@@ -302,4 +370,4 @@ export const THSCommonIndexFuturesCodeArr=[
 	{value:'ths_chg_ratio_future',label:bus.$i18nt.t('EtaBasePage.incre_decre')/* "涨跌幅" */},
 	{value:'ths_swing_d_future',label:bus.$i18nt.t('EtaBasePage.fluctua_day')/* "日振幅" */},
 	{value:'ths_open_interest_future',label:bus.$i18nt.t('EtaBasePage.open_inter')/* "持仓量" */},
-]
+]

+ 64 - 9
src/views/dataEntry_manage/databaseList.vue

@@ -65,6 +65,13 @@
 			<!-- <target-tree /> -->
 			<div class="main-left left" id="left" v-show="isMainLeftShow">
 				<div class="tree-cont">
+					<div style="padding-bottom:20px;padding-right:20px;display:flex;justify-content:space-between">
+						<span>目录</span>
+						<el-checkbox 
+							v-model="IsOnlyMe"
+							@change="onlyMeHandler"
+						>只看我的</el-checkbox>
+					</div>
 					<div class="target_tree">
 					<el-tree
 						ref="menuTree"
@@ -405,15 +412,17 @@
 		width="920px"
 		v-dialogDrag>
 			<div class="dialog-computed-header">
-				<el-radio-group v-model="computed_source" size="medium" @change="computed_type = 0">
-					<el-radio-button :label="1"><!-- 常规计算 -->{{$t('EtaBasePage.normal_calculate_tab')}}</el-radio-button>
-					<el-radio-button :label="2"><!-- 批量计算 -->{{$t('EtaBasePage.batch_calculate_tab')}}</el-radio-button>
+				<el-radio-group :value="1" size="medium">
+					<el-radio-button :label="1">{{$t('EtaBasePage.normal_calculate_tab')}}</el-radio-button>
+					<span @click="showBatchComputedPop=true">
+					<el-radio-button :label="2">{{$t('EtaBasePage.batch_calculate_tab')}}</el-radio-button>
+					</span>
 				</el-radio-group>
 			</div>
 			<ul class="computed-ul">
 				<li
-					:class="['cpmputed-li',{'act':item.type === computed_type}]" 
-					v-for="item in computedShowTypes" 
+					:class="['cpmputed-li',item.type === computed_type?'act':'']" 
+					v-for="item in computedTypes" 
 					:key="item.type" 
 					@click="changeComputedType(item.type)">
 					{{item.name}}
@@ -526,6 +535,16 @@
 			@addCallBack="addComputedCallBack"
 			@lookHistory="id => {toHistoryPage(id,$route.matched);lookEdbId=id;}"
 		/>
+
+		<!-- 批量计算指标 -->
+		<batchComputedV2 
+			:isShow="showBatchComputedPop" 
+			:type="computed_type"
+			:operationForm="operationForm"
+			@close="isOpenComputed=false;showBatchComputedPop=false" 
+			@closeSelf="handleCloseBatchPopSelf"
+			@addCallBack="addComputedCallBack"
+		/>
 	</div>
 </template>
 
@@ -554,6 +573,7 @@ import EdbLabelList from '@/components/edbLabelList.vue';
 import chartTrendRender from './databaseComponents/chartTrendRender.vue';
 import edbDetailData from './databaseComponents/edbDetailData.vue';
 import SmoothEdbDialog from './databaseComponents/smoothEdbDialog.vue';
+import batchComputedV2 from './databaseComponents/batchComputedV2.vue';
 export default {
 	name: '',
 	components: {
@@ -578,6 +598,7 @@ export default {
 		chartTrendRender,
 		edbDetailData,
 		SmoothEdbDialog,
+		batchComputedV2
 	},
 	directives: {
 		drag(el, bindings,vnode) {
@@ -615,6 +636,7 @@ export default {
 	},
 	data() {
 		return {
+			IsOnlyMe:false,//只看我的
 			showData: false,
 			search_txt: '', //搜索词
 			searchOptions:[],//搜索到的筛选列表
@@ -768,6 +790,8 @@ export default {
 			activeName:'second',
 
 			isMainLeftShow:true,
+
+			showBatchComputedPop:false,
 		};
 	},
 	watch: {
@@ -950,7 +974,7 @@ export default {
 		/* 获取树分类数据 */
 		getTreeData(params) {
 			
-			dataBaseInterface.targetCatalog({ParentId:0}).then(res=>{
+			dataBaseInterface.targetCatalog({IsOnlyMe:this.IsOnlyMe,ParentId:0}).then(res=>{
 				if(res.Ret===200){
 					const arr=res.Data.AllNodes || []
 					this.treeData=arr.map(item=>{
@@ -1061,6 +1085,7 @@ export default {
 				PageSize:this.PageSize,
 				CurrentIndex:this.CurrentIndex,
 				ClassifyId:this.select_classifyId,
+				IsOnlyMe:this.IsOnlyMe
 			}).then(res=>{
 				if(res.Ret!==200) return
 				if(res.Data){
@@ -1708,6 +1733,7 @@ export default {
 			this.calulateList = [];
 			this.calulateForm = {};
 			this.operationForm = {};
+			this.computed_type=0
 			this.isOpenComputed = true;
 		},
 		/* 新增计算指标回调 */
@@ -1716,6 +1742,9 @@ export default {
 			this.computed_source = 1;
 			this.showAssociateChart=false
 			this.showAssociateComputeData=false
+			this.showBatchComputedPop=false
+			this.isOpenComputed = false
+			console.log(type, params);
 			// this.getTreeData();
 			type === 'add' ? this.getTreeData(params) : this.getTreeData();
 			type === 'edit' && this.initGetData()
@@ -1811,7 +1840,7 @@ export default {
 						end_date: item.EndDate
 					}
 				})
-				const { EdbInfoId,CalculateFormula,EdbName,Unit,Frequency,EmptyType,MaxEmptyType } = res.EdbInfoDetail;
+				const { EdbInfoId,CalculateFormula,EdbName,Unit,Frequency,EmptyType,MaxEmptyType,Extra } = res.EdbInfoDetail;
 				/* 公式和表单 */
 				this.calulateForm =  {
 					edb_id: EdbInfoId,
@@ -1822,9 +1851,18 @@ export default {
 					frequency: Frequency,
 					emptyType: EmptyType,
 					maxEmptyType: MaxEmptyType,
+					Extra,
 					view
 				};
 			} else  {
+				// 多指标求和求平均
+				if([81,82].includes(type)){
+					this.operationForm={...res,view}
+					this.showBatchComputedPop=true
+					return
+				}
+
+
 				let dataInfo = res.EdbInfoDetail;
 				let old_edb = res.CalculateList;
 
@@ -1834,6 +1872,7 @@ export default {
 					frequency: dataInfo.Frequency,
 					unit: dataInfo.Unit,
 					menu: menuArrId||[],
+					Extra:dataInfo.Extra,
 					view
 				}
 
@@ -1870,6 +1909,7 @@ export default {
 						view
 					}
 				}
+				
 			}
 		},
 
@@ -2017,13 +2057,21 @@ export default {
 				this.dynamicNode&&this.resetNodeStyle(this.dynamicNode)
 			})
 		},
+		//只看我的
+		onlyMeHandler(){
+			this.getTreeData()
+
+			this.CurrentIndex = 1;
+			this.$refs.listRef.scrollTop = 0;
+			this.getEdbChartList();
+		},
 		//绑定el-tree的load属性
 		async getLazyTreeData (node,resolve){
 			if(node.level===0){
 				resolve(this.treeData)
 			}else{
 				let arr=[]
-				const res=await dataBaseInterface.targetCatalog({ParentId:node.data.ClassifyId})
+				const res=await dataBaseInterface.targetCatalog({ParentId:node.data.ClassifyId,IsOnlyMe:this.IsOnlyMe})
 				if (res.Ret === 200) {
 					const temarr = res.Data.AllNodes || [];
 					arr=temarr.map(item=>{
@@ -2074,6 +2122,13 @@ export default {
 		// 添加wind wsd指标成功
 		addTargetSuccess(params){
 			this.getTreeData(params);
+		},
+
+		handleCloseBatchPopSelf(){
+			this.showBatchComputedPop=false
+			this.$nextTick(()=>{//重新打开计算指标选择类型弹窗
+				this.isOpenComputed=true
+			})
 		}
 	},
 	//离开页面时保存标签
@@ -2189,7 +2244,7 @@ export default {
 			}
 			.target_tree {
 				color: #333;
-				height: calc(100vh - 350px);
+				height: calc(100vh - 400px); 
 				overflow: auto;
 				.label-input .el-input__inner {
 					height: 25px;

+ 4 - 3
src/views/dataEntry_manage/thirdBase/icpiConsumption.vue

@@ -157,9 +157,10 @@ export default {
         
         // 设置表格数据
         this.setDataList(res.Data);
-        this.$nextTick(() => {
-          this.initWidth();
-        });
+        this.CurrentIndex === 1 &&
+          this.$nextTick(() => {
+            this.initWidth();
+          });
       }).finally(()=>{
         this.dataloading = false;
       })

+ 176 - 23
src/views/operation_manage/AIQA/AIQA.vue

@@ -45,7 +45,7 @@
             </div>
             <!-- 仅这一部分滚动 -->
             <div class="window-content-wrap hidden-scrollbar">
-                <div class="content-item" v-for="item in historyList" :key="item.AiChatId">
+                <div class="content-item" v-for="item in historyList" :key="item.AiChatId" >
                     <!-- user 提问 -->
                     <Message-Item :messageInfo="formatMsg(item,'user')"
                         @startTyping="handleStartTyping"
@@ -57,9 +57,22 @@
                         @finishedTyping="handleFinishedTyping"
                     />
                 </div>
-                <New-Window-Hint v-if="activeWindowId===0"/>
+                <New-Window-Hint v-if="activeWindowId===0" />
             </div>
-            <div class="input-box">
+            <div class="input-box" id="input-box">
+                <div class="upload-row">
+                    <el-upload
+                    style="display: inline-block; margin-right: 8px"
+                    accept=".pptx,.pdf"
+                    action=""
+                    :http-request="handleUpload"
+                    :before-upload="handleBeforeUpload"
+                    :show-file-list="false"
+                    :disabled="startUploadAudio">
+                        <img src="~@/assets/img/icons/ai-upload.png" />
+                    </el-upload>
+                    <span>支持格式:PDF、PPTX;大小不超过10MB;要求纯文本,不含图片</span>
+                </div>
                 <textarea rows="6" v-model="inputText" :placeholder="$t('ToolBox.AIQuestion.input_placeholder')" @keydown.enter="handleSendMsg"></textarea>
                 <div class="send-btn" @click="handleSendMsg"><img src="~@/assets/img/ai_m/send.png" />{{$t('ToolBox.AIQuestion.send_btn')}}</div>
             </div>
@@ -116,6 +129,9 @@ export default {
             windowContentLoading:null,
             answerLoading:false,//回答中
             companyName:'',
+            aiFileIds:[],
+            // 上传窗口的队列
+            windowSet:new Set()
         };
     },
     watch:{
@@ -162,16 +178,23 @@ export default {
                 if(res.Ret!==200) return
                 const {List} = res.Data
                 this.historyList = List||[]
+
+                this.aiFileIds=this.historyList.map(item => item.OpenaiFileId).filter(Boolean)
+
                 this.windowContentLoading&&this.windowContentLoading.close()
                 //使用模型
                 this.model = this.historyList.length?this.historyList[this.historyList.length-1].Model:'GPT-4 Turbo'
                 //如果有历史记录,则滚动到底部
-                this.$nextTick(()=>{
-                    const windowContentWrap = document.querySelector('.window-content-wrap')
-                    windowContentWrap.scrollTo({
-                        top:windowContentWrap.scrollHeight,
-                        behavior:'smooth'
-                    })
+                this.windowContentToBottom()
+            })
+        },
+        // 滚动到聊天窗口底部
+        windowContentToBottom(){
+            this.$nextTick(()=>{
+                const windowContentWrap = document.querySelector('.window-content-wrap')
+                windowContentWrap.scrollTo({
+                    top:windowContentWrap.scrollHeight,
+                    behavior:'smooth'
                 })
             })
         },
@@ -184,11 +207,12 @@ export default {
                 messageType:'',
                 modelName:''
             }
-            const {Ask,Answer,CreateTime,ModifyTime,isPlay,Model} = msg
+            const {Ask,Answer,CreateTime,ModifyTime,isPlay,Model,OpenaiFilePath} = msg
             if(type==='user'){
                 msgObj.messageText = Ask||''
                 msgObj.messageType = 'question'
                 msgObj.messageTime = CreateTime||''
+                msgObj.askFileUrl = OpenaiFilePath || ''
             }
             else{
                 msgObj.messageText = Answer||''
@@ -196,6 +220,7 @@ export default {
                 msgObj.messageTime = ModifyTime||''
                 msgObj.modelName = Model||''
                 msgObj.isPlay = Boolean(isPlay)
+                msgObj.askFileUrl = OpenaiFilePath || ''
             }
             return msgObj
         },
@@ -211,6 +236,7 @@ export default {
             this.activeWindow=null
             this.historyList=[]
             this.model='GPT-4 Turbo'
+            this.aiFileIds=[]
             //this.inputText=''
             this.isTyping = false
         },
@@ -319,7 +345,7 @@ export default {
             //mock 加入到historyList中
             const msgObj = {
                 AiChatId:-1,
-                AiChatTopicId:0,
+                AiChatTopicId:this.activeWindowId || 0,
                 Ask:this.inputText,
                 Answer:'回答生成中...',
                 CreateTime:'',
@@ -329,20 +355,23 @@ export default {
             this.historyList.push(msgObj)
             
             //滚动到底部
-            this.$nextTick(()=>{
-                const windowContentWrap = document.querySelector('.window-content-wrap')
-                windowContentWrap.scrollTo({
-                    top:windowContentWrap.scrollHeight,
-                    behavior:'smooth'
-                })
-            })
+            this.windowContentToBottom()
+
             const inputText = this.inputText
             this.inputText = ''
-            aiQAInterence.sendChatMsg({
+            let apiName = "sendChatMsg"
+            let params={
                 AiChatTopicId:this.activeWindowId<=0?0:this.activeWindowId,
                 Ask:inputText,
                 // Model:this.model
-            }).then(res=>{
+            }
+            if(this.aiFileIds && this.aiFileIds.length>0){
+                // 文件检索功能
+                apiName="fileRetrieve"
+                params.OpenaiFileId=this.aiFileIds
+            }
+            // console.log(params,"params");
+            aiQAInterence[apiName](params).then(res=>{
                 this.answerLoading=false
                 //在回答未获取前切换了新窗口
                 if(this.historyList.length===0){
@@ -387,7 +416,10 @@ export default {
             })
         },
         //获取窗口列表
-        getWindowList(){
+        /**
+         * @param {*} topicId AiChatTopicId 定位到具体窗口
+         */
+        getWindowList(topicId){
             this.listWrapLoading = this.$loading({
                 target:document.querySelector('.list-wrap'),
                 background: 'rgba(244, 245, 249, 1)'
@@ -395,6 +427,9 @@ export default {
             aiQAInterence.getTopicList().then(res=>{
                 if(res.Ret!==200) return
                 this.windowList = res.Data.List||[]
+                if(topicId){
+                    this.changeActiveWindow({AiChatTopicId:topicId})
+                }
                 this.listWrapLoading&&this.listWrapLoading.close()
             })
         },
@@ -405,11 +440,112 @@ export default {
                     this.companyName=res.Data.CompanyName||''
                 }
             })
+        },
+        inputBoxDragover(event){
+            event.preventDefault(); //阻止默认行为,允许放置
+        },
+        inputBoxDrop(event){
+            event.preventDefault(); //阻止浏览器默认行为
+            // 获取文件的数据
+            const DataTransferItemList = event.dataTransfer.files
+            if(DataTransferItemList && DataTransferItemList.length){
+                if(DataTransferItemList.length>1){
+                    return this.$message.error("单次只能上传一个文件,请重试");
+                }else{
+                    let file = DataTransferItemList[0]
+                    if(file.type && (file.name.endsWith('.pdf')||file.name.endsWith('.pptx'))){
+                        if(file.size/1024/1024 > 10.1){
+                            this.$message.error("上传文件大小不超过10MB");
+                            return false;
+                        }
+                        this.handleUpload({file})
+                    }else{
+                        return this.$message.error("上传文件格式只支持PDF、PPTX");
+                    }
+                }
+            }else{
+                // 没有文件数据
+                let txt = event.dataTransfer.getData("text/plain")
+                this.inputText=txt
+            }
+        },
+        handleBeforeUpload(e) {
+            if(!(e.name.endsWith('.pdf') || e.name.endsWith('.pptx'))){
+                this.$message.error("上传文件格式只支持PDF、PPTX");
+                return false;
+            }
+            if(!(e.size/1024/1024 < 10.1)){
+                this.$message.error("上传文件大小不超过10MB");
+                return false;
+            }
+        },
+        handleUpload(e){
+            // console.log(this.windowSet,this.activeWindowId);
+            if(this.windowSet.has(this.activeWindowId)){
+                return this.$message.warning("请等待文件上传完成")
+            }
+
+            let {file} = e
+            let downloadHint = this.$message({
+                type:"info",
+                message:'上传中,请稍后······',
+                duration:0,
+                iconClass:'el-icon-loading'
+            })
+            let formData = new FormData()
+            formData.append('File',file)
+            formData.append('AiChatTopicId',this.activeWindowId)
+            this.windowSet.add(this.activeWindowId)
+            aiQAInterence.fileUpload(formData).then(res=>{
+                downloadHint.close()
+                if(res.Ret == 200){
+                    let Data = res.Data || {}
+                    this.$message.success(`${Data.ResourceName}上传成功`)
+                    if(this.windowList.find(item => item.AiChatTopicId == Data.AiChatTopicId)){
+                        // 窗口存在
+                        this.windowSet.delete(Data.AiChatTopicId)
+
+                        if(Data.AiChatTopicId == this.activeWindowId){
+                            this.aiFileIds.push(Data.OpenaiFileId)
+                            const msgObj = {
+                                AiChatId:Data.AiChatId || -1,
+                                AiChatTopicId:Data.AiChatTopicId,
+                                Ask:Data.ResourceName,
+                                OpenaiFilePath:Data.ResourceUrl,
+                                Answer:Data.Answer || '',
+                                CreateTime:Data.CreateTime||'',
+                                ModifyTime:Data.ModifyTime || '',
+                                Model:this.model
+                            }
+                            this.historyList.push(msgObj)
+                            this.windowContentToBottom()
+                        }
+                    }else{
+                        //窗口不存在
+                        this.windowSet.delete(0)
+                        this.getWindowList(this.activeWindowId==0 ? Data.AiChatTopicId:0)
+                    }
+                }
+            }).catch(()=>{
+                downloadHint.close()
+                // 失败,清空
+                this.windowSet.clear()
+            })
         }
     },
     mounted(){
         this.getWindowList()
         this.getBaseConfig()
+        const dropDom = document.getElementById('input-box')
+        dropDom.addEventListener('dragover',this.inputBoxDragover);
+
+        dropDom.addEventListener('drop',this.inputBoxDrop);
+    },
+    beforeDestroy(){
+        const dropDom = document.getElementById('input-box')
+        dropDom.removeEventListener('dragover',this.inputBoxDragover);
+
+        dropDom.removeEventListener('drop',this.inputBoxDrop);
     }
 };
 </script>
@@ -556,13 +692,30 @@ $border-color:#3D52A1;
             }
         }
         .input-box{
-            padding:30px;
+            padding:12px 30px 30px;
             position: relative;
+            .upload-row{
+                display: flex;
+                align-items: center;
+                padding: 0 20px;
+                margin-bottom: 12px;
+                img{
+                    height: 20px;
+                    width: 20px;
+                    vertical-align: bottom;
+                    box-shadow: 3px 3px 8px 0px #182c421f;
+                }
+                span{
+                    color: #A5A5A5;
+                    font-size: 15px;
+                    font-weight: 400;
+                }
+            }
             textarea{
                 width:100%;
                 border-radius: 16px;
                 box-sizing: border-box;
-                padding:20px 85px 20px 20px;
+                padding:20px 95px 20px 20px;
                 font-size: 16px;
                 resize: none;
                 border-color: #E3E3E3;

+ 42 - 4
src/views/operation_manage/AIQA/components/messageItem.vue

@@ -1,10 +1,21 @@
 <template>
-    <div class="message-item-wrap" :class="messageInfo.messageType">
+    <div class="message-item-wrap" :class="messageInfo.messageType" 
+    v-if="!(messageInfo.messageType=='answer' && messageInfo.askFileUrl && (!messageInfo.messageText))">
+    <!-- 上传文件时,不想有回答 -->
         <div class="message-icon"><img :src="IconSrc"  v-if="IconSrc"/></div>
         <div class="message-info">
             <span class="message-time" :class="messageInfo.messageType">{{messageInfo.messageTime}}</span>
-            <div class="message-text" :class="messageInfo.messageType" v-if="!isPlay">{{messageInfo.messageText}}</div>
-            <div class="message-text typing" :class="messageInfo.messageType" v-else>{{typingText}}</div>
+            <div class="message-text" :class="messageInfo.messageType">
+                <template v-if="messageInfo.askFileUrl">
+                    <div class="message-file" @click="fileClickHandle(messageInfo.askFileUrl)">
+                        <img :src="getFileIcon" />
+                        <span :class="{'typing':isPlay}">{{isPlay ? typingText : messageInfo.messageText}}</span>
+                    </div>
+                </template>
+                <template v-else>
+                    <span :class="{'typing':isPlay}">{{isPlay ? typingText : messageInfo.messageText}}</span>
+                </template>
+            </div>
         </div>
     </div>
 </template>
@@ -55,6 +66,19 @@ export default {
             const {messageType,modelName} = this.messageInfo
             const iconType = messageType==='question'?'user':'GPT-4 Turbo'
             return this.iconMap[iconType]||''
+        },
+        getFileIcon(){
+            if(this.messageInfo.askFileUrl){
+                if(this.messageInfo.askFileUrl.endsWith('.pdf')){
+                    return require('@/assets/img/icons/file_type_pdf.png')
+                }else if(this.messageInfo.askFileUrl.endsWith('.pptx')){
+                    return require('@/assets/img/icons/file_type_ppt.png')
+                }else{
+                    return require('@/assets/img/icons/file_type_unknown.png')
+                }
+            }else{
+                return ''
+            }
         }
     },
     methods: {
@@ -78,6 +102,9 @@ export default {
             this.isPlay = false
             this.typingText=''
             this.$emit('finishedTyping',this.messageInfo)
+        },
+        fileClickHandle(url){
+            window.open(url,"_blank")
         }
     },
 };
@@ -108,13 +135,24 @@ export default {
             padding:14px 20px;
             display: inline-block;
             white-space: pre-line;
+            .message-file{
+                display: flex;
+                align-items: center;
+                cursor: pointer;
+                margin: -4px;
+                img{
+                   height: 24px;
+                   width: 24px; 
+                   margin-right: 8px;
+                }
+            }
             &.answer{
                 background-color: #F4F4F4;
             }
             &.question{
                 background-color: #E3EFFD;
             }
-            &.typing{
+            .typing{
                 &::after{
                     content: '|';
                     animation: blink 1s infinite

+ 21 - 2
src/views/ppt_manage/newVersion/pptEnPublish.vue

@@ -58,7 +58,7 @@ import mixins from '../mixins/mixins';
 import html2canvas from 'html2canvas';
 import pptxgen from "pptxgenjs";
 import moment from 'moment';
-import{dataBaseInterface,getOSSSign} from "@/api/api.js"
+import{pptInterface,dataBaseInterface,getOSSSign} from "@/api/api.js"
 import {pptEnInterface} from '@/api/modules/pptEnApi.js';
 import Highcharts from "highcharts/highstock";
 import HighchartszhCN  from '@/utils/highcahrts-zh_CN'
@@ -491,10 +491,29 @@ export default {
       };
 
       pptx2.write('blob').then((data)=>{
+        // 1走后端接口上传
+        const uploadType=this.$setting.dynamicOutLinks.PptUpdateApi ||
+                        this.$store.state.dynamicOutLinks.PptUpdateApi ||
+                        JSON.parse(localStorage.getItem('dynamicOutLinks')).PptUpdateApi
+        if(uploadType==1){
+          let form = new FormData()
+          form.append("file",data)
+          form.append("PptId",this.$route.query.id) 
+          pptInterface.uploadPPTXFile(form).then(res=>{
+            if(res.Ret===200){
+              this.publishPPT(res.Data.ResourceUrl)
+            }
+          })
+          return
+        }
+
+        
+        // 上传到阿里云oss
+        // this.handleUploadToOSS(data)
         let clientType = this.$setting.dynamicOutLinks.ObjectStorageClient ||
                         this.$store.state.dynamicOutLinks.ObjectStorageClient ||
                         JSON.parse(localStorage.getItem('dynamicOutLinks')).ObjectStorageClient
-        // 上传到 对象存储器 阿里云、mino
+        // 上传到 对象存储器
         uploadFileDirect(clientType,data,temName,options).then(url=>{
           console.log('文件地址',url);
           this.publishPPT(url)

+ 18 - 8
src/views/ppt_manage/newVersion/pptPublish.vue

@@ -515,15 +515,25 @@ export default {
       };
 
       //console.log('pptx',pptx)
+      //根据配置选择是走后端接口上传还是直接前端上传到oss
       pptx2.write('blob').then((data)=>{
-        // let form = new FormData()
-        // form.append("file",data)
-        // form.append("PptId",this.$route.query.id) 
-        // pptInterface.uploadPPTXFile(form).then(res=>{
-        //   if(res.Ret===200){
-        //     this.publishPPT(res.Data.ResourceUrl)
-        //   }
-        // })
+        // 1走后端接口上传
+        const uploadType=this.$setting.dynamicOutLinks.PptUpdateApi ||
+                        this.$store.state.dynamicOutLinks.PptUpdateApi ||
+                        JSON.parse(localStorage.getItem('dynamicOutLinks')).PptUpdateApi
+        if(uploadType==1){
+          let form = new FormData()
+          form.append("file",data)
+          form.append("PptId",this.$route.query.id) 
+          pptInterface.uploadPPTXFile(form).then(res=>{
+            if(res.Ret===200){
+              this.publishPPT(res.Data.ResourceUrl)
+            }
+          })
+          return
+        }
+
+        
         // 上传到阿里云oss
         // this.handleUploadToOSS(data)
         let clientType = this.$setting.dynamicOutLinks.ObjectStorageClient ||

+ 3 - 3
src/views/ppt_manage/newVersion/utils/config.js

@@ -413,21 +413,21 @@ export const modelConfig = [{
             width:33,
             height:(restHeight)*0.48*0.9,
             x:0,
-            y:(restHeight)*0.48
+            y:(restHeight)*0.48+(restHeight*0.48*0.1)/2
         },
         {
             position:5,
             width:33,
             height:(restHeight)*0.48*0.9,
             x:33,
-            y:(restHeight)*0.48
+            y:(restHeight)*0.48+(restHeight*0.48*0.1)/2
         },
         {
             position:6,
             width:33,
             height:(restHeight)*0.48*0.9,
             x:33*2,
-            y:(restHeight)*0.48
+            y:(restHeight)*0.48+(restHeight*0.48*0.1)/2
         }]
     },{
         modelId:11,

+ 25 - 4
src/views/system_manage/enAuthManage.vue

@@ -126,7 +126,7 @@
           <span>{{$t('SystemManage.DepartManage.user_table_depart')}}:{{setAuthData.DepartmentGroup}}</span>
         </div>
         <div class="select-list">
-          <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">{{$t('Common.all_select')}}</el-checkbox>
+          <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" class="check-all">{{$t('Common.all_select')}}</el-checkbox>
             <el-checkbox-group v-model="setAuthData.selectList" @change="handleCheckedChange">
               <el-checkbox v-for="auth in authOptions" :label="auth.code" :key="auth.code" >{{auth.label}}</el-checkbox>
             </el-checkbox-group>
@@ -249,6 +249,9 @@ export default {
       //   },{
       //     code:'english_day_new_admin',
       //     label: '每日资讯管理员'
+      //   },{
+      //       code:'overseas_custorm',
+      //       label:'海外客户管理员'
       //   }],//权限设置页面选项
       isIndeterminate:false,//权限设置 全选样式
       checkAll:true,//权限设置 全选值
@@ -491,16 +494,34 @@ export default {
     padding:40px 100px;
     .user-info{
       padding-bottom: 20px;
-      margin-bottom: 20px;
-      border-bottom: 1px solid #DCDFE6;
+      margin-bottom: 30px;
       display: flex;
       justify-content: space-between;
+      span{
+        background-color: #EEF5FE;
+        border:1px solid #0052D9;
+        border-radius: 4px;
+        padding:5px 10px;
+      }
     }
     .select-list{
-      background-color: #F0F2F5;
+      border:1px solid #DCDFE6;
+      border-radius: 4px;
       padding:20px;
+      .check-all{
+        display: block;
+        border-bottom:1px solid #DCDFE6;
+        margin: 0 -20px;
+        padding-left: 20px;
+        padding-bottom: 20px;
+      }
       .el-checkbox-group{
         margin-top: 20px;
+        display: flex;
+        flex-wrap: wrap;
+        .el-checkbox{
+            width:40%;
+        }
       }
     }
   }

+ 8 - 1
src/views/system_manage/etaBaseConfig.vue

@@ -81,6 +81,10 @@
                         <el-input type="text" v-model="formData.ICPLicense" placeholder="文本中输入≥2个空格表示文本分段,小屏时换行展示" />
                         <ConfigAnnotation picHintText="" picName="ICPLicense" @showImage="previewImage"/>
                     </el-form-item>
+                    <el-form-item label="登录页标题" prop="ETATitle">
+                        <el-input type="text" v-model="formData.ETATitle" placeholder="请输入登录页标题" />
+                        <ConfigAnnotation picHintText="" picName="ETATitle" @showImage="previewImage"/>
+                    </el-form-item>
                 </div>
             </div>
             <!-- 研报设置 -->
@@ -385,6 +389,7 @@ export default {
                 IsReportApprove:false,//是否开启研报审批
                 ReportApproveType:'eta',//研报审批选项
                 ICPLicense:'', //备案信息
+                ETATitle:'', //登录页标题
             },//表单预设值
             rules: {
                 Disclaimer:[{ required: true, message: '请输入免责声明', trigger: 'blur' }],
@@ -413,6 +418,7 @@ export default {
                 XfVcn:[{ required: true, message: '请输入voice_name', trigger: 'blur' }],
                 CnPptCoverImgs:[{ required: true, validator:ListValidator}],
                 EnPptCoverImgs:[{ required: true, validator:ListValidator}],
+                ETATitle:[{ required: true, message: '请输入登录页标题', trigger: 'blur' }],
             },//表单校验
             disclaimerConfig:{
                 toolbarButtons:[
@@ -465,7 +471,8 @@ export default {
                 'pptBgPic':[require('@/assets/img/eta_base_config/ppt_bgpic.jpg')],
                 'pptBackPic':[require('@/assets/img/eta_base_config/ppt_back.jpg')],
                 'emailContentTemplate':[require('@/assets/img/eta_base_config/email_content_template.png')],
-                'ICPLicense':[require('@/assets/img/eta_base_config/record_information.jpg')]
+                'ICPLicense':[require('@/assets/img/eta_base_config/record_information.jpg')],
+                'ETATitle':[require('@/assets/img/eta_base_config/ETA_title.png')]
             },
             /* loading */
             configLoading:null,