activity.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. <template>
  2. <view class="creat">
  3. <cu-custom bgColor="bg-fff" :isBack="true">
  4. <block slot="content">选择活动商品</block>
  5. </cu-custom>
  6. <view class="search-style">
  7. <view class="search">
  8. <image src="/static/index/search.png" mode=""></image>
  9. <u-input type="text" v-model="productName" placeholder="搜索商品名称" />
  10. <span @click="searchList">搜索</span>
  11. </view>
  12. <view class="type">
  13. <text style="margin-right: 10px;" :style="showCategoryPopup ? 'color: #449AFF;' : ''"
  14. @click="showCategoryPopup = !showCategoryPopup">{{ selectedCategory ||
  15. '全部类型' }}<i :class="showCategoryPopup ? 'typeI' : ''"></i></text>
  16. <!-- <u-select style="position: absolute;top:0" mode="single-column" :list="industryoptions"
  17. v-model="industryShow" label-name="lable" value-name="value"
  18. @confirm="industryopConfirm($event)"></u-select> -->
  19. </view>
  20. </view>
  21. <!-- 弹出层 -->
  22. <view :class="['dropdown-content', { 'show': showCategoryPopup }]" @tap="searchPopup">
  23. <view class="dropdown-content2">
  24. <view
  25. :class="['dropdown-content1', 'flex', 'justify-between', '', { 'scolcentent': showCategoryPopup }]"
  26. @tap.stop.prevent>
  27. <scroll-view scroll-y class="colcentent">
  28. <view class="category-content">
  29. <!-- 第一级 -->
  30. <scroll-view scroll-y class="category-column">
  31. <view v-for="item in firstLevel" :key="item.id"
  32. :class="['category-item', selectedFirst === item.id ? 'active' : '']"
  33. @click="selectFirst(item)">
  34. {{ item.name }}
  35. </view>
  36. </scroll-view>
  37. <!-- 第二级 -->
  38. <scroll-view scroll-y class="category-column">
  39. <view v-for="item in secondLevel" :key="item.id"
  40. :class="['category-item', selectedSecond === item.id ? 'active' : '']"
  41. @click="selectSecond(item)">
  42. {{ item.name }}
  43. </view>
  44. </scroll-view>
  45. <!-- 第三级 -->
  46. <scroll-view scroll-y class="category-column">
  47. <view v-for="item in thirdLevel" :key="item.id"
  48. :class="['category-item', selectedThird === item.id ? 'active' : '']"
  49. @click="selectThird(item)">
  50. {{ item.name }}
  51. </view>
  52. </scroll-view>
  53. </view>
  54. </scroll-view>
  55. </view>
  56. <view class="operateBtn flex ">
  57. <view class="cancel " @click.stop="showCategoryPopup = false">
  58. 取消
  59. </view>
  60. <view class="confirm " @click.stop="querysearch">
  61. 确定
  62. </view>
  63. </view>
  64. </view>
  65. </view>
  66. <view class="top"></view>
  67. <view class="content">
  68. <view class="product-item" v-for="(item, index) in productList" :key="index"
  69. @click="handleRadioChange(item.productId)">
  70. <view class="product-info">
  71. <image class="product-image" :src="item.productImage" mode="aspectFill"></image>
  72. <view class="product-details">
  73. <view class="product-name">{{ item.productName }}</view>
  74. <!-- <view class="product-date">{{ item.saleStartDate + '-' + item.saleEndDate }}</view> -->
  75. <view class="product-price">
  76. <text class="actual-price">¥{{ item.soldPrice }}</text>
  77. <text class="original-price">¥{{ item.price }}</text>
  78. </view>
  79. </view>
  80. </view>
  81. <view v-if="selectedIds.indexOf(item.productId) == '-1'" class="radio-container"></view>
  82. <image v-else class="radio-img" src="/static/coupon/danxuan.png" mode=""></image>
  83. </view>
  84. </view>
  85. <view class="btn">
  86. <view class="flex">
  87. <view @click="groupChange(1)" class="flex">
  88. <text v-if="!selectAll" style="display: inline-block;" class="radio-container"></text>
  89. <image v-else style=" vertical-align: top" class="radio-img" src="/static/coupon/quanxuan.png"
  90. mode=""></image>
  91. <text style="margin-left:10rpx">全选</text>
  92. </view>
  93. <view @click="groupChange(2)" class="flex" style="margin-left:36rpx">
  94. <text v-if="!invertAll" style="display: inline-block;" class="radio-container"></text>
  95. <image v-else style=" vertical-align: top;" class="radio-img" src="/static/coupon/danxuan.png"
  96. mode=""></image>
  97. <text style="margin-left:10rpx">反选</text>
  98. </view>
  99. </view>
  100. <button class="cu-btn submit round " @click="submitDistribution" v-if="rowDetail.consumerId"
  101. :disabled="this.selectedIds.length == 0">确定发放</button>
  102. <button class="cu-btn submit round " @click="submit" v-else
  103. :disabled="this.selectedIds.length == 0">确定</button>
  104. </view>
  105. </view>
  106. </template>
  107. <script>
  108. import { USER_INFO } from "@/common/util/constants"
  109. import {
  110. mapState
  111. } from 'vuex'
  112. export default {
  113. data() {
  114. return {
  115. showCategoryPopup: false,
  116. selectedFirst: null,
  117. selectedSecond: null,
  118. selectedThird: null,
  119. firstLevel: [],
  120. secondLevel: [],
  121. thirdLevel: [],
  122. selectAll: false,
  123. invertAll: false,
  124. productList: [], // 商品列表
  125. selectedIds: [], // 当前选中的商品ID组
  126. radiovalue1: '',
  127. productName: '',
  128. selectedCategory: '全部类型',
  129. industryShow: false,
  130. rowDetail: {},
  131. categoryId: ''
  132. }
  133. },
  134. onLoad(e) {
  135. this.getList()
  136. this.$http.get('/sys/category/getChildListBatch?parentIds=1889836358116098050').then(res => {
  137. if (res.data.success) {
  138. this.firstLevel = res.data.result.records
  139. }
  140. else {
  141. this.$tip.error(res.data.message);
  142. }
  143. })
  144. if (e && e.params) {
  145. this.selectedIds = JSON.parse(decodeURIComponent(e.params))
  146. }
  147. if (e && e.row) {
  148. this.rowDetail = JSON.parse(decodeURIComponent(e.row))
  149. }
  150. },
  151. methods: {
  152. async getSearch(id, type) {
  153. let res = await this.$http.get('/sys/category/childList?pid=' + id)
  154. if (res.data.success) {
  155. this[type + 'Level'] = res.data.result
  156. }
  157. },
  158. searchPopup() {
  159. this.showCategoryPopup = !this.showCategoryPopup;
  160. },
  161. getList() {
  162. this.$http.post('/merchant/localVoucherInfo/getProductList', { merchantId: uni.getStorageSync(USER_INFO).merchantId, productName: this.productName, categoryId: this.categoryId }).then(res => {
  163. if (res.data.success) {
  164. this.productList = res.data.result
  165. }
  166. else {
  167. this.$tip.error(res.data.message);
  168. }
  169. })
  170. },
  171. selectFirst(item) {
  172. this.selectedFirst = item.id
  173. this.selectedSecond = null
  174. this.selectedThird = null
  175. this.selectedCategory = item.name
  176. // 根据选择加载二级分类
  177. this.getSearch(item.id, 'second')
  178. this.thirdLevel = []
  179. },
  180. selectSecond(item) {
  181. this.selectedSecond = item.id
  182. this.selectedThird = null
  183. this.selectedCategory = item.name
  184. // 根据选择加载三级分类
  185. this.getSearch(item.id, 'third')
  186. },
  187. selectThird(item) {
  188. this.selectedThird = item.id
  189. this.selectedCategory = item.name
  190. },
  191. querysearch() {
  192. this.showCategoryPopup = false
  193. this.categoryId = this.selectedThird ? this.selectedThird : this.selectedSecond ? this.selectedSecond : this.selectedFirst
  194. this.getList()
  195. },
  196. groupChange(e) {
  197. if (e == 1) {
  198. this.selectedIds = !this.selectAll ? this.productList.map(item => item.productId) : []
  199. this.selectAll = !this.selectAll
  200. this.invertAll = false
  201. }
  202. if (e == 2) {
  203. // 反选功能
  204. this.invertAll = !this.invertAll
  205. this.selectAll = false
  206. // 获取所有商品ID
  207. const allProductIds = this.productList.map(item => item.productId)
  208. // 创建新的选中数组
  209. let newSelectedIds = []
  210. // 遍历所有商品ID
  211. allProductIds.forEach(productId => {
  212. // 如果当前ID不在已选中列表中,则添加到新列表
  213. // 如果当前ID在已选中列表中,则不添加(即取消选中)
  214. if (!this.selectedIds.includes(productId)) {
  215. newSelectedIds.push(productId)
  216. }
  217. })
  218. // 更新选中列表
  219. this.selectedIds = newSelectedIds
  220. }
  221. },
  222. searchList() {
  223. this.getList()
  224. },
  225. // 发放
  226. submitDistribution() {
  227. this.$http.post('/merchant/localConsumerUserInfo/addStoreProductOut', { ...this.rowDetail, productIds: this.selectedIds, merchantId: uni.getStorageSync(USER_INFO).merchantId, }).then(res => {
  228. if (res.data.success) {
  229. this.$tip.success(res.data.message || '发放成功');
  230. uni.navigateBack({
  231. delta: 1
  232. });
  233. }
  234. else {
  235. this.$tip.error(res.data.message);
  236. }
  237. })
  238. },
  239. // 确认
  240. submit() {
  241. uni.navigateBack({
  242. delta: 1
  243. });
  244. if (this.selectedIds.length > 0) {
  245. this.$store.state.shopSelectedIds = this.selectedIds
  246. // uni.setStorageSync('allowanceSelected', this.selectedIds)
  247. }
  248. },
  249. // 单选按钮变化处理
  250. handleRadioChange(id) {
  251. this. selectAll =false;
  252. this. invertAll = false
  253. // 判断是否已存在
  254. const index = this.selectedIds.indexOf(id)
  255. if (index > -1) {
  256. // 如果存在则删除
  257. this.selectedIds.splice(index, 1)
  258. } else {
  259. // 如果不存在则添加
  260. this.selectedIds.push(id)
  261. }
  262. // if (e) {
  263. // this.selectedId.push(item.id);
  264. // } else {
  265. // this.selectedId
  266. // }
  267. },
  268. }
  269. }
  270. </script>
  271. <style scoped lang="scss">
  272. .creat {
  273. width: 100vw;
  274. height: 100vh;
  275. background: #F7F8FC;
  276. display: flex;
  277. flex-direction: column;
  278. justify-content: space-between;
  279. }
  280. .top {
  281. width: 100%;
  282. height: var(--status-bar-height);
  283. background-color: #fff;
  284. }
  285. .content {
  286. width: 100%;
  287. flex: 1;
  288. padding: 24rpx;
  289. overflow-y: auto;
  290. }
  291. .btn {
  292. width: 100%;
  293. padding: 18rpx 26rpx;
  294. height: 112rpx;
  295. background-color: #fff;
  296. display: flex;
  297. justify-content: space-between;
  298. align-items: center;
  299. .submit {
  300. color: #fff;
  301. width: 205rpx;
  302. text-align: center;
  303. background: linear-gradient(90deg, #77B6FF 0%, #449AFF 100%);
  304. }
  305. }
  306. .search-style {
  307. border-top: 1px solid #EEEEEE;
  308. border-bottom: 1px solid #EEEEEE;
  309. background: #fff;
  310. padding: 16rpx 24rpx;
  311. .type {
  312. background: #FFFFFF;
  313. font-size: 26rpx;
  314. color: #333333;
  315. margin-top: 23rpx;
  316. position: relative;
  317. i {
  318. margin-left: 12rpx;
  319. display: inline-block;
  320. width: 0;
  321. height: 0;
  322. border: 4px solid;
  323. border-color: #AFB0B3;
  324. border-bottom: 4px solid transparent;
  325. border-right: 4px solid transparent;
  326. border-left: 4px solid transparent;
  327. }
  328. .typeI {
  329. border-color: #449AFF;
  330. border-top: 4px solid transparent;
  331. border-right: 4px solid transparent;
  332. border-left: 4px solid transparent;
  333. margin-bottom: 8rpx;
  334. }
  335. }
  336. .search {
  337. height: 55rpx;
  338. background: #F7F8FC;
  339. border-radius: 12rpx;
  340. padding: 0rpx 24rpx;
  341. display: flex;
  342. align-items: center;
  343. justify-content: space-between;
  344. image {
  345. width: 36rpx;
  346. height: 36rpx;
  347. }
  348. input {
  349. // height: 36rpx;
  350. font-size: 26rpx;
  351. }
  352. span {
  353. font-size: 26rpx;
  354. color: #333333;
  355. }
  356. }
  357. }
  358. .product-item {
  359. display: flex;
  360. justify-content: space-between;
  361. align-items: center;
  362. padding: 24rpx;
  363. background: #FFFFFF;
  364. margin-bottom: 20rpx;
  365. // border-bottom: 1px solid #EEEEEE;
  366. }
  367. .product-info {
  368. display: flex;
  369. align-items: center;
  370. flex: 1;
  371. }
  372. .product-image {
  373. width: 120rpx;
  374. height: 120rpx;
  375. border-radius: 8rpx;
  376. margin-right: 20rpx;
  377. }
  378. .product-details {
  379. flex: 1;
  380. }
  381. .product-name {
  382. font-size: 28rpx;
  383. color: #333333;
  384. margin-bottom: 8rpx;
  385. }
  386. .product-date {
  387. font-size: 24rpx;
  388. color: #999999;
  389. margin-bottom: 8rpx;
  390. }
  391. .product-price {
  392. display: flex;
  393. align-items: baseline;
  394. }
  395. .actual-price {
  396. font-size: 32rpx;
  397. color: #FF4B33;
  398. font-weight: bold;
  399. margin-right: 12rpx;
  400. }
  401. .original-price {
  402. font-size: 24rpx;
  403. color: #999999;
  404. text-decoration: line-through;
  405. }
  406. .radio-container {
  407. width: 40rpx;
  408. height: 40rpx;
  409. border-radius: 50%;
  410. border: 1px solid #B4B4B4;
  411. }
  412. .radio-img {
  413. width: 40rpx;
  414. height: 40rpx;
  415. }
  416. ::v-deep .u-radio {
  417. margin-left: 20rpx;
  418. }
  419. .category-trigger {
  420. display: flex;
  421. align-items: center;
  422. padding: 20rpx;
  423. .trigger-text {
  424. font-size: 28rpx;
  425. color: #666;
  426. &.active {
  427. color: #2979ff;
  428. }
  429. }
  430. .trigger-icon {
  431. margin-left: 8rpx;
  432. font-size: 24rpx;
  433. color: #999;
  434. }
  435. }
  436. .operateBtn {
  437. font-weight: bold;
  438. font-size: 28rpx;
  439. text-align: center;
  440. .cancel {
  441. width: 50%;
  442. height: 70rpx;
  443. color: #449AFF;
  444. line-height: 70rpx;
  445. background: rgba(68, 154, 255, 0.05);
  446. }
  447. .confirm {
  448. width: 50%;
  449. height: 70rpx;
  450. line-height: 70rpx;
  451. color: #fff;
  452. background: #449AFF;
  453. border-radius: 0px 0px 20rpx 0px;
  454. }
  455. }
  456. .category-content {
  457. display: flex;
  458. height: 100%;
  459. padding: 20rpx 22rpx;
  460. }
  461. .category-column {
  462. flex: 1;
  463. height: 100%;
  464. border-right: 1px solid #eee;
  465. &:last-child {
  466. border-right: none;
  467. }
  468. }
  469. .category-item {
  470. padding: 20rpx 20rpx;
  471. font-size: 26rpx;
  472. color: #333;
  473. // border-bottom: 1px solid #f5f5f5;
  474. &.active {
  475. background: rgba(68, 154, 255, 0.1);
  476. color: #2983EC;
  477. }
  478. }
  479. .dropdown-content {
  480. background-color: rgba(0, 0, 0, 0.6);
  481. height: 0px;
  482. opacity: 0;
  483. transition: opacity 0.3s ease;
  484. .title {
  485. font-size: 14px;
  486. color: #232832;
  487. font-weight: bold;
  488. border-bottom: 1px solid #E1E1E1;
  489. }
  490. }
  491. .show {
  492. height: 100vh;
  493. opacity: 1;
  494. /* 下拉菜单内容的最大高度 */
  495. }
  496. .dropdown-content1 {
  497. // background-color: #fff;
  498. height: 0px;
  499. overflow: hidden;
  500. transition: height 0.4s ease;
  501. // border-radius: 0px 0px 20rpx 20rpx;
  502. }
  503. .dropdown-content2 {
  504. background-color: #fff;
  505. // height: 0px;
  506. // overflow: hidden;
  507. // transition: height 0.4s ease;
  508. border-radius: 0px 0px 20rpx 20rpx;
  509. margin-bottom: 10px;
  510. }
  511. .scolcentent {
  512. height: 486rpx;
  513. overflow-y: auto;
  514. /* 下拉菜单遮罩最大高度 */
  515. }
  516. </style>