detail-2.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <template>
  2. <div id="form-1">
  3. <el-row>
  4. <!-- 自营店铺订单待发货--发货清单 -->
  5. <el-col :span="24" class="main animate__animated animate__backInRight">
  6. <el-col class="top_btn"><el-button type="primary" size="mini" @click="toBack()">返回</el-button></el-col>
  7. <el-col :span="24" class="one"> <span>发货清单</span> </el-col>
  8. <el-col class="top_btn"> <el-button type="primary" @click="toFile()">导出清单</el-button></el-col>
  9. <el-col :span="24" class="two">
  10. <el-col :span="15" v-for="(item, index) in list" :key="index">
  11. <el-card class="box-card">
  12. <el-col class="clearfix">
  13. <el-col>收货人:{{ item.address.name }},{{ item.address.phone }}</el-col>
  14. <el-col>收货人地址:{{ item.address.province }},{{ item.address.city }},{{ item.address.area }},{{ item.address.address }}</el-col>
  15. </el-col>
  16. <el-col class="two_1">
  17. <data-table
  18. :select="true"
  19. :selected="selected"
  20. @handleSelect="(e) => handleSelect(e, item.address)"
  21. rowKey="index"
  22. :usePage="false"
  23. :fields="fields"
  24. :data="item.goodsList"
  25. >
  26. </data-table>
  27. </el-col>
  28. </el-card>
  29. </el-col>
  30. </el-col>
  31. </el-col>
  32. </el-row>
  33. </div>
  34. </template>
  35. <script>
  36. const _ = require('lodash');
  37. import FileSaver from 'file-saver';
  38. const ExcelJS = require('exceljs');
  39. import { mapState, mapGetters, createNamespacedHelpers } from 'vuex';
  40. export default {
  41. name: 'form-1',
  42. props: { deliverList: { type: Array } },
  43. components: {},
  44. data: function () {
  45. return {
  46. list: [],
  47. fields: [
  48. { label: '订单编号', model: 'order_no' },
  49. { label: '商品名称', model: 'goods.name' },
  50. { label: '商品规格', model: 'name' },
  51. { label: '商品数量', model: 'buy_num' },
  52. ],
  53. selected: [],
  54. fileList: [],
  55. };
  56. },
  57. async created() {
  58. await this.search();
  59. },
  60. methods: {
  61. // 查询
  62. async search() {
  63. let data = this.deliverList;
  64. if (data) {
  65. let test = _(data).groupBy('address._id').values().value();
  66. let list = [];
  67. for (const p1 of test) {
  68. let goodsList = [];
  69. for (const p2 of p1) {
  70. if (p2.is_afterSale == false) {
  71. for (let p3 of p2.goods) {
  72. // _.pick(p3, ['goods', 'name', 'buy_num']);
  73. // let p3_2 = (({ goods, name, buy_num }) => ({ goods, name, buy_num }))(p3);
  74. let good = (({ name }) => ({ name }))(p3.goods);
  75. p3.goods = good;
  76. p3.order_no = p2.no;
  77. }
  78. goodsList.push(...p2.goods);
  79. let i = 0;
  80. for (const p4 of goodsList) {
  81. p4.index = i;
  82. i++;
  83. }
  84. }
  85. }
  86. let address = _.pick(p1[0].address, ['name', 'phone', 'province', 'city', 'area', 'address', '_id']);
  87. // let address = (({ name, phone, province, city, area, address, _id }) => ({ name, phone, province, city, area, address, _id }))(p1[0].address);
  88. list.push({ goodsList, address });
  89. }
  90. console.log(list);
  91. this.$set(this, 'list', list);
  92. }
  93. },
  94. // 选中要导出的商品
  95. handleSelect(goodsList, address) {
  96. let fileList = this.fileList;
  97. if (fileList.length == 0) {
  98. fileList.push({ goodsList, address });
  99. } else {
  100. if (goodsList.length > 0) {
  101. for (const val of fileList) {
  102. if (address._id == val.address._id) val.goodsList = goodsList;
  103. else fileList.push({ goodsList, address });
  104. }
  105. } else {
  106. let p1 = fileList.filter((i) => i.address._id != address._id);
  107. fileList = p1;
  108. }
  109. }
  110. let list = _.uniqBy(fileList, 'address._id');
  111. this.$set(this, 'fileList', list);
  112. },
  113. // 导出清单
  114. toFile() {
  115. const workbook = new ExcelJS.Workbook();
  116. let list = this.fileList;
  117. for (let [index, p1] of list.entries()) {
  118. let name = p1.address.name + index;
  119. const worksheet = workbook.addWorksheet(name);
  120. // 设置标题-start
  121. // 获取单元格位置
  122. let titleCell = worksheet.getCell('A1');
  123. // 合并单元格
  124. worksheet.mergeCells('A1:D1');
  125. // 单元格内容
  126. titleCell.value = '发货清单';
  127. worksheet.columns.forEach(function (column, i) {
  128. column.font = { size: 14 };
  129. column.width = 38;
  130. column.alignment = { wrapText: true, vertical: 'middle', horizontal: 'left' };
  131. column.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } };
  132. });
  133. // 单元格内容样式
  134. titleCell.style = {
  135. alignment: { vertical: 'middle', horizontal: 'center' },
  136. font: { size: 20, bold: true },
  137. border: { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } },
  138. };
  139. // 设置标题-end
  140. let data = [
  141. ['收获人', p1.address.name],
  142. ['联系电话', p1.address.phone],
  143. ['收货地址', p1.address.province + p1.address.city + p1.address.area + p1.address.address],
  144. ['订单号', '产品名称', '产品规格', '购买数量'],
  145. ];
  146. for (const p2 of p1.goodsList) {
  147. let p4 = [[p2.order_no, p2.goods.name, p2.name, p2.buy_num]];
  148. data.push(...p4);
  149. }
  150. const row = worksheet.getRow(1);
  151. row.height = 40;
  152. for (const val of data) {
  153. worksheet.addRow(val);
  154. }
  155. }
  156. workbook.xlsx.writeBuffer().then((buffer) => {
  157. FileSaver.saveAs(new Blob([buffer], { type: 'application/octet-stream' }), `发货清单.xlsx`);
  158. });
  159. },
  160. // 返回
  161. toBack() {
  162. this.$emit('toBack');
  163. },
  164. },
  165. computed: {
  166. data() {
  167. return this.$route.query.data;
  168. },
  169. },
  170. metaInfo() {
  171. return { title: this.$route.meta.title };
  172. },
  173. watch: {
  174. test: {
  175. deep: true,
  176. immediate: true,
  177. handler(val) {},
  178. },
  179. },
  180. };
  181. </script>
  182. <style lang="less" scoped>
  183. .main {
  184. .top_btn {
  185. margin: 0 0 10px 0;
  186. }
  187. .one {
  188. margin: 0 0 10px 0;
  189. span:nth-child(1) {
  190. font-size: 20px;
  191. font-weight: 700;
  192. margin-right: 10px;
  193. }
  194. }
  195. .two {
  196. margin: 5px 10%;
  197. .data-table {
  198. margin: 5px 0;
  199. }
  200. .clearfix {
  201. margin: 4px 0;
  202. .el-col {
  203. margin: 4px 0;
  204. }
  205. }
  206. .box-card {
  207. margin: 5px;
  208. padding: 5px 0 20px 0;
  209. }
  210. .shop {
  211. text-align: center;
  212. font-size: 18px;
  213. }
  214. .item {
  215. margin-bottom: 18px;
  216. }
  217. }
  218. }
  219. </style>