batchComputedV2.vue 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085
  1. <template>
  2. <el-dialog
  3. :visible.sync="isShow"
  4. :close-on-click-modal="false"
  5. :modal-append-to-body="false"
  6. @close="handleClose"
  7. custom-class="batch-computed-dialog fit-screen-dialog"
  8. center
  9. top="5vh"
  10. v-dialogDrag
  11. :title="showSave ? $t('EtaBasePage.title_batch_save') : $t('EtaBasePage.title_batch_calc')"
  12. >
  13. <div class="batch-computed-wrap" v-if="!showSave">
  14. <el-form inline :disabled="operationForm.view">
  15. <div class="type-wrap">
  16. <div style="margin-right:50px">
  17. <span><!-- 计算公式 -->{{$t('EtaBasePage.calculate_formula')}}</span>
  18. <el-select :disabled="isEdit" v-model="computedType" @change="handleComputedTypeChange" :placeholder="$t('Edb.please_select')">
  19. <el-option
  20. v-for="opt in computedBatchTypes"
  21. :key="opt.type"
  22. :label="opt.name"
  23. :value="opt.type"
  24. />
  25. </el-select>
  26. </div>
  27. <div style="flex:1">
  28. <!-- 累计值转月/季值 -->
  29. <el-form-item v-if="computedType=='toMonthSeason'">
  30. <el-radio-group v-model="subComputedType" @change="handleComputedSubTypeChange">
  31. <el-radio :label="5">
  32. <!-- 转月值 -->
  33. {{$t('Edb.CalculatesAll.to_monthly_v2')}}
  34. </el-radio>
  35. <el-radio :label="61">
  36. <!-- 转季值 -->
  37. {{$t('Edb.CalculatesAll.to_quarterly_v2')}}
  38. </el-radio>
  39. </el-radio-group>
  40. </el-form-item>
  41. <!-- N期移动均值、N期环比值、N期环差值 -->
  42. <el-form-item required v-if="[8,12,13].includes(computedType)" :label="$t('EtaBasePage.label_n_val')" style="width:280px">
  43. <el-input v-model="formData.nNum" :placeholder="$t('Edb.InputHolderAll.input_n_value')" type="number" style="width:200px"></el-input>
  44. </el-form-item>
  45. <!-- 超级季节性 -->
  46. <template v-if="computedType==35">
  47. <el-form-item required :label="$t('EtaBasePage.label_n_val')" style="width:280px">
  48. <el-input v-model="formData.nNum" :placeholder="$t('Edb.InputHolderAll.input_n_value')" type="number" style="width:200px"></el-input>
  49. </el-form-item>
  50. <el-form-item :label="$t('EtaBasePage.label_calendar')" style="width:180px">
  51. <el-select v-model="formData.calendarType" style="width:120px">
  52. <el-option :label="$t('Chart.calendar_gre')" value="公历"></el-option>
  53. <el-option :label="$t('Chart.calendar_lunar_text')" value="农历"></el-option>
  54. </el-select>
  55. </el-form-item>
  56. </template>
  57. <!-- 降频 -->
  58. <template v-if="computedType==51">
  59. <el-form-item required :label="$t('Edb.Detail.e_fre')" style="width:180px">
  60. <el-select v-model="formData.frequency" style="width:120px">
  61. <el-option v-for="opt in frequencyArr" :key="opt.value" :label="opt.label" :value="opt.value"></el-option>
  62. </el-select>
  63. </el-form-item>
  64. <el-form-item :label="$t('EtaBasePage.label_val_type')" style="width:200px">
  65. <el-select v-model="formData.valueType" style="width:120px">
  66. <el-option key="期末值" :label="$t('EtaBasePage.val_type_end')" value="期末值"/>
  67. <el-option key="平均值" :label="$t('EtaBasePage.val_type_average')" value="平均值"/>
  68. </el-select>
  69. </el-form-item>
  70. </template>
  71. <!-- 累计值 -->
  72. <template v-if="computedType=='accumulate'">
  73. <el-form-item>
  74. <el-radio v-model="subComputedType" :label="62">
  75. <!-- 累计值 -->
  76. {{$t('Edb.CalculatesAll.cumulate')}}
  77. </el-radio>
  78. </el-form-item>
  79. <el-form-item required :label="$t('Edb.Detail.e_fre')" style="width:180px" v-if="subComputedType==62">
  80. <el-select v-model="formData.frequency" style="width:120px">
  81. <el-option v-for="opt in frequencyArr" :key="opt.value" :label="opt.label" :value="opt.value"></el-option>
  82. </el-select>
  83. </el-form-item>
  84. <el-form-item :label="$t('Edb.CalculatesAll.latest_processing')" style="width:210px" v-if="subComputedType==62">
  85. <el-select v-model="formData.newValue" style="width:120px">
  86. <el-option :label="$t('EtaBasePage.default_select_text')" :value="0"/>
  87. <el-option :label="$t('EtaBasePage.mean_imputation_select_text')" :value="1"/>
  88. </el-select>
  89. </el-form-item>
  90. <el-form-item>
  91. <el-radio v-model="subComputedType" :label="63">
  92. <!-- /* '年初至今累计值' */ -->
  93. {{$t('Edb.CalculatesAll.cumulate_oneyear')}}
  94. </el-radio>
  95. </el-form-item>
  96. </template>
  97. <!-- 指数修匀 -->
  98. <template v-if="computedType==72">
  99. <el-form-item required :label="$t('EtaBasePage.alpha_value_lable')" style="width:220px">
  100. <el-input v-model.trim="formData.alphaValue" style="width:140px" :placeholder="$t('Edb.InputHolderAll.input_alpha_val')"></el-input>
  101. </el-form-item>
  102. </template>
  103. <!-- 与常数计算 -->
  104. <template v-if="computedType=='withNum'">
  105. <el-form-item required :label="$t('EtaBasePage.formula_lable')">
  106. <el-input v-model="formData.formula" :placeholder="$t('EtaBasePage.input_formula_msg')" clearable style="width: 200px"/>
  107. <span>
  108. <!-- 公式示例:A+100,或A*2 -->
  109. {{$t('EtaBasePage.formula_example_text')}}
  110. </span>
  111. </el-form-item>
  112. </template>
  113. <!-- 与单指标计算 -->
  114. <template v-if="computedType=='withEDB'">
  115. <el-form-item required :label="$t('EtaBasePage.metric_label_b')">
  116. <el-select
  117. v-model="select_target"
  118. v-loadMore="searchLoad"
  119. :filterable="!select_target"
  120. clearable
  121. :placeholder="$t('Edb.InputHolderAll.input_name')"
  122. style="width: 250px"
  123. remote
  124. :remote-method="getTarget"
  125. @click.native="inputFocusHandle"
  126. @change="chooseTarget"
  127. @blur="search_have_more = false"
  128. >
  129. <i slot="prefix" class="el-input__icon el-icon-search"></i>
  130. <el-option
  131. v-for="item in searchOptions"
  132. :key="item.EdbInfoId"
  133. :label="$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
  134. :value="item.EdbInfoId"
  135. :disabled="!item.HaveOperaAuth"
  136. >
  137. <div>
  138. <img
  139. :src="$icons.lock_ico2"
  140. width="18"
  141. height="18"
  142. style="vertical-align:middle"
  143. v-if="!item.HaveOperaAuth"
  144. />
  145. {{$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName}}
  146. </div>
  147. </el-option>
  148. </el-select>
  149. </el-form-item>
  150. <el-form-item required :label="$t('EtaBasePage.formula_lable')">
  151. <el-input v-model="formData.formula" :placeholder="$t('EtaBasePage.input_formula_msg')" clearable style="width: 200px"/>
  152. <span>
  153. <!-- 公式示例:A+B,或A/B,A/(A+B) -->
  154. {{$t('EtaBasePage.formula_example_text_a_b')}}
  155. </span>
  156. </el-form-item>
  157. <el-form-item :label="$t('EtaBasePage.create_edb_time_index')">
  158. <el-cascader
  159. v-model="formData.timeSeriesVal"
  160. style="width:180px"
  161. :options="timeSeriesOpt"
  162. :props="{emitPath:false}"
  163. :show-all-levels="false"
  164. :placeholder="$t('Edb.please_select')"
  165. ></el-cascader>
  166. </el-form-item>
  167. <el-form-item :label="$t('EtaBasePage.null_val_deal')">
  168. <el-select
  169. v-model="formData.nullValueWay"
  170. :placeholder="$t('Edb.please_select')"
  171. style="width:180px"
  172. >
  173. <el-option
  174. v-for="item in nullWayOptions"
  175. :key="item.value"
  176. :label="item.label"
  177. :value="item.value"
  178. >
  179. </el-option>
  180. </el-select>
  181. </el-form-item>
  182. <el-form-item :label="$t('EtaBasePage.max_null_val')" v-if="showMaxNullDeal">
  183. <el-select
  184. v-model="formData.maxNullWay"
  185. :placeholder="$t('Edb.please_select')"
  186. >
  187. <el-option :label="$t('EtaBasePage.equal_zeto')" :value="1" />
  188. <el-option label="跳过空值" :value="2" />
  189. </el-select>
  190. </el-form-item>
  191. </template>
  192. <!-- 多指标求和/平均 -->
  193. <template v-if="computedType=='multipleEDB'">
  194. <el-form-item style="margin-right:30px">
  195. <el-radio-group :disabled="isEdit" v-model="subComputedType">
  196. <el-radio :label="81"><!-- -->{{$t('EtaBasePage.sum_radio_label')}}</el-radio>
  197. <el-radio :label="82"><!-- 求平均 -->{{$t('EtaBasePage.average_radio_label')}}</el-radio>
  198. </el-radio-group>
  199. </el-form-item>
  200. <el-form-item :label="$t('EtaBasePage.create_edb_time_index')">
  201. <el-cascader
  202. v-model="formData.timeSeriesVal"
  203. style="width:180px"
  204. :options="timeSeriesOpt"
  205. :props="{emitPath:false}"
  206. :show-all-levels="false"
  207. :placeholder="$t('Edb.please_select')"
  208. ></el-cascader>
  209. </el-form-item>
  210. <el-form-item :label="$t('EtaBasePage.null_val_deal')">
  211. <el-select
  212. v-model="formData.nullValueWay"
  213. :placeholder="$t('Edb.please_select')"
  214. style="width:180px"
  215. >
  216. <el-option
  217. v-for="item in nullWayOptions"
  218. :key="item.value"
  219. :label="item.label"
  220. :value="item.value"
  221. >
  222. </el-option>
  223. </el-select>
  224. </el-form-item>
  225. </template>
  226. </div>
  227. </div>
  228. </el-form>
  229. <div class="filter-wrap" style="margin-top:20px">
  230. <p style="margin-bottom:10px">
  231. <!-- 待选指标(选择指标数量不超过{{MAXAddNUM}}) -->
  232. {{$t('EtaBasePage.pending_metrics',{num:MAXAddNUM})}}
  233. </p>
  234. <div>
  235. <cascader
  236. style="display:inline-block"
  237. v-model="filter.classify"
  238. :options="classifyOpt"
  239. clearable
  240. collapse-tags
  241. :placeholder="$t('EtaBasePage.label_classify')"
  242. cascaderWidth="width: 240px"
  243. @changeVal="handleFilter"
  244. :config="{ multiple: true, emitPath: false }"
  245. />
  246. <el-select
  247. v-model="filter.frequency"
  248. :placeholder="$t('EtaBasePage.select_frequency')"
  249. style="width: 140px"
  250. clearable
  251. multiple
  252. collapse-tags
  253. @change="handleFilter"
  254. :disabled="[5,61].includes(subComputedType)"
  255. >
  256. <el-option
  257. v-for="item in frequencyArr"
  258. :key="item.value"
  259. :label="item.label"
  260. :value="item.value"
  261. >
  262. </el-option>
  263. </el-select>
  264. <el-cascader
  265. v-model="filter.user"
  266. :placeholder="$t('EtaBasePage.table_col_creator')"
  267. :options="sysUserOpts"
  268. :props="sysUserProps"
  269. collapse-tags
  270. :show-all-levels="false"
  271. clearable
  272. filterable
  273. style="width:240px"
  274. @change="handleFilter"
  275. />
  276. <el-input
  277. :placeholder="$t('Edb.InputHolderAll.input_name_orid')"
  278. v-model="filter.keyword"
  279. style="width: 200px"
  280. @keydown.enter.native="handleFilter"
  281. >
  282. <i slot="prefix" class="el-input__icon el-icon-search"></i>
  283. </el-input>
  284. <el-checkbox
  285. :label="$t('EtaBasePage.label_all_check')"
  286. v-model="isCheckAll"
  287. :indeterminate="isCheckIndeterminate"
  288. style="margin-left:10px"
  289. @change="listCheckAllChange"
  290. :disabled="operationForm.view"
  291. />
  292. </div>
  293. </div>
  294. <div class="table-wrap">
  295. <div class="left-box">
  296. <el-table
  297. :data="list"
  298. border
  299. @sort-change="sortChange"
  300. @selection-change="selectionChange"
  301. ref="edbDataRef"
  302. @select="selectHandle"
  303. @select-all="selectAllHandle"
  304. height="500px"
  305. v-loading="listLoading"
  306. >
  307. <el-table-column type="selection" min-width="50" align="center" :selectable="filterEdbAuth"/>
  308. <el-table-column :label="$t('EtaBasePage.full_metric_name')" show-overflow-tooltip align="center" :prop="$parent.currentLang==='en'?'EdbNameEn':'EdbName'"/>
  309. <el-table-column :label="$t('Edb.Detail.e_latest_date')" align="center" prop="EndDate" width="120px" />
  310. <el-table-column :label="$t('Edb.Detail.e_latest_value')" align="center" show-overflow-tooltip prop="EndValue" width="80px"/>
  311. <el-table-column :label="$t('EtaBasePage.table_col_creator')" align="center" show-overflow-tooltip prop="SysUserRealName" width="80px"/>
  312. <el-table-column :label="$t('Edb.Detail.e_fre')" align="center" prop="Frequency" width="50px">
  313. <template slot-scope="scope">
  314. <span>{{ getFrequencyTrans(scope.row.Frequency) }}</span>
  315. </template>
  316. </el-table-column>
  317. <el-table-column :label="$t('Edb.Detail.e_unit')" show-overflow-tooltip align="center" :prop="$parent.currentLang==='en'?'UnitEn':'Unit'" width="50px">
  318. <template slot-scope="scope">
  319. <span>{{ getUnitTrans(scope.row.Unit) }}</span>
  320. </template>
  321. </el-table-column>
  322. </el-table>
  323. <m-page
  324. style="margin-top:10px"
  325. class="table-page"
  326. v-show="total"
  327. :total="total"
  328. :pageSize="pageSize"
  329. :page_no="page"
  330. :pagercount="5"
  331. @handleCurrentChange="pageNumberChange"
  332. />
  333. </div>
  334. <div style="padding-top:200px;margin:0 30px">
  335. <el-button type="primary" :disabled="operationForm.view" :loading="addLoading" @click="getAddEdbListData">
  336. <!-- 加入已选指标 -->
  337. {{$t('EtaBasePage.add_to_selections')}}
  338. </el-button>
  339. </div>
  340. <div class="right-box">
  341. <el-table
  342. :data="selectList"
  343. border
  344. height="500px"
  345. >
  346. <el-table-column :label="$t('EtaBasePage.serial_num')" width="50px" align="center" prop="No" v-if="computedType=='multipleEDB'">
  347. <template slot-scope="scope">
  348. {{scope.$index|getNoText}}
  349. </template>
  350. </el-table-column>
  351. <el-table-column :label="$t('EtaBasePage.full_metric_name')" show-overflow-tooltip align="center" :prop="$parent.currentLang==='en'?'EdbNameEn':'EdbName'"/>
  352. <el-table-column width="50px" align="center" v-if="!operationForm.view">
  353. <template slot="header" slot-scope="scope">
  354. <img @click="handleDelSelect('all')" style="width:15px;height:15px;cursor: pointer;" src="~@/assets/img/ai_m/delete.png" alt="">
  355. </template>
  356. <template slot-scope="scope">
  357. <img @click="handleDelSelect(scope)" style="width:15px;height:15px;cursor: pointer;" src="~@/assets/img/ai_m/delete.png" alt="">
  358. </template>
  359. </el-table-column>
  360. </el-table>
  361. </div>
  362. </div>
  363. <div style="text-align:center;margin:60px 0 40px 0">
  364. <el-button type="primary" plain @click="handleCloseSelf">{{$t('Dialog.cancel_btn')}}</el-button>
  365. <el-button type="primary" @click="handleNextStep">{{$t('Dialog.next_step')}}</el-button>
  366. </div>
  367. </div>
  368. <!-- 结果保存 -->
  369. <batchComputedSave
  370. :select_target="select_target"
  371. :computedType="computedType"
  372. :subComputedType="subComputedType"
  373. :selectList="selectList"
  374. :formData="formData"
  375. :isEdit="isEdit"
  376. :operationForm="operationForm"
  377. @close="showSave=false"
  378. @addCallBack="handleAddSuccess"
  379. v-else
  380. />
  381. </el-dialog>
  382. </template>
  383. <script>
  384. import mPage from '@/components/mPage.vue'
  385. import {computedBatchTypesV2,getBatchComputedTypesV2} from './util'
  386. import { dataBaseInterface,departInterence } from '@/api/api.js';
  387. import batchComputedSave from './batchComputedSave.vue';
  388. import {generateSeriesArray} from './util'
  389. const tag_arr = generateSeriesArray();
  390. export default {
  391. components:{mPage,batchComputedSave},
  392. props:{
  393. isShow:{
  394. type: Boolean
  395. },
  396. operationForm: {
  397. type: Object,
  398. },
  399. type: {
  400. type: Number
  401. },
  402. },
  403. filters:{
  404. getNoText(e){
  405. return tag_arr[e]
  406. }
  407. },
  408. computed:{
  409. // 最大添加指标的上限
  410. MAXAddNUM(){
  411. let num=50
  412. if(this.computedType=='multipleEDB'){
  413. num=100
  414. }
  415. return num
  416. },
  417. /* max空值处理显示 当输入的公式包含MAX、MIN且空值处理为0时,输入公式失焦后出现右侧选项; */
  418. showMaxNullDeal() {
  419. let haveMaxOrMin = this.formData.formula.toUpperCase().includes('MAX') || this.formData.formula.toUpperCase().includes('MIN')
  420. return haveMaxOrMin && this.formData.nullValueWay===4
  421. },
  422. timeSeriesOpt(){
  423. let arr=[
  424. {
  425. // label:`指标A`,
  426. label:this.$t('EtaBasePage.edbTagA'),
  427. value:'A'
  428. },
  429. {
  430. // label:`指标B`,
  431. label:this.$t('EtaBasePage.edbTagB'),
  432. value:'B'
  433. }
  434. ]
  435. if(this.computedType=='multipleEDB'){
  436. arr=this.selectList.map((item,index)=>{
  437. return{
  438. label:`指标${tag_arr[index]}`,
  439. value:tag_arr[index]
  440. }
  441. })
  442. }
  443. return [
  444. {
  445. // label:'指定指标时间序列',
  446. lable:this.$t('EtaBasePage.specify_series_label'),
  447. value:'0',
  448. children:arr
  449. },
  450. {
  451. // label:'所有指标时间序列并集',
  452. lable:this.$t('EtaBasePage.union_series_label'),
  453. value:'all',
  454. }
  455. ]
  456. },
  457. frequencyArr(){
  458. if(this.computedType==75){
  459. return [
  460. {
  461. value: '周度',
  462. label: /* '周度' */this.$t('Edb.FreAll.week'),
  463. },
  464. {
  465. value: '旬度',
  466. label: /* '旬度' */this.$t('Edb.FreAll.dekad'),
  467. },
  468. {
  469. value: '月度',
  470. label: /* '月度' */this.$t('Edb.FreAll.month'),
  471. },
  472. {
  473. value: '季度',
  474. label: /* '季度' */ this.$t('Edb.FreAll.quarter'),
  475. },
  476. {
  477. value: '年度',
  478. label: /* '年度' */ this.$t('Edb.FreAll.year'),
  479. }]
  480. }
  481. return [
  482. {
  483. value: '日度',
  484. label: /* '日度' */this.$t('Edb.FreAll.day'),
  485. },
  486. {
  487. value: '周度',
  488. label: /* '周度' */this.$t('Edb.FreAll.week'),
  489. },
  490. {
  491. value: '旬度',
  492. label: /* '旬度' */this.$t('Edb.FreAll.dekad'),
  493. },
  494. {
  495. value: '月度',
  496. label: /* '月度' */this.$t('Edb.FreAll.month'),
  497. },
  498. {
  499. value: '季度',
  500. label: /* '季度' */ this.$t('Edb.FreAll.quarter'),
  501. },
  502. {
  503. value: '年度',
  504. label: /* '年度' */ this.$t('Edb.FreAll.year'),
  505. }]
  506. },
  507. computedBatchTypes(){
  508. return getBatchComputedTypesV2()
  509. }
  510. },
  511. watch: {
  512. isShow(n){
  513. if(!n){
  514. this.subComputedType=''
  515. this.select_target=''
  516. this.selectList=[]
  517. this.tableDataCheckedList=[]
  518. this.tableDataIds=[]
  519. this.isCheckAll=false
  520. this.isCheckIndeterminate=false
  521. this.checkAllStatus=false
  522. this.selectionReactCancel=false
  523. this.isEdit=false
  524. this.showSave=false
  525. this.computedType=computedBatchTypesV2[0].type
  526. this.filter={
  527. classify:'',
  528. frequency:'',
  529. user:'',
  530. keyword:''
  531. }
  532. this.formData={
  533. nNum:1,
  534. calendarType:'公历',
  535. frequency:'',
  536. valueType:'期末值',
  537. newValue:0,
  538. alphaValue:'',
  539. formula:'',
  540. timeSeriesVal:'A',
  541. nullValueWay:0,
  542. maxNullWay:1,
  543. }
  544. }else{
  545. // 编辑多指标求和\平均
  546. if([81,82].includes(this.type)){
  547. this.initData()
  548. }
  549. this.handleFilter()
  550. }
  551. }
  552. },
  553. data() {
  554. return {
  555. showSave:false,//显示结果保存模块
  556. /* computedBatchTypes:computedBatchTypesV2,//计算类型筛选项 */
  557. computedType:computedBatchTypesV2[0].type,//当前选中的计算类型
  558. subComputedType:'',//二级计算类型
  559. formData:{
  560. nNum:1,
  561. calendarType:'公历',
  562. frequency:'',
  563. valueType:'期末值',
  564. newValue:0,
  565. alphaValue:'',
  566. formula:'',
  567. timeSeriesVal:'A',
  568. nullValueWay:0,
  569. maxNullWay:1,
  570. },
  571. select_target:'',
  572. searchOptions:[],//指标列表
  573. search_have_more:false,
  574. search_page: 1,
  575. current_search: '',
  576. filter:{
  577. classify:'',
  578. frequency:'',
  579. user:'',
  580. keyword:''
  581. },
  582. classifyOpt: [],
  583. classifyProps: {
  584. label: 'ClassifyName',
  585. value: 'ClassifyId',
  586. children: 'Children',
  587. multiple: true,
  588. emitPath:false
  589. },
  590. sysUserOpts:[],
  591. sysUserProps:{
  592. value: "AdminId",
  593. label: "RealName",
  594. children: "ChildrenList",
  595. multiple: true,
  596. emitPath:false
  597. },
  598. nullWayOptions: [
  599. { label: /* '查找前后35天最近值' */ this.$t('EtaBasePage.null_val_deal_0'),value: 0 },
  600. { label: /* '不计算' */ this.$t('EtaBasePage.not_alculate_options'),value: 1 },
  601. { label: /* '前值填充' */this.$t('EtaBasePage.forward_fill_options'),value: 2 },
  602. { label: /* '后值填充' */this.$t('EtaBasePage.backward_fill_options') ,value: 3 },
  603. { label: /* '等于0' */this.$t('EtaBasePage.equal_zeto') ,value: 4 },
  604. ],
  605. isCheckAll:false,//是否全选
  606. isCheckIndeterminate:false,// 标志列表当前是全选状态还是不是全选状态和 isCheckAll不一样
  607. checkAllStatus:false,
  608. selectionReactCancel:false,// 是否不触发 selection的逻辑
  609. listLoading:false,
  610. page:1,
  611. pageSize:20,
  612. total:0,
  613. list:[],
  614. tableDataCheckedList:[],
  615. tableDataIds:[],
  616. selectList:[],//添加到右侧的数据
  617. addLoading:false,
  618. isEdit:false,//是否为多指标求和等编辑
  619. }
  620. },
  621. mounted() {
  622. this.getClassifyOpt()
  623. this.getEDBList()
  624. this.getSysUserList()
  625. },
  626. methods: {
  627. // 编辑时初始化数据
  628. initData(){
  629. this.isEdit=true
  630. const arr=this.operationForm.CalculateList||[]
  631. this.selectList=arr.map(item=>{
  632. return {
  633. ClassifyId:item.ClassifyId,
  634. EdbInfoId:item.FromEdbInfoId,
  635. EdbName:item.FromEdbName,
  636. Frequency:item.Frequency,
  637. Unit:item.Unit
  638. }
  639. })
  640. this.computedType='multipleEDB'
  641. this.subComputedType=this.type
  642. this.formData.timeSeriesVal=this.operationForm.EdbInfoDetail.Extra?JSON.parse(this.operationForm.EdbInfoDetail.Extra).DateTag:'A'
  643. this.formData.nullValueWay=this.operationForm.EdbInfoDetail.EmptyType||0
  644. },
  645. //批量计算成功回调
  646. handleAddSuccess(type,params){
  647. this.$emit('addCallBack',type,params)
  648. },
  649. // 跳转下一步
  650. handleNextStep(){
  651. if(this.selectList.length===0){
  652. this.$message.warning(/* "请选择指标" */this.$t('Edb.InputHolderAll.input_select_edb'))
  653. return
  654. }
  655. if([8,12,13,35].includes(this.computedType) && !this.formData.nNum){
  656. this.$message.warning(/* "请输入N数值" */ this.$t('Edb.InputHolderAll.input_n_value'))
  657. return
  658. }
  659. if([51].includes(this.computedType)&& !this.formData.frequency){
  660. this.$message.warning(/*'请选择频度'*/this.$t('Edb.InputHolderAll.input_fre'))
  661. return
  662. }
  663. if(['accumulate'].includes(this.computedType)&&this.subComputedType==62&& !this.formData.frequency){
  664. this.$message.warning(/*'请选择频度'*/this.$t('Edb.InputHolderAll.input_fre'))
  665. return
  666. }
  667. if(this.computedType==72&&!this.formData.alphaValue){
  668. this.$message.warning(/*'请输入alpha值'*/this.$t('Edb.InputHolderAll.input_alpha_val'))
  669. return
  670. }
  671. if(this.computedType==72&&(Number(this.formData.alphaValue)<=0||Number(this.formData.alphaValue)>=1)){
  672. this.$message.warning(/*''请输入>0,<1的数值的alpha值''*/ this.$t('EtaBasePage.numeric_greater_msg'))
  673. return
  674. }
  675. if(this.computedType=='withEDB'&&!this.select_target){
  676. this.$message.warning(/*'请选择指标B'*/this.$t('EtaBasePage.select_indicator_msg'))
  677. return
  678. }
  679. if(['withNum','withEDB'].includes(this.computedType)&&!this.formData.formula){
  680. this.$message.warning(/*'请输入公式'8*/this.$t('EtaBasePage.input_formula_msg'))
  681. return
  682. }
  683. this.isCheckAll=false
  684. this.isCheckIndeterminate=false
  685. this.checkAllStatus=false
  686. this.tableDataCheckedList=[]
  687. this.tableDataIds=[]
  688. this.showSave=true
  689. },
  690. // 点击加入已选指标库
  691. async getAddEdbListData(){
  692. if(!(this.isCheckAll || this.isCheckIndeterminate ) || (!(this.list && this.list.length>0))){
  693. this.$message.warning(/* "请选择指标" */this.$t('Edb.InputHolderAll.input_select_edb'))
  694. return
  695. }
  696. if(this.selectList.length>=this.MAXAddNUM){
  697. this.$message.warning(/* "已达批量添加指标数量上限" */this.$t('EtaBasePage.limit_indicators_msg'))
  698. return
  699. }
  700. const params={
  701. SysUserIds:this.filter.user?this.filter.user.join(','):'',
  702. ClassifyIds:this.filter.classify?this.filter.classify.join(','):'',
  703. Keyword:this.filter.keyword,
  704. Frequency:this.filter.frequency?this.filter.frequency.join(','):'',
  705. SelectAll:this.checkAllStatus,
  706. EdbInfoIds:this.tableDataCheckedList.join(',')
  707. }
  708. this.addLoading=true
  709. const res=await dataBaseInterface.getBatchFilterAddEdbList(params)
  710. this.addLoading=false
  711. if(res.Ret!=200) return
  712. // 加入到已选指标中 要去重
  713. const arr=res.Data.SearchItem||[]
  714. const temArr=this.mergeAndDistinct(this.selectList,arr)
  715. // 截取数组 防止数量溢出
  716. this.selectList=temArr.filter(_ =>_.HaveOperaAuth).slice(0,this.MAXAddNUM)
  717. },
  718. mergeAndDistinct(arr1, arr2) {
  719. // 合并两个数组
  720. const mergedArray = arr1.concat(arr2);
  721. // 根据 EdbInfoId 字段进行去重
  722. const distinctArray = mergedArray.filter((item, index, self) => {
  723. return index === self.findIndex(t => t.EdbInfoId === item.EdbInfoId);
  724. });
  725. return distinctArray;
  726. },
  727. // 删除已选指标库指标
  728. handleDelSelect(e){
  729. if(this.operationForm.view) return
  730. if(e==='all'){
  731. this.selectList=[]
  732. return
  733. }
  734. const index=e.$index
  735. this.selectList.splice(index,1)
  736. },
  737. // 切换计算类型
  738. handleComputedTypeChange(){
  739. this.subComputedType=''
  740. this.select_target=''
  741. this.formData={
  742. nNum:1,
  743. calendarType:'公历',
  744. frequency:'',
  745. valueType:'期末值',
  746. newValue:0,
  747. alphaValue:'',
  748. formula:'',
  749. timeSeriesVal:'A',
  750. nullValueWay:0,
  751. maxNullWay:1,
  752. }
  753. this.filter={
  754. classify:'',
  755. frequency:'',
  756. user:'',
  757. keyword:''
  758. }
  759. this.selectList=[]
  760. if(this.computedType=='toMonthSeason'){
  761. this.subComputedType=5
  762. this.filter.frequency=['月度']
  763. }else if(this.computedType=='accumulate'){
  764. this.subComputedType=62
  765. }else if(this.computedType=='multipleEDB'){
  766. this.subComputedType=81
  767. }
  768. this.handleFilter()
  769. },
  770. handleComputedSubTypeChange(){
  771. if(this.subComputedType==61){
  772. this.filter.frequency=['季度']
  773. }
  774. if(this.subComputedType==5){
  775. this.filter.frequency=['月度']
  776. }
  777. this.selectList=[]
  778. this.handleFilter()
  779. },
  780. /* 指标列表 */
  781. getTarget(query) {
  782. this.search_page = 1;
  783. this.current_search = query;
  784. this.searchApi(this.current_search);
  785. },
  786. /* 聚焦获取当前检索 */
  787. inputFocusHandle(e) {
  788. this.search_page = 1;
  789. this.current_search = e.target.value;
  790. this.searchApi(this.current_search);
  791. },
  792. searchApi(query,page=1) {
  793. dataBaseInterface.targetSearchByPage({
  794. KeyWord:query,
  795. CurrentIndex: page,
  796. FilterSource: 1,
  797. Frequency: ''
  798. }).then(res => {
  799. if(res.Ret !== 200) return
  800. const { List,Paging } = res.Data;
  801. this.search_have_more = page < Paging.Pages;
  802. let arr = page === 1 ? List : this.searchOptions.concat(List);
  803. this.searchOptions = arr;
  804. })
  805. },
  806. searchLoad() {
  807. if(!this.search_have_more) return;
  808. this.searchApi(this.current_search,++this.search_page)
  809. },
  810. handleClose(){
  811. this.showSave=false
  812. this.$emit('close')
  813. },
  814. handleCloseSelf(){//仅仅关闭批量计算弹窗
  815. this.$emit('closeSelf')
  816. },
  817. filterNodes(arr) {
  818. arr.length &&
  819. arr.forEach((item) => {
  820. item.Children.length && this.filterNodes(item.Children);
  821. if (!item.Children.length) {
  822. delete item.Children;
  823. }
  824. });
  825. },
  826. // 获取指标分类
  827. async getClassifyOpt(){
  828. const res=await dataBaseInterface.menuListV3()
  829. if (res.Ret !== 200) return
  830. this.filterNodes(res.Data.AllNodes||[]);
  831. this.classifyOpt = res.Data.AllNodes || [];
  832. },
  833. // 获取所有系统用户
  834. async getSysUserList() {
  835. const res = await departInterence.getQuestionAdminList();
  836. if (res.Ret === 200) {
  837. this.sysUserOpts = res.Data.List||[];
  838. }
  839. },
  840. // 获取指标列表
  841. async getEDBList(type){
  842. this.listLoading=true
  843. const res=await dataBaseInterface.getBatchAddEdbSearchList({
  844. CurrentIndex:this.page,
  845. PageSize: this.pageSize,
  846. SysUserIds:this.filter.user?this.filter.user.join(','):'',
  847. ClassifyIds:this.filter.classify?this.filter.classify.join(','):'',
  848. Keyword:this.filter.keyword,
  849. Frequency:this.filter.frequency?this.filter.frequency.join(','):'',
  850. NotFrequency:this.computedType==75?'日度':''
  851. })
  852. this.listLoading=false
  853. if(res.Ret===200){
  854. this.list=res.Data.SearchItem||[]
  855. this.total=res.Data.Paging.Totals||0
  856. if(this.list.length>0){
  857. this.tableDataIds = this.list.map(it => it.EdbInfoId)
  858. }else{
  859. this.tableDataIds = []
  860. }
  861. if(type == 'adjustSelection'){
  862. this.adjustSelection()
  863. }else{
  864. this.isCheckAll=false
  865. this.checkAllStatus=false
  866. this.isCheckIndeterminate=false
  867. this.listCheckAllChange(this.isCheckAll)
  868. }
  869. }
  870. },
  871. pageNumberChange(e){
  872. this.page=e
  873. this.getEDBList('adjustSelection')
  874. },
  875. handleFilter(e){
  876. this.page=1
  877. this.list=[]
  878. this.getEDBList()
  879. },
  880. // 切换列表全选按钮状态
  881. listCheckAllChange(check){
  882. this.tableDataCheckedList=[]
  883. this.checkAllStatus=check
  884. if(check){
  885. // 全选
  886. this.$refs.edbDataRef && this.$refs.edbDataRef.clearSelection()
  887. this.$refs.edbDataRef && this.$refs.edbDataRef.toggleAllSelection()
  888. }else{
  889. //全不选
  890. this.$refs.edbDataRef && this.$refs.edbDataRef.clearSelection()
  891. }
  892. },
  893. selectionChange(val){
  894. if(this.selectionReactCancel) return
  895. // selectAllHandle的触发在selectionChange后面,将selectionChange的逻辑延迟一下
  896. setTimeout(()=>{
  897. // 去重
  898. let duplicateArr = Array.from(new Set(this.tableDataCheckedList))
  899. if((duplicateArr.length == this.total && (!this.checkAllStatus))
  900. || (duplicateArr.length == 0 && this.checkAllStatus)){
  901. this.isCheckAll = true
  902. this.isCheckIndeterminate=false
  903. }else if((duplicateArr.length == 0 && (!this.checkAllStatus))
  904. || (duplicateArr.length == this.total && this.checkAllStatus)){
  905. this.isCheckAll = false
  906. this.isCheckIndeterminate=false
  907. }else{
  908. this.isCheckAll = false
  909. this.isCheckIndeterminate=true
  910. }
  911. },1)
  912. },
  913. //用户手动勾选数据行的 Checkbox 时触发的事件
  914. selectHandle(selection, row){
  915. if(this.selectionReactCancel) return
  916. let check=false
  917. if(selection.some(it => it.EdbInfoId == row.EdbInfoId)){
  918. // 勾选
  919. // 勾选
  920. if(this.checkAllStatus){
  921. check=false
  922. }else{
  923. check=true
  924. }
  925. }else{
  926. // 取消勾选
  927. if(this.checkAllStatus){
  928. check=true
  929. }else{
  930. check=false
  931. }
  932. }
  933. if(check){
  934. this.tableDataCheckedList.push(row.EdbInfoId)
  935. }else{
  936. this.tableDataCheckedList=this.tableDataCheckedList.filter(it => it!=row.EdbInfoId)
  937. }
  938. },
  939. // 用户手动勾选全选 Checkbox 时触发的事件
  940. selectAllHandle(selection){
  941. if(this.selectionReactCancel) return
  942. let check = false; // 从tableDataCheckedList 添加还是删除
  943. if(selection && selection.length>0){
  944. // 全选
  945. if(this.checkAllStatus){
  946. check=false
  947. }else{
  948. check=true
  949. }
  950. }else{
  951. // 全不选
  952. if(this.checkAllStatus){
  953. check=true
  954. }else{
  955. check=false
  956. }
  957. }
  958. if(check){
  959. this.tableDataCheckedList = [...this.tableDataCheckedList,...this.tableDataIds]
  960. }else{
  961. this.tableDataCheckedList = this.tableDataCheckedList.filter(it => !this.tableDataIds.includes(it))
  962. }
  963. },
  964. adjustSelection(){
  965. this.selectionReactCancel=true
  966. if(!this.checkAllStatus){
  967. this.tableDataCheckedList.map(it =>{
  968. let row = this.list.find(da => da.EdbInfoId==it)
  969. if(row){
  970. setTimeout(()=>{
  971. this.$refs.edbDataRef.toggleRowSelection(row,true)
  972. },10)
  973. }
  974. })
  975. }else{
  976. this.$refs.edbDataRef.toggleAllSelection()
  977. this.tableDataCheckedList.map(it =>{
  978. let row = this.list.find(da => da.EdbInfoId==it)
  979. if(row){
  980. setTimeout(()=>{
  981. this.$refs.edbDataRef.toggleRowSelection(row,false)
  982. },50)
  983. }
  984. })
  985. }
  986. setTimeout(()=>{
  987. this.selectionReactCancel=false
  988. },50)
  989. },
  990. filterEdbAuth(row) {
  991. return row.HaveOperaAuth
  992. }
  993. },
  994. }
  995. </script>
  996. <style lang="scss">
  997. .batch-computed-dialog{
  998. max-width: 1200px;
  999. width:90vw;
  1000. overflow: hidden;
  1001. }
  1002. .batch-computed-wrap{
  1003. .type-wrap{
  1004. display: flex;
  1005. }
  1006. .table-wrap{
  1007. margin-top: 20px;
  1008. display: flex;
  1009. justify-content: space-between;
  1010. .left-box{
  1011. width: 50%;
  1012. }
  1013. .right-box{
  1014. flex: 1;
  1015. flex-shrink: 0;
  1016. }
  1017. }
  1018. }
  1019. </style>