index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. <template>
  2. <view class="index">
  3. <!-- 头部功能组件 -->
  4. <cu-loadding :show="show" />
  5. <!-- header -->
  6. <cu-custom bgColor="bg-gradual-blue">
  7. <view slot="content">{{ value.title }}</view>
  8. </cu-custom>
  9. <!-- section -->
  10. <!-- 富文本 -->
  11. <rich-text style="width: 100vw;" :nodes="value.describe"></rich-text>
  12. <!-- 输入表单 -->
  13. <view class="titles" style="background-color: #f60d11;">
  14. <view class="bg-pink light"></view>
  15. <view>填写信息</view>
  16. </view>
  17. <view style="background-color: #f60d11;" class="from padding-lr padding-bottom">
  18. <view style="border-radius: 20rpx;" class="bg-white padding-bottom padding-top-xl">
  19. <form>
  20. <view class="cu-form-group">
  21. <view class="title text-bold text-black">门店名称</view>
  22. <view style="flex: 1;" class="text-bold text-black">{{ value.branch_name }}</view>
  23. </view>
  24. <view class="cu-form-group">
  25. <view class="title text-bold text-black">门店地址</view>
  26. <view style="flex: 1;" class="text-bold text-black">{{ value.branch_address }}</view>
  27. <text style="color:#f60d11;" class="cuIcon-locationfill"></text>
  28. </view>
  29. <view class="cu-form-group">
  30. <view class="title text-bold text-black">服务电话</view>
  31. <view style="flex: 1;" class="text-bold text-black">{{ value.branch_tel }}</view>
  32. <van-icon size="16" color="#f60d11" name="phone" />
  33. </view>
  34. <view class="cu-form-group">
  35. <view class="title text-bold text-black">填写姓名</view>
  36. <input type="text" class="text-bold text-black" v-model="formData.name" placeholder="请输入车型" />
  37. </view>
  38. <view class="cu-form-group">
  39. <view class="title text-bold text-black">填写车型</view>
  40. <input type="text" class="text-bold text-black" v-model="formData.model" placeholder="请输入车型" />
  41. </view>
  42. <view class="cu-form-group">
  43. <view class="title text-bold text-black">车牌号码</view>
  44. <view style="flex: auto;"><key-code :value.sync="formData.number" /></view>
  45. </view>
  46. <view class="cu-form-group">
  47. <view class="title text-bold text-black">手机号码</view>
  48. <input type="number" confirm-type="done" @confirm="submit" class="text-bold text-black" v-model="formData.tel" placeholder="请输入手机号码" />
  49. </view>
  50. <view class="cu-form-group justify-center">
  51. <view style="width: 300rpx;">
  52. <van-button :loading="loading" color="#f60d11" @click="submit" size="small" block round type="info">提交信息</van-button>
  53. </view>
  54. </view>
  55. </form>
  56. </view>
  57. </view>
  58. <!-- 历史购买记录 -->
  59. <view class="titles " style="background-color: #f60d11;">
  60. <view class="bg-pink light"></view>
  61. <view class="text-center">已有{{ historyData.totalResult }}人购买</view>
  62. </view>
  63. <view style="background-color: #f60d11;" class="padding-lr padding-bottom">
  64. <view style="border-radius: 20rpx;flex-wrap: wrap;" class="padding-bottom padding-top-xl bg-white ">
  65. <view class="flex padding-tb">
  66. <view style="width: 20%;" class="text-center text-bold text-black">序号</view>
  67. <view style="width: 25%;" class="text-center text-bold text-black">车牌号码</view>
  68. <view style="width: 25%;" class="text-center text-bold text-black">卡卷状态</view>
  69. <view style="width: 30%;" class="text-center text-bold text-black">购买时间</view>
  70. </view>
  71. <view v-for="(item, index) of historyData.value" :key="index" class="flex padding-tb-sm border">
  72. <view style="width: 20%;" class="text-center text-cut">{{ index + 1 }}</view>
  73. <view style="width: 25%;" class="text-center text-cut">{{ item.number }}</view>
  74. <view style="width: 25%;" class="text-center text-cut">已经领取</view>
  75. <view style="width: 30%;" class="text-center text-cut">{{ item.create_time }}</view>
  76. </view>
  77. <view v-if="btnShow" class="flex justify-center padding">
  78. <view style="width: 300rpx;"><van-button color="#f60d11" @click="more" size="small" block round type="info">查看更多</van-button></view>
  79. </view>
  80. </view>
  81. </view>
  82. <!-- footer -->
  83. <!-- 个人中心 -->
  84. <view
  85. @click="personal"
  86. style="width:120rpx ;height:120rpx;box-shadow: 0rpx 0rpx 20rpx #aaa;position: fixed;right: 40rpx;bottom: 30vh;z-index: 9999;"
  87. class=" bg-orange light round padding-sm flex align-center justify-center"
  88. >
  89. <view class="text-center ">
  90. <text class="cuIcon-peoplefill text-xl"></text>
  91. <view class="text-xs">个人中心</view>
  92. </view>
  93. </view>
  94. <!-- 生成海报 -->
  95. <view
  96. @click="pic"
  97. style="width:120rpx ;height:120rpx;box-shadow: 0rpx 0rpx 20rpx #aaa;position: fixed;right: 40rpx;bottom: 18vh;z-index: 9999;"
  98. class=" bg-orange light round padding-sm flex align-center justify-center"
  99. >
  100. <view class="text-center ">
  101. <text class="cuIcon-pic text-xl"></text>
  102. <view class="text-xs">生成海报</view>
  103. </view>
  104. </view>
  105. <!-- 底部功能栏 -->
  106. <view style="height: 50px;">
  107. <van-submit-bar :loading="loading" :price="value.amount * 100" button-text="立即购买" @submit="submit">
  108. <view @click="consult">
  109. <van-icon name="service-o"></van-icon>
  110. <text>咨询</text>
  111. </view>
  112. </van-submit-bar>
  113. </view>
  114. <!-- 微信快捷登录 -->
  115. <van-dialog
  116. message="尚未登录"
  117. confirmButtonText="微信快捷登录"
  118. :show="dialog"
  119. id="van-dialog"
  120. show-cancel-button
  121. @close="dialog = false"
  122. confirm-button-open-type="getPhoneNumber"
  123. @getphonenumber="getphonenumber"
  124. />
  125. </view>
  126. </template>
  127. <script>
  128. import keyCode from './components/keyCode.vue';
  129. import Dialog from '@/wxcomponents/vant/dist/dialog/dialog';
  130. export default {
  131. components: {
  132. keyCode
  133. },
  134. data() {
  135. return {
  136. show: true, //加载
  137. btnShow: true, //查看更多
  138. loading: false, //立即支付
  139. dialog: false, //微信快捷登录
  140. value: {},
  141. // 提交文本
  142. formData: {
  143. name: '',
  144. tel: '',
  145. model: '',
  146. number: ''
  147. },
  148. // 购买数据
  149. historyData: {
  150. totalResult: '',
  151. currentPage: 1,
  152. totalPage: 1,
  153. value: []
  154. }
  155. };
  156. },
  157. onLoad(options) {
  158. this.getOptions(options);
  159. this.initRequest();
  160. },
  161. // 分享朋友
  162. onShareAppMessage: function(e) {
  163. return {
  164. title: this.value.title,
  165. // imageUrl:""
  166. path: `/pages/index/index?customer_id=${this.$store.state.userInfo.user_id || ''}&activity_id=${this.$store.state.userInfo.activity_id}`
  167. };
  168. },
  169. // 分享朋友圈
  170. onShareTimeline: function(res) {
  171. return {
  172. title: this.value.title,
  173. // imageUrl:"",
  174. query: `customer_id=${this.$store.state.userInfo.user_id || ''}&activity_id=${this.$store.state.userInfo.activity_id}`
  175. };
  176. },
  177. methods: {
  178. // 接受参数
  179. getOptions(options) {
  180. var result = {};
  181. if (options.scene) {
  182. result = this.$global.qrcodeValue(options.scene);
  183. } else {
  184. result = options;
  185. }
  186. console.log(result);
  187. this.$store.commit('userInfo', result);
  188. },
  189. // 微信快捷登录
  190. async getphonenumber(e) {
  191. try {
  192. var { encryptedData, iv } = e.detail;
  193. var { openid, appid, activity_id } = this.$store.state.userInfo;
  194. var res = await this.$global.request({ url: '/customer/wxbind/', method: 'post', data: { openid, appid, activity_id, encryptedData, iv } });
  195. if (res.data.token) uni.setStorageSync('token', 'JWT ' + res.data.token);
  196. this.$store.commit('userInfo', res.data);
  197. uni.showToast({
  198. icon: 'none',
  199. title: '登录成功'
  200. });
  201. } catch (err) {
  202. this.showErr(err);
  203. } finally {
  204. this.show = false;
  205. }
  206. },
  207. // 报错
  208. showErr(content) {
  209. content = JSON.stringify(content) === '{}' ? '未知错误' : content;
  210. uni.showModal({
  211. content,
  212. showCancel: false,
  213. success: res => console.log(res)
  214. });
  215. },
  216. // 进入页面请求
  217. async initRequest() {
  218. try {
  219. var { appid, code } = await this.codeAppid();
  220. // codeSession
  221. var res = await this.$global.request({
  222. url: '/customer/code2Session/',
  223. method: 'post',
  224. data: {
  225. code,
  226. appid,
  227. activity_id: this.$store.state.userInfo.activity_id || ''
  228. }
  229. });
  230. if (res.data.token) uni.setStorageSync('token', 'JWT ' + res.data.token);
  231. this.$store.commit('userInfo', { appid, code, ...res.data });
  232. // 活动详情
  233. res = await this.$global.request({
  234. url: '/customer/activity/detail/',
  235. method: 'get',
  236. data: {
  237. activity_id: this.$store.state.userInfo.activity_id
  238. // appid:this.$store.state.userInfo.appid
  239. }
  240. });
  241. // 富文本处理
  242. res.data.describe = this.$global.richTextChange(res.data.describe);
  243. this.value = res.data;
  244. // 已有人购买
  245. this.payed();
  246. } catch (err) {
  247. this.showErr(err);
  248. } finally {
  249. this.show = false;
  250. }
  251. },
  252. // 请求购买情况
  253. async payed() {
  254. try {
  255. var { currentPage, totalPage, value } = this.historyData;
  256. var res = await this.$global.request({
  257. url: '/customer/order/activity_order/',
  258. method: 'get',
  259. data: {
  260. activity_id: this.$store.state.userInfo.activity_id,
  261. limit: 5,
  262. page: currentPage
  263. }
  264. });
  265. currentPage++;
  266. totalPage = res.totalPage;
  267. value = value.concat(res.data);
  268. if (currentPage > totalPage) this.btnShow = false;
  269. this.historyData = { value, currentPage, totalPage, totalResult: res.totalResult };
  270. } catch (err) {
  271. this.showErr(err);
  272. }
  273. },
  274. // 获取 code appid
  275. codeAppid() {
  276. return new Promise((resolve, reject) => {
  277. const appid = uni.getAccountInfoSync().miniProgram.appId;
  278. uni.login({ success, fail: err => reject(err) });
  279. function success(res) {
  280. var { code } = res;
  281. resolve({ code, appid });
  282. }
  283. });
  284. },
  285. // 提交信息
  286. async submit() {
  287. // 验证登录状态
  288. if (!uni.getStorageSync('token')) {
  289. this.dialog = true;
  290. return false;
  291. }
  292. try {
  293. this.loading = true;
  294. var res = await this.$global.request({
  295. url: '/customer/order/',
  296. method: 'post',
  297. header: {
  298. 'Content-Type': 'application/x-www-form-urlencoded',
  299. Authorization: uni.getStorageSync('token')
  300. },
  301. data: {
  302. appid: this.$store.state.userInfo.appid,
  303. activity_id: this.$store.state.userInfo.activity_id,
  304. activity: this.$store.state.userInfo.activity_id,
  305. openid: this.$store.state.userInfo.openid,
  306. recommend_member: this.$store.state.userInfo.customer_id || '',
  307. ...this.formData
  308. }
  309. });
  310. this.signature(res.data);
  311. } catch (err) {
  312. this.showErr(err);
  313. } finally {
  314. this.loading = false;
  315. }
  316. },
  317. // 支付签名
  318. signature(data) {
  319. uni.requestPayment({
  320. timeStamp: data.timeStamp,
  321. nonceStr: data.nonceStr,
  322. package: data.package,
  323. signType: data.signType,
  324. paySign: data.paySign,
  325. success() {
  326. uni.showToast({
  327. icon: 'none',
  328. title: '支付成功'
  329. });
  330. },
  331. fail() {
  332. uni.showToast({
  333. icon: 'none',
  334. title: '支付失败'
  335. });
  336. }
  337. });
  338. },
  339. // 查看更多
  340. more() {
  341. this.payed();
  342. },
  343. // 我要咨询
  344. consult() {
  345. if (this.value.branch_tel)
  346. uni.makePhoneCall({
  347. phoneNumber: this.value.branch_tel
  348. });
  349. },
  350. // 个人中心
  351. personal() {
  352. uni.navigateTo({
  353. url: '/pages/login/index'
  354. });
  355. },
  356. // 生成海报
  357. pic() {
  358. // 验证登录状态
  359. if (!uni.getStorageSync('token')) {
  360. this.dialog = true;
  361. return false;
  362. }
  363. uni.navigateTo({
  364. url: '/pages/pic/index'
  365. });
  366. }
  367. }
  368. };
  369. </script>
  370. <style lang="scss" scoped>
  371. .index {
  372. .titles {
  373. padding-top: 30rpx;
  374. position: relative;
  375. > view:nth-child(1) {
  376. position: relative;
  377. width: 340rpx;
  378. height: 40rpx;
  379. left: calc(50% - 170rpx);
  380. &::before {
  381. content: '';
  382. position: absolute;
  383. display: table;
  384. border-right: 20rpx solid transparent;
  385. border-top: 40rpx solid #f60d11;
  386. }
  387. &::after {
  388. content: '';
  389. position: absolute;
  390. right: 0;
  391. display: table;
  392. border-left: 20rpx solid transparent;
  393. border-top: 40rpx solid #f60d11;
  394. }
  395. }
  396. > view:nth-child(2) {
  397. border-radius: 15rpx;
  398. width: 300rpx;
  399. color: #f60d11;
  400. position: absolute;
  401. left: calc(50% - 150rpx);
  402. box-sizing: border-box;
  403. top: 25rpx;
  404. padding: 20rpx 0;
  405. text-align: center;
  406. font-size: 34rpx;
  407. background-image: linear-gradient(to bottom, #fff, #f9bcc7);
  408. }
  409. }
  410. }
  411. </style>