index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. <template>
  2. <view class="page">
  3. <image :src="imgUrl" mode="widthFix" />
  4. <view class="wait_content" v-if="imagePage && requestParam.class_id == 11">敬请期待</view>
  5. <view class="product_box" v-if="!imagePage">
  6. <view class="to_bottom" v-if="!productList.length && !isReqing"> -----还没有产品啦-----</view>
  7. <!-- 产品列表 -->
  8. <view class="product_list">
  9. <!-- Vue3 项目部分小程序端事件延迟或调用失败 在执行事件的元素上添加 data-eventsync="true" 属性以解决此问题 -->
  10. <view @click="toDetail(item)" data-eventsync="true" class="product_item" v-for="(item, index) in productList" :key="index">
  11. <view class="product_item_content">
  12. <view class="product_image_content">
  13. <image class="product_image" :src="item.thumb" mode=""></image>
  14. </view>
  15. <view>
  16. <view class="product_name">
  17. <text v-if="item.promo_title" class="regiment_title">{{ item.promo_title }}</text>
  18. <text v-if="item.regiment_title" class="regiment_title">{{ item.regiment_title }}</text>
  19. <text>{{ item.name }}</text></view
  20. >
  21. <view class="product_spec"
  22. ><text>{{ item.spec }}</text></view
  23. ></view
  24. >
  25. </view>
  26. <view class="product_item_bottom">
  27. <view class="stock_price">
  28. <view class="product_price" v-if="isShowPrice">
  29. <text>¥{{ item.price }} </text>
  30. </view>
  31. <view class="product_stock">剩{{ item.stock }}个</view>
  32. </view>
  33. <view class="stock_button">立即抢购</view>
  34. </view>
  35. </view>
  36. </view>
  37. </view>
  38. </view>
  39. </template>
  40. <script>
  41. export default {
  42. data() {
  43. return {
  44. imagePage: false,
  45. imgUrl: '',
  46. // 轮播图
  47. bannerList: [],
  48. // 产品列表
  49. productList: [],
  50. // 请求参数
  51. requestParam: {
  52. name: '',
  53. page: 1,
  54. class_id: '',
  55. },
  56. // 是否最后一页
  57. isLast: false,
  58. // 是否请求中
  59. isReqing: false,
  60. // 是否显示价格
  61. isShowPrice: false,
  62. // 城市名称
  63. cityName: '选城市',
  64. // 选择城市
  65. toSelectedCity: false,
  66. // 是否是管理员
  67. isManager: false,
  68. };
  69. },
  70. onLoad(param) {
  71. // #ifdef MP-WEIXIN
  72. //分享按钮
  73. uni.showShareMenu({
  74. withShareTicket: true,
  75. menus: ['shareAppMessage', 'shareTimeline'],
  76. });
  77. // #endif
  78. this.imgUrl = `https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/index/banner_${param.id}.png`;
  79. this.imagePage = ['101', '11', '1'].includes(param.id);
  80. this.requestParam.class_id = param.id;
  81. uni.setNavigationBarTitle({
  82. title: param.name,
  83. });
  84. },
  85. onShareAppMessage(obj) {
  86. // 获取分享信息
  87. let shareList = getApp().globalData.shareList;
  88. // 获取分享信息
  89. let shareObj = {
  90. title: '999智控终端平台\n药优惠 得积分 兑豪礼',
  91. path: '/pages/index/index',
  92. imageUrl: '',
  93. };
  94. // 循环列表
  95. for (let i in shareList) {
  96. if (shareList[i].pages == 'pages/index/index') {
  97. shareObj.path = shareList[i].path ? shareList[i].path : shareObj.path;
  98. shareObj.title = shareList[i].title ? `999智控终端平台\n${shareList[i].title}` : shareObj.title;
  99. shareObj.imageUrl = shareList[i].image_url ? shareList[i].image_url : shareObj.imageUrl;
  100. }
  101. }
  102. // 返回分享信息
  103. return shareObj;
  104. },
  105. onShow() {
  106. // 是否显示价格
  107. this.isShowPrice = this.$checkAccess.checkShowPrice();
  108. // 城市名
  109. this.cityName = this.$checkAccess.getCity();
  110. // 选城市
  111. (this.cityName = this.cityName ? this.cityName : '选城市'),
  112. // 登录并且未选择城市,才可以选择城市
  113. (this.toSelectedCity = !this.$checkAccess.getCity() ? true : false);
  114. // 数据
  115. //未选城市先弹窗提醒选择城市
  116. if (!this.$checkAccess.getCity() && this.$checkAccess.checkLogin()) {
  117. uni.showModal({
  118. title: '',
  119. content: '请先选择城市',
  120. success: (res) => {
  121. if (res.confirm) {
  122. uni.navigateTo({
  123. url: '/pages/user/info',
  124. });
  125. }
  126. },
  127. });
  128. }
  129. //如果已选城市且没有添加客服每天弹窗一次
  130. if (this.$checkAccess.getCity() && this.$checkAccess.getFollowQrcode()) {
  131. // 获取弹出时间
  132. let followPopupTime = uni.getStorageSync('followPopupTime');
  133. // 现在的时候
  134. let nowTime = new Date().getTime();
  135. // 时间戳
  136. followPopupTime = followPopupTime ? followPopupTime : 0;
  137. // 弹出结果
  138. if (followPopupTime <= 0 || followPopupTime - nowTime > 86400000) {
  139. this.$refs.addFollow.open('center');
  140. uni.setStorageSync('followPopupTime', nowTime);
  141. }
  142. }
  143. this.isManager = this.$checkAccess.isManager();
  144. // 没有数据的话,或者请求中,不允许刷新
  145. if (this.isReqing) return;
  146. // 获取列表
  147. this.$http.request('/api/banner/get_list').then((re) => {
  148. if (re.code === 'success') {
  149. this.bannerList = re.data;
  150. }
  151. });
  152. // 请求参数
  153. this.requestParam.name = '';
  154. // 请求参数
  155. this.requestParam.page = 1;
  156. // 是否是最后一页
  157. this.isLast = false;
  158. // 设置请求中
  159. this.isReqing = true;
  160. // 请求
  161. this.$http.request('api/product/get_list', this.requestParam).then((re) => {
  162. // 设置非请求中
  163. this.isReqing = false;
  164. // 成功结果
  165. if (re.code == 'success') {
  166. // 如果是最后一页
  167. if (re.data.last_page <= this.requestParam.page) this.isLast = true;
  168. // 赋值
  169. this.productList = re.data.data;
  170. // 获取下一页
  171. this.getMore(re);
  172. }
  173. });
  174. },
  175. onPullDownRefresh() {
  176. // 如果请求中,不允许请求,
  177. if (this.isReqing) return false;
  178. // 初始化页码为1
  179. this.requestParam.page = 1;
  180. // 是否是最后一页
  181. this.isLast = false;
  182. // 设置请求中
  183. this.isReqing = true;
  184. // 请求列表
  185. this.$http.request('api/product/get_list', this.requestParam).then((re) => {
  186. // 设置非请求中
  187. this.isReqing = false;
  188. // 成功结果
  189. if (re.code == 'success') {
  190. // 如果是最后一页
  191. if (re.data.last_page <= this.requestParam.page) this.isLast = true;
  192. // 赋值
  193. this.productList = re.data.data;
  194. // 获取下一页
  195. this.getMore(re);
  196. }
  197. });
  198. uni.stopPullDownRefresh();
  199. },
  200. onReachBottom() {
  201. // 如果页码是0,避免第一页重复
  202. if (this.requestParam.page < 1) return;
  203. // 最后一页不再请求
  204. if (this.isLast) return;
  205. // 请求中,不再请求
  206. if (this.isReqing) return;
  207. // 增加一页
  208. this.requestParam.page = this.requestParam.page + 1;
  209. // 设置请求中
  210. this.isReqing = true;
  211. // 请求列表
  212. this.$http.request('api/product/get_list', this.requestParam).then((re) => {
  213. // 设置非请求中
  214. this.isReqing = false;
  215. // 成功结果
  216. if (re.code == 'success') {
  217. // 最后一页
  218. if (re.data.last_page <= this.requestParam.page) this.isLast = true;
  219. // 追加数据
  220. this.productList.push(...re.data.data);
  221. }
  222. });
  223. },
  224. methods: {
  225. // 请求加载下一页
  226. getMore(callback) {
  227. // 首页不足10个,并且下一页存在大于当前页
  228. if (this.productList.length < 10 && callback.data.last_page > this.requestParam.page) {
  229. // 最后一页不再请求
  230. if (this.isLast) return;
  231. // 增加一页
  232. this.requestParam.page = this.requestParam.page + 1;
  233. // 请求列表
  234. this.$http.request('api/product/get_list', this.requestParam).then((re) => {
  235. // 成功结果
  236. if (re.code == 'success') {
  237. // 最后一页
  238. if (re.data.last_page <= this.requestParam.page) this.isLast = true;
  239. // 追加数据
  240. this.productList.push(...re.data.data);
  241. // 获取下一页
  242. this.getMore(re);
  243. }
  244. });
  245. }
  246. },
  247. searchChange(e) {
  248. // 如果没有搜索词
  249. if (!this.requestParam.name) {
  250. this.searchOpen();
  251. }
  252. },
  253. searchOpen() {
  254. // 请求中,不再请求
  255. if (this.isReqing) return;
  256. // 是否是最后一页
  257. this.isLast = false;
  258. // 初始化页码为1
  259. this.requestParam.page = 1;
  260. // 设置请求中
  261. this.isReqing = true;
  262. // 请求列表
  263. this.$http.request('api/product/get_list', this.requestParam).then((re) => {
  264. // 设置非请求中
  265. this.isReqing = false;
  266. // 成功结果
  267. if (re.code == 'success') {
  268. this.productList = re.data.data;
  269. if (re.data.data.length && re.data.last_page >= this.requestParam.page) this.isLast = true;
  270. }
  271. });
  272. },
  273. toDetail(item) {
  274. uni.navigateTo({
  275. url: '/pages/product/index?product_id=' + item.id,
  276. });
  277. },
  278. navLottery(url) {
  279. // 没有路径,不跳转
  280. if (!url) return;
  281. // 判断是不是小程序链接
  282. if (url.includes('http')) {
  283. // 转码
  284. let link_url = encodeURIComponent(url);
  285. // 跳转到webview
  286. uni.redirectTo({
  287. url: `/pages/webview/index?link_url=${link_url}`,
  288. });
  289. } else {
  290. // 跳转到webview
  291. uni.navigateTo({
  292. url: url,
  293. });
  294. }
  295. },
  296. closePopup() {
  297. this.$refs.addFollow.close();
  298. //存key以及时间
  299. uni.setStorage({
  300. key: 'followPopupTime',
  301. data: new Date().getTime(),
  302. });
  303. },
  304. },
  305. };
  306. </script>
  307. <style lang="less" scoped>
  308. .page {
  309. width: 100vw;
  310. height: 100vh;
  311. display: flex;
  312. flex-direction: column;
  313. > image {
  314. width: 100%;
  315. position: sticky;
  316. margin-bottom: 20rpx;
  317. flex-shrink: 0;
  318. }
  319. .wait_content {
  320. position: absolute;
  321. bottom: 5%;
  322. left: 50%;
  323. transform: translate(-50%, -50%);
  324. font-size: 30rpx;
  325. color: #999;
  326. text-align: center;
  327. width: 550rpx;
  328. height: 75rpx;
  329. display: flex;
  330. justify-content: center;
  331. align-items: center;
  332. box-sizing: border-box;
  333. background-color: #ffffff;
  334. opacity: 0.9;
  335. border-radius: 20rpx;
  336. }
  337. > view {
  338. flex: 1;
  339. font-size: 30rpx;
  340. color: #999;
  341. display: flex;
  342. justify-content: center;
  343. align-items: center;
  344. }
  345. .product_box {
  346. display: block;
  347. padding: 0rpx 35rpx;
  348. .product_list {
  349. display: block;
  350. overflow: hidden;
  351. margin: 0rpx auto;
  352. .product_item {
  353. // float: left;
  354. width: 100%;
  355. // height: 520rpx;
  356. display: block;
  357. overflow: hidden;
  358. margin: 20rpx 0rpx;
  359. margin-right: 40rpx;
  360. background-color: #ffffff;
  361. border-radius: 20rpx;
  362. padding: 16rpx;
  363. box-sizing: border-box;
  364. .product_item_content {
  365. display: flex;
  366. gap: 10rpx;
  367. }
  368. .product_item_bottom {
  369. display: flex;
  370. justify-content: space-between;
  371. align-items: center;
  372. }
  373. .product_image_content {
  374. width: 168rpx;
  375. height: 168rpx;
  376. background: #f5f5f5;
  377. border-radius: 16rpx 16rpx 16rpx 16rpx;
  378. display: flex;
  379. align-items: center;
  380. justify-content: center;
  381. flex-shrink: 0;
  382. }
  383. .product_image {
  384. width: 143rpx;
  385. height: 149rpx;
  386. flex-shrink: 0;
  387. }
  388. .product_name {
  389. // height: 80rpx;
  390. font-size: 30rpx;
  391. line-height: 40rpx;
  392. overflow: hidden;
  393. margin: 10rpx 0rpx;
  394. padding: 0rpx 10rpx;
  395. text-overflow: ellipsis;
  396. .regiment_title {
  397. background-color: red;
  398. color: #f9f9f9;
  399. }
  400. }
  401. .product_spec {
  402. height: 30rpx;
  403. color: #999999;
  404. font-size: 24rpx;
  405. line-height: 30rpx;
  406. padding: 0rpx 10rpx;
  407. overflow: hidden;
  408. white-space: nowrap;
  409. text-overflow: ellipsis;
  410. }
  411. .stock_price {
  412. color: #dddddd;
  413. font-size: 20rpx;
  414. overflow: hidden;
  415. line-height: 30rpx;
  416. padding: 0rpx 10rpx;
  417. display: flex;
  418. gap: 10rpx;
  419. align-items: baseline;
  420. padding-left: 185rpx;
  421. box-sizing: border-box;
  422. .product_price {
  423. color: red;
  424. font-size: 30rpx;
  425. line-height: 60rpx;
  426. .product_market {
  427. font-size: 24rpx;
  428. color: #999999;
  429. line-height: 30rpx;
  430. vertical-align: top;
  431. text-decoration: line-through;
  432. }
  433. }
  434. .product_stock {
  435. font-size: 20rpx;
  436. line-height: 60rpx;
  437. }
  438. }
  439. .stock_button {
  440. width: 152rpx;
  441. height: 60rpx;
  442. background: #f89c33;
  443. border-radius: 500rpx 500rpx 500rpx 500rpx;
  444. color: #ffffff;
  445. color: 26rpx;
  446. text-align: center;
  447. line-height: 60rpx;
  448. font-size: 24rpx;
  449. }
  450. }
  451. .product_item:nth-child(even) {
  452. margin-right: 0rpx;
  453. }
  454. }
  455. }
  456. }
  457. </style>