多租户商城-客户PC端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

555 lines
15 KiB

2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="attentionds">
  3. <div class="attentiondsTit">
  4. <div class="attentionBox">
  5. <div class="">
  6. <div class="searchRight">
  7. <span v-if="!edit" class="batch" @click="showEdit">批量管理</span>
  8. <div v-else class="saveList">
  9. <el-checkbox v-model="selectAll" @change="changeChecked" :true-label='1' :false-label='0'>全选</el-checkbox>
  10. <span class="delete" @click="cancelFun">取消收藏</span>
  11. <span class="save" @click="saveList">保存</span>
  12. </div>
  13. <input v-if="activeName==='commodity'" type="text" v-model="keyword" @keyup.enter="searchPro" :placeholder="$t('common.searchproducthint')">
  14. <input v-else type="text" v-model="keyword" @keyup.enter="searchPro" :placeholder="$t('common.searchshophint')">
  15. <span class="searchBtn" @click="searchPro">
  16. <icon-svg icon-class="search" />
  17. </span>
  18. </div>
  19. </div>
  20. </div>
  21. <el-tabs v-model="activeName" @tab-click="handleClick">
  22. <el-tab-pane label="收藏的商品" name="commodity">
  23. <div class="list sub-main" v-if="flag" v-loading="loading">
  24. <div class="attentiondsList">
  25. <div class="listBox">
  26. <div class="attentiondsItem" v-for="(item,index) of attentiondList" :key="item.collectId" :class="{selected: item.selected === 1, edit: edit}" @click="selectPro(index,item.selected)">
  27. <div class="mc" v-if="edit"></div>
  28. <div class="imgBox" :class="{offShelf: item.shelveState === 0}">
  29. <div class="tipText" v-if="item.shelveState === 0">
  30. <span>已下架</span>
  31. </div>
  32. <img :src="item.image" alt="">
  33. </div>
  34. <div class="info">
  35. <h3 class="overflow">{{ item.productName }}</h3>
  36. <span class="price">¥{{ item.price }}</span>
  37. </div>
  38. <div class="btnBox">
  39. <span @click="cancelSingle(item.collectId)">取消收藏</span>
  40. <span @click="toProductDetail(item)">查看详情</span>
  41. </div>
  42. </div>
  43. <div class="clearfix"></div>
  44. </div>
  45. </div>
  46. <el-pagination
  47. v-if="attentiondList.length>0"
  48. background
  49. layout="prev, pager, next, jumper"
  50. :page-size="10"
  51. :current-page="page"
  52. @current-change="handleCurrentChange"
  53. :total="total">
  54. </el-pagination>
  55. </div>
  56. <div class="nothing sub-main" v-else>
  57. <icon-svg style="width: 240px; height: 240px; margin-bottom: 20px;" icon-class="user-favorite-nodata" />
  58. <p class="fs20 font-color-999">你还没有收藏的商品</p>
  59. </div>
  60. </el-tab-pane>
  61. <el-tab-pane label="收藏的店铺" name="shop">
  62. <div class="list sub-main" v-if="flag" v-loading="loading">
  63. <div class="attentiondsList">
  64. <div class="listBox">
  65. <div class="attentiondsItem" v-for="(item,index) of shopList" :key="item.id" :class="{selected: item.selected === 1, edit: edit}" @click="selectShop(index,item.selected)">
  66. <div class="mc" v-if="edit"></div>
  67. <div class="imgBox">
  68. <img :src="item.shopLogo" alt="">
  69. </div>
  70. <div class="info">
  71. <h3>{{ item.shopName }}</h3>
  72. </div>
  73. <div class="btnBox">
  74. <span @click="cancelSingle(item.collectId)">取消收藏</span>
  75. <span @click="toStore(item.shopId)">进入店铺</span>
  76. </div>
  77. </div>
  78. <div class="clearfix"></div>
  79. </div>
  80. </div>
  81. <el-pagination
  82. v-if="shopList.length>0"
  83. background
  84. layout="prev, pager, next, jumper"
  85. :page-size="10"
  86. :current-page="page"
  87. @current-change="handleCurrentChange"
  88. :total="total">
  89. </el-pagination>
  90. </div>
  91. <div class="nothing sub-main" v-else>
  92. <icon-svg style="width: 240px; height: 240px; margin-bottom: 20px;" icon-class="user-favorite-nodata" />
  93. <p class="fs20 font-color-999">你还没有收藏的店铺</p>
  94. </div>
  95. </el-tab-pane>
  96. </el-tabs>
  97. </div>
  98. </div>
  99. </template>
  100. <script>
  101. import {
  102. getCollectShop,
  103. getCollectProduct,
  104. cancelCollect
  105. } from '@/api/user/user.js'
  106. export default {
  107. name: 'favorites',
  108. data () {
  109. return {
  110. page: 1,
  111. pageSize: 10,
  112. total: 0,
  113. edit: false,
  114. attentiondChecked: 0,
  115. selectAll: 0,
  116. activeName: 'commodity',
  117. keyword: '',
  118. attentiondList: [],
  119. shopList: [],
  120. flag: true,
  121. loading: false
  122. }
  123. },
  124. mounted () {
  125. this.getAllProduct()
  126. },
  127. methods: {
  128. // 收藏店铺查询
  129. async getAllShop () {
  130. this.loading = true
  131. const response = await getCollectShop({
  132. page: this.page,
  133. pageSize: this.pageSize,
  134. search: this.keyword
  135. })
  136. const res = response.data
  137. if (res.code === '200') {
  138. this.shopList = res.data.list
  139. this.total = res.data.total
  140. this.flag = res.data.list.length > 0
  141. this.loading = false
  142. } else {
  143. this.$message.warning(res.message)
  144. }
  145. },
  146. // 收藏商品查询
  147. async getAllProduct () {
  148. const response = await getCollectProduct({
  149. page: this.page,
  150. pageSize: this.pageSize,
  151. search: this.keyword
  152. })
  153. const res = response.data
  154. if (res.code === '200') {
  155. this.attentiondList = res.data.list
  156. this.total = res.data.total
  157. this.flag = res.data.list.length > 0
  158. this.loading = false
  159. } else {
  160. this.$message.warning(res.message)
  161. }
  162. },
  163. handleCurrentChange (val) {
  164. this.page = val
  165. if (this.activeName === 'commodity') {
  166. this.getAllProduct()
  167. } else {
  168. this.getAllShop()
  169. }
  170. },
  171. saveList () {
  172. if (this.activeName === 'commodity') {
  173. this.attentiondList.forEach(i => {
  174. this.$set(i, 'selected', 0)
  175. })
  176. } else {
  177. this.shopList.forEach(i => {
  178. this.$set(i, 'selected', 0)
  179. })
  180. }
  181. this.selectAll = 0
  182. this.edit = false
  183. },
  184. handleClick () {
  185. this.page = 1
  186. this.keyword = ''
  187. this.edit = false
  188. this.selectAll = 0
  189. if (this.activeName === 'commodity') {
  190. this.getAllProduct()
  191. } else {
  192. this.getAllShop()
  193. }
  194. },
  195. // 跳转到商品详情
  196. toProductDetail (item) {
  197. let data = {
  198. shopId: item.shopId,
  199. skuId: item.skuId,
  200. productId: item.productId
  201. }
  202. this.$router.push({
  203. path: '/productDetail',
  204. query: {
  205. proData: JSON.stringify(data)
  206. }
  207. })
  208. },
  209. // 跳转到店铺
  210. toStore (id) {
  211. this.$router.push({
  212. path: '/store', query: {shopId: id}
  213. })
  214. },
  215. // 商品单个选中
  216. selectPro (index, selected) {
  217. if (selected === 1) {
  218. this.attentiondList[index].selected = 0
  219. } else {
  220. this.attentiondList[index].selected = 1
  221. }
  222. this.selectAll = 1
  223. this.attentiondList.map(item => {
  224. if (item.selected === 0) {
  225. this.selectAll = 0
  226. }
  227. })
  228. },
  229. // 店铺单个选中
  230. selectShop (index, selected) {
  231. if (selected === 1) {
  232. this.shopList[index].selected = 0
  233. } else {
  234. this.shopList[index].selected = 1
  235. }
  236. this.selectAll = 1
  237. this.shopList.map(item => {
  238. if (item.selected === 0) {
  239. this.selectAll = 0
  240. }
  241. })
  242. },
  243. // 全选
  244. changeChecked () {
  245. if (this.activeName === 'commodity') {
  246. this.attentiondList.forEach(i => {
  247. this.$set(i, 'selected', this.selectAll)
  248. })
  249. console.log(this.attentiondList)
  250. } else {
  251. this.shopList.forEach(i => {
  252. this.$set(i, 'selected', this.selectAll)
  253. })
  254. console.log(this.shopList)
  255. }
  256. },
  257. // 批量管理
  258. showEdit () {
  259. if (this.activeName === 'commodity') {
  260. if (this.attentiondList.length === 0) {
  261. return
  262. }
  263. } else {
  264. if (this.shopList.length === 0) {
  265. return
  266. }
  267. }
  268. this.edit = true
  269. },
  270. // 搜索
  271. searchPro () {
  272. this.page = 1
  273. if (this.activeName === 'commodity') {
  274. this.getAllProduct()
  275. } else {
  276. this.getAllShop()
  277. }
  278. },
  279. // 取消收藏请求
  280. async unfavorite (ids) {
  281. const response = await cancelCollect({ ids: ids })
  282. const res = response.data
  283. if (res.code === '200') {
  284. this.$message.success('取消成功')
  285. this.edit = false
  286. if (this.activeName === 'commodity') {
  287. this.getAllProduct()
  288. } else {
  289. this.getAllShop()
  290. }
  291. }
  292. },
  293. // 取消单个收藏
  294. cancelSingle (id) {
  295. let ids = [id]
  296. this.unfavorite(ids)
  297. },
  298. // 取消选中收藏
  299. cancelFun () {
  300. let flag2 = false
  301. let ids = []
  302. if (this.activeName === 'commodity') {
  303. this.attentiondList.forEach(item => {
  304. if (item.selected === 1) {
  305. flag2 = true
  306. ids.push(item.collectId)
  307. }
  308. })
  309. if (flag2 === false) {
  310. return this.$message.warning('请先选择需要取消的收藏')
  311. }
  312. } else {
  313. this.shopList.forEach(item => {
  314. if (item.selected === 1) {
  315. flag2 = true
  316. ids.push(item.collectId)
  317. }
  318. })
  319. if (flag2 === false) {
  320. return this.$message.warning('请先选择需要取消的收藏')
  321. }
  322. }
  323. this.$confirm('此操作将取消选中的收藏, 是否继续?', '提示', {
  324. confirmButtonText: this.$t('common.sure'),
  325. cancelButtonText: this.$t('common.cancel'),
  326. type: 'warning'
  327. }).then(() => {
  328. this.unfavorite(ids)
  329. }).catch(() => {
  330. })
  331. }
  332. }
  333. }
  334. </script>
  335. <style lang="scss" scoped>
  336. $searchHeight: 37px;
  337. .attentionds {
  338. border: 1px solid #E5E5E5;
  339. .attentiondsTit {
  340. display: flex;
  341. justify-content: space-between;
  342. align-items: center;
  343. margin-bottom: 30px;
  344. position: relative;
  345. >>> .el-tabs__nav-wrap::after {
  346. height: 1px;
  347. }
  348. >>> .el-tabs--top {
  349. width: 100%;
  350. }
  351. .attentionBox {
  352. position: absolute;
  353. top: 10px;
  354. right: 25px;
  355. z-index: 99;
  356. .searchRight {
  357. display: flex;
  358. input {
  359. margin-left: 16px;
  360. border: 1px solid #E5E5E5;
  361. padding-left: 10px;
  362. font-size: 14px;
  363. width: 280px;
  364. }
  365. span {
  366. display: block;
  367. height: 30px;
  368. line-height: 30px;
  369. }
  370. .batch {
  371. color: #FFFFFF;
  372. font-size: 12px;
  373. width: 78px;
  374. text-align: center;
  375. height: $searchHeight;
  376. line-height: $searchHeight;
  377. background: $mainGlod;
  378. cursor: pointer;
  379. }
  380. .searchBtn {
  381. // width: 64px;
  382. height: $searchHeight;
  383. line-height: $searchHeight;
  384. // background: $mainGlod;
  385. color: #FFFFFF;
  386. font-size: 25px;
  387. text-align: center;
  388. cursor: pointer;
  389. position: absolute;
  390. right: 10px;
  391. }
  392. }
  393. }
  394. span {
  395. display: block;
  396. height: 30px;
  397. line-height: 30px;
  398. }
  399. .saveList {
  400. display: flex;
  401. align-items: center;
  402. span {
  403. margin-left: 36px;
  404. cursor: pointer;
  405. color: #333333;
  406. font-size: 14px;
  407. }
  408. span.save {
  409. width: 104px;
  410. height: $searchHeight;
  411. background: #FFFFFF;
  412. color: #333333;
  413. border: 1px solid $mainGlod;
  414. text-align: center;
  415. line-height: $searchHeight;
  416. }
  417. }
  418. >>> .el-tabs__nav-scroll {
  419. padding: 0 25px;
  420. height: 60px;
  421. line-height: 60px;
  422. background-color: #FAFAFA;
  423. }
  424. }
  425. .list {
  426. padding: 10px 20px 20px 20px;
  427. .attentiondsList {
  428. .topTime {
  429. color: #333333;
  430. font-size: 18px;
  431. margin-bottom: 30px;
  432. }
  433. .listBox {
  434. .attentiondsItem {
  435. width: 186px;
  436. float: left;
  437. margin:0 18px 20px 0;
  438. position: relative;
  439. .imgBox {
  440. width: 186px;
  441. height: 186px;
  442. border: 1px solid #E5E5E5;
  443. border-bottom: 0;
  444. box-sizing: border-box;
  445. img {
  446. width: 100%;
  447. height: 100%;
  448. }
  449. }
  450. .info {
  451. border: 1px solid #E5E5E5;
  452. box-sizing: border-box;
  453. text-align: center;
  454. padding: 0 15px 15px;
  455. h3 {
  456. font-size: 14px;
  457. color: #333333;
  458. height: 30px;
  459. line-height: 30px;
  460. margin-top: 10px;
  461. }
  462. span {
  463. color: $mainGlod;
  464. font-size: 14px;
  465. }
  466. }
  467. .btnBox {
  468. border: 1px solid #E5E5E5;
  469. display: flex;
  470. border-top: none;
  471. span {
  472. width: 50%;
  473. display: block;
  474. text-align: center;
  475. font-size: 14px;
  476. color: #333333;
  477. height: 30px;
  478. line-height: 30px;
  479. cursor: pointer;
  480. }
  481. span:first-child {
  482. border-right: 1px solid #E5E5E5;
  483. box-sizing: border-box;
  484. }
  485. }
  486. .offShelf {
  487. position: relative;
  488. z-index: 99;
  489. .tipText {
  490. top: 0;
  491. position: absolute;
  492. left: 0;
  493. right: 0;
  494. bottom: 0;
  495. display: flex;
  496. align-items: center;
  497. justify-content: center;
  498. background: rgba(28,28,28,0.5);
  499. color: #fff;
  500. }
  501. }
  502. }
  503. .attentiondsItem:nth-child(5n) {
  504. margin-right: 0;
  505. }
  506. .edit:before {
  507. content: "";
  508. background: url("./../../../assets/images/user-unselected.svg");
  509. width: 24px;
  510. height: 24px;
  511. position: absolute;
  512. right: 10px;
  513. top: 10px;
  514. display: block;
  515. background-size: contain;
  516. z-index: 999;
  517. }
  518. .selected:before {
  519. background: url("./../../../assets/images/user-selected.svg");
  520. background-size: contain;
  521. }
  522. }
  523. }
  524. >>> .el-pagination {
  525. margin: 30px 0 20px 0;
  526. }
  527. }
  528. .sub-main{
  529. min-height: 400px;
  530. }
  531. .nothing{
  532. width: 100%;
  533. margin-top: 30px;
  534. text-align: center;
  535. min-height: 400px;
  536. p{
  537. margin-bottom: 20px;
  538. }
  539. .el-button{
  540. background-color: $mainGlod;
  541. color: #FFFFFF;
  542. font-weight: normal;
  543. border-radius: 0;
  544. }
  545. }
  546. .mc{
  547. width: 100%;
  548. height: 100%;
  549. position: absolute;
  550. opacity: 0;
  551. }
  552. }
  553. </style>