computedDialog.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. <template>
  2. <el-dialog
  3. :visible.sync="isOpenComputed"
  4. :close-on-click-modal="false"
  5. :modal-append-to-body="false"
  6. @close="cancelHandle"
  7. custom-class="computed-dialog fit-screen-dialog"
  8. center
  9. top="6vh"
  10. v-dialogDrag
  11. >
  12. <div slot="title" style="display: flex; align-items: center">
  13. <img
  14. :src="$icons.computed"
  15. style="color: #fff; width: 16px; height: 16px; margin-right: 5px"
  16. />
  17. <span style="font-size: 16px">{{ title }}</span>
  18. </div>
  19. <div class="dialog-main">
  20. <ul class="add-cont">
  21. <li class="add-li" v-for="(list, index) in addList" :key="index">
  22. <span class="li-tag">{{ list.tag }}</span>
  23. <el-select
  24. v-model="list.target"
  25. v-loadMore="searchLoad"
  26. :filterable="!list.target"
  27. clearable
  28. placeholder="请输入指标名称"
  29. style="width: 400px"
  30. @change="chooseTarget"
  31. @clear="clearHandle(index)"
  32. :disabled="calulateForm.view"
  33. remote
  34. :remote-method="searchTarget"
  35. @click.native="inputFocusHandle"
  36. >
  37. <i slot="prefix" class="el-input__icon el-icon-search"></i>
  38. <el-option
  39. v-for="item in searchOptions"
  40. :key="item.EdbInfoId"
  41. :label="$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
  42. :value="item.EdbInfoId"
  43. >
  44. <edbDetailPopover :info="item">
  45. <div slot="reference">{{$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName}}</div>
  46. </edbDetailPopover>
  47. </el-option>
  48. </el-select>
  49. <i class="el-icon-tickets" style="color:#409EFF;font-size:18px" @click="$emit('lookHistory',list.target)" v-if="list.target"/>
  50. <i
  51. class="el-icon-error del-tag"
  52. v-if="index > 3 && !calulateForm.view"
  53. @click="delTarget(index)"
  54. />
  55. <span :class="{
  56. 'target-date': true,
  57. 'newest': list.end_date===newestDate
  58. }" v-if="list.start_date">{{
  59. `${list.start_date}至${list.end_date}`
  60. }}</span>
  61. </li>
  62. </ul>
  63. <span class="add-icon" @click="addTargetHandle" v-if="!calulateForm.view">
  64. <i
  65. class="el-icon-circle-plus-outline"
  66. style="color: #5882ef; font-size: 16px"
  67. />
  68. 添加更多参数
  69. </span>
  70. <div class="computed-min">
  71. <div class="computed-section" v-if="edbSource !== 'predict'">
  72. <div>
  73. <label class="label">生成指标时间序列</label>
  74. <div style="width:200px;display: inline-block;">
  75. <el-cascader
  76. v-model="selectTimeSeriesVal"
  77. style="width:100%"
  78. :options="timeSeriesOpt"
  79. :props="{emitPath:false}"
  80. :show-all-levels="false"
  81. placeholder="请选择"
  82. ></el-cascader>
  83. </div>
  84. </div>
  85. </div>
  86. <div class="computed-section">
  87. <div>
  88. <label class="label">空值处理
  89. <el-tooltip placement="top">
  90. <div slot="content" v-html="formTips['null-val']" style="width:300px;line-height:20px;"/>
  91. <i class="el-icon-question"/>
  92. </el-tooltip>
  93. </label>
  94. <el-select
  95. v-model="nullValueForm.nullValueWay"
  96. placeholder="请选择"
  97. :disabled="calulateForm.view"
  98. >
  99. <el-option
  100. v-for="item in nullWayOptions"
  101. :key="item.value"
  102. :label="item.label"
  103. :value="item.value"
  104. >
  105. </el-option>
  106. </el-select>
  107. </div>
  108. <div style="margin-left: 120px" v-if="showMaxNullDeal">
  109. <label class="label">MAX、MIN空值处理
  110. <el-tooltip placement="top">
  111. <div slot="content" v-html="formTips['max-null-val']" style="width:300px;line-height:20px;"/>
  112. <i class="el-icon-question"/>
  113. </el-tooltip>
  114. </label>
  115. <el-select
  116. v-model="nullValueForm.maxNullWay"
  117. placeholder="请选择"
  118. :disabled="calulateForm.view"
  119. >
  120. <el-option label="等于0" :value="1" />
  121. <el-option label="跳过空值" :value="2" />
  122. </el-select>
  123. </div>
  124. </div>
  125. <div class="computed-section">
  126. <label class="label">计算公式
  127. <el-tooltip placement="top">
  128. <div slot="content" v-html="formTips['formula']" style="width:300px;line-height:20px;"/>
  129. <i class="el-icon-question"/>
  130. </el-tooltip>
  131. </label>
  132. <!-- <el-input placeholder="请输入公式" v-model="formula" clearable :disabled="calulateForm.view">
  133. </el-input> -->
  134. <ul class="formula-list">
  135. <li style="margin-bottom: 15px;">
  136. <el-input placeholder="请输入公式" v-model="formulaList[0].formula" clearable :disabled="calulateForm.view" style="width: 600px"/>
  137. <span v-if="formulaDateArr.length" class="date-section-text">{{formulaDateArr[formulaDateArr.length-1]}}(含)之后</span>
  138. <span class="example-txt">公式示例:A*0.5+B*C*1.2+120-MAX(A,B,C) &nbsp;函数支持:MAX(),MIN(),ln(A),log(a,A),abs(),exp(),pow(),round()</span>
  139. </li>
  140. <li class="formula-item" v-for="(item,index) in formulaList.slice(1)" :key="index+1">
  141. <el-input
  142. placeholder="请输入公式"
  143. v-model="item.formula"
  144. clearable
  145. :disabled="calulateForm.view"
  146. style="width: 220px"
  147. />
  148. <el-date-picker
  149. v-model="item.date"
  150. type="date"
  151. value-format="yyyy-MM-dd"
  152. style="margin: 0 10px;width: 220px"
  153. placeholder="选择日期"
  154. :disabled="calulateForm.view"
  155. @change="selectFormulaDate($event,item)"
  156. />
  157. <i class="el-icon-circle-close" style="font-size:20px;" v-if="!calulateForm.view" @click="removeFormulaItem(index+1)"/>
  158. <template v-if="formulaDateArr.length&&item.date">
  159. <span v-if="item.date===formulaDateArr[0]" class="date-section-text">{{formulaDateArr[0]}}之前</span>
  160. <span v-else class="date-section-text">{{formulaDateArr[formulaDateArr.findIndex(_ =>_ ===item.date)-1]}}(含)——{{item.date}}</span>
  161. </template>
  162. </li>
  163. </ul>
  164. </div>
  165. <el-button
  166. v-if="!calulateForm.view"
  167. icon="el-icon-plus"
  168. style="margin-left:70px;"
  169. @click="addFormulaHandle"
  170. >新增分段</el-button>
  171. </div>
  172. <el-form
  173. ref="diaForm"
  174. label-position="right"
  175. inline
  176. label-width="80px"
  177. :model="formData"
  178. :rules="formRules"
  179. :disabled="calulateForm.view"
  180. >
  181. <el-form-item label="指标名称" prop="targetName">
  182. <el-input
  183. v-model="formData.targetName"
  184. style="width: 340px"
  185. placeholder="请输入指标名称"
  186. />
  187. </el-form-item>
  188. <el-form-item label="单位" prop="unit">
  189. <selectUnit v-model="formData.unit" style="width: 340px" />
  190. </el-form-item>
  191. <el-form-item label="指标目录" prop="menu">
  192. <el-cascader
  193. v-model="formData.menu"
  194. :options="options"
  195. :props="levelProps"
  196. clearable
  197. placeholder="请选择指标目录"
  198. />
  199. </el-form-item>
  200. <el-form-item label="频度" prop="frequency">
  201. <el-select
  202. v-model="formData.frequency"
  203. placeholder="请选择频率"
  204. style="width: 340px"
  205. clearable
  206. >
  207. <el-option
  208. v-for="item in frequencyArr"
  209. :key="item"
  210. :label="item"
  211. :value="item"
  212. >
  213. </el-option>
  214. </el-select>
  215. </el-form-item>
  216. </el-form>
  217. </div>
  218. <div class="dia-bot" v-if="!calulateForm.view">
  219. <el-button
  220. type="primary"
  221. style="margin-right: 20px"
  222. @click="saveHandle"
  223. :loading="dataloading"
  224. v-if="title==='计算指标'"
  225. >生成计算指标</el-button
  226. >
  227. <el-button
  228. type="primary"
  229. style="margin-right: 20px"
  230. @click="saveHandle"
  231. v-else
  232. >保存</el-button
  233. >
  234. <el-button type="primary" plain @click="cancelHandle('cancel')">取消</el-button>
  235. </div>
  236. <el-popover
  237. placement="top-start"
  238. width="360"
  239. trigger="click">
  240. <p style="padding:30px;line-height:25px;" v-html="$parent.tips.get(type)"/>
  241. <span slot="reference" class="tip-label">公式说明</span>
  242. </el-popover>
  243. </el-dialog>
  244. </template>
  245. <script>
  246. import { dataBaseInterface } from '@/api/api.js';
  247. import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
  248. import { formRules } from '../databaseComponents/util';
  249. import { unitArr } from '@/utils/defaultOptions';
  250. import {generateSeriesArray} from './util'
  251. const MAXEDBNUM=50//最大可添加的指标数量
  252. const tag_arr = generateSeriesArray();
  253. // for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
  254. export default {
  255. name: '',
  256. props: {
  257. isOpenComputed: {
  258. type: Boolean,
  259. },
  260. title: {
  261. type: String,
  262. default: '计算指标',
  263. },
  264. calulateForm: {
  265. type: Object,
  266. },
  267. calulateList: {
  268. type: Array,
  269. },
  270. edbSource: { // ''||'predict'
  271. type: String,
  272. default: ''
  273. }
  274. },
  275. computed: {
  276. type() {
  277. return this.edbSource ? 31 : 4;
  278. },
  279. /* max空值处理显示 当输入的公式包含MAX、MIN且空值处理为0时,输入公式失焦后出现右侧选项; */
  280. showMaxNullDeal() {
  281. let haveMaxOrMin = this.formulaList.some(_ => _.formula.toUpperCase().includes('MAX') || _.formula.toUpperCase().includes('MIN'))
  282. return haveMaxOrMin && this.nullValueForm.nullValueWay===4
  283. },
  284. formulaDateArr() {
  285. return this.formulaList.map(_ => _.date).filter(_ => _).sort((a,b) => new Date(a)-new Date(b))
  286. },
  287. timeSeriesOpt(){
  288. const arr=[
  289. {
  290. label:'指定指标时间序列',
  291. value:'0',
  292. children:[]
  293. },
  294. {
  295. label:'所有指标时间序列并集',
  296. value:'all',
  297. }
  298. ]
  299. arr[0].children=this.addList.filter(item=>item.target).map(item=>{
  300. return {
  301. label:`指标${item.tag}`,
  302. value:item.tag
  303. }
  304. })
  305. return arr
  306. }
  307. },
  308. watch: {
  309. isOpenComputed(newval) {
  310. newval && this.getMenu();
  311. // newval && this.searchTarget('');
  312. /* 回显 */
  313. if (this.calulateList.length && newval) {
  314. this.addList = _.cloneDeep(this.calulateList);
  315. this.formulaList = JSON.parse(this.calulateForm.formula).map(_ => ({
  316. formula: _.f,
  317. date: _.d||''
  318. }));
  319. this.formData = {
  320. targetName: this.calulateForm.targetName,
  321. unit: this.calulateForm.unit,
  322. menu: this.calulateForm.menu,
  323. frequency: this.calulateForm.frequency,
  324. };
  325. this.nullValueForm = {
  326. nullValueWay: this.calulateForm.emptyType,
  327. maxNullWay: this.calulateForm.maxEmptyType,
  328. }
  329. this.searchOptions = this.calulateList.map(item => ({
  330. EdbInfoId: item.target,
  331. EdbName: item.edb_name,
  332. }))
  333. if(this.calulateForm.Extra){
  334. const ExtraObj=JSON.parse(this.calulateForm.Extra)
  335. this.selectTimeSeriesVal=ExtraObj.DateTag
  336. }
  337. this.getNewestDate();
  338. }
  339. },
  340. 'addList':{
  341. handler(n){
  342. if(this.selectTimeSeriesVal=='all') return
  343. const arr=this.addList.filter(item=>item.target).map(item=>{
  344. return {
  345. label:`指标${item.tag}`,
  346. value:item.tag
  347. }
  348. })
  349. if(!arr.length) return
  350. if(!this.selectTimeSeriesVal){
  351. this.selectTimeSeriesVal=arr[0].value
  352. }else{//已经有选择的值了
  353. let flag=false
  354. arr.forEach(item=>{
  355. if(item.value==this.selectTimeSeriesVal){
  356. flag=true
  357. }
  358. })
  359. if(!flag){
  360. this.selectTimeSeriesVal=arr[0].value
  361. }
  362. }
  363. },
  364. deep:true
  365. }
  366. },
  367. data() {
  368. return {
  369. options: [],
  370. levelProps: {
  371. label: 'ClassifyName',
  372. value: 'ClassifyId',
  373. children: 'Children',
  374. checkStrictly: true
  375. },
  376. frequencyArr: ['日度', '周度','旬度','月度', '季度', '年度'],
  377. formRules,
  378. unitArr,
  379. addList: [
  380. {
  381. tag: tag_arr[0],
  382. target: '',
  383. start_date: '',
  384. end_date: '',
  385. },
  386. {
  387. tag: tag_arr[1],
  388. target: '',
  389. start_date: '',
  390. end_date: '',
  391. },
  392. {
  393. tag: tag_arr[2],
  394. target: '',
  395. start_date: '',
  396. end_date: '',
  397. },
  398. {
  399. tag: tag_arr[3],
  400. target: '',
  401. start_date: '',
  402. end_date: '',
  403. },
  404. ],
  405. searchOptions: [],
  406. formula: '', //计算公式
  407. formulaList: [ //公式数组
  408. { formula: '', }
  409. ],
  410. dataloading: false,
  411. formData: {
  412. targetName: '',
  413. unit: '',
  414. menu: '',
  415. frequency: '',
  416. },
  417. search_have_more: false,
  418. search_page: 1,
  419. current_search:'',
  420. newestDate: '',
  421. nullValueForm: {
  422. nullValueWay: 0,
  423. maxNullWay: 1
  424. },//空值处理
  425. nullWayOptions: [
  426. { label: '查找前后35天最近值',value: 0 },
  427. { label: '不计算',value: 1 },
  428. { label: '前值填充',value: 2 },
  429. { label: '后值填充',value: 3 },
  430. { label: '等于0',value: 4 },
  431. ],
  432. selectTimeSeriesVal:'',
  433. formTips: {
  434. 'null-val': `1、查找前后35天最近值:在参与计算的日期序列上某指标无值时,该指标往前/往后找距离最近的值作为当天的值进行计算,遍历允许跨年,往前最多35天,往后最多35天<br>
  435. 2、不计算:只要有一个指标在某个日期没有值(即空值),则计算指标在该日期没有值 <br>
  436. 3、前值填充:空值优先以最近的前值填充,没有前值时,用后值填充 <br>
  437. 4、后值填充:空值优先以最近的后值填充,没有前值时,用后值填充 <br>
  438. 5、等于0:空值以0值参与计算 <br>
  439. 注意:此处缺失值的处理,作用于数据全部时间段`,
  440. 'max-null-val': `MAX、MIN公式中指标存在空值时按如下规则处理:<br>
  441. 1、等于0,空值用0参与计算;<br>
  442. 2、跳过空值,去除空值指标,剩余指标进行计算,若该日期所有指标均为空值,则该日期无值;`,
  443. 'formula':`1、支持新增分段,实现不同分段使用不同的计算公式,若未新增分段,则所有日期序列用统一公式计算<br>
  444. 2、新增分段需配置新公式和时间节点,在时间节点之前(不含)使用新公式,在时间节点之后(含)使用已配置公式,每个分段公式支持修改<br>
  445. 3、分段时间节点不允许重复,不允许超出第一个指标的日期区间`
  446. }
  447. };
  448. },
  449. methods: {
  450. /* 获取目录结构 */
  451. async getMenu() {
  452. const res = this.edbSource === 'predict'
  453. ? await preDictEdbInterface.classifyListV2()
  454. : await dataBaseInterface.menuListV3()
  455. if (res.Ret !== 200) return
  456. this.filterNodes(res.Data.AllNodes||[]);
  457. this.options = res.Data.AllNodes || [];
  458. },
  459. // 递归改变第三级目录结构
  460. filterNodes(arr) {
  461. arr.length &&
  462. arr.forEach((item) => {
  463. item.Children.length && this.filterNodes(item.Children);
  464. if (!item.Children.length) {
  465. delete item.Children;
  466. }
  467. });
  468. },
  469. /* 添加额外的指标列 */
  470. addTargetHandle() {
  471. const MAXNUM=this.edbSource === 'predict'?26:MAXEDBNUM
  472. if(this.addList.length >=MAXNUM) return this.$message.warning('添加指标个数已达上限')
  473. let tag = this.addList[this.addList.length-1].tag;
  474. let index = tag_arr.findIndex(item => item === tag);
  475. const item = {
  476. tag: tag_arr[index+1],
  477. target: '',
  478. start_date: '',
  479. end_date: ''
  480. };
  481. this.addList.push(item);
  482. },
  483. /* 搜索指标 */
  484. searchTarget(query) {
  485. this.search_page = 1;
  486. this.current_search = query;
  487. this.searchApi(this.current_search);
  488. },
  489. /* 聚焦获取当前检索 */
  490. inputFocusHandle(e) {
  491. this.search_page = 1;
  492. this.current_search = e.target.value;
  493. this.searchApi(this.current_search);
  494. },
  495. async searchApi(query,page=1) {
  496. const res = this.edbSource === 'predict'
  497. ? await preDictEdbInterface.edbSearch({
  498. Keyword: query,
  499. CurrentIndex: page,
  500. FilterSource: this.type === 45 ? 3 : this.type === 66 ? 6 : 1,
  501. Frequency: this.type===64?'季度': ''
  502. })
  503. : await dataBaseInterface.targetSearchByPage({
  504. KeyWord:query,
  505. CurrentIndex: page,
  506. FilterSource: this.type === 14 ? 3 : this.type === 63 ? 6 : 1,
  507. Frequency: this.type===61?'季度': ''
  508. })
  509. if(res.Ret !== 200) return
  510. const { List,Paging } = res.Data;
  511. this.search_have_more = page < Paging.Pages;
  512. this.searchOptions = page === 1 ? List : this.searchOptions.concat(List);
  513. },
  514. searchLoad() {
  515. if(!this.search_have_more) return;
  516. this.searchApi(this.current_search,++this.search_page)
  517. },
  518. /* 选中指标 显示开始日期结束日期 */
  519. chooseTarget(val) {
  520. if (val) {
  521. const choose_obj = this.searchOptions.find(
  522. (item) => item.EdbInfoId === val
  523. );
  524. this.addList.forEach((list) => {
  525. if (list.target === val) {
  526. list.start_date = choose_obj.StartDate;
  527. list.end_date = choose_obj.EndDate;
  528. this.getNewestDate();
  529. }
  530. });
  531. }
  532. },
  533. /* 获取所选日期最早日期 */
  534. getNewestDate() {
  535. let dateArr = this.addList.filter(_ => _.end_date).map(_ => new Date(_.end_date).getTime())
  536. let earliestDate = Math.min(...dateArr);
  537. let sameDateArr = dateArr.filter(_ => _===earliestDate)
  538. if(dateArr.length === 1 || sameDateArr.length===dateArr.length) {
  539. this.newestDate = '';
  540. return
  541. }
  542. this.newestDate = this.$moment(Math.min(...dateArr)).format('YYYY-MM-DD');
  543. },
  544. /* 清空指标和关联日期 */
  545. clearHandle(index) {
  546. this.addList[index].start_date = '';
  547. this.addList[index].end_date = '';
  548. this.getNewestDate();
  549. },
  550. // 删除指标
  551. delTarget(index) {
  552. this.addList.splice(index, 1);
  553. this.getNewestDate();
  554. },
  555. async saveHandle() {
  556. if (!this.formulaList[0].formula) return this.$message.warning('计算公式不能为空');
  557. await this.$refs.diaForm.validate();
  558. // 指标id数组
  559. let EdbInfoIdArr = this.addList.filter((item) => item.target).map((item) => ({
  560. EdbInfoId: item.target,
  561. FromTag: item.tag,
  562. }));
  563. let formulaArr = this.formulaList
  564. .filter((_,index) => index===0||(index>0&&_.formula&&_.date))
  565. .map(_ => ({f: _.formula,d: _.date}))
  566. const { nullValueWay,maxNullWay } = this.nullValueForm;
  567. let params = {
  568. CalculateFormula: JSON.stringify(formulaArr),
  569. ClassifyId: this.formData.menu[this.formData.menu.length - 1] || 0,
  570. EdbName: this.formData.targetName,
  571. Frequency: this.formData.frequency,
  572. Unit: this.formData.unit,
  573. EdbInfoIdArr,
  574. EmptyType: nullValueWay,
  575. MaxEmptyType: maxNullWay,
  576. Extra:JSON.stringify({
  577. DateTag:this.selectTimeSeriesVal
  578. })
  579. };
  580. this.dataloading = true;
  581. let res;
  582. if(this.edbSource === 'predict') {
  583. res = await preDictEdbInterface.calculateEdbSave(this.calulateForm.edb_id ? {...params,EdbInfoId:this.calulateForm.edb_id } : params)
  584. }else {
  585. res = this.calulateForm.edb_id
  586. ? await dataBaseInterface.calculateEdit({...params,EdbInfoId: this.calulateForm.edb_id})
  587. : await dataBaseInterface.calculateAdd(params)
  588. }
  589. this.dataloading = false;
  590. if (res.Ret !== 200) return
  591. this.$message.success(res.Msg);
  592. this.calulateForm.edb_id
  593. ? this.$emit('addCallBack','edit')
  594. : this.$emit('addCallBack','add',{ code:res.Data.UniqueCode,id:res.Data.EdbInfoId,classifyId:params.ClassifyId });
  595. this.init();
  596. },
  597. /* 新增公式分段 */
  598. addFormulaHandle() {
  599. let addItem = {
  600. formula: this.formulaList[this.formulaList.length-1].formula,
  601. date: ''
  602. }
  603. this.formulaList.push(addItem)
  604. },
  605. /* 移除公式 */
  606. removeFormulaItem(index) {
  607. this.formulaList.splice(index,1)
  608. },
  609. /* 选择日期 检验排 */
  610. selectFormulaDate(val,item) {
  611. console.log(val,item)
  612. const { start_date,end_date } = this.addList[0];
  613. if(!start_date) return
  614. let dateStamp = new Date(val).getTime(),
  615. startStamp = new Date(start_date).getTime(),
  616. endStamp = new Date(end_date).getTime();
  617. if (dateStamp > endStamp || dateStamp < startStamp) {
  618. item.date = '';
  619. return this.$message.warning('分段日期必须在第一个指标日期区间')
  620. }
  621. else if(this.formulaList.filter(_ => _.date===val).length>1) {
  622. item.date = '';
  623. return this.$message.warning('分段日期不可重复')
  624. }
  625. },
  626. init() {
  627. this.$refs.diaForm.resetFields();
  628. this.addList = [
  629. {
  630. tag: tag_arr[0],
  631. target: '',
  632. start_date: '',
  633. end_date: '',
  634. },
  635. {
  636. tag: tag_arr[1],
  637. target: '',
  638. start_date: '',
  639. end_date: '',
  640. },
  641. {
  642. tag: tag_arr[2],
  643. target: '',
  644. start_date: '',
  645. end_date: '',
  646. },
  647. {
  648. tag: tag_arr[3],
  649. target: '',
  650. start_date: '',
  651. end_date: '',
  652. },
  653. ];
  654. this.searchOptions = [];
  655. this.formula = '';
  656. this.formData = {
  657. targetName: '',
  658. unit: '',
  659. menu: '',
  660. frequency: '',
  661. };
  662. this.formulaList = [
  663. { formula: '' }
  664. ]
  665. this.nullValueForm = {
  666. nullValueWay: 0,
  667. maxNullWay: 1
  668. }
  669. },
  670. cancelHandle(type) {
  671. this.init();
  672. this.$emit('cancel');
  673. type==='cancel' && !this.calulateForm.edb_id && this.$emit('openPrev');
  674. },
  675. },
  676. mounted() {},
  677. };
  678. </script>
  679. <style lang="scss">
  680. .computed-dialog {
  681. max-width: 1200px !important;
  682. width:85vw;
  683. overflow: hidden;
  684. div::-webkit-scrollbar {
  685. width: 6px !important;
  686. }
  687. .el-dialog__body {
  688. max-height: 700px;
  689. overflow: auto;
  690. }
  691. .dialog-main {
  692. padding: 25px 42px 25px 25px;
  693. @media screen and (max-height:850px){
  694. box-sizing: border-box;
  695. height: 65vh;
  696. overflow-y: auto;
  697. }
  698. .el-cascader .el-input {
  699. width: 340px;
  700. }
  701. .add-cont {
  702. display: flex;
  703. flex-wrap: wrap;
  704. justify-content: space-between;
  705. .add-li {
  706. position: relative;
  707. margin-bottom: 48px;
  708. .li-tag {
  709. font-size: 16px;
  710. margin-right: 8px;
  711. }
  712. .del-tag {
  713. position: absolute;
  714. right: -30px;
  715. top: 12px;
  716. font-size: 16px;
  717. cursor: pointer;
  718. }
  719. .target-date {
  720. color: #5882ef;
  721. position: absolute;
  722. bottom: -25px;
  723. left: 24px;
  724. &.newest {
  725. color: #f00;
  726. }
  727. }
  728. }
  729. }
  730. .add-icon {
  731. font-size: 16px;
  732. color: #5882ef;
  733. cursor: pointer;
  734. }
  735. .computed-min {
  736. margin: 50px 0;
  737. padding-bottom: 40px;
  738. border-bottom: 1px dashed #aab4cc;
  739. .computed-section {
  740. display: flex;
  741. margin-top: 20px;
  742. .el-cascader .el-input {
  743. width: 100%;
  744. }
  745. }
  746. .label {
  747. padding:10px 10px 10px 0;
  748. }
  749. .example-txt {
  750. display: block;
  751. margin-top: 10px;
  752. }
  753. .formula-item {
  754. display: flex;
  755. align-items: center;
  756. margin-bottom: 15px;
  757. }
  758. .date-section-text {
  759. margin-left: 15px;
  760. }
  761. }
  762. }
  763. .dia-bot {
  764. padding-bottom: 40px;
  765. display: flex;
  766. justify-content: center;
  767. }
  768. .tip-label {
  769. position: absolute;
  770. bottom: 30px;
  771. right: 30px;
  772. color: #409EFF;
  773. cursor: pointer;
  774. }
  775. }
  776. </style>