From b50df74802ab8ae820b57be4cdb6bf8fda7180a5 Mon Sep 17 00:00:00 2001 From: Jason <5340635+wen-jason@user.noreply.gitee.com> Date: Mon, 3 Apr 2023 15:13:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=99=E9=A2=9D=E5=85=85=E5=80=BC=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/src/api/app/recharge.ts | 10 + admin/src/api/finance.ts | 31 ++ admin/src/api/setting/pay.ts | 26 ++ admin/src/components/link/shop-pages.vue | 5 + admin/src/hooks/usePaging.ts | 26 +- admin/src/views/app/recharge/index.vue | 54 +++ .../consumer/components/account-adjust.vue | 104 ++++++ admin/src/views/consumer/lists/detail.vue | 43 ++- admin/src/views/consumer/lists/index.vue | 2 +- admin/src/views/finance/balance_details.vue | 101 ++++++ .../views/finance/component/refund-log.vue | 68 ++++ admin/src/views/finance/recharge_record.vue | 141 ++++++++ admin/src/views/finance/refund_record.vue | 226 ++++++++++++ admin/src/views/setting/pay/config/edit.vue | 279 +++++++++++++++ admin/src/views/setting/pay/config/index.vue | 63 ++++ admin/src/views/setting/pay/method/index.vue | 138 ++++++++ uniapp/src/api/app.ts | 5 + uniapp/src/api/pay.ts | 16 + uniapp/src/api/recharge.ts | 16 + uniapp/src/api/user.ts | 5 + .../components/page-status/page-status.vue | 62 ++++ uniapp/src/components/payment/payment.vue | 330 ++++++++++++++++++ uniapp/src/components/price/price.vue | 126 +++++++ uniapp/src/enums/appEnums.ts | 15 + .../src/packages/pages/recharge/recharge.vue | 102 ++++++ .../pages/recharge_record/recharge_record.vue | 44 +++ .../pages/user_wallet/user_wallet.vue | 118 +++++++ .../static/images/recharge_success.png | Bin 0 -> 3036 bytes uniapp/src/pages.json | 37 +- .../pages/payment_result/payment_result.vue | 157 +++++++++ uniapp/src/pages/user_set/user_set.vue | 3 +- uniapp/src/router/index.ts | 12 +- .../static/images/payment/icon_succeed.png | Bin 0 -> 2002 bytes .../static/images/payment/icon_waiting.png | Bin 0 -> 1844 bytes .../vk-uview-ui/components/u-tabs/u-tabs.vue | 21 +- uniapp/src/utils/client.ts | 2 +- uniapp/src/utils/pay/index.ts | 14 + uniapp/src/utils/pay/pay.ts | 28 ++ uniapp/src/utils/pay/wechat.ts | 58 +++ uniapp/src/utils/util.ts | 27 ++ uniapp/src/utils/wechat.ts | 74 ++-- uniapp/tsconfig.json | 9 +- 42 files changed, 2554 insertions(+), 44 deletions(-) create mode 100644 admin/src/api/app/recharge.ts create mode 100644 admin/src/api/finance.ts create mode 100644 admin/src/api/setting/pay.ts create mode 100644 admin/src/views/app/recharge/index.vue create mode 100644 admin/src/views/consumer/components/account-adjust.vue create mode 100644 admin/src/views/finance/balance_details.vue create mode 100644 admin/src/views/finance/component/refund-log.vue create mode 100644 admin/src/views/finance/recharge_record.vue create mode 100644 admin/src/views/finance/refund_record.vue create mode 100644 admin/src/views/setting/pay/config/edit.vue create mode 100644 admin/src/views/setting/pay/config/index.vue create mode 100644 admin/src/views/setting/pay/method/index.vue create mode 100644 uniapp/src/api/pay.ts create mode 100644 uniapp/src/api/recharge.ts create mode 100644 uniapp/src/components/page-status/page-status.vue create mode 100644 uniapp/src/components/payment/payment.vue create mode 100644 uniapp/src/components/price/price.vue create mode 100644 uniapp/src/packages/pages/recharge/recharge.vue create mode 100644 uniapp/src/packages/pages/recharge_record/recharge_record.vue create mode 100644 uniapp/src/packages/pages/user_wallet/user_wallet.vue create mode 100644 uniapp/src/packages/static/images/recharge_success.png create mode 100644 uniapp/src/pages/payment_result/payment_result.vue create mode 100644 uniapp/src/static/images/payment/icon_succeed.png create mode 100644 uniapp/src/static/images/payment/icon_waiting.png create mode 100644 uniapp/src/utils/pay/index.ts create mode 100644 uniapp/src/utils/pay/pay.ts create mode 100644 uniapp/src/utils/pay/wechat.ts diff --git a/admin/src/api/app/recharge.ts b/admin/src/api/app/recharge.ts new file mode 100644 index 00000000..8342c044 --- /dev/null +++ b/admin/src/api/app/recharge.ts @@ -0,0 +1,10 @@ +import request from '@/utils/request' + +export function getRechargeConfig() { + return request.get({ url: '/marketing/recharge/detail' }) +} + +// 设置 +export function setRechargeConfig(params: any) { + return request.post({ url: '/marketing/recharge/save', params }) +} diff --git a/admin/src/api/finance.ts b/admin/src/api/finance.ts new file mode 100644 index 00000000..790c6683 --- /dev/null +++ b/admin/src/api/finance.ts @@ -0,0 +1,31 @@ +import request from '@/utils/request' + +// 余额明细 +export function accountLog(params?: any) { + return request.get({ url: '/finance/wallet/list', params }) +} + +// 充值记录 +export function rechargeLists(params?: any) { + return request.get({ url: '/finance/recharger/list', params }, { ignoreCancelToken: true }) +} + +//退款 +export function refund(params?: any) { + return request.post({ url: '/finance/recharger/refund', params }) +} + +//重新退款 +export function refundAgain(params?: any) { + return request.post({ url: '/finance/recharger/refundAgain', params }) +} + +//退款记录 +export function refundRecord(params?: any) { + return request.get({ url: '/finance/refund/list', params }) +} + +//退款日志 +export function refundLog(params?: any) { + return request.get({ url: '/finance/refund/log', params }) +} diff --git a/admin/src/api/setting/pay.ts b/admin/src/api/setting/pay.ts new file mode 100644 index 00000000..8adad91f --- /dev/null +++ b/admin/src/api/setting/pay.ts @@ -0,0 +1,26 @@ +import request from '@/utils/request' + +// 获取支付方式 +export function getPayWay() { + return request.get({ url: '/setting/payment/method' }) +} + +// 设置支付方式 +export function setPayWay(params: any) { + return request.post({ url: '/setting/payment/editMethod', params }) +} + +// 获取支付方式 +export function getPayConfigLists() { + return request.get({ url: '/setting/payment/list' }) +} + +// 设置支付方式 +export function setPayConfig(params: any) { + return request.post({ url: '/setting/payment/editConfig', params }) +} + +// 设置支付方式 +export function getPayConfig(params: any) { + return request.get({ url: '/setting/payment/detail', params }) +} diff --git a/admin/src/components/link/shop-pages.vue b/admin/src/components/link/shop-pages.vue index e5c747b4..acb49b26 100644 --- a/admin/src/components/link/shop-pages.vue +++ b/admin/src/components/link/shop-pages.vue @@ -92,6 +92,11 @@ const linkList = ref([ path: '/pages/search/search', name: '搜索', type: LinkTypeEnum.SHOP_PAGES + }, + { + path: '/packages/pages/user_wallet/user_wallet', + name: '我的钱包', + type: LinkTypeEnum.SHOP_PAGES } ]) diff --git a/admin/src/hooks/usePaging.ts b/admin/src/hooks/usePaging.ts index 8a1aa599..d0de38d9 100644 --- a/admin/src/hooks/usePaging.ts +++ b/admin/src/hooks/usePaging.ts @@ -1,3 +1,4 @@ +import { isFunction } from 'lodash' import { reactive, toRaw } from 'vue' // 分页钩子函数 @@ -7,10 +8,20 @@ interface Options { fetchFun: (_arg: any) => Promise params?: Record firstLoading?: boolean + beforeRequest?(params: Record): Record + afterRequest?(res: Record): void } export function usePaging(options: Options) { - const { page = 1, size = 15, fetchFun, params = {}, firstLoading = false } = options + const { + page = 1, + size = 15, + fetchFun, + params = {}, + firstLoading = false, + beforeRequest, + afterRequest + } = options // 记录分页初始参数 const paramsInit: Record = Object.assign({}, toRaw(params)) // 分页数据 @@ -19,19 +30,28 @@ export function usePaging(options: Options) { size, loading: firstLoading, count: 0, - lists: [] as any[] + lists: [] as any[], + extend: {} as Record }) // 请求分页接口 const getLists = () => { pager.loading = true + let requestParams = params + if (isFunction(beforeRequest)) { + requestParams = beforeRequest(params) + } return fetchFun({ pageNo: pager.page, pageSize: pager.size, - ...params + ...requestParams }) .then((res: any) => { pager.count = res?.count pager.lists = res?.lists + pager.extend = res?.extend + if (isFunction(afterRequest)) { + afterRequest(res) + } return Promise.resolve(res) }) .catch((err: any) => { diff --git a/admin/src/views/app/recharge/index.vue b/admin/src/views/app/recharge/index.vue new file mode 100644 index 00000000..4944a140 --- /dev/null +++ b/admin/src/views/app/recharge/index.vue @@ -0,0 +1,54 @@ + + diff --git a/admin/src/views/consumer/components/account-adjust.vue b/admin/src/views/consumer/components/account-adjust.vue new file mode 100644 index 00000000..889cb3b2 --- /dev/null +++ b/admin/src/views/consumer/components/account-adjust.vue @@ -0,0 +1,104 @@ + + diff --git a/admin/src/views/consumer/lists/detail.vue b/admin/src/views/consumer/lists/detail.vue index 969df850..b69c8c67 100644 --- a/admin/src/views/consumer/lists/detail.vue +++ b/admin/src/views/consumer/lists/detail.vue @@ -5,9 +5,25 @@ -
-
用户头像
- +
+
+
用户头像
+ +
+
+
账户余额
+
+ ¥{{ formData.user_money }} + + 调整 + +
+
{{ formData.sn }} @@ -80,6 +96,11 @@ {{ formData.lastLoginTime }} +
@@ -88,7 +109,7 @@ import type { FormInstance } from 'element-plus' import { getUserDetail, userEdit } from '@/api/consumer' import feedback from '@/utils/feedback' import { isEmpty } from '@/utils/util' - +import AccountAdjust from '../components/account-adjust.vue' const route = useRoute() const formData = reactive({ avatar: '', @@ -105,7 +126,10 @@ const formData = reactive({ }) const formRef = shallowRef() - +const adjustState = reactive({ + show: false, + value: '' +}) const getDetails = async () => { const data = await getUserDetail({ id: route.query.id @@ -126,6 +150,15 @@ const handleEdit = async (value: string, field: string) => { feedback.msgSuccess('编辑成功') getDetails() } +const handleAdjust = (value: string) => { + adjustState.show = true + adjustState.value = value +} +const handleConfirmAdjust = async (value: any) => { + await adjustMoney({ user_id: route.query.id, ...value }) + adjustState.show = false + getDetails() +} getDetails() diff --git a/admin/src/views/consumer/lists/index.vue b/admin/src/views/consumer/lists/index.vue index 0d5b07fa..f9c24128 100644 --- a/admin/src/views/consumer/lists/index.vue +++ b/admin/src/views/consumer/lists/index.vue @@ -44,7 +44,7 @@ - + diff --git a/admin/src/views/finance/balance_details.vue b/admin/src/views/finance/balance_details.vue new file mode 100644 index 00000000..f2c27df7 --- /dev/null +++ b/admin/src/views/finance/balance_details.vue @@ -0,0 +1,101 @@ + + diff --git a/admin/src/views/finance/component/refund-log.vue b/admin/src/views/finance/component/refund-log.vue new file mode 100644 index 00000000..da59a6ab --- /dev/null +++ b/admin/src/views/finance/component/refund-log.vue @@ -0,0 +1,68 @@ + + + diff --git a/admin/src/views/finance/recharge_record.vue b/admin/src/views/finance/recharge_record.vue new file mode 100644 index 00000000..dbd5faa6 --- /dev/null +++ b/admin/src/views/finance/recharge_record.vue @@ -0,0 +1,141 @@ + + diff --git a/admin/src/views/finance/refund_record.vue b/admin/src/views/finance/refund_record.vue new file mode 100644 index 00000000..9a38df94 --- /dev/null +++ b/admin/src/views/finance/refund_record.vue @@ -0,0 +1,226 @@ + + diff --git a/admin/src/views/setting/pay/config/edit.vue b/admin/src/views/setting/pay/config/edit.vue new file mode 100644 index 00000000..edfe065e --- /dev/null +++ b/admin/src/views/setting/pay/config/edit.vue @@ -0,0 +1,279 @@ + + diff --git a/admin/src/views/setting/pay/config/index.vue b/admin/src/views/setting/pay/config/index.vue new file mode 100644 index 00000000..c2975a14 --- /dev/null +++ b/admin/src/views/setting/pay/config/index.vue @@ -0,0 +1,63 @@ + + + diff --git a/admin/src/views/setting/pay/method/index.vue b/admin/src/views/setting/pay/method/index.vue new file mode 100644 index 00000000..db23be06 --- /dev/null +++ b/admin/src/views/setting/pay/method/index.vue @@ -0,0 +1,138 @@ + + + diff --git a/uniapp/src/api/app.ts b/uniapp/src/api/app.ts index 9d5dcd37..32cec0d5 100644 --- a/uniapp/src/api/app.ts +++ b/uniapp/src/api/app.ts @@ -1,3 +1,4 @@ +import wechatOa from '@/utils/wechat' import request from '@/utils/request' //发送短信 @@ -24,3 +25,7 @@ export function uploadImage(file: any, token?: string) { fileType: 'image' }) } + +export function wxJsConfig(data: any) { + return request.get({ url: '/wechat/jsConfig', data }) +} diff --git a/uniapp/src/api/pay.ts b/uniapp/src/api/pay.ts new file mode 100644 index 00000000..cf56c8be --- /dev/null +++ b/uniapp/src/api/pay.ts @@ -0,0 +1,16 @@ +import request from '@/utils/request' + +//支付方式 +export function getPayWay(data: any) { + return request.get({ url: '/pay/payWay', data }, { isAuth: true }) +} + +// 预支付 +export function prepay(data: any) { + return request.post({ url: '/pay/prepay', data }, { isAuth: true }) +} + +// 预支付 +export function getPayResult(data: any) { + return request.get({ url: '/pay/payStatus', data }, { isAuth: true }) +} diff --git a/uniapp/src/api/recharge.ts b/uniapp/src/api/recharge.ts new file mode 100644 index 00000000..1432dd8f --- /dev/null +++ b/uniapp/src/api/recharge.ts @@ -0,0 +1,16 @@ +import request from '@/utils/request' + +//充值 +export function recharge(data: any) { + return request.post({ url: '/recharge/placeOrder', data }, { isAuth: true }) +} + +//充值记录 +export function rechargeRecord(data: any) { + return request.get({ url: '/recharge/record', data }, { isAuth: true }) +} + +// 充值配置 +export function rechargeConfig() { + return request.get({ url: '/recharge/config' }, { isAuth: true }) +} diff --git a/uniapp/src/api/user.ts b/uniapp/src/api/user.ts index c81c137b..8e1014ba 100644 --- a/uniapp/src/api/user.ts +++ b/uniapp/src/api/user.ts @@ -41,3 +41,8 @@ export function oaAuthBind(data: any) { export function updateUser(data: Record, header: any) { return request.post({ url: '/user/updateUser', data, header }) } + +//余额明细 +export function accountLog(data: any) { + return request.get({ url: '/logs/userMoney', data }) +} diff --git a/uniapp/src/components/page-status/page-status.vue b/uniapp/src/components/page-status/page-status.vue new file mode 100644 index 00000000..946fcc3b --- /dev/null +++ b/uniapp/src/components/page-status/page-status.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/uniapp/src/components/payment/payment.vue b/uniapp/src/components/payment/payment.vue new file mode 100644 index 00000000..7e444500 --- /dev/null +++ b/uniapp/src/components/payment/payment.vue @@ -0,0 +1,330 @@ + + + + + diff --git a/uniapp/src/components/price/price.vue b/uniapp/src/components/price/price.vue new file mode 100644 index 00000000..58984989 --- /dev/null +++ b/uniapp/src/components/price/price.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/uniapp/src/enums/appEnums.ts b/uniapp/src/enums/appEnums.ts index c399d6ab..957d40da 100644 --- a/uniapp/src/enums/appEnums.ts +++ b/uniapp/src/enums/appEnums.ts @@ -32,3 +32,18 @@ export enum FieldType { NICKNAME = 'nickname', SEX = 'sex' } + +// 支付结果 +export enum PayStatusEnum { + SUCCESS = 'success', + FAIL = 'fail', + PENDING = 'pending' +} + +// 页面状态 +export enum PageStatusEnum { + LOADING = 'loading', // 加载中 + NORMAL = 'normal', // 正常 + ERROR = 'error', // 异常 + EMPTY = 'empty' // 为空 +} \ No newline at end of file diff --git a/uniapp/src/packages/pages/recharge/recharge.vue b/uniapp/src/packages/pages/recharge/recharge.vue new file mode 100644 index 00000000..20f65c81 --- /dev/null +++ b/uniapp/src/packages/pages/recharge/recharge.vue @@ -0,0 +1,102 @@ + + diff --git a/uniapp/src/packages/pages/recharge_record/recharge_record.vue b/uniapp/src/packages/pages/recharge_record/recharge_record.vue new file mode 100644 index 00000000..f152cfdc --- /dev/null +++ b/uniapp/src/packages/pages/recharge_record/recharge_record.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/uniapp/src/packages/pages/user_wallet/user_wallet.vue b/uniapp/src/packages/pages/user_wallet/user_wallet.vue new file mode 100644 index 00000000..14d85cb1 --- /dev/null +++ b/uniapp/src/packages/pages/user_wallet/user_wallet.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/uniapp/src/packages/static/images/recharge_success.png b/uniapp/src/packages/static/images/recharge_success.png new file mode 100644 index 0000000000000000000000000000000000000000..c6df9db68554611d9c1e417db17bd7ebcbc2aa37 GIT binary patch literal 3036 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 + + + + + + + + + + diff --git a/uniapp/src/pages/user_set/user_set.vue b/uniapp/src/pages/user_set/user_set.vue index 0c4c9c45..4cd5f5e6 100644 --- a/uniapp/src/pages/user_set/user_set.vue +++ b/uniapp/src/pages/user_set/user_set.vue @@ -145,13 +145,14 @@ const bindWechat = async () => { await mnpAuthBind({ code: code }) + + uni.$u.toast('绑定成功') //#endif // #ifdef H5 if (isWeixin.value) { wechatOa.getUrl() } // #endif - uni.$u.toast('绑定成功') await userStore.getUser() uni.hideLoading() } catch (e) { diff --git a/uniapp/src/router/index.ts b/uniapp/src/router/index.ts index 2de8363d..541f3055 100644 --- a/uniapp/src/router/index.ts +++ b/uniapp/src/router/index.ts @@ -1,7 +1,12 @@ +import { ClientEnum } from '@/enums/appEnums' import { BACK_URL } from '@/enums/cacheEnums' import { useUserStore } from '@/stores/user' import { getToken } from '@/utils/auth' import cache from '@/utils/cache' +import { client } from '@/utils/client' +// #ifdef H5 +import wechatOa from '@/utils/wechat' +// #endif import { routes } from './routes' const whiteList = ['register', 'login', 'forget_pwd'] @@ -41,6 +46,11 @@ export function setupRouter() { cache.set(BACK_URL, from.fullPath) } }) - + setTimeout(async () => { + if (client == ClientEnum.OA_WEIXIN) { + // jssdk配置 + await wechatOa.config() + } + }) // #endif } diff --git a/uniapp/src/static/images/payment/icon_succeed.png b/uniapp/src/static/images/payment/icon_succeed.png new file mode 100644 index 0000000000000000000000000000000000000000..c27b413e82d4d718fce470e47722a6451929c4e4 GIT binary patch literal 2002 zcmchY`#Tc~9L86Z)l_cPId0o9Y;F;$M5JkUOj$0?ZCgmKTu;edijrnjk}wG!8PX(* z6iUk?8@Xm~Ba8<%hG8)~&OdS9=Xu}HkMHyS{_@gXPoZ~#)xiJ&U>C*-b!L;{|9Lxb zGeyVbqBk++igkC~r0jnb;M2LyHu)wp@bd-0N59=)LXh0+>#_}0*WJrQMf+O*hPFnH zuL^s`f)(i+cVUz<(=xI$Ytf#_77bk;E?Zb%nU;u{vz&B6UGzw~S6|M@c^;AXq;qln z*V>|3D#@E-S$(@rpZrK2uO3*Q#`QjO?tbuou4mH2YH0IRy{l(VxdGPYIK94NPfL;D zV@5*fzTN-Of4;_9H&H42&?ontj79=Wj$cveA#A=%J`#gE?oJ^z3|=@pZmlFwYCcu* zMo&p)CiC*8{Y(61nJoV@pD9Wcc_$=wjFOMVt6S#OnQ@R03JLnOp{K`Z zhHXcNY6$hACEa3z_uE6?qHJrq*dSO+_?pLJ?)RU>kr>kmP3rBNMBlmP_ao~;kCTjB zYWd&qlTB+U=YO%6k%KiKSSRJ|elw*DR>7uD7Pz4ly~32V(`tQn`ASe=6Nm)W%b11e zp5AZimzGILkC4`I$VS+=!yp=5<9#uD<V3`P)rRsnGy!6F{nvm+KQgU#2hVe;J z&55uH>rwxV`>}gd#7>Yqi_hD-QVRlONoOKr-E4o#@hPk>Rm=hdy}#()v+3FT#72#4 zqnPBpb1;a#?+@u8l&F0-4YXCFz{*!5GqaD|BIaS<-J{konavq~s{D@3l?UTWh3|ZP zgdu7@v!C6xul;tnTw(ydi}>gN$XDsCEAl_l9Ul|#sxrO9O$uVOxJU1?$PEo|6h z$th|D=lr`sIOUoJ*f5&7lq!n7bzvr`Q~=5z+vQ>|HgN>*SoVNV9Nzr{EzV=KT;hY~ z1gh{N+n7*gQ?`|hh>|`AQHgU6-~U>6!^AXn)nBN~ZeY9VY$HuWbFjHfYTY$V@?x4ka@)TYLU*j@f>fInc6bRKixfcSgr6I_Z1dpAWS>lHv7eG;~r z(0rm&@tk^LGgSfC3Uu-Ya0Y~}8o7cvuFGPT0AB@Z+%cn5!Kh5^&@=iTwIMT4Uu3pG zz!3=!J+I;(NB!AiGFOVohBgW_6m!Us31~O=(V}rz&a;KSn+1Rz#EkYnlKN=Z!DDI> zg|Db;ie}{kPpo?K*(V4qBJUuUe#9iLiVpBKxZ$v;CCx~|b5$7?p_nAwreAGXR~-WJ zNEc0ng-ii10Qypa6Nrb8 zTc>dC2URS2WbdZ(GgQ0|2-Wm!i%riGUE{=uy#)apCl0!hW}OibfbeUuklj#TS$_S2 zAU@aM?#Y35`4As+%DPbCMTfn(OQ4p5FeS}a1FJ5}eesoFH@I{5x?uNUX}kH>qljo( zW}-@RW(4Vq(U&@d zLG>REAc8W#I7l_v{wt-N)A$0I46|Yk_yn~z4sP_yLnyfc=o-iAE1EG!aW>pu5+0qm z>Vh9m$52%{tc(6Zok7byee*$XP};eecRTBA?_E_~K{3-!y%G&N3|A98Kkb5#7+x%d zE@bCwGX`u+EYg^vD{y{r>)Y7B4!zlZ=Y@th6)3vnDajhPJK)0l?bUz#c@@&@`e1cj zz&q^@ylKBRv8=eSy1nEDgE@0e`V8C2OKRFGe2H^k763M86*Gg2uZF@uSJ=VtEuPW$ ep^3#**%te#@%P!qQr6~T0WglIP%j-wxBdk%#Uzse literal 0 HcmV?d00001 diff --git a/uniapp/src/static/images/payment/icon_waiting.png b/uniapp/src/static/images/payment/icon_waiting.png new file mode 100644 index 0000000000000000000000000000000000000000..956702a4f9190289bff8523b57b15c6d5048fdcd GIT binary patch literal 1844 zcmchY`8yPd1IEV@8X=5(G}gMA)GV=;a*ShgMT#}h?eg{(c)Jsh;;xZ7Bk6}@*=({my9seP`}S}mpVJ@9 z{)FNF96nsE_oI@^kLzg!J3HI}a0GX9dgxkCD>CCFR6?BVr2>N#v9Io4XZpzvA=YNq zC6V`L(Pi+Du>in{B?R2e<*_Gm`YU$&;%Oo8_ck92pzhlyXgR=_$gr?Io@203Vv^4t z4F#!n@-;uTn7T|r{6eZ)+LlyS-+=y6V<3{A3b3q+LN*`7%)0dJ?xl_oDn?WAj!QC! zT`vsw$7Z-hb0_|1%kq7PO>Xn|`{dR-o{Pumh&IA2yPv3=`K``u*>cwT~-XN0ZK)wMx8|@(BDBh?n;9izUUW3=#Oy&aQ zZ;(eGGS5CFtyRI&*Gn*Ka9b|vFx&!ZbTj;lY0p7Y+z1JVzpJmt7nRrCOLV@8RcRJZ z%~c0l(p79SeXD$_#x;wHtI#CS?Nk-zvmL5LW%aJed9(2L5&>UrJmoiG^^Th`nhJOj z1JSlsPR*DNbmOYcVT_9$%iHQLuOxP|p|!$gue9}XSv8CAx4QcBBvj-+P?EyV= znxVUMJ#v}vgB^u}OnYLL9^pDQeXb9dB;*6-0Y6nV33#{ltKLv;pJ2J|S2O+r|(ngyz95D{-v&aIPHS*FPcnw zcNOK&=*1)rD9!2lV_I0;n*h^1n&&WImP4i+Qm2+if;YY8^~J79j8;Z;vpD=Qv1Q~} zEc_|gx73_4^_TeFi1bN-_SQ*BAVd}|E`d7XYb?lP{2&Vo8y}YUi}(1Zh$E$nvpPP1T|m>A{^11t8GnvruNH1)?Bp=MD+)jJp<*4gd> zUP9`fv@>no+6EfGX7R7iij|j^9zM6Ss*BVH!hTb!6NSy#?7BE|A~_3no(>PynE?3g|!{{FxNndYv1(cP1iu5aXeGxj%TQA)-i z%g(=1aM(vnCu%=4pLU0}H`}|kWJeXE%!6!EKQ7QzKS&N1F`w?HOm0rwImTbgDpatg zC?tc1l3P6LL`eykaE~kkWC+W<8uK&QreSunc@A7$Mvn^C0jYLt-1_60JxSUKd(Ky# z?Ooxf8Uw*izD&qF|0J^I1mwz@?G{5op*mg7E$z%O>5jIfSK@lR#8UL-c+YRl*P|4E zQ%L;_DMy!-A=zuxdnRyrYN5slPg7Fo$4f(n4U8U6844)c|NWMF{xgC=L54T{y60cux$;Zc*^CzA z=tQIJ^(Eud@NrEO>$6kSO738;w{l&Cd_on_mHPDIr;P?!>bFh*Avw>eI>eh21T|V% z%CK2JtER5L>79L~?E}(n%tA_6%zdYb`svpobVvNE3KS8<7St|$kNmJd;WrU}Hy>l* zbusHgox#&!@W;;M?5tiOxI!h3aQ~Zl^eQ>IG@`Q5yy~vW;-x z3i>P5acnriW?{b-q1*1LbZ4C=Rz-IY{b{6r=|w@dSUAqzZYtEHjW|g4&o1&P*7VoA zO1}8HDzDgpvH58?!&+ { - this.init(); - }); + list: { + immediate: true, + handler(n, o) { + if(o) { + // list变动时,重制内部索引,否则可能导致超出数组边界的情况 + if(n.length !== o.length) this.currentIndex = 0; + // 用$nextTick等待视图更新完毕后再计算tab的局部信息,否则可能因为tab还没生成就获取,就会有问题 + } + setTimeout(() => { + this.init(); + },200) + } }, current: { immediate: true, @@ -290,6 +295,7 @@ for (let i = 0; i < this.list.length; i++) { // 只要size和rect两个参数 query.select(`#u-tab-item-${i}`).fields({ + id: true, size: true, rect: true }); @@ -319,6 +325,7 @@ let left = tabInfo.left + tabInfo.width / 2 - this.parentLeft; // 计算当前活跃item到组件左边的距离 this.scrollBarLeft = left - uni.upx2px(this.barWidth) / 2; + // 第一次移动滑块的时候,barFirstTimeMove为true,放到延时中将其设置false // 延时是因为scrollBarLeft作用于computed计算时,需要一个过程需,否则导致出错 if(this.barFirstTimeMove == true) { diff --git a/uniapp/src/utils/client.ts b/uniapp/src/utils/client.ts index 06e8d8a0..98b1aafc 100644 --- a/uniapp/src/utils/client.ts +++ b/uniapp/src/utils/client.ts @@ -43,7 +43,7 @@ export const getClient = () => { // 根据端处理事件 //@ts-ignore -export const handleClientEvent = ({ MP_WEIXIN, OA_WEIXIN, H5, IOS, ANDROID, OTHER }) => { +export const handleClientEvent = ({ MP_WEIXIN, OA_WEIXIN, H5, IOS, ANDROID, OTHER }: any) => { // #ifdef MP-WEIXIN return MP_WEIXIN() // #endif diff --git a/uniapp/src/utils/pay/index.ts b/uniapp/src/utils/pay/index.ts new file mode 100644 index 00000000..12b463eb --- /dev/null +++ b/uniapp/src/utils/pay/index.ts @@ -0,0 +1,14 @@ +import { Pay } from './pay' +import { Wechat } from './wechat' + +// 支付方式 +enum PayWayEnum { + BALANCE = 1, + WECHAT = 2, + ALIPAY = 3 +} +const wechat = new Wechat() +// 注入微信支付 +Pay.inject(PayWayEnum[2], wechat) +const pay = new Pay() +export { pay, PayWayEnum } diff --git a/uniapp/src/utils/pay/pay.ts b/uniapp/src/utils/pay/pay.ts new file mode 100644 index 00000000..09486009 --- /dev/null +++ b/uniapp/src/utils/pay/pay.ts @@ -0,0 +1,28 @@ +import { PayWayEnum } from '.' + +export class Pay { + private static modules = new Map() + static inject(name: string, module: any) { + this.modules.set(name, module) + } + constructor() { + //动态注入支付方式 + for (const [name, module] of Pay.modules.entries()) { + module.init(name, this) + } + } + + //调用支付 + async payment(payWay: PayWayEnum, options: any) { + try { + //@ts-ignore + const module = this[PayWayEnum[payWay]] + if (!module) { + throw new Error(`can not find pay way ${payWay}`) + } + return await module.run(options) + } catch (error) { + return Promise.reject(error) + } + } +} diff --git a/uniapp/src/utils/pay/wechat.ts b/uniapp/src/utils/pay/wechat.ts new file mode 100644 index 00000000..513eb4ba --- /dev/null +++ b/uniapp/src/utils/pay/wechat.ts @@ -0,0 +1,58 @@ +import { PayStatusEnum } from '@/enums/appEnums' +import { handleClientEvent } from '../client' +//#ifdef H5 +import wechatOa from '../wechat' +//#endif +export class Wechat { + init(name: string, pay: any) { + pay[name] = this + } + + async run(options: any) { + try { + const res = await handleClientEvent({ + MP_WEIXIN: () => { + return new Promise((resolve) => { + console.log(options) + uni.requestPayment({ + orderInfo: '', + provider: 'wxpay', + timeStamp: options.timeStamp, + nonceStr: options.nonceStr, + package: options.packageValue, + paySign: options.paySign, + signType: options.signType, + success() { + resolve(PayStatusEnum.SUCCESS) + }, + fail() { + resolve(PayStatusEnum.FAIL) + } + }) + }) + }, + OA_WEIXIN: () => { + return new Promise((resolve) => { + wechatOa + .pay(options) + .then(() => { + resolve(PayStatusEnum.SUCCESS) + }) + .catch(() => { + resolve(PayStatusEnum.FAIL) + }) + }) + }, + H5: () => { + return new Promise((resolve) => { + window.open(options.url, '_self') + resolve(PayStatusEnum.PENDING) + }) + } + }) + return res + } catch (error) { + return Promise.reject(error) + } + } +} diff --git a/uniapp/src/utils/util.ts b/uniapp/src/utils/util.ts index 2577ed7f..c8608e17 100644 --- a/uniapp/src/utils/util.ts +++ b/uniapp/src/utils/util.ts @@ -94,6 +94,33 @@ export function objectToQuery(params: Record): string { return query.slice(0, -1) } +/** + * @description 格式化输出价格 + * @param { string } price 价格 + * @param { string } take 小数点操作 + * @param { string } prec 小数位补 + */ +export function formatPrice({ price, take = 'all', prec = undefined }: any) { + let [integer, decimals = ''] = (price + '').split('.') + + // 小数位补 + if (prec !== undefined) { + const LEN = decimals.length + for (let i = prec - LEN; i > 0; --i) decimals += '0' + decimals = decimals.substr(0, prec) + } + + switch (take) { + case 'int': + return integer + case 'dec': + return decimals + case 'all': + return integer + '.' + decimals + } +} + + /** * @description 组合异步任务 * @param { string } task 异步任务 diff --git a/uniapp/src/utils/wechat.ts b/uniapp/src/utils/wechat.ts index cd29de0c..1e1c6210 100644 --- a/uniapp/src/utils/wechat.ts +++ b/uniapp/src/utils/wechat.ts @@ -1,7 +1,7 @@ import weixin from 'weixin-js-sdk' import { getWxCodeUrl, OALogin } from '@/api/account' -import { useUserStore } from '@/stores/user' import { isAndroid } from './client' +import { wxJsConfig } from '@/api/app' const wechatOa = { getSignLink() { @@ -15,6 +15,27 @@ const wechatOa = { location.href = res.url }) }, + config() { + return new Promise((resolve, reject) => { + wxJsConfig({ + url: this.getSignLink() + }).then((res) => { + weixin.config({ + appId: res.appid, // 必填,公众号的唯一标识 + timestamp: res.timestamp, // 必填,生成签名的时间戳 + nonceStr: res.nonceStr, // 必填,生成签名的随机串 + signature: res.signature, // 必填,签名 + jsApiList: res.jsApiList, + success: () => { + resolve('success') + }, + fail: (res: any) => { + reject('weixin config is fail') + } + }) + }) + }) + }, authLogin(code: string) { return new Promise((resolve, reject) => { OALogin({ @@ -35,6 +56,36 @@ const wechatOa = { }) }) }, + pay(options: Record) { + return new Promise((resolve, reject) => { + this.ready() + .then(() => { + weixin.chooseWXPay({ + timestamp: options.timeStamp, + nonceStr: options.nonceStr, + package: options.packageValue, + signType: options.signType, + paySign: options.paySign, + success: (res: any) => { + if (res.errMsg === 'chooseWXPay:ok') { + resolve(res) + } else { + reject(res.errMsg) + } + }, + cancel: (res: any) => { + reject(res) + }, + fail: (res: any) => { + reject(res) + } + }) + }) + .catch((err) => { + reject(err) + }) + }) + }, share(options: Record) { this.ready().then(() => { const { shareTitle, shareLink, shareImage, shareDesc } = options @@ -91,24 +142,3 @@ const wechatOa = { } export default wechatOa -// export function wxOaConfig() { -// return new Promise((resolve, reject) => { -// apiJsConfig().then((res) => { -// console.log(res) //微信配置 -// weixin.config({ -// debug: false, // 开启调试模式 -// appId: res.appId, // 必填,公众号的唯一标识 -// timestamp: res.timestamp, // 必填,生成签名的时间戳 -// nonceStr: res.nonceStr, // 必填,生成签名的随机串 -// signature: res.signature, // 必填,签名 -// jsApiList: res.jsApiList, // 必填,需要使用的JS接口列表 -// success: () => { -// resolve('success') -// }, -// fail: (res: any) => { -// reject('weixin config is fail') -// } -// }) -// }) -// }) -// } diff --git a/uniapp/tsconfig.json b/uniapp/tsconfig.json index 82086881..51f693c9 100644 --- a/uniapp/tsconfig.json +++ b/uniapp/tsconfig.json @@ -17,5 +17,12 @@ "@/*": ["./src/*"] } }, - "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "typings/**/*.d.ts"] + "include": [ + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue", + "typings/**/*.d.ts", + "../admin/src/api/finance.ts" + ] }