index.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. <div id="app" v-cloak>
  2. <el-card shadow="never" style="border:0;" body-style="background-color: #f3f3f3;padding: 10px 0 0;">
  3. <div slot="header">
  4. <div>
  5. <span>精选好货</span>
  6. </div>
  7. </div>
  8. <div class="table-body">
  9. <el-form
  10. :inline="true"
  11. :model="searchData"
  12. size="small"
  13. >
  14. <el-row>
  15. <el-form-item label="选品时间">
  16. <el-date-picker
  17. v-model="searchData.data"
  18. type="datetimerange"
  19. range-separator="至"
  20. start-placeholder="开始日期"
  21. end-placeholder="结束日期"
  22. value-format="yyyy-MM-dd HH:mm:ss"
  23. >
  24. </el-date-picker>
  25. </el-form-item>
  26. <el-form-item label="商品状态">
  27. <el-select size="small" v-model="searchData.status" placeholder="商品状态">
  28. <el-option :label="item.label" :value="item.value" v-for="(item, index) in goodsStatus"></el-option>
  29. </el-select>
  30. </el-form-item>
  31. </el-row>
  32. <el-row>
  33. <el-form-item label="一级分类">
  34. <el-select v-model="searchData.firstCategoryId" @change='searchCategory(1)'>
  35. <el-option :key="cate.id" v-for="(cate, key) in category_1" :label="cate.name" :value="cate.id"></el-option>
  36. </el-select>
  37. </el-form-item>
  38. <el-form-item label="二级分类">
  39. <el-select v-model="searchData.secondCategoryId" @change='searchCategory(2)'>
  40. <el-option :key="cate.id" v-for="(cate, key) in category_2" :label="cate.name" :value="cate.id"></el-option>
  41. </el-select>
  42. </el-form-item>
  43. <el-form-item label="三级分类">
  44. <el-select v-model="searchData.thirdCategoryId" @change='searchCategory(3)'>
  45. <el-option :key="cate.id" v-for="(cate, key) in category_3" :label="cate.name" :value="cate.id"></el-option>
  46. </el-select>
  47. </el-form-item>
  48. </el-row>
  49. <el-row>
  50. <el-form-item>
  51. <el-button type="primary" @click="onSearch">查询</el-button>
  52. <el-button type="primary" @click="onReset">重置</el-button>
  53. </el-form-item>
  54. </el-row>
  55. </el-form>
  56. </div>
  57. <div class="table-body">
  58. <div class="list-header">
  59. <div class="list-header-left">
  60. <el-checkbox v-model="checked" @change="allSelect">全选</el-checkbox>
  61. </div>
  62. <div class="list-header-right">
  63. <span style="margin-right: 20px;">已选{{ countIsSelect() }}件</span>
  64. <el-button size="mini" type="primary" @click="batchAdd">批量加入</el-button>
  65. </div>
  66. </div>
  67. <!--商品信息-->
  68. <el-row class="goods-list"
  69. v-if="goods_list"
  70. :gutter="10"
  71. v-loading="listLoading"
  72. >
  73. <template v-for="(goods, index) in goods_list">
  74. <el-col :sm="4" :span="8" class="goods-item">
  75. <div @click="selectGoods(index)">
  76. <el-card :body-style="{ padding: '0px'}" shadow="always" :class="goods.is_select == true ? 'goods-select' : ''">
  77. <!-- <img :src="getCover(goods.carouselImgList)" style="height: 200px; width: 100%;"> -->
  78. <el-image
  79. style="width: 100%; height: 200px"
  80. :src="getCover(goods.carouselImgList)"
  81. fit="cover"
  82. ></el-image>
  83. <div style="padding: 10px;" class="goods-infos">
  84. <div class="goods-name">
  85. <span>{{ goods.name }}</span>
  86. </div>
  87. <div class="goods-prices">
  88. <div class="goods-prices-item">
  89. <div class="title">采购价</div>
  90. <div class="price">{{ getPrice(goods.skuAttr, 'basePrice') }}</div>
  91. </div>
  92. <div class="goods-prices-item">
  93. <div class="title">官方销售价</div>
  94. <div class="price">{{ getPrice(goods.skuAttr, 'officialDistriPrice') }}</div>
  95. </div>
  96. </div>
  97. <div class="goods-prices">
  98. <div class="goods-prices-item">
  99. <div class="title">建议零售价</div>
  100. <div class="price">{{ getPrice(goods.skuAttr, 'suggestPrice') }}</div>
  101. </div>
  102. <div class="goods-prices-item">
  103. <div class="title">是否包邮</div>
  104. <div class="price">{{ goods.freeExpress == 1 ? '包邮' : '不包邮'}}</div>
  105. </div>
  106. </div>
  107. <div class="goods-btns">
  108. <div>
  109. <el-button @click="skuDetail(goods)" type="primary" plain size="mini" :disabled="goods.detail_url == '' ? true : false">查看详情</el-button>
  110. <!-- <el-button @click="detailUrl(goods)" type="primary" plain size="mini">查看详情</el-button> -->
  111. </div>
  112. <div>
  113. <el-button type="info" disabled plain size="mini" v-if="goods.storage">已加入</el-button>
  114. <el-button v-else type="primary" plain @click="oneAdd(goods)" size="mini">加入商品库</el-button>
  115. </div>
  116. </div>
  117. </div>
  118. </el-card>
  119. </div>
  120. </el-col>
  121. </template>
  122. </el-row>
  123. <!-- 无数据 -->
  124. <el-row v-if="goods_list.length == 0">
  125. <el-empty description="暂无数据"></el-empty>
  126. </el-row>
  127. <!-- 分页 -->
  128. <el-row type="flex" class="page" justify="end" v-if="goods_list.length > 0">
  129. <el-pagination @current-change="pagination" background layout="prev, pager, next" :page-count="pageCount" v-if="goods_list"></el-pagination>
  130. </el-row>
  131. </div>
  132. <el-dialog title="查看商品" :visible.sync="dialogVisible" width="50%" :before-close="handleClose">
  133. <template>
  134. <el-table :data="attrData" style="width: 100%">
  135. <el-table-column prop="attr" label="规格">
  136. <template slot-scope="scope">
  137. <span>
  138. {{ attrName(scope.row.skuPropertyList) }}
  139. </span>
  140. </template>
  141. </el-table-column>
  142. <el-table-column prop="status" label="状态">
  143. <template slot-scope="scope">
  144. <span v-if="scope.row.status == 1">已下架</span>
  145. <span v-else>已上架</span>
  146. </template>
  147. </el-table-column>
  148. <el-table-column prop="buyStartQty" label="起购数量">
  149. <template slot-scope="scope">
  150. <span v-if="scope.row.buyStartQty > 0">{{ scope.row.buyStartQty }}</span>
  151. <span v-else>--</span>
  152. </template>
  153. </el-table-column>
  154. <el-table-column prop="basePrice" label="采购价">
  155. </el-table-column>
  156. <el-table-column prop="officialDistriPrice" label="官方销售价">
  157. </el-table-column>
  158. <el-table-column prop="suggestPrice" label="建议零售价">
  159. </el-table-column>
  160. </el-table>
  161. </template>
  162. <span slot="footer" class="dialog-footer">
  163. <el-button @click="dialogVisible = false">取 消</el-button>
  164. <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
  165. </span>
  166. </el-dialog>
  167. </el-card>
  168. </div>
  169. <script>
  170. // 是否包邮
  171. const goodsStatus = [{
  172. value: -1,
  173. label: '全部',
  174. },
  175. {
  176. value: 1,
  177. label: '已上架',
  178. },
  179. {
  180. value: 2,
  181. label: '已下架',
  182. },
  183. {
  184. value: 3,
  185. label: '已失效',
  186. },
  187. ];
  188. const app = new Vue({
  189. el: '#app',
  190. filters: {
  191. addZero: function(data) {
  192. return Math.round((data / 100) * 100) / 100 + '元';
  193. },
  194. },
  195. data() {
  196. return {
  197. goodsStatus: goodsStatus,
  198. searchData: {
  199. data: '',
  200. firstCategoryId: '',
  201. secondCategoryId: '',
  202. thirdCategoryId: '',
  203. status: '',
  204. },
  205. goods_list: [],
  206. category_1: [],
  207. category_2: [],
  208. category_3: [],
  209. level: 0,
  210. pid: 0,
  211. pageCount: 0,
  212. page: 1,
  213. currentPage: null,
  214. listLoading: false,
  215. btnLoading: false,
  216. checked: false,
  217. dialogVisible: false,
  218. attrData: [],
  219. };
  220. },
  221. methods: {
  222. /**
  223. * 跳转详情
  224. */
  225. skuDetail(goods) {
  226. this.attrData = goods.skuAttr
  227. this.attrTab = goods.skuAttr[0].skuPropertyList
  228. this.dialogVisible = true
  229. },
  230. handleClose() {
  231. this.dialogVisible = false
  232. },
  233. /**
  234. * 选择商品
  235. */
  236. selectGoods(index) {
  237. if (this.goods_list[index].storage) {
  238. return false
  239. }
  240. if (this.goods_list[index].is_select) {
  241. Vue.set(this.goods_list[index], 'is_select', false)
  242. } else {
  243. Vue.set(this.goods_list[index], 'is_select', true)
  244. }
  245. },
  246. /**
  247. * 计算已选择
  248. */
  249. countIsSelect() {
  250. let count = 0
  251. this.goods_list.forEach(item => {
  252. if (item.is_select == true) {
  253. count++
  254. }
  255. })
  256. return count
  257. },
  258. /**
  259. * 单个加入
  260. */
  261. oneAdd(goods) {
  262. this.addStorage([goods.spuId])
  263. goods.storage = 1
  264. },
  265. /**
  266. * 批量加入
  267. */
  268. batchAdd() {
  269. let num = 0
  270. let goods_id = new Array()
  271. this.goods_list.forEach(function(item, index) {
  272. if (item.is_select && !item.storage) {
  273. num++
  274. goods_id.push(item.spuId)
  275. }
  276. })
  277. if (num <= 0) {
  278. this.$message.error('请选择商品')
  279. return false
  280. }
  281. this.addStorage(goods_id)
  282. },
  283. /**
  284. * 全选
  285. */
  286. allSelect() {
  287. if (this.checked) {
  288. this.goods_list.forEach(function(item, index) {
  289. if (!item.storage) {
  290. item.is_select = true
  291. }
  292. })
  293. } else {
  294. this.goods_list.forEach(function(item, index) {
  295. if (!item.storage) {
  296. item.is_select = false
  297. }
  298. })
  299. }
  300. },
  301. /**
  302. * 分类选择
  303. */
  304. searchCategory(level) {
  305. this.level = level
  306. if (level == 1) {
  307. this.pid = this.searchData.firstCategoryId
  308. this.category_2 = []
  309. this.category_3 = []
  310. this.searchData.secondCategoryId = ''
  311. this.searchData.thirdCategoryId = ''
  312. }
  313. if (level == 2) {
  314. this.pid = this.searchData.secondCategoryId == 0 ? this.searchData.firstCategoryId : this.searchData.secondCategoryId
  315. this.category_3 = []
  316. this.searchData.thirdCategoryId = ''
  317. }
  318. if (level == 3) {
  319. this.pid = this.searchData.thirdCategoryId == 0 ? this.searchData.secondCategoryId : this.searchData.thirdCategoryId
  320. return true
  321. }
  322. this.getCategoryList()
  323. },
  324. /**
  325. * 搜索
  326. */
  327. onSearch() {
  328. this.page = 1
  329. this.getGoodsList()
  330. },
  331. /**
  332. * 分页
  333. */
  334. pagination(currentPage) {
  335. this.page = currentPage
  336. this.getGoodsList()
  337. },
  338. /**
  339. * 获取商品列表
  340. */
  341. getGoodsList() {
  342. this.listLoading = true
  343. let params = {
  344. r: 'star-chain/goods/index',
  345. }
  346. let data = {
  347. ...{
  348. pageIndex: this.page,
  349. },
  350. ...this.searchData
  351. }
  352. request({
  353. method: 'post',
  354. params: params,
  355. data: data,
  356. }).then(e => {
  357. if (e.data.code === 0) {
  358. this.goods_list = e.data.data.list
  359. this.pageCount = e.data.data.page_count
  360. this.currentPage = e.data.data.current_page
  361. } else {
  362. this.$message.error(e.data.msg)
  363. }
  364. this.listLoading = false
  365. }).catch(e => {
  366. this.listLoading = false
  367. })
  368. },
  369. /**
  370. * 获取分类
  371. */
  372. getCategoryList() {
  373. let self = this
  374. request({
  375. params: {
  376. r: 'star-chain/goods/category',
  377. pid: this.pid,
  378. },
  379. }).then(e => {
  380. if (e.data.code === 0) {
  381. let data = e.data
  382. if (this.level == 0) {
  383. self.category_1 = data.data
  384. }
  385. if (this.level == 1) {
  386. self.category_2 = data.data
  387. }
  388. if (this.level == 2) {
  389. self.category_3 = data.data
  390. }
  391. } else {
  392. this.$message.error(e.data.msg)
  393. }
  394. }).catch(e => {})
  395. },
  396. /**
  397. * 添加到商品
  398. */
  399. addStorage(goods_id) {
  400. if (this.listLoading) return true
  401. this.listLoading = true
  402. request({
  403. method: 'post',
  404. data: {
  405. ids: goods_id,
  406. },
  407. params: {
  408. r: 'star-chain/goods/storage-add',
  409. },
  410. }).then(e => {
  411. if (e.data.code === 0) {
  412. this.$message.success(e.data.msg)
  413. this.goods_list.forEach(function(item, key) {
  414. index = goods_id.indexOf(item.id)
  415. if (index >= 0) {
  416. Vue.set(item, 'storage', true)
  417. Vue.set(item, 'is_select', false)
  418. }
  419. })
  420. this.listLoading = false
  421. } else {
  422. this.$message.error(e.data.msg)
  423. this.listLoading = false
  424. }
  425. }).catch(e => {
  426. this.listLoading = false
  427. })
  428. },
  429. /**
  430. * 获取商品主图
  431. */
  432. getCover(list) {
  433. return list[0]
  434. },
  435. /**
  436. * 获取价格
  437. */
  438. getPrice(attr, type) {
  439. let min = 0
  440. let max = 0
  441. if (attr) {
  442. attr.forEach((v, index) => {
  443. let price = v[type]
  444. if (index == 0) {
  445. min = max = price
  446. } else {
  447. min = min < price ? price : min
  448. max = max > price ? price : max
  449. }
  450. })
  451. }
  452. return min == max ? min : min + '~' + max
  453. },
  454. /**
  455. * 重置
  456. */
  457. onReset() {
  458. this.searchData = {
  459. name: '',
  460. import: '',
  461. firstCategoryId: '',
  462. secondCategoryId: '',
  463. thirdCategoryId: '',
  464. }
  465. },
  466. /**
  467. * 规格名称
  468. */
  469. attrName(attr) {
  470. let name = []
  471. attr.forEach((v) => {
  472. name.push(v.specValueName)
  473. })
  474. return name.join(' / ')
  475. },
  476. },
  477. mounted: function() {
  478. this.page = getQuery('page') ? getQuery('page') : 1
  479. this.getGoodsList()
  480. this.getCategoryList()
  481. }
  482. })
  483. </script>
  484. <style lang="scss">
  485. .table-body {
  486. padding: 20px;
  487. background-color: #fff;
  488. }
  489. .table-body + .table-body {
  490. padding-top: 0;
  491. }
  492. .list-header {
  493. display: flex;
  494. align-items: center;
  495. justify-content: space-between;
  496. padding: 5px 0;
  497. }
  498. .list-header-left {
  499. display: flex;
  500. align-items: center;
  501. }
  502. .list-header-sort {
  503. display: flex;
  504. margin-left: 10px;
  505. }
  506. .list-header-sort div + div {
  507. margin-left: 15px;
  508. }
  509. .goods-item {
  510. margin-bottom: 10px;
  511. }
  512. .goods-name {
  513. height: 40px;
  514. overflow: hidden;
  515. font-size: 12px;
  516. font-weight: normal;
  517. }
  518. .goods-infos {
  519. padding: 10px;
  520. }
  521. .goods-infos .title {
  522. font-weight: 100;
  523. }
  524. .goods-rates {
  525. margin-top: 3px;
  526. display: flex;
  527. justify-content: space-around;
  528. }
  529. .goods-prices {
  530. display: flex;
  531. justify-content: space-around;
  532. }
  533. .goods-prices-item + .goods-prices-item {
  534. margin-left: 5px;
  535. }
  536. .goods-prices-item .price {
  537. margin-top: 2px;
  538. color: #F56C6C;
  539. text-align: center;
  540. }
  541. .goods-rates-item + .goods-rates-item {
  542. margin-left: 5px;
  543. }
  544. .goods-rates-item .rate {
  545. margin-top: 2px;
  546. color: #E6A23C;
  547. text-align: center;
  548. }
  549. .goods-btns {
  550. display: flex;
  551. justify-content: space-between;
  552. margin-top: 5px;
  553. }
  554. .goods-select {
  555. border-color: #F56C6C;
  556. }
  557. .caret-top {
  558. border: 5px solid transparent;
  559. margin: 1px 0;
  560. border-bottom-color: rgb(51, 51, 51);
  561. }
  562. .caret-bottom {
  563. border: 5px solid transparent;
  564. margin: 1px 0;
  565. border-top-color: rgb(51, 51, 51);
  566. }
  567. .bottom-active {
  568. border-bottom-color: rgb(186, 41, 92);
  569. }
  570. .top-active {
  571. border-top-color: rgb(186, 41, 92);
  572. }
  573. .caret-wrapper {
  574. display: inline-flex;
  575. flex-direction: column;
  576. align-items: center;
  577. height: 25px;
  578. width: 11px;
  579. vertical-align: middle;
  580. cursor: pointer;
  581. overflow: initial;
  582. position: relative;
  583. }
  584. </style>