index.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. <template>
  2. <view class="signUp">
  3. <image class="good-img" :src="info.activityMain" mode="aspectFit"></image>
  4. <view class="goods-info">
  5. <view class="goods-name">
  6. {{ info.activityName }}
  7. </view>
  8. <view class="price-box" v-if="info.activityEnable == 1">
  9. <view class="left">
  10. <view class="unit">
  11. </view>
  12. <view class="price">
  13. {{ info.price }}
  14. </view>
  15. </view>
  16. </view>
  17. </view>
  18. <view class="list">
  19. <view class="item">
  20. <view class="label">
  21. 活动时间
  22. </view>
  23. <view class="value">
  24. {{ info.activityStartTime }} 至 {{ info.activityEndTime }}
  25. </view>
  26. </view>
  27. <view class="item" v-if="info.activityEnable == 1">
  28. <view class="label">
  29. 报名时间
  30. </view>
  31. <view class="value">
  32. {{ info.signupStartTime }} 至 {{ info.signupEndTime }}
  33. </view>
  34. </view>
  35. <view class="item" v-if="info.address">
  36. <view class="label">
  37. 活动地址
  38. </view>
  39. <view class="value">
  40. {{ info.address }}
  41. </view>
  42. </view>
  43. </view>
  44. <view class="sub-title">
  45. 活动详情
  46. </view>
  47. <view class="desc-box">
  48. <rich-text @longpress="goImgDetials" class="goods-desc" :nodes="info.activityDetail"></rich-text>
  49. </view>
  50. <view class="buy-box" v-if="info.activityEnable == 1 && !isEnd">
  51. <button class="buy-btn" type="default" @click="handleSignUp">报名</button>
  52. </view>
  53. </view>
  54. </template>
  55. <script>
  56. import { getActivityDetail } from '@/api/activity.js'
  57. export default {
  58. data() {
  59. return {
  60. id: 0,
  61. info: {},
  62. isEnd: false
  63. }
  64. },
  65. onShareTimeline() {
  66. return {
  67. title: this.info.activityName,
  68. query: `scene=${this.id}`,
  69. imageUrl: this.info.activityMain
  70. }
  71. },
  72. onShareAppMessage() {
  73. return {
  74. title: this.info.activityName,
  75. path: `/signUp/index?scene=${this.id}`,
  76. desc: '贵大印象文创'
  77. }
  78. },
  79. methods: {
  80. extractImageSrcFromHtml(htmlString) {
  81. // 正则表达式用于匹配 <img> 标签的 src 属性
  82. const regex = /<img[^>]+src="([^"]+)"[^>]*>/gi;
  83. let match;
  84. const result = [];
  85. // 执行正则表达式匹配,并收集所有匹配到的 src 属性
  86. while ((match = regex.exec(htmlString)) !== null) {
  87. result.push(match[1]); // match[1] 是正则表达式中的第一个捕获组,即 src 属性的值
  88. }
  89. return result;
  90. },
  91. goImgDetials(e) {
  92. // console.log('e', e);
  93. // console.log(this.info.activityDetail)
  94. const imgArr = this.extractImageSrcFromHtml(this.info.activityDetail)
  95. // console.log('imgArr', imgArr);
  96. // let item = e.detail.node;
  97. // if (item.name == "img") {
  98. uni.previewImage({
  99. urls: imgArr,
  100. longPressActions: {
  101. itemList: ["保存到相册", "识别二维码"],
  102. itemColor: "#007AFF",
  103. success: function (data) {
  104. let {
  105. tapIndex,
  106. index
  107. } = data;
  108. // tapIndex 第几个按钮
  109. // index 第几张图片
  110. if (tapIndex == 0) {
  111. // 保存到相册
  112. plus.gallery.save(imgArr[index], () => {
  113. uni.showToast({
  114. icon: "none",
  115. title: "保存成功!"
  116. })
  117. }, () => {
  118. uni.showToast({
  119. icon: "none",
  120. title: "保存失败!"
  121. })
  122. })
  123. } else {
  124. // 现将文件下载到本地
  125. uni.downloadFile({
  126. url: imgArr[index],
  127. success: (args) => {
  128. // 扫描二维码
  129. plus.barcode.scan(
  130. args.tempFilePath,
  131. (code, url) => {
  132. // 如果识别成功
  133. if (code == 0) {
  134. // 打开扫描结果
  135. plus.runtime.openURL(url)
  136. }
  137. },
  138. (err) => {
  139. uni.showToast({
  140. icon: 'none',
  141. title: "图中没有可识别的二维码"
  142. })
  143. console.log(err, 'err');
  144. },
  145. [plus.barcode.QR],
  146. true)
  147. },
  148. fail: () => {
  149. }
  150. })
  151. }
  152. }
  153. }
  154. })
  155. // }
  156. },
  157. handleSignUp() {
  158. let that = this
  159. let { activityStartTime, activityEndTime, limited, activityName, id, price, shopId } = this.info
  160. let obj = {
  161. activityStartTime,
  162. activityEndTime,
  163. limited,
  164. activityName,
  165. id,
  166. price,
  167. shopId
  168. }
  169. if (uni.getStorageSync('token')) {
  170. uni.setStorageSync('activity', JSON.stringify(obj))
  171. uni.navigateTo({
  172. url: '/signUp/makeOut?id=' + this.info.dataCollectId
  173. })
  174. } else {
  175. uni.showModal({
  176. title: '请登录',
  177. confirmText: '去登录',
  178. success(res) {
  179. console.log(res);
  180. if (res.confirm) {
  181. uni.navigateTo({
  182. url: `/login/login/login?redirect=/signUp/index&scene=${that.id}`
  183. })
  184. }
  185. }
  186. })
  187. }
  188. },
  189. getActivityDetail(id) {
  190. getActivityDetail({ id }).then(res => {
  191. if (res.state == 'Success') {
  192. this.info = res.content
  193. this.info.activityDetail = res.content.activityDetail.replace(/<img/gi, '<img class="img_class" ')
  194. uni.setNavigationBarTitle({
  195. title: this.info.activityName
  196. })
  197. if (new Date(this.info.activityEndTime).getTime() < new Date().getTime()) {//活动结束
  198. this.isEnd = true
  199. }
  200. }
  201. })
  202. }
  203. },
  204. onLoad(options) {
  205. console.log('options', options);
  206. this.id = decodeURIComponent(options.scene)
  207. this.getActivityDetail(this.id)
  208. }
  209. }
  210. </script>
  211. <style lang="scss">
  212. .signUp {
  213. background: #F9F9F9;
  214. padding-bottom: 200rpx;
  215. min-height: 100vh;
  216. .good-img {
  217. width: 100%;
  218. height: 750rpx;
  219. vertical-align: bottom;
  220. }
  221. .goods-info {
  222. padding: 24rpx;
  223. margin-bottom: 20rpx;
  224. background: #fff;
  225. .price-box {
  226. display: flex;
  227. justify-content: space-between;
  228. align-items: center;
  229. margin-top: 20rpx;
  230. .left {
  231. display: flex;
  232. align-items: flex-end;
  233. .unit {
  234. font-size: 20rpx;
  235. color: $uni-color-primary;
  236. font-weight: bold;
  237. }
  238. .price {
  239. font-size: 36rpx;
  240. color: $uni-color-primary;
  241. font-weight: bold;
  242. }
  243. }
  244. }
  245. .goods-name {
  246. font-size: 32rpx;
  247. color: #222222;
  248. font-weight: bold;
  249. }
  250. }
  251. .sub-title {
  252. font-weight: 600;
  253. font-size: 28rpx;
  254. color: #222222;
  255. padding: 24rpx;
  256. border-radius: 16rpx 16rpx 0 0;
  257. background: #fff;
  258. }
  259. .desc-box {
  260. .goods-desc {
  261. color: #222222;
  262. font-size: 24rpx;
  263. .img_class {
  264. max-width: 100% !important;
  265. vertical-align: bottom;
  266. }
  267. }
  268. }
  269. .list {
  270. background: #fff;
  271. margin-bottom: 20rpx;
  272. .item {
  273. padding: 24rpx;
  274. border-top: 1rpx solid #F0F0F0;
  275. .label {
  276. font-weight: 600;
  277. font-size: 28rpx;
  278. color: #222222;
  279. }
  280. .value {
  281. font-weight: 300;
  282. font-size: 24rpx;
  283. color: #AAAAAA;
  284. margin-top: 16rpx;
  285. line-height: 40rpx;
  286. }
  287. }
  288. }
  289. .buy-box {
  290. position: fixed;
  291. bottom: 0%;
  292. left: 0%;
  293. width: 100%;
  294. background: #fff;
  295. padding: 10rpx 24rpx env(safe-area-inset-bottom);
  296. border-top: 1rpx solid #EEEEEE;
  297. box-sizing: border-box;
  298. .buy-btn {
  299. width: 702rpx;
  300. height: 80rpx;
  301. line-height: 80rpx;
  302. text-align: center;
  303. background: $uni-color-primary;
  304. border-radius: 40rpx;
  305. font-weight: 600;
  306. font-size: 28rpx;
  307. color: #FFFFFF;
  308. }
  309. }
  310. }
  311. </style>