success.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. <template>
  2. <view class="content">
  3. <view class="inner y-bc">
  4. <view class="box-img y-bc">
  5. <image src="@/static/images/wallet/withdrawal_successful.png"></image>
  6. <view class="title">{{statusTitle}}</view>
  7. <text class="desc">{{statusDesc}}</text>
  8. </view>
  9. <view class="btn-box">
  10. <view class="btn" @click="navTo">提现记录</view>
  11. <view class="btn back" v-if="canConfirmReceipt" @click="confirmReceipt">确认收款</view>
  12. <view class="btn back" v-if="canWithdrawAgain" @click="withdrawAgain">再次提现</view>
  13. <view class="btn back" v-if="!canWithdrawAgain && !canConfirmReceipt" @click="goBack()">返回</view>
  14. </view>
  15. </view>
  16. </view>
  17. </template>
  18. <script>
  19. import {getRedPacketLogByCode} from '@/api/integral.js'
  20. export default {
  21. data() {
  22. return {
  23. order:null,
  24. orderCode: null,
  25. }
  26. },
  27. computed: {
  28. // 根据订单状态显示标题
  29. statusTitle() {
  30. if (!this.order || this.order.status === undefined) {
  31. return '提现申请成功';
  32. }
  33. const status = Number(this.order.status);
  34. console.log("提现状态",this.order.status,status)
  35. // -3取消中 -2取消 -1失败 0发送中 1已发送 2取消 3转账处理中 4待收款用户确认 5转账结果尚未明确
  36. if (status === -3) {
  37. return '取消中';
  38. } else if (status === -2 || status === 2) {
  39. return '已取消';
  40. } else if (status === -1) {
  41. return '提现失败';
  42. } else if (status === 0) {
  43. return '发送中';
  44. } else if (status === 1) {
  45. return '提现申请成功';
  46. } else if (status === 3) {
  47. return '转账处理中';
  48. } else if (status === 4) {
  49. return '待确认收款';
  50. } else if (status === 5) {
  51. return '待确认收款';
  52. } else {
  53. return '提现申请成功';
  54. }
  55. },
  56. // 根据订单状态显示描述
  57. statusDesc() {
  58. if (!this.order || this.order.status === undefined) {
  59. return '预计两小时到账';
  60. }
  61. const status = Number(this.order.status);
  62. if (status === -3) {
  63. return this.order.remark || '提现正在取消中';
  64. } else if (status === -2 || status === 2) {
  65. return this.order.remark || '提现已取消';
  66. } else if (status === -1) {
  67. return this.order.remark || '提现失败,请重试';
  68. } else if (status === 0) {
  69. return this.order.remark || '提现请求已发送,正在处理中';
  70. } else if (status === 1) {
  71. return this.order.remark || '预计两小时到账';
  72. } else if (status === 3) {
  73. return this.order.remark || '转账正在处理中,请稍候';
  74. } else if (status === 4) {
  75. return '待收款确认,请在24小时内确认收款';
  76. } else if (status === 5) {
  77. return '转账结果尚未明确,请在24小时内确认收款';
  78. } else {
  79. return '预计两小时到账';
  80. }
  81. },
  82. // 是否可以再次提现(失败、取消等状态可以再次提现)
  83. canWithdrawAgain() {
  84. if (!this.order || this.order.status === undefined) {
  85. return false;
  86. }
  87. const status = Number(this.order.status);
  88. // 失败(-1)、取消(-2,2)状态可以再次提现
  89. return status === -1 || status === -2 || status === 2;
  90. },
  91. // 是否可以确认收款(状态4和5可以拉起微信收款确认页面)
  92. canConfirmReceipt() {
  93. if (!this.order || this.order.status === undefined) {
  94. return false;
  95. }
  96. const status = Number(this.order.status);
  97. // 状态4和5可以确认收款
  98. return status === 4 || status === 5;
  99. }
  100. },
  101. onLoad(option) {
  102. // 兼容旧的order参数
  103. if (option.order) {
  104. try {
  105. this.order = JSON.parse(option.order);
  106. } catch (e) {
  107. console.error('解析order参数失败:', e);
  108. }
  109. }
  110. // 获取orderCode参数
  111. if (option.orderCode) {
  112. this.orderCode = option.orderCode;
  113. // 确认收款后查询订单状态
  114. this.getRedPacketLogByCode(option.orderCode);
  115. }
  116. },
  117. onShow() {
  118. // 如果页面显示时已有orderCode,再次查询订单状态(用户从微信返回时)
  119. if (this.orderCode) {
  120. this.getRedPacketLogByCode(this.orderCode);
  121. }
  122. },
  123. methods: {
  124. getWxMerchantTransferPlugin() {
  125. const pluginIds = ['wxMerchantTransfer'];
  126. for (let i = 0; i < pluginIds.length; i++) {
  127. const pluginId = pluginIds[i];
  128. try {
  129. const plugin = uni.requireNativePlugin(pluginId);
  130. if (plugin && typeof plugin.open === 'function') {
  131. return plugin;
  132. }
  133. } catch (error) {}
  134. }
  135. return null;
  136. },
  137. encodeWechatTransferPackage(value) {
  138. return encodeURIComponent(String(value || '')).replace(/[!'()*]/g, ch => {
  139. return '%' + ch.charCodeAt(0).toString(16).toUpperCase();
  140. });
  141. },
  142. resolveWxUniversalLink() {
  143. const app = typeof getApp === 'function' ? getApp() : null;
  144. const fromGlobal = app && app.globalData ? app.globalData.wxUniversalLink : '';
  145. const candidates = [
  146. fromGlobal,
  147. 'https://rtlink.ylrzcloud.com/uni-universallinks/__UNI__33EAA2D/',
  148. 'https://yjf.runtzh.com/'
  149. ];
  150. for (let i = 0; i < candidates.length; i++) {
  151. const link = String(candidates[i] || '')
  152. .replace(/[`'"]/g, '')
  153. .trim();
  154. if (link && /^https?:\/\//i.test(link)) {
  155. return link;
  156. }
  157. }
  158. return '';
  159. },
  160. openWxMerchantTransferByPlusIos(params, callback) {
  161. try {
  162. if (typeof plus === 'undefined' || !plus.ios || plus.os.name !== 'iOS') {
  163. return false;
  164. }
  165. let WXApi = null;
  166. try {
  167. WXApi = plus.ios.importClass('WXApi');
  168. } catch (error) {
  169. WXApi = plus.ios.import('WXApi');
  170. }
  171. const req = plus.ios.newObject('WXOpenBusinessViewReq');
  172. if (!WXApi || !req) {
  173. return false;
  174. }
  175. const universalLink = this.resolveWxUniversalLink();
  176. let registerState = 'skip';
  177. let installedState = 'unknown';
  178. let supportState = 'unknown';
  179. let apiVersion = '';
  180. if (params.appId) {
  181. try {
  182. if (universalLink) {
  183. registerState = String(!!plus.ios.invoke(WXApi, 'registerApp:universalLink:', String(params.appId), universalLink));
  184. } else {
  185. registerState = String(!!plus.ios.invoke(WXApi, 'registerApp:', String(params.appId)));
  186. }
  187. } catch (error) {
  188. registerState = 'error';
  189. }
  190. }
  191. try {
  192. installedState = String(!!plus.ios.invoke(WXApi, 'isWXAppInstalled'));
  193. } catch (error) {}
  194. try {
  195. supportState = String(!!plus.ios.invoke(WXApi, 'isWXAppSupportApi'));
  196. } catch (error) {}
  197. try {
  198. apiVersion = String(plus.ios.invoke(WXApi, 'getApiVersion') || '');
  199. } catch (error) {}
  200. plus.ios.invoke(req, 'setBusinessType:', 'requestMerchantTransfer');
  201. const encodedPackage = this.encodeWechatTransferPackage(params.package);
  202. const query = `mchId=${params.mchId}&appId=${params.appId}&package=${encodedPackage}`;
  203. plus.ios.invoke(req, 'setQuery:', query);
  204. const sent = plus.ios.invoke(WXApi, 'sendReq:', req);
  205. plus.ios.deleteObject(req);
  206. if (typeof callback === 'function') {
  207. const failMessage = `微信唤起失败,请确认微信可用后重试(appId=${params.appId}, universalLink=${universalLink || 'empty'}, registered=${registerState}, installed=${installedState}, supportApi=${supportState}, apiVersion=${apiVersion || 'unknown'},请检查 universalLink 域名证书是否过期)`;
  208. callback(sent ? { code: 0, message: 'Request sent successfully' } : { code: -2, message: failMessage });
  209. }
  210. return true;
  211. } catch (error) {
  212. console.error('openWxMerchantTransferByPlusIos failed', error);
  213. if (typeof callback === 'function') {
  214. callback({ code: -2, message: error && error.message ? error.message : 'Failed to send request' });
  215. }
  216. return true;
  217. }
  218. },
  219. openWxMerchantTransfer(params, callback) {
  220. if (typeof plus !== 'undefined' && plus.os && plus.os.name === 'iOS') {
  221. const iosHandled = this.openWxMerchantTransferByPlusIos(params, callback);
  222. if (iosHandled) {
  223. return;
  224. }
  225. }
  226. const wxMerchantTransfer = this.getWxMerchantTransferPlugin();
  227. if (wxMerchantTransfer && typeof wxMerchantTransfer.open === 'function') {
  228. wxMerchantTransfer.open(params, callback);
  229. return;
  230. }
  231. if (typeof callback === 'function') {
  232. callback({ code: -5, message: '微信转账功能未正确初始化,请检查基座插件配置。' });
  233. }
  234. },
  235. // 查询订单状态
  236. getRedPacketLogByCode(code) {
  237. if (!code) return;
  238. getRedPacketLogByCode({ orderCode: code }).then(res => {
  239. if (res.code == 200) {
  240. console.log("订单状态查询结果:", res);
  241. // 可以根据订单状态更新UI或进行其他操作
  242. if (res.data) {
  243. this.order = res.data;
  244. }
  245. } else {
  246. console.warn("查询订单状态失败:", res.msg);
  247. }
  248. }, err => {
  249. console.error("查询订单状态错误:", err);
  250. });
  251. },
  252. goBack() {
  253. uni.navigateBack()
  254. },
  255. navTo(){
  256. uni.navigateTo({
  257. url:'/pages/user/wallet/recordList'
  258. })
  259. },
  260. copyOrderSn(text) {
  261. // 复制方法
  262. uni.setClipboardData({
  263. data:text,
  264. success:()=>{
  265. uni.showToast({
  266. title:'内容已成功复制到剪切板',
  267. icon:'none'
  268. })
  269. }
  270. });
  271. },
  272. goOrderDetails(id){
  273. uni.redirectTo({
  274. url: "/pages_user/user/storeOrderDetail?id="+id
  275. })
  276. },
  277. // 再次提现
  278. withdrawAgain() {
  279. uni.navigateBack();
  280. },
  281. // 确认收款(拉起微信收款确认页面)
  282. confirmReceipt() {
  283. if (!this.order) {
  284. uni.showToast({
  285. title: '订单信息不完整',
  286. icon: 'none'
  287. });
  288. return;
  289. }
  290. const appId = this.order.appId;
  291. const mchId = this.order.mchId;
  292. const packageValue = this.order.packageInfo;
  293. if (!appId || !mchId || !packageValue) {
  294. uni.showToast({
  295. title: '缺少必要参数,无法确认收款',
  296. icon: 'none'
  297. });
  298. return;
  299. }
  300. // #ifdef APP-PLUS
  301. const params = {
  302. appId: String(appId),
  303. mchId: String(mchId),
  304. package: String(packageValue)
  305. };
  306. console.log('拉起微信收款确认页面,参数:', params);
  307. this.openWxMerchantTransfer(params, (res) => {
  308. console.log('确认收款回调结果:', res);
  309. if (res.code === 0) {
  310. // 确认收款成功,重新查询订单状态
  311. if (this.orderCode) {
  312. setTimeout(() => {
  313. this.getRedPacketLogByCode(this.orderCode);
  314. }, 1000);
  315. }
  316. } else if (res.code === -3) {
  317. const resultMessage = (res.message || '').toLowerCase();
  318. if (resultMessage.includes('not installed') || resultMessage.includes('未安装')) {
  319. uni.showModal({
  320. title: '提示',
  321. content: '请先安装微信客户端',
  322. showCancel: false
  323. });
  324. } else {
  325. uni.showModal({
  326. title: '提示',
  327. content: res.message || '当前微信版本不支持,请升级后重试',
  328. showCancel: false
  329. });
  330. }
  331. } else {
  332. uni.showModal({
  333. title: '确认收款失败',
  334. content: res.message || '请稍后重试',
  335. showCancel: false
  336. });
  337. }
  338. });
  339. // #endif
  340. // #ifndef APP-PLUS
  341. uni.showToast({
  342. icon: 'none',
  343. title: '此功能仅在 APP 中可用',
  344. });
  345. // #endif
  346. }
  347. }
  348. }
  349. </script>
  350. <style lang="scss">
  351. page{
  352. height: 100%;
  353. background-color: #FFFFFF;
  354. }
  355. .content{
  356. height: 100%;
  357. display: flex;
  358. flex-direction: column;
  359. justify-content:flex-start;
  360. .inner{
  361. padding:24rpx;
  362. image{
  363. width: 224rpx;
  364. height: 160rpx;
  365. }
  366. .box-img{
  367. margin-top: 160rpx;
  368. .title{
  369. font-family: PingFang SC, PingFang SC;
  370. font-weight: 500;
  371. font-size: 48rpx;
  372. color: #222222;
  373. margin-top: 64rpx;
  374. margin-bottom: 10rpx;
  375. }
  376. .desc{
  377. font-family: PingFang SC, PingFang SC;
  378. font-weight: 500;
  379. font-size: 28rpx;
  380. color: #757575;
  381. }
  382. }
  383. }
  384. .btn-box{
  385. margin-top:60rpx;
  386. box-sizing: border-box;
  387. display: flex;
  388. align-items: center;
  389. justify-content: center;
  390. flex-wrap: wrap;
  391. gap: 24rpx;
  392. .btn{
  393. min-width: 254rpx;
  394. height: 88rpx;
  395. padding: 0 32rpx;
  396. border-radius: 44rpx 44rpx 44rpx 44rpx;
  397. border: 2rpx solid #FF5030;
  398. display: flex;
  399. align-items: center;
  400. justify-content: center;
  401. font-family: PingFang SC, PingFang SC;
  402. font-weight: 400;
  403. font-size: 32rpx;
  404. color: #FF5030;
  405. &.back{
  406. background: #FF5030;
  407. color: #fff;
  408. }
  409. }
  410. }
  411. }
  412. </style>