mirror of
https://gitee.com/niucloud-team/niucloud-admin.git
synced 2025-12-13 11:12:49 +00:00
更新uni-app
This commit is contained in:
parent
db93e399eb
commit
8a600afd4f
@ -1,37 +1,40 @@
|
||||
<script setup lang="ts">
|
||||
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
||||
import manifest from '@/manifest.json'
|
||||
import { redirectInterceptor, launchInterceptor } from '@/utils/interceptor'
|
||||
import { getToken, isWeixinBrowser } from '@/utils/common'
|
||||
import { getToken, isWeixinBrowser, urlDeconstruction } from '@/utils/common'
|
||||
import useMemberStore from '@/stores/member'
|
||||
import useConfigStore from '@/stores/config'
|
||||
import { useLogin } from '@/hooks/useLogin'
|
||||
import { language } from '@/locale'
|
||||
|
||||
// #ifdef H5
|
||||
if (import.meta.env.VITE_APP_DEBUG) { new window.VConsole() }
|
||||
// #endif
|
||||
|
||||
|
||||
onLaunch(async (data) => {
|
||||
// 添加初始化拦截器
|
||||
launchInterceptor()
|
||||
// 添加页面跳转拦截器
|
||||
redirectInterceptor()
|
||||
|
||||
// #ifdef H5
|
||||
uni.getSystemInfoSync().platform == 'ios' && (uni.setStorageSync('initUrl', location.href))
|
||||
// #endif
|
||||
|
||||
const configStore = useConfigStore()
|
||||
configStore.getTabbarConfig()
|
||||
await configStore.getLoginConfig()
|
||||
|
||||
// 隐藏tabbar
|
||||
uni.hideTabBar()
|
||||
|
||||
// #ifdef H5
|
||||
uni.getSystemInfoSync().platform == 'ios' && (uni.setStorageSync('initUrl', location.href))
|
||||
// #endif
|
||||
|
||||
|
||||
// 判断是否已登录
|
||||
if (getToken()) {
|
||||
const memberStore = useMemberStore()
|
||||
await memberStore.setToken(getToken())
|
||||
}
|
||||
|
||||
if (!getToken()) {
|
||||
const login = useLogin()
|
||||
// 三方平台自动登录
|
||||
@ -40,10 +43,18 @@
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
if (isWeixinBrowser()) {
|
||||
data.query.code ? login.authLogin(data.query.code) : login.getAuthCode()
|
||||
data.query.code ? login.authLogin(data.query.code) : login.getAuthCode('snsapi_userinfo')
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 监听浏览器返回
|
||||
// #ifdef H5
|
||||
window.addEventListener("popstate", function(e) {
|
||||
const path = '/' + location.pathname.replace(manifest.h5.router.base, '')
|
||||
language.loadLocaleMessages(path, uni.getLocale())
|
||||
}, false);
|
||||
// #endif
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
|
||||
@ -61,4 +61,11 @@ export function weappLogin(data : AnyObject) {
|
||||
*/
|
||||
export function bind(data : AnyObject) {
|
||||
return request.post('bind', data, { showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录会员访问日志
|
||||
*/
|
||||
export function memberLog(data : AnyObject) {
|
||||
return request.post('member/log', data)
|
||||
}
|
||||
@ -1,40 +1,145 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getMemberInfo() {
|
||||
return request.get('member/member')
|
||||
return request.get('member/member')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取积分流水
|
||||
*/
|
||||
export function getPointList(data : AnyObject) {
|
||||
return request.get('member/account/point', data)
|
||||
return request.get('member/account/point', data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取余额流水
|
||||
* 获取不可提现余额流水
|
||||
*/
|
||||
export function getBalanceList(data : AnyObject) {
|
||||
return request.get('member/account/balance', data)
|
||||
return request.get('member/account/balance', data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可提现余额流水
|
||||
*/
|
||||
export function getMoneyList(data : AnyObject) {
|
||||
return request.get('member/account/money', data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 会员信息修改
|
||||
*/
|
||||
export function updateMember(data : AnyObject) {
|
||||
return request.put(`member/modify/${data.field}`, data, { showErrorMessage: true })
|
||||
export function modifyMember(data : AnyObject) {
|
||||
return request.put(`member/modify/${data.field}`, data, { showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起充值
|
||||
*/
|
||||
export function createRecharge(data : AnyObject) {
|
||||
return request.post('order/recharge', data, { showErrorMessage: true })
|
||||
return request.post('order/recharge', data, { showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 充值记录列表
|
||||
*/
|
||||
export function getRechargeList(data : AnyObject) {
|
||||
return request.get('order/recharge', data, { showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 充值记录详情
|
||||
*/
|
||||
export function getRechargeDetail(id:number) {
|
||||
return request.get(`order/recharge/${id}`, {}, { showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录会员绑定手机号
|
||||
*/
|
||||
export function bindMobile(data : AnyObject) {
|
||||
return request.put('member/mobile', data, { showErrorMessage: true })
|
||||
return request.put('member/mobile', data, { showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 提现转账方式
|
||||
*/
|
||||
export function cashOutTransferType() {
|
||||
return request.get('member/cash_out/transfertype')
|
||||
}
|
||||
|
||||
/**
|
||||
* 提现配置
|
||||
*/
|
||||
export function cashOutConfig() {
|
||||
return request.get('member/cash_out/config')
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请余额提现
|
||||
*/
|
||||
export function cashOutApply(data : AnyObject) {
|
||||
return request.post('member/cash_out/apply', data, { showSuccessMessage: true, showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提现账户信息
|
||||
*/
|
||||
export function getCashoutAccountInfo(data : AnyObject) {
|
||||
return request.get(`member/cashout_account/${data.account_id}`, {})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取首条提现账户信息
|
||||
*/
|
||||
export function getFirstCashoutAccountInfo(data : AnyObject) {
|
||||
return request.get('member/cashout_account/firstinfo', data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提现账户列表
|
||||
*/
|
||||
export function getCashoutAccountList(data : AnyObject) {
|
||||
return request.get(`member/cashout_account`, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提现记录列表
|
||||
*/
|
||||
export function getCashOutList(data : AnyObject) {
|
||||
return request.get(`member/cash_out`, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提现记录详情
|
||||
*/
|
||||
export function getCashOutDetail(id : number) {
|
||||
return request.get(`member/cash_out/${id}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加提现账户
|
||||
*/
|
||||
export function addCashoutAccount(data : AnyObject) {
|
||||
return request.post('member/cashout_account', data, { showSuccessMessage: true, showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加提现账户
|
||||
*/
|
||||
export function editCashoutAccount(data : AnyObject) {
|
||||
return request.put(`member/cashout_account/${data.account_id}`, data, { showSuccessMessage: true, showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除提现账户
|
||||
*/
|
||||
export function deleteCashoutAccount(accountId: number) {
|
||||
return request.delete(`member/cashout_account/${accountId}`, { showSuccessMessage: true, showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 佣金信息
|
||||
*/
|
||||
export function getCommissionList(data : AnyObject) {
|
||||
return request.get(`member/account/commission`, data)
|
||||
}
|
||||
20
uni-app/components/diy/comp-extend/index.vue
Normal file
20
uni-app/components/diy/comp-extend/index.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 扩展组件 -->
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// 自定义扩展组件
|
||||
import { computed } from 'vue';
|
||||
import useDiyStore from '@/stores/diy';
|
||||
const props = defineProps(['component', 'index']);
|
||||
const diyStore = useDiyStore();
|
||||
const diyComponent = computed(() => {
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return diyStore.value[props.index];
|
||||
} else {
|
||||
return props.component;
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
24
uni-app/components/diy/extend/hello-info/index.vue
Normal file
24
uni-app/components/diy/extend/hello-info/index.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<view>
|
||||
演示插件信息——自定义组件
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import useDiyStore from '@/stores/diy';
|
||||
|
||||
const props = defineProps(['component', 'index']);
|
||||
|
||||
const diyStore = useDiyStore();
|
||||
|
||||
const diyComponent = computed(() => {
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return diyStore.value[props.index];
|
||||
} else {
|
||||
return props.component;
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
24
uni-app/components/diy/extend/hello-text/index.vue
Normal file
24
uni-app/components/diy/extend/hello-text/index.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<view>
|
||||
演示插件文本——自定义组件
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import useDiyStore from '@/stores/diy';
|
||||
|
||||
const props = defineProps(['component', 'index']);
|
||||
|
||||
const diyStore = useDiyStore();
|
||||
|
||||
const diyComponent = computed(() => {
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return diyStore.value[props.index];
|
||||
} else {
|
||||
return props.component;
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@ -6,35 +6,41 @@
|
||||
|
||||
<!-- 标题 -->
|
||||
<template v-if="component.componentName == 'Text'">
|
||||
<diy-text :component="component" :index="index"></diy-text>
|
||||
<diy-system-text :component="component" :index="index"></diy-system-text>
|
||||
</template>
|
||||
|
||||
<!-- 图片广告 -->
|
||||
<template v-if="component.componentName == 'ImageAds'">
|
||||
<diy-image-ads :component="component" :index="index"></diy-image-ads>
|
||||
<diy-system-image-ads :component="component" :index="index"></diy-system-image-ads>
|
||||
</template>
|
||||
|
||||
<!-- 图文导航 -->
|
||||
<template v-if="component.componentName == 'GraphicNav'">
|
||||
<diy-graphic-nav :component="component" :index="index"></diy-graphic-nav>
|
||||
<diy-system-graphic-nav :component="component" :index="index"></diy-system-graphic-nav>
|
||||
</template>
|
||||
|
||||
<!-- 文章 -->
|
||||
<template v-if="component.componentName == 'Article'">
|
||||
<diy-article :component="component" :index="index"></diy-article>
|
||||
<diy-system-article :component="component" :index="index"></diy-system-article>
|
||||
</template>
|
||||
|
||||
<!-- 辅助空白 -->
|
||||
<template v-if="component.componentName == 'HorzBlank'">
|
||||
<diy-horz-blank :component="component" :index="index"></diy-horz-blank>
|
||||
<diy-system-horz-blank :component="component" :index="index"></diy-system-horz-blank>
|
||||
</template>
|
||||
|
||||
<!-- 会员信息 -->
|
||||
<template v-if="component.componentName == 'MemberInfo'">
|
||||
<diy-member-info :component="component" :index="index"></diy-member-info>
|
||||
<diy-system-member-info :component="component" :index="index"></diy-system-member-info>
|
||||
</template>
|
||||
|
||||
<!-- 自定义扩展组件 -->
|
||||
<template v-if="systemComponent.indexOf(component.componentName) == -1">
|
||||
<diy-comp-extend :component="component" :index="index"></diy-comp-extend>
|
||||
</template>
|
||||
</view>
|
||||
<template v-if="diyStore.mode == ''">
|
||||
<view class="pt-[20rpx]"></view>
|
||||
<tabbar />
|
||||
</template>
|
||||
</view>
|
||||
@ -43,7 +49,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useDiyStore from '@/stores/diy';
|
||||
import { onMounted, nextTick, computed } from 'vue';
|
||||
import { onMounted, nextTick, computed, ref } from 'vue';
|
||||
import Sortable from 'sortablejs';
|
||||
import { range } from 'lodash-es';
|
||||
|
||||
@ -59,6 +65,9 @@
|
||||
}
|
||||
})
|
||||
|
||||
// 系统组件
|
||||
const systemComponent = ref(['Text', 'ImageAds', 'GraphicNav', 'Article', 'HorzBlank', 'MemberInfo'])
|
||||
|
||||
onMounted(() => {
|
||||
// #ifdef H5
|
||||
if (diyStore.mode == 'decorate') {
|
||||
|
||||
@ -1,120 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<u-navbar :placeholder="true" bgColor="var(--primary-color)" titleStyle="color: #fff">
|
||||
<template #left>
|
||||
</template>
|
||||
</u-navbar>
|
||||
<!-- #endif -->
|
||||
<view class="bg-primary" v-if="info">
|
||||
<view class="flex p-[30rpx]">
|
||||
<u-avatar :src="img(info.headimg)" size="60" leftIcon="none" @click="clickAvatar"></u-avatar>
|
||||
<view class="flex-1 w-0 mx-[20rpx] flex justify-center flex-col">
|
||||
<view class="text-white font-bold text-lg">{{ info.nickname }}</view>
|
||||
<view></view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<app-link url="/pages/setting/index">
|
||||
<text class="iconfont iconshezhi text-white text-lg ml-[10rpx]"></text>
|
||||
</app-link>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="flex m-[30rpx] mb-0 py-[30rpx] bg-white rounded-lg rounded-b-none">
|
||||
<view class="flex-1 text-center">
|
||||
<view class="font-bold">
|
||||
<app-link url="/pages/member/point">{{ parseInt(info.point) }}</app-link>
|
||||
</view>
|
||||
<view class="text-sm mt-[10rpx]">
|
||||
<app-link url="/pages/member/point">{{ t('point') }}</app-link>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-1 text-center">
|
||||
<view class="font-bold">
|
||||
<app-link url="/pages/member/balance">{{ moneyFormat(info.balance) }}</app-link>
|
||||
</view>
|
||||
<view class="text-sm mt-[10rpx]">
|
||||
<app-link url="/pages/member/balance">{{ t('balance') }}</app-link>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<information-filling ref="infoFill"></information-filling>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view v-else class="flex p-[30rpx] bg-primary" @click="toLogin">
|
||||
<u-avatar src="" size="60"></u-avatar>
|
||||
<view class="flex-1 w-0 mx-[20rpx] flex justify-center flex-col">
|
||||
<view class="text-white font-bold text-lg">{{ t('login') }}/{{ t('register') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import useMemberStore from '@/stores/member'
|
||||
import { useLogin } from '@/hooks/useLogin'
|
||||
import { img, isWeixinBrowser, redirect, urlDeconstruction, moneyFormat } from '@/utils/common'
|
||||
import { t } from '@/locale'
|
||||
import { wechatSync } from '@/api/system'
|
||||
import useDiyStore from '@/stores/diy'
|
||||
|
||||
const props = defineProps(['component', 'index']);
|
||||
|
||||
const diyStore = useDiyStore();
|
||||
|
||||
const diyComponent = computed(() => {
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return diyStore.value[props.index];
|
||||
} else {
|
||||
return props.component;
|
||||
}
|
||||
})
|
||||
|
||||
const memberStore = useMemberStore()
|
||||
|
||||
const { query } = urlDeconstruction(location.href)
|
||||
if (query.code && isWeixinBrowser()) {
|
||||
wechatSync({ code: query.code }).then(res => {
|
||||
memberStore.getMemberInfo()
|
||||
})
|
||||
}
|
||||
|
||||
const info = computed(() => {
|
||||
// 装修模式
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return {
|
||||
headimg: '',
|
||||
nickname: '昵称',
|
||||
balance: 0,
|
||||
point: 0
|
||||
}
|
||||
} else {
|
||||
return memberStore.info;
|
||||
}
|
||||
})
|
||||
|
||||
const toLogin = () => {
|
||||
useLogin().setLoginBack({ url: '/pages/member/index' })
|
||||
}
|
||||
|
||||
const infoFill = ref(false)
|
||||
const clickAvatar = () => {
|
||||
// #ifdef MP-WEIXIN
|
||||
infoFill.value.show = true
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
if (isWeixinBrowser()) {
|
||||
useLogin().getAuthCode('snsapi_userinfo')
|
||||
} else {
|
||||
redirect({ url: '/pages/member/personal' })
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<view class="bg-white">
|
||||
<view v-if="diyComponent.layout == 'vertical'" class="graphic-nav py-[20rpx] px-[30rpx] box-border relative">
|
||||
<div v-if="diyComponent.navTitle"
|
||||
<view class="bg-[#F5F6F8]">
|
||||
<view v-if="diyComponent.layout == 'vertical'" class="graphic-nav px-[32rpx] bg-white rounded-[20rpx] box-border relative m-[30rpx]">
|
||||
<!-- <div v-if="diyComponent.navTitle"
|
||||
class="py-2 border-solid border-b border-t-0 border-l-0 border-r-0 border-gray-200">
|
||||
{{diyComponent.navTitle}}
|
||||
</div>
|
||||
</div> -->
|
||||
<view
|
||||
class="graphic-nav-item flex items-center justify-between py-2 border-solid border-l-0 border-r-0 border-b-0 border-gray-200"
|
||||
class="graphic-nav-item flex items-center justify-between py-2 border-gray-200"
|
||||
v-for=" (item, index) in diyComponent.list" :key="item.id"
|
||||
:class="[index == 0 ? 'border-t-0':'border-t']" @click="redirectTo(item.link)">
|
||||
|
||||
174
uni-app/components/diy/system/member-info/index.vue
Normal file
174
uni-app/components/diy/system/member-info/index.vue
Normal file
@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<u-navbar :placeholder="true" bgColor="var(--primary-color)" titleStyle="color: #fff">
|
||||
<template #left>
|
||||
</template>
|
||||
</u-navbar>
|
||||
<!-- #endif -->
|
||||
<view class="pt-[34rpx] member-info">
|
||||
<view v-if="info" class="flex ml-[32rpx] mr-[52rpx] items-center relative">
|
||||
<!-- clickAvatar 唤起获取微信 -->
|
||||
<u-avatar :src="img(info.headimg)" size="60" leftIcon="none" @click="clickAvatar"></u-avatar>
|
||||
<view class="ml-[22rpx]">
|
||||
<view class="text-[#222222] truncate w-[430rpx] font-bold text-lg">{{ info.nickname }}</view>
|
||||
<view class="text-[#696B70] text-[24rpx] mt-[10rpx]">{{ t('memberLanguage') }}</view>
|
||||
</view>
|
||||
<view class="set-icon flex items-center absolute right-0 top-2">
|
||||
<app-link url="/pages/setting/index">
|
||||
<text class="iconfont iconshezhi text-[#000] text-[1.6rem] ml-[10rpx]"></text>
|
||||
</app-link>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="flex ml-[32rpx] mr-[52rpx] items-center relative" @click="toLogin">
|
||||
<u-avatar src="" size="60"></u-avatar>
|
||||
<view class="ml-[22rpx]">
|
||||
<view class="text-[#222222] font-bold text-lg">{{ t('login') }}/{{ t('register') }}</view>
|
||||
<view class="text-[#696B70] text-[24rpx] mt-[10rpx]">{{ t('memberLanguage') }}</view>
|
||||
</view>
|
||||
<view class="set-icon flex items-center absolute right-0 top-2">
|
||||
<app-link url="/pages/setting/index">
|
||||
<text class="iconfont iconshezhi text-[#000] text-[1.6rem] ml-[10rpx]"></text>
|
||||
</app-link>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="flex m-[30rpx] mb-0 py-[30rpx] ">
|
||||
<view class="flex-1 text-center">
|
||||
<view class="font-bold">
|
||||
<app-link :url="(info ? '/pages/member/point' : '')">{{ parseInt(info?.point) || 0 }}</app-link>
|
||||
</view>
|
||||
<view class="text-sm mt-[10rpx]">
|
||||
<app-link :url="(info ? '/pages/member/point' : '')">{{ t('point') }}</app-link>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-1 text-center">
|
||||
<view class="font-bold">
|
||||
<app-link :url="(info ? '/pages/member/balance' : '')">{{ money }}</app-link>
|
||||
</view>
|
||||
<view class="text-sm mt-[10rpx]">
|
||||
<app-link :url="(info ? '/pages/member/balance' : '')">{{ t('balance') }}</app-link>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="m-[32rpx] flex justify-between p-[32rpx] bg-white rounded-[20rpx]">
|
||||
<app-link url="/pages/member/personal">
|
||||
<view>
|
||||
<view class="w-[60rpx] h-[60rpx] mx-auto">
|
||||
<image class="w-[60rpx]" :src="img('static/resource/images/diy/m_info.jpg')" mode="widthFix" />
|
||||
</view>
|
||||
<view class="text-[24rpx] text-[#333] mt-[18rpx] text-center">{{ t('memberCenter') }}</view>
|
||||
</view>
|
||||
</app-link>
|
||||
<app-link url="/pages/member/balance">
|
||||
<view>
|
||||
<view class="w-[60rpx] h-[60rpx] mx-auto">
|
||||
<image class="w-[60rpx]" :src="img('static/resource/images/diy/m_balance.jpg')"
|
||||
mode="widthFix" />
|
||||
</view>
|
||||
<view class="text-[24rpx] text-[#333] mt-[18rpx] text-center">{{ t('myBalance') }}</view>
|
||||
</view>
|
||||
</app-link>
|
||||
<app-link url="/pages/member/point">
|
||||
<view>
|
||||
<view class="w-[60rpx] h-[60rpx] mx-auto">
|
||||
<image class="w-[60rpx]" :src="img('static/resource/images/diy/m_point.jpg')" mode="widthFix" />
|
||||
</view>
|
||||
<view class="text-[24rpx] text-[#333] mt-[18rpx] text-center">{{ t('myPoint') }}</view>
|
||||
</view>
|
||||
</app-link>
|
||||
<app-link>
|
||||
<view @click="servicePopup = true">
|
||||
<view class="w-[60rpx] h-[60rpx] mx-auto">
|
||||
<image class="w-[60rpx]" :src="img('static/resource/images/diy/m_service.jpg')"
|
||||
mode="widthFix" />
|
||||
</view>
|
||||
<view class="text-[24rpx] text-[#333] mt-[18rpx] text-center">{{ t('customerService') }}</view>
|
||||
</view>
|
||||
</app-link>
|
||||
</view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<information-filling ref="infoFill"></information-filling>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import useMemberStore from '@/stores/member'
|
||||
import { useLogin } from '@/hooks/useLogin'
|
||||
import { img, isWeixinBrowser, redirect, urlDeconstruction, moneyFormat } from '@/utils/common'
|
||||
import { t } from '@/locale'
|
||||
import { wechatSync } from '@/api/system'
|
||||
import useDiyStore from '@/stores/diy'
|
||||
|
||||
const props = defineProps(['component', 'index']);
|
||||
|
||||
const diyStore = useDiyStore();
|
||||
|
||||
const diyComponent = computed(() => {
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return diyStore.value[props.index];
|
||||
} else {
|
||||
return props.component;
|
||||
}
|
||||
})
|
||||
|
||||
const memberStore = useMemberStore()
|
||||
|
||||
const { query } = urlDeconstruction(location.href)
|
||||
if (query.code && isWeixinBrowser()) {
|
||||
wechatSync({ code: query.code }).then(res => {
|
||||
memberStore.getMemberInfo()
|
||||
})
|
||||
}
|
||||
|
||||
const info = computed(() => {
|
||||
// 装修模式
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return {
|
||||
headimg: '',
|
||||
nickname: '昵称',
|
||||
balance: 0,
|
||||
point: 0
|
||||
}
|
||||
} else {
|
||||
return memberStore.info;
|
||||
}
|
||||
})
|
||||
|
||||
const money = computed(() => {
|
||||
if (info.value) {
|
||||
let m = parseFloat(info.value.balance) + parseFloat(info.value.money)
|
||||
return moneyFormat(m.toString());
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
|
||||
const toLogin = () => {
|
||||
useLogin().setLoginBack({ url: '/pages/member/index' })
|
||||
}
|
||||
|
||||
const infoFill = ref(false)
|
||||
const clickAvatar = () => {
|
||||
// #ifdef MP-WEIXIN
|
||||
infoFill.value.show = true
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
if (isWeixinBrowser()) {
|
||||
useLogin().getAuthCode('snsapi_userinfo')
|
||||
} else {
|
||||
redirect({ url: '/pages/member/personal' })
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.member-info {
|
||||
background-image: linear-gradient(#E3F0FF, #F5F6F8)
|
||||
}
|
||||
</style>
|
||||
@ -35,7 +35,7 @@
|
||||
import { t } from '@/locale'
|
||||
import useMemberStore from '@/stores/member'
|
||||
import { img } from '@/utils/common'
|
||||
import { updateMember } from '@/api/member'
|
||||
import { modifyMember } from '@/api/member'
|
||||
import { fetchBase64Image } from '@/api/system'
|
||||
|
||||
const show = ref(false)
|
||||
@ -92,7 +92,7 @@
|
||||
loading.value = true
|
||||
|
||||
// 修改头像
|
||||
await updateMember({ field: 'headimg', value: formData.headimg })
|
||||
await modifyMember({ field: 'headimg', value: formData.headimg })
|
||||
.then(() => {
|
||||
memberStore.info.headimg = formData.headimg
|
||||
})
|
||||
@ -102,7 +102,7 @@
|
||||
if (!loading.value) return
|
||||
|
||||
// 修改昵称
|
||||
updateMember({ field: 'nickname', value: formData.nickname })
|
||||
modifyMember({ field: 'nickname', value: formData.nickname })
|
||||
.then(() => {
|
||||
memberStore.info.nickname = formData.nickname
|
||||
loading.value = false
|
||||
|
||||
@ -1,173 +1,178 @@
|
||||
<template>
|
||||
<u-popup :show="show" :round="10" @close="handleClose" :closeable="true" bgColor="#fff"
|
||||
:closeOnClickOverlay="false">
|
||||
<view class="flex flex-col h-[75vh]" v-if="payInfo">
|
||||
<view class="head">
|
||||
<view class="text-center py-[26rpx]">{{ t('pay.payTitle') }}</view>
|
||||
<view class="flex items-end justify-center w-full text-xl font-bold py-[20rpx]">
|
||||
<view class="text-base mr-[4rpx]">{{ t('currency') }}</view>
|
||||
{{ moneyFormat(payInfo.money) }}
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" class="flex-1 pt-[20rpx]">
|
||||
<view class="flex text-sm px-[30rpx] py-[20rpx]">
|
||||
<view class="text-gray-500">{{ t('pay.orderInfo') }}</view>
|
||||
<view class="text-right flex-1 pl-[30rpx] truncate">{{ payInfo.body }}</view>
|
||||
</view>
|
||||
<view class="mx-[30rpx] py-[10rpx] px-[30rpx] bg-white rounded-md bg-page">
|
||||
<view
|
||||
class="pay-item py-[18rpx] flex items-center border-0 border-b border-solid border-[#eee]"
|
||||
v-for="(item, index) in payInfo.pay_type_list"
|
||||
:key="index" @click="type = item.key">
|
||||
<u-image :src="img(item.icon)" width="50rpx" height="50rpx"></u-image>
|
||||
<view class="flex-1 px-[20rpx] text-sm font-bold">{{ item.name }}</view>
|
||||
<u-icon name="checkbox-mark" color="var(--primary-color)" v-if="item.key == type"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="p-[30rpx]">
|
||||
<u-button type="primary" :loading="loading" :text="t('pay.confirmPay')" shape="circle"
|
||||
@click="confirmPay"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<u-popup :show="show" :round="10" @close="handleClose" :closeable="true" bgColor="#fff"
|
||||
:closeOnClickOverlay="false">
|
||||
<view class="flex flex-col h-[75vh]" v-if="payInfo">
|
||||
<view class="head">
|
||||
<view class="text-center py-[26rpx]">{{ t('pay.payTitle') }}</view>
|
||||
<view class="flex items-end justify-center w-full text-xl font-bold py-[20rpx]">
|
||||
<view class="text-base mr-[4rpx]">{{ t('currency') }}</view>
|
||||
{{ moneyFormat(payInfo.money) }}
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" class="flex-1 pt-[20rpx]">
|
||||
<view class="flex text-sm px-[30rpx] py-[20rpx]">
|
||||
<view class="text-gray-500">{{ t('pay.orderInfo') }}</view>
|
||||
<view class="text-right flex-1 pl-[30rpx] truncate">{{ payInfo.body }}</view>
|
||||
</view>
|
||||
<view class="mx-[30rpx] py-[10rpx] px-[30rpx] bg-white rounded-md bg-page">
|
||||
<block v-if="payInfo.pay_type_list.length">
|
||||
<view class="pay-item py-[18rpx] flex items-center border-0 border-b border-solid border-[#eee]"
|
||||
v-for="(item, index) in payInfo.pay_type_list" :key="index" @click="type = item.key">
|
||||
<u-image :src="img(item.icon)" width="50rpx" height="50rpx"></u-image>
|
||||
<view class="flex-1 px-[20rpx] text-sm font-bold">{{ item.name }}</view>
|
||||
<u-icon name="checkbox-mark" color="var(--primary-color)" v-if="item.key == type"></u-icon>
|
||||
</view>
|
||||
</block>
|
||||
<view class="py-[20rpx] text-center text-sm text-gray-subtitle">{{ t('pay.notHavePayType') }}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="p-[30rpx]">
|
||||
<u-button type="primary" :loading="loading" :text="t('pay.confirmPay')" shape="circle"
|
||||
@click="confirmPay"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { t } from '@/locale'
|
||||
import { getPayInfo, pay } from '@/api/pay'
|
||||
import { img, redirect, isWeixinBrowser, moneyFormat } from '@/utils/common'
|
||||
import wechat from '@/utils/wechat'
|
||||
import { ref } from 'vue'
|
||||
import { t } from '@/locale'
|
||||
import { getPayInfo, pay } from '@/api/pay'
|
||||
import { img, redirect, isWeixinBrowser, moneyFormat } from '@/utils/common'
|
||||
import wechat from '@/utils/wechat'
|
||||
|
||||
const show = ref(false)
|
||||
const loading = ref(false)
|
||||
// #ifdef H5
|
||||
if (isWeixinBrowser()) wechat.init();
|
||||
// #endif
|
||||
|
||||
const payInfo = ref<AnyObject | null>(null)
|
||||
const type = ref('')
|
||||
const show = ref(false)
|
||||
const loading = ref(false)
|
||||
|
||||
/**
|
||||
* 确认支付
|
||||
*/
|
||||
const confirmPay = () => {
|
||||
if (uni.$u.test.isEmpty(type.value)) {
|
||||
uni.showToast({ title: t('pay.notHavePayType'), icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
const payInfo = ref<AnyObject | null>(null)
|
||||
const type = ref('')
|
||||
|
||||
pay({
|
||||
out_trade_no: payInfo.value?.out_trade_no,
|
||||
type: type.value
|
||||
}).then(res => {
|
||||
switch (type.value) {
|
||||
case 'wechatpay':
|
||||
// #ifndef H5
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
...res.data,
|
||||
success: (res) => {
|
||||
redirect({ url: '/pages/pay/result', param: { code: payInfo.value?.out_trade_no }, mode: 'redirectTo' })
|
||||
},
|
||||
fail: (res) => {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
if (isWeixinBrowser()) {
|
||||
res.data.timestamp = res.data.timeStamp
|
||||
delete res.data.timeStamp
|
||||
wechat.pay({
|
||||
...res.data,
|
||||
success: () => {
|
||||
redirect({ url: '/pages/pay/result', param: { code: payInfo.value?.out_trade_no }, mode: 'redirectTo' })
|
||||
},
|
||||
cancel: () => {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.setStorageSync('paymenting', payInfo.value?.out_trade_no)
|
||||
location.href = res.data.h5_url
|
||||
addListenerPayBack()
|
||||
}
|
||||
// #endif
|
||||
break;
|
||||
case 'alipay':
|
||||
// #ifdef H5
|
||||
if (isWeixinBrowser()) {
|
||||
redirect({ url: '/pages/pay/browser', param: { code: payInfo.value?.out_trade_no, alipay: encodeURIComponent(res.data.url) }, mode: 'redirectTo' })
|
||||
} else {
|
||||
uni.setStorageSync('paymenting', payInfo.value?.out_trade_no)
|
||||
location.href = res.data.url
|
||||
addListenerPayBack()
|
||||
}
|
||||
// #endif
|
||||
break;
|
||||
default:
|
||||
redirect({ url: '/pages/pay/result', param: { code: payInfo.value?.out_trade_no }, mode: 'redirectTo' })
|
||||
}
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 确认支付
|
||||
*/
|
||||
const confirmPay = () => {
|
||||
if (uni.$u.test.isEmpty(type.value)) {
|
||||
uni.showToast({ title: t('pay.notHavePayType'), icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
|
||||
/**
|
||||
* 检测是否是支付后返回
|
||||
*/
|
||||
uni.$on('checkIsReturnAfterPayment', () => {
|
||||
if (uni.getStorageSync('paymenting')) {
|
||||
redirect({
|
||||
url: '/pages/pay/result',
|
||||
param: { code: uni.getStorageSync('paymenting') },
|
||||
mode: 'redirectTo',
|
||||
success() {
|
||||
uni.removeStorageSync('paymenting')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
pay({
|
||||
out_trade_no: payInfo.value?.out_trade_no,
|
||||
type: type.value
|
||||
}).then(res => {
|
||||
switch (type.value) {
|
||||
case 'wechatpay':
|
||||
// #ifndef H5
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
...res.data,
|
||||
success: (res) => {
|
||||
redirect({ url: '/pages/pay/result', param: { code: payInfo.value?.out_trade_no }, mode: 'redirectTo' })
|
||||
},
|
||||
fail: (res) => {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
if (isWeixinBrowser()) {
|
||||
res.data.timestamp = res.data.timeStamp
|
||||
delete res.data.timeStamp
|
||||
wechat.pay({
|
||||
...res.data,
|
||||
success: () => {
|
||||
redirect({ url: '/pages/pay/result', param: { code: payInfo.value?.out_trade_no }, mode: 'redirectTo' })
|
||||
},
|
||||
cancel: () => {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.setStorageSync('paymenting', payInfo.value?.out_trade_no)
|
||||
location.href = res.data.h5_url
|
||||
addListenerPayBack()
|
||||
}
|
||||
// #endif
|
||||
break;
|
||||
case 'alipay':
|
||||
// #ifdef H5
|
||||
if (isWeixinBrowser()) {
|
||||
redirect({ url: '/pages/pay/browser', param: { code: payInfo.value?.out_trade_no, alipay: encodeURIComponent(res.data.url) }, mode: 'redirectTo' })
|
||||
} else {
|
||||
uni.setStorageSync('paymenting', payInfo.value?.out_trade_no)
|
||||
location.href = res.data.url
|
||||
addListenerPayBack()
|
||||
}
|
||||
// #endif
|
||||
break;
|
||||
default:
|
||||
redirect({ url: '/pages/pay/result', param: { code: payInfo.value?.out_trade_no }, mode: 'redirectTo' })
|
||||
}
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const open = (outTradeNo : string) => {
|
||||
getPayInfo(outTradeNo)
|
||||
.then((res : any) => {
|
||||
let { data } = res
|
||||
if (uni.$u.test.isEmpty(data)) {
|
||||
uni.showToast({ title: t('pay.notObtainedInfo'), icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (data.money == 0) {
|
||||
redirect({ url: '/pages/pay/result', param: { code: outTradeNo }, mode: 'redirectTo' })
|
||||
return
|
||||
}
|
||||
if (data.status != 0) {
|
||||
uni.showToast({ title: t('pay.paymentDocuments') + data.status_name, icon: 'none' })
|
||||
return
|
||||
}
|
||||
payInfo.value = data
|
||||
type.value = data.pay_type_list[0] ? data.pay_type_list[0].key : ''
|
||||
show.value = true
|
||||
})
|
||||
.catch(() => { })
|
||||
}
|
||||
/**
|
||||
* 检测是否是支付后返回
|
||||
*/
|
||||
uni.$on('checkIsReturnAfterPayment', () => {
|
||||
if (uni.getStorageSync('paymenting')) {
|
||||
redirect({
|
||||
url: '/pages/pay/result',
|
||||
param: { code: uni.getStorageSync('paymenting') },
|
||||
mode: 'redirectTo',
|
||||
success() {
|
||||
uni.removeStorageSync('paymenting')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['close'])
|
||||
const open = (outTradeNo : string) => {
|
||||
getPayInfo(outTradeNo)
|
||||
.then((res : any) => {
|
||||
let { data } = res
|
||||
if (uni.$u.test.isEmpty(data)) {
|
||||
uni.showToast({ title: t('pay.notObtainedInfo'), icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (data.money == 0) {
|
||||
redirect({ url: '/pages/pay/result', param: { code: outTradeNo }, mode: 'redirectTo' })
|
||||
return
|
||||
}
|
||||
if (data.status != 0) {
|
||||
uni.showToast({ title: t('pay.paymentDocuments') + data.status_name, icon: 'none' })
|
||||
return
|
||||
}
|
||||
payInfo.value = data
|
||||
type.value = data.pay_type_list[0] ? data.pay_type_list[0].key : ''
|
||||
show.value = true
|
||||
})
|
||||
.catch(() => { })
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
uni.removeStorageSync('paymenting')
|
||||
show.value = false
|
||||
emits('close')
|
||||
}
|
||||
const emits = defineEmits(['close'])
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
const handleClose = () => {
|
||||
uni.removeStorageSync('paymenting')
|
||||
show.value = false
|
||||
emits('close')
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pay-item:last-child {
|
||||
border: none;
|
||||
}
|
||||
.pay-item:last-child {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
@ -1,29 +1,41 @@
|
||||
<template>
|
||||
<u-tabbar :value="value" @change="tabbarChange" :fixed="true" :placeholder="true" :safeAreaInsetBottom="true" :inactive-color="tabbar.textColor" :active-color="tabbar.textHoverColor" v-if="tabbar">
|
||||
<block v-for="item in tabbar.list">
|
||||
<u-tabbar-item :style="{'background-color': tabbar.backgroundColor}" :text="item.text" :icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url" v-if="tabbar.type == 1"></u-tabbar-item>
|
||||
<u-tabbar-item :style="{'background-color': tabbar.backgroundColor}" :icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url" v-if="tabbar.type == 2"></u-tabbar-item>
|
||||
<u-tabbar-item :style="{'background-color': tabbar.backgroundColor}" :text="item.text" :name="item.link.url" v-if="tabbar.type == 3"></u-tabbar-item>
|
||||
</block>
|
||||
</u-tabbar>
|
||||
<u-tabbar :value="value" @change="tabbarChange" :fixed="true" :placeholder="true" :safeAreaInsetBottom="true"
|
||||
:inactive-color="tabbar.textColor" :active-color="tabbar.textHoverColor" v-if="tabbar">
|
||||
<block v-for="item in tabbar.list">
|
||||
<u-tabbar-item :style="{'background-color': tabbar.backgroundColor}" :text="item.text"
|
||||
:icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url"
|
||||
v-if="tabbar.type == 1"></u-tabbar-item>
|
||||
<u-tabbar-item :style="{'background-color': tabbar.backgroundColor}"
|
||||
:icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url"
|
||||
v-if="tabbar.type == 2"></u-tabbar-item>
|
||||
<u-tabbar-item :style="{'background-color': tabbar.backgroundColor}" :text="item.text" :name="item.link.url"
|
||||
v-if="tabbar.type == 3"></u-tabbar-item>
|
||||
</block>
|
||||
</u-tabbar>
|
||||
<view class="tab-bar-placeholder"></view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { redirect, currRoute, img } from '@/utils/common'
|
||||
import useConfigStore from '@/stores/config'
|
||||
import { computed } from 'vue'
|
||||
import { redirect, currRoute, img } from '@/utils/common'
|
||||
import useConfigStore from '@/stores/config'
|
||||
|
||||
const tabbar = computed(() => {
|
||||
return useConfigStore().tabbar
|
||||
})
|
||||
const tabbar = computed(() => {
|
||||
return useConfigStore().tabbar
|
||||
})
|
||||
|
||||
const value = computed(() => {
|
||||
return '/' + currRoute()
|
||||
})
|
||||
const value = computed(() => {
|
||||
return '/' + currRoute()
|
||||
})
|
||||
|
||||
const tabbarChange = (name: string) => {
|
||||
redirect({ url: `${name}` })
|
||||
}
|
||||
const tabbarChange = (name : string) => {
|
||||
redirect({ url: `${name}` })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.tab-bar-placeholder {
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 112rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 112rpx);
|
||||
}
|
||||
</style>
|
||||
@ -12,11 +12,9 @@ export function useCaptcha(formData: formData) {
|
||||
const refresh = async ()=> {
|
||||
try {
|
||||
const res:AnyObject = await getCaptcha()
|
||||
if (res.code == 200) {
|
||||
formData.captcha_key = res.data.captcha_key
|
||||
formData.captcha_code = ''
|
||||
image.value = res.data.img.replace(/\r\n/g, '')
|
||||
}
|
||||
formData.captcha_key = res.data.captcha_key
|
||||
formData.captcha_code = ''
|
||||
image.value = res.data.img.replace(/\r\n/g, '')
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { redirect, isWeixinBrowser } from '@/utils/common'
|
||||
import { redirect, isWeixinBrowser, urlDeconstruction } from '@/utils/common'
|
||||
import { weappLogin, wechatLogin } from '@/api/auth'
|
||||
import { getWechatAuthCode } from '@/api/system'
|
||||
import useMemberStore from '@/stores/member'
|
||||
@ -14,18 +14,18 @@ export function useLogin() {
|
||||
const config = useConfigStore()
|
||||
// #ifdef MP-WEIXIN
|
||||
if (uni.getStorageSync('openid') && config.login.is_bind_mobile) {
|
||||
redirect({ url: '/pages/auth/bind' })
|
||||
redirect({ url: '/pages/auth/bind', mode: 'redirectTo' })
|
||||
return
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
if (isWeixinBrowser() && uni.getStorageSync('openid') && config.login.is_bind_mobile) {
|
||||
redirect({ url: '/pages/auth/bind' })
|
||||
redirect({ url: '/pages/auth/bind', mode: 'redirectTo' })
|
||||
return
|
||||
}
|
||||
// #endif
|
||||
redirect({ url: '/pages/auth/login' })
|
||||
redirect({ url: '/pages/auth/login', mode: 'redirectTo' })
|
||||
})
|
||||
}
|
||||
|
||||
@ -83,8 +83,13 @@ export function useLogin() {
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
let url = `${location.origin}${location.pathname}`
|
||||
let query = urlDeconstruction(location.href).query
|
||||
query.code && (delete query.code)
|
||||
Object.keys(query).length && (url += uni.$u.queryParams(query))
|
||||
|
||||
getWechatAuthCode({
|
||||
url: `${location.origin}${location.pathname}`,
|
||||
url,
|
||||
scopes
|
||||
}).then((res : AnyObject) => {
|
||||
location.href = res.data.url
|
||||
|
||||
@ -21,7 +21,7 @@ export function useSendSms(smsRef: AnyObject | null) {
|
||||
|
||||
let result: string | boolean = false
|
||||
await sendSms(param).then(res=>{
|
||||
if (res.code == 200) {
|
||||
if (res.code == 1) {
|
||||
result = res.data.key
|
||||
} else {
|
||||
smsRef.value.reset()
|
||||
@ -29,6 +29,7 @@ export function useSendSms(smsRef: AnyObject | null) {
|
||||
}
|
||||
}).catch(err=>{
|
||||
result = false
|
||||
smsRef.value.reset()
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
@ -8,14 +8,19 @@ import wechat from '@/utils/wechat'
|
||||
// #endif
|
||||
|
||||
export const useShare = () => {
|
||||
let wechatOptions : WeixinJsSdk.OnMenuShareAppMessageOptions = {
|
||||
var wechatOptions : WeixinJsSdk.OnMenuShareAppMessageOptions = {
|
||||
title: '',
|
||||
link: ''
|
||||
};
|
||||
|
||||
let weappOptions = {};
|
||||
var weappOptions = {};
|
||||
|
||||
// #ifdef H5
|
||||
const wechatInit = async () => {
|
||||
if (!isWeixinBrowser()) return;
|
||||
await wechat.init();
|
||||
}
|
||||
|
||||
// 微信公众号分享
|
||||
const wechatShare = () => {
|
||||
if (!isWeixinBrowser()) return;
|
||||
@ -23,17 +28,26 @@ export const useShare = () => {
|
||||
}
|
||||
// #endif
|
||||
|
||||
const setShare = (options : any = {}) => {
|
||||
const setShare = async (options : any = {}) => {
|
||||
let memberStore = useMemberStore();
|
||||
|
||||
// 初始化sdk
|
||||
await wechatInit();
|
||||
|
||||
if (options && options.wechat && options.weapp) {
|
||||
let query = currShareRoute().params;
|
||||
|
||||
if (memberStore.info) {
|
||||
query.push('mid=' + memberStore.info.member_id);
|
||||
query.mid = memberStore.info.member_id;
|
||||
}
|
||||
|
||||
let str = [];
|
||||
for (let key in query) {
|
||||
str.push(key + '=' + query[key]);
|
||||
}
|
||||
|
||||
// #ifdef H5
|
||||
let link = location.origin + location.pathname + (query.length > 0 ? '?' + query.join('&') : '');
|
||||
let link = location.origin + location.pathname + (str.length > 0 ? '?' + str.join('&') : '');
|
||||
wechatOptions = {
|
||||
title: options.wechat.title || '',
|
||||
link: options.wechat.link || link,
|
||||
@ -45,37 +59,35 @@ export const useShare = () => {
|
||||
|
||||
weappOptions = {
|
||||
title: options.weapp.title || '',
|
||||
query: options.weapp.path || '/' + currRoute() + (query.length > 0 ? '?' + query.join('&') : ''),
|
||||
query: options.weapp.path || '/' + currRoute() + (str.length > 0 ? '?' + str.join('&') : ''),
|
||||
imageUrl: options.weapp.url ? img(options.weapp.url) : ''
|
||||
}
|
||||
} else {
|
||||
getShareInfo({ route: '/' + currRoute(), params: currShareRoute().params.toString() }).then((res : any) => {
|
||||
if (res.code == 200) {
|
||||
let data = res.data;
|
||||
getShareInfo({ route: '/' + currRoute(), params: JSON.stringify(currShareRoute().params) }).then((res : any) => {
|
||||
let data = res.data;
|
||||
|
||||
// #ifdef H5
|
||||
let wechat = data.wechat;
|
||||
if (wechat) {
|
||||
let link = location.origin + location.pathname + (data.query ? '?' + data.query : '');
|
||||
wechatOptions = {
|
||||
link: link,
|
||||
title: wechat.title,
|
||||
desc: wechat.desc,
|
||||
imgUrl: wechat.url ? img(wechat.url) : ''
|
||||
}
|
||||
}
|
||||
wechatShare()
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
let wechat = data.wechat;
|
||||
if (wechat) {
|
||||
let link = location.origin + location.pathname + (data.query ? '?' + data.query : '');
|
||||
wechatOptions = {
|
||||
link: link,
|
||||
title: wechat.title,
|
||||
desc: wechat.desc,
|
||||
imgUrl: wechat.url ? img(wechat.url) : ''
|
||||
}
|
||||
}
|
||||
wechatShare()
|
||||
// #endif
|
||||
|
||||
let weapp = data.weapp;
|
||||
if (weapp) {
|
||||
weappOptions = {
|
||||
query: data.url,
|
||||
title: weapp.title,
|
||||
imageUrl: weapp.url ? img(weapp.url) : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
let weapp = data.weapp;
|
||||
if (weapp) {
|
||||
weappOptions = {
|
||||
query: data.url,
|
||||
title: weapp.title,
|
||||
imageUrl: weapp.url ? img(weapp.url) : ''
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -1,13 +1,18 @@
|
||||
{
|
||||
// pages.json 中文标题
|
||||
"pages.index.index": "",
|
||||
"pages.article.list": "资讯中心",
|
||||
"pages.article.detail": "文章详情",
|
||||
"pages.member.index": "",
|
||||
"pages.auth.login": "登录",
|
||||
"pages.auth.register": "注册",
|
||||
"pages.auth.resetpwd": "找回密码",
|
||||
"pages.setting.index": "设置",
|
||||
"pages.auth.bind": "绑定手机号",
|
||||
"pages.member.personal": "个人资料"
|
||||
// pages.json 中文标题
|
||||
"pages.index.index": "",
|
||||
"pages.article.list": "资讯中心",
|
||||
"pages.article.detail": "文章详情",
|
||||
"pages.member.index": "",
|
||||
"pages.auth.login": "登录",
|
||||
"pages.auth.register": "注册",
|
||||
"pages.auth.resetpwd": "找回密码",
|
||||
"pages.setting.index": "设置",
|
||||
"pages.auth.bind": "绑定手机号",
|
||||
"pages.member.personal": "个人资料",
|
||||
"pages.member.balance": "我的余额",
|
||||
"pages.member.detailed_account": "流水明细",
|
||||
"pages.member.apply_cash_out": "申请提现",
|
||||
"pages.member.cash_out": "提现记录",
|
||||
"pages.member.cash_out_detail": "提现详情"
|
||||
}
|
||||
@ -5,6 +5,8 @@
|
||||
"captchaTitle": "请完成验证",
|
||||
"confirm": "确认",
|
||||
"cancel": "取消",
|
||||
"save": "保存",
|
||||
"delete": "删除",
|
||||
"captchaPlaceholder": "请输入验证码",
|
||||
"mobilePlaceholder": "请输入手机号码",
|
||||
"mobileError": "请输入正确的手机号",
|
||||
@ -36,5 +38,9 @@
|
||||
"completePay": "已完成支付",
|
||||
"incompletePay": "未完成支付",
|
||||
"getting": "获取支付结果中"
|
||||
}
|
||||
},
|
||||
"memberLanguage": "与你分享我的观点,共享真实世界",
|
||||
"myBalance": "我的余额",
|
||||
"myPoint": "我的积分",
|
||||
"customerService": "联系客服"
|
||||
}
|
||||
7
uni-app/locale/zh-Hans/pages.member.account.json
Normal file
7
uni-app/locale/zh-Hans/pages.member.account.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"alipayAccountNo": "支付宝账号",
|
||||
"addBankCard": "添加银行卡",
|
||||
"addAlipayAccount": "添加支付宝账号",
|
||||
"endNumber": "尾号",
|
||||
"bankCard": "银行卡"
|
||||
}
|
||||
17
uni-app/locale/zh-Hans/pages.member.account_edit.json
Normal file
17
uni-app/locale/zh-Hans/pages.member.account_edit.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"addBankCard": "添加银行卡",
|
||||
"addBankCardTips": "请添加持卡人本人的银行卡",
|
||||
"addAlipayAccount": "添加支付宝账号",
|
||||
"addAlipayAccountTips": "请添加已实名的支付宝账号",
|
||||
"bankRealname": "持卡人姓名",
|
||||
"bankRealnamePlaceholder": "请输入持卡人姓名",
|
||||
"bankName": "银行名称",
|
||||
"bankNamePlaceholder": "请输入银行名称",
|
||||
"bankAccountNo": "银行卡号",
|
||||
"bankAccountNoPlaceholder": "请输入银行卡号",
|
||||
"alipayRealname": "真实姓名",
|
||||
"alipayRealnamePlaceholder": "请输入真实姓名",
|
||||
"alipayAccountNo": "支付宝账号",
|
||||
"alipayAccountNoPlaceholder": "请输入支付宝账号",
|
||||
"deleteConfirm": "确定要删除该账号吗?"
|
||||
}
|
||||
29
uni-app/locale/zh-Hans/pages.member.apply_cash_out.json
Normal file
29
uni-app/locale/zh-Hans/pages.member.apply_cash_out.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"cashOut": "提现",
|
||||
"balanceDetail": "余额明细",
|
||||
"cashOutTo": "提现到",
|
||||
"cashOutTypePlaceholder": "请选择提现方式",
|
||||
"wechatpay": "微信默认钱包",
|
||||
"cashOutMoneyTip": "提现金额",
|
||||
"money": "可提现余额",
|
||||
"allTx": "全部提现",
|
||||
"minWithdrawal": "最小提现金额为",
|
||||
"commissionTo": "手续费为",
|
||||
"cashOutList": "提现记录",
|
||||
"cashOutToWechat": "提现至微信",
|
||||
"cashOutToWechatTips": "提现至微信零钱",
|
||||
"cashOutToAlipay": "提现至支付宝",
|
||||
"cashOutToAlipayTips": "请先添加支付宝账号",
|
||||
"cashOutToBank": "提现至银行卡",
|
||||
"cashOutToBankTips": "请先添加银行卡",
|
||||
"alipayAccountNo": "支付宝账号",
|
||||
"debitCard": "储蓄卡",
|
||||
"abnormalOperation": "异常操作",
|
||||
"noAvailableCashOutType": "没有可用的提现方式",
|
||||
"applyMoneyPlaceholder": "请输入提现金额",
|
||||
"moneyformatError": "提现金额格式错误",
|
||||
"applyMoneyExceed": "提现金额超出可提现金额",
|
||||
"applyMoneyBelow": "提现金额小于最低提现金额",
|
||||
"replace": "更换",
|
||||
"toAdd": "去添加"
|
||||
}
|
||||
@ -1,8 +1,15 @@
|
||||
{
|
||||
"balanceInfo": "我的余额",
|
||||
"recharge": "充值",
|
||||
"cashOut":"提现",
|
||||
"balanceDetail": "余额明细",
|
||||
"accountBalance":"账户余额(元)",
|
||||
"balance":"余额(元)",
|
||||
"money":"可提现余额(元)",
|
||||
"availableBalance": "可用余额",
|
||||
"rechargeAmountError": "充值金额错误",
|
||||
"clickRecharge": "立即充值",
|
||||
"rechargeAmountPlaceholder": "请输入充值金额"
|
||||
"rechargeAmountPlaceholder": "请输入充值金额",
|
||||
"yuan":"元",
|
||||
"rechargeRecord":"充值记录"
|
||||
}
|
||||
11
uni-app/locale/zh-Hans/pages.member.cash_out.json
Normal file
11
uni-app/locale/zh-Hans/pages.member.cash_out.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"applyTime": "申请时间",
|
||||
"toBeReviewed": "官方正在审核,请耐心等待",
|
||||
"toBeTransfer": "官方正在转账,请耐心等待",
|
||||
"transfer": "官方已转账,请及时查收",
|
||||
"cancelApply": "申请已取消",
|
||||
"balanceDetail": "余额记录",
|
||||
"commissionDetail": "佣金记录",
|
||||
"emptyTip": "暂无余额记录",
|
||||
"commissemptyTip": "暂无佣金记录"
|
||||
}
|
||||
12
uni-app/locale/zh-Hans/pages.member.cash_out_detail.json
Normal file
12
uni-app/locale/zh-Hans/pages.member.cash_out_detail.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"statusName": "当前状态",
|
||||
"cashOutNo": "交易号",
|
||||
"serviceMoney": "手续费",
|
||||
"createTime": "申请时间",
|
||||
"auditTime": "审核时间",
|
||||
"transferBank": "银行名称",
|
||||
"transferAccount": "收款账号",
|
||||
"refuseReason": "拒绝理由",
|
||||
"transferTypeName": "转账方式名称",
|
||||
"transferTime": "转账时间"
|
||||
}
|
||||
14
uni-app/locale/zh-Hans/pages.member.commission.json
Normal file
14
uni-app/locale/zh-Hans/pages.member.commission.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"recharge": "充值",
|
||||
"cashOut":"提现",
|
||||
"commissionDetail": "佣金明细",
|
||||
"accountCommission":"账户佣金(元)",
|
||||
"commission":"累计佣金(元)",
|
||||
"money":"提现中佣金(元)",
|
||||
"availableCommission": "可用佣金",
|
||||
"rechargeAmountError": "充值金额错误",
|
||||
"clickRecharge": "立即充值",
|
||||
"rechargeAmountPlaceholder": "请输入充值金额",
|
||||
"yuan":"元",
|
||||
"commissionInfo": "我的佣金"
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"balanceDetail": "余额明细",
|
||||
"commissionDetail": "佣金明细",
|
||||
"emptyTip": "暂无余额明细",
|
||||
"commissemptyTip": "暂无佣金明细"
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
{
|
||||
"nickname": "昵称",
|
||||
"sex": "性别",
|
||||
"mobile": "手机号",
|
||||
"birthday": "生日",
|
||||
"unknown": "未知",
|
||||
"updateHeadimg": "更换头像",
|
||||
"updateNickname": "修改昵称",
|
||||
"man": "男",
|
||||
"woman": "女",
|
||||
"bindMobile": "绑定手机"
|
||||
}
|
||||
4
uni-app/locale/zh-Hans/pages.member.recharge_record.json
Normal file
4
uni-app/locale/zh-Hans/pages.member.recharge_record.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"rechargeRecord": "充值记录",
|
||||
"emptyTip": "暂无充值记录"
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"statusName": "当前状态",
|
||||
"cashOutNo": "交易号",
|
||||
"serviceMoney": "手续费",
|
||||
"createTime": "申请时间",
|
||||
"auditTime": "审核时间",
|
||||
"transferBank": "银行名称",
|
||||
"transferAccount": "收款账号",
|
||||
"refuseReason": "拒绝理由",
|
||||
"transferTypeName": "转账方式名称",
|
||||
"transferTime": "转账时间"
|
||||
}
|
||||
13
uni-app/locale/zh-Hans/pages.member.withdrawal_detail.json
Normal file
13
uni-app/locale/zh-Hans/pages.member.withdrawal_detail.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"recharge": "充值",
|
||||
"cashOut":"提现",
|
||||
"balanceDetail": "余额明细",
|
||||
"accountBalance":"账户余额(元)",
|
||||
"balance":"余额(元)",
|
||||
"money":"可提现余额(元)",
|
||||
"availableBalance": "可用余额",
|
||||
"rechargeAmountError": "充值金额错误",
|
||||
"clickRecharge": "立即充值",
|
||||
"rechargeAmountPlaceholder": "请输入充值金额",
|
||||
"yuan":"元"
|
||||
}
|
||||
@ -1,68 +1,11 @@
|
||||
{
|
||||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
"pages": [ // pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.index.index%"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/index/diy",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.index.diy%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/login",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarBackgroundColor": "#fff",
|
||||
"navigationBarTitleText": "%pages.auth.login%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/register",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarBackgroundColor": "#fff",
|
||||
"navigationBarTitleText": "%pages.auth.register%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/resetpwd",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarBackgroundColor": "#fff",
|
||||
"navigationBarTitleText": "%pages.auth.resetpwd%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/bind",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarBackgroundColor": "#fff",
|
||||
"navigationBarTitleText": "%pages.auth.bind%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/agreement",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/article/list",
|
||||
@ -73,6 +16,60 @@
|
||||
"navigationBarTitleText": "%pages.article.list%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/agreement",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.auth.agreement%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/bind",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.auth.bind%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/login",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.auth.login%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/register",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.auth.register%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/resetpwd",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.auth.resetpwd%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/diy",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.index.diy%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/article/detail",
|
||||
"style": {
|
||||
@ -82,6 +79,83 @@
|
||||
"navigationBarTitleText": "%pages.article.detail%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/member/apply_cash_out",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.apply_cash_out%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "pages/member/commission",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.commission%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "pages/member/balance",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.balance%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "pages/member/recharge_record",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.recharge_record%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "pages/member/recharge_record_detail",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.recharge_record_detail%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "pages/member/detailed_account",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.detailed_account%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/member/cash_out",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.cash_out%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/member/cash_out_detail",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.cash_out_detail%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/member/index",
|
||||
"style": {
|
||||
@ -92,22 +166,19 @@
|
||||
{
|
||||
"path": "pages/member/info",
|
||||
"style": {
|
||||
"navigationBarTitleText": "%pages.member.index%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "pages/setting/index",
|
||||
"style": {
|
||||
"navigationBarBackgroundColor": "#f7f7f7",
|
||||
"navigationBarTitleText": "%pages.setting.index%"
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.info%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "pages/member/personal",
|
||||
"style": {
|
||||
"navigationBarBackgroundColor": "#f7f7f7",
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.personal%"
|
||||
},
|
||||
"needLogin": true
|
||||
@ -118,17 +189,51 @@
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.balance%"
|
||||
"navigationBarTitleText": "%pages.member.point%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "pages/member/balance",
|
||||
"path": "pages/member/account",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.balance%"
|
||||
"navigationBarTitleText": "%pages.member.account%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "pages/member/account_edit",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.account_edit%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "pages/pay/browser",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "%pages.pay.browser%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/pay/result",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "%pages.pay.result%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/setting/index",
|
||||
"style": {
|
||||
// #ifdef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.setting.index%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
@ -140,20 +245,16 @@
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.webview.index%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/pay/result",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/pay/browser",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "",
|
||||
"navigationBarBackgroundColor": "#ffffff",
|
||||
"backgroundColor": "#F8F8F8",
|
||||
"backgroundColorTop": "#F8F8F8",
|
||||
"backgroundColorBottom": "#F8F8F8"
|
||||
},
|
||||
"tabBar": {
|
||||
"list": [{
|
||||
"pagePath": "pages/index/index"
|
||||
@ -166,16 +267,12 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "uni-app",
|
||||
"navigationBarBackgroundColor": "#F8F8F8",
|
||||
"backgroundColor": "#F8F8F8"
|
||||
},
|
||||
"uniIdRouter": {},
|
||||
"easycom": {
|
||||
"custom": {
|
||||
"^u-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||
"diy-system-(\W.*)": "@/components/diy/system/$1/index.vue",
|
||||
"diy-extend-(\W.*)": "@/components/diy/extend/$1/index.vue",
|
||||
"diy-(\W.*)": "@/components/diy/$1/index.vue"
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,19 +58,19 @@
|
||||
id: id.value,
|
||||
name: name.value
|
||||
}).then((res : any) => {
|
||||
if (res.code == 200) {
|
||||
let sources = JSON.parse(res.data.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.global.title
|
||||
})
|
||||
if (res.data.value) {
|
||||
let sources = JSON.parse(res.data.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.global.title
|
||||
})
|
||||
}
|
||||
|
||||
let share = res.data.share ? JSON.parse(res.data.share) : null;
|
||||
setShare(share);
|
||||
let share = res.data.share ? JSON.parse(res.data.share) : null;
|
||||
setShare(share);
|
||||
|
||||
loading.value = false;
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -53,17 +53,16 @@
|
||||
getDiyInfo({
|
||||
name: 'DIY_INDEX'
|
||||
}).then((res : any) => {
|
||||
if (res.code == 200) {
|
||||
let sources = JSON.parse(res.data.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
if (res.data.value) {
|
||||
let sources = JSON.parse(res.data.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.global.title
|
||||
})
|
||||
}
|
||||
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.global.title
|
||||
})
|
||||
|
||||
loading.value = false;
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
77
uni-app/pages/member/account.vue
Normal file
77
uni-app/pages/member/account.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<view class="w-screen h-screen bg-page">
|
||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getCashoutAccountListFn">
|
||||
<view class="h-[20rpx]"></view>
|
||||
<view class="p-[30rpx] bg-white mx-[32rpx] my-[20rpx] rounded flex" v-for="(item, index) in accountList" :key="index" @click="handleClick(item)">
|
||||
<view class="w-[100rpx] h-[100rpx] flex items-center justify-center mr-[10rpx]">
|
||||
<image
|
||||
src="data:image/png;base64,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"
|
||||
mode="widthFix" class="w-[80rpx]" v-if="item.account_type == 'bank'"></image>
|
||||
<text class="iconfont iconzhifubaoxuanzhong text-[#188dfb] text-[80rpx]" v-else></text>
|
||||
</view>
|
||||
<view>
|
||||
<view>{{ item.account_type == 'bank' ? item.bank_name : t('alipayAccountNo') }}</view>
|
||||
<view v-if="item.account_type == 'bank'" class="text-sm text-gray-subtitle mt-[10rpx]">{{ t('endNumber') }} {{ item.account_no.substring(item.account_no.length - 4) }}{{ t('bankCard') }}</view>
|
||||
<view v-else class="text-sm text-gray-subtitle mt-[10rpx]">{{ item.account_no }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="p-[30rpx] bg-white mx-[32rpx] my-[20rpx] rounded flex" @click="redirect({ url: '/pages/member/account_edit', param: { type: accountType, mode } })">
|
||||
<u-icon name="plus" color="#333" size="16"></u-icon>
|
||||
<text class="text-sm ml-[10rpx] flex-1">{{ accountType == 'bank' ? t('addBankCard') : t('addAlipayAccount') }}</text>
|
||||
<u-icon name="arrow-right" color="#333" size="14"></u-icon>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { redirect } from '@/utils/common'
|
||||
import { getCashoutAccountList } from '@/api/member'
|
||||
import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue'
|
||||
import useMescroll from '@/components/mescroll/hooks/useMescroll.js'
|
||||
import { onPageScroll, onReachBottom, onLoad } from '@dcloudio/uni-app'
|
||||
import { t } from '@/locale'
|
||||
|
||||
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom)
|
||||
const accountList = ref<Array<any>>([])
|
||||
const loading = ref(false)
|
||||
const accountType = ref('bank')
|
||||
const mescrollRef = ref(null)
|
||||
const mode = ref('get')
|
||||
|
||||
onLoad((data) => {
|
||||
data.type && (accountType.value = data.type)
|
||||
data.mode && (mode.value = data.mode)
|
||||
})
|
||||
|
||||
const getCashoutAccountListFn = (mescroll : mescrollStructure) => {
|
||||
loading.value = false;
|
||||
let data : object = {
|
||||
page: mescroll.num,
|
||||
limit: mescroll.size,
|
||||
account_type: accountType.value
|
||||
};
|
||||
|
||||
getCashoutAccountList(data).then((res) => {
|
||||
const newArr = (res.data.data as Array<Object>);
|
||||
//设置列表数据
|
||||
if (mescroll.num == 1) {
|
||||
accountList.value = []; //如果是第一页需手动制空列表
|
||||
}
|
||||
accountList.value = accountList.value.concat(newArr);
|
||||
mescroll.endSuccess(newArr.length);
|
||||
loading.value = true;
|
||||
}).catch(() => {
|
||||
loading.value = true;
|
||||
mescroll.endErr(); // 请求失败, 结束加载
|
||||
})
|
||||
}
|
||||
|
||||
const handleClick = (data: AnyObject) => {
|
||||
if (mode.value == 'get') redirect({ url: '/pages/member/account_edit', param: { id: data.account_id, type: accountType.value, mode: mode.value } })
|
||||
else redirect({ url: '/pages/member/apply_cash_out', param: { account_id: data.account_id, type: accountType.value } })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
153
uni-app/pages/member/account_edit.vue
Normal file
153
uni-app/pages/member/account_edit.vue
Normal file
@ -0,0 +1,153 @@
|
||||
<template>
|
||||
<scroll-view scroll-y="true" class="w-screen h-screen bg-page">
|
||||
<view class="h-[30rpx]"></view>
|
||||
<view class="p-[30rpx] bg-white mx-[32rpx] rounded">
|
||||
<block v-if="formData.account_type == 'bank'">
|
||||
<view class="text-center text-base font-bold mt-[50rpx]">{{ t('addBankCard') }}</view>
|
||||
<view class="text-center text-sm mt-[10rpx]">{{ t('addBankCardTips') }}</view>
|
||||
|
||||
<view class="mt-[50rpx]">
|
||||
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules"
|
||||
ref="formRef">
|
||||
<view class="mt-[10rpx]">
|
||||
<u-form-item :label="t('bankRealname')" prop="realname" :border-bottom="true">
|
||||
<u-input v-model="formData.realname" border="none" clearable
|
||||
:placeholder="t('bankRealnamePlaceholder')"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="mt-[10rpx]">
|
||||
<u-form-item :label="t('bankName')" prop="bank_name" :border-bottom="true">
|
||||
<u-input v-model="formData.bank_name" border="none" clearable
|
||||
:placeholder="t('bankNamePlaceholder')"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="mt-[10rpx]">
|
||||
<u-form-item :label="t('bankAccountNo')" prop="account_no" :border-bottom="true">
|
||||
<u-input v-model="formData.account_no" border="none" clearable
|
||||
:placeholder="t('bankAccountNoPlaceholder')"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block v-if="formData.account_type == 'alipay'">
|
||||
<view class="text-center text-base font-bold mt-[50rpx]">{{ t('addAlipayAccount') }}</view>
|
||||
<view class="text-center text-sm mt-[10rpx]">{{ t('addAlipayAccountTips') }}</view>
|
||||
|
||||
<view class="mt-[50rpx]">
|
||||
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules"
|
||||
ref="formRef">
|
||||
<view class="mt-[10rpx]">
|
||||
<u-form-item :label="t('alipayRealname')" prop="realname" :border-bottom="true">
|
||||
<u-input v-model="formData.realname" border="none" clearable
|
||||
:placeholder="t('alipayRealnamePlaceholder')"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="mt-[10rpx]">
|
||||
<u-form-item :label="t('alipayAccountNo')" prop="account_no" :border-bottom="true">
|
||||
<u-input v-model="formData.account_no" border="none" clearable
|
||||
:placeholder="t('alipayAccountNoPlaceholder')"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<view class="mt-[100rpx]">
|
||||
<u-button :text="t('save')" type="primary" shape="circle" :loading="loading"
|
||||
@click="handleSave"></u-button>
|
||||
<view class="mt-[30rpx]" v-if="formData.account_id">
|
||||
<u-button :text="t('delete')" type="primary" shape="circle" :plain="true" :loading="loading"
|
||||
@click="deleteConfirm = true"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<u-modal :show="deleteConfirm" :content="t('deleteConfirm')" :confirmText="t('confirm')" :cancelText="t('cancel')"
|
||||
:showCancelButton="true" @confirm="handleDelete" @cancel="deleteConfirm = false"></u-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, reactive } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getCashoutAccountInfo, addCashoutAccount, editCashoutAccount, deleteCashoutAccount } from '@/api/member'
|
||||
import { t } from '@/locale'
|
||||
import { redirect } from '@/utils/common'
|
||||
|
||||
const loading = ref(false)
|
||||
const formRef = ref(null)
|
||||
const mode = ref('get')
|
||||
const deleteConfirm = ref(false)
|
||||
const formData = reactive<AnyObject>({
|
||||
account_id: 0,
|
||||
account_type: 'bank',
|
||||
bank_name: '',
|
||||
realname: '',
|
||||
account_no: ''
|
||||
})
|
||||
|
||||
const rules = computed(() => {
|
||||
return {
|
||||
'realname': {
|
||||
type: 'string',
|
||||
required: true,
|
||||
message: formData.account_type == 'bank' ? t('bankRealnamePlaceholder') : t('alipayRealnamePlaceholder'),
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
'bank_name': {
|
||||
type: 'string',
|
||||
required: formData.account_type == 'bank',
|
||||
message: t('bankNamePlaceholder'),
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
'account_no': {
|
||||
type: 'string',
|
||||
required: true,
|
||||
message: formData.account_type == 'bank' ? t('bankAccountNoPlaceholder') : t('alipayAccountNoPlaceholder'),
|
||||
trigger: ['blur', 'change'],
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onLoad((data) => {
|
||||
data.type && (formData.account_type = data.type)
|
||||
data.mode && (mode.value = data.mode)
|
||||
if (data.id) {
|
||||
formData.account_id = data.id
|
||||
|
||||
getCashoutAccountInfo({ account_id: data.id }).then((res : responseResult) => {
|
||||
if (res.data) {
|
||||
Object.keys(formData).forEach((key : string) => {
|
||||
if (res.data[key] != undefined) formData[key] = res.data[key]
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const handleSave = () => {
|
||||
const save = formData.account_id ? editCashoutAccount : addCashoutAccount
|
||||
|
||||
formRef.value.validate().then(() => {
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
|
||||
save(formData).then((res) => {
|
||||
if (mode.value == 'get') redirect({ url: '/pages/member/account', param: { type: formData.account_type, mode: mode.value } })
|
||||
else redirect({ url: '/pages/member/apply_cash_out', param: { account_id: res.data, type: formData.account_type } })
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const handleDelete = () => {
|
||||
deleteCashoutAccount(formData.account_id).then(() => {
|
||||
redirect({ url: '/pages/member/account', mode: 'redirectTo' })
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
278
uni-app/pages/member/apply_cash_out.vue
Normal file
278
uni-app/pages/member/apply_cash_out.vue
Normal file
@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<scroll-view scroll-y="true" class="w-screen h-screen bg-page" v-if="!pageLoading">
|
||||
<view>
|
||||
<view class="p-[30rpx] bg-white">
|
||||
<view>{{t('cashOutMoneyTip')}}</view>
|
||||
<view class="flex py-[20rpx] items-baseline border-0 border-b-[2rpx] border-solid border-gray-200">
|
||||
<text class="text-[60rpx] ">{{ t('currency') }}</text>
|
||||
<input type="digit" class="h-[70rpx] leading-[70rpx] pl-[10rpx] flex-1 font-bold text-[60rpx]"
|
||||
v-model="applyData.apply_money" />
|
||||
<image @click="clearMoney" v-if="applyData.apply_money"
|
||||
:src="img('static/resource/images/member/apply_cash_out/close.png')" class="w-[40rpx] h-[40rpx]"
|
||||
mode="widthFix" />
|
||||
</view>
|
||||
<view class="pt-[20rpx]">
|
||||
<text
|
||||
class="text-gray-400 text-[28rpx]">{{t('money')}}:{{ t('currency') }}{{ moneyFormat(cashOutMoney) }}</text>
|
||||
<text class="pl-[10rpx] text-[28rpx] text-primary" @click="allMoney">{{t('allTx')}}</text>
|
||||
</view>
|
||||
<view>
|
||||
<text
|
||||
class="text-[24rpx] text-gray-400">{{t('minWithdrawal')}}{{ t('currency') }}{{ moneyFormat(config.min) }}</text>
|
||||
<text class="text-[24rpx] text-gray-400">,{{t('commissionTo')}}{{ config.rate + '%' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="px-[30rpx] bg-white mt-[30rpx]">
|
||||
<!-- 提现到微信 -->
|
||||
<view class="py-[30rpx] flex" v-if="config.transfer_type.includes('wechat') && memberStore.info && (memberStore.info.wx_openid || memberStore.info.weapp_openid)">
|
||||
<view><text class="iconfont iconweixin1 text-[#43c93e] text-[70rpx]"></text></view>
|
||||
<view class="flex-1 px-[20rpx]">
|
||||
<view>{{ t('cashOutToWechat') }}</view>
|
||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">{{ t('cashOutToWechatTips') }}</view>
|
||||
</view>
|
||||
<view class="flex items-center" @click="applyData.transfer_type = 'wechat'">
|
||||
<text class="iconfont iconduigou text-[40rpx] text-primary"
|
||||
v-if="applyData.transfer_type == 'wechat'"></text>
|
||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]"
|
||||
v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提现到支付宝 -->
|
||||
<view class="py-[30rpx] flex" v-if="config.transfer_type.includes('alipay')">
|
||||
<view><text class="iconfont iconzhifubaoxuanzhong text-[#188dfb] text-[70rpx]"></text></view>
|
||||
<view class="flex-1 px-[20rpx]">
|
||||
<view>{{ t('cashOutToAlipay') }}</view>
|
||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">
|
||||
<view v-if="alipayAccountInfo">
|
||||
{{ t('cashOutTo') }}{{ t('alipayAccountNo') }}{{ alipayAccountInfo.account_no }} <text class="text-black" @click="redirect({ url: '/pages/member/account', param: { type: 'alipay', mode: 'select' } })">{{ t('replace') }}</text>
|
||||
</view>
|
||||
<view v-else>
|
||||
{{ t('cashOutToAlipayTips') }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<u-button :plain="true" type="primary" shape="circle" :custom-style="{height: '56rpx'}" v-if="!alipayAccountInfo" @click="redirect({ url: '/pages/member/account', param: { type: 'alipay', mode: 'select' } })">{{ t('toAdd') }}</u-button>
|
||||
<view v-else @click="applyData.transfer_type = 'alipay'">
|
||||
<text class="iconfont iconduigou text-[40rpx] text-primary"
|
||||
v-if="applyData.transfer_type == 'alipay'"></text>
|
||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]"
|
||||
v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提现到银行卡 -->
|
||||
<view class="py-[30rpx] flex" v-if="config.transfer_type.includes('bank')">
|
||||
<view class="w-[70rpx] flex justify-center">
|
||||
<image
|
||||
src="data:image/png;base64,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"
|
||||
mode="widthFix" class="w-[60rpx]"></image>
|
||||
</view>
|
||||
<view class="flex-1 px-[20rpx]">
|
||||
<view>{{ t('cashOutToBank') }}</view>
|
||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">
|
||||
<view v-if="bankAccountInfo">
|
||||
{{ t('cashOutTo') }}{{ bankAccountInfo.bank_name }}{{ t('debitCard') }}{{ bankAccountInfo.account_no.substring(bankAccountInfo.account_no.length - 4) }} <text class="text-black" @click="redirect({ url: '/pages/member/account', param: { type: 'bank', mode: 'select' } })">{{ t('replace') }}</text>
|
||||
</view>
|
||||
<view v-else>
|
||||
{{ t('cashOutToBankTips') }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<u-button :plain="true" type="primary" shape="circle" :custom-style="{height: '56rpx'}" v-if="!bankAccountInfo" @click="redirect({ url: '/pages/member/account', param: { type: 'bank', mode: 'select' } })">{{ t('toAdd') }}</u-button>
|
||||
<view v-else @click="applyData.transfer_type = 'bank'">
|
||||
<text class="iconfont iconduigou text-[40rpx] text-primary"
|
||||
v-if="applyData.transfer_type == 'bank'"></text>
|
||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]"
|
||||
v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="px-[32rpx]">
|
||||
<u-button type="primary" shape="circle" :text="t('cashOut')" class="mt-[60rpx] mb-[40rpx]"
|
||||
:disabled="applyData.apply_money == '' || applyData.apply_money == 0" :loading="loading"
|
||||
@click="cashOut"></u-button>
|
||||
</view>
|
||||
|
||||
<view class="mt-[40rpx] text-center text-sm" @click="redirect({ url: '/pages/member/cash_out'})">
|
||||
{{t('cashOutList')}}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<u-loading-page :loading="pageLoading" bg-color="#e8e8e8" loading-text=""></u-loading-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, computed } from 'vue'
|
||||
import { t } from '@/locale'
|
||||
import { moneyFormat, redirect, img } from '@/utils/common'
|
||||
import useMemberStore from '@/stores/member'
|
||||
import { cashOutConfig, cashOutApply, getFirstCashoutAccountInfo, getCashoutAccountInfo } from '@/api/member'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
const pageLoading = ref(true)
|
||||
const loading = ref(false)
|
||||
const memberStore = useMemberStore()
|
||||
|
||||
// 申请提现数据
|
||||
const applyData = reactive({
|
||||
apply_money: '',
|
||||
transfer_type: '',
|
||||
account_type: 'money',
|
||||
account_id: 0
|
||||
})
|
||||
|
||||
// 可提现金额
|
||||
const cashOutMoney = computed(() => {
|
||||
return memberStore.info ? memberStore.info[ applyData.account_type ] : 0
|
||||
})
|
||||
|
||||
|
||||
watch(() => applyData.transfer_type, (nval) => {
|
||||
switch (nval) {
|
||||
case 'bank':
|
||||
applyData.account_id = bankAccountInfo.value ? bankAccountInfo.value.account_id : 0
|
||||
break;
|
||||
case 'alipay':
|
||||
applyData.account_id = alipayAccountInfo.value ? alipayAccountInfo.value.account_id : 0
|
||||
break;
|
||||
default:
|
||||
applyData.account_id = 0
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
const config = reactive<AnyObject>({
|
||||
is_auto_transfer: 0, // 是否自动转账
|
||||
is_auto_verify: 0, // 是否自动审核
|
||||
is_open: 0, // 是否启用提现
|
||||
min: 0, // 最低提现金额
|
||||
rate: 0, // 手续费比率
|
||||
transfer_type: [] // 提现方式
|
||||
})
|
||||
|
||||
let query:AnyObject | undefined = {}
|
||||
|
||||
onLoad(async (data) => {
|
||||
query = data
|
||||
uni.getStorageSync('cashOutAccountType') && (applyData.account_type = uni.getStorageSync('cashOutAccountType'))
|
||||
|
||||
if (!['money', 'commission'].includes(applyData.account_type)) {
|
||||
uni.showToast({
|
||||
title: t('abnormalOperation'),
|
||||
icon: 'none',
|
||||
success() {
|
||||
setTimeout(() => { uni.navigateBack({ delta: 1}) }, 1500)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 提现配置
|
||||
await cashOutConfig().then((res : any) => {
|
||||
for (let key in res.data) {
|
||||
config[key] = res.data[key];
|
||||
}
|
||||
if (config.transfer_type.includes('wechat') && memberStore.info && (!memberStore.info.wx_openid && !memberStore.info.weapp_openid)) config.transfer_type.splice(0, 1)
|
||||
config.transfer_type.includes('bank') && getBankAccountInfo()
|
||||
config.transfer_type.includes('alipay') && getAlipayAccountInfo()
|
||||
applyData.transfer_type = config.transfer_type[0]
|
||||
pageLoading.value = false
|
||||
})
|
||||
})
|
||||
|
||||
//全部提现
|
||||
const allMoney = () => {
|
||||
applyData.apply_money = moneyFormat(cashOutMoney)
|
||||
}
|
||||
|
||||
// 清空提现金额
|
||||
const clearMoney = () => {
|
||||
applyData.apply_money = '';
|
||||
}
|
||||
|
||||
const verify = () => {
|
||||
if (!applyData.transfer_type) {
|
||||
uni.showToast({ title: t('noAvailableCashOutType'), icon: 'none' })
|
||||
return false
|
||||
}
|
||||
if (uni.$u.test.isEmpty(applyData.apply_money)) {
|
||||
uni.showToast({ title: t('applyMoneyPlaceholder'), icon: 'none' })
|
||||
return false
|
||||
}
|
||||
if (!uni.$u.test.amount(applyData.apply_money)) {
|
||||
uni.showToast({ title: t('moneyformatError'), icon: 'none' })
|
||||
return false
|
||||
}
|
||||
if (parseFloat(applyData.apply_money) > parseFloat(cashOutMoney.value)) {
|
||||
uni.showToast({ title: t('applyMoneyExceed'), icon: 'none' })
|
||||
return false
|
||||
}
|
||||
if (parseFloat(applyData.apply_money) < parseFloat(config.min)) {
|
||||
uni.showToast({ title: t('applyMoneyBelow'), icon: 'none' })
|
||||
return false
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付宝提现账号信息
|
||||
*/
|
||||
const alipayAccountInfo = ref(null)
|
||||
const getAlipayAccountInfo = () => {
|
||||
const data = { account_type: 'alipay', account_id: 0 }
|
||||
let request = getFirstCashoutAccountInfo
|
||||
|
||||
if (query.type && query.type == 'alipay' && query.account_id) {
|
||||
request = getCashoutAccountInfo
|
||||
data.account_id = query.account_id
|
||||
}
|
||||
|
||||
request(data).then(res => {
|
||||
if (res.data && res.data.account_id) alipayAccountInfo.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取银行卡提现账号信息
|
||||
*/
|
||||
const bankAccountInfo = ref(null)
|
||||
const getBankAccountInfo = () => {
|
||||
const data = { account_type: 'bank', account_id: 0 }
|
||||
let request = getFirstCashoutAccountInfo
|
||||
|
||||
if (query.type && query.type == 'bank' && query.account_id) {
|
||||
request = getCashoutAccountInfo
|
||||
data.account_id = query.account_id
|
||||
}
|
||||
request(data).then(res => {
|
||||
if (res.data && res.data.account_id) bankAccountInfo.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请提现
|
||||
*/
|
||||
const cashOut = ()=> {
|
||||
if (verify()) {
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
|
||||
cashOutApply(applyData)
|
||||
.then(res => {
|
||||
redirect({ url: '/pages/member/cash_out' })
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -1,209 +1,147 @@
|
||||
<template>
|
||||
<view class="bg-gray-100 min-h-[100vh]">
|
||||
<view class="bg-gradient-to-r from-red-500 to-red-400 fixed top-0 left-0 right-0 z-10">
|
||||
<view class="px-5 py-6 bg-right-top bg-no-repeat bg-contain"
|
||||
:style="{'backgroundImage': `url(${img('static/resource/images/member/balance_bg.png')})`}">
|
||||
<text class="text-white">{{t('availableBalance')}}</text>
|
||||
<view class="flex align-center justify-between mt-[15rpx]">
|
||||
<text
|
||||
class="text-4xl text-white using-hidden w-95">{{memberStore.info ? moneyFormat(memberStore.info.balance) : 0.00 }}</text>
|
||||
<view class="w-[60px]">
|
||||
<u-button type="primary" :plain="true" :text="t('recharge')" size="small"
|
||||
:customStyle="{backgroundColor: 'transparent',color: '#fff', borderColor: '#fff'}"
|
||||
@click="topUpFn"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getBalanceListFn" top="253rpx">
|
||||
<view
|
||||
class="bg-white flex items-center border-solid border-t-0 border-l-0 border-r-0 border-b-1 border-gray-300 px-2 py-3">
|
||||
<u-icon name="list-dot" color="#666" size="20"></u-icon>
|
||||
<text class="text-sm">{{t('balanceDetail')}}</text>
|
||||
</view>
|
||||
<view v-for="(item,index) in balanceList" :key="item.id"
|
||||
:class="['bg-white relative px-2 py-3',{'border-solid border-t-0 border-l-0 border-r-0 border-b-1 border-gray-200': balanceList.length-1 != index}] ">
|
||||
<view class="text-base">{{item.from_type_name}}</view>
|
||||
<view class="text-xs text-gray-400 mt-1">{{item.create_time}}</view>
|
||||
<view class="text-sm absolute top-[50%] transform -translate-y-[50%] right-2">{{item.account_data}}
|
||||
</view>
|
||||
</view>
|
||||
<mescroll-empty v-if="!balanceList.length && loading"></mescroll-empty>
|
||||
</mescroll-body>
|
||||
<view class="account-info-wrap">
|
||||
<view class="account-info-head" :style="{ background: 'url(' + img('static/resource/images/member/balance_bg.png') + ') no-repeat 95% 30% / auto 250rpx, linear-gradient(314deg, #FE7849 0%, #FF1959 100%)'}">
|
||||
<view class="name">{{t('balanceInfo')}}</view>
|
||||
<view class="content">
|
||||
<view class="money">
|
||||
{{ memberStore.info ? moneyFormat((parseFloat(memberStore.info.balance) + parseFloat(memberStore.info.money)).toString()) : 0.00 }}
|
||||
</view>
|
||||
<view class="text">{{t('accountBalance')}}</view>
|
||||
<view class="money-wrap">
|
||||
<view class="money-item" @click="redirect({ url: '/pages/member/detailed_account', param: { type : 'balance' } })">
|
||||
<view class="money">
|
||||
{{ moneyFormat(memberStore.info?.balance)|| '0.00' }}
|
||||
</view>
|
||||
<view class="text leading-none">{{ t('balance') }}</view>
|
||||
</view>
|
||||
<view class="money-item" @click="redirect({ url: '/pages/member/detailed_account', param: { type : 'money' } })">
|
||||
<view class="money">
|
||||
{{ moneyFormat(memberStore.info?.money)|| '0.00' }}
|
||||
</view>
|
||||
<view class="text leading-none">{{ t('money') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-popup :show="topUpShow" mode="center" :round="10" @close="closePopup" :closeable="true">
|
||||
<view class="w-80 px-3 pb-5 pt-7 box-border">
|
||||
<u--input :placeholder="t('rechargeAmountPlaceholder')" v-model="rechargeAmount" border="bottom"
|
||||
type="number"
|
||||
clearable>
|
||||
</u--input>
|
||||
<view class="top-up-wrap flex flex-wrap justify-around mt-3">
|
||||
<view
|
||||
:class="['top-up-item w-22 box-border border-1 text-center rounded mt-2 py-3 px-4 border-gray-400 border-solid',{'border-primary text-primary':rechargeAmount == 20}]"
|
||||
@click="rechargeAmount = 20">
|
||||
<text>20元</text>
|
||||
</view>
|
||||
<view
|
||||
:class="['top-up-item w-22 box-border border-1 text-center rounded mt-2 py-3 px-4 border-gray-400 border-solid',{'border-primary text-primary':rechargeAmount == 30}]"
|
||||
@click="rechargeAmount = 30">
|
||||
<text>30元</text>
|
||||
</view>
|
||||
<view
|
||||
:class="['top-up-item w-22 box-border border-1 text-center rounded mt-2 py-3 px-4 border-gray-400 border-solid',{'border-primary text-primary':rechargeAmount == 50}]"
|
||||
@click="rechargeAmount = 50">
|
||||
<text>50元</text>
|
||||
</view>
|
||||
<view
|
||||
:class="['top-up-item w-22 box-border border-1 text-center rounded mt-2 py-3 px-4 border-gray-400 border-solid',{'border-primary text-primary':rechargeAmount == 100}]"
|
||||
@click="rechargeAmount = 100">
|
||||
<text>100元</text>
|
||||
</view>
|
||||
<view
|
||||
:class="['top-up-item w-22 box-border border-1 text-center rounded mt-2 py-3 px-4 border-gray-400 border-solid',{'border-primary text-primary':rechargeAmount == 200}]"
|
||||
@click="rechargeAmount = 200">
|
||||
<text>200元</text>
|
||||
</view>
|
||||
<view
|
||||
:class="['top-up-item w-22 box-border border-1 text-center rounded mt-2 py-3 px-4 border-gray-400 border-solid',{'border-primary text-primary':rechargeAmount == 300}]"
|
||||
@click="rechargeAmount = 300">
|
||||
<text>300元</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt-5 px-2">
|
||||
<u-button type="primary" shape="circle" :loading="rechargeLoading" :text="t('clickRecharge')"
|
||||
@click="recharge"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<view class="account-info-btn">
|
||||
<u-button type="primary" shape="circle" class="btn"
|
||||
:customStyle="{backgroundColor: '#FE4E50',color: '#fff', borderColor: '#FE4E50',width: 'calc(100vw - 64rpx)'}"
|
||||
@click="topUpFn">
|
||||
<img class="max-w-[36rpx] max-h-[36rpx] mr-1" :src="img('static/resource/images/member/reset.png')" alt="">
|
||||
<text>{{t('recharge')}}</text>
|
||||
</u-button>
|
||||
<u-button v-if="cashOutConfigObj.is_open == 1" type="primary" :plain="true" shape="circle" class="btn"
|
||||
:customStyle="{backgroundColor: '#fff',color: '#FE4E50', borderColor: '#FE4E50',width: 'calc(100vw - 64rpx)'}"
|
||||
@click="applyCashOut">
|
||||
<img class="max-w-[36rpx] max-h-[36rpx] mr-1" :src="img('static/resource/images/member/withdraw_deposit.png')" alt="">
|
||||
<text>{{t('cashOut')}}</text>
|
||||
</u-button>
|
||||
</view>
|
||||
|
||||
<pay ref="payRef" @close="rechargeLoading = false"></pay>
|
||||
</view>
|
||||
|
||||
<!-- 充值 -->
|
||||
<u-popup :show="topUpShow" mode="center" :round="10" @close="closePopup" :closeable="true">
|
||||
<view class="w-80 px-3 pb-4 pt-7 box-border">
|
||||
<u--input :placeholder="t('rechargeAmountPlaceholder')" v-model="rechargeAmount" border="bottom"
|
||||
type="number" clearable>
|
||||
</u--input>
|
||||
<view class="top-up-wrap flex flex-wrap justify-around mt-3">
|
||||
<view v-for="(item,index) in rechargePackage" :key="index"
|
||||
:class="['top-up-item w-22 box-border border-1 text-center rounded mt-2 py-3 px-4 border-gray-400 border-solid',{'border-primary text-primary':rechargeAmount == item}]"
|
||||
@click="rechargeAmount = item">
|
||||
<text>{{item}}{{t('yuan')}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt-5 px-2">
|
||||
<u-button type="primary" shape="circle" :loading="rechargeLoading" :text="t('clickRecharge')"
|
||||
@click="recharge"></u-button>
|
||||
</view>
|
||||
<view class="mt-[20rpx] text-center text-sm"
|
||||
@click="redirect({ url: '/pages/member/recharge_record' })">{{t('rechargeRecord')}}</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
<pay ref="payRef" @close="rechargeLoading = false"></pay>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { t } from '@/locale'
|
||||
import { moneyFormat, img } from '@/utils/common';
|
||||
import { getBalanceList, createRecharge } from '@/api/member';
|
||||
import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue';
|
||||
import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue';
|
||||
import useMescroll from '@/components/mescroll/hooks/useMescroll.js';
|
||||
import { onPageScroll, onReachBottom, onShow } from '@dcloudio/uni-app';
|
||||
import useMemberStore from '@/stores/member'
|
||||
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom);
|
||||
import { ref, reactive } from 'vue'
|
||||
import { t } from '@/locale'
|
||||
import { moneyFormat, redirect, img } from '@/utils/common';
|
||||
import { createRecharge, cashOutConfig } from '@/api/member';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import useMemberStore from '@/stores/member'
|
||||
|
||||
const memberStore = useMemberStore(),
|
||||
balanceList = ref<Array<any>>([]),
|
||||
mescrollRef = ref(null),
|
||||
loading = ref<boolean>(false),
|
||||
topUpShow = ref<boolean>(false);
|
||||
const memberStore = useMemberStore(),
|
||||
topUpShow = ref<boolean>(false);
|
||||
|
||||
interface mescrollStructure {
|
||||
num : number,
|
||||
size : number,
|
||||
endSuccess : Function,
|
||||
[propName : string] : any
|
||||
}
|
||||
const getBalanceListFn = (mescroll : mescrollStructure) => {
|
||||
loading.value = false;
|
||||
let data : Object = {
|
||||
page: mescroll.num,
|
||||
page_size: mescroll.size,
|
||||
};
|
||||
interface acceptingDataStructure {
|
||||
data : acceptingDataItemStructure,
|
||||
msg : string,
|
||||
code : number
|
||||
}
|
||||
interface acceptingDataItemStructure {
|
||||
data : object,
|
||||
[propName : string] : number | string | object
|
||||
}
|
||||
getBalanceList(data).then((res : acceptingDataStructure) => {
|
||||
let newArr = res.data.data;
|
||||
mescroll.endSuccess(newArr.length);
|
||||
//设置列表数据
|
||||
if (mescroll.num == 1) {
|
||||
balanceList.value = []; //如果是第一页需手动制空列表
|
||||
const topUpFn = () => {
|
||||
topUpShow.value = true;
|
||||
}
|
||||
|
||||
const closePopup = () => {
|
||||
topUpShow.value = false;
|
||||
}
|
||||
|
||||
const rechargePackage = ref([20, 30, 50, 100, 200, 300])
|
||||
|
||||
const rechargeAmount = ref<string | number>("");
|
||||
const rechargeLoading = ref(false)
|
||||
|
||||
const payRef = ref(null)
|
||||
|
||||
const cashOutConfigObj = reactive({
|
||||
is_auto_transfer: 0, // 是否自动转账
|
||||
is_auto_verify: 0, // 是否自动审核
|
||||
is_open: 0, // 是否启用提现
|
||||
min: 0, // 最低提现金额
|
||||
rate: 0, // 手续费比率
|
||||
transfer_type: [] // 提现方式
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
// h5端检测是否是支付后返回 支付组件必须调用
|
||||
// #ifdef H5
|
||||
uni.$emit('checkIsReturnAfterPayment')
|
||||
// #endif
|
||||
|
||||
cashOutConfig().then((res) => {
|
||||
for (let key in res.data) {
|
||||
cashOutConfigObj[key] = res.data[key];
|
||||
}
|
||||
balanceList.value = balanceList.value.concat(newArr);
|
||||
loading.value = true;
|
||||
}).catch(() => {
|
||||
loading.value = true;
|
||||
mescroll.endErr(); // 请求失败, 结束加载
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const topUpFn = () => {
|
||||
topUpShow.value = true;
|
||||
}
|
||||
/**
|
||||
* 发起充值
|
||||
*/
|
||||
const recharge = () => {
|
||||
if (uni.$u.test.isEmpty(rechargeAmount.value)) {
|
||||
uni.showToast({ title: t('rechargeAmountPlaceholder'), icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!uni.$u.test.amount(rechargeAmount.value) || rechargeAmount.value <= 0) {
|
||||
uni.showToast({ title: t('rechargeAmountError'), icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (rechargeLoading.value) return
|
||||
rechargeLoading.value = true
|
||||
|
||||
const closePopup = () => {
|
||||
topUpShow.value = false;
|
||||
}
|
||||
|
||||
const rechargeAmount = ref<string | number>("");
|
||||
const rechargeLoading = ref(false)
|
||||
|
||||
const payRef = ref(null)
|
||||
|
||||
onShow(() => {
|
||||
// h5端检测是否是支付后返回 支付组件必须调用
|
||||
// #ifdef H5
|
||||
uni.$emit('checkIsReturnAfterPayment')
|
||||
// #endif
|
||||
})
|
||||
|
||||
/**
|
||||
* 发起充值
|
||||
*/
|
||||
const recharge = () => {
|
||||
if (uni.$u.test.isEmpty(rechargeAmount.value)) {
|
||||
uni.showToast({ title: t('rechargeAmountPlaceholder'), icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!uni.$u.test.amount(rechargeAmount.value) || rechargeAmount.value <= 0) {
|
||||
uni.showToast({ title: t('rechargeAmountError'), icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (rechargeLoading.value) return
|
||||
rechargeLoading.value = true
|
||||
|
||||
createRecharge({ recharge_money: rechargeAmount.value })
|
||||
.then(res => {
|
||||
payRef.value?.open(res.data.out_trade_no)
|
||||
})
|
||||
.catch(() => {
|
||||
rechargeLoading.value = false
|
||||
})
|
||||
createRecharge({ recharge_money: rechargeAmount.value }).then(res => {
|
||||
payRef.value?.open(res.data.out_trade_no)
|
||||
}).catch(() => {
|
||||
rechargeLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const applyCashOut = ()=> {
|
||||
uni.setStorageSync('cashOutAccountType', 'money')
|
||||
redirect({ url: '/pages/member/apply_cash_out' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@mixin flex {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
/* 单行超出隐藏 */
|
||||
.using-hidden {
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
white-space: break-spaces;
|
||||
}
|
||||
|
||||
.popup-content {
|
||||
@include flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 15px;
|
||||
height: 50px;
|
||||
background-color: #fff;
|
||||
}
|
||||
@import '@/styles/account_info.scss';
|
||||
</style>
|
||||
76
uni-app/pages/member/cash_out.vue
Normal file
76
uni-app/pages/member/cash_out.vue
Normal file
@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<view class="member-record-list">
|
||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getCashOutListFn">
|
||||
<view v-for="(item,index) in cashOutList" :key="item.id" class="member-record-item" @click="toDetailFn(item)">
|
||||
<view class="name">{{item.transfer_type_name}}</view>
|
||||
<view class="desc">{{t('applyTime')}}: {{item.create_time}}</view>
|
||||
<view class="desc">{{ item.status != -1 ? currentStatusDesc(item.status) : item.refuse_reason}}</view>
|
||||
<view class="money" :class="item.apply_money > 0 ? 'text-active' : ''">
|
||||
{{ item.apply_money > 0 ? '+' + item.apply_money : item.apply_money }}
|
||||
</view>
|
||||
<view class="state">
|
||||
{{ item.status_name }}
|
||||
</view>
|
||||
</view>
|
||||
<mescroll-empty v-if="!cashOutList.length && loading" :option="{tip : (account_type == 'commission' ? t('commissemptyTip') : t('emptyTip') )}"></mescroll-empty>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/locale'
|
||||
import { redirect, img } from '@/utils/common';
|
||||
import { getCashOutList } from '@/api/member';
|
||||
import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue';
|
||||
import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue';
|
||||
import useMescroll from '@/components/mescroll/hooks/useMescroll.js';
|
||||
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app';
|
||||
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom);
|
||||
|
||||
let cashOutList = ref<Array<any>>([]);
|
||||
let mescrollRef = ref(null);
|
||||
let loading = ref<boolean>(false);
|
||||
let account_type = uni.getStorageSync('cashOutAccountType')
|
||||
const currentStatusDesc = (status) =>{
|
||||
switch(status){
|
||||
case 1:
|
||||
return t('toBeReviewed')
|
||||
case 2:
|
||||
return t('toBeTransfer')
|
||||
case 3:
|
||||
return t('transfer')
|
||||
case -2:
|
||||
return t('cancelApply')
|
||||
}
|
||||
}
|
||||
|
||||
const getCashOutListFn = (mescroll)=>{
|
||||
let data = ref({});
|
||||
loading.value = false;
|
||||
data.value.page = mescroll.num;
|
||||
data.value.page_size = mescroll.size;
|
||||
data.value.account_type = account_type;
|
||||
getCashOutList(data.value).then((res) => {
|
||||
let newArr = res.data.data;
|
||||
mescroll.endSuccess(newArr.length);
|
||||
//设置列表数据
|
||||
if (mescroll.num == 1){
|
||||
cashOutList.value = []; //如果是第一页需手动制空列表
|
||||
}
|
||||
cashOutList.value = cashOutList.value.concat(newArr);
|
||||
loading.value = true;
|
||||
}).catch(()=>{
|
||||
loading.value = true;
|
||||
mescroll.endErr(); // 请求失败, 结束加载
|
||||
})
|
||||
}
|
||||
|
||||
const toDetailFn = (data)=>{
|
||||
redirect({ url: '/pages/member/cash_out_detail', param: { id: data.id }});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/styles/member_record_list.scss';
|
||||
</style>
|
||||
77
uni-app/pages/member/cash_out_detail.vue
Normal file
77
uni-app/pages/member/cash_out_detail.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<view class="member-record-detail">
|
||||
<view class="money-wrap">
|
||||
<text>-{{ cashOutInfo.apply_money }}</text>
|
||||
<text>{{ cashOutInfo.status_name }}</text>
|
||||
</view>
|
||||
<!-- 状态0待审核1.待转账2已转账 -1拒绝' -->
|
||||
<view class="item">
|
||||
<view class="line-wrap">
|
||||
<text class="label">{{t('cashOutNo')}}</text>
|
||||
<text class="value">{{ cashOutInfo.cash_out_no }}</text>
|
||||
</view>
|
||||
<view class="line-wrap">
|
||||
<text class="label">{{t('serviceMoney')}}</text>
|
||||
<text class="value">¥{{ cashOutInfo.service_money }}</text>
|
||||
</view>
|
||||
<view class="line-wrap">
|
||||
<text class="label">{{t('createTime')}}</text>
|
||||
<text class="value">{{ cashOutInfo.create_time }}</text>
|
||||
</view>
|
||||
<view class="line-wrap" v-if="cashOutInfo.status">
|
||||
<text class="label">{{t('auditTime')}}</text>
|
||||
<text class="value">{{ cashOutInfo.audit_time }}</text>
|
||||
</view>
|
||||
<view class="line-wrap" v-if="cashOutInfo.transfer_bank">
|
||||
<text class="label">{{t('transferBank')}}</text>
|
||||
<text class="value">{{ cashOutInfo.transfer_bank }}</text>
|
||||
</view>
|
||||
<view class="line-wrap">
|
||||
<text class="label">{{t('transferAccount')}}</text>
|
||||
<text class="value">{{ cashOutInfo.transfer_account }}</text>
|
||||
</view>
|
||||
<view class="line-wrap" v-if="cashOutInfo.status == -1 && cashOutInfo.refuse_reason">
|
||||
<text class="label">{{t('refuseReason')}}</text>
|
||||
<text class="value">{{ cashOutInfo.refuse_reason }}</text>
|
||||
</view>
|
||||
<view class="line-wrap" v-if="cashOutInfo.status == 2">
|
||||
<text class="label">{{t('transferTypeName')}}</text>
|
||||
<text class="value">{{ cashOutInfo.transfer_type_name }}</text>
|
||||
</view>
|
||||
<view class="line-wrap" v-if="cashOutInfo.status == 2">
|
||||
<text class="label">{{t('transferTime')}}</text>
|
||||
<text class="value">{{ cashOutInfo.transfer_time }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { t } from '@/locale'
|
||||
import { redirect, img } from '@/utils/common';
|
||||
import { getCashOutDetail } from '@/api/member';
|
||||
|
||||
let cashOutInfo = ref({});
|
||||
let loading = ref<boolean>(false);
|
||||
onLoad((option) => {
|
||||
let id = option.id || "";
|
||||
getCashoutAccountListFn(id)
|
||||
})
|
||||
|
||||
const getCashoutAccountListFn = (id) => {
|
||||
loading.value = false;
|
||||
|
||||
getCashOutDetail(id).then((res) => {
|
||||
cashOutInfo.value = res.data;
|
||||
loading.value = true;
|
||||
}).catch(() => {
|
||||
loading.value = true;
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/styles/member_record_detail.scss';
|
||||
</style>
|
||||
53
uni-app/pages/member/commission.vue
Normal file
53
uni-app/pages/member/commission.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<view class="account-info-wrap">
|
||||
|
||||
<view class="account-info-head"
|
||||
:style="{ background: 'url(' + img('static/resource/images/member/balance_bg.png') + ') no-repeat 95% 30% / auto 250rpx, linear-gradient(314deg, #FE7849 0%, #FF1959 100%)'}">
|
||||
<view class="name">{{t('commissionInfo')}}</view>
|
||||
<view class="content">
|
||||
<view class="money" @click="redirect({ url: '/pages/member/detailed_account', param: { type : 'commission' } })">
|
||||
{{ memberStore.info ? moneyFormat(memberStore.info.commission) : 0.00 }}
|
||||
</view>
|
||||
<view class="text" @click="redirect({ url: '/pages/member/detailed_account', param: { type : 'commission' } })">{{t('accountCommission')}}</view>
|
||||
<view class="money-wrap">
|
||||
<view class="money-item">
|
||||
<view class="money">
|
||||
{{ moneyFormat(memberStore.info?.commission_get)|| '0.00' }}
|
||||
</view>
|
||||
<view class="text">{{ t('commission') }}</view>
|
||||
</view>
|
||||
<view class="money-item">
|
||||
<view class="money">
|
||||
{{ moneyFormat(memberStore.info?.commission_cash_outing)|| '0.00' }}
|
||||
</view>
|
||||
<view class="text">{{ t('money') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="account-info-btn">
|
||||
<u-button type="primary" :plain="true" shape="circle" class="btn"
|
||||
:customStyle="{backgroundColor: '#fff',color: '#FE4E50', borderColor: '#FE4E50',width: 'calc(100vw - 64rpx)'}"
|
||||
@click="applyCashOut">
|
||||
<img class="max-w-[36rpx] max-h-[36rpx] mr-1" :src="img('static/resource/images/member/withdraw_deposit.png')" alt="">
|
||||
<text>{{t('cashOut')}}</text>
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { t } from '@/locale'
|
||||
import { moneyFormat, redirect, img } from '@/utils/common';
|
||||
import useMemberStore from '@/stores/member'
|
||||
const memberStore = useMemberStore();
|
||||
const applyCashOut = ()=> {
|
||||
uni.setStorageSync('cashOutAccountType', 'commission')
|
||||
redirect({ url: '/pages/member/apply_cash_out' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/styles/account_info.scss';
|
||||
</style>
|
||||
83
uni-app/pages/member/detailed_account.vue
Normal file
83
uni-app/pages/member/detailed_account.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<view class="member-record-list">
|
||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getListFn" top="">
|
||||
<view v-for="(item,index) in list" :key="item.id" class="member-record-item">
|
||||
<view class="name">{{item.from_type_name}}</view>
|
||||
<view class="desc" v-if="item.memo">{{item.memo}}</view>
|
||||
<view class="desc">{{item.create_time}}</view>
|
||||
<view class="money" :class="item.account_data > 0 ? 'text-active' : ''">
|
||||
{{ item.account_data > 0 ? '+' + item.account_data : item.account_data }}
|
||||
</view>
|
||||
</view>
|
||||
<mescroll-empty v-if="!list.length && loading" :option="{tip : (type == 'commission' ? t('commissemptyTip') : t('emptyTip') )}"></mescroll-empty>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { t } from '@/locale'
|
||||
import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue';
|
||||
import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue';
|
||||
import useMescroll from '@/components/mescroll/hooks/useMescroll.js';
|
||||
import { getBalanceList, getMoneyList, getCommissionList} from '@/api/member';
|
||||
import { onPageScroll, onReachBottom, onLoad, onShow } from '@dcloudio/uni-app';
|
||||
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom);
|
||||
|
||||
const type = ref('')
|
||||
|
||||
onLoad((options) => {
|
||||
type.value = options.type || 'balance';
|
||||
});
|
||||
|
||||
const list = ref<Array<any>>([]),
|
||||
loading = ref<boolean>(false),
|
||||
mescrollRef = ref(null);
|
||||
|
||||
interface mescrollStructure {
|
||||
num : number,
|
||||
size : number,
|
||||
endSuccess : Function,
|
||||
[propName : string] : any
|
||||
}
|
||||
|
||||
const getListFn = (mescroll : mescrollStructure) => {
|
||||
loading.value = false;
|
||||
let data : Object = {
|
||||
page: mescroll.num,
|
||||
page_size: mescroll.size
|
||||
};
|
||||
interface acceptingDataStructure {
|
||||
data : acceptingDataItemStructure,
|
||||
msg : string,
|
||||
code : number
|
||||
}
|
||||
interface acceptingDataItemStructure {
|
||||
data : object,
|
||||
[propName : string] : number | string | object
|
||||
}
|
||||
|
||||
let fnList = (params : any) => { };
|
||||
if (type.value == 'balance') fnList = getBalanceList;
|
||||
else if (type.value == 'money') fnList = getMoneyList;
|
||||
else if (type.value == 'commission') fnList = getCommissionList;
|
||||
|
||||
fnList(data).then((res : acceptingDataStructure) => {
|
||||
let newArr = res.data.data;
|
||||
mescroll.endSuccess(newArr.length);
|
||||
//设置列表数据
|
||||
if (mescroll.num == 1) {
|
||||
list.value = []; //如果是第一页需手动制空列表
|
||||
}
|
||||
list.value = list.value.concat(newArr);
|
||||
loading.value = true;
|
||||
}).catch(() => {
|
||||
loading.value = true;
|
||||
mescroll.endErr(); // 请求失败, 结束加载
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/styles/member_record_list.scss';
|
||||
</style>
|
||||
@ -48,15 +48,15 @@
|
||||
getDiyInfo({
|
||||
name: 'DIY_MEMBER_INDEX'
|
||||
}).then((res : any) => {
|
||||
if (res.code == 200) {
|
||||
let sources = JSON.parse(res.data.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.global.title
|
||||
})
|
||||
loading.value = false;
|
||||
}
|
||||
if (res.data.value) {
|
||||
let sources = JSON.parse(res.data.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.global.title
|
||||
})
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
useMemberStore().getMemberInfo()
|
||||
|
||||
@ -67,7 +67,7 @@
|
||||
import { t } from '@/locale'
|
||||
import useMemberStore from '@/stores/member'
|
||||
import { img, mobileConceal } from '@/utils/common'
|
||||
import { updateMember } from '@/api/member'
|
||||
import { modifyMember } from '@/api/member'
|
||||
import { fetchBase64Image, uploadImage } from '@/api/system'
|
||||
|
||||
const memberStore = useMemberStore()
|
||||
@ -86,7 +86,7 @@
|
||||
const updateNicknameConfirm = () => {
|
||||
if (uni.$u.test.isEmpty(updateNickname.value)) { uni.showToast({ title: t('nicknamePlaceholder'), icon: 'none' }); return }
|
||||
|
||||
updateMember({
|
||||
modifyMember({
|
||||
field: 'nickname',
|
||||
value: updateNickname.value
|
||||
}).then(res => {
|
||||
@ -106,7 +106,7 @@
|
||||
]
|
||||
})
|
||||
const updateSex = (e) => {
|
||||
updateMember({
|
||||
modifyMember({
|
||||
field: 'sex',
|
||||
value: e.value
|
||||
}).then(res => {
|
||||
@ -123,7 +123,7 @@
|
||||
encoding: 'base64', //编码格式
|
||||
success: res => {
|
||||
fetchBase64Image({ content: res.data }).then(uploadRes => {
|
||||
updateMember({
|
||||
modifyMember({
|
||||
field: 'headimg',
|
||||
value: uploadRes.data.url
|
||||
}).then(res => {
|
||||
@ -139,7 +139,7 @@
|
||||
filePath: event.file.url,
|
||||
name: 'file'
|
||||
}).then(res => {
|
||||
updateMember({
|
||||
modifyMember({
|
||||
field: 'headimg',
|
||||
value: res.data.url
|
||||
}).then(() => {
|
||||
@ -154,7 +154,7 @@
|
||||
*/
|
||||
const birthdayPicker = ref(false)
|
||||
const updateBirthday = (e) => {
|
||||
updateMember({
|
||||
modifyMember({
|
||||
field: 'birthday',
|
||||
value: uni.$u.date(e.value, 'yyyy-mm-dd')
|
||||
}).then(() => {
|
||||
|
||||
80
uni-app/pages/member/recharge_record.vue
Normal file
80
uni-app/pages/member/recharge_record.vue
Normal file
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<view class="member-record-list">
|
||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getListFn" top="">
|
||||
<view v-for="(item,index) in list" :key="item.id" class="member-record-item" @click="toDetailFn(item)">
|
||||
<view class="name">{{item.from_type_name}}</view>
|
||||
<view class="desc" v-if="item.memo">{{item.memo}}</view>
|
||||
<view class="desc">{{item.create_time}}</view>
|
||||
<view class="money" :class="item.account_data > 0 ? 'text-active' : ''">
|
||||
{{ item.account_data > 0 ? '+' + item.account_data : item.account_data }}
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<mescroll-empty v-if="!list.length && loading" :option="{tip : t('emptyTip') }"></mescroll-empty>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { t } from '@/locale'
|
||||
import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue';
|
||||
import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue';
|
||||
import useMescroll from '@/components/mescroll/hooks/useMescroll.js';
|
||||
import { getRechargeList} from '@/api/member';
|
||||
import { onPageScroll, onReachBottom, onLoad } from '@dcloudio/uni-app';
|
||||
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom);
|
||||
|
||||
|
||||
const list = ref<Array<any>>([]),
|
||||
loading = ref<boolean>(false),
|
||||
mescrollRef = ref(null);
|
||||
|
||||
interface mescrollStructure {
|
||||
num : number,
|
||||
size : number,
|
||||
endSuccess : Function,
|
||||
[propName : string] : any
|
||||
}
|
||||
|
||||
const getListFn = (mescroll : mescrollStructure) => {
|
||||
loading.value = false;
|
||||
let data : Object = {
|
||||
page: mescroll.num,
|
||||
page_size: mescroll.size
|
||||
};
|
||||
interface acceptingDataStructure {
|
||||
data : acceptingDataItemStructure,
|
||||
msg : string,
|
||||
code : number
|
||||
}
|
||||
interface acceptingDataItemStructure {
|
||||
data : object,
|
||||
[propName : string] : number | string | object
|
||||
}
|
||||
|
||||
getRechargeList(data).then((res : acceptingDataStructure) => {
|
||||
let newArr = res.data.data;
|
||||
mescroll.endSuccess(newArr.length);
|
||||
//设置列表数据
|
||||
if (mescroll.num == 1) {
|
||||
list.value = []; //如果是第一页需手动制空列表
|
||||
}
|
||||
list.value = list.value.concat(newArr);
|
||||
loading.value = true;
|
||||
}).catch(() => {
|
||||
loading.value = true;
|
||||
mescroll.endErr(); // 请求失败, 结束加载
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const toDetailFn = (data)=>{
|
||||
redirect({ url: '/pages/member/recharge_record_detail', param: { id: data.order_id }});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/styles/member_record_list.scss';
|
||||
</style>
|
||||
77
uni-app/pages/member/recharge_record_detail.vue
Normal file
77
uni-app/pages/member/recharge_record_detail.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<view class="member-record-detail">
|
||||
<view class="money-wrap">
|
||||
<text>-{{ cashOutInfo.apply_money }}</text>
|
||||
<text>{{ cashOutInfo.status_name }}</text>
|
||||
</view>
|
||||
<!-- 状态0待审核1.待转账2已转账 -1拒绝' -->
|
||||
<view class="item">
|
||||
<view class="line-wrap">
|
||||
<text class="label">{{t('cashOutNo')}}</text>
|
||||
<text class="value">{{ cashOutInfo.cash_out_no }}</text>
|
||||
</view>
|
||||
<view class="line-wrap">
|
||||
<text class="label">{{t('serviceMoney')}}</text>
|
||||
<text class="value">¥{{ cashOutInfo.service_money }}</text>
|
||||
</view>
|
||||
<view class="line-wrap">
|
||||
<text class="label">{{t('createTime')}}</text>
|
||||
<text class="value">{{ cashOutInfo.create_time }}</text>
|
||||
</view>
|
||||
<view class="line-wrap" v-if="cashOutInfo.status">
|
||||
<text class="label">{{t('auditTime')}}</text>
|
||||
<text class="value">{{ cashOutInfo.audit_time }}</text>
|
||||
</view>
|
||||
<view class="line-wrap" v-if="cashOutInfo.transfer_bank">
|
||||
<text class="label">{{t('transferBank')}}</text>
|
||||
<text class="value">{{ cashOutInfo.transfer_bank }}</text>
|
||||
</view>
|
||||
<view class="line-wrap">
|
||||
<text class="label">{{t('transferAccount')}}</text>
|
||||
<text class="value">{{ cashOutInfo.transfer_account }}</text>
|
||||
</view>
|
||||
<view class="line-wrap" v-if="cashOutInfo.status == -1 && cashOutInfo.refuse_reason">
|
||||
<text class="label">{{t('refuseReason')}}</text>
|
||||
<text class="value">{{ cashOutInfo.refuse_reason }}</text>
|
||||
</view>
|
||||
<view class="line-wrap" v-if="cashOutInfo.status == 2">
|
||||
<text class="label">{{t('transferTypeName')}}</text>
|
||||
<text class="value">{{ cashOutInfo.transfer_type_name }}</text>
|
||||
</view>
|
||||
<view class="line-wrap" v-if="cashOutInfo.status == 2">
|
||||
<text class="label">{{t('transferTime')}}</text>
|
||||
<text class="value">{{ cashOutInfo.transfer_time }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { t } from '@/locale'
|
||||
import { redirect, img } from '@/utils/common';
|
||||
import { getRechargeDetail } from '@/api/member';
|
||||
|
||||
let cashOutInfo = ref({});
|
||||
let loading = ref<boolean>(false);
|
||||
onLoad((option) => {
|
||||
let id = option.id || "";
|
||||
getCashoutAccountListFn(id)
|
||||
})
|
||||
|
||||
const getCashoutAccountListFn = (id) => {
|
||||
loading.value = false;
|
||||
|
||||
getRechargeDetail(id).then((res) => {
|
||||
cashOutInfo.value = res.data;
|
||||
loading.value = true;
|
||||
}).catch(() => {
|
||||
loading.value = true;
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/styles/member_record_detail.scss';
|
||||
</style>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.9 KiB |
@ -1,5 +1,5 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { getToken, setToken, removeToken, redirect } from '@/utils/common'
|
||||
import { setToken, removeToken, redirect } from '@/utils/common'
|
||||
import { getMemberInfo } from '@/api/member'
|
||||
import { logout } from '@/api/auth'
|
||||
|
||||
@ -11,7 +11,7 @@ interface Member {
|
||||
const useMemberStore = defineStore('member', {
|
||||
state: () : Member => {
|
||||
return {
|
||||
token: getToken(),
|
||||
token: uni.getStorageSync(import.meta.env.VITE_REQUEST_STORAGE_TOKEN_KEY),
|
||||
info: null
|
||||
}
|
||||
},
|
||||
@ -26,12 +26,12 @@ const useMemberStore = defineStore('member', {
|
||||
.then((res : any) => {
|
||||
this.info = res.data
|
||||
})
|
||||
.catch(() => {
|
||||
this.logout()
|
||||
.catch(async () => {
|
||||
await this.logout()
|
||||
})
|
||||
},
|
||||
logout(isRedirect : boolean = false) {
|
||||
logout().then(() => {
|
||||
async logout(isRedirect : boolean = false) {
|
||||
await logout().then(() => {
|
||||
this.$reset()
|
||||
removeToken()
|
||||
isRedirect && redirect({ url: '/pages/index/index' })
|
||||
|
||||
41
uni-app/styles/account_info.scss
Normal file
41
uni-app/styles/account_info.scss
Normal file
@ -0,0 +1,41 @@
|
||||
.account-info-wrap{
|
||||
@apply bg-[#F5F6FA] min-h-[100vh];
|
||||
.account-info-head{
|
||||
@apply relative h-40;
|
||||
.name{
|
||||
@apply ml-4 pt-7 text-white text-lg mb-3;
|
||||
}
|
||||
.content{
|
||||
@apply absolute bg-white left-3 right-3 rounded-lg p-5;
|
||||
.money{
|
||||
@apply text-xl font-bold;
|
||||
}
|
||||
.text{
|
||||
@apply text-xs text-slate-500 mt-2;
|
||||
}
|
||||
.money-wrap{
|
||||
@apply mt-5 flex;
|
||||
.money-item{
|
||||
@apply flex-1;
|
||||
}
|
||||
.money{
|
||||
@apply text-lg;
|
||||
}
|
||||
.text{
|
||||
@apply mt-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.account-info-btn{
|
||||
@apply flex mt-24 ml-3 mr-3;
|
||||
.btn{
|
||||
&:first-of-type{
|
||||
@apply mr-1 rounded;
|
||||
}
|
||||
&:last-of-type{
|
||||
@apply ml-1 rounded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,51 +1,98 @@
|
||||
@font-face {
|
||||
font-family: "iconfont";
|
||||
/* Project id 3952239 */
|
||||
src: url('//at.alicdn.com/t/c/font_3952239_vfd4vlalsk.woff2?t=1680088109665') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_3952239_vfd4vlalsk.woff?t=1680088109665') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_3952239_vfd4vlalsk.ttf?t=1680088109665') format('truetype');
|
||||
font-family: "iconfont"; /* Project id 3952239 */
|
||||
src: url('//at.alicdn.com/t/c/font_3952239_ukixio2ve7k.woff2?t=1684147503182') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_3952239_ukixio2ve7k.woff?t=1684147503182') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_3952239_ukixio2ve7k.ttf?t=1684147503182') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.iconcheckbox_nol:before {
|
||||
content: "\e626";
|
||||
}
|
||||
|
||||
.iconweixin1:before {
|
||||
content: "\e878";
|
||||
}
|
||||
|
||||
.iconyinlian:before {
|
||||
content: "\e68b";
|
||||
}
|
||||
|
||||
.iconzhifubaoxuanzhong:before {
|
||||
content: "\e802";
|
||||
}
|
||||
|
||||
.iconshuaxin:before {
|
||||
content: "\e631";
|
||||
}
|
||||
|
||||
.iconkefu:before {
|
||||
content: "\e612";
|
||||
}
|
||||
|
||||
.iconfenxiang:before {
|
||||
content: "\e610";
|
||||
}
|
||||
|
||||
.icondianzan:before {
|
||||
content: "\ec7f";
|
||||
}
|
||||
|
||||
.iconhuiyuanjiage:before {
|
||||
content: "\e611";
|
||||
}
|
||||
|
||||
.iconxiazai:before {
|
||||
content: "\e69c";
|
||||
}
|
||||
|
||||
.icondunpai:before {
|
||||
content: "\e80b";
|
||||
}
|
||||
|
||||
.icona-shejianchangguan:before {
|
||||
content: "\e647";
|
||||
}
|
||||
|
||||
.iconduigou:before {
|
||||
content: "\e632";
|
||||
content: "\e632";
|
||||
}
|
||||
|
||||
.iconzhifushibai:before {
|
||||
content: "\e663";
|
||||
content: "\e663";
|
||||
}
|
||||
|
||||
.iconweixinzhifu2:before {
|
||||
content: "\e62b";
|
||||
content: "\e62b";
|
||||
}
|
||||
|
||||
.iconalipay:before {
|
||||
content: "\e618";
|
||||
content: "\e618";
|
||||
}
|
||||
|
||||
.iconbalance:before {
|
||||
content: "\e73b";
|
||||
content: "\e73b";
|
||||
}
|
||||
|
||||
.iconwode-xian:before {
|
||||
content: "\e60f";
|
||||
content: "\e60f";
|
||||
}
|
||||
|
||||
.iconwodezixun:before {
|
||||
content: "\e645";
|
||||
content: "\e645";
|
||||
}
|
||||
|
||||
.iconshouye-zhihui:before {
|
||||
content: "\e61d";
|
||||
content: "\e61d";
|
||||
}
|
||||
|
||||
.iconshezhi:before {
|
||||
content: "\e600";
|
||||
}
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
25
uni-app/styles/member_record_detail.scss
Normal file
25
uni-app/styles/member_record_detail.scss
Normal file
@ -0,0 +1,25 @@
|
||||
page{
|
||||
background-color: #f5f6fa;
|
||||
@apply pt-4;
|
||||
}
|
||||
.member-record-detail{
|
||||
@apply m-4 mt-0 bg-white rounded-md px-4 py-6;
|
||||
.money-wrap{
|
||||
@apply flex items-center flex-col mb-6;
|
||||
text:first-of-type{
|
||||
@apply text-3xl font-bold mt-1;
|
||||
}
|
||||
text:last-of-type{
|
||||
@apply text-sm mt-3;
|
||||
}
|
||||
}
|
||||
.line-wrap{
|
||||
@apply flex justify-between text-sm mt-3;
|
||||
.label{
|
||||
@apply text-[#878787];
|
||||
}
|
||||
.value{
|
||||
@apply text-[#222];
|
||||
}
|
||||
}
|
||||
}
|
||||
21
uni-app/styles/member_record_list.scss
Normal file
21
uni-app/styles/member_record_list.scss
Normal file
@ -0,0 +1,21 @@
|
||||
.member-record-list{
|
||||
@apply min-h-[100vh];
|
||||
.member-record-item{
|
||||
@apply relative mx-4 border-solid border-t-0 border-l-0 border-r-0 border-b-1 border-[#ECEBEC] py-3;
|
||||
.name{
|
||||
@apply text-sm;
|
||||
}
|
||||
.desc{
|
||||
@apply text-xs text-[#8D8C8D] mt-1;
|
||||
}
|
||||
.text-active{
|
||||
color: #FF0D3E;
|
||||
}
|
||||
.money{
|
||||
@apply absolute right-3 top-4 text-base font-bold;
|
||||
}
|
||||
.state{
|
||||
@apply absolute right-3 top-11 text-[#8D8C8D] text-xs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import { getTabbarPages } from './pages'
|
||||
import useDiyStore from '@/stores/diy'
|
||||
import useMemberStore from '@/stores/member'
|
||||
|
||||
/**
|
||||
* 跳转页面
|
||||
@ -105,17 +106,14 @@ export const currShareRoute = () => {
|
||||
// #endif
|
||||
|
||||
// 拼接参数
|
||||
let params = [];
|
||||
let params = {};
|
||||
for (let key in currentParam) {
|
||||
params.push(key + '=' + currentParam[key])
|
||||
params[key] = currentParam[key]
|
||||
}
|
||||
let currentPath = '/' + currentRoute;
|
||||
let currentQuery = params.join('&');
|
||||
if (currentQuery) currentPath += '?' + currentQuery;
|
||||
|
||||
return {
|
||||
path: currentPath,
|
||||
query: currentQuery,
|
||||
params: params
|
||||
}
|
||||
}
|
||||
@ -125,7 +123,7 @@ export const currShareRoute = () => {
|
||||
* @returns
|
||||
*/
|
||||
export function getToken() : null | string {
|
||||
return uni.getStorageSync(import.meta.env.VITE_REQUEST_STORAGE_TOKEN_KEY)
|
||||
return useMemberStore().token
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { language } from '@/locale'
|
||||
import { checkNeedLogin } from '@/utils/auth'
|
||||
import { urlDeconstruction } from '@/utils/common'
|
||||
import { urlDeconstruction, getToken } from '@/utils/common'
|
||||
import { memberLog } from '@/api/auth'
|
||||
|
||||
/**
|
||||
* 页面跳转拦截器
|
||||
@ -12,10 +13,15 @@ export const redirectInterceptor = () => {
|
||||
uni.addInterceptor(name, {
|
||||
invoke(args) {
|
||||
const route = urlDeconstruction(args.url)
|
||||
|
||||
// 加载语言包
|
||||
language.loadLocaleMessages(route.path, uni.getLocale())
|
||||
|
||||
// 校验是否需要登录
|
||||
checkNeedLogin(route)
|
||||
|
||||
// 添加会员访问日志
|
||||
if (getToken()) memberLog({ route: route.path, params: JSON.stringify(route.query), pre_route: getCurrentPages()[0].route })
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -25,9 +31,11 @@ export const redirectInterceptor = () => {
|
||||
* 应用初始化拦截器
|
||||
*/
|
||||
export const launchInterceptor = () => {
|
||||
// 加载语言包
|
||||
const launch = uni.getLaunchOptionsSync()
|
||||
launch.path = `/${launch.path}`
|
||||
language.loadLocaleMessages(launch.path, uni.getLocale())
|
||||
|
||||
// 校验是否需要登录
|
||||
checkNeedLogin(launch)
|
||||
|
||||
@ -38,6 +46,10 @@ export const launchInterceptor = () => {
|
||||
|
||||
// #ifdef H5
|
||||
const match = location.href.match(/\/s(\d*)\//);
|
||||
if (match) uni.setStorageSync('site_id', match[1])
|
||||
if (match) uni.setStorageSync('wap_site_id', match[1])
|
||||
else uni.removeStorageSync('wap_site_id')
|
||||
// #endif
|
||||
|
||||
// 添加会员访问日志
|
||||
if (getToken()) memberLog({ route: launch.path, params: JSON.stringify(launch.query || {}), pre_route: '' })
|
||||
}
|
||||
@ -27,7 +27,7 @@ class Request {
|
||||
this.config.header[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = import.meta.env.VITE_SITE_ID
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
this.config.header[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = uni.getStorageSync('site_id') || import.meta.env.VITE_SITE_ID
|
||||
this.config.header[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = uni.getStorageSync('wap_site_id') || import.meta.env.VITE_SITE_ID
|
||||
// #endif
|
||||
|
||||
this.config.header[import.meta.env.VITE_REQUEST_HEADER_CHANNEL_KEY] = getAppChannel()
|
||||
@ -66,18 +66,18 @@ class Request {
|
||||
*/
|
||||
public upload(url : string, data : AnyObject = {}, config : RequestConfig = {}) {
|
||||
this.requestInterceptors()
|
||||
|
||||
Object.assign(this.config, {
|
||||
|
||||
const params = Object.assign(uni.$u.deepClone(this.config), {
|
||||
url: this.baseUrl + url,
|
||||
...data
|
||||
})
|
||||
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
...this.config,
|
||||
...params,
|
||||
success: res => {
|
||||
const data = JSON.parse(res.data)
|
||||
if (data.code == 200) {
|
||||
if (data.code == 1) {
|
||||
this.config.showSuccessMessage && uni.showToast({ title: data.msg, icon: 'none' })
|
||||
resolve(data)
|
||||
} else {
|
||||
@ -99,7 +99,7 @@ class Request {
|
||||
private request(method : string, url : string, data ?: AnyObject) {
|
||||
this.requestInterceptors()
|
||||
|
||||
Object.assign(this.config, {
|
||||
const params = Object.assign(uni.$u.deepClone(this.config), {
|
||||
url: this.baseUrl + url,
|
||||
method,
|
||||
data
|
||||
@ -107,10 +107,10 @@ class Request {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
...this.config,
|
||||
...params,
|
||||
success: res => {
|
||||
const data = res.data
|
||||
if (data.code == 200) {
|
||||
if (data.code == 1) {
|
||||
this.config.showSuccessMessage && uni.showToast({ title: data.msg, icon: 'none' })
|
||||
resolve(data)
|
||||
} else {
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
import wx from 'weixin-js-sdk'
|
||||
import { getWechatSkdConfig } from '@/api/system'
|
||||
import { isWeixinBrowser } from '@/utils/common'
|
||||
|
||||
class Wechat {
|
||||
constructor() {
|
||||
this.init()
|
||||
// #ifdef H5
|
||||
// isWeixinBrowser() && this.init()
|
||||
// #endif
|
||||
}
|
||||
|
||||
private init() {
|
||||
public init() {
|
||||
getWechatSkdConfig({
|
||||
url: uni.getSystemInfoSync().platform == 'ios' ? uni.getStorageSync('initUrl') : location.href
|
||||
}).then((res : responseResult) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user