index.vue 13 KB

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