MixedTable.vue 47 KB

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