detail.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <template>
  2. <view class="container">
  3. <view>
  4. <swiper style="height: 240px;" indicator-dots="true" autoplay="true" interval="2000" duration="500">
  5. <swiper-item v-for="(image, index) in eventsInfo.imgList" :key="index">
  6. <image :src="image" class="slide-image"></image>
  7. </swiper-item>
  8. </swiper>
  9. <view class="section1">
  10. <view class="row">
  11. <view class="title">
  12. {{eventsInfo.title}}
  13. </view>
  14. </view>
  15. <view class="time_yuyue">
  16. <view class="ico">
  17. <image src="/static/images/time.png" style="width: 16px; height: 16px;"></image>
  18. </view>
  19. <view class="time">日期:{{eventsInfo.eventsDate}} 时间:{{eventsInfo.eventTime}}</view>
  20. </view>
  21. <view class="time_yuyue2" @click="onOpenMap">
  22. <view class="ico" >
  23. <image src="/static/images/daohang.png" style="width: 16px; height: 16px;"></image>
  24. </view>
  25. <view >{{eventsInfo.address}}</view>
  26. </view>
  27. <view class="kefu">
  28. <view class="didian">
  29. <button open-type="contact" hover-class="none" style="background: none; padding-right: 5px;">
  30. <uni-icons custom-prefix="custom-icon" type="chat" size="20" color="#999999"></uni-icons>
  31. </button>
  32. 联系客服工作人员
  33. </view>
  34. </view>
  35. <view class="title" style="text-align: left;">预订详细说明:</view>
  36. <view class="miaoshu" v-html="eventsInfo.intro" style="width:100%!important;">
  37. </view>
  38. <uni-popup ref="calenderPop">
  39. <view class="times">
  40. <view class="calender-box" style="background: #FFFFFF;">
  41. <view style="background: #FFFFFF;height: 110rpx;padding: 40rpx;box-sizing: border-box;
  42. display: flex;align-items: center;justify-content: space-between;border-top: 2rpx solid #F8F8F8;">
  43. <view style="color: #333333;font-size: 32rpx;font-weight: bold;">预约日期</view>
  44. <view style="display: flex;align-items: center;">
  45. <view class="DateText">
  46. <picker mode="date" :value="date" @change="onDateChange">
  47. <view class="date-picker">{{date}}</view>
  48. </picker>
  49. </view>
  50. <uni-icons type="right" color="#BCBCBC"></uni-icons>
  51. </view>
  52. </view>
  53. <view style="background: #FFFFFF;height: 110rpx;padding: 40rpx;box-sizing: border-box;
  54. display: flex;align-items: center;justify-content: space-between;border-top: 2rpx solid #F8F8F8;">
  55. <view style="color: #333333;font-size: 32rpx;font-weight: bold;">预约时间</view>
  56. <view style="display: flex;align-items: center;">
  57. <view class="DateText">
  58. <picker mode="time" :value="time" @change="bindTimeChange">
  59. <view class="uni-input">{{time}}</view>
  60. </picker>
  61. </view>
  62. <uni-icons type="right" color="#BCBCBC"></uni-icons>
  63. </view>
  64. </view>
  65. <!-- <uni-datetime-picker
  66. type="datetime"
  67. :clear-icon="false"
  68. v-model="single"
  69. @change="onChangeCalender"
  70. />
  71. <uni-calendar
  72. type="datetime"@maskClick="onChangeCalender"
  73. class="uni-calendar--hook"
  74. :lunar="true"
  75. :selected="planSelected"
  76. :showMonth="true"
  77. :startDate="startDate"
  78. @change="onChangeCalender"
  79. /> -->
  80. <!-- confirmCreateReq -->
  81. </view>
  82. <view style="background-color: #FFF; padding: 20px 20px; width: 100%;">
  83. <input @input='KeyName' placeholder='请输入留言' style="background-color: #FFFFFF; height:50px; border: 1px solid #ccc;width: 95%; padding-left: 20px; border-radius: 10px;"></input></view>
  84. </view>
  85. <view class="btn">
  86. <button @click="cancel">取消</button>
  87. <button @click="onChangeCalender">确定</button>
  88. </view>
  89. </uni-popup>
  90. </view>
  91. <view class="footer">
  92. <view class="footer-left">
  93. </view>
  94. <view style="width: 100%; padding: 20px 10px 20px 0px; font-weight: bold; color:black;">
  95. 预订价格:{{eventsInfo.fee}}</view>
  96. <view class="right">
  97. <text class="text" @click="onOpenTimer">确认预订</text>
  98. </view>
  99. </view>
  100. </view>
  101. <map id="map" ref="map" style="display: none;" v-if="eventsInfo && eventsInfo.id>0" :show-location="true"
  102. :latitude="eventsInfo.latitude" :longitude="eventsInfo.longitude"></map>
  103. </view>
  104. </template>
  105. <script>
  106. import {
  107. mapState,
  108. mapGetters,
  109. mapMutations
  110. } from 'vuex'
  111. import he from 'he';
  112. const app = getApp();
  113. export default {
  114. data() {
  115. return {
  116. eventId: null,
  117. info: null,
  118. eventsInfo: {},
  119. longitude: '',
  120. latitude: '',
  121. planSelected: [],
  122. startDate: '',
  123. dataForm: {
  124. id: 0,
  125. reqDate: '',
  126. userId: 0,
  127. memo:''
  128. },
  129. date: '请选择日期',
  130. time: '请选择时间'
  131. };
  132. },
  133. // onLoad(option) {
  134. // this.dataForm.id=option.id||0;
  135. // this.dataForm.userId = uni.getStorageSync("user_id");
  136. // },
  137. mounted() {
  138. this.fetchEventsDetail();
  139. },
  140. computed: {
  141. ...mapState(['store_id', 'systemInfo'])
  142. },
  143. onLoad(options) {
  144. this.eventId = options.id; // 获取传递的 id 参数
  145. this.dataForm.id=String(options.id)||'0';
  146. this.dataForm.userId = uni.getStorageSync("user_id");
  147. console.log(String(this.dataForm.userId));
  148. this.fetchEventsDetail();
  149. },
  150. methods: {
  151. // 会员充值end
  152. KeyName(t) {
  153. this.dataForm.memo = t.detail.value;
  154. },
  155. getNavigation({
  156. latitude,
  157. longitude,
  158. title,
  159. address,
  160. }) {
  161. uni.openLocation({
  162. latitude: Number(latitude),
  163. longitude: Number(longitude),
  164. address: address,
  165. name: title,
  166. success: function() {
  167. console.log('success');
  168. }
  169. });
  170. },
  171. //取消
  172. cancel() {
  173. this.date = '请选择日期'
  174. this.time = '请选择时间'
  175. this.$refs.calenderPop.close();
  176. },
  177. bindTimeChange(e) {
  178. this.time = e.detail.value
  179. },
  180. onDateChange(e) {
  181. this.date = e.detail.value;
  182. },
  183. onOpenTimer(e) {
  184. // if(this.plan==null){
  185. // uni.showToast({
  186. // title:"活动已过期,或暂无计划",
  187. // icon:"error"
  188. // })
  189. // return;
  190. // }
  191. this.$refs.calenderPop.open('bottom');
  192. let d = new Date();
  193. this.startDate = d.getFullYear() + "-" + (d.getMonth() + 1) + '-' + d.getDate();
  194. },
  195. onChangeCalender() {
  196. if (this.date === '请选择日期') {
  197. this.showToast('请选择预约日期');
  198. return;
  199. } else if (this.time === '请选择时间') {
  200. this.showToast('请选择预约时间');
  201. return;
  202. }
  203. this.dataForm.reqDate = this.date;
  204. // 微信小程序特定逻辑
  205. // #ifdef MP-WEIXIN
  206. console.log(this.dataForm.userId);
  207. if (this.dataForm.userId <= 0) {
  208. this.showToast("用户信息不存在");
  209. return false;
  210. }
  211. this.confirmCreateReq();
  212. // #endif
  213. // 非微信小程序平台
  214. // #ifndef MP-WEIXIN
  215. this.showToast('请使用小程序提交');
  216. // #endif
  217. },
  218. showToast(title) {
  219. uni.showToast({
  220. title: title,
  221. icon: 'none'
  222. });
  223. },
  224. onOpenMap(e) {
  225. console.log(112);
  226. let _this = this;
  227. _this._mapContext = uni.createMapContext("map", _this);
  228. _this._mapContext.openMapApp({
  229. longitude: parseFloat(_this.eventsInfo.longitude),//31.20393719991159
  230. latitude: parseFloat(_this.eventsInfo.latitude),//121.43760859966278
  231. destination: _this.eventsInfo.address,
  232. success: (res) => {
  233. console.log("success");
  234. },
  235. fail: (res) => {
  236. console.log("fail");
  237. },
  238. complete: (res) => {
  239. console.log(_this.info);
  240. }
  241. })
  242. },
  243. confirmCreateReq() {
  244. let _this = this;
  245. let orderObj = {
  246. orderTime: _this.time,
  247. orderDate: _this.date,
  248. userId: String(_this.dataForm.userId),
  249. eventId: String(_this.dataForm.id),
  250. memo:_this.dataForm.memo
  251. }
  252. uni.showModal({
  253. title: '确认预约',
  254. content: '您是否确认提交预约信息',
  255. cancelText: "取消",
  256. confirmText: "确认",
  257. success: (confirm) => {
  258. if (confirm.confirm) {
  259. _this.$http.request('events/createOrder', orderObj, "", "", true).then(
  260. res => {
  261. if (res.code == 200) {
  262. if (res.data.payStatus == '2') {
  263. //末支付
  264. // #ifdef MP-WEIXIN
  265. wx.requestPayment({
  266. timeStamp: res.data.params.timeStamp,
  267. nonceStr: res.data.params.nonceStr,
  268. package: res.data.params.package,
  269. signType: res.data.params.signType,
  270. paySign: res.data.params.paySign,
  271. success: (res) => {
  272. uni.showToast({
  273. title: '您的预约申请已成功提交',
  274. icon: 'success',
  275. success: (res) => {
  276. _this.$refs.calenderPop
  277. .close();
  278. }
  279. })
  280. },
  281. fail: (res) => {
  282. uni.showToast({
  283. title: '支付失败',
  284. icon: 'error',
  285. })
  286. }
  287. })
  288. // #endif
  289. } else {
  290. uni.showToast({
  291. title: '您的预约申请已成功提交',
  292. icon: 'success',
  293. success: () => {
  294. _this.$refs.calenderPop.close();
  295. }
  296. })
  297. }
  298. }
  299. }).catch(err => {})
  300. }
  301. }
  302. })
  303. },
  304. fetchEventsDetail() {
  305. let _this = this; // 使用 _this 来保持上下文一致性
  306. if (!_this.eventId) {
  307. console.error('无效的事件ID:', _this.eventId);
  308. return; // 如果 eventId 无效,则提前退出函数
  309. }
  310. _this.$http.request('events/eventInfo', {
  311. id: _this.eventId, // 确保使用 _this.eventId
  312. }).then(response => {
  313. console.log(response); // 先打印整个响应对象查看结构
  314. if (response && response.data) {
  315. _this.eventsInfo = response.data; // 确保 response.data 存在
  316. _this.eventsInfo.intro = he.decode(_this.eventsInfo.intro);
  317. _this.eventsInfo.intro = response.data.intro.replace(/\<img/gi, '<img style="max-width:100%;height:auto" ')
  318. console.log(_this.eventsInfo); // 打印 eventsInfo 确认数据
  319. } else {
  320. console.error('响应数据结构不符合预期:', response);
  321. }
  322. }).catch(error => {
  323. console.error('数据获取失败:', error);
  324. });
  325. }
  326. }
  327. }
  328. </script>
  329. <style lang="scss">
  330. @import './detail.scss';
  331. .miaoshu img {
  332. width: 100%!important;
  333. height: auto;
  334. object-fit: cover; // 保持图片的宽高比,填充整个内容框架
  335. }
  336. </style>