MixedTable.vue 43 KB

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