MixedTable.vue 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441
  1. <template>
  2. <div class="table-wrapper" @keydown="handlekeyDownKeys">
  3. <template v-if="config.data.length">
  4. <!-- 工具栏 -->
  5. <toolBarSection v-if="!disabled" :cell="selectCell" @updateCell="updateCellStyle"/>
  6. <!-- 公式显示区 -->
  7. <div class="formula-wrapper" v-if="!disabled">
  8. <span style="flex-shrink: 0;color:#C0C4CC">{{$t('OnlineExcelPage.formula_lable')}}</span>
  9. <el-input
  10. v-if="selectCell&&selectCell.DataType===6"
  11. v-model="selectCell.Value"
  12. @change="updateValueByFormula"
  13. />
  14. </div>
  15. <table
  16. width="auto"
  17. border="0"
  18. class="table"
  19. :style="disabled ? 'width:100%' : ''"
  20. >
  21. <thead>
  22. <tr>
  23. <!-- 行头 -->
  24. <th class="th-tg sm"></th>
  25. <!-- 列头 -->
  26. <th
  27. v-for="(item, index) in columnHeader"
  28. :key="index"
  29. class="th-tg th-col"
  30. :data-cindex="item"
  31. :data-rindex="-1"
  32. @contextmenu.prevent="rightClickHandle"
  33. >
  34. {{ item }}
  35. </th>
  36. </tr>
  37. </thead>
  38. <tbody>
  39. <tr v-for="(row, index) in config.data" :key="index">
  40. <!-- 行头 -->
  41. <th
  42. class="th-tg th-row sm"
  43. @contextmenu.prevent="rightClickHandle"
  44. :data-rindex="rowHeader[index]"
  45. :data-cindex="-1"
  46. >
  47. {{ rowHeader[index] }}
  48. </th>
  49. <td
  50. v-for="(cell, cell_index) in row"
  51. :key="`${index}_${cell_index}`"
  52. :data-rindex="rowHeader[index]"
  53. :data-cindex="columnHeader[cell_index]"
  54. :data-key="cell.Uid"
  55. @click="clickCell($event, cell)"
  56. @dblclick="dblClickCellHandle($event,cell)"
  57. @contextmenu.prevent="rightClickHandle($event,cell)"
  58. @mouseenter="getRelationEdbInfo(cell)"
  59. @copy="copyCellHandle($event,cell)"
  60. @paste="pasteCellHandle($event,cell)"
  61. >
  62. <!-- 插入单元格禁止编辑 -->
  63. <!-- [4,5,6,7,8].includes(cell.DataType)&&!cell.CanEdit -->
  64. <template
  65. v-if="!cell.CanEdit
  66. ||disabled
  67. ||(cell.DataType===1&&[1,2].includes(cell.DataTimeType))"
  68. >
  69. <!-- 单元格类型5 7显示指标浮窗 -->
  70. <el-popover
  71. v-if="[5,7].includes(cell.DataType)&&!disabled"
  72. placement="top-start"
  73. width="350"
  74. trigger="hover"
  75. >
  76. <ul>
  77. <li style="display:flex;margin:10px;">
  78. <label style="min-width:80px;">{{$t('OnlineExcelPage.indicator_name_lbl')}}</label>
  79. {{cellrelationEdbInfo.EdbName}}
  80. </li>
  81. <li style="display:flex;margin:10px;">
  82. <label style="min-width:80px;">{{$t('OnlineExcelPage.lastest_date_lab')}}</label>
  83. {{cellrelationEdbInfo.LatestDate}}
  84. </li>
  85. <li style="display:flex;margin:10px;">
  86. <label style="min-width:80px;">{{$t('Table.edb_id')}}</label>
  87. {{cellrelationEdbInfo.EdbCode}}
  88. </li>
  89. </ul>
  90. <span
  91. slot="reference"
  92. :data-rindex="rowHeader[index]"
  93. :data-cindex="columnHeader[cell_index]"
  94. :data-key="cell.Uid"
  95. >{{ cell.ShowStyle?cell.ShowFormatValue:cell.ShowValue }}</span>
  96. </el-popover>
  97. <!-- 数字格式化显示 -->
  98. <span
  99. v-else-if="cell.ShowStyle"
  100. :data-rindex="rowHeader[index]"
  101. :data-cindex="columnHeader[cell_index]"
  102. :data-key="cell.Uid"
  103. >
  104. {{cell.ShowFormatValue}}
  105. </span>
  106. <span
  107. :data-rindex="rowHeader[index]"
  108. :data-cindex="columnHeader[cell_index]"
  109. :data-key="cell.Uid"
  110. v-else
  111. >{{ cell.ShowValue }}</span>
  112. </template>
  113. <el-autocomplete
  114. v-else
  115. v-model="cell.Value"
  116. :ref="`inputRef${cell.Uid}`"
  117. popper-class="edb-select-popover"
  118. :data-key="cell.Uid"
  119. :data-rindex="rowHeader[index]"
  120. :data-cindex="columnHeader[cell_index]"
  121. :fetch-suggestions="searchTarget"
  122. @change.native="changeVal($event, cell)"
  123. @keydown.native="keyEnterHandle($event,cell)"
  124. @blur="() => {$set(cell,'CanEdit',false)}"
  125. >
  126. <!-- @select="selectTarget($event,cell)"
  127. @click="clickCell($event, cell)"
  128. :highlight-first-item="cell.DataType===2"
  129. -->
  130. <template slot-scope="scope">
  131. <edbDetailPopover :info="scope.item">
  132. <div slot="reference" v-if="cell.DataType===2" class="edb-item">
  133. <span class="edb-item-name text_oneLine">{{ scope.item.EdbName }}</span>
  134. <i class="el-icon-check" style="color:#0052D9;font-size:18px;"/>
  135. </div>
  136. <div slot="reference" v-else>{{ scope.item.EdbName }}</div>
  137. </edbDetailPopover>
  138. </template>
  139. </el-autocomplete>
  140. </td>
  141. </tr>
  142. </tbody>
  143. </table>
  144. <!-- 右键菜单 -->
  145. <div class="contextMenu-wrapper" id="contextMenu-wrapper" @mouseleave="()=>{activeNames=[];hideContextMenu()}">
  146. <div :class="['item',{'deletesty': menu.key==='reset'}]" v-for="menu in config.contextMenuOption" :key="menu.key" @click="handleContext(menu.key)">
  147. <span v-if="!menu.children">{{menu.label}}</span>
  148. <el-collapse v-model="activeNames" @change="handleChange" v-if="menu.children">
  149. <el-collapse-item name="1">
  150. <template slot="title">
  151. {{menu.label}}
  152. </template>
  153. <div class="subMenu-wrapper">
  154. <div slot="reference" class="item" v-for="submenu in menu.children" :key="submenu.key" @click="edbCalculateInsertOpen(submenu)">
  155. <el-popover
  156. width="300"
  157. trigger="hover"
  158. placement="right"
  159. >
  160. <div v-html="formulaTip.get(submenu.fromEdbKey)"></div>
  161. <div slot="reference" style="width:100%">{{submenu.label}}</div>
  162. </el-popover>
  163. </div>
  164. </div>
  165. </el-collapse-item>
  166. </el-collapse>
  167. <!-- 二级菜单 -->
  168. <!-- <div class="subMenu-wrapper" v-if="menu.children">
  169. <div slot="reference" class="item" v-for="submenu in menu.children" :key="submenu.key" @click="edbCalculateInsertOpen(submenu)">
  170. <el-popover
  171. width="300"
  172. trigger="hover"
  173. placement="right"
  174. >
  175. <div v-html="formulaTip.get(submenu.fromEdbKey)"></div>
  176. <div slot="reference" style="width:100%">{{submenu.label}}</div>
  177. </el-popover>
  178. </div>
  179. </div> -->
  180. </div>
  181. </div>
  182. </template>
  183. <div class="nodata" v-else>
  184. <tableNoData :text="$t('Table.prompt_slogan')"/>
  185. </div>
  186. <!-- 选择指标 -->
  187. <selectTargetValueDia
  188. :isShow.sync="isSelectTargetValueDialog"
  189. :info="insertTargetValueInfo"
  190. @insert="insertSelectData"
  191. ref="selectTargetValueRef"
  192. />
  193. <!-- 插入系统/指标日期弹窗 -->
  194. <insertDateDia
  195. :isShow.sync="isInsertDateDialog"
  196. :info="insertDateInfo"
  197. @insert="insertDatehandle"
  198. />
  199. <!-- 指标计算弹窗 -->
  200. <calculateEdbDia
  201. ref="calculateEdbDiaRef"
  202. :isShow.sync="isInsertCalculate"
  203. :info="insertCalculateInfo"
  204. @insert="insertCalculateData"
  205. />
  206. <!-- 日期计算弹窗 -->
  207. <calculateDateDia
  208. ref="calculateDateDiaRef"
  209. :isShow.sync="isInsertCalculateDate"
  210. :info="insertCalculateDateInfo"
  211. @insert="insertCalculateDateValue"
  212. />
  213. </div>
  214. </template>
  215. <script>
  216. import {
  217. getRowHeaderCode,
  218. getColumnHeaderCode,
  219. selectCellStyle,
  220. selectMoreCellStyle,
  221. setRelationStyle,
  222. getRightClickMenu,
  223. checkDateFormat,
  224. setFocus,
  225. findCellByKey,
  226. resetRelationStyle,
  227. resetDialogCellStyle,
  228. extractFactorsFromFormula,
  229. findCellByFactor,
  230. splitString,
  231. toUpperCase,
  232. findCellKeyByFactor,
  233. isNumberVal,
  234. transDecimalPlace
  235. } from "../common/customTable";
  236. import * as sheetInterface from "@/api/modules/sheetApi.js";
  237. import { dataBaseInterface } from '@/api/api.js';
  238. import md5 from '@/utils/md5.js';
  239. import selectTargetValueDia from './selectTargetValueDia.vue';
  240. import insertDateDia from './insertDateDia.vue';
  241. import calculateEdbDia from './calculateEdbDia.vue';
  242. import calculateDateDia from './calculateDateDia.vue';
  243. import toolBarSection from './toolBarSection.vue';
  244. import { formulaTip } from '@/views/dataEntry_manage/databaseComponents/util';
  245. export default {
  246. props: {
  247. disabled: { //是否只预览
  248. type: Boolean,
  249. default: false,
  250. }
  251. },
  252. components: {
  253. selectTargetValueDia,
  254. insertDateDia,
  255. calculateEdbDia,
  256. calculateDateDia,
  257. toolBarSection
  258. },
  259. computed: {
  260. //列头
  261. columnHeader() {
  262. return getColumnHeaderCode(
  263. this.config.data[0] ? this.config.data[0].length : 0
  264. );
  265. },
  266. //行头
  267. rowHeader() {
  268. let total_length = this.config.data.length;
  269. // console.log(this.config.data)
  270. return getRowHeaderCode(total_length);
  271. },
  272. },
  273. watch:{
  274. 'config.data':{
  275. handler(newVal){
  276. if(!this.disabled && this.hasInit){
  277. this.$emit("autoSave")
  278. }
  279. },
  280. deep:true
  281. },
  282. insertRelationArr:{
  283. handler(newVal){
  284. if(!this.disabled && this.hasInit){
  285. this.$emit("autoSave")
  286. }
  287. },
  288. deep:true
  289. },
  290. },
  291. data() {
  292. return {
  293. config: {
  294. /* 单元格类型
  295. 1手动日期格 DataTimeType 0 /系统日期导入格 DataTimeType 1 /指标日期导入格 DataTimeType 2
  296. 2指标格 //eta1.5.6又弃用了
  297. 3自定义输入
  298. 4插入值 表格里有关联的日期和指标格 // eta1.1.6弃用了
  299. 5弹窗里的插入值 有关联日期格
  300. 6公式计算单元格
  301. 7指标计算的插入值单元格
  302. 8日期计算值单元格
  303. */
  304. data: [],
  305. contextMenuOption: [],
  306. },
  307. selectCell: {},//选中单元格info
  308. rightClickCell: {},//右键单元格 key c r
  309. insertTargetCell: {},//选择右键插入时的单元格 可和右键单元格不一样 key c r
  310. insertRelationArr: [], //表格单元格依赖关系数组
  311. isSelectTargetValueDialog: false,//选择指标插入值弹窗
  312. insertTargetValueInfo: {},//编辑 关联info
  313. cellrelationEdbInfo: {}, //指标浮窗信息
  314. copyCellItem: {},//复制时的单元格信息 用于粘贴赋值
  315. calculateClickCell: null,//双击公式单元格时的单元格信息 用于之后选其他单元格拼接公式
  316. isInsertDateDialog: false,//导入日期弹窗
  317. insertDateInfo: {},
  318. isInsertCalculate: false,//插入指标计算值
  319. insertCalculateInfo: {},//指标计算单元格info
  320. formulaTip,
  321. hasInit:false,
  322. isInsertCalculateDate: false,//日期计算弹窗
  323. insertCalculateDateInfo: {},//日期计算info
  324. activeNames: []
  325. };
  326. },
  327. mounted() {
  328. if(this.$route.path === '/addMixedSheet' && !this.$route.query.id) this.initData();
  329. },
  330. methods: {
  331. /* 输入时实时搜索 满足日期格式不搜索 有=视为输入公式不搜索 eta1.5.6弃用了*/
  332. async searchTarget(query,cb) {
  333. return cb([])
  334. //又要过滤掉2020-05-这样的奇葩其他格式 不让检索
  335. let dateOtherRegex = /^(?:(?:19|20)\d\d)([-])(0[1-9]|1[0-2])(-?)$/
  336. if(!query
  337. ||checkDateFormat(query)
  338. ||dateOtherRegex.test(query)
  339. ||query.startsWith('=')
  340. ) return cb([])
  341. const { DataType,EdbInfoId } = this.selectCell;
  342. const res = DataType===2
  343. ? await dataBaseInterface.targetDetail({EdbInfoId})
  344. : await sheetInterface.searchTarget({
  345. KeyWord: query,
  346. CurrentIndex: 1,
  347. PageSize: 1000
  348. })
  349. if(res.Ret !== 200) return
  350. let arr = DataType===2 ? [res.Data] : (res.Data.List||[])
  351. cb(arr);
  352. },
  353. /* 单击 */
  354. clickCell(e, cell) {
  355. if(this.disabled) return
  356. selectCellStyle(e);
  357. this.selectCell = cell;
  358. setFocus(e);
  359. //是插值单元格时寻找关联依赖的单元格 设置选框
  360. if([4,5,7].includes(cell.DataType)) {
  361. const { key } = e.target.dataset;
  362. if(!this.insertRelationArr.find(_ => _.key===key)) return
  363. let { relation_date,relation_edb } = this.insertRelationArr.find(_ => _.key===key)
  364. relation_date.key && setRelationStyle(relation_date)
  365. relation_edb.key && setRelationStyle(relation_edb)
  366. }
  367. //选择指标弹窗打开时选择日期更新弹窗数据
  368. this.isSelectTargetValueDialog&&this.$refs.selectTargetValueRef.changeRleationDate(this.selectCell)
  369. //计算指标弹窗打开时选择日期更新弹窗数据
  370. this.isInsertCalculate&&this.$refs.calculateEdbDiaRef.changeRleationDate(this.selectCell)
  371. //日期计算弹窗打开选中日期框时且有选中item时更新选中值
  372. cell.DataType===1&&this.isInsertCalculateDate&&this.$refs.calculateDateDiaRef.selectIndex&&this.$refs.calculateDateDiaRef.setSelectItemValue(this.selectCell)
  373. },
  374. /* 插入值 往左往上寻找同行同列是否有符合条件的一指标一日期 */
  375. async insertValue() {
  376. let params = this.findNearestCell();
  377. console.log(params)
  378. if(!params) {
  379. this.selectCell.DataType = 3;
  380. this.selectCell.DataTimeType = 0;
  381. this.selectCell.ShowValue = '';
  382. this.selectCell.Value = '';
  383. this.selectCell.DataTime = '';
  384. this.selectCell.EdbInfoId = 0;
  385. this.$message.warning(this.$t('OnlineExcelPage.no_here_val_msg') );
  386. return
  387. }
  388. const { EdbInfoId,Date,DataTimeType } = params
  389. const res = await sheetInterface.insertData({EdbInfoId,Date})
  390. if(res.Ret !==200) return
  391. res.Data ? this.$message.success(this.$t('OnlineExcelPage.insert_success_msg') ) : this.$message.warning(this.$t('OnlineExcelPage.the_date_no_val_msg') )
  392. this.selectCell.DataType = 4;
  393. this.selectCell.ShowValue = res.Data;
  394. this.selectCell.Value = res.Data;
  395. this.selectCell.EdbInfoId = EdbInfoId;
  396. this.selectCell.DataTime = Date;
  397. this.setRelation(params)
  398. },
  399. // 建立插入单元格和依赖单元格关联关系
  400. setRelation(data,cellType=4) {
  401. const { insert_cell } = data;
  402. let relation_obj = {
  403. type: cellType,
  404. key: insert_cell.key,
  405. relation_date: {
  406. type: 1,
  407. key: insert_cell.relation_date
  408. },
  409. relation_edb: {
  410. type: 2,
  411. key: insert_cell.relation_edb
  412. }
  413. }
  414. let haveIndex = this.insertRelationArr.findIndex(_ => _.key===insert_cell.key);
  415. if(haveIndex===-1) {
  416. this.insertRelationArr.push(relation_obj)
  417. }else {
  418. this.insertRelationArr.splice(haveIndex,1,relation_obj)
  419. }
  420. console.log(this.insertRelationArr)
  421. },
  422. /* 向左向上找出所有格子 找出离插入单元格最近的两个符合条件的单元格 看是否满足一指标一日期的条件
  423. 不满足就无法插入值
  424. */
  425. findNearestCell() {
  426. let { rindex,cindex,key } = this.rightClickCell;
  427. let index_row = this.rowHeader.findIndex(_ => _===rindex);
  428. let index_col = this.columnHeader.findIndex(_ => _===cindex);
  429. //同行左侧所有格子
  430. let row_cell_arr = this.config.data[index_row].filter((_,cell_index) => cell_index<index_col);
  431. //同列上侧所有格子
  432. let col_cell_arr = this.config.data.filter((row,row_index) => row_index<index_row).map(row=> row[index_col]);
  433. if(!row_cell_arr.length || !col_cell_arr.length){
  434. return null
  435. }
  436. //寻找最近的符合1 2类型的两个格子
  437. let params = null;
  438. for (let i = row_cell_arr.length - 1; i >= 0; i--) {
  439. for (let j = col_cell_arr.length - 1; j >= 0; j--) {
  440. if(!params) {
  441. if((row_cell_arr[i].DataType===1&&col_cell_arr[j].DataType===2)
  442. ||(row_cell_arr[i].DataType===2&&col_cell_arr[j].DataType===1)) {
  443. params = {
  444. DataTimeType: row_cell_arr[i].DataType===1 ? row_cell_arr[i].DataTimeType : col_cell_arr[j].DataTimeType,
  445. Date: row_cell_arr[i].DataType===1 ? row_cell_arr[i].ShowValue : col_cell_arr[j].ShowValue,
  446. EdbInfoId: row_cell_arr[i].DataType===2 ? row_cell_arr[i].EdbInfoId : col_cell_arr[j].EdbInfoId,
  447. insert_cell: {
  448. key,
  449. relation_date: row_cell_arr[i].DataType===1 ? row_cell_arr[i].Uid: col_cell_arr[j].Uid,
  450. relation_edb: row_cell_arr[i].DataType===2 ? row_cell_arr[i].Uid: col_cell_arr[j].Uid,
  451. },
  452. }
  453. break
  454. }
  455. }
  456. }
  457. }
  458. return params;
  459. },
  460. /* 选择指标 单元格类型为2 已经是指标单元格了就重置单元格 否则就视为选择指标*/
  461. selectTarget(e,cell) {
  462. const { EdbName,EdbInfoId } = e;
  463. //如果已经是指标单元格了再次点击就清空
  464. if(cell.DataType===2&&cell.EdbInfoId) {
  465. this.clearCell()
  466. }else {
  467. cell.DataType = 2;
  468. cell.DataTime = '';
  469. cell.ShowValue = EdbName;
  470. cell.Value = EdbName;
  471. cell.EdbInfoId = EdbInfoId;
  472. }
  473. this.checkCellRelation(cell)
  474. },
  475. /* 输入框失焦 设置单元格类型 处理关联关系 */
  476. async changeVal(e, cell) {
  477. // 是日期格式 DataType为1
  478. // 自定义内容 DataType 3
  479. //有=号为输入公式 DataType 6
  480. const {value} = e.target;
  481. if(!value){ //无值重置单元格
  482. cell.DataType = 3;
  483. cell.ShowValue = value;
  484. cell.Value = value;
  485. cell.EdbInfoId = 0;
  486. cell.DataTime = '';
  487. cell.Extra=''
  488. }else {
  489. //指标类型不做格式处理
  490. if(cell.DataType===2) return
  491. console.log(checkDateFormat(value))
  492. let dateFormat = checkDateFormat(value);
  493. if(dateFormat) { //是日期格式
  494. cell.DataType = 1;
  495. cell.Extra='';
  496. cell.ShowValue = dateFormat;
  497. cell.DataTime = dateFormat;
  498. cell.Value = dateFormat;
  499. }else if(value.startsWith('=')) { //公式单元格
  500. cell.DataType = 6;
  501. let calculateVal = await this.getValueByFormula(value);
  502. if(!calculateVal) return
  503. cell.ShowValue = calculateVal;
  504. //处理公式关系
  505. this.$set(cell,'Extra',this.dealFormulaConstruction(value))
  506. }else {//自定义值
  507. cell.DataType = 3;
  508. cell.ShowValue = value;
  509. cell.Value = value;
  510. cell.EdbInfoId = 0;
  511. cell.DataTime = '';
  512. cell.Extra=''
  513. }
  514. }
  515. /* 不是数字类型,清除原来设置的格式 */
  516. if(!isNumberVal(value)){
  517. cell.ShowStyle = '';
  518. cell.ShowStyle = '';
  519. } ;
  520. //判断是否是有插入值的依赖单元格 更新值或重置关系
  521. this.checkCellRelation(cell)
  522. },
  523. /* 当前单元格是否和插入值有关联 无就不管 */
  524. async checkCellRelation(cell) {
  525. if(!this.insertRelationArr.length) return
  526. const key= cell.Uid;
  527. //有关联的N组数组
  528. let haveRelationArr = this.insertRelationArr.filter(_ => _.relation_date.key===key||_.relation_edb.key===key);
  529. if(!haveRelationArr.length) return
  530. //去处理每一组关联的情况
  531. haveRelationArr.forEach( async(relation) => {
  532. const { relation_date,relation_edb,type } = relation;
  533. if((relation_date.key === key && cell.DataType === 1) || (relation_edb.key === key && cell.DataType === 2)) { //单元格类型不变只变值仍有关联关系 更新值
  534. //类型4的表格插值才调接口刷数据 之后关联的有其他类型插值 区分一下
  535. if(type === 4) {
  536. //刷新插入值结果
  537. let params = null;
  538. if(relation_date.key === key && cell.DataType === 1) { //修改的是依赖日期格
  539. let { EdbInfoId } = findCellByKey(this.config.data,relation.key)
  540. params = {
  541. EdbInfoId,
  542. Date: cell.ShowValue
  543. }
  544. } else if( relation_edb.key === key && cell.DataType === 2) { //修改的依赖指标格
  545. let {ShowValue} = findCellByKey(this.config.data,relation_date.key)
  546. params = {
  547. EdbInfoId: cell.EdbInfoId,
  548. Date: ShowValue
  549. }
  550. }
  551. const res = await sheetInterface.insertData(params)
  552. if(res.Ret !==200) return
  553. //现在日期无值也不清除关系了
  554. // !res.Data && this.updateInsertCell(relation.key);
  555. this.config.data.forEach(row => {
  556. row.forEach(cell => {
  557. if(cell.Uid === relation.key) {
  558. cell.DataType = relation.type;
  559. cell.ShowValue = res.Data;
  560. cell.Value = res.Data;
  561. cell.EdbInfoId = params.EdbInfoId;
  562. cell.DataTime = params.Date;
  563. }
  564. })
  565. })
  566. }
  567. }else {
  568. // 清除插入值单元格式和关联关系
  569. this.updateInsertCell(relation.key);
  570. }
  571. })
  572. },
  573. // 清除插入值单元格式和关联关系
  574. updateInsertCell(key) {
  575. this.config.data.forEach(row => {
  576. row.forEach(cell => {
  577. if(cell.Uid === key) {
  578. cell.DataType = 3;
  579. cell.EdbInfoId = 0;
  580. cell.DataTime = '';
  581. cell.ShowValue = '';
  582. cell.Value = '';
  583. cell.ShowStyle = ''
  584. }
  585. })
  586. })
  587. let relationIndex = this.insertRelationArr.findIndex(_ => _.key===key)
  588. this.insertRelationArr.splice(relationIndex,1)
  589. },
  590. /* 输入公式的计算值 */
  591. async getValueByFormula(val) {
  592. // 提取因数数组
  593. let factors = extractFactorsFromFormula(val)
  594. console.log(factors)
  595. //根据因数找单元格
  596. let isAllCell = factors.some(_ => findCellByFactor(_)===null||isNaN(findCellByFactor(_)))
  597. if(isAllCell) {
  598. this.$message.warning(this.$t('OnlineExcelPage.xxformula_val_error_msgx') )
  599. return '';
  600. }
  601. let TagMap = {};
  602. factors.forEach(_ => {
  603. if(!TagMap[_]) {
  604. TagMap[_] = Number(findCellByFactor(_))
  605. }
  606. });
  607. const res = await sheetInterface.calculateCustomCellData({
  608. CalculateFormula: val,
  609. TagMap
  610. })
  611. if(res.Ret !== 200) return
  612. return res.Data
  613. },
  614. /* 顶部公式改变 */
  615. async updateValueByFormula(value) {
  616. this.changeVal({target: {value}},this.selectCell)
  617. },
  618. /* 右键 */
  619. rightClickHandle(e,cell) {
  620. if(this.disabled) return
  621. const { rindex,cindex,key } = e.target.dataset;
  622. this.rightClickCell = {
  623. rindex,
  624. cindex,
  625. key
  626. }
  627. this.selectCell = cell;
  628. let pos;
  629. if(rindex==='-1') { //列头处
  630. pos = 'col'
  631. }else if(cindex==='-1') { //行头
  632. pos = 'row'
  633. }else {//单元格
  634. pos = 'cell'
  635. }
  636. this.config.contextMenuOption = pos === 'cell'
  637. ? getRightClickMenu(pos,(cell.DataType===1&&[1,2].includes(cell.DataTimeType))||[5,7,8].includes(cell.DataType))
  638. : getRightClickMenu(pos)
  639. this.$nextTick(() => {
  640. let dom = $('#contextMenu-wrapper')[0];
  641. if(e.clientY > window.innerHeight/2) {
  642. dom.style.left = e.clientX-3 + 'px';
  643. dom.style.top = e.clientY-dom.offsetHeight-3 + 'px';
  644. }else {
  645. dom.style.left = e.clientX-3 + 'px';
  646. dom.style.top = e.clientY-3 + 'px';
  647. }
  648. ['col','row'].includes(pos) && selectMoreCellStyle(e);
  649. pos==='cell' && this.clickCell(e,cell);
  650. })
  651. },
  652. /* */
  653. hideContextMenu() {
  654. const dom = $('#contextMenu-wrapper')[0];
  655. dom.style.left = '-9999px';
  656. dom.style.top = '-9999px';
  657. },
  658. /* 右键事件 */
  659. async handleContext(key) {
  660. //可右键编辑的单元格类型
  661. let editHandlesMap = {
  662. 1: this.insertDateOpen,
  663. 5: this.selectTargetOpen,
  664. 7: this.edbCalculateInsertOpen,
  665. 8: this.insertDateCalculateOpen
  666. }
  667. const keyMap = {
  668. 'del': this.delColOrRow,//删除
  669. 'insert-col-left': this.insertCol,//向左插入列
  670. 'insert-col-right': this.insertCol,//向右插入列
  671. 'insert-row-up': this.insertRow,//向上插入行
  672. 'insert-row-down': this.insertRow,//向下插入行
  673. 'insert-value': this.insertValue,//插入值
  674. 'choose-target': this.selectTargetOpen,//选择指标插入值
  675. 'insert-date': this.insertDateOpen,//导入系统日期
  676. // 'insert-edb-date': this.insertDateOpen,//导入指标日期
  677. 'insert-date-calculate': this.insertDateCalculateOpen,//日期计算弹窗
  678. 'reset': this.clearCell, //清空
  679. 'cell-edit': this.selectCell ? editHandlesMap[this.selectCell.DataType] : null
  680. }
  681. keyMap[key] && keyMap[key](key)
  682. key!=='insert-edb-calculate' && this.hideContextMenu()
  683. },
  684. /* 打开选择指标弹窗
  685. 打开弹窗后仍可以在页面上点击 多存一个选择指标时的当前单元格信息 */
  686. selectTargetOpen(type) {
  687. this.insertTargetCell = this.selectCell;
  688. resetDialogCellStyle();
  689. setRelationStyle({ key:this.insertTargetCell.Uid },'td-choose-insert-target')
  690. if(type === 'cell-edit') {
  691. this.insertTargetValueInfo = {
  692. ...this.insertTargetCell
  693. }
  694. }else {
  695. this.insertTargetValueInfo = {}
  696. }
  697. this.isSelectTargetValueDialog = true;
  698. this.resetDialogStatus('insertEdbVal')
  699. },
  700. /* 插入选择指标的值 */
  701. insertSelectData({ edbId,value,relationDate,relationUid,str }) {
  702. this.insertTargetCell.DataType = 5;
  703. this.insertTargetCell.ShowValue = value;
  704. this.insertTargetCell.Value = str;
  705. this.insertTargetCell.EdbInfoId = edbId;
  706. this.insertTargetCell.DataTime = relationDate;
  707. this.insertTargetCell.ShowFormatValue = this.insertTargetCell.ShowStyle ? transDecimalPlace(value,JSON.parse(this.insertTargetCell.ShowStyle)) : '';
  708. value ? this.$message.success(this.$t('ETable.Msg.insertion_success_msg')) : this.$message.warning(this.$t('ETable.Msg.date_no_data'))
  709. //如果有关联表格日期就建立新的关联关系
  710. if(relationDate&&relationUid) {
  711. let relation = {
  712. insert_cell: {
  713. key: this.insertTargetCell.Uid,
  714. relation_date: relationUid,
  715. relation_edb: '',
  716. }
  717. }
  718. this.setRelation(relation,5);
  719. }else { //重新插值后之后原来有关联的清除关系
  720. let haveIndex = this.insertRelationArr.findIndex(_ => _.key===this.insertTargetCell.Uid);
  721. haveIndex!==-1 && this.insertRelationArr.splice(haveIndex,1)
  722. resetRelationStyle();
  723. }
  724. },
  725. /* 清除单元格内容 格式 关联关系 */
  726. clearCell() {
  727. if([4,5].includes(this.selectCell.DataType)) resetRelationStyle();
  728. this.selectCell.DataType = 3;
  729. this.selectCell.ShowValue = '';
  730. this.selectCell.Value = '';
  731. this.selectCell.DataTime = '';
  732. this.selectCell.DataTimeType = 0;
  733. this.selectCell.EdbInfoId = 0;
  734. this.selectCell.ShowStyle = '';
  735. this.selectCell.ShowFormatValue = '';
  736. this.checkCellRelation(this.selectCell)
  737. },
  738. /* 删除行列 */
  739. delColOrRow() {
  740. let { rindex,cindex } = this.rightClickCell;
  741. if(rindex==='-1') { //删除列
  742. console.log('删除列',cindex)
  743. if(this.columnHeader.length === 1) return this.$message.warning(this.$t('OnlineExcelPage.keep_one_column_msg') )
  744. let index = this.columnHeader.findIndex(_ => _ === cindex);
  745. //删除时清除关系
  746. if(this.insertRelationArr.length) {
  747. let delCellIds = this.config.data.map(row => row[index].Uid);
  748. this.clearRelationInsertCell(delCellIds);
  749. }
  750. this.config.data.forEach(row => {
  751. row.splice(index,1)
  752. })
  753. }else if(cindex === '-1') { //删除行
  754. console.log('删除行',rindex)
  755. if(this.rowHeader.length === 1) return this.$message.warning(this.$t('OnlineExcelPage.keep_one_row_msg') )
  756. let index = this.rowHeader.findIndex(_ => _ === rindex)
  757. if(this.insertRelationArr.length) {
  758. //删除时清除关系
  759. let delCellIds = this.config.data[index].map(cell => cell.Uid);
  760. this.clearRelationInsertCell(delCellIds);
  761. }
  762. this.config.data.splice(index,1)
  763. }
  764. },
  765. /* 删除时清除关联关系 和删除单元格有关联的插入值单元格和 */
  766. clearRelationInsertCell(delCellIds) {
  767. //清除关联插入值得单元格
  768. let haveRelationArr = this.insertRelationArr.filter(_ => delCellIds.includes(_.relation_date.key)||delCellIds.includes(_.relation_edb.key));
  769. // console.log(haveRelationArr)
  770. haveRelationArr.forEach(relation => {
  771. !delCellIds.includes(relation)&&this.updateInsertCell(relation.key);
  772. })
  773. this.insertRelationArr = this.insertRelationArr.filter(_ => !delCellIds.includes(_.key)&&!delCellIds.includes(_.relation_date.key)&&!delCellIds.includes(_.relation_edb.key))
  774. },
  775. /* 插入列 */
  776. insertCol(key) {
  777. let { cindex } = this.rightClickCell;
  778. let index = this.columnHeader.findIndex(_ => _ === cindex);
  779. this.config.data.forEach((row,rindex) => {
  780. row.splice(key==='insert-col-left'?index:index+1,0,{
  781. ShowValue: "",
  782. Value: "",
  783. DataType: 3,
  784. DataTime: "",
  785. EdbInfoId: 0,
  786. Uid: md5.hex_md5(`${new Date().getTime()}${rindex}`)
  787. })
  788. })
  789. },
  790. /* 插入行 */
  791. insertRow(key) {
  792. let { rindex } = this.rightClickCell;
  793. let index = this.rowHeader.findIndex(_ => _ === rindex)
  794. let row = new Array(this.columnHeader.length).fill("").map((_,cindex) => ({
  795. ShowValue: "",
  796. Value: "",
  797. DataType: 3,
  798. DataTime: "",
  799. EdbInfoId: 0,
  800. Uid: md5.hex_md5(`${new Date().getTime()}${cindex}`)
  801. }));
  802. this.config.data.splice( key==='insert-row-up'?index:index+1,0,row)
  803. },
  804. /* 单元格类型5 浮到上面展示指标信息浮窗 */
  805. async getRelationEdbInfo({EdbInfoId,DataType}) {
  806. if(![5,7].includes(DataType)||this.disabled) return
  807. const res = await dataBaseInterface.targetDetail({EdbInfoId})
  808. if(res.Ret !== 200) return
  809. this.cellrelationEdbInfo = res.Data;
  810. },
  811. /* 导入系统/指标日期弹窗 */
  812. insertDateOpen(type) {
  813. this.insertTargetCell = this.selectCell;
  814. resetDialogCellStyle();
  815. if(type === 'cell-edit') { //编辑日期
  816. this.insertDateInfo = {
  817. ...this.insertTargetCell
  818. }
  819. }else {
  820. this.insertDateInfo = {
  821. // key:type
  822. }
  823. }
  824. this.isInsertDateDialog = true;
  825. this.resetDialogStatus();
  826. },
  827. /* 弹窗都是无遮罩的 弹一个就重置其他的 */
  828. resetDialogStatus(type='init') {
  829. if(type!=='insertEdbVal') {
  830. this.$refs.selectTargetValueRef&&this.$refs.selectTargetValueRef.initData();
  831. this.isSelectTargetValueDialog = false;
  832. }
  833. if(type!=='insertEdbCalculateVal') {
  834. this.$refs.calculateEdbDiaRef&&this.$refs.calculateEdbDiaRef.initData();
  835. this.isInsertCalculate = false;
  836. }
  837. if(type!=='insertDateCalculateVal') {
  838. this.$refs.calculateDateDiaRef&&this.$refs.calculateDateDiaRef.initData();
  839. this.isInsertCalculateDate = false;
  840. }
  841. },
  842. /* 插入系统/指标日期 */
  843. insertDatehandle({insertValue,dataTimeType,str}) {
  844. this.insertTargetCell.DataType = 1;
  845. this.insertTargetCell.DataTimeType = dataTimeType;
  846. this.insertTargetCell.ShowValue = insertValue;
  847. this.insertTargetCell.Value = str;
  848. this.insertTargetCell.EdbInfoId = 0;
  849. this.insertTargetCell.DataTime = insertValue;
  850. },
  851. /* 指标计算弹窗 */
  852. edbCalculateInsertOpen(item) {
  853. this.insertTargetCell = this.selectCell;
  854. resetDialogCellStyle();
  855. setRelationStyle({ key:this.insertTargetCell.Uid },'td-choose-insert-target');
  856. if(item === 'cell-edit') { //编辑
  857. const { Value } = this.insertTargetCell;
  858. let menuInfo = this.config.contextMenuOption
  859. .find(_ => _.key==='insert-edb-calculate').children
  860. .find(menu => menu.source === JSON.parse(Value).Source);
  861. this.insertCalculateInfo = {
  862. ...menuInfo,
  863. ...this.insertTargetCell
  864. }
  865. }else {
  866. this.insertCalculateInfo = {
  867. ...item
  868. }
  869. }
  870. this.isInsertCalculate = true;
  871. this.resetDialogStatus('insertEdbCalculateVal')
  872. },
  873. /* 导入指标计算值 */
  874. insertCalculateData(item) {
  875. // console.log(item)
  876. const { InsertValue,EdbInfoId,Str,relationDate,relationUid } = item;
  877. this.insertTargetCell.DataType = 7;
  878. this.insertTargetCell.ShowValue = InsertValue;
  879. this.insertTargetCell.Value = Str;
  880. this.insertTargetCell.EdbInfoId = EdbInfoId;
  881. this.insertTargetCell.DataTime = relationDate;
  882. this.insertTargetCell.ShowFormatValue = this.insertTargetCell.ShowStyle ? transDecimalPlace(InsertValue,JSON.parse(this.insertTargetCell.ShowStyle)) : '';
  883. InsertValue ? this.$message.success(this.$t('ETable.Msg.insertion_success_msg')) : this.$message.warning(this.$t('ETable.Msg.date_no_data'))
  884. //如果有关联表格日期就建立新的关联关系
  885. if(relationDate&&relationUid) {
  886. let relation = {
  887. insert_cell: {
  888. key: this.insertTargetCell.Uid,
  889. relation_date: relationUid,
  890. relation_edb: '',
  891. }
  892. }
  893. this.setRelation(relation,7);
  894. }else { //重新插值后之后原来有关联的清除关系
  895. let haveIndex = this.insertRelationArr.findIndex(_ => _.key===this.insertTargetCell.Uid);
  896. haveIndex!==-1 && this.insertRelationArr.splice(haveIndex,1)
  897. resetRelationStyle();
  898. }
  899. },
  900. /* 日期计算弹窗 */
  901. insertDateCalculateOpen(type) {
  902. this.insertTargetCell = this.selectCell;
  903. resetDialogCellStyle()
  904. setRelationStyle({ key:this.insertTargetCell.Uid },'td-choose-insert-target')
  905. if(type === 'cell-edit') { //编辑
  906. this.insertCalculateDateInfo = {
  907. ...this.insertTargetCell
  908. }
  909. }else {
  910. this.insertCalculateDateInfo = {}
  911. }
  912. this.isInsertCalculateDate = true;
  913. this.resetDialogStatus('insertDateCalculateVal');
  914. },
  915. /* 插入日期计算值 */
  916. insertCalculateDateValue(data) {
  917. const { insertValue,str } = data;
  918. this.insertTargetCell.DataType = 8;
  919. this.insertTargetCell.ShowValue = insertValue;
  920. this.insertTargetCell.Value = str;
  921. this.insertTargetCell.EdbInfoId = 0;
  922. this.insertTargetCell.DataTime = '';
  923. this.insertTargetCell.ShowFormatValue = this.insertTargetCell.ShowStyle ? transDecimalPlace(insertValue,JSON.parse(this.insertTargetCell.ShowStyle)) : '';
  924. this.$message.success('插入成功')
  925. },
  926. /* 初始化8行5列 */
  927. initData(initData=null) {
  928. console.log('initData');
  929. this.hasInit=false
  930. if(initData) {
  931. const { CellRelation,Data } = initData;
  932. this.config.data = Data;
  933. this.insertRelationArr = JSON.parse(CellRelation);
  934. }else {
  935. this.config.data = new Array(8).fill("").map((_,_rindex) => {
  936. return new Array(5).fill("").map((cell,_cindex) => ({
  937. ShowValue: "",
  938. ShowStyle: '',
  939. ShowFormatValue: '',
  940. Value: "",
  941. DataType: 3,
  942. DataTimeType: 0,
  943. DataTime: "",
  944. EdbInfoId:0,
  945. Uid: md5.hex_md5(`${new Date().getTime()}${_rindex}${_cindex}`)
  946. }));
  947. });
  948. }
  949. this.$nextTick(()=>{
  950. this.hasInit=true
  951. })
  952. },
  953. /* 处理因数结构 =a1+b1 => [{ Tag: a,Row:1,Key:'' }] */
  954. dealFormulaConstruction(val) {
  955. // 提取因数数组
  956. let factors = extractFactorsFromFormula(val)
  957. let arr = factors.map(str => ({
  958. Tag: splitString(toUpperCase(str))[0],
  959. Row: splitString(toUpperCase(str))[1],
  960. Key: findCellKeyByFactor(str)
  961. }))
  962. return JSON.stringify(arr)
  963. },
  964. /* 要支持复制粘贴把公式也带过去 公式单元格类型为6 其余就正常复制文本 */
  965. copyCellHandle(e,cell) {
  966. this.copyCellItem = cell;
  967. // 阻止默认的复制操作
  968. e.preventDefault();
  969. },
  970. /* 要支持复制粘贴把公式也带过去 公式单元格类型为6 其余就正常复制文本 */
  971. pasteCellHandle(e,cell) {
  972. if(this.copyCellItem.DataType === 6) {
  973. cell.DataType = this.copyCellItem.DataType;
  974. cell.ShowValue = this.copyCellItem.ShowValue;
  975. cell.Value = this.copyCellItem.Value;
  976. cell.DataTime = this.copyCellItem.DataTime;
  977. cell.EdbInfoId = this.copyCellItem.EdbInfoId;
  978. cell.ShowStyle = this.copyCellItem.ShowStyle;
  979. cell.ShowFormatValue = this.copyCellItem.ShowFormatValue;
  980. }else {
  981. cell.DataType = 3;
  982. cell.ShowValue = this.copyCellItem.ShowValue;
  983. cell.Value = this.copyCellItem.ShowValue;
  984. cell.ShowStyle = this.copyCellItem.ShowStyle;
  985. cell.ShowFormatValue = this.copyCellItem.ShowFormatValue;
  986. cell.DataTime = '';
  987. cell.EdbInfoId = 0;
  988. }
  989. // 阻止默认的粘贴操作
  990. e.preventDefault();
  991. },
  992. /* 单元格enter失焦 */
  993. keyEnterHandle(e,cell) {
  994. if(e.keyCode===13) {
  995. //非得搞个要回车失焦
  996. e.target.nodeName && e.target.blur();
  997. this.$refs[`inputRef${e.target.dataset.key}`]&&this.$refs[`inputRef${e.target.dataset.key}`][0].close()
  998. // cell.DataType===6 && this.$set(cell,'CanEdit',false)
  999. // this.$set(cell,'CanEdit',false)
  1000. }
  1001. },
  1002. /* 双击切换状态 插值单元格不允许切换 可切换类型1,2,3,6*/
  1003. dblClickCellHandle(e,cell) {
  1004. if(this.disabled || ![1,2,3,6].includes(cell.DataType) || [1,2].includes(cell.DataTimeType)) return
  1005. this.$set(cell,'CanEdit',true)
  1006. console.log(cell)
  1007. this.$nextTick(() => {
  1008. if(e.target.childNodes[0].childNodes[0].childNodes[1].nodeName==='INPUT') e.target.childNodes[0].childNodes[0].childNodes[1].focus();
  1009. })
  1010. },
  1011. /* 处理保存的参数 */
  1012. getSaveParams() {
  1013. const { data } = this.config;
  1014. let params = {
  1015. CellRelation: JSON.stringify(this.insertRelationArr),
  1016. Data: data
  1017. }
  1018. return params
  1019. },
  1020. /* tab禁掉 */
  1021. handlekeyDownKeys(e) {
  1022. if(e.keyCode === 9) {
  1023. e.preventDefault();
  1024. }
  1025. },
  1026. /* 改变单元格显示文本 */
  1027. updateCellStyle({ShowStyle,ShowFormatValue}) {
  1028. this.$set(this.selectCell,'ShowStyle',ShowStyle)
  1029. this.$set(this.selectCell,'ShowFormatValue',ShowFormatValue)
  1030. }
  1031. },
  1032. };
  1033. </script>
  1034. <style scoped lang="scss">
  1035. .nodata {
  1036. text-align: center;
  1037. font-size: 16px;
  1038. color: #666;
  1039. padding: 100px 0;
  1040. }
  1041. .table-wrapper {
  1042. width: 100%;
  1043. overflow: auto;
  1044. .formula-wrapper {
  1045. height: 42px;
  1046. display: flex;
  1047. align-items: center;
  1048. background: #fff;
  1049. border-radius: 4px;
  1050. box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
  1051. border: 1px solid #DCDFE6;
  1052. margin-bottom: 15px;
  1053. padding: 0 15px;
  1054. }
  1055. .table td,th {
  1056. width: 104px;
  1057. min-width: 104px;
  1058. height: 35px;
  1059. max-height: 35px;
  1060. background: #fff;
  1061. text-align: center;
  1062. word-break: break-all;
  1063. border: 1px solid #dcdfe6;
  1064. overflow: hidden;
  1065. text-overflow: ellipsis;
  1066. position: relative;
  1067. color: #606266;
  1068. &.td-chose::after {
  1069. position: absolute;
  1070. top: 0;
  1071. left: 0;
  1072. right: 0;
  1073. bottom: 0;
  1074. content: "";
  1075. display: block;
  1076. outline: 0;
  1077. border: 2px solid #0033ff;
  1078. box-shadow: 0 0 5px rgba(73, 177, 249, 0.5);
  1079. }
  1080. &.td-relation::after {
  1081. position: absolute;
  1082. top: 0;
  1083. left: 0;
  1084. right: 0;
  1085. bottom: 0;
  1086. content: "";
  1087. display: block;
  1088. outline: 0;
  1089. border: 2px dashed #0033ff;
  1090. box-shadow: 0 0 5px rgba(73, 177, 249, 0.5);
  1091. }
  1092. &.td-col-select::after {
  1093. position: absolute;
  1094. top: 0;
  1095. left: 0;
  1096. right: 0;
  1097. bottom: 0;
  1098. content: "";
  1099. display: block;
  1100. outline: 0;
  1101. border: 1px solid rgb(24, 173, 24);
  1102. border-bottom: none;
  1103. border-top: none;
  1104. }
  1105. &.td-row-select::after {
  1106. position: absolute;
  1107. top: 0;
  1108. left: 0;
  1109. right: 0;
  1110. bottom: 0;
  1111. content: "";
  1112. display: block;
  1113. outline: 0;
  1114. border: 1px solid rgb(24, 173, 24);
  1115. border-left: none;
  1116. border-right: none;
  1117. }
  1118. &.td-choose-insert-target::after {
  1119. position: absolute;
  1120. top: 0;
  1121. left: 0;
  1122. right: 0;
  1123. bottom: 0;
  1124. content: "";
  1125. display: block;
  1126. outline: 0;
  1127. border: 2px dashed orange;
  1128. box-shadow: 0 0 5px rgba(73, 177, 249, 0.5);
  1129. }
  1130. }
  1131. .th-tg {
  1132. background: #ebeef5;
  1133. &:hover {
  1134. cursor: pointer;
  1135. background: #ddd;
  1136. /* border: 2px solid #409eff; */
  1137. }
  1138. &.sm {
  1139. width: 36px;
  1140. min-width: 36px;
  1141. max-width: 36px;
  1142. }
  1143. }
  1144. //整行选中
  1145. tr {
  1146. position: relative;
  1147. &.choose-all::after {
  1148. position: absolute;
  1149. top: 0;
  1150. left: 0;
  1151. right: 0;
  1152. bottom: 0;
  1153. content: "";
  1154. display: block;
  1155. outline: 0;
  1156. border: 2px solid #5897fb;
  1157. box-shadow: 0 0 5px rgba(73, 177, 249, 0.5);
  1158. }
  1159. }
  1160. .contextMenu-wrapper {
  1161. position: fixed;
  1162. z-index: 99;
  1163. top: -9999px;
  1164. left: -9999px;
  1165. background: #fff;
  1166. padding: 10px 0;
  1167. min-width: 180px;
  1168. max-height: 400px;
  1169. overflow-y: auto;
  1170. /* border: 1px solid #999; */
  1171. box-shadow: 0 1px 4px #999;
  1172. .item {
  1173. padding: 10px 25px;
  1174. cursor: pointer;
  1175. &:hover {
  1176. background-color: #f5f7fa;
  1177. }
  1178. &:hover .subMenu-wrapper {
  1179. display: block;
  1180. }
  1181. }
  1182. .subMenu-wrapper {
  1183. width: 180px;
  1184. /* display: none; */
  1185. padding: 10px 0;
  1186. /* box-shadow: 0 1px 4px #999; */
  1187. /* background: #fff; */
  1188. /* position: absolute;
  1189. right: -178px;
  1190. top:-205px;
  1191. max-height: 400px;
  1192. overflow-y: auto; */
  1193. .item {
  1194. &:hover {
  1195. background: #fff;
  1196. }
  1197. }
  1198. }
  1199. }
  1200. }
  1201. </style>
  1202. <style lang="scss">
  1203. .table-wrapper {
  1204. td {
  1205. .el-input__inner {
  1206. border: none;
  1207. outline: none;
  1208. text-align: center;
  1209. height: 34px;
  1210. line-height: 34px;
  1211. }
  1212. }
  1213. .el-input.is-disabled .el-input__inner {
  1214. background-color: #fff;
  1215. }
  1216. }
  1217. .formula-wrapper .el-input__inner { border: none; outline: none; }
  1218. .edb-select-popover {
  1219. width: 300px !important;
  1220. .edb-item {
  1221. display: flex;
  1222. justify-content: space-between;
  1223. align-items: center;
  1224. .edb-item-name {
  1225. max-width: 260px;
  1226. }
  1227. }
  1228. }
  1229. .el-collapse {
  1230. border: none !important;
  1231. .el-collapse-item__header {
  1232. padding: 0;
  1233. height: auto;
  1234. line-height: normal;
  1235. margin-bottom: 0 !important;
  1236. background: transparent !important;
  1237. }
  1238. .el-collapse-item__wrap {
  1239. background: transparent !important;
  1240. border: none !important;
  1241. }
  1242. .el-collapse-item__content {
  1243. padding: 0 !important;
  1244. }
  1245. }
  1246. </style>