index.blade.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. @extends('layouts.base')
  2. @section('title','中台商品管理')
  3. @section('content')
  4. <div id="app">
  5. <div class="panel panel-info">
  6. <div class="panel-heading">
  7. <span>当前位置:</span>
  8. <a href="#">
  9. <span>中台商品管理</span>
  10. </a>
  11. </div>
  12. </div>
  13. <div class="alert alert-info alert-important">
  14. <span>使用方法:</span>
  15. <span style="padding-left: 60px;">1. 下载 <a style="text-decoration: none;
  16. color: #333;" href="{{ yzWebUrl('plugin.goods-handle.backend.zt.exampleExcel') }}" >
  17. 【中台商品ID模板】
  18. </a>,填入需要导入的中台商品id</span>
  19. <span style="padding-left: 60px;">2. 上传中台商品IDExcel并确认导入</span>
  20. <span style="padding-left: 60px;">3. 导出中台商品列表进行比价</span>
  21. </div>
  22. <form id="importform" class="form-horizontal form" action="{{ yzWebUrl('plugin.goods-handle.backend.zt.index') }}"
  23. method="post" enctype="multipart/form-data">
  24. <div class='form-group'>
  25. <div class="form-group">
  26. <label class="col-sm-2 control-label must">EXCEL文件</label>
  27. <div class="col-sm-5 goodsname" style="padding-right:0;">
  28. <input type="file" name="import_zt_goods_ids" class="form-control"/>
  29. </div>
  30. </div>
  31. <div class='form-group'>
  32. <div class="col-sm-12">
  33. <div class="modal-footer">
  34. <button type="submit" class="btn btn-primary" name="cancelsend" value="yes">
  35. 导入中台商品ID
  36. </button>
  37. <a style="margin-left: 10px;" class="btn btn-primary" @click="exportZtGoodsList()">导出中台商品数据</a>
  38. </div>
  39. </div>
  40. </div>
  41. </div>
  42. </form>
  43. @section('search')
  44. <template>
  45. <!-- 表格start -->
  46. <el-table :data="goods_list" style="width: 100%" :class="table_loading==true?'loading-height':''" v-loading="table_loading" :span-method="arraySpanMethod" height="600">
  47. <el-table-column prop="p_id" label="中台商品ID" width="70" align="center"></el-table-column>
  48. </el-table-column>
  49. <el-table-column label="图片" width="60" align="center">
  50. <template slot-scope="scope">
  51. <img :src="scope.row.image_url" style="width:50px;height:50px;">
  52. </template>
  53. </el-table-column>
  54. <el-table-column label="商品名称" min-width="180" align="left" class="edit-cell">
  55. <template slot-scope="scope">
  56. [[scope.row.products_title]]
  57. </template>
  58. </el-table-column>
  59. <el-table-column label="中台商品规格ID" min-width="80" align="left" class="edit-cell">
  60. <template slot-scope="scope">
  61. [[scope.row.skus_id]]
  62. </template>
  63. </el-table-column>
  64. <el-table-column label="中台商品规格标题" min-width="120" align="left" class="edit-cell">
  65. <template slot-scope="scope">
  66. [[scope.row.skus_title]]
  67. </template>
  68. </el-table-column>
  69. <el-table-column label="供货价" max-width="80" align="center">
  70. <template slot="header" slot-scope="scope">
  71. <div style="display: flex;align-items: center;justify-content:center">
  72. <span>供货价</span>
  73. <div style="display: flex;flex-direction: column;margin-left: 5px;">
  74. <i class="el-icon-caret-top" :class="sort_price == 'asc' ? 'sort_active' : '' " @click="btnPositiveSequence('price')" ></i>
  75. <i class="el-icon-caret-bottom" :class="sort_price == 'desc' ? 'sort_active' : '' " @click="btnReverseOrder('price')"></i>
  76. </div>
  77. </div>
  78. </template>
  79. <template slot-scope="scope">
  80. ¥[[scope.row.price /100]]
  81. </template>
  82. </el-table-column>
  83. <el-table-column prop='' label="成本价" width="80" align="center">
  84. <template slot-scope="scope">
  85. ¥[[scope.row.cost_price /100]]
  86. </template>
  87. </el-table-column>
  88. <el-table-column prop='' label="零售价" width="80" align="center">
  89. <template slot-scope="scope">
  90. ¥[[scope.row.origin_price /100]]
  91. </template>
  92. </el-table-column>
  93. <el-table-column prop='' label="指导价" width="80" align="center">
  94. <template slot-scope="scope">
  95. ¥[[scope.row.guide_price /100]]
  96. </template>
  97. </el-table-column>
  98. <el-table-column prop='' label="营销价" width="80" align="center">
  99. <template slot-scope="scope">
  100. ¥[[scope.row.activity_price /100]]
  101. </template>
  102. </el-table-column>
  103. <el-table-column prop="member_num" label="利润率" width="80" align="center">
  104. <template slot-scope="scope" >
  105. <div v-if="scope.row.price != 0"> [[((scope.row.guide_price - scope.row.price)* 100 /scope.row.guide_price).toFixed(2)]]% </div>
  106. <div v-else>0%</div>
  107. </template>
  108. </el-table-column>
  109. <el-table-column label="库存" align="center" max-width="80">
  110. <template slot="header" slot-scope="scope">
  111. <div style="display: flex;align-items: center;justify-content:center">
  112. <span>库存</span>
  113. <div style="display: flex;flex-direction: column;margin-left: 5px;">
  114. <i class="el-icon-caret-top" :class="sort_stock == 'asc' ? 'sort_active' : '' " @click="btnPositiveSequence('stock')" ></i>
  115. <i class="el-icon-caret-bottom" :class="sort_stock == 'desc' ? 'sort_active' : '' " @click="btnReverseOrder('stock')"></i>
  116. </div>
  117. </div>
  118. </template>
  119. <template slot-scope="scope">
  120. [[scope.row.stock]]
  121. </template>
  122. </el-table-column>
  123. <el-table-column prop="real_sales" label="销量" max-width="80" align="center">
  124. <template slot="header" slot-scope="scope">
  125. <div style="display: flex;align-items: center;justify-content:center">
  126. <span>销量</span>
  127. <div style="display: flex;flex-direction: column;margin-left: 5px;">
  128. <i class="el-icon-caret-top" :class="sort_sales == 'asc' ? 'sort_active' : '' " @click="btnPositiveSequence('sales')" ></i>
  129. <i class="el-icon-caret-bottom" :class="sort_sales == 'desc' ? 'sort_active' : '' " @click="btnReverseOrder('sales')"></i>
  130. </div>
  131. </div>
  132. </template>
  133. <template slot-scope="scope">
  134. [[scope.row.sales]]
  135. </template>
  136. </el-table-column>
  137. <el-table-column prop='brand_name' label="品牌" width="80" align="center">
  138. <template slot-scope="scope">
  139. [[scope.row.brand_name]]
  140. </template>
  141. </el-table-column>
  142. <el-table-column prop='supplier_name' label="供应渠道" width="80" align="center">
  143. <template slot-scope="scope">
  144. [[scope.row.supplier_name]]
  145. </template>
  146. </el-table-column>
  147. </el-table>
  148. <!-- 表格end -->
  149. </template>
  150. @show
  151. <div class="vue-page" v-show="total>1">
  152. <el-row>
  153. <el-col align="right">
  154. <el-pagination layout="total, sizes, prev, pager, next, jumper" @size-change="setPageSize" @current-change="search" :total="total" :page-sizes="[15,30,50, 100]" :page-size="per_size" :current-page="current_page" background v-loading="loading"></el-pagination>
  155. </el-col>
  156. </el-row>
  157. </div>
  158. </div>
  159. <script type="text/javascript">
  160. var app = new Vue({
  161. el: "#app",
  162. delimiters: ['[[', ']]'],
  163. data(){
  164. return{
  165. ztIds:<?php echo $ztIds;?>,
  166. goods_list: [],
  167. sort_price:"",
  168. sort_stock:"",
  169. sort_sales:"",
  170. needMergeArr: ['p_id','image_url', 'products_title'], // 有合并项的列(首列ID 和 第二列姓名)
  171. rowMergeArrs: {}, // 包含需要一个或多个合并项信息的对象
  172. multipleSelection:[],
  173. total:0,
  174. per_size:15,
  175. current_page:0,
  176. loading:false,
  177. }
  178. },
  179. created() {
  180. this.getData(1);
  181. },
  182. methods: {
  183. getData(page) {
  184. var that = this;
  185. that.table_loading = true;
  186. let json = {
  187. ztIds: this.ztIds,
  188. }
  189. let loading = this.$loading({
  190. lock: true,
  191. text: 'Loading',
  192. spinner: 'el-icon-loading',
  193. background: 'rgba(0, 0, 0, 0.7)'
  194. });
  195. that.$http.post("{!! yzWebFullUrl('plugin.goods-handle.backend.zt.getZtGoods') !!}", {search:json,page:page}).then(response => {
  196. if (response.data.result == 1) {
  197. that.goods_list = response.data.data.goods_list.data;
  198. let arr = [];
  199. that.goods_list.forEach((item, index) => {
  200. item.title = that.escapeHTML(item.title)
  201. arr.push(Object.assign({}, item, {is_choose: 0}))//是否选中
  202. });
  203. that.goods_list = arr;
  204. that.total = response.data.data.goods_list.total;
  205. that.current_page = response.data.data.goods_list.current_page;
  206. that.per_size = response.data.data.goods_list.per_page;
  207. that.rowMergeArrs = this.rowMergeHandle(that.needMergeArr, that.goods_list); // 处理数据
  208. } else {
  209. that.$message.error(response.data.msg);
  210. }
  211. loading.close();
  212. that.table_loading = false;
  213. }), function (res) {
  214. console.log(res);
  215. that.table_loading = false;
  216. };
  217. },
  218. // 字符转义
  219. escapeHTML(a) {
  220. a = "" + a;
  221. return a.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, "\"").replace(/&apos;/g, "'");
  222. ;
  223. },
  224. arraySpanMethod({ row, column, rowIndex, columnIndex }) {
  225. // 没办法循环判断具体是那一列 所以就只好写了多个if
  226. if (column.property === 'p_id') return this.mergeAction('p_id', rowIndex, column);
  227. if (column.property === 'products_title') return this.mergeAction('products_title', rowIndex, column);
  228. if (column.property === 'image_url') return this.mergeAction('image_url', rowIndex, column);
  229. },
  230. mergeAction(val, rowIndex, colData) { // 参数 val 为 "name" 或者"id"
  231. let _row = this.rowMergeArrs[val].rowArr[rowIndex];
  232. let _col = _row > 0 ? 1 : 0;
  233. return [_row, _col];
  234. },
  235. rowMergeHandle(arr, data) { //arr: ['name', 'id'] data为tableData
  236. if (!Array.isArray(arr) && !arr.length) return false;
  237. if (!Array.isArray(data) && !data.length) return false;
  238. let needMerge = {};
  239. arr.forEach(i => { // i 为 "name" 或者 "id"
  240. needMerge[i] = {
  241. rowArr: [],
  242. rowMergeNum: 0
  243. };
  244. data.forEach((item, index) => { // item: { id: '122', name: '王小虎', amount1: '539', amount2: '4.1', amount3: 15 }
  245. /* item 为表格每一项的数据 ,index 为表格数据索引 */
  246. // 表格首个数据单独处理
  247. if (index === 0) {
  248. needMerge[i].rowArr.push(1);
  249. needMerge[i].rowMergeNum = 0;
  250. } else {
  251. // 如果后一项与前一项相等,只用改变 rowArr 数组,不用管 rowMergeNum 数值
  252. if (item[i] === data[index - 1][i]) { // 后一项name与前一项name对比
  253. needMerge[i].rowArr[needMerge[i].rowMergeNum] += 1; //此处是 rowMergeNum 属性存在的意义,就是为了定位要改变的数值
  254. needMerge[i].rowArr.push(0);
  255. }
  256. //如果后一项与前一项不相等,rowArr、rowMergeNum都改变
  257. else {
  258. needMerge[i].rowArr.push(1);
  259. needMerge[i].rowMergeNum = index;
  260. }
  261. }
  262. });
  263. });
  264. return needMerge;
  265. },
  266. exportZtGoodsList() {
  267. //this.$refs.multipleTable.toggleRowSelection(this.goods_list[index],true); //row 选中
  268. var ztIds=this.ztIds;
  269. var data={ztIds:ztIds};
  270. var url = '{!! yzWebFullUrl('plugin.goods-handle.backend.zt.exportZtGoodsList') !!}';
  271. const loading = this.$loading({ target: '.loading-area' })
  272. axios({
  273. method:'post',
  274. url: url, // 请求地址
  275. data: data, // 参数
  276. responseType: 'blob', // 表明返回服务器返回的数据类型
  277. headers: {
  278. 'Content-Type': 'application/json'
  279. }
  280. }).then(res => {
  281. loading.close()
  282. const blob = new Blob([res.data], {
  283. type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;"
  284. });
  285. const downloadElement = document.createElement("a");
  286. const href = window.URL.createObjectURL(blob);
  287. const filename = "中台商品数据"
  288. downloadElement.href = href;
  289. downloadElement.download = filename + '.xlsx'; //命名下载名称
  290. downloadElement.click();
  291. window.URL.revokeObjectURL(href); //下载完成进行释放
  292. })
  293. },
  294. search(val) {
  295. this.getData(val);
  296. },
  297. setPageSize(val) {
  298. let refresh = val !== this.per_size;
  299. this.per_size = val;
  300. if (refresh) {
  301. this.search(1);
  302. }
  303. },
  304. }
  305. })
  306. </script>
  307. @endsection('content')