billgenerated.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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
  9. style="width: 100%"
  10. @selection-change="handleSelectionChange"
  11. @row-click="rowClick"
  12. :row-style="rowStyle"
  13. :row-class-name="rowClassName" >
  14. <el-table-column type="selection" width="55" />
  15. <el-table-column prop="lineNo" label="行号" width="50px" >
  16. <template slot-scope="scope">
  17. <span>{{Number(scope.$index) + 1}}</span>
  18. </template>
  19. </el-table-column>
  20. <el-table-column label="账单" prop="accStatus" width="60px" >
  21. <template slot-scope="{ row }">
  22. <span>{{row.accStatus?'是':'否'}}</span>
  23. </template>
  24. </el-table-column>
  25. <el-table-column label="往来单位" prop="corpCnName" width="160px" >
  26. <template slot-scope="{ row }">
  27. <el-tooltip class="item" effect="dark" :content="row.corpCnName" placement="top">
  28. <span class="textHide">{{row.corpCnName}}</span>
  29. </el-tooltip>
  30. </template>
  31. </el-table-column>
  32. <el-table-column label="费用简称" prop="feeCnName" width="120px" />
  33. <el-table-column label="预付/到付" prop="paymode" width="120px" />
  34. <el-table-column label="计量单位" prop="unitNo" width="120px" />
  35. <el-table-column label="币种" prop="curCode" width="120px" />
  36. <el-table-column label="汇率" prop="exrate" width="100px" />
  37. <el-table-column label="单价" prop="price" width="120px" />
  38. <el-table-column label="数量" prop="quantity" width="120px" />
  39. <el-table-column label="CNY(含税)" prop="rmbAmount" width="100px" />
  40. <el-table-column label="USD(含税)" prop="usdAmount" width="100px" />
  41. <el-table-column label="CNY(净额)" prop="rmbAmountNet" width="100px" />
  42. <el-table-column label="USD(净额)" prop="rmbAmountNet" width="100px" />
  43. <el-table-column label="核算要素" prop="elementsCnName" width="120px" />
  44. <el-table-column label="付费申请金额" prop="appliedAmount" width="120px" />
  45. <el-table-column label="发票申请金额" prop="appliedInvoiceAmount" width="120px" />
  46. <el-table-column label="已开票金额" prop="uninvoicedAmount" width="120px" />
  47. <el-table-column label="已结算金额" prop="stlTtlAmount" width="120px" />
  48. <el-table-column label="备注" prop="remarks" width="100px" />
  49. <el-table-column label="单价是否含税" prop="isTax" width="120px" >
  50. <template slot-scope="{row}">
  51. <span>{{row.isTax?'是':'否'}}</span>
  52. </template>
  53. </el-table-column>
  54. </el-table>
  55. </div>
  56. </template>
  57. <script>
  58. export default {
  59. props:{
  60. tableData:{
  61. type:Array,
  62. default:[]
  63. },
  64. handleSelectionData:{
  65. type:Array,
  66. default: []
  67. }
  68. },
  69. data(){
  70. return {
  71. }
  72. },
  73. methods:{
  74. // 表头样式
  75. tableHeaderCellStyle({row,column,rowIndex, columnIndex}){
  76. return "padding:4px 0px;fontSize:12px;color:#000;background:#ecf5ff"
  77. },
  78. // 列表多选
  79. // 多选选择的数据
  80. handleSelectionChange(arr){
  81. this.$emit('handleSelectionChange',arr)
  82. },
  83. // 监听点击表格事件
  84. rowClick(row, column, event) {
  85. let refsElTable = this.$refs.tableRef; // 获取表格对象
  86. if (this.CtrlDown) {
  87. refsElTable.toggleRowSelection(row); // ctrl多选 如果点击两次同样会取消选中
  88. return;
  89. }
  90. if ( this.shiftOrAltDown && this.handleSelectionData.length > 0) {
  91. // 通过rowIndex判断已选择的行中最上面和最下面的是哪行,再对比按住shift/alt点击的当前行得到新的最上面和最下面的行,把这两行中间的行进行循环选中。
  92. let topAndBottom = this.getTopAndBottom( row, this.bottomSelectionRow, this.topSelectionRow );
  93. refsElTable.clearSelection(); //先清空 不然会导致在这两行中间之外的行状态不变
  94. for (let index = topAndBottom.top; index <= topAndBottom.bottom; index++) { //选中两行之间的所有行
  95. refsElTable.toggleRowSelection(this.tableData[index], true);
  96. }
  97. } else {
  98. let findRow = this.handleSelectionData.find(c => c.rowIndex == row.rowIndex); //找出当前选中行
  99. //如果只有一行且点击的也是这一行则取消选择 否则清空再选中当前点击行
  100. if (findRow&& this.handleSelectionData.length === 1 ) {
  101. refsElTable.toggleRowSelection(row, false);
  102. return;
  103. }
  104. // refsElTable.clearSelection(); // 清空之前选择的数据(如果放开,选择之前会变成单选)
  105. refsElTable.toggleRowSelection(row); // 调用选中行方法
  106. }
  107. },
  108. // 行的 style 的回调方法
  109. rowStyle({row,rowIndex}) {
  110. // 直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
  111. // object: 要添加或者修改属性的目标对象;prop: 要定义或修改属性的名称;descript: 是一个对象,里面是我们上述的对象属性的特性;
  112. Object.defineProperty(row, 'rowIndex', { //给每一行添加不可枚举属性rowIndex来标识当前行
  113. value: rowIndex, // 设置age的值,不设置的话默认为undefined
  114. writable: true, // 表示属性的值true可以修改,false不可以被修改
  115. enumerable: false, // 设置为false表示不能通过 for-in 循环返回
  116. // configurable: false, // configurable 设置为 false,意味着这个属性不能从对象上删除
  117. })
  118. },
  119. keyDown(event) {
  120. let key = event.keyCode;
  121. if (key == 17) this.CtrlDown = true;
  122. if (key == 16 || key == 18) this.shiftOrAltDown = true;
  123. },
  124. keyUp(event) {
  125. let key = event.keyCode;
  126. if (key == 17) this.CtrlDown = false;
  127. if (key == 16 || key == 18) this.shiftOrAltDown = false;
  128. },
  129. // 文章说明 https://www.jianshu.com/p/48f2c522d2a2
  130. getTopAndBottom(row, bottom, top){
  131. let n = row.rowIndex,
  132. mx = bottom.rowIndex,
  133. mi = top.rowIndex;
  134. if (n > mx) {
  135. return {
  136. top: mi,
  137. bottom: n
  138. };
  139. } else if (n < mx && n > mi) {
  140. return {
  141. top: mi,
  142. bottom: n
  143. };
  144. } else if (n < mi) {
  145. return {
  146. top: n,
  147. bottom: mx
  148. };
  149. } else if (n == mi || n == mx) {
  150. return {
  151. top: mi,
  152. bottom: mx
  153. };
  154. }
  155. },
  156. // 给选中行加上current-row这个class类,所以要使用row-class-name这个属性(其实给每一行添加rowIndex也可以用这个属性),
  157. // 判断方式也是通过判断rowIndex对比
  158. rowClassName({ row, rowIndex }) {
  159. let rowName = "",
  160. findRow = this.handleSelectionData.find(c => c.rowIndex === row.rowIndex);
  161. if (findRow) {
  162. rowName = "current-row "; // elementUI 默认高亮行的class类 不用再样式了^-^,也可通过css覆盖改变背景颜色
  163. }
  164. return rowName; //也可以再加上其他类名 如果有需求的话
  165. },
  166. },
  167. mounted() {
  168. // 按住ctrl实现多选 设置监听keydown事件,以及keyup事件,
  169. addEventListener("keydown", this.keyDown, false);
  170. addEventListener("keyup", this.keyUp, false);
  171. },
  172. beforeDestroy() { //解绑
  173. removeEventListener("keydown", this.keyDown);
  174. removeEventListener("keyup", this.keyUp);
  175. },
  176. computed: { //实时得到最上行和最下行
  177. bottomSelectionRow() {
  178. if (this.handleSelectionData.length == 0) return null;
  179. return this.handleSelectionData.reduce((start, end) => {
  180. return start.rowIndex > end.rowIndex ? start : end;
  181. });
  182. },
  183. topSelectionRow() {
  184. if (this.handleSelectionData.length == 0) return null;
  185. return this.handleSelectionData.reduce((start, end) => {
  186. return start.rowIndex < end.rowIndex ? start : end;
  187. });
  188. }
  189. },
  190. }
  191. </script>
  192. <style scoped>
  193. .textHide {
  194. width: 100%;
  195. overflow: hidden;
  196. white-space: nowrap;
  197. text-overflow: ellipsis;
  198. }
  199. </style>