index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. <template>
  2. <div class="dataEntry-page">
  3. <header>
  4. <div class="left-btn">
  5. <el-button
  6. type="primary"
  7. @click="isShowinsert=true"
  8. v-permission="permissionBtn.dataSourcePermission.manualDataWrite_import"
  9. ><!-- 导入数据 -->{{$t('ManualEntryPage.tit_insert_data')}}</el-button>
  10. <el-button
  11. type="primary"
  12. @click="$router.push({path: '/batchToBase' })"
  13. v-permission="permissionBtn.dataSourcePermission.manualDataWrite_batch_add"
  14. ><!-- 批量加入指标库 -->{{$t('ManualEntryPage.batch_addbase')}}</el-button>
  15. <el-button
  16. v-permission="permissionBtn.dataSourcePermission.manualDataWrite_online_excel"
  17. type="primary"
  18. @click="$router.push({path: '/onlineExcelCopy' })"
  19. ><!-- 在线Excel -->{{$t('ManualEntryPage.online_excel')}}</el-button>
  20. <el-button
  21. v-permission="permissionBtn.dataSourcePermission.manualDataWrite_batch_del"
  22. type="primary"
  23. @click="$router.push({path: '/batchDelList' })"
  24. ><!-- 批量删除 -->{{$t('ManualEntryPage.batch_del')}}</el-button>
  25. <el-select
  26. @change="changeFrequency"
  27. v-model="frequencySelect"
  28. :placeholder="$t('Edb.InputHolderAll.select_fre')"
  29. style="width: 240px;margin-left: 10px"
  30. clearable
  31. >
  32. <el-option
  33. v-for="item in frequencyArr"
  34. :key="item.label"
  35. :label="item.label"
  36. :value="item.value"
  37. >
  38. </el-option>
  39. </el-select>
  40. </div>
  41. <div class="right-wrap">
  42. <a style="width: 100%" :href="exportUrl" download>
  43. <el-button
  44. v-permission="permissionBtn.dataSourcePermission.manualDataWrite_export"
  45. type="text"
  46. >
  47. <!-- 导出Excel -->{{$t('Common.exp_excel')}}
  48. <el-tooltip placement="top">
  49. <div slot="content" v-html="exportMsg" style="max-width:350px"></div>
  50. <i class="el-icon-warning" style="color: #666;"></i>
  51. </el-tooltip>
  52. </el-button>
  53. </a>
  54. <el-select
  55. v-model="search_txt"
  56. v-loadMore="searchLoad"
  57. ref="searchRef"
  58. :filterable="!search_txt"
  59. remote
  60. clearable
  61. :placeholder="$t('Edb.InputHolderAll.input_name_orid')"
  62. style="width: 260px;margin-left:10px;"
  63. :remote-method="searchHandle"
  64. @click.native="inputFocusHandle"
  65. >
  66. <i slot="prefix" class="el-input__icon el-icon-search"></i>
  67. <el-option
  68. v-for="item in searchOptions"
  69. :key="item.TradeCode"
  70. :label="item.SecName"
  71. :value="item.TradeCode"
  72. />
  73. </el-select>
  74. </div>
  75. </header>
  76. <div class="main">
  77. <div class="main-left" id="left">
  78. <div class="left-main">
  79. <div class="tree-cont">
  80. <el-tree
  81. ref="treeRef"
  82. class="classify-tree"
  83. :data="classifyList"
  84. node-key="UniqueCode"
  85. :props="defaultProp"
  86. :current-node-key="select_node"
  87. :default-expanded-keys="defaultShowNodes"
  88. :expand-on-click-node="false"
  89. check-strictly
  90. empty-text="暂无分类"
  91. lazy
  92. :load="getLazyTreeData"
  93. @current-change="nodeChange"
  94. >
  95. <span class="custom-tree-node" slot-scope="{ node, data }">
  96. <span
  97. class="text_oneLine node_label"
  98. :style="`width:${
  99. (select_node === data.UniqueCode && node.Nodewidth) || ''
  100. }`"
  101. >
  102. <span>{{ data.ClassifyName }}</span>
  103. </span>
  104. </span>
  105. </el-tree>
  106. </div>
  107. </div>
  108. </div>
  109. <div class="main-right" id="right">
  110. <!-- 分类 -->
  111. <template v-if="!selectedEdb">
  112. <div>
  113. <h3><!-- 共{{total}}个指标 --> {{$t('EtaBasePage.total_show',{limit:total})}}</h3>
  114. <el-table
  115. :data="tableData"
  116. style="box-shadow: 0px 3px 6px rgba(155, 170, 219, 0.2);margin-top: 20px"
  117. border
  118. ref="table"
  119. >
  120. <el-table-column
  121. v-for="item in tableColums"
  122. :key="item.key"
  123. :label="item.label"
  124. :width="item.widthsty"
  125. :min-width="item.minwidthsty"
  126. align="center"
  127. >
  128. <template slot-scope="{row}">
  129. <span v-if="item.key==='SecName'" class="editsty" @click="lookDetailHandle(row)">{{row[item.key]}}</span>
  130. <span v-else>{{row[item.key]}}</span>
  131. </template>
  132. </el-table-column>
  133. <el-table-column
  134. :label="$t('Table.column_operations')"
  135. align="center"
  136. min-width="200"
  137. >
  138. <template slot-scope="{row}">
  139. <div>
  140. <span class="editsty" @click="handleEdb({item:row,type:'edit',from:1})" v-if="permissionBtn.isShowBtn('dataSourcePermission','manualDataWrite_edit')">{{$t('Table.edit_btn')}}</span>
  141. <span v-if="row.IsJoinEdb===0&&permissionBtn.isShowBtn('dataSourcePermission','manualDataWrite_add')" class="editsty" @click="handleEdb({item:row,type:'addToBase'})"><!-- 加入指标库 -->{{$t('ManualEntryPage.add_tobase')}}</span>
  142. <span class="editsty" @click="handleEdb({item:row,type:'logs'})"><!-- 操作日志 -->{{$t('ManualEntryPage.opera_logs')}}</span>
  143. <span v-if="row.IsJoinEdb===0&&permissionBtn.isShowBtn('dataSourcePermission','manualDataWrite_del')" class="deletesty" @click="handleEdb({item:row,type:'del'})">{{$t('Table.delete_btn')}}</span>
  144. </div>
  145. </template>
  146. </el-table-column>
  147. <div class="nodata" slot="empty">
  148. <tableNoData :text="$t('Table.prompt_slogan')" size="mini"/>
  149. </div>
  150. </el-table>
  151. <div style="height:35px;margin: 20px 0;">
  152. <m-page
  153. :page_no="pageNo"
  154. :pageSize="pageSize"
  155. :total="total"
  156. @handleCurrentChange="pageChange"
  157. />
  158. </div>
  159. </div>
  160. </template>
  161. <!-- 指标详情 -->
  162. <template v-else>
  163. <edbDetail
  164. ref="edbDetailRef"
  165. :id="selectedEdb"
  166. @handle="handleEdb"
  167. />
  168. </template>
  169. </div>
  170. </div>
  171. <!-- 导入数据弹窗 -->
  172. <insert-data
  173. :isShowinsert.sync="isShowinsert"
  174. @importSuccess="importSuccess"
  175. source="dataEntry"
  176. />
  177. <!-- 操作日志弹窗 -->
  178. <operateLogsDia
  179. :isShow.sync="isShowOperaLogs"
  180. :edbCode="operteId"
  181. />
  182. <!-- 加入指标库弹窗 -->
  183. <completeTargetDia
  184. :isOpenDialog="isAddBaseDia"
  185. @cancel="isAddBaseDia=false"
  186. :params="addBaseInfo"
  187. @add="handleAddBaseApi"
  188. />
  189. </div>
  190. </template>
  191. <script>
  192. import { dataInterence } from '@/api/api.js';
  193. import mPage from '@/components/mPage.vue';
  194. import edbDetail from './components/edbDetail.vue'
  195. import operateLogsDia from './components/operateLogsDia.vue';
  196. import insertData from '../components/insertData.vue';
  197. import completeTargetDia from '../databaseComponents/completeTargetDia.vue';
  198. import { frequencySelectList } from '@/utils/defaultOptions';
  199. export default {
  200. components: {
  201. mPage,
  202. edbDetail,
  203. operateLogsDia,
  204. insertData,
  205. completeTargetDia
  206. },
  207. computed: {
  208. tableColums() {
  209. return [
  210. { label: this.$t('Edb.Detail.e_id'),key: 'TradeCode' },
  211. { label: this.$t('Edb.Detail.e_name'),key: 'SecName',minwidthsty:'150px' },
  212. { label: this.$t('Edb.Detail.e_fre'),key: 'Frequency',widthsty:'100px' },
  213. { label: this.$t('Edb.Detail.e_unit'),key: 'Unit', },
  214. { label: this.$t('Edb.Detail.e_creator'),key: 'UserName', },
  215. { label: this.$t('Edb.Detail.e_update_time'),key: 'ModifyTime', },
  216. ]
  217. },
  218. exportUrl() {
  219. let exportDataurl = process.env.VUE_APP_API_ROOT + "/entry/export/dataList";
  220. let str = `${exportDataurl}?ClassifyId=${
  221. this.selectClassifyId
  222. }&TradeCode=${
  223. this.selectedEdb ? this.selectedEdb : ''
  224. }&StartDate=&EndDate=&Mobile=&${localStorage.getItem("auth")}`;
  225. return str.replace(/#/g, encodeURIComponent("#")).replace(/;/g, encodeURIComponent(";"));
  226. },
  227. frequencyArr(){
  228. return frequencySelectList(['月度'])
  229. }
  230. },
  231. watch: {
  232. search_txt(nval) {
  233. if(!nval) return
  234. this.selectClassifyId = 0;
  235. this.selectedEdb = nval;
  236. this.selectNode = this.searchOptions.find(_ => _.TradeCode===nval).UniqueCode;
  237. }
  238. },
  239. data() {
  240. return {
  241. tableSearch:{},
  242. frequencySelect:'',
  243. defaultProp: {
  244. label: 'ClassifyName',
  245. children: 'Child',
  246. isLeaf: 'isLeaf'
  247. },
  248. defaultShowNodes: [],
  249. classifyList: [],
  250. tableData: [],
  251. pageNo: 1,
  252. total: 0,
  253. pageSize: 10,
  254. search_txt: '',
  255. searchOptions: [],
  256. search_page: 1,
  257. current_search: '',
  258. search_have_more: false,
  259. exportMsg: /* `导出当前页面筛选的指标列表` */this.$t('ManualEntryPage.export_msg'),//导出tip
  260. selectClassifyId: 0,
  261. selectNode: '',
  262. selectedEdb: 0,
  263. /* 操作日志弹窗 */
  264. isShowOperaLogs: false,
  265. operteId: '',
  266. /* 导入弹窗 */
  267. isShowinsert:false,
  268. /* 加入弹窗 */
  269. isAddBaseDia: false,
  270. addBaseInfo: {}
  271. }
  272. },
  273. mounted(){
  274. this.getClassify();
  275. if(sessionStorage.getItem('cacheDataList')){
  276. this.cacheDataList()
  277. }else{
  278. this.getTableData()
  279. }
  280. },
  281. methods:{
  282. // 缓存列表页面
  283. cacheDataList(){
  284. const cacheData=JSON.parse(sessionStorage.getItem('cacheDataList'))
  285. console.log(cacheData)
  286. if(cacheData.editType===1){
  287. // 列表进入编辑
  288. const dataArr=[
  289. {key:'ClassifyId',value:'selectClassifyId'},
  290. {key:'CurrentIndex',value:'pageNo'},
  291. {key:'PageSize',value:'pageSize'},
  292. {key:'Frequency',value:'frequencySelect'},
  293. {key:'total',value:'total'}
  294. ]
  295. dataArr.forEach(el=>{
  296. this[el.value]=cacheData.tableSearch[el.key]
  297. })
  298. this.getTableData()
  299. }else{
  300. // 详情进入编辑
  301. this.selectedEdb = cacheData.id;
  302. this.searchHandle(cacheData.id)
  303. }
  304. sessionStorage.removeItem('cacheDataList')
  305. },
  306. // 改变频度
  307. changeFrequency(){
  308. this.selectedEdb=''
  309. this.pageNo = 1;
  310. this.getTableData()
  311. },
  312. lookDetailHandle(row) {
  313. this.selectClassifyId = 0;
  314. this.selectNode = '';
  315. this.selectedEdb = row.TradeCode;
  316. },
  317. // 获取分类
  318. getClassify() {
  319. dataInterence.getClassifyV2().then(res =>{
  320. if(res.Ret === 200 && res.Data.List) {
  321. this.classifyList = res.Data.List||[];
  322. }
  323. })
  324. },
  325. //加载子指标
  326. async getLazyTreeData(node,resolve,maxLevel=2) {
  327. if(node.level===0){
  328. resolve(this.classifyList)
  329. }else if(node.level>0&&node.level<maxLevel){
  330. //获取对应层级的Child
  331. resolve(node.data.Child||[])
  332. }else{
  333. let arr=[]
  334. const res=await dataInterence.getClassifyLoadChild({
  335. ClassifyId: node.data.ClassifyId
  336. })
  337. if (res.Ret === 200) {
  338. const temarr = res.Data.List || [];
  339. arr=temarr.map(item=>{
  340. return {
  341. ...item,
  342. isLeaf:item.TradeCode?true:false
  343. }
  344. })
  345. }
  346. resolve(arr)
  347. }
  348. },
  349. async getTableData() {
  350. this.tableSearch={
  351. ClassifyId: this.selectClassifyId,
  352. CurrentIndex: this.pageNo,
  353. PageSize: this.pageSize,
  354. Frequency:this.frequencySelect
  355. }
  356. const res = await dataInterence.getEdbListV2(this.tableSearch)
  357. if(res.Ret !==200) return
  358. this.tableData = res.Data.List || [];
  359. this.total = res.Data.Paging.Totals;
  360. },
  361. pageChange(page) {
  362. this.pageNo = page;
  363. this.getTableData()
  364. },
  365. /* 搜索 */
  366. searchHandle(query) {
  367. this.search_page = 1;
  368. this.current_search = query;
  369. this.searchApi(this.current_search)
  370. },
  371. searchApi(query,page=1) {
  372. dataInterence.searchEdbV2({
  373. Keyword:query,
  374. CurrentIndex: page
  375. }).then(res => {
  376. if(res.Ret !== 200) return
  377. const { List,Paging } = res.Data;
  378. this.search_have_more = page < Paging.Pages;
  379. this.searchOptions = page === 1 ? List : this.searchOptions.concat(List);
  380. })
  381. },
  382. /* 聚焦获取当前检索 */
  383. inputFocusHandle(e) {
  384. this.search_page = 1;
  385. this.current_search = e.target.value;
  386. this.searchApi(this.current_search);
  387. },
  388. searchLoad() {
  389. if(!this.search_have_more) return;
  390. this.searchApi(this.current_search,++this.search_page);
  391. },
  392. //选中节点
  393. nodeChange(data,node) {
  394. this.selectClassifyId = !data.TradeCode?data.ClassifyId:0;
  395. this.selectNode = data.UniqueCode;
  396. this.selectedEdb = data.TradeCode;
  397. if(this.selectClassifyId){
  398. this.pageNo = 1;
  399. this.getTableData();
  400. }
  401. },
  402. //导入成功
  403. importSuccess() {
  404. this.isShowinsert = false;
  405. this.getTableList();
  406. },
  407. /* 操作 */
  408. handleEdb({item,type,from}) {
  409. const typeMap = {
  410. 'edit': this.handleEditEdb,
  411. 'addToBase': this.handleAddToBase,
  412. 'logs': this.handleOperaLogs,
  413. 'del': this.handleDelEdb
  414. }
  415. typeMap[type]&&typeMap[type](item,from)
  416. },
  417. handleEditEdb(item,from) {
  418. let cacheData={
  419. editType:from, // 1-列表编辑 2-详情编辑
  420. id:item.TradeCode,
  421. tableSearch:{...this.tableSearch,total:this.total}
  422. }
  423. sessionStorage.setItem('cacheDataList',JSON.stringify(cacheData))
  424. this.$router.push({
  425. path: '/dataEdit',
  426. query: {
  427. id: item.TradeCode,
  428. }
  429. })
  430. },
  431. /* 加入指标库 */
  432. handleAddToBase(item) {
  433. this.addBaseInfo = {
  434. edb_name: item.SecName,
  435. menu: [],
  436. frequency: item.Frequency,
  437. unit: item.Unit,
  438. ...item
  439. }
  440. this.isAddBaseDia = true
  441. },
  442. handleAddBaseApi(params) {
  443. dataInterence.addToBaseBatchV2(
  444. [{
  445. EdbCode: params.TradeCode,
  446. EdbName: params.EdbName,
  447. Frequency: params.Frequency,
  448. Unit: params.Unit,
  449. ClassifyId: params.ClassifyId
  450. }]
  451. ).then(res=>{
  452. this.saveLoading = false
  453. if(res.Ret!==200) return
  454. this.$message.success(this.$t('MsgPrompt.add_msg2'))
  455. this.isAddBaseDia = false;
  456. if(this.selectedEdb){
  457. this.$refs.edbDetailRef.edbInfo.Detail.IsJoinEdb=1
  458. }else {
  459. this.getTableData()
  460. }
  461. })
  462. },
  463. // 查看操作日志
  464. handleOperaLogs(item){
  465. this.operteId = item.TradeCode;
  466. this.isShowOperaLogs = true;
  467. },
  468. /* 删除指标 */
  469. handleDelEdb(item) {
  470. // 删除前检测指标下是否有录入数据
  471. dataInterence.checkTarget({
  472. TradeCode:item.TradeCode
  473. }).then(res => {
  474. if(res.Data.Status===1){
  475. this.$message.error(/* "该指标已加入指标库,不可删除" */ this.$t('ManualEdbListPage.edb_not_allow_delete'))
  476. return
  477. }else{
  478. this.$confirm(
  479. res.Data.Status===0 ? this.$t('ManualEdbListPage.del_edb_msg') : this.$t('ManualEdbListPage.del_edb_rela_msg'),
  480. this.$t('Dialog.warn_tit'),{
  481. type:'warning'
  482. }).then(() => {
  483. dataInterence.delTarget({
  484. TradeCode:item.TradeCode
  485. }).then(res =>{
  486. if( res.Ret !== 200 ) return
  487. this.$message.success(/* '删除成功!' */this.$t('MsgPrompt.delete_msg'));
  488. this.getClassify();
  489. this.getTableData()
  490. });
  491. }).catch(() => {});
  492. }
  493. })
  494. }
  495. },
  496. }
  497. </script>
  498. <style scoped lang='scss'>
  499. .dataEntry-page {
  500. *{box-sizing: border-box;}
  501. header,.main-left,.main-right {
  502. padding: 20px;
  503. background: #fff;
  504. border: 1px solid #C8CDD9;
  505. border-radius: 4px;
  506. }
  507. header {
  508. margin-bottom: 20px;
  509. display: flex;
  510. justify-content: space-between;
  511. align-items: center;
  512. }
  513. .main {
  514. display: flex;
  515. .main-left {
  516. width: 300px;
  517. flex-shrink: 0;
  518. margin-right: 30px;
  519. .tree-cont {
  520. height: calc(100vh - 260px);
  521. overflow: auto;
  522. }
  523. .classify-tree {
  524. color: #333;
  525. overflow: hidden;
  526. .custom-tree-node {
  527. display: flex;
  528. justify-content: space-between;
  529. align-items: center;
  530. display: block;
  531. flex: 1;
  532. }
  533. }
  534. }
  535. .main-right {
  536. flex: 1;
  537. height: calc(100vh - 220px);
  538. overflow: auto;
  539. }
  540. }
  541. }
  542. </style>
  543. <style lang="scss">
  544. .dataEntry-page {
  545. .classify-tree {
  546. .el-tree__drop-indicator {
  547. height: 3px;
  548. background-color: #409eff;
  549. }
  550. .el-tree-node__content {
  551. margin-bottom: 14px !important;
  552. }
  553. .el-tree-node__children {
  554. .el-tree-node {
  555. margin-bottom: 0px !important;
  556. padding-left: 18px;
  557. }
  558. .el-tree-node__content {
  559. margin-bottom: 5px !important;
  560. padding-left: 0 !important;
  561. }
  562. }
  563. .expanded.el-icon-caret-right:before {
  564. content: url('~@/assets/img/set_m/down.png') !important;
  565. }
  566. .el-icon-caret-right:before {
  567. content: url('~@/assets/img/set_m/slide.png') !important;
  568. }
  569. .el-tree-node__expand-icon{
  570. padding-top: 10px;
  571. }
  572. .el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
  573. content: '' !important;
  574. }
  575. .el-tree-node__expand-icon.expanded {
  576. -webkit-transform: rotate(0deg);
  577. transform: rotate(0deg);
  578. }
  579. .el-tree-node.is-current>.el-tree-node__content {
  580. background-color: #f0f4ff !important;
  581. }
  582. .el-tree-node__content {
  583. padding-right: 10px !important;
  584. }
  585. }
  586. }
  587. </style>