index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <template>
  2. <view class="page-wrapper history" :style="viewColor">
  3. <view class="history_count">
  4. <block v-if="list.length>0">
  5. <view class="history_header acea-row">
  6. <text>共{{total}}条</text>
  7. <view class="text" @click.stop="handleEdit">{{isEdit ? '完成' : '管理'}}</view>
  8. </view>
  9. <view class="list" v-for="(item,index) in list">
  10. <view class="item_time">
  11. <view v-if="isEdit" class="checkbox" @click="historyAllCheck(item,index)">
  12. <text v-if="!item.allCheck" class="iconfont icon-weixuanzhong"></text>
  13. <text v-else class="iconfont icon-xuanzhong1"></text>
  14. </view>
  15. <view>{{item.date}}</view>
  16. </view>
  17. <view class="item_main acea-row">
  18. <view class="item acea-row" :class="{gary :(itemn.spu && itemn.spu.status ==1) }" v-for="(itemn,indexn) in item.list" v-if="itemn.spu">
  19. <view v-if="isEdit" class="item item_count" @click="historyCheck(itemn,indexn)">
  20. <!-- <image :src="itemn.spu.image" mode=""></image> -->
  21. <view class="checkbox">
  22. <text v-if="!itemn.check" class="iconfont icon-weixuanzhong"></text>
  23. <text v-else class="iconfont icon-xuanzhong1"></text>
  24. </view>
  25. <easy-loadimage class="easy-img" mode="widthFix" :image-src="itemn.spu.image"></easy-loadimage>
  26. <view class="info">
  27. <view class="msg">
  28. <block v-if="itemn.spu && itemn.spu.status == 1">
  29. <view class="price"><text>¥</text>{{itemn.spu.price}}</view>
  30. </block>
  31. <block v-else>
  32. <view class="tips">该商品已下架</view>
  33. </block>
  34. </view>
  35. </view>
  36. </view>
  37. <view v-else class="item item_count" @click="goPage(itemn)" >
  38. <easy-loadimage class="easy-img" mode="widthFix" :image-src="itemn.spu.image"></easy-loadimage>
  39. <view class="info">
  40. <view class="msg">
  41. <block v-if="itemn.spu && itemn.spu.status == 1">
  42. <view class="price"><text>¥</text>{{itemn.spu.price}}</view>
  43. </block>
  44. <block v-else>
  45. <view class="tips">该商品已下架</view>
  46. </block>
  47. </view>
  48. </view>
  49. </view>
  50. </view>
  51. </view>
  52. </view>
  53. </block>
  54. <block v-else>
  55. <emptyPage title="暂无浏览记录~"></emptyPage>
  56. </block>
  57. </view>
  58. <view class='footer acea-row row-between-wrapper' v-if="isEdit">
  59. <view>
  60. <view class="allcheckbox" @click.stop="checkboxAllChange">
  61. <text v-if="!isAllSelect" class="iconfont icon-weixuanzhong"></text>
  62. <text v-else class="iconfont icon-xuanzhong1"></text>
  63. 全选
  64. </view>
  65. </view>
  66. <view class='acea-row row-between-wrapper'>
  67. <view class='button acea-row row-middle' style="margin-right: 20rpx;">
  68. <form @submit="subCollect" report-submit='true'>
  69. <button class='bnt collect_btn' formType="submit">收藏</button>
  70. </form>
  71. </view>
  72. <view class='button acea-row row-middle'>
  73. <form @submit="subDel('batch')" report-submit='true'>
  74. <button class='bnt delete_btn' formType="submit">删除</button>
  75. </form>
  76. </view>
  77. </view>
  78. </view>
  79. </view>
  80. </template>
  81. <script>
  82. // +----------------------------------------------------------------------
  83. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  84. // +----------------------------------------------------------------------
  85. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  86. // +----------------------------------------------------------------------
  87. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  88. // +----------------------------------------------------------------------
  89. // | Author: CRMEB Team <admin@crmeb.com>
  90. // +----------------------------------------------------------------------
  91. import emptyPage from '@/components/emptyPage.vue'
  92. import { historyList, historyDelete, historyBatchDelete, historyBatchCollect } from '@/api/user.js'
  93. import { goShopDetail } from '@/libs/order.js'
  94. import easyLoadimage from '@/components/easy-loadimage/easy-loadimage.vue';
  95. import { mapGetters } from "vuex";
  96. export default{
  97. components:{
  98. emptyPage,
  99. easyLoadimage
  100. },
  101. computed: mapGetters(['viewColor']),
  102. data(){
  103. return {
  104. list:[],
  105. isScroll:true,
  106. page:1,
  107. limit:50,
  108. isAllSelect: false,
  109. isEdit: false,
  110. allArr: [],
  111. total: 0
  112. }
  113. },
  114. onShow() {
  115. this.list = [];
  116. this.allArr = [];
  117. this.isScroll = true;
  118. this.page = 1;
  119. this.getList();
  120. this.isAllSelect = false;
  121. this.isEdit = false;
  122. },
  123. methods:{
  124. getList(){
  125. // if(!this.isScroll) return
  126. let that = this
  127. historyList({
  128. page:that.page,
  129. limit:that.limit
  130. }).then(({data})=>{
  131. that.total = data.count
  132. if(!data.list) return ;
  133. data.list.forEach((item, index) => {
  134. item.check = false
  135. })
  136. that.isScroll = data.list.length>=that.limit
  137. that.page+=1
  138. that.list = that.list.concat(data.list)
  139. that.listFilter(that.list)
  140. })
  141. },
  142. // 数据结构重组
  143. listFilter(arr){
  144. arr.forEach((item,index)=>{
  145. if(!item.allCheck){
  146. this.$set(item,'allCheck',false)
  147. }
  148. item.list.forEach((itemn,indexn)=>{
  149. if(!itemn.check){
  150. this.$set(itemn,'check',false)
  151. }
  152. })
  153. })
  154. if(this.isAllSelect){this.cartAllCheck('allCheck')}
  155. },
  156. // 全选
  157. checkboxAllChange() {
  158. this.isAllSelect = !this.isAllSelect
  159. this.cartAllCheck('allCheck')
  160. },
  161. handleEdit(){
  162. this.isEdit = !this.isEdit;
  163. },
  164. // 商品选中
  165. historyCheck(item) {
  166. item.check = !item.check
  167. this.cartAllCheck('goodsCheck')
  168. },
  169. // 删除
  170. subDel: function(type) {
  171. let that = this
  172. let type_id
  173. let content = (type == 'empty') ? '确定清空浏览记录?' : '确定删除浏览记录?'
  174. if(type == 'batch'){
  175. type_id = []
  176. that.list.forEach(item=>{
  177. item.list.forEach(el=>{
  178. if(el.check){
  179. type_id.push(el.user_history_id)
  180. }
  181. })
  182. })
  183. }else{
  184. type_id = 1
  185. }
  186. if(type_id.length == 0 && type == 'batch'){
  187. return that.$util.Tips({
  188. title: '请选择记录'
  189. });
  190. }else{
  191. uni.showModal({
  192. title: '提示',
  193. content: content,
  194. success: function (res) {
  195. if (res.confirm) {
  196. historyBatchDelete({
  197. history_id:type_id,
  198. }).then(res=>{
  199. that.allArr = [];
  200. that.page = 1;
  201. that.list = [];
  202. that.isEdit = false;
  203. that.isScroll = true;
  204. that.getList();
  205. return that.$util.Tips({
  206. title: res.message,
  207. icon: 'success'
  208. });
  209. }).catch(err => {
  210. return that.$util.Tips({
  211. title: err
  212. });
  213. });
  214. }else if (res.cancel) {
  215. return that.$util.Tips({
  216. title: '已取消'
  217. });
  218. }
  219. }
  220. });
  221. }
  222. },
  223. subCollect(){
  224. let that = this, type_id = []
  225. that.list.forEach(item=>{
  226. item.list.forEach(el=>{
  227. if(el.check){
  228. type_id.push(el.spu.spu_id)
  229. }
  230. })
  231. })
  232. historyBatchCollect({
  233. type_id:type_id,
  234. type: 1
  235. }).then(res=>{
  236. that.allArr = [];
  237. that.page = 1;
  238. that.list = [];
  239. that.isEdit = false;
  240. that.isScroll = true;
  241. that.isAllSelect = false;
  242. that.getList();
  243. return that.$util.Tips({
  244. title: res.message,
  245. icon: 'success'
  246. });
  247. }).catch(err => {
  248. return that.$util.Tips({
  249. title: err
  250. });
  251. });
  252. },
  253. // 商铺全选
  254. historyAllCheck(item, index) {
  255. // 店铺取消
  256. if (item.allCheck) {
  257. item.allCheck = false
  258. item.list.forEach((el, i) => {
  259. el.check = false
  260. })
  261. } else {
  262. item.allCheck = true
  263. item.list.forEach((el, i) => {
  264. el.check = true
  265. })
  266. }
  267. this.cartAllCheck('goodsCheck')
  268. },
  269. // 删除
  270. bindDelete(item,index){
  271. historyDelete(item.user_history_id).then(res=>{
  272. this.list.splice(index,1)
  273. uni.showToast({
  274. title:res.message,
  275. icon:'none'
  276. })
  277. }).catch(error=>{
  278. uni.showToast({
  279. title:error,
  280. icon:'none'
  281. })
  282. })
  283. },
  284. goPage(item){
  285. goShopDetail(item.spu).then(res => {
  286. uni.navigateTo({
  287. url:`/pages/goods_details/index?id=${item.spu.product_id}`
  288. })
  289. })
  290. },
  291. // 全选判断
  292. cartAllCheck(type) {
  293. let allArr = [];
  294. this.list.forEach((el, index) => {
  295. if (type == 'goodsCheck') {
  296. let tempArr = el.list.filter(item => {
  297. return item.check == true
  298. })
  299. if (el.list.length == tempArr.length) {
  300. el.allCheck = true
  301. allArr.push(el)
  302. } else {
  303. el.allCheck = false
  304. }
  305. } else {
  306. el.list.forEach((item) => {
  307. item.check = this.isAllSelect
  308. })
  309. el.allCheck = this.isAllSelect
  310. if (el.allCheck) allArr.push(el)
  311. }
  312. })
  313. // 全选
  314. this.isAllSelect = allArr.length == this.list.length ? true : false
  315. },
  316. },
  317. onReachBottom() {
  318. this.getList()
  319. },
  320. // 滚动监听
  321. onPageScroll(e) {
  322. // 传入scrollTop值并触发所有easy-loadimage组件下的滚动监听事件
  323. uni.$emit('scroll');
  324. }
  325. }
  326. </script>
  327. <style lang="scss" scoped>
  328. page{background: #ffffff;}
  329. .history{
  330. margin-bottom: 96rpx;
  331. .history_count{
  332. padding: 0 30rpx 0;
  333. padding: 0 30rpx calc(0rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
  334. padding: 0 30rpx calc(0rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
  335. }
  336. .history_header{
  337. justify-content: space-between;
  338. margin: 30rpx 0;
  339. text{
  340. font-size: 26rpx;
  341. color: #666666;
  342. }
  343. .text{
  344. color: var(--view-theme);
  345. }
  346. }
  347. .list{
  348. margin-top: 20rpx;
  349. .item_time{
  350. font-size: 36rpx;
  351. color: #282828;
  352. font-weight: bold;
  353. display: flex;
  354. align-items: center;
  355. }
  356. .item_main{
  357. margin-top: 30rpx;
  358. }
  359. }
  360. .item{
  361. width: 217rpx;
  362. border-radius: 16rpx;
  363. margin: 0 20rpx 20rpx 0;
  364. position: relative;
  365. &:nth-child(3n){
  366. margin-right: 0;
  367. }
  368. /deep/image,/deep/.easy-loadimage,uni-image{
  369. width: 217rpx;
  370. height: 217rpx;
  371. border-radius: 16rpx;
  372. }
  373. .info{
  374. margin-top: 20rpx;
  375. color: var(--view-priceColor);
  376. font-size: 24rpx;
  377. }
  378. }
  379. }
  380. /deep/.loadfail-img,.easy-img{
  381. width: 217rpx;
  382. height: 217rpx;
  383. border-radius: 16rpx;
  384. display: block;
  385. }
  386. .item_time .checkbox .iconfont{
  387. font-size: 38rpx;
  388. color: #999999;
  389. margin-right: 10rpx;
  390. &.icon-xuanzhong1{
  391. color: var(--view-theme);
  392. }
  393. }
  394. .item_main .checkbox .iconfont{
  395. font-size: 40rpx;
  396. color: #DEDEDE;
  397. position: absolute;
  398. right: 12rpx;
  399. top: 12rpx;
  400. z-index: 10;
  401. border-radius: 100%;
  402. &.icon-weixuanzhong{
  403. &::after{
  404. content: "";
  405. display: block;
  406. width: 36rpx;
  407. height: 36rpx;
  408. background: rgba(0,0,0,.38);
  409. position: absolute;
  410. top: 2rpx;
  411. left: 2rpx;
  412. border-radius: 100%;
  413. border: 1px solid #DEDEDE;
  414. }
  415. }
  416. }
  417. .history .item .icon-xuanzhong1{
  418. color: var(--view-theme);
  419. }
  420. .history .footer {
  421. z-index: 99;
  422. width: 100%;
  423. height: 100rpx;
  424. height: calc(100rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
  425. height: calc(100rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
  426. background-color: #ffffff;
  427. position: fixed;
  428. padding: 0 20rpx;
  429. box-sizing: border-box;
  430. border-top: 1px solid #eee;
  431. bottom: var(--window-bottom);
  432. }
  433. .allcheckbox .iconfont{
  434. margin-right: 11px;
  435. font-size: 40rpx;
  436. color: #cccccc;
  437. }
  438. .allcheckbox .icon-xuanzhong1{
  439. color: var(--view-theme);
  440. }
  441. .history .footer .button .bnt {
  442. font-size: 28rpx;
  443. color: #999;
  444. border-radius: 50rpx;
  445. border: 1px solid #999;
  446. width: 160rpx;
  447. height: 60rpx;
  448. text-align: center;
  449. line-height: 60rpx;
  450. &.collect_btn{
  451. color: var(--view-theme);
  452. border-color: var(--view-theme);
  453. }
  454. }
  455. </style>