lock.uvue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <script setup lang='ts'>
  2. import { type PropType } from 'vue'
  3. import { dict } from '@/.cool/store'
  4. import { wechatPay, wechatPayRequest, wechatPayQuery, wechatPayCancel } from '@/services/user'
  5. import { type SubjectCourseResult, fetchSubjectCourse } from '@/services/subject/course'
  6. import { user } from '@/.cool'
  7. import { ref } from 'vue'
  8. const emit = defineEmits(['close'])
  9. const props = defineProps({
  10. record: {
  11. type: Object,
  12. default: () => ({})
  13. },
  14. type: {
  15. type: String as PropType<'vip' | 'course'>,
  16. default: 'vip'
  17. },
  18. finish: {
  19. type: Boolean,
  20. default: true
  21. },
  22. studyUnitLock: {
  23. type: Boolean,
  24. default: false
  25. }
  26. })
  27. const visible = ref(false)
  28. const visible2 = ref(false)
  29. const visible3 = ref(false)
  30. const visible4 = ref(false)
  31. const msg = ref('')
  32. function handleOpen() {
  33. console.log(1)
  34. switch (props.type) {
  35. case 'course':
  36. if (!props.record.payFlag) {
  37. visible.value = true
  38. return
  39. }
  40. fetchSubjectCourse({
  41. id: props.record.id
  42. }).then(res => {
  43. if (res.studyUnitLock) {
  44. visible4.value = true
  45. msg.value = res.msg
  46. }
  47. })
  48. break;
  49. case 'vip':
  50. visible3.value = true
  51. break;
  52. }
  53. }
  54. async function getPayStatus(outTradeNo: string) {
  55. const res = await wechatPayQuery({
  56. outTradeNo
  57. })
  58. if (res.code !== 1000) {
  59. getPayStatus(outTradeNo)
  60. } else {
  61. emit('close', true)
  62. await user.get()
  63. }
  64. }
  65. const handlePay = async () => {
  66. try {
  67. const { prepayId, outTradeNo } = await wechatPay({
  68. subjectId: props.type === 'course' ? props.record.subjectId : dict.getValueByLabelMapByType('index_subject_id')['物理'],
  69. })
  70. const { signature, timestamp, nonceStr } = await wechatPayRequest({
  71. prepayId, outTradeNo
  72. })
  73. console.log(signature)
  74. uni.requestPayment({
  75. provider: "wxpay",
  76. timeStamp: timestamp,
  77. nonceStr: nonceStr,
  78. package: "prepay_id=" + prepayId,
  79. paySign: signature,
  80. signType: "RSA",
  81. success: (res) => {
  82. console.log('res: ', res)
  83. uni.showToast({
  84. title: "支付成功",
  85. icon: 'success'
  86. });
  87. // 支付成功后,查询支付结果
  88. getPayStatus(outTradeNo)
  89. },
  90. fail: (err) => {
  91. console.error("err", err);
  92. uni.hideLoading();
  93. // 支付失败后,取消订单
  94. wechatPayCancel({
  95. outTradeNo
  96. }).then(res => {
  97. if (res.code === 200) {
  98. uni.showToast({
  99. title: "订单已取消",
  100. icon: 'success'
  101. });
  102. emit('close', false)
  103. }
  104. })
  105. }
  106. });
  107. } catch (err: any) {
  108. uni.showToast({
  109. title: err.message,
  110. icon: 'error'
  111. });
  112. }
  113. }
  114. </script>
  115. <template>
  116. <view class="absolute top-0 left-0 w-full h-full flex items-center justify-center bg1" @tap.stop="handleOpen">
  117. <cl-image src="https://oss.xiaoxiongcode.com/static/home/lock.png" mode="widthFix" width="30%" height="auto" />
  118. </view>
  119. <cl-popup v-model="visible" showClose :size="400" :show-header="false" direction="center">
  120. <view class="p-[40px] ">
  121. <cl-text class="text-center" color="#000" :size="20"> 小朋友,快叫爸爸妈妈帮忙,解锁更多精彩内容吧! </cl-text>
  122. <cl-button class="mt-4" size="large" type="warn" block @tap="handlePay"> 前往购课 </cl-button>
  123. </view>
  124. </cl-popup>
  125. <cl-popup v-model="visible2" showClose :size="400" :show-header="false" direction="center">
  126. <view class="p-[40px] ">
  127. <cl-text class="text-center" color="#000" :size="20"> 请先学习完前面章节再来解锁! </cl-text>
  128. <cl-button class="mt-4" size="large" type="warn" block @tap="visible2 = false"> 返回 </cl-button>
  129. </view>
  130. </cl-popup>
  131. <cl-popup v-model="visible3" showClose :size="400" :show-header="false" direction="center">
  132. <view class="p-[40px] ">
  133. <cl-text class="text-center" color="#000" :size="20"> 小朋友,快叫爸爸妈妈帮忙成为会员,解锁更多精彩内容吧! </cl-text>
  134. <cl-text class="text-center" color="#666" :size="14"> 购买物理AI课后自动成为会员</cl-text>
  135. <cl-button class="mt-4" size="large" type="warn" block @tap="handlePay"> 前往购课 </cl-button>
  136. </view>
  137. </cl-popup>
  138. <cl-popup v-model="visible4" showClose :size="400" :show-header="false" direction="center">
  139. <view class="p-[40px] ">
  140. <cl-text class="text-center" color="#000" :size="20"> {{ msg }} </cl-text>
  141. <cl-button class="mt-4" size="large" type="warn" block @tap="visible4 = false"> 返回 </cl-button>
  142. </view>
  143. </cl-popup>
  144. </template>
  145. <style lang="scss" scoped>
  146. .bg1 {
  147. background-color: rgba(255, 255, 255, 0.5);
  148. }
  149. </style>