computedDialog.vue 20 KB

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