index.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <template>
  2. <up-popup :show="showPopup" :closeOnClickOverlay="true" @close="close">
  3. <view class="payment">
  4. <view class="title acea-row row-center-wrapper">
  5. 选择付款方式<text class="iconfont icon-guanbi" @click="close"></text>
  6. </view>
  7. <view
  8. class="item acea-row row-between-wrapper"
  9. @click="goPay(item)"
  10. v-for="(item, index) in payMode"
  11. :key="index"
  12. >
  13. <view class="left acea-row row-between-wrapper">
  14. <view class="iconfont" :class="item.icon"></view>
  15. <view class="text">
  16. <view class="name">{{ item.name }}</view>
  17. <view class="info" v-if="item.value === 'yue'">
  18. {{ item.title }}
  19. <span class="money">¥{{ appStore.userInfo.nowMoney }}</span>
  20. </view>
  21. <view class="info" v-else>{{ item.title }}</view>
  22. </view>
  23. </view>
  24. <!-- <view class="iconfont icon-xiangyou"></view> -->
  25. </view>
  26. </view>
  27. </up-popup>
  28. </template>
  29. <script setup>
  30. import { computed } from "vue";
  31. import { onLoad } from "@dcloudio/uni-app";
  32. import { usePayment } from "@/hooks/usePayment.js";
  33. import { wechatOrderPay, wechatQueryPayResult } from "@/api/order.js";
  34. import { useAppStore } from "@/stores/app";
  35. import { useToast } from "@/hooks/useToast";
  36. import { getUserInfo } from "@/api/user";
  37. const emit = defineEmits(["closePopup", "payComplete", "payFail"]);
  38. const { Toast } = useToast();
  39. const { submitPayment } = usePayment();
  40. const props = defineProps({
  41. mallType: {
  42. type: Number,
  43. default: 0, // 0: 水贝商城 1: 贝币商城
  44. },
  45. payMode: {
  46. type: Array,
  47. default: () => [],
  48. },
  49. showPopup: {
  50. type: Boolean,
  51. default: false,
  52. },
  53. order_id: {
  54. type: String,
  55. default: "",
  56. },
  57. totalPrice: {
  58. type: String,
  59. default: "0",
  60. },
  61. });
  62. const appStore = useAppStore();
  63. const systemPlatform = computed(() => appStore.systemPlatform);
  64. function close() {
  65. // emit("onChangeFun", { action: "payClose" });
  66. emit("closePopup");
  67. }
  68. async function fetchUserInfo() {
  69. const { data } = await getUserInfo();
  70. appStore.UPDATE_USERINFO(data);
  71. }
  72. onLoad(() => {
  73. fetchUserInfo();
  74. });
  75. async function goPay(item) {
  76. try {
  77. const number = item.number || 0;
  78. const paytype = item.value;
  79. let goPages = "/pages/order_pay_status/index?order_id=" + props.order_id;
  80. if (!props.order_id) {
  81. return Toast({ title: "请选择要支付的订单" });
  82. }
  83. if (
  84. paytype === "yue" &&
  85. parseFloat(number) < parseFloat(props.totalPrice)
  86. ) {
  87. return Toast({ title: "余额不足!" });
  88. }
  89. uni.showLoading({ title: "支付中" });
  90. const params = {
  91. mallType: props.mallType,
  92. orderNo: props.order_id,
  93. payChannel: item.payChannel,
  94. payType: paytype,
  95. };
  96. const res = await wechatOrderPay(params);
  97. let jsConfig = res.data.jsConfig;
  98. let orderId = res.data.orderNo;
  99. switch (res.data.payType) {
  100. case "alipay":
  101. const result = await submitPayment({
  102. type: res.data.payType,
  103. orderInfo: res.data.alipayRequest,
  104. });
  105. if (result && result.status === "success") {
  106. emit("payComplete");
  107. return Toast(
  108. { title: result.message, icon: "success" },
  109. { tab: 4, url: goPages }
  110. );
  111. } else {
  112. emit("payFail", { message: result.message || "支付失败" });
  113. return Toast(
  114. { title: result.message },
  115. { tab: 5, url: goPages + "&status=0" }
  116. );
  117. }
  118. break;
  119. case "yue":
  120. Toast(
  121. { title: "余额支付成功", icon: "success" },
  122. { tab: 4, url: goPages }
  123. );
  124. emit("payComplete");
  125. break;
  126. case "weixinh5":
  127. location.replace(
  128. jsConfig.mwebUrl +
  129. "&redirect_url=" +
  130. window.location.protocol +
  131. "//" +
  132. window.location.host +
  133. goPages +
  134. "&status=1"
  135. );
  136. Toast({ title: "支付中" });
  137. emit("payComplete");
  138. break;
  139. case "weixinApp":
  140. const wxPayResult = await submitPayment({
  141. type: res.data.payType,
  142. orderInfo: res.data.prepayWithRequestPaymentResponse,
  143. });
  144. let wxPayFailMsg = wxPayResult?.message || "支付失败";
  145. if (wxPayResult.status === "支付成功") {
  146. emit("payComplete");
  147. return Toast(
  148. { title: "支付成功", icon: "success" },
  149. { tab: 4, url: goPages }
  150. );
  151. } else if (wxPayResult.status === "支付失败") {
  152. emit("payFail", { message: wxPayFailMsg });
  153. return Toast(
  154. { title: "支付失败" },
  155. { tab: 5, url: `${goPages}&msg=${wxPayFailMsg}` }
  156. );
  157. } else if (wxPayResult.status === "用户取消支付") {
  158. emit("payFail", { message: "用户取消支付" });
  159. return Toast(
  160. { title: "用户取消支付" },
  161. {
  162. tab: 5,
  163. url: `${goPages}&msg=用户取消支付`,
  164. }
  165. );
  166. }
  167. break;
  168. }
  169. } catch (error) {
  170. console.error("goPay error", error);
  171. emit("payFail", { message: error.message || error.msg || "支付失败" });
  172. return Toast({
  173. title: error.message || error.msg || "支付失败",
  174. });
  175. } finally {
  176. uni.hideLoading();
  177. }
  178. }
  179. </script>
  180. <style scoped lang="scss">
  181. .payment {
  182. background-color: #fff;
  183. }
  184. .payment .title {
  185. text-align: center;
  186. height: 123rpx;
  187. font-size: 32rpx;
  188. color: #282828;
  189. font-weight: bold;
  190. padding-right: 30rpx;
  191. margin-left: 30rpx;
  192. position: relative;
  193. border-bottom: 1rpx solid #eee;
  194. }
  195. .payment .title .iconfont {
  196. position: absolute;
  197. right: 30rpx;
  198. top: 50%;
  199. transform: translateY(-50%);
  200. font-size: 43rpx;
  201. color: #8a8a8a;
  202. font-weight: normal;
  203. }
  204. .payment .item {
  205. border-bottom: 1rpx solid #eee;
  206. height: 130rpx;
  207. margin-left: 30rpx;
  208. padding-right: 30rpx;
  209. }
  210. .payment .item .left {
  211. width: 610rpx;
  212. }
  213. .payment .item .left .text {
  214. width: 540rpx;
  215. }
  216. .payment .item .left .text .name {
  217. font-size: 32rpx;
  218. color: #282828;
  219. }
  220. .payment .item .left .text .info {
  221. font-size: 24rpx;
  222. color: #999;
  223. }
  224. .payment .item .left .text .info .money {
  225. color: #ff9900;
  226. }
  227. .payment .item .left .iconfont {
  228. font-size: 45rpx;
  229. color: #09bb07;
  230. }
  231. .payment .item .left .iconfont.icon-zhifubao {
  232. color: #00aaea;
  233. }
  234. .payment .item .left .iconfont.icon-balance {
  235. color: #ff9900;
  236. font-size: 50rpx;
  237. }
  238. .payment .item .left .iconfont.icon-yuezhifu1 {
  239. color: #eb6623;
  240. }
  241. .payment .item .iconfont {
  242. font-size: 0.3rpx;
  243. color: #999;
  244. }
  245. </style>