index.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. <?php
  2. use common\helpers\ComponentHelper;
  3. ComponentHelper::loadComponentView('components/com-goods-detail', \Yii::$app->controller->module->viewPath);
  4. ?>
  5. <div id="app" v-cloak>
  6. <el-card shadow="never" style="border:0;min-width: 1200px;" body-style="background-color: #f3f3f3;padding: 10px 0 0;">
  7. <div slot="header">
  8. <span>精选好货</span>
  9. </div>
  10. <div class="table-body">
  11. <el-form size="small" :inline="true" flex="dir:left cross:center">
  12. <div class="item-box" style="margin-right: 15px">
  13. <el-input clearable size="small" style="width: 200px" v-model="search.goods_name" placeholder="请输入商品名称"></el-input>
  14. </div>
  15. <div class="item-box" style="margin-right: 15px">
  16. <el-select v-model="search.cate_id" placeholder="请选择类目" clearable size="small">
  17. <el-option v-for="(item, index) in cats" :key="index" :label="item.cate_name" :value="item.third_cate_id"></el-option>
  18. </el-select>
  19. </div>
  20. <div class="item-box" flex="dir:left cross:center">
  21. <el-button size="small" type="primary" style="padding: 9px 15px !important;" @click="searchs">搜索</el-button>
  22. </div>
  23. </el-form>
  24. </div>
  25. <div class="table-body">
  26. <el-row>
  27. <el-col :xs="1" :sm="1">
  28. <el-checkbox v-model="checked" @change="allSelect">全选</el-checkbox>
  29. </el-col>
  30. <!--最新上架,本月销量,协议价,指导价,营销价,常规利润率-->
  31. <el-col :sm="2" class="search-sort" v-for="(item,key) in sort_list">
  32. <div @click="searchSort" :data-key="item.key" :data-type="item.sort" :data-index="key">
  33. <span class="">{{item.name}}</span>
  34. <span class="caret-wrapper">
  35. <i class="caret-top " :class="item.sort == 'desc' ? 'bottom-active' : ''"></i>
  36. <i class="caret-bottom" :class="item.sort == 'asc' ? 'top-active' : ''"></i>
  37. </span>
  38. </div>
  39. </el-col>
  40. <el-col :sm="8" style="text-align: right">
  41. <span style="margin-right: 20px;">已选{{ countIsSelect() }}件</span>
  42. <el-button size="mini" :disabled="btnLoading" v-loading="btnLoading" type="primary" @click="batchAdd">批量加入</el-button>
  43. </el-col>
  44. </el-row>
  45. <!--商品信息-->
  46. <el-row class="goods-list"
  47. v-loading="listLoading"
  48. v-if="list"
  49. element-loading-text="拼命加载中"
  50. element-loading-spinner="el-icon-loading"
  51. >
  52. <el-col v-for="(goods,index) in list" :sm="4" :span="8" :gutter="4" style="padding: 10px">
  53. <div class="goods-wrapper" @click="selectGoods(index)" :class="goods.is_select == true ? 'goods-select' : ''">
  54. <el-col class="goods" style="padding: 5px;">
  55. <el-col><img :src="goods.default_image" style="height: 200px;width: 100%;" width="100%"></el-col>
  56. <el-col class="ellipsis">{{goods.goods_name}}</el-col>
  57. <el-col>
  58. <el-col class="goods-price agreement_price" :span="8">
  59. <div>
  60. <div class="title">供货价</div>
  61. <div class="number price">{{goods.gonghuojia|addZero(rate)}}</div>
  62. </div>
  63. </el-col>
  64. <el-col class="goods-price rate" :span="8">
  65. <div>
  66. <div class="title">建议零售价</div>
  67. <div class="number price">{{goods.retail_price|addZero(rate)}}</div>
  68. </div>
  69. </el-col>
  70. <el-col class="goods-price rate" :span="8">
  71. <div>
  72. <div class="title">商品价格</div>
  73. <div class="number price">{{goods.price|addZero(rate)}}</div>
  74. </div>
  75. </el-col>
  76. </el-col>
  77. <el-col class="bottom-price">
  78. <el-col class="goods-action">
  79. <el-col :span="12" style="text-align: center">
  80. <div>
  81. <el-button @click="detailUrl(goods)" type="primary" plain size="mini">查看详情</el-button>
  82. </div>
  83. </el-col>
  84. <el-col :span="12" style="text-align: center">
  85. <div>
  86. <el-button type="info" disabled plain size="mini" v-if="goods.is_storage">已加入</el-button>
  87. <el-button v-else type="primary" plain @click="oneAdd(goods)" size="mini">加入选品库</el-button>
  88. </div>
  89. </el-col>
  90. </el-col>
  91. </el-col>
  92. </el-col>
  93. </div>
  94. </el-col>
  95. </el-row>
  96. <!-- 无数据 -->
  97. <el-row class="goods-list" v-loading="listLoading" v-else>
  98. <el-empty description="暂无商品"></el-empty>
  99. </el-row>
  100. <!-- 分页 -->
  101. <el-row type="flex" class="page" justify="end">
  102. <el-pagination @current-change="pagination" background layout="prev, pager, next" :page-count="pageCount" v-if="list"></el-pagination>
  103. </el-row>
  104. </div>
  105. <com-goods-detail :goods-id="goodsDetailId"></com-goods-detail>
  106. </el-card>
  107. </div>
  108. <script>
  109. const app = new Vue({
  110. el: '#app',
  111. data: {
  112. page: 1,
  113. time: [], //本地存时间,请求时不发送
  114. search: {
  115. goods_name: '',
  116. cate_id: '',
  117. goods_type: '',
  118. discount: '',
  119. sort: '',
  120. sort_type: ''
  121. },
  122. loading: false,
  123. activeName: '-1',
  124. list: [], //列表数据
  125. btnLoading: false,
  126. listLoading: false,
  127. checked: false,
  128. sort_list: [
  129. {
  130. name: "最新上架",
  131. key: 'time',
  132. is_active: false,
  133. sort: '',
  134. },
  135. {
  136. name: "供货价",
  137. key: 'price',
  138. is_active: false,
  139. sort: '',
  140. },
  141. ],
  142. type: '',
  143. sort: '',
  144. goodsDetailId: 0,
  145. pageCount: 0,
  146. cats: <?= $cats ?>,
  147. rate: <?= $rate ?>,
  148. },
  149. mounted() {
  150. // 获取列表首页数据
  151. this.loadData(this.page, this.search); //获取列表数据
  152. },
  153. filters: {
  154. addZero: function(data, rate) {
  155. // return parseFloat(data * rate).toFixed(2) + '元';
  156. // console.log(Math.floor(data * rate * 100) * 0.01, data, rate)
  157. return (Math.floor(data * rate * 100) * 0.01).toFixed(2) + '元';
  158. },
  159. getRate: function(rate) {
  160. return Math.round(Number(rate) * 100, 2)
  161. },
  162. },
  163. methods: {
  164. // 1.0 获取视频列表
  165. loadData(page, others) {
  166. this.loading = true;
  167. request({
  168. method: 'get',
  169. params: {
  170. r: 'qi-shang-tong/goods/index',
  171. page: page,
  172. limit: 18,
  173. ...others, //其他搜索字段
  174. },
  175. }).then(e => {
  176. this.loading = false;
  177. if (e.data.code === 0) {
  178. this.list = e.data.data.list;
  179. this.pageCount = Math.ceil(e.data.data.count / 18);
  180. } else {
  181. this.$message.error(e.data.msg);
  182. }
  183. }).catch(e => {});
  184. },
  185. pagination(page) {
  186. this.page = page;
  187. this.loadData(this.page, this.search);
  188. },
  189. searchs() {
  190. this.page = 1;
  191. this.loadData(this.page, this.search);
  192. },
  193. detailUrl(goods) {
  194. this.goodsDetailId = goods.goods_id
  195. },
  196. // 选择商品
  197. selectGoods(index) {
  198. if (this.list[index].is_storage) {
  199. return false;
  200. }
  201. if (this.list[index].is_select) {
  202. Vue.set(this.list[index], 'is_select', false);
  203. } else {
  204. Vue.set(this.list[index], 'is_select', true);
  205. }
  206. },
  207. // 计算
  208. countIsSelect () {
  209. let count = 0
  210. this.list.forEach(item => {
  211. if (item.is_select == true) {
  212. count++
  213. }
  214. })
  215. return count
  216. },
  217. // 单个加入
  218. oneAdd(goods) {
  219. this.post([goods]);
  220. },
  221. // 批量加入
  222. batchAdd() {
  223. let num = 0;
  224. let goods = []
  225. this.list.forEach(function(item, index) {
  226. if (item.is_select) {
  227. num++;
  228. goods.push(item);
  229. }
  230. })
  231. if (num <= 0) {
  232. this.$message.error('请选择商品');
  233. return false;
  234. }
  235. this.post(goods);
  236. },
  237. post(goods) {
  238. this.btnLoading = true
  239. request({
  240. method: 'post',
  241. params: {
  242. r: 'qi-shang-tong/goods/import',
  243. },
  244. data: {
  245. 'goods': JSON.stringify(goods)
  246. },
  247. }).then(e => {
  248. this.btnLoading = false;
  249. if (e.data.code === 0) {
  250. // this.page = 1
  251. // this.search = {
  252. // goods_name: '',
  253. // cate_id: '',
  254. // goods_type: '',
  255. // discount: '',
  256. // sort: '',
  257. // sort_type: ''
  258. // }
  259. this.loadData(this.page, this.search);
  260. this.$message.success(e.data.msg);
  261. } else {
  262. this.$message.error(e.data.msg);
  263. }
  264. }).catch(e => {
  265. this.btnLoading = false;
  266. });
  267. },
  268. // 全选
  269. allSelect() {
  270. if (this.checked) {
  271. this.list.forEach(function(item, index) {
  272. if (!item.storage) {
  273. item.is_select = true;
  274. }
  275. })
  276. } else {
  277. this.list.forEach(function(item, index) {
  278. item.is_select = false;
  279. })
  280. }
  281. },
  282. searchSort(event) {
  283. let el = event.currentTarget;
  284. this.search.sort_type = el.dataset.key;
  285. let index = el.dataset.index;
  286. let data = this.sort_list[index];
  287. if (data.sort == '' || data.sort == 'asc') {
  288. this.sort_list[index].sort = 'desc';
  289. } else {
  290. this.sort_list[index].sort = 'asc';
  291. }
  292. this.sort_list.forEach(function(item, key) {
  293. if (key != index) {
  294. item.sort = '';
  295. }
  296. })
  297. this.search.sort = this.sort_list[index].sort;
  298. this.searchs()
  299. },
  300. },
  301. });
  302. </script>
  303. <style>
  304. .table-body {
  305. padding: 20px;
  306. background-color: #fff;
  307. }
  308. .input-item {
  309. display: inline-block;
  310. width: 150px;
  311. margin: 0 0 20px;
  312. }
  313. .input-item .el-input__inner {
  314. border-right: 1px solid #dcdfe6;
  315. }
  316. .input-item .el-input__inner:hover {
  317. border: 1px solid #dcdfe6;
  318. border-right: 0;
  319. outline: 0;
  320. }
  321. .input-item .el-input__inner:focus {
  322. border: 1px solid #dcdfe6;
  323. border-right: 0;
  324. outline: 0;
  325. }
  326. .input-item .el-input-group__append {
  327. background-color: #fff;
  328. border-left: 0;
  329. width: 10%;
  330. padding: 0;
  331. }
  332. .input-item .el-input-group__append .el-button {
  333. padding: 0;
  334. }
  335. .input-item .el-input-group__append .el-button {
  336. margin: 0;
  337. }
  338. .select {
  339. float: left;
  340. width: 100px;
  341. margin-right: 10px;
  342. }
  343. .el-table th>.cell {
  344. color: #333;
  345. font-weight: bold;
  346. font-size: 14px;
  347. }
  348. .el-table__footer-wrapper,
  349. .el-table__header-wrapper {
  350. border-bottom: 1.4px solid #D6D6D6;
  351. }
  352. .search-sort {
  353. display: inline-block;
  354. margin: 0px 10px;
  355. cursor: pointer;
  356. color: rgb(51, 51, 51);
  357. }
  358. .caret-wrapper {
  359. display: inline-flex;
  360. flex-direction: column;
  361. align-items: center;
  362. height: 25px;
  363. width: 11px;
  364. vertical-align: middle;
  365. cursor: pointer;
  366. overflow: initial;
  367. position: relative;
  368. }
  369. .caret-top {
  370. border: 5px solid transparent;
  371. margin: 1px 0;
  372. border-bottom-color: rgb(51, 51, 51);
  373. }
  374. .caret-bottom {
  375. border: 5px solid transparent;
  376. margin: 1px 0;
  377. border-top-color: rgb(51, 51, 51);
  378. }
  379. .active {
  380. border-top-color: rgb(41, 186, 156);
  381. }
  382. .ellipsis {
  383. height: 40px;
  384. font-size: 14px;
  385. color: #333;
  386. overflow: hidden;
  387. text-overflow: ellipsis;
  388. }
  389. .goods-wrapper {
  390. border: 2px solid #CCCCCC;
  391. display: inline-block;
  392. border-radius: 2px;
  393. }
  394. .goods-select {
  395. border: 2px solid #bb730c;
  396. }
  397. .goods-price {
  398. text-align: center;
  399. }
  400. .goods-price .number {
  401. color: red;
  402. font-weight: 600;
  403. font-size: 14px;
  404. }
  405. .goods-price .title {
  406. padding: 5px 0;
  407. color: #999;
  408. ;
  409. font-size: 10px;
  410. font-weight: 600;
  411. }
  412. .bottom-price .title {
  413. padding: 5px 0;
  414. color: #8b8888;
  415. ;
  416. font-size: 10px;
  417. }
  418. .bottom-price .number {
  419. color: #ff5100;
  420. font-size: 10px;
  421. }
  422. .goods-action {
  423. margin-top: 8px;
  424. }
  425. .goods-action .title {
  426. color: #0634aa;
  427. }
  428. .bottom-active {
  429. border-bottom-color: rgb(186, 41, 92);
  430. }
  431. .top-active {
  432. border-top-color: rgb(186, 41, 92);
  433. }
  434. .price {
  435. white-space: nowrap;
  436. }
  437. .goods-list {
  438. min-height: 100px;
  439. margin-top: 5px;
  440. }
  441. .page {
  442. padding: 10px 0;
  443. }
  444. </style>