predictEdb.vue 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876
  1. <template>
  2. <div class="predictEdb-container" >
  3. <span
  4. class="slide-icon slide-right"
  5. @click="isSlideLeft = !isSlideLeft"
  6. v-show="isSlideLeft"
  7. >
  8. <i class="el-icon-d-arrow-right"></i>
  9. </span>
  10. <div class="predict-edb-main" id="box">
  11. <div class="main-left left" id="left" v-show="!isSlideLeft">
  12. <div class="datasheet_top">
  13. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_addEdb"
  14. type="primary" @click="addEdbHandle">添加指标</el-button>
  15. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_calcuEdb"
  16. type="primary" @click="addComputedHandler" style="margin-right:10px;">计算指标</el-button>
  17. <change-lang v-permission="permissionBtn.predictEdbPermission.edbPreData_switchEn"
  18. :lang="currentLang" style="height: 32px;" @changeLang="changeLangHandle"/>
  19. </div>
  20. <div class="search-cont" v-loading="searchLoading">
  21. <el-select
  22. v-model="search_txt"
  23. ref="searchRef"
  24. :filterable="!search_txt"
  25. remote
  26. clearable
  27. placeholder="指标名称"
  28. style="width: 100%"
  29. :remote-method="searchHandle"
  30. @focus="searchHandle('')"
  31. >
  32. <i slot="prefix" class="el-input__icon el-icon-search"></i>
  33. <el-option
  34. v-for="item in searchOptions"
  35. :key="item.EdbInfoId"
  36. :label="currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
  37. :value="item.EdbInfoId"
  38. >
  39. <span>{{ currentLang==='en' ? (item.EdbNameEn||item.EdbName) : item.EdbName }}</span>
  40. </el-option>
  41. </el-select>
  42. </div>
  43. <div style="margin:20px 0;padding:0 20px;display:flex;justify-content:space-between">
  44. <span>目录</span>
  45. <el-checkbox v-model="isOnlyMe" v-permission="permissionBtn.predictEdbPermission.edbPreData_isOnlyMine"
  46. @change="onlyMeHandler">只看我的</el-checkbox>
  47. </div>
  48. <div class="tree-cont">
  49. <div class="target_tree">
  50. <el-tree
  51. ref="treeRef"
  52. :data="treeData"
  53. node-key="UniqueCode"
  54. :props="defaultProp"
  55. :allow-drag="canDragHandle"
  56. :allow-drop="canDropHandle"
  57. :current-node-key="select_node"
  58. :default-expanded-keys="defaultShowNodes"
  59. :draggable="isEdbBtnShow('edbPreData_classifyOpt_move')"
  60. :expand-on-click-node="false"
  61. check-strictly
  62. empty-text="暂无分类"
  63. lazy
  64. :load="getLazyTreeData"
  65. @node-expand="handleNodeExpand"
  66. @node-collapse="handleNodeCollapse"
  67. @current-change="nodeChange"
  68. @node-drop="dropOverHandle"
  69. @node-drag-end="dropMouseLeave"
  70. @node-drag-leave="dropMouseLeave"
  71. @node-drag-enter="dropMouseOver"
  72. @node-drag-over="dropMouseOver"
  73. >
  74. <span class="custom-tree-node" slot-scope="{ node, data }">
  75. <el-input
  76. ref="editVal"
  77. style="width: 90px"
  78. placeholder="请输入值"
  79. class="label-input"
  80. v-model="new_label"
  81. v-if="data.isEdit"
  82. @blur="changeValue(data)"
  83. />
  84. <span
  85. @dblclick.stop="editNodeLabel(data)"
  86. v-else
  87. class="text_oneLine node_label"
  88. :style="`width:${
  89. (select_node === data.UniqueCode && node.Nodewidth) || ''
  90. }`"
  91. :id="`node${data.UniqueCode}`"
  92. >
  93. <span>{{ currentLang==='en' ? (data.ClassifyNameEn||data.ClassifyName) : data.ClassifyName }}</span>
  94. </span>
  95. <span
  96. style="display: flex; align-items: center"
  97. v-if="select_node === data.UniqueCode"
  98. >
  99. <img
  100. src="~@/assets/img/data_m/move_ico.png"
  101. alt=""
  102. style="width: 14px; height: 14px; margin-right: 8px"
  103. v-if="data.Button.MoveButton"
  104. />
  105. <!-- 添加子项 -->
  106. <img
  107. src="~@/assets/img/set_m/add.png"
  108. alt=""
  109. style="width: 14px; height: 14px; margin-right: 8px"
  110. @click.stop="addNode(node, data)"
  111. v-if="data.Button.AddButton&&!data.EdbInfoId&&isEdbBtnShow('edbPreData_classifyOpt_add')&&node.level<6"
  112. />
  113. <!-- 编辑目录 -->
  114. <img
  115. src="~@/assets/img/set_m/edit.png"
  116. alt=""
  117. style="width: 15px; height: 14px; margin-right: 8px"
  118. @click.stop="editNode(node, data)"
  119. v-if="data.Button.OpButton&&!data.EdbInfoId&&isEdbBtnShow('edbPreData_classifyOpt_add')"
  120. />
  121. <!-- 删除目录 -->
  122. <img
  123. slot="reference"
  124. src="~@/assets/img/set_m/del.png"
  125. alt=""
  126. style="width: 14px; height: 14px"
  127. @click.stop="removeNode(node, data)"
  128. v-if="data.Button.DeleteButton&&!data.EdbInfoId&&isEdbBtnShow('edbPreData_classifyOpt_delete')"
  129. />
  130. <!-- 查看预测规则 -->
  131. <i class="el-icon-view" v-if="data.EdbInfoId&&isEdbBtnShow('edbPreData_checkPreRule')" @click.stop="viewNode(node,data)"></i>
  132. <!-- 查看关联图表 -->
  133. <img
  134. v-if="data.Button.ShowChartRelation&&isEdbBtnShow('edbPreData_checkRelatedChart')"
  135. @click.stop="showAssociateChart=true,showAssociateComputeData=false"
  136. src="~@/assets/img/icons/associate_chart.png"
  137. style="width: 14px; height: 14px;margin-left: 8px"
  138. alt=""
  139. />
  140. <!-- 查看关联指标 -->
  141. <img
  142. v-if="data.Button.ShowEdbRelation&&isEdbBtnShow('edbPreData_checkRelatedEdb')"
  143. @click.stop="showAssociateComputeData=true,showAssociateChart=false"
  144. src="~@/assets/img/icons/associate_data.png"
  145. style="width: 14px; height: 14px;margin-left: 8px"
  146. alt=""
  147. />
  148. </span>
  149. </span>
  150. </el-tree>
  151. </div>
  152. <div
  153. class="noDepart"
  154. @click="addLevelOneHandle"
  155. v-if="opLevelOneClassify&&isEdbBtnShow('edbPreData_classifyOpt_add')"
  156. >
  157. <img
  158. src="~@/assets/img/set_m/add_ico.png"
  159. alt=""
  160. style="width: 16px; height: 16px; margin-right: 10px"
  161. />
  162. <span>添加一级目录</span>
  163. </div>
  164. </div>
  165. <span
  166. class="move-btn resize"
  167. v-drag
  168. id="resize"
  169. @mousemove="dynamicNode && resetNodeStyle(dynamicNode)"
  170. ></span>
  171. <span class="slide-icon slide-left" @click="isSlideLeft = !isSlideLeft">
  172. <i class="el-icon-d-arrow-left"></i>
  173. </span>
  174. </div>
  175. <div class="main-right" id="right" :style="isSlideLeft ? 'width:100%' : 'width:80%'"
  176. :class="{'detail-main':select_id&&!showAssociateChart&&!showAssociateComputeData}"
  177. >
  178. <!-- 详情 -->
  179. <div class="edb-detail-wrapper main-min-width" v-if="select_id&&!showAssociateChart&&!showAssociateComputeData">
  180. <div class="detail-header">
  181. <el-tabs v-model="activeTab" @tab-click="changeShowType">
  182. <el-tab-pane label="走势图" name="Chart">
  183. </el-tab-pane>
  184. <el-tab-pane label="数据详情" name="Data">
  185. </el-tab-pane>
  186. </el-tabs>
  187. <div class="edb-tool-icon edb-tool" style="align-items: center;">
  188. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_update"
  189. type="text" @click="updateEdbPartHandle">刷新</el-button>
  190. <el-button type="text" @click="editEdbHandle('')"
  191. v-if="edbButton.OpButton&&isEdbBtnShow('edbPreData_edit')">编辑</el-button>
  192. <el-button type="text" @click="saveEdbHandle"
  193. v-if="detail_show_chart&&isEdbBtnShow('edbPreData_save')">保存</el-button>
  194. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_edbSource"
  195. type="text" @click="isLookHistory=true;lookEdbId=select_id">指标溯源</el-button>
  196. <el-popover v-if="showPopover"
  197. placement="bottom-end"
  198. trigger="hover"
  199. popper-class="edb-tool-popover"
  200. width="300" style="display: inline-block;">
  201. <div class="edb-tool-wrap">
  202. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_enNameSetting"
  203. type="text" @click="clickEdbNameHandle" v-if="currentLang==='ch'||!edb_nameEn">
  204. 设置英文名称
  205. </el-button>
  206. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_recalcu"
  207. type="text" @click="updateEdbHandle">重新计算</el-button>
  208. <el-button class="deletesty" @click="delEdbHandle" type="text"
  209. v-if="edbButton.DeleteButton&&isEdbBtnShow('edbPreData_del')">删除</el-button>
  210. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_copyData"
  211. type="text" @click="copyData">复制数据</el-button>
  212. </div>
  213. <div class="edb-btn" slot="reference">
  214. <el-button type="text">更多操作</el-button>
  215. <i class="el-icon-more" style="font-size: 14px;transform: rotate(90deg);cursor: pointer;color: #3375e1;"/>
  216. </div>
  217. </el-popover>
  218. </div>
  219. <!-- <div class="edb-tool">
  220. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_enNameSetting"
  221. type="text" @click="clickEdbNameHandle" v-if="currentLang==='ch'||!edb_nameEn">
  222. 设置英文名称
  223. </el-button>
  224. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_edbSource"
  225. type="text" @click="isLookHistory=true;lookEdbId=select_id">指标溯源</el-button>
  226. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_update"
  227. type="text" @click="updateEdbPartHandle">刷新</el-button>
  228. <el-button type="text" @click="editEdbHandle('')"
  229. v-if="edbButton.OpButton&&isEdbBtnShow('edbPreData_edit')">编辑</el-button>
  230. <el-button type="text" @click="saveEdbHandle"
  231. v-if="detail_show_chart&&isEdbBtnShow('edbPreData_save')">保存</el-button>
  232. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_recalcu"
  233. type="text" @click="updateEdbHandle">重新计算</el-button>
  234. <el-button class="deletesty" @click="delEdbHandle" type="text"
  235. v-if="edbButton.DeleteButton&&isEdbBtnShow('edbPreData_del')">删除</el-button>
  236. <el-button v-permission="permissionBtn.predictEdbPermission.edbPreData_copyData"
  237. type="text" @click="copyData">复制数据</el-button>
  238. </div> -->
  239. </div>
  240. <!-- -->
  241. <div class="detail-wrap">
  242. <component
  243. :is="detail_show_chart?'edbDetail':'childData'"
  244. :id="select_id"
  245. :lang="currentLang"
  246. :isAllowEditLimit="isEdbBtnShow('edbPreData_editLimit')"
  247. ref="detailComponentRef"
  248. @updateTit="setNameBack"
  249. @setCurrentClassify="setCurrentClassify"
  250. @setOpera="(obj) => { edbButton = obj }"
  251. @openEnNameDia="openEnNameDia"
  252. />
  253. </div>
  254. </div>
  255. <!-- 列表 -->
  256. <div class="sheet-list-cont" v-else-if="!select_id">
  257. <div class="list-top">
  258. <span>共{{ edb_total }}个预测指标</span>
  259. </div>
  260. <div
  261. class="edbChartList-wrapper"
  262. ref="listRef"
  263. @scroll="loadMoreHandle"
  264. >
  265. <div class="chart-list-item-wrap">
  266. <div class="sheet-item" v-for="item in edbChartList" :key="item.EdbInfoId">
  267. <div class="item-top">
  268. <span class="text_oneLine">{{ currentLang === 'en' ? (item.EdbNameEn||item.EdbName) : item.EdbName }}</span>
  269. </div>
  270. <div class="chart-img" @click="detailShowHandle(item)"
  271. :style="item.ChartImage?{background: `no-repeat top/cover url('${item.ChartImage}')`}:{}"></div>
  272. <div class="item-bottom">
  273. <span>创建时间: {{ item.CreateTime.slice(0,10) }}</span>
  274. </div>
  275. </div>
  276. </div>
  277. <!-- <el-col
  278. :span="8"
  279. style="margin-bottom: 20px; padding-right: 20px"
  280. v-for="item in edbChartList"
  281. :key="item.EdbInfoId"
  282. >
  283. <el-card class="sheet-item">
  284. <div slot="header" class="item-top">
  285. <span class="text_oneLine">{{ currentLang === 'en' ? (item.EdbNameEn||item.EdbName) : item.EdbName }}</span>
  286. </div>
  287. <img
  288. :src="item.ChartImage"
  289. alt=""
  290. class="chart-img"
  291. @click="detailShowHandle(item)"
  292. />
  293. <div class="item-bottom">
  294. <span>创建时间: {{ item.CreateTime.slice(0,10) }}</span>
  295. </div>
  296. </el-card>
  297. </el-col> -->
  298. </div>
  299. <div v-if="!edb_total" class="nodata">
  300. <tableNoData text="暂无指标"/>
  301. </div>
  302. </div>
  303. <!-- 指标关联图模块 -->
  304. <div class="edb-detail-wrapper" style="padding: 30px 20px;" v-if="showAssociateChart&&select_id">
  305. <dataAssociateChart :edbInfoId="select_id"></dataAssociateChart>
  306. </div>
  307. <div class="edb-detail-wrapper" style="padding: 30px 20px;" v-if="showAssociateComputeData&&select_id">
  308. <dataAssociateComputeData :edbInfoId="select_id"></dataAssociateComputeData>
  309. </div>
  310. </div>
  311. </div>
  312. <!-- 计算弹窗控制 -->
  313. <el-dialog
  314. :visible.sync="isOpenComputed"
  315. :close-on-click-modal="false"
  316. :modal-append-to-body='false'
  317. @close="isOpenComputed=false;"
  318. custom-class="dialog-computed"
  319. top="6vh"
  320. center
  321. width="85vw"
  322. v-dialogDrag>
  323. <div class="dialog-computed-header">
  324. <el-radio-group v-model="computed_source" size="medium" @change="computed_type = 0">
  325. <el-radio-button :label="1">常规计算</el-radio-button>
  326. <el-radio-button :label="2">批量计算</el-radio-button>
  327. </el-radio-group>
  328. </div>
  329. <ul class="computed-ul">
  330. <li
  331. :class="['cpmputed-li',{'act':item.type === computed_type}]"
  332. v-for="item in computedTypes"
  333. :key="item.type"
  334. @click="changeComputedType(item.type)"
  335. >
  336. {{item.name}}
  337. <el-popover
  338. placement="top-start"
  339. width="450"
  340. trigger="hover"
  341. v-if="tips.get(item.type)"
  342. >
  343. <p style="padding:20px;line-height:25px;" v-html="tips.get(item.type)"/>
  344. <i slot="reference" class="el-icon-warning-outline"/>
  345. </el-popover>
  346. </li>
  347. </ul>
  348. </el-dialog>
  349. <!-- 指标弹窗 -->
  350. <edb-dialog
  351. :isShow.sync="isEdbDia"
  352. :title="edbdia_title"
  353. :edbForm="edbForm"
  354. @successHandle="handleEdbCallBack"
  355. />
  356. <!-- 分类弹窗 -->
  357. <edbClassifyDia
  358. :isOpenDialog.sync="classifyDia"
  359. :title="dialog_title"
  360. :form="classifyForm"
  361. @successCallback="getTreeData"
  362. />
  363. <!-- 输入英文指标弹窗 -->
  364. <set-en-name-dia
  365. :isOpenDialog="setEnName"
  366. @cancel="setEnName=false"
  367. :formData="formItemArray"
  368. @updateEnName="updateEnName"
  369. cType="predictEbd"
  370. />
  371. <!-- 运算指标弹窗 -->
  372. <computedDialog
  373. :isOpenComputed="computed_type === 31"
  374. edbSource="predict"
  375. :title="computedTit"
  376. :calulateForm="calulateForm"
  377. :calulateList="calulateList"
  378. @cancel="computed_type=0"
  379. @addCallBack="addComputedCallBack"
  380. @openPrev="isOpenComputed=true"
  381. @lookHistory="id => {isLookHistory=true;lookEdbId=id;}"
  382. />
  383. <!-- 同比同差计算弹窗 -->
  384. <!-- 转月值 同比 同差 平均值弹窗 -->
  385. <operationDialog
  386. :isOperation="[42,32,33,39,43,44,45,46,49,54,55,64,65,66,69,70].includes(computed_type) && computed_source===1"
  387. :type="computed_type"
  388. :operationForm="operationForm"
  389. @cancel="computed_type=0"
  390. @addCallBack="addComputedCallBack"
  391. @openPrev="isOpenComputed=true"
  392. @lookHistory="id => {isLookHistory=true;lookEdbId=id;}"
  393. @changeSource="changeComputedType"
  394. />
  395. <!-- 规则详情弹窗 -->
  396. <rules-detail
  397. :isOpenDialog.sync="isShowRuleDialog"
  398. :rules="showRules"
  399. :fromEdbInfo="showFromEdbInfo"
  400. />
  401. <!-- 批量计算弹窗 -->
  402. <batchComputedDialog
  403. :isBatchComputed="[32,33,39,43,44,45,42,64,65,66].includes(computed_type) && computed_source===2"
  404. :type="computed_type"
  405. edbSource="predict"
  406. @cancel="computed_type=0"
  407. @addCallBack="addComputedCallBack"
  408. @openPrev="isOpenComputed=true"
  409. @lookHistory="id => {isLookHistory=true;lookEdbId=id;}"
  410. @changeSource="changeComputedType"
  411. />
  412. <!-- 拼接弹窗 -->
  413. <joint-target-dia
  414. :isShow="computed_type === 'joint'"
  415. :params="operationForm"
  416. :isPredict="true"
  417. @cancel="computed_type=0"
  418. @addCallBack="addComputedCallBack"
  419. @openPrev="isOpenComputed=true"
  420. />
  421. <!-- 拟合残差弹窗 -->
  422. <fittingResidueDia
  423. :isShow="computed_type === 50"
  424. :type="50"
  425. :operationForm="operationForm"
  426. :isPredict="true"
  427. @cancel="computed_type=0"
  428. @addCallBack="addComputedCallBack"
  429. @openPrev="isOpenComputed=true"
  430. />
  431. <!-- 扩散指数弹窗 -->
  432. <diffusionIndexDialog
  433. :isShow="computed_type === 56 && computed_source===1"
  434. :type="computed_type"
  435. :isPredict="true"
  436. :operationForm="operationForm"
  437. @cancel="computed_type=0"
  438. @addCallBack="addComputedCallBack"
  439. @openPrev="isOpenComputed=true"
  440. />
  441. <!-- 指标历史记录 -->
  442. <edbHistoryDialog
  443. :isOpenDialog.sync="isLookHistory"
  444. :edbId="lookEdbId"
  445. />
  446. <!-- 指数修匀弹窗 -->
  447. <SmoothEdbDialog
  448. :is-open-smooth="computed_type==='alpha'"
  449. :computed-source="computed_source"
  450. :operationForm="operationForm"
  451. :isPredict="true"
  452. @cancel="computed_type=0"
  453. @openPrev="isOpenComputed=true"
  454. @addCallBack="addComputedCallBack"
  455. @lookHistory="id => {isLookHistory=true;lookEdbId=id;}"
  456. />
  457. </div>
  458. </template>
  459. <script>
  460. import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
  461. import { dataBaseInterface } from '@/api/api.js';
  462. import leftMixin from './mixins/mixin';
  463. import edbDialog from './components/edbDia.vue'
  464. import childData from './components/childData.vue'
  465. import edbDetail from './components/edbDetail.vue'
  466. import edbClassifyDia from './components/classifyDia.vue'
  467. import changeLang from "@/views/dataEntry_manage/components/changeLang.vue"
  468. import setEnNameDia from "@/views/dataEntry_manage/components/setEnNameDia.vue"
  469. // import computedDialog from './components/computedDialog';
  470. import computedDialog from '@/views/dataEntry_manage/databaseComponents/computedDialog';
  471. import operationDialog from './components/operationDialog';
  472. import rulesDetail from './components/rulesDetailDia.vue'
  473. import batchComputedDialog from '@/views/dataEntry_manage/databaseComponents/batchComptedDialog.vue';
  474. import jointTargetDia from '@/views/dataEntry_manage/databaseComponents/jointTargetDia'
  475. import fittingResidueDia from '@/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue';
  476. import diffusionIndexDialog from '@/views/dataEntry_manage/databaseComponents/diffusionIndexDia.vue';
  477. import { formulaTip } from '@/views/dataEntry_manage/databaseComponents/util';
  478. import dataAssociateChart from '@/views/dataEntry_manage/databaseComponents/dataAssociateChart.vue'
  479. import dataAssociateComputeData from '@/views/dataEntry_manage/databaseComponents/dataAssociateComputeData.vue'
  480. import SmoothEdbDialog from '@/views/dataEntry_manage/databaseComponents/smoothEdbDialog.vue';
  481. export default {
  482. name:'',
  483. components: {
  484. edbDialog,
  485. childData,
  486. edbClassifyDia,
  487. changeLang,
  488. setEnNameDia,
  489. computedDialog,
  490. operationDialog,
  491. edbDetail,
  492. rulesDetail,
  493. jointTargetDia,
  494. fittingResidueDia,
  495. batchComputedDialog,
  496. diffusionIndexDialog,
  497. dataAssociateChart,
  498. dataAssociateComputeData,
  499. SmoothEdbDialog
  500. },
  501. mixins:[ leftMixin ],
  502. beforeRouteLeave (to, from, next) {
  503. // 前去编辑则存一次选择的节点
  504. if(to.path=='/editpredictEdb'){
  505. const obj={
  506. code:this.select_node,
  507. id:this.select_id
  508. }
  509. sessionStorage.setItem('predictEdbTreeData',JSON.stringify(obj))
  510. }else{
  511. sessionStorage.setItem('predictEdbTreeData','')
  512. }
  513. next()
  514. },
  515. data () {
  516. return {
  517. showData: false,
  518. search_txt: '',
  519. searchOptions:[],
  520. isSlideLeft: false,//左侧分类收起
  521. select_node: '',//节点唯一标识code
  522. select_classify: '',
  523. new_label:'',//双击修改的value
  524. treeData: [], //分类数据
  525. defaultShowNodes: [], //展开节点
  526. defaultProp: {
  527. label: 'ClassifyName',
  528. children: 'Children',
  529. isLeaf:'isLeaf'
  530. }, //树结构配置项
  531. dynamicNode: null,
  532. edbName: '',
  533. edb_nameEn: '',
  534. edbUserId: '',
  535. /* 分类弹窗 */
  536. dialog_title:'',
  537. classifyDia: false, //
  538. classifyForm: {},
  539. /* 添加指标弹窗 */
  540. isEdbDia: false,
  541. edbdia_title:'',
  542. edbForm: {},
  543. select_id: '',//选中的id
  544. sheetDetailInfo: {},
  545. detail_show_chart: true,//详情展示方式 chart data
  546. /* 列表 */
  547. publicHaveMove: true,//是否还有列表数据
  548. edbChartList: [],
  549. edb_total: 0,
  550. public_page: 1,
  551. public_pages_size: 16,
  552. currentLang:'ch', // ch(中文) en(英文)
  553. setEnName:false,
  554. // 传入的formItem所需内容
  555. formItemArray:[],
  556. /* 计算指标弹窗 */
  557. isOpenComputed:false,
  558. computedTit:'',
  559. calulateForm:{},
  560. operationForm:{},
  561. calulateList:[],
  562. computed_type:0,//打开弹窗的类型
  563. tips: new Map([
  564. [31,formulaTip.get(4)],
  565. [42,formulaTip.get(5)],
  566. [32,formulaTip.get(6)],
  567. [33,formulaTip.get(7)],
  568. [39,formulaTip.get(8)],
  569. [43,formulaTip.get(12)],
  570. [44,formulaTip.get(13)],
  571. [45,formulaTip.get(14)],
  572. ['joint',formulaTip.get('joint')],
  573. [46,formulaTip.get(22)],
  574. [49,formulaTip.get(35)],
  575. [50,formulaTip.get(37)],
  576. [54,formulaTip.get(51)],
  577. [55,formulaTip.get(52)],
  578. [56,formulaTip.get(53)],
  579. ['toMonthSeason',formulaTip.get('toMonthSeason')],
  580. ['accumulate',formulaTip.get('accumulate')],
  581. [64,formulaTip.get(61)],
  582. [65,formulaTip.get(62)],
  583. [66,formulaTip.get(63)],
  584. ['alpha',formulaTip.get('alpha')]
  585. ]),//公式说明
  586. isShowRuleDialog: false,
  587. showRules: [],
  588. showFromEdbInfo: {},
  589. edbButton: {},//详情操作
  590. opLevelOneClassify: false,//一级分类按钮
  591. computed_source: 1,//计算类型 1常规 2批量
  592. isBatchComputed: false,//批量计算弹窗
  593. baseTypes: [
  594. { name: '指标运算',type: 31 },
  595. { name: '同比值',type: 32 },
  596. { name: '同差值',type: 33 },
  597. { name: 'N数值移动平均计算',type: 39 },
  598. { name: '累计值转月/季值',type: 'toMonthSeason' },
  599. { name: 'N数值环比值',type: 43 },
  600. { name: 'N数值环差值',type: 44 },
  601. { name: '升频',type: 45 },
  602. // { name: '指标拼接',type: 'joint' },
  603. { name: '时间移位',type: 46 },
  604. { name: '超季节性',type: 49 },
  605. { name: '拟合残差',type: 50 },
  606. { name: '年化',type: 55 },
  607. { name: '降频',type: 54 },
  608. { name: '扩散指数',type: 56 },
  609. { name: '累计值',type: 'accumulate' },
  610. { name: '指数修匀',type:'alpha'}
  611. ],
  612. batchTypes: [
  613. { name: '同比值',type: 32 },
  614. { name: '同差值',type: 33 },
  615. { name: 'N数值移动平均计算',type: 39 },
  616. { name: 'N数值环比值',type: 43 },
  617. { name: 'N数值环差值',type: 44 },
  618. { name: '升频',type: 45 },
  619. { name: '累计值转月/季值',type: 'toMonthSeason' },
  620. { name: '累计值',type: 'accumulate' },
  621. { name: '指数修匀',type:'alpha'}
  622. ],
  623. isOnlyMe:false,//只看我的
  624. /* 查看历史弹窗 */
  625. isLookHistory: false,
  626. lookEdbId: 0,
  627. searchLoading:false,
  628. showAssociateChart:false,//显示指标关联的图
  629. showAssociateComputeData:false,//显示指标关联的引用计算指标
  630. activeTab:'',
  631. };
  632. },
  633. computed: {
  634. computedTypes() {
  635. return this.computed_source === 1 ? this.baseTypes : this.batchTypes;
  636. },
  637. role() {
  638. let role = localStorage.getItem('Role') || '';
  639. if(['rai_admin','ficc_admin'].includes(role)) {
  640. return 'admin'
  641. }
  642. else {
  643. return role;
  644. }
  645. },
  646. /* 登录角色id */
  647. roleId() {
  648. let id = parseInt(localStorage.getItem('AdminId'));
  649. return id;
  650. },
  651. showPopover(){
  652. return this.isEdbBtnShow('edbPreData_enNameSetting')||
  653. this.isEdbBtnShow('edbPreData_recalcu')||
  654. this.edbButton.DeleteButton&&this.isEdbBtnShow('edbPreData_del')||
  655. this.isEdbBtnShow('edbPreData_copyData')
  656. }
  657. },
  658. watch: {
  659. /* 设置动态右侧区域宽度 */
  660. isSlideLeft(newval) {
  661. if (!newval) {
  662. this.$nextTick(() => {
  663. this.reloadRightWid();
  664. });
  665. }
  666. },
  667. // /* 表格id */
  668. select_id(newval) {
  669. this.detail_show_chart = true;
  670. this.activeTab='Chart'
  671. this.$nextTick(()=>{
  672. //切换为曲线图 重置选择状态
  673. if(this.$refs.detailComponentRef){
  674. this.$refs.detailComponentRef.$refs.chartInfo.chartInfo.ChartType=1;
  675. this.$refs.detailComponentRef.$refs.chartInfo.year_select=10;
  676. this.$refs.detailComponentRef.$refs.chartInfo.year_select_season=20;
  677. this.$refs.detailComponentRef.$refs.chartInfo.calendar_type='公历';
  678. this.$refs.detailComponentRef.$refs.chartInfo.count_year=5;
  679. this.$refs.detailComponentRef.$refs.chartInfo.count_year_season=5;
  680. this.$refs.detailComponentRef.$refs.chartInfo.select_date=[];
  681. this.$refs.detailComponentRef.$refs.chartInfo.season_year=[];
  682. this.$refs.detailComponentRef.$refs.chartInfo.dateTip='请选择时间段';
  683. }
  684. })
  685. },
  686. select_classify(newval) {
  687. if(this.$refs.listRef) this.$refs.listRef.scrollTop = 0;
  688. if(newval) {
  689. this.activeTab = ''
  690. this.public_page = 1;
  691. this.getPublicList()
  692. }
  693. },
  694. /* 搜索关键词 */
  695. search_txt(newval) {
  696. if(newval) {
  697. let search_obj = this.searchOptions.find(_ => _.EdbInfoId === newval);
  698. // let deep_arr = _.cloneDeep(this.treeData);
  699. // 查找图表的分类父级id
  700. // let arr = this.findParentNodeHandle(deep_arr, search_obj.ClassifyId).reverse(); // 父的父的父-父的父-父
  701. // this.defaultShowNodes = arr;
  702. this.select_node = search_obj.UniqueCode;
  703. this.$refs.treeRef.setCurrentKey(this.select_node);
  704. // 重置筛选状态
  705. this.select_id = newval;
  706. }
  707. }
  708. },
  709. methods: {
  710. isEdbBtnShow(type){
  711. const {predictEdbPermission,checkPermissionBtn}=this.permissionBtn
  712. return checkPermissionBtn(predictEdbPermission[type])||false
  713. },
  714. setCurrentClassify(ClassifyList){
  715. //获取指标详情后才能拿到准确的classifyId
  716. //根据准备的id查找指标的父级目录并展开
  717. console.log(ClassifyList);
  718. // 展开目录
  719. this.defaultShowNodes=ClassifyList.reverse().map(item=>item.UniqueCode)
  720. //滚动到高亮节点位置
  721. // this.$nextTick(()=>{
  722. setTimeout(() => {
  723. const dom = document.getElementById(`node${this.select_node}`)||{}
  724. const parentDom = document.getElementsByClassName('target_tree')[0];
  725. /* if (dom.offsetTop > parentDom.offsetHeight) {
  726. parentDom.scrollTo({
  727. top: dom.offsetTop - parentDom.offsetHeight / 2,
  728. left: 0,
  729. behavior: "smooth",
  730. });
  731. } */
  732. //parent可视区间:[scrollTop,scrollTop+offsetHeight]
  733. //node位置:node.offsetTop
  734. const overTop = dom.offsetTop+dom.clientHeight<parentDom.scrollTop
  735. const overBottom = dom.offsetTop+dom.clientHeight+30>parentDom.scrollTop+parentDom.offsetHeight
  736. if(overTop){
  737. parentDom.scrollTop = dom.offsetTop-30
  738. }
  739. if(overBottom){
  740. parentDom.scrollTop = dom.offsetTop - parentDom.offsetHeight/2
  741. }
  742. this.searchLoading = false;
  743. }, 1500);
  744. setTimeout(() => {
  745. this.$refs.treeRef.setCurrentKey(this.select_node);//设置高亮
  746. }, 1500);
  747. // })
  748. },
  749. setNameBack({edb_name,edb_nameEn,userid}) {
  750. this.edbName=edb_name;
  751. this.edb_nameEn= edb_nameEn;
  752. this.edbUserId=userid;
  753. },
  754. /* 添加指标 */
  755. addEdbHandle() {
  756. if(!this.treeData.length) return this.$message.warning('请先添加预测指标分类');
  757. this.$router.push({
  758. path:'/addpredictEdb'
  759. })
  760. },
  761. /* 获取分类 */
  762. getTreeData(params=null) {
  763. preDictEdbInterface.predictEdbCatalog({IsOnlyMe:this.isOnlyMe||false,ParentId:0}).then(res => {
  764. const { Ret,Data } = res;
  765. if(Ret !== 200) return
  766. this.treeData = Data.AllNodes || [];
  767. this.opLevelOneClassify = Data.CanOpClassify;
  768. this.currentLang = Data.Language === 'EN' ? 'en' : 'ch';
  769. this.showData = true;
  770. this.$nextTick(() => {
  771. /* 新增完成后 处理树展开和选中 */
  772. params && this.selectCurrentNode(params);
  773. });
  774. })
  775. },
  776. /* 搜索 */
  777. searchHandle(query) {
  778. if (query) {
  779. /* 查找列表 */
  780. preDictEdbInterface
  781. .edbSearch({
  782. Keyword: query,
  783. CurrentIndex: 1,
  784. PageSize: 10000,
  785. IsOnlyMe:this.isOnlyMe||false
  786. })
  787. .then((res) => {
  788. if (res.Ret !== 200) return
  789. this.searchOptions = res.Data.List || [];
  790. });
  791. } else {
  792. this.searchOptions = [];
  793. }
  794. },
  795. /* 选中分类变化时 */
  796. nodeChange({ UniqueCode,EdbInfoId,ClassifyId },node) {
  797. this.search_txt = '';
  798. this.select_node = UniqueCode;
  799. this.select_id = EdbInfoId || 0;
  800. this.select_classify = !EdbInfoId ? ClassifyId : 0;
  801. this.resetNodeStyle(node);
  802. this.dynamicNode = node;
  803. this.showAssociateChart=false
  804. this.showAssociateComputeData=false
  805. },
  806. async saveEdbHandle() {
  807. const {Ret} = await preDictEdbInterface.saveChartInfo({
  808. EdbInfoId: this.select_id,
  809. MaxValue: Number(this.$refs.detailComponentRef.$refs.chartInfo.tableData[0].MaxData),
  810. MinValue: Number(this.$refs.detailComponentRef.$refs.chartInfo.tableData[0].MinData)
  811. })
  812. if(Ret !== 200) return
  813. this.$message.success('保存成功')
  814. this.setChartImage()
  815. },
  816. /* 关联图片 */
  817. setChartImage() {
  818. let svg = this.$refs.detailComponentRef.$refs.chartInfo.$refs.chartRef.chart.getSVG({
  819. chart: {
  820. width: 340,
  821. height: 230,
  822. },
  823. });
  824. let form = new FormData();
  825. form.append("Img", svg);
  826. this.setImageHandle(form);
  827. },
  828. async setImageHandle(form) {
  829. let { Data } = await dataBaseInterface.uploadImgSvg(form);
  830. await preDictEdbInterface.setImg({
  831. EdbInfoId: this.select_id,
  832. ImageUrl: Data.ResourceUrl,
  833. });
  834. },
  835. /* 添加一级目录 */
  836. addLevelOneHandle() {
  837. this.dialog_title = '添加';
  838. this.classifyForm = {
  839. classify_name: '',
  840. Level:0,
  841. ParentId:0
  842. }
  843. this.classifyDia = true;
  844. },
  845. // 递归节点
  846. getNodeParentData(data,arr){
  847. if(data.level===0) return
  848. arr.push({classifyName:data.data.ClassifyName,classifyId:data.data.ClassifyId})
  849. this.getNodeParentData(data.parent,arr)
  850. return arr
  851. },
  852. addNode(node,{ClassifyName,ClassifyId}){
  853. this.dialog_title = '添加'
  854. let arr=[]
  855. arr=this.getNodeParentData(node,arr)
  856. /* 添加目录 */
  857. this.classifyForm = {
  858. classify_name:'',
  859. Level:node.level,
  860. ParentId:ClassifyId,
  861. parentArr:arr,
  862. }
  863. this.classifyDia = true;
  864. },
  865. /* 编辑节点 */
  866. editNode(node, { ClassifyName,ClassifyId,Level,ParentId}) {
  867. this.dialog_title = '编辑';
  868. let arr=[]
  869. arr=this.getNodeParentData(node.parent,arr)
  870. /* 编辑目录 */
  871. this.classifyForm = {
  872. classify_name: ClassifyName,
  873. classify_id: ClassifyId,
  874. Level:node.level-1,
  875. ParentId:ParentId,
  876. parentArr:arr,
  877. };
  878. this.classifyDia = true;
  879. },
  880. /* 删除节点校验 */
  881. async removeNode(node, { ClassifyId,EdbInfoId }) {
  882. const { Data } = await preDictEdbInterface.classifyDelCheck({ ClassifyId,EdbInfoId })
  883. const { DeleteStatus,TipsMsg } = Data;
  884. // DeleteStatus === 1
  885. // ? this.$confirm('该分类下关联指标不可删除', '删除失败', {
  886. // confirmButtonText: '知道了',
  887. // showCancelButton: false,
  888. // type: 'error',
  889. // }) : DeleteStatus === 0 && !EdbInfoId
  890. // ? this.$confirm('确定删除当前分类吗?', '提示', {
  891. // confirmButtonText: '确定',
  892. // cancelButtonText: '取消',
  893. // type: 'warning',
  894. // }).then(() => {
  895. // this.delApi(ClassifyId, EdbInfoId)
  896. // }): null;
  897. /**
  898. * 0 可删除
  899. * 1 关联指标
  900. * 2 有子目录无指标
  901. */
  902. const deleteLabelMap = {
  903. 1: '该目录关联指标不可删除',
  904. 2: '确认删除当前目录及包含的子目录吗?',
  905. 3: '当前指标已用作画图,不可删除',
  906. 4: TipsMsg
  907. }
  908. if([1,3,4].includes(DeleteStatus)) this.$confirm(
  909. deleteLabelMap[DeleteStatus],
  910. '删除失败',
  911. {
  912. confirmButtonText: '知道了',
  913. showCancelButton:false,
  914. type: 'error'
  915. })
  916. else if([0,2].includes(DeleteStatus)) this.$confirm(
  917. DeleteStatus === 2
  918. ? deleteLabelMap[DeleteStatus]
  919. : EdbInfoId?'删除后指标和指标值均不可使用,确认删除吗?':'确定删除当前目录吗?',
  920. '提示',
  921. {
  922. confirmButtonText: '确定',
  923. cancelButtonText: '取消',
  924. type: 'warning'
  925. }).then(() => {
  926. this.delApi(ClassifyId, EdbInfoId)
  927. }).catch(() => {
  928. });
  929. },
  930. /* 删除方法 */
  931. delApi(ClassifyId, EdbInfoId, type='') {
  932. preDictEdbInterface
  933. .classifyDel({
  934. ClassifyId,
  935. EdbInfoId,
  936. })
  937. .then((res) => {
  938. if (res.Ret !== 200) return
  939. this.$message.success(res.Msg);
  940. if (!res.Data.EdbInfoId || !res.Data) this.select_id = '';
  941. //删除表格后自动显示下一张表格
  942. type && res.Data.EdbInfoId
  943. ? this.getTreeData({
  944. code: res.Data.UniqueCode,
  945. id: res.Data.EdbInfoId,
  946. classifyId:res.Data.ClassifyId
  947. })
  948. : this.getTreeData();
  949. });
  950. },
  951. /* 删除指标 */
  952. delEdbHandle() {
  953. this.$confirm('ETA预测指标删除后不可恢复,确认删除吗?', '提示', {
  954. confirmButtonText: '确定',
  955. cancelButtonText: '取消',
  956. type: 'warning',
  957. })
  958. .then(() => {
  959. this.delApi(
  960. this.select_classify || 0,
  961. this.select_id,
  962. 'del-edb'
  963. );
  964. })
  965. .catch(() => {});
  966. },
  967. /* 分类成功回调 */
  968. classifyCallback(type) {
  969. this.getTreeData();
  970. if (type === 'add') {
  971. //新增分类完成之后,展开父节点显示刚新增的分类,若已展开节点则不做处理
  972. let code = this.add_parent_id;
  973. let flag = this.defaultShowNodes.some(item => item === code);
  974. !flag && this.defaultShowNodes.push(code);
  975. this.add_parent_id = '';
  976. }
  977. },
  978. /* 展开对应菜单 显示详情 */
  979. detailShowHandle({ UniqueCode, EdbInfoId,ClassifyId}) {
  980. let params = {
  981. code: UniqueCode,
  982. id: EdbInfoId,
  983. classifyId:ClassifyId
  984. };
  985. this.selectCurrentNode(params);
  986. this.select_classify = 0;
  987. },
  988. /* 操作指标后 */
  989. handleEdbCallBack(param) {
  990. this.getTreeData(param)
  991. //编辑后刷数据
  992. if(!param) {
  993. console.log('编辑后刷数据');
  994. this.detail_show_chart ? this.$refs.detailComponentRef.getDetail('updateImg') : this.$refs.detailComponentRef.getData();
  995. }
  996. },
  997. /* 更新指标 */
  998. updateEdbHandle: _.debounce(function() {
  999. this.loading = this.$loading({
  1000. lock: true,
  1001. target:'.edb-detail-wrapper',
  1002. text: '刷新数据中...',
  1003. spinner: 'el-icon-loading',
  1004. background: 'rgba(255, 255, 255, 0.8)'
  1005. });
  1006. preDictEdbInterface.edbRefresh({
  1007. EdbInfoId: this.select_id
  1008. }).then(res => {
  1009. this.loading.close();
  1010. if(res.Ret !== 200) return
  1011. this.$message.success(res.Msg)
  1012. //更新完刷数据
  1013. console.log('更新完刷数据');
  1014. this.detail_show_chart ? this.$refs.detailComponentRef.getDetail('updateImg') : this.$refs.detailComponentRef.getData();
  1015. })
  1016. },300),
  1017. /* 部分刷新 */
  1018. updateEdbPartHandle: _.debounce(function() {
  1019. this.loading = this.$loading({
  1020. lock: true,
  1021. target:'.edb-detail-wrapper',
  1022. text: '刷新数据中...',
  1023. spinner: 'el-icon-loading',
  1024. background: 'rgba(255, 255, 255, 0.8)'
  1025. });
  1026. preDictEdbInterface.edbPartRefresh({
  1027. EdbInfoId: this.select_id
  1028. }).then(res => {
  1029. this.loading.close();
  1030. if(res.Ret !== 200) return
  1031. this.$message.success(res.Msg)
  1032. //更新完刷数据
  1033. console.log('更新完刷数据');
  1034. this.detail_show_chart ? this.$refs.detailComponentRef.getDetail('updateImg') : this.$refs.detailComponentRef.getData();
  1035. })
  1036. },300),
  1037. /* 编辑指标 */
  1038. editEdbHandle(type="") {
  1039. preDictEdbInterface.edbDetail({
  1040. EdbInfoId: this.select_id
  1041. }).then(res => {
  1042. if(res.Ret !== 200) return
  1043. const { RuleList,EdbType,Source,CalculateList } = res.Data;
  1044. // 原始指标
  1045. if(EdbType === 1) {
  1046. !type && this.$router.push({
  1047. path:'/editpredictEdb',
  1048. query:{
  1049. id:this.select_id
  1050. }
  1051. })
  1052. if(type === 'view') {
  1053. this.showRules = RuleList;
  1054. this.showFromEdbInfo = CalculateList[0];
  1055. this.isShowRuleDialog=true};
  1056. } else {
  1057. //计算指标
  1058. this.setComputedDialogForm(res.Data,type);
  1059. switch (Source) {
  1060. case 47:
  1061. case 48:
  1062. this.computed_type = 'joint';
  1063. break
  1064. case 72:
  1065. case 73:
  1066. this.computed_type = 'alpha';
  1067. break
  1068. default:
  1069. this.computed_type = Source;
  1070. break
  1071. }
  1072. // this.computed_type =[47,48].includes(Source)?'joint': Source;
  1073. // this.computed_type = [72,73].includes(Source)? 'alpha': Source;
  1074. }
  1075. })
  1076. },
  1077. /* 查看指标 */
  1078. viewNode() {
  1079. this.editEdbHandle('view')
  1080. },
  1081. /* 计算指标回显 */
  1082. setComputedDialogForm({Source,CalculateList,CalculateFormula,EdbInfoId,EdbName,Unit,Frequency,ClassifyId,ClassifyList,MoveType,MoveFrequency,Calendar,CorrelationStr,EmptyType,MaxEmptyType},type='') {
  1083. //找到指标的父级
  1084. const parentNodes = ClassifyList.length&&ClassifyList.map(item=>item.ClassifyId)
  1085. //指标运算 or 其他计算类型指标
  1086. if( Source === 31 ) {
  1087. /* 回显指标和表单 */
  1088. this.computedTit = '编辑计算指标';
  1089. /* 依赖的指标列表 */
  1090. this.calulateList = CalculateList.map(item => ({
  1091. tag: item.FromTag,
  1092. edb_name: item.FromEdbName,
  1093. target: item.FromEdbInfoId,
  1094. start_date: item.StartDate,
  1095. end_date: item.EndDate
  1096. }))
  1097. /* 公式和表单 */
  1098. this.calulateForm = {
  1099. edb_id:EdbInfoId,
  1100. formula: CalculateFormula,
  1101. menu: parentNodes,
  1102. targetName: EdbName,
  1103. unit: Unit,
  1104. frequency: Frequency,
  1105. emptyType: EmptyType,
  1106. maxEmptyType: MaxEmptyType,
  1107. view: type === 'view'
  1108. };
  1109. } else {
  1110. if([47,48,50,56].includes(Source)){//拟合残差
  1111. this.operationForm={
  1112. edb_id:EdbInfoId,
  1113. targetName: EdbName,
  1114. frequency: Frequency,
  1115. unit: Unit,
  1116. menu: parentNodes,
  1117. view: type === 'view',
  1118. source: Source,
  1119. date: CalculateFormula,
  1120. pre_edb: Source === 47 ? CalculateList.find(item => item.FromTag === 'A').FromEdbInfoId : '', //俺也不懂为什么这么定义都是江西老表的锅
  1121. after_edb: Source === 47 ? CalculateList.find(item => item.FromTag === 'B').FromEdbInfoId : '',
  1122. old_stay_edb: Source === 48 ? CalculateList.find(item => item.FromTag === 'A').FromEdbInfoId : '',
  1123. concat_edb: Source === 48 ? CalculateList.find(item => item.FromTag === 'B').FromEdbInfoId : '',
  1124. from_arr: CalculateList,
  1125. correlationStr: CorrelationStr
  1126. }
  1127. return
  1128. }
  1129. this.operationForm = {
  1130. oldedb_id: CalculateList[0].FromEdbInfoId,
  1131. oldEdb_name: CalculateList[0].FromEdbName,
  1132. edb_id: EdbInfoId,
  1133. targetName: EdbName,
  1134. unit: Unit,
  1135. menu: parentNodes.reverse(),
  1136. frequency: Frequency,
  1137. formula: CalculateFormula || '',
  1138. view: type === 'view',
  1139. moveType: MoveType,
  1140. moveUnit: MoveFrequency,
  1141. moveVal: Source === 46 ? CalculateFormula : '',
  1142. calendar_type: Source === 49 ? Calendar : '',
  1143. }
  1144. if([72,73].includes(Source)){
  1145. this.operationForm = {
  1146. edb_id: EdbInfoId,
  1147. oldedb_id: CalculateList[0].FromEdbInfoId,
  1148. oldEdb_name: CalculateList[0].FromEdbName,
  1149. EdbName,Frequency,Unit,ClassifyId,Formula:CalculateFormula,
  1150. view: type === 'view'
  1151. }
  1152. }
  1153. }
  1154. },
  1155. /* 复制数据 */
  1156. copyData() {
  1157. preDictEdbInterface.edbDataInfo({
  1158. EdbInfoId: this.select_id,
  1159. CurrentIndex: 1,
  1160. PageSize: 100000,
  1161. }).then(res => {
  1162. if(res.Ret !== 200) return
  1163. const { DataList,PredictDataList } = res.Data.Item;
  1164. let total_data = [...PredictDataList,...DataList];
  1165. let str = '日期\t 值\n';
  1166. total_data.forEach((item) => (str += `${item.DataTime}\t${item.Value}\n`));
  1167. this.$copyText(str).then(
  1168. (res) => {
  1169. this.$message.success('已成功复制!');
  1170. },
  1171. (err) => {
  1172. this.$message.error('复制失败!');
  1173. }
  1174. );
  1175. })
  1176. },
  1177. /* 获取表格列表 */
  1178. getPublicList() {
  1179. preDictEdbInterface.edbList({
  1180. CurrentIndex: this.public_page,
  1181. PageSize: this.public_pages_size,
  1182. ClassifyId: this.select_classify || 0,
  1183. IsOnlyMe:this.isOnlyMe||false,
  1184. }).then(res => {
  1185. if(res.Ret !== 200) return
  1186. this.publicHaveMove = res.Data
  1187. ? this.public_page < res.Data.Paging.Pages
  1188. : false;
  1189. this.edbChartList = res.Data
  1190. ? this.public_page === 1
  1191. ? res.Data.List
  1192. : [...this.edbChartList, ...res.Data.List]
  1193. : [];
  1194. this.edb_total = res.Data ? res.Data.Paging.Totals : 0;
  1195. })
  1196. },
  1197. /* 加载更多 */
  1198. loadMoreHandle: _.throttle(function() {
  1199. let scrollTop = this.$refs.listRef.scrollTop;
  1200. let clientHeight = this.$refs.listRef.clientHeight;
  1201. let scrollHeight = this.$refs.listRef.scrollHeight;
  1202. if(scrollTop + clientHeight >= scrollHeight-10 && this.publicHaveMove){
  1203. this.public_page++;
  1204. this.getPublicList();
  1205. }
  1206. },300),
  1207. /* 切换中英文 */
  1208. changeLangHandle: _.debounce(async function (lang){
  1209. this.search_txt = '';
  1210. this.currentLang = lang;
  1211. await dataBaseInterface.setUserLang({
  1212. ConfigCode: 'predict_edb_language',
  1213. ConfigValue: lang === 'en' ? 'EN' : 'CN'
  1214. })
  1215. },200),
  1216. /* 编辑英文 */
  1217. openEnNameDia(info){
  1218. this.formItemArray=[{
  1219. label:'指标名称',
  1220. value:info.EdbName,
  1221. key:'EdbName',
  1222. notEdit:true
  1223. }]
  1224. // 中文单位有 才能编辑英文单位
  1225. if(info.Unit && info.Unit!='无'){
  1226. this.formItemArray.push({
  1227. label:'单位',
  1228. value:info.Unit,
  1229. key:'Unit',
  1230. notEdit:true
  1231. },
  1232. {
  1233. label:'英文指标名称',
  1234. value:info.EdbNameEn,
  1235. key:'EdbNameEn',
  1236. placeholder:'请输入英文指标名称'
  1237. },
  1238. {
  1239. label:'英文单位',
  1240. value:info.UnitEn,
  1241. key:'UnitEn',
  1242. placeholder:'请输入英文单位'
  1243. })
  1244. }else{
  1245. this.formItemArray.push({
  1246. label:'英文指标名称',
  1247. value:info.EdbNameEn,
  1248. key:'EdbNameEn',
  1249. placeholder:'请输入英文指标名称'
  1250. })
  1251. }
  1252. this.setEnName = true
  1253. },
  1254. clickEdbNameHandle() {
  1255. this.$refs.detailComponentRef.changeEnOptions();
  1256. },
  1257. updateEnName(item){
  1258. let params={
  1259. EdbInfoId: Number(this.select_id),
  1260. ...item
  1261. }
  1262. dataBaseInterface.edbInfoEditEn(params).then(res=>{
  1263. if(res.Ret ==200){
  1264. this.$message({
  1265. message:res.Msg,
  1266. type:"success"
  1267. })
  1268. this.detail_show_chart ? this.$refs.detailComponentRef.getDetail() : this.$refs.detailComponentRef.getData();
  1269. this.setEnName = false
  1270. this.getTreeData({
  1271. code: this.select_node,
  1272. id: this.select_id
  1273. });
  1274. }
  1275. })
  1276. },
  1277. /* 打开计算弹窗 */
  1278. addComputedHandler() {
  1279. this.computedTit = '计算指标';
  1280. this.calulateList = [];
  1281. this.calulateForm = {};
  1282. this.operationForm = {};
  1283. this.isOpenComputed = true;
  1284. },
  1285. /* 选择计算类型 */
  1286. changeComputedType(type) {
  1287. let typeMapSource = {
  1288. 'toMonthSeason': 42,
  1289. 'accumulate': 65
  1290. }
  1291. this.computed_type = typeMapSource[type] || type;;
  1292. this.isOpenComputed = false;
  1293. },
  1294. /* 新增计算指标回调 */
  1295. addComputedCallBack(type, params) {
  1296. this.computed_type = 0;
  1297. this.computed_source = 1;
  1298. this.showAssociateChart=false;
  1299. this.showAssociateComputeData=false;
  1300. type === 'add' ? this.getTreeData(params) : this.getTreeData();
  1301. if(type === 'edit') {
  1302. this.detail_show_chart ? this.$refs.detailComponentRef.getDetail() : this.$refs.detailComponentRef.getData();
  1303. }
  1304. },
  1305. /* 重绘右侧区域宽度 */
  1306. reloadRightWid() {
  1307. let total_wid = $('.predict-edb-main')[0].offsetWidth;
  1308. let left = $('#left')[0].offsetWidth;
  1309. let rigtWid = total_wid - left - 20 + 'px';
  1310. $('#right')[0].style.width = rigtWid;
  1311. },
  1312. //只看我的
  1313. onlyMeHandler(){
  1314. this.getTreeData()
  1315. this.public_page = 1;
  1316. this.$refs.listRef.scrollTop = 0;
  1317. this.getPublicList();
  1318. },
  1319. //懒加载el-tree
  1320. async getLazyTreeData(node,resolve,maxLevel=3){
  1321. if(node.level===0){
  1322. resolve(this.treeData)
  1323. }else{
  1324. let arr=[]
  1325. const res=await preDictEdbInterface.predictEdbCatalog({IsOnlyMe:this.isOnlyMe||false,ParentId:node.data.ClassifyId})
  1326. if (res.Ret === 200) {
  1327. const temarr = res.Data.AllNodes || [];
  1328. arr=temarr.map(item=>{
  1329. return {
  1330. ...item,
  1331. isLeaf:item.EdbInfoId?true:false
  1332. }
  1333. })
  1334. }
  1335. resolve(arr)
  1336. }
  1337. },
  1338. changeTreeNode(){
  1339. this.$refs.treeRef.setCurrentKey(this.select_node);
  1340. this.$nextTick(()=>{
  1341. const _node = this.$refs.treeRef.getNode(this.select_node)
  1342. this.dynamicNode = _node;
  1343. this.dynamicNode&&this.resetNodeStyle(this.dynamicNode)
  1344. })
  1345. },
  1346. changeShowType(){
  1347. if(!this.activeTab) return
  1348. this.detail_show_chart = this.activeTab==='Chart'?true:false
  1349. }
  1350. },
  1351. mounted() {
  1352. const obj=sessionStorage.getItem('predictEdbTreeData')
  1353. if(obj||this.$route.query.code){
  1354. let code=obj?JSON.parse(obj).code:this.$route.query.code
  1355. let id=obj?JSON.parse(obj).id:this.$route.query.id
  1356. let classifyId=obj?JSON.parse(obj).classifyId:this.$route.query.classifyId
  1357. this.getTreeData({code: code,id: Number(id),classifyId:Number(classifyId)})
  1358. }else{
  1359. this.getTreeData()
  1360. }
  1361. // 清除缓存数据
  1362. setTimeout(() => {
  1363. sessionStorage.setItem('predictEdbTreeData','')
  1364. }, 1000);
  1365. this.getPublicList();
  1366. window.addEventListener('resize', this.reloadRightWid);
  1367. },
  1368. destroyed() {
  1369. window.removeEventListener('resize', this.reloadRightWid);
  1370. }
  1371. }
  1372. </script>
  1373. <style lang="scss">
  1374. .predictEdb-container{
  1375. .detail-header{
  1376. display: flex;
  1377. position: relative;
  1378. height: 60px;
  1379. .el-tabs{
  1380. width:200px;
  1381. .el-tabs__header{
  1382. margin-bottom: 0;
  1383. }
  1384. .el-tabs__nav{
  1385. display: flex;
  1386. width: 100%;
  1387. .el-tabs__item{
  1388. flex: 1;
  1389. text-align: center;
  1390. font-size: 16px;
  1391. height: 60px;
  1392. line-height: 60px;
  1393. }
  1394. }
  1395. }
  1396. }
  1397. .edb-tool{
  1398. flex: 1;
  1399. text-align: right;
  1400. display: flex;
  1401. gap: 16px;
  1402. justify-content: flex-end;
  1403. padding-right: 15px;
  1404. position: relative;
  1405. &::after{
  1406. position: absolute;
  1407. content:'';
  1408. width:100%;
  1409. left: 0;
  1410. bottom: 0;
  1411. height:2px;
  1412. background-color: #E4E7ED;
  1413. }
  1414. }
  1415. }
  1416. </style>
  1417. <style lang='scss' scoped>
  1418. @import "~@/styles/theme-vars.scss";
  1419. *{ box-sizing: border-box;}
  1420. $mini-font: 12px; $normal-font: 14px;
  1421. .predictEdb-container {
  1422. .slide-icon {
  1423. padding: 20px 0;
  1424. /* display: block; */
  1425. box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
  1426. border-radius: 5px;
  1427. cursor: pointer;
  1428. position: absolute;
  1429. top: 50%;
  1430. transform: translateY(-50%);
  1431. z-index: 99;
  1432. &:hover {
  1433. background-color: rgba(0, 0, 0, 0.05);
  1434. }
  1435. &.slide-left {
  1436. right: 0;
  1437. }
  1438. &.slide-right {
  1439. left: 0;
  1440. }
  1441. }
  1442. .predict-edb-main {
  1443. display: flex;
  1444. .main-left {
  1445. width: 400px;
  1446. min-width: 380px;
  1447. background: #fff;
  1448. margin-right: 20px;
  1449. border: 1px solid #ececec;
  1450. border-radius: 4px;
  1451. box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
  1452. height: calc(100vh - 120px);
  1453. overflow: hidden;
  1454. position: relative;
  1455. box-sizing: border-box;
  1456. .datasheet_top {
  1457. padding: 20px;
  1458. background: #fff;
  1459. border: 1px solid #ececec;
  1460. box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
  1461. margin-bottom: 20px;
  1462. display: flex;
  1463. align-items: center;
  1464. }
  1465. .search-cont {
  1466. padding: 0 20px;
  1467. }
  1468. .tree-cont {
  1469. padding: 0 20px 30px 20px;
  1470. /* max-height: calc(100vh - 280px);
  1471. overflow: auto; */
  1472. }
  1473. .target_tree {
  1474. color: #333;
  1475. max-height: calc(100vh - 400px);
  1476. overflow-y:auto;
  1477. .custom-tree-node {
  1478. display: flex !important;
  1479. justify-content: space-between;
  1480. align-items: center;
  1481. display: block;
  1482. flex: 1;
  1483. .node_label {
  1484. margin-right: 2px;
  1485. }
  1486. .el-icon-view {
  1487. color: #409eff;
  1488. font-size: 18px;
  1489. margin-left: 5px;
  1490. }
  1491. }
  1492. }
  1493. .noDepart {
  1494. margin: 30px 0;
  1495. display: flex;
  1496. align-items: center;
  1497. justify-content: center;
  1498. color: $theme-color;
  1499. font-size: 16px;
  1500. cursor: pointer;
  1501. }
  1502. .move-btn {
  1503. height: 100%;
  1504. width: 4px;
  1505. /* opacity: 0; */
  1506. position: absolute;
  1507. right: 0px;
  1508. top: 0;
  1509. &:hover {
  1510. cursor: col-resize;
  1511. /* background-color: orange */
  1512. }
  1513. }
  1514. }
  1515. .main-right {
  1516. width: 80%;
  1517. height: calc(100vh - 120px);
  1518. &.detail-main{
  1519. overflow-x:auto;
  1520. }
  1521. .edb-detail-wrapper {
  1522. height: 100%;
  1523. border: 1px solid #ececec;
  1524. border-radius: 4px;
  1525. box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
  1526. overflow: hidden;
  1527. background: #fff;
  1528. &.main-min-width{
  1529. min-width: 780px;
  1530. }
  1531. .detail-top {
  1532. padding: 20px;
  1533. display: flex;
  1534. justify-content: space-between;
  1535. align-items: center;
  1536. border-bottom: 1px solid #ececec;
  1537. .title {
  1538. font-size: 16px;
  1539. &.disabled { color: #ccc; }
  1540. }
  1541. .action-ul {
  1542. display: flex;
  1543. li { margin: 0 10px; }
  1544. }
  1545. }
  1546. .detail-wrap {
  1547. position: relative;
  1548. padding: 16px;
  1549. height: calc(100vh - 180px);
  1550. overflow-y: auto;
  1551. .toggle-text {
  1552. position: absolute;
  1553. right: 20px;
  1554. top: 40px;
  1555. z-index: 2;
  1556. display: flex;
  1557. align-items: center;
  1558. }
  1559. /* min-height: 500px; */
  1560. }
  1561. }
  1562. .sheet-list-cont {
  1563. color: #333;
  1564. .el-card .el-card__header,
  1565. .el-card__body {
  1566. padding: 10px;
  1567. }
  1568. .list-top {
  1569. display: flex;
  1570. align-items: center;
  1571. justify-content: space-between;
  1572. }
  1573. .edbChartList-wrapper {
  1574. margin-top: 10px;
  1575. display: flex;
  1576. flex-wrap: wrap;
  1577. max-height: calc(100vh - 143px);
  1578. overflow: hidden;
  1579. overflow-y: auto;
  1580. .drag-cont {
  1581. width: 100%;
  1582. display: flex;
  1583. flex-wrap: wrap;
  1584. }
  1585. .dragShdow {
  1586. box-shadow: 0 1px 8px rgba(64, 158, 255, 0.8);
  1587. opacity: 0.5;
  1588. }
  1589. .sheet-item {
  1590. width:23%;
  1591. min-width: 210px;
  1592. border-radius: 4px;
  1593. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  1594. border: 1px solid #EBEEF5;
  1595. background-color: #FFFFFF;
  1596. overflow: hidden;
  1597. color: #303133;
  1598. transition: 0.3s;
  1599. .item-top,.item-bottom{
  1600. padding:10px;
  1601. text-align: left;
  1602. }
  1603. .item-top {
  1604. display: flex;
  1605. justify-content: space-between;
  1606. align-items: center;
  1607. font-size: 16px;
  1608. font-weight: 600;
  1609. box-shadow: 0 3px 6px rgba(37, 37, 239, 0.1);
  1610. }
  1611. .chart-img {
  1612. /* width: 100%;
  1613. height: 230px;
  1614. object-fit: fill !important; */
  1615. margin:10px;
  1616. margin-bottom: 0;
  1617. height: 0;
  1618. padding-bottom: 67%;
  1619. cursor: pointer;
  1620. }
  1621. .item-bottom {
  1622. display: flex;
  1623. justify-content: space-between;
  1624. font-size: 12px;
  1625. color: #666;
  1626. .collected {
  1627. color: #f00;
  1628. cursor: pointer;
  1629. }
  1630. .join_txt {
  1631. color: $theme-color;
  1632. cursor: pointer;
  1633. }
  1634. }
  1635. }
  1636. }
  1637. .nodata {
  1638. text-align: center;
  1639. }
  1640. }
  1641. }
  1642. }
  1643. .computed-ul {
  1644. max-height: 600px;
  1645. height: 70vh;
  1646. overflow-y: auto;
  1647. padding: 40px 92px;
  1648. display: flex;
  1649. flex-wrap: wrap;
  1650. .cpmputed-li {
  1651. width: 180px;
  1652. padding: 19px 0;
  1653. height:60px;
  1654. color: $theme-color;
  1655. font-size: 16px;
  1656. background:#ECF5FF;
  1657. border-radius: 8px;
  1658. border: 1px solid #B3D8FF;
  1659. text-align: center;
  1660. cursor: pointer;
  1661. margin-right: 65px;
  1662. margin-bottom: 55px;
  1663. &:nth-child(3n) {
  1664. margin-right:0;
  1665. }
  1666. &:hover {
  1667. background: $theme-color;
  1668. color: #fff;
  1669. }
  1670. &.act {
  1671. background: $theme-color;
  1672. color: #fff;
  1673. }
  1674. }
  1675. }
  1676. }
  1677. </style>
  1678. <style lang="scss">
  1679. @import "~@/styles/theme-vars.scss";
  1680. .predictEdb-container {
  1681. .label-input .el-input__inner {
  1682. height: 25px;
  1683. line-height: 25px;
  1684. padding: 0 10px;
  1685. }
  1686. .el-dialog--center .el-dialog__body {
  1687. padding: 40px 20px 30px 60px;
  1688. }
  1689. .el-tree__drop-indicator{
  1690. height:3px;
  1691. background-color: $theme-color;
  1692. }
  1693. .el-tree-node__content {
  1694. margin-bottom: 14px !important;
  1695. }
  1696. .el-tree-node__children {
  1697. .el-tree-node {
  1698. /* margin-bottom: 8px !important; */
  1699. margin-bottom: 0px !important;
  1700. padding-left: 18px;
  1701. }
  1702. .el-tree-node__content {
  1703. margin-bottom: 5px !important;
  1704. padding-left: 0 !important;
  1705. }
  1706. }
  1707. .expanded.el-icon-caret-right:before {
  1708. content: url('../../assets/img/set_m/down.png') !important;
  1709. }
  1710. .el-icon-caret-right:before {
  1711. content: url('../../assets/img/set_m/slide.png') !important;
  1712. }
  1713. .el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
  1714. content: '' !important;
  1715. }
  1716. .el-tree-node__expand-icon.expanded {
  1717. -webkit-transform: rotate(0deg);
  1718. transform: rotate(0deg);
  1719. }
  1720. .el-tree-node.is-current > .el-tree-node__content {
  1721. background-color: #f0f4ff !important;
  1722. }
  1723. .el-tree-node__content {
  1724. padding-right: 10px !important;
  1725. }
  1726. .dialog-computed {
  1727. max-width:950px !important;
  1728. .el-dialog__header {
  1729. background-color: #fff;
  1730. .el-dialog__close {
  1731. color: #333;
  1732. }
  1733. }
  1734. }
  1735. }
  1736. .edb-tool-popover{
  1737. .edb-tool-wrap{
  1738. display: flex;
  1739. flex-wrap: wrap;
  1740. gap:10px;
  1741. .el-button + .el-button{
  1742. margin-left: 0;
  1743. }
  1744. }
  1745. }
  1746. </style>