fromtableDetails.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. <template>
  2. <div>
  3. <el-table
  4. ref="tableRef"
  5. :cell-style="{ padding: '0px', fontSize: '12px' }"
  6. :header-cell-style="tableHeaderCellStyle"
  7. :data="tableData"
  8. :border="true"
  9. show-summary
  10. :summary-method="summaryMethod"
  11. style="width: 100%"
  12. @selection-change="handleSelectionChange"
  13. @row-click="rowClick"
  14. :row-style="rowStyle"
  15. :row-class-name="rowClassName"
  16. >
  17. <el-table-column fixed="left" type="selection" width="50" align="center"></el-table-column>
  18. <el-table-column type="index" width="40" align="center"> </el-table-column>
  19. <el-table-column prop="descr" label="摘要" min-width="150px" style="padding: 0" align="center">
  20. <template slot-scope="{ row }">
  21. <el-input
  22. style="width: 100%"
  23. type="text"
  24. v-model="row.descr"
  25. size="small"
  26. autocomplete="off"
  27. clearable
  28. placeholder="请输入摘要"
  29. :disabled="disabled"
  30. >
  31. </el-input>
  32. </template>
  33. </el-table-column>
  34. <el-table-column prop="accountCode" label="科目代码" width="360px">
  35. <template slot-scope="{ row }">
  36. <div style="display: flex; align-items: center; justify-content: space-between">
  37. <search-query
  38. v-if="!isARAPRow(row)"
  39. style="width: 100%"
  40. :datalist="accountData"
  41. :selectValue="row.accountCode"
  42. :filterable="true"
  43. :clearable="true"
  44. :remote="true"
  45. :buttonIf="false"
  46. :desc="true"
  47. :forParameter="{ key: 'code', label: 'code', value: 'code', desc: 'fullName' }"
  48. :disabled="disabled"
  49. @corpFocus="accountsListfun"
  50. @remoteMethod="accountsListfun"
  51. @corpChange="corpChange($event, 'accountId', row)"
  52. >
  53. </search-query>
  54. <span v-if="isARAPRow(row)">{{row.accountCode}}</span>
  55. <el-tooltip
  56. v-if="!disabled && (row.isEmpl === 1 || row.isCorp === 1 || row.isDept === 1 || row.isItem === 1) && !isARAPRow(row)"
  57. class="item"
  58. effect="dark"
  59. content="核算项目"
  60. placement="top"
  61. >
  62. <el-button size="mini" type="primary" icon="el-icon-edit" circle @click="auxiliaryAccountingfun(row)" :disabled="disabled"></el-button>
  63. </el-tooltip>
  64. <el-tooltip v-if="!disabled && row.isDc === 1" class="item" effect="dark" content="预收/预付核销" placement="top">
  65. <el-button size="mini" type="primary" icon="el-icon-scissors" circle @click="showOffRecordsfun(row)" :disabled="disabled"></el-button>
  66. </el-tooltip>
  67. </div>
  68. <div style="display: flex">
  69. <span>{{
  70. (row.accountCnName ? row.accountCnName : " ") +
  71. (row.isEmpl === 1 && row.emplName ? "/" + row.emplName : "") +
  72. (row.isDept === 1 && row.deptName ? "/" + row.deptName : "") +
  73. (row.isCorp === 1 && row.corpShortName ? "/" + row.corpShortName : "") +
  74. (row.isItem === 1 ? "/" + row.itemClassify + "-" + (row.itemName ? row.itemName : "") : "")
  75. }}</span>
  76. </div>
  77. </template>
  78. </el-table-column>
  79. <el-table-column prop="dc" label="方向" min-width="45px" style="padding: 0" align="center">
  80. <template slot-scope="{ row }">
  81. <span>{{ row.dc == "D" ? "借" : "贷" }}</span>
  82. </template>
  83. </el-table-column>
  84. <el-table-column label="本币金额">
  85. <el-table-column prop="amountDr" label="借方" min-width="90px" align="center">
  86. <template slot-scope="{ row }">
  87. <el-input-number
  88. v-if="!isARAPRow(row)"
  89. style="width: 100%"
  90. v-model="row.amountDr"
  91. size="small"
  92. autocomplete="off"
  93. :disabled="row.curCode !== 'CNY' || !row.accountId || disabled"
  94. placeholder="请输入借方"
  95. :precision="2"
  96. @change="amountBlur(row, 'D')"
  97. @keydown.native="handleKeydown($event, row, 'amountDr')"
  98. :controls="false"
  99. >
  100. </el-input-number>
  101. <span v-else>{{ fmtAmt(row.amountDr, 2) }}</span>
  102. </template>
  103. </el-table-column>
  104. <el-table-column prop="amountCr" label="货方" min-width="90px" align="center">
  105. <template slot-scope="{ row }">
  106. <el-input-number
  107. v-if="!isARAPRow(row)"
  108. style="width: 100%"
  109. v-model="row.amountCr"
  110. size="small"
  111. autocomplete="off"
  112. :disabled="row.curCode !== 'CNY' || !row.accountId || disabled"
  113. placeholder="请输入货方"
  114. :precision="2"
  115. @change="amountBlur(row, 'C')"
  116. @keydown.native="handleKeydown($event, row, 'amountCr')"
  117. :controls="false"
  118. >
  119. </el-input-number>
  120. <span v-else>{{ fmtAmt(row.amountCr, 2) }}</span>
  121. </template>
  122. </el-table-column>
  123. </el-table-column>
  124. <el-table-column label="外币金额">
  125. <el-table-column prop="curCode" label="币种" min-width="60px" align="center"> </el-table-column>
  126. <el-table-column prop="exrate" label="汇率" min-width="80px" align="center">
  127. <template slot-scope="{ row }">
  128. <el-input-number
  129. v-if="row.curCode === 'USD' && !isARAPRow(row)"
  130. style="width: 100%"
  131. v-model="row.exrate"
  132. size="small"
  133. autocomplete="off"
  134. clearable
  135. placeholder="请输入借方"
  136. :precision="4"
  137. @change="amountBlur(row, 'exrate')"
  138. :disabled="disabled"
  139. :controls="false"
  140. >
  141. </el-input-number>
  142. <span v-else-if="row.curCode === 'USD'">{{ fmtAmt(row.exrate, 2) }}</span>
  143. <span v-else></span>
  144. </template>
  145. </el-table-column>
  146. <el-table-column prop="amountDrUsd" label="借方" min-width="90px" align="center">
  147. <template slot-scope="{ row }">
  148. <el-input-number
  149. v-if="row.curCode === 'USD' && row.changeMode !== 'd' && !isARAPRow(row)"
  150. style="width: 100%; text-align: right"
  151. v-model="row.amountDrUsd"
  152. size="small"
  153. autocomplete="off"
  154. :disabled="row.curCode === 'CNY' || !row.accountId || disabled"
  155. clearable
  156. placeholder="请输入借方"
  157. :precision="2"
  158. @change="amountUSDBlur(row, 'Dusd')"
  159. :controls="false"
  160. >
  161. </el-input-number>
  162. <span v-else>{{ fmtAmt(row.amountDrUsd, 2) }}</span>
  163. </template>
  164. </el-table-column>
  165. <el-table-column prop="amountCrUsd" label="货方" min-width="90px" align="center">
  166. <template slot-scope="{ row }">
  167. <el-input-number
  168. v-if="row.curCode === 'USD' && row.changeMode !== 'd' && !isARAPRow(row)"
  169. style="width: 100%"
  170. v-model="row.amountCrUsd"
  171. size="small"
  172. autocomplete="off"
  173. :disabled="row.curCode === 'CNY' || !row.accountId || disabled"
  174. clearable
  175. placeholder="请输入货方"
  176. :precision="2"
  177. @change="amountUSDBlur(row, 'Cusd')"
  178. :controls="false"
  179. >
  180. </el-input-number>
  181. <span v-else>{{ fmtAmt(row.amountCrUsd, 2) }}</span>
  182. </template>
  183. </el-table-column>
  184. </el-table-column>
  185. <!--
  186. <el-table-column prop="remarks" label="备注" width="200px">
  187. <template slot-scope="{ row }">
  188. <el-input
  189. style="width: 100%;"
  190. type="textarea"
  191. v-model="row.remarks"
  192. size="small"
  193. autocomplete="off"
  194. clearable
  195. placeholder="请输入备注"
  196. :disabled="disabled"
  197. >
  198. </el-input>
  199. </template>
  200. </el-table-column>
  201. -->
  202. <el-table-column v-if="!disabled" label="操作" fixed="right" width="100px">
  203. <template slot-scope="scope">
  204. <el-tooltip class="item" effect="dark" content="添加" placement="top">
  205. <el-button
  206. size="mini"
  207. type="primary"
  208. icon="el-icon-plus"
  209. circle
  210. @click="addRowsfun(scope.row, scope.$index)"
  211. :disabled="disabled"
  212. ></el-button>
  213. </el-tooltip>
  214. <el-tooltip v-if="!isARAPRow(scope.row)" class="item" effect="dark" :content="scope.row.changeMode === 'd' ? '恢复' : '删除'" placement="top">
  215. <el-button
  216. size="mini"
  217. type="danger"
  218. icon="el-icon-delete"
  219. circle
  220. @click="deletefun(scope.row, scope.$index)"
  221. :disabled="disabled"
  222. ></el-button>
  223. </el-tooltip>
  224. </template>
  225. </el-table-column>
  226. </el-table>
  227. </div>
  228. </template>
  229. <script>
  230. import SearchQuery from "@/components/iosbasic-data/searchquery.vue";
  231. import { accountsList } from "@/api/iosBasicData/accounts";
  232. import { bcurrencyGetExrate } from "@/api/iosBasicData/rateManagement";
  233. import { dateFormat } from "@/util/date";
  234. export default {
  235. components: { SearchQuery },
  236. data() {
  237. return {
  238. accountData: [] // 科目数据
  239. };
  240. },
  241. props: {
  242. assemblyForm: {
  243. type: Object,
  244. default: {}
  245. },
  246. tableData: {
  247. type: Array,
  248. default: []
  249. },
  250. handleSelectionData: {
  251. type: Array,
  252. default: []
  253. },
  254. disabled: {
  255. type: Boolean,
  256. default: false
  257. }
  258. },
  259. async created() {
  260. this.accountsListfun();
  261. // this.option = await this.getColumnData(this.getColumnName(321.1), this.optionBack);
  262. },
  263. methods: {
  264. forceNumber(s, d) {
  265. let N = Number(s);
  266. return isNaN(N) ? 0.0 : Number(N.toFixed(d ? d : 2));
  267. },
  268. fmtAmt(value, d){
  269. let N = this.forceNumber(value, d).toFixed(d);
  270. return N === '0.00' ? '' : N;
  271. },
  272. // 自定义合计
  273. summaryMethod(param) {
  274. const { columns, data } = param;
  275. const sums = [];
  276. columns.forEach((column, index) => {
  277. if (index === 2) {
  278. sums[index] = "合计";
  279. return;
  280. }
  281. const values = data.map(item => (item.changeMode === "d" ? 0.0 : Number(item[column.property])));
  282. // 显示列的统计 金额
  283. let arr = ["amountDr", "amountCr", "amountDrUsd", "amountCrUsd"];
  284. // 判断是否有这个数据
  285. if (arr.indexOf(column.property) != -1) {
  286. if (!values.every(value => isNaN(value))) {
  287. sums[index] = values.reduce((prev, curr) => {
  288. const value = Number(curr);
  289. if (!isNaN(value)) {
  290. return prev + curr;
  291. } else {
  292. return prev;
  293. }
  294. }, 0);
  295. sums[index] = sums[index].toFixed(2); // 把合计的参数保留两位小数
  296. // sums[index] += " 元";
  297. } else {
  298. sums[index] = " ";
  299. }
  300. }
  301. });
  302. return sums;
  303. },
  304. isARAPRow(row) {
  305. let code = row && row.accountCode ? row.accountCode : "";
  306. return code.startsWith("1141") || code.startsWith("2121")
  307. },
  308. handleKeydown(e, row, name) {
  309. console.log("handleKeydown", e, name);
  310. if (e.key === "=") {
  311. e.preventDefault();
  312. // amountDr,amountCr
  313. let amtDr = 0.0,
  314. amtCr = 0.0;
  315. this.tableData.forEach(item => {
  316. if (item !== row) {
  317. amtDr = this.forceNumber(amtDr + this.forceNumber(item.amountDr, 2), 2);
  318. amtCr = this.forceNumber(amtCr + this.forceNumber(item.amountCr, 2), 2);
  319. }
  320. });
  321. console.log("amtDr", amtDr, "amtCr", amtCr);
  322. if (name === "amountDr") {
  323. this.$set(row, "amountCr", 0.0);
  324. this.$set(row, name, this.forceNumber(amtCr - amtDr, 2));
  325. }
  326. if (name === "amountCr") {
  327. this.$set(row, "amountDr", 0.0);
  328. this.$set(row, name, this.forceNumber(amtDr - amtCr, 2));
  329. }
  330. if (row.curCode === "USD") {
  331. this.$set(row, "exrate", this.forceNumber(row.exrate, 4));
  332. if (row.exrate.toFixed(4) === "0.0000") {
  333. this.$set(row, "exrate", 1);
  334. }
  335. this.$set(row, "amountDrUsd", this.forceNumber(this.forceNumber(row.amountDr, 2) / row.exrate, 2));
  336. this.$set(row, "amountCrUsd", this.forceNumber(this.forceNumber(row.amountCr, 2) / row.exrate, 2));
  337. }else{
  338. this.$set(row, "exrate", 1);
  339. this.$set(row, "amountDrUsd", 0.00);
  340. this.$set(row, "amountCrUsd", 0.00);
  341. }
  342. }
  343. },
  344. // 借方/贷方 本币的计算
  345. amountBlur(row, name) {
  346. console.log("amountBlur", row, name);
  347. if (name == "D") {
  348. this.$set(row, "amountCr", 0);
  349. }
  350. if (name == "C") {
  351. this.$set(row, "amountDr", 0);
  352. }
  353. // if (name == 'Dusd') {
  354. // this.$set(row,'amountCrUsd',0)
  355. // }
  356. // if (name == 'Cusd') {
  357. // this.$set(row,'amountDrUsd',0)
  358. // }
  359. if (row.curCode == "USD") {
  360. this.$set(row, "exrate", row.exrate ? Number(row.exrate) : 1);
  361. this.$set(row, "amountCr", row.amountCr ? Number(row.amountCr) : 0);
  362. this.$set(row, "amountDr", row.amountDr ? Number(row.amountDr) : 0);
  363. this.$set(row, "amountCrUsd", (row.amountCr / row.exrate).toFixed(2));
  364. this.$set(row, "amountDrUsd", (row.amountDr / row.exrate).toFixed(2));
  365. }
  366. // 合计本位币
  367. this.$set(row, "amountDrLoc", row.amountDr);
  368. this.$set(row, "amountCrLoc", row.amountCr);
  369. },
  370. // 外币的计算
  371. amountUSDBlur(row, name) {
  372. console.log("amountUSDBlur", row, name);
  373. if (name == "Dusd") {
  374. this.$set(row, "amountCrUsd", 0);
  375. }
  376. if (name == "Cusd") {
  377. this.$set(row, "amountDrUsd", 0);
  378. }
  379. this.$set(row, "exrate", row.exrate ? Number(row.exrate) : 1);
  380. this.$set(row, "amountCrUsd", row.amountCrUsd ? Number(row.amountCrUsd) : 0);
  381. this.$set(row, "amountDrUsd", row.amountDrUsd ? Number(row.amountDrUsd) : 0);
  382. this.$set(row, "amountCr", (row.amountCrUsd * row.exrate).toFixed(2));
  383. this.$set(row, "amountDr", (row.amountDrUsd * row.exrate).toFixed(2));
  384. // 合计本位币
  385. this.$set(row, "amountDrLoc", (row.amountDrUsd * row.exrate).toFixed(2));
  386. this.$set(row, "amountCrLoc", (row.amountCrUsd * row.exrate).toFixed(2));
  387. },
  388. // 获取科目类型数据
  389. accountsListfun(code) {
  390. // isManual == 1 的允许手工添加
  391. accountsList(1, 10, { code, isDetail: 1, isManual: 1 }).then(res => {
  392. console.log(res.data.data.records);
  393. this.accountData = res.data.data.records;
  394. });
  395. },
  396. // 行删除
  397. deletefun(row, index) {
  398. this.$emit("deletefun", row, index);
  399. },
  400. // 行添加
  401. addRowsfun(row, index) {
  402. this.$emit("addRowsfun", row, index);
  403. },
  404. // 辅助核算
  405. auxiliaryAccountingfun(row) {
  406. if (!row.accountId) {
  407. return this.$message.warning("请先选择科目代码");
  408. }
  409. this.$emit("auxiliaryAccountingfun", row);
  410. },
  411. showOffRecordsfun(row) {
  412. if (!row.accountId) {
  413. return this.$message.warning("请先选择科目代码");
  414. }
  415. if (!row.amountDr && !row.amountCr) {
  416. return this.$message.warning("请输入金额");
  417. }
  418. this.$emit("showOffRecordsfun", row);
  419. },
  420. // 下拉回调
  421. corpChange(value, name, row) {
  422. let found = false;
  423. if (name === "accountId") {
  424. for (let item of this.accountData) {
  425. console.log(item);
  426. if (item.code == value) {
  427. found = true;
  428. console.log(item, item.id);
  429. this.$set(row, "accountId", item.id);
  430. this.$set(row, "accountCode", item.code);
  431. this.$set(row, "accountCnName", item.cnName);
  432. this.$set(row, "accountEnName", item.enName);
  433. this.$set(row, "accountFullName", item.fullName);
  434. this.$set(row, "accountLevel", item.level);
  435. this.$set(row, "accountProperty", item.property);
  436. this.$set(row, "dc", item.dc);
  437. // 币种
  438. this.$set(row, "curCode", item.curCode === "USD" ? item.curCode : "CNY");
  439. // 汇率
  440. this.$set(row, "exrate", item.exrate);
  441. // 其他
  442. this.$set(row, "isForeign", item.isForeign);
  443. this.$set(row, "isQuantity", item.isQuantity);
  444. this.$set(row, "isCorp", item.isCorp);
  445. this.$set(row, "isDept", item.isDept);
  446. this.$set(row, "isEmpl", item.isEmpl);
  447. this.$set(row, "isItem", item.isItem);
  448. this.$set(row, "itemClassifyId", item.itemClassifyId);
  449. this.$set(row, "itemClassify", item.itemClassify);
  450. this.$set(row, "isDc", item.isDc);
  451. this.$set(row, "isArAp", item.isArAp);
  452. // 打开弹窗
  453. this.$emit("auxiliaryAccountingfun", row);
  454. }
  455. }
  456. if (!found) {
  457. console.log("not found");
  458. this.$set(row, "accountId", 0);
  459. this.$set(row, "accountCode", "");
  460. this.$set(row, "accountCnName", "");
  461. this.$set(row, "accountEnName", "");
  462. this.$set(row, "accountFullName", "");
  463. this.$set(row, "accountLevel", 0);
  464. this.$set(row, "accountProperty", 0);
  465. this.$set(row, "dc", "");
  466. // 币种
  467. this.$set(row, "curCode", "");
  468. // 汇率
  469. // 其他
  470. this.$set(row, "isForeign", 0);
  471. this.$set(row, "isQuantity", 0);
  472. this.$set(row, "isCorp", 0);
  473. this.$set(row, "isDept", 0);
  474. this.$set(row, "isEmpl", 0);
  475. this.$set(row, "isItem", 0);
  476. this.$set(row, "itemClassifyId", 0);
  477. this.$set(row, "itemClassify", "");
  478. this.$set(row, "isDc", 0);
  479. this.$set(row, "isArAp", 0);
  480. this.$set(row, "exrate", 0);
  481. }
  482. if (row.curCode === "USD") {
  483. bcurrencyGetExrate({
  484. date: this.assemblyForm.voucherDate
  485. ? this.assemblyForm.voucherDate.slice(0, 10) + " 00:00:00"
  486. : dateFormat(new Date(), "yyyy-MM-dd") + " 00:00:00", // 凭证日期
  487. dc: row.dc,
  488. type: 1
  489. }).then(res => {
  490. for (let item of res.data.data) {
  491. if (item.code === row.curCode) {
  492. this.$set(row, "exrate", this.forceNumber(item.exrate, 4));
  493. this.$set(row, "amountDr", this.forceNumber(row.amountDr, 2));
  494. this.$set(row, "amountCr", this.forceNumber(row.amountCr, 2));
  495. this.$set(row, "amountDrUsd", this.forceNumber(row.amountDrUsd, 2));
  496. this.$set(row, "amountCrUsd", this.forceNumber(row.amountCrUsd, 2));
  497. if (row.amountDrUsd !== 0.0) {
  498. this.$set(row, "amountCrUsd", 0.0);
  499. this.$set(row, "amountCr", 0.0);
  500. this.$set(row, "amountDr", this.forceNumber(row.amountDrUsd * item.exrate, 2));
  501. } else {
  502. this.$set(row, "amountDrUsd", 0.0);
  503. this.$set(row, "amountDr", 0.0);
  504. this.$set(row, "amountCr", this.forceNumber(row.amountCrUsd * item.exrate, 2));
  505. }
  506. }
  507. }
  508. });
  509. } else {
  510. this.$set(row, "exrate", 0);
  511. this.$set(row, "amountDrUsd", 0.0);
  512. this.$set(row, "amountCrUsd", 0.0);
  513. }
  514. }
  515. console.log(row);
  516. },
  517. // 表头样式
  518. tableHeaderCellStyle({ row, column, rowIndex, columnIndex }) {
  519. return "padding:4px 0px;fontSize:12px;color:#000;background:#ecf5ff;text-align:center";
  520. },
  521. // 列表多选
  522. // 多选选择的数据
  523. handleSelectionChange(arr) {
  524. this.$emit("handleSelectionChange", arr);
  525. },
  526. // 监听点击表格事件
  527. rowClick(row, column, event) {
  528. let refsElTable = this.$refs.tableRef; // 获取表格对象
  529. if (this.CtrlDown) {
  530. refsElTable.toggleRowSelection(row); // ctrl多选 如果点击两次同样会取消选中
  531. return;
  532. }
  533. if (this.shiftOrAltDown && this.handleSelectionData.length > 0) {
  534. // 通过rowIndex判断已选择的行中最上面和最下面的是哪行,再对比按住shift/alt点击的当前行得到新的最上面和最下面的行,把这两行中间的行进行循环选中。
  535. let topAndBottom = this.getTopAndBottom(row, this.bottomSelectionRow, this.topSelectionRow);
  536. refsElTable.clearSelection(); //先清空 不然会导致在这两行中间之外的行状态不变
  537. for (let index = topAndBottom.top; index <= topAndBottom.bottom; index++) {
  538. //选中两行之间的所有行
  539. refsElTable.toggleRowSelection(this.tableData[index], true);
  540. }
  541. } else {
  542. let findRow = this.handleSelectionData.find(c => c.rowIndex == row.rowIndex); //找出当前选中行
  543. //如果只有一行且点击的也是这一行则取消选择 否则清空再选中当前点击行
  544. if (findRow && this.handleSelectionData.length === 1) {
  545. refsElTable.toggleRowSelection(row, false);
  546. return;
  547. }
  548. // refsElTable.clearSelection(); // 清空之前选择的数据(如果放开,选择之前会变成单选)
  549. refsElTable.toggleRowSelection(row); // 调用选中行方法
  550. }
  551. },
  552. // 行的 style 的回调方法
  553. rowStyle({ row, rowIndex }) {
  554. // 直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
  555. // object: 要添加或者修改属性的目标对象;prop: 要定义或修改属性的名称;descript: 是一个对象,里面是我们上述的对象属性的特性;
  556. Object.defineProperty(row, "rowIndex", {
  557. //给每一行添加不可枚举属性rowIndex来标识当前行
  558. value: rowIndex, // 设置age的值,不设置的话默认为undefined
  559. writable: true, // 表示属性的值true可以修改,false不可以被修改
  560. enumerable: false // 设置为false表示不能通过 for-in 循环返回
  561. // configurable: false, // configurable 设置为 false,意味着这个属性不能从对象上删除
  562. });
  563. },
  564. keyDown(event) {
  565. let key = event.keyCode;
  566. if (key == 17) this.CtrlDown = true;
  567. if (key == 16 || key == 18) this.shiftOrAltDown = true;
  568. },
  569. keyUp(event) {
  570. let key = event.keyCode;
  571. if (key == 17) this.CtrlDown = false;
  572. if (key == 16 || key == 18) this.shiftOrAltDown = false;
  573. },
  574. // 文章说明 https://www.jianshu.com/p/48f2c522d2a2
  575. getTopAndBottom(row, bottom, top) {
  576. let n = row.rowIndex,
  577. mx = bottom.rowIndex,
  578. mi = top.rowIndex;
  579. if (n > mx) {
  580. return {
  581. top: mi,
  582. bottom: n
  583. };
  584. } else if (n < mx && n > mi) {
  585. return {
  586. top: mi,
  587. bottom: n
  588. };
  589. } else if (n < mi) {
  590. return {
  591. top: n,
  592. bottom: mx
  593. };
  594. } else if (n == mi || n == mx) {
  595. return {
  596. top: mi,
  597. bottom: mx
  598. };
  599. }
  600. },
  601. // 给选中行加上current-row这个class类,所以要使用row-class-name这个属性(其实给每一行添加rowIndex也可以用这个属性),
  602. // 判断方式也是通过判断rowIndex对比
  603. rowClassName({ row, rowIndex }) {
  604. let rowName = "",
  605. findRow = this.handleSelectionData.find(c => c.rowIndex === row.rowIndex);
  606. if (findRow) {
  607. rowName = "current-row "; // elementUI 默认高亮行的class类 不用再样式了^-^,也可通过css覆盖改变背景颜色
  608. }
  609. return rowName; //也可以再加上其他类名 如果有需求的话
  610. }
  611. },
  612. mounted() {
  613. // 按住ctrl实现多选 设置监听keydown事件,以及keyup事件,
  614. addEventListener("keydown", this.keyDown, false);
  615. addEventListener("keyup", this.keyUp, false);
  616. },
  617. beforeDestroy() {
  618. //解绑
  619. removeEventListener("keydown", this.keyDown);
  620. removeEventListener("keyup", this.keyUp);
  621. },
  622. computed: {
  623. //实时得到最上行和最下行
  624. bottomSelectionRow() {
  625. if (this.handleSelectionData.length == 0) return null;
  626. return this.handleSelectionData.reduce((start, end) => {
  627. return start.rowIndex > end.rowIndex ? start : end;
  628. });
  629. },
  630. topSelectionRow() {
  631. if (this.handleSelectionData.length == 0) return null;
  632. return this.handleSelectionData.reduce((start, end) => {
  633. return start.rowIndex < end.rowIndex ? start : end;
  634. });
  635. }
  636. }
  637. };
  638. </script>
  639. <style scoped>
  640. ::v-deep input::-webkit-outer-spin-button,
  641. ::v-deep input::-webkit-inner-spin-button {
  642. -webkit-appearance: none !important;
  643. }
  644. ::v-deep input[type="number"] {
  645. -moz-appearance: textfield !important;
  646. }
  647. ::v-deep .el-table td {
  648. padding: 0;
  649. }
  650. ::v-deep .el-table .cell {
  651. padding-left: 2px !important;
  652. padding-right: 2px !important;
  653. }
  654. ::v-deep .el-input-number .el-input__inner {
  655. text-align: right;
  656. }
  657. </style>