feat(登录)
This commit is contained in:
parent
c611e44858
commit
c65eb5ddcd
2
.env
2
.env
|
@ -5,7 +5,7 @@ MALL_VERSION = v1.0.0
|
|||
MALL_BASE_URL = http://api-dashboard.yudao.iocoder.cn
|
||||
|
||||
# 后端接口 - 测试环境(通过 process.env.NODE_ENV = development)
|
||||
MALL_DEV_BASE_URL = http://mall-backend-dev.jiandyb.cn:7001
|
||||
MALL_DEV_BASE_URL = https://mall-baclend-local.jiandyb9834.xyz
|
||||
|
||||
# 后端接口前缀(一般不建议调整)
|
||||
MALL_API_PATH = /merchant-api
|
||||
|
|
2
App.vue
2
App.vue
|
@ -3,8 +3,6 @@ import { onLaunch, onShow, onError } from '@dcloudio/uni-app'
|
|||
import { peachInit } from './peach'
|
||||
|
||||
onLaunch(() => {
|
||||
// 隐藏原生导航栏 使用自定义底部导航
|
||||
uni.hideTabBar()
|
||||
peachInit()
|
||||
})
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
},
|
||||
"pages": [
|
||||
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/index/redirect"
|
||||
},
|
||||
{
|
||||
"path": "pages/order/list",
|
||||
"style": {
|
||||
|
@ -67,7 +70,6 @@
|
|||
{
|
||||
"root": "pages/public",
|
||||
"pages": [
|
||||
|
||||
{
|
||||
"path": "error",
|
||||
"style": {
|
||||
|
|
|
@ -3,31 +3,35 @@
|
|||
<view :style="[{ paddingTop: peach.$platform.navBar + 'px' }]"></view>
|
||||
<view class="dashboard-module ss-p-x-30">
|
||||
<view class="merchant-info flex align-center">
|
||||
<image class="logo" :src="state.merchantInfo.logo" mode="aspectFill"></image>
|
||||
<image class="logo" :src="merchantInfo.logo" mode="aspectFill"></image>
|
||||
|
||||
<view class="detail flex flex-column justify-center gap-10">
|
||||
<view class="name ss-font-26">{{ state.merchantInfo.name }}</view>
|
||||
<view class="description ss-font-26">{{ state.merchantInfo.description }}</view>
|
||||
<view class="name ss-font-26">{{ merchantInfo.name }}</view>
|
||||
<view class="description ss-font-26">{{ merchantInfo?.contactPhone }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="statistic ss-m-t-24">
|
||||
<view class="title ss-font-24 ss-m-b-20">
|
||||
{{ `今日收款金额(成功收款${state.statistic.total}笔)` }}
|
||||
{{ `今日收款金额(成功收款${state.statistic.todayPaymentCount}笔)` }}
|
||||
</view>
|
||||
<view class="income flex justify-between align-center">
|
||||
<view class="left flex align-center">
|
||||
<view class="unit self-start">¥</view>
|
||||
<view class="sincome ss-font-60">{{ state.statistic.income }}</view>
|
||||
<view class="sincome ss-font-60">{{ state.statistic.todayPaymentAmount || 0 }}</view>
|
||||
</view>
|
||||
<button class="right-btn ss-reset-button">查看详情</button>
|
||||
</view>
|
||||
<view class="des ss-m-t-20">
|
||||
总销售额{{ state.statistic.totalSalesAmount }}元 | 成功退款{{ state.statistic.refundCount }}笔 |
|
||||
退款金额{{ state.statistic.refundAmount }}元
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="more ss-m-t-70">
|
||||
<view class="title ss-m-b-30">基础数据</view>
|
||||
<view class="items">
|
||||
<view class="item" v-for="item in state.more">
|
||||
<view class="item" v-for="item in state.more" :key="item.name">
|
||||
<view class="label">{{ item.name }}</view>
|
||||
<view class="value">{{ item.value }}</view>
|
||||
<view class="last"> 昨日 {{ item.last }} </view>
|
||||
|
@ -39,8 +43,11 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import peach from '@/peach'
|
||||
import $store from '@/peach/store'
|
||||
import UserUtil from '@/peach/api/member/user'
|
||||
import bg from '@/static/bg-page.png'
|
||||
|
||||
const bgStyle = {
|
||||
|
@ -51,43 +58,62 @@ const bgStyle = {
|
|||
}
|
||||
|
||||
const state = ref({
|
||||
merchantInfo: {
|
||||
name: '测试商家',
|
||||
logo: '/static/logo.png',
|
||||
description: '测试商家描述',
|
||||
},
|
||||
statistic: {
|
||||
total: 100,
|
||||
income: 2222222222,
|
||||
todayPaymentCount: 0,
|
||||
todayPaymentAmount: 0,
|
||||
totalSalesAmount: 0,
|
||||
refundCount: 0,
|
||||
refundAmount: 0,
|
||||
},
|
||||
more: [
|
||||
{
|
||||
name: '支付金额',
|
||||
value: 10000000,
|
||||
last: 100000000,
|
||||
},
|
||||
{
|
||||
name: '访客数',
|
||||
value: 100000,
|
||||
last: 100000,
|
||||
name: '销售金额',
|
||||
key: 'Amount',
|
||||
value: 0,
|
||||
last: 0,
|
||||
},
|
||||
{
|
||||
name: '订单数',
|
||||
value: 100000,
|
||||
last: 10000,
|
||||
key: 'orderCount',
|
||||
value: 0,
|
||||
last: 0,
|
||||
},
|
||||
{
|
||||
name: '客单价',
|
||||
value: 10000,
|
||||
last: 100,
|
||||
name: '待核销',
|
||||
key: 'verificationOrderCount',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
name: '支付买家数',
|
||||
value: 100,
|
||||
last: 100,
|
||||
name: '待配送',
|
||||
key: 'deliveryOrderCount',
|
||||
value: 0,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const userStore = $store('user')
|
||||
|
||||
const merchantInfo = computed(() => {
|
||||
return userStore.userInfo?.particulars
|
||||
})
|
||||
|
||||
async function getStatistic() {
|
||||
let res = await UserUtil.getHomeStatistics()
|
||||
for (let key of Object.keys(state.value.statistic)) {
|
||||
state.value.statistic[key] = res.data[key]
|
||||
}
|
||||
|
||||
state.value.more[0].value = res.data.todayPaymentAmount ?? 0
|
||||
state.value.more[0].last = res.data.yesterdaySalesAmount ?? 0
|
||||
state.value.more[1].value = res.data.orderCount
|
||||
state.value.more[1].last = res.data.yesterdayOrderCount
|
||||
state.value.more[2].value = res.data.verificationOrderCount
|
||||
state.value.more[3].value = res.data.deliveryOrderCount
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
getStatistic()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -136,6 +162,11 @@ const state = ref({
|
|||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.des {
|
||||
color: var(--ui-TC-2);
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.more {
|
||||
|
|
|
@ -6,15 +6,32 @@
|
|||
</view>
|
||||
<uni-forms ref="smsLoginRef" v-model="state.model" :rules="state.rules" validateTrigger="bind">
|
||||
<uni-forms-item name="mobile">
|
||||
<uni-easyinput :styles="state.inputStyle" trim="all" placeholder="请输入手机号" v-model="state.model.mobile"
|
||||
:inputBorder="false" type="number" />
|
||||
<uni-easyinput
|
||||
:styles="state.inputStyle"
|
||||
trim="all"
|
||||
placeholder="请输入手机号"
|
||||
v-model="state.model.mobile"
|
||||
:inputBorder="false"
|
||||
type="number"
|
||||
/>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item name="code">
|
||||
<uni-easyinput :styles="state.inputStyle" trim="all" placeholder="验证码" v-model="state.model.code"
|
||||
:inputBorder="false" type="number" maxlength="4">
|
||||
<uni-easyinput
|
||||
:styles="state.inputStyle"
|
||||
trim="all"
|
||||
placeholder="验证码"
|
||||
v-model="state.model.code"
|
||||
:inputBorder="false"
|
||||
type="number"
|
||||
maxlength="4"
|
||||
>
|
||||
<template #right>
|
||||
<button :disabled="state.isMobileEnd" :class="{ 'code-btn-end': state.isMobileEnd }"
|
||||
class="ss-reset-button code-btn code-btn-start" @tap="getSmsCode('smsLogin', state.model.mobile)">
|
||||
<button
|
||||
:disabled="state.isMobileEnd"
|
||||
:class="{ 'code-btn-end': state.isMobileEnd }"
|
||||
class="ss-reset-button code-btn code-btn-start"
|
||||
@tap="getSmsCode('smsLogin', state.model.mobile)"
|
||||
>
|
||||
{{ getSmsTimer('smsLogin') }}
|
||||
</button>
|
||||
</template>
|
||||
|
@ -24,8 +41,12 @@
|
|||
<button class="ss-reset-button login-btn-start" @tap="smsLoginSubmit">登录</button>
|
||||
<view class="agreement-box ss-flex ss-row-center" :class="{ shake: state.isShaking }">
|
||||
<label class="radio ss-flex" @tap="onChange">
|
||||
<radio :checked="state.agreeStatus" color="var(--ui-BG-Main)" style="transform: scale(0.8)"
|
||||
@tap.stop="onChange" />
|
||||
<radio
|
||||
:checked="state.agreeStatus"
|
||||
color="var(--ui-BG-Main)"
|
||||
style="transform: scale(0.8)"
|
||||
@tap.stop="onChange"
|
||||
/>
|
||||
<view class="agreement-text ss-flex ss-m-l-8">
|
||||
我已阅读并遵守
|
||||
<view class="tcp-text" @tap.stop="onProtocol('商家入驻协议')"> 《商家入驻协议》 </view>
|
||||
|
@ -38,10 +59,10 @@
|
|||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { code, mobile } from '@/peach/validate/form';
|
||||
import AuthUtil from '@/peach/api/member/auth';
|
||||
import { code, mobile } from '@/peach/validate/form'
|
||||
import AuthUtil from '@/peach/api/member/auth'
|
||||
import peach from '@/peach'
|
||||
import { showAuthModal, closeAuthModal, getSmsCode, getSmsTimer } from '@/peach/hooks/useModal';
|
||||
import { showAuthModal, closeAuthModal, getSmsCode, getSmsTimer } from '@/peach/hooks/useModal'
|
||||
|
||||
const title = ref('欢迎登录')
|
||||
const smsLoginRef = ref(null)
|
||||
|
@ -56,21 +77,19 @@ const state = ref({
|
|||
},
|
||||
rules: {
|
||||
mobile,
|
||||
code
|
||||
code,
|
||||
},
|
||||
inputStyle: {
|
||||
backgroundColor: '#ECECEC'
|
||||
}
|
||||
backgroundColor: '#ECECEC',
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
function onChange() {
|
||||
state.value.agreeStatus = !state.value.agreeStatus
|
||||
}
|
||||
|
||||
|
||||
async function smsLoginSubmit() {
|
||||
const validate = await smsLoginRef.value.validate().catch(err => {
|
||||
const validate = await smsLoginRef.value.validate().catch((err) => {
|
||||
console.log('err', err)
|
||||
})
|
||||
if (!validate) return
|
||||
|
@ -84,18 +103,12 @@ async function smsLoginSubmit() {
|
|||
}
|
||||
|
||||
const { code } = await AuthUtil.smsLogin(state.value.model)
|
||||
if (code === 0) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.login-module {
|
||||
|
||||
.uni-easyinput {
|
||||
|
||||
::v-deep .uni-easyinput__content {
|
||||
border-radius: 41rpx;
|
||||
padding: 0 10rpx;
|
||||
|
@ -104,7 +117,7 @@ async function smsLoginSubmit() {
|
|||
.is-focused {
|
||||
::v-deep .content-clear-icon {
|
||||
.uniui-clear {
|
||||
color: red !important
|
||||
color: red !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
<view :style="[{ paddingTop: peach.$platform.navBar + 'px' }]"></view>
|
||||
<view class="my-module ss-p-x-30">
|
||||
<view class="user-info flex align-center">
|
||||
<image class="avatar" :src="state.userInfo.avatar" mode="aspectFill"></image>
|
||||
<image class="avatar" :src="userInfo.avatar || '/static/default_avatar.png'" mode="aspectFill"></image>
|
||||
|
||||
<view class="detail flex flex-column justify-center gap-10">
|
||||
<view class="name ss-font-26">{{ state.userInfo.name }}</view>
|
||||
<view class="description ss-font-26">{{ state.userInfo.description }}</view>
|
||||
<view class="name ss-font-26">{{ userInfo.nickname }}</view>
|
||||
<view class="description ss-font-26">{{ userInfo.mobile }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
@ -16,17 +16,17 @@
|
|||
<view class="remain flex justify-between align-center">
|
||||
<view class="left flex align-center">
|
||||
<view class="unit self-start">¥</view>
|
||||
<view class="sremain ss-font-60">{{ state.statistic.remain }}</view>
|
||||
<view class="sremain ss-font-60">{{ remain }}</view>
|
||||
</view>
|
||||
<button class="right-btn ss-reset-button">查看详情</button>
|
||||
</view>
|
||||
<view class="cent ss-m-t-20"> 总获取积分{{ state.statistic.cent }} </view>
|
||||
<view class="cent ss-m-t-20"> 总获取积分{{ cent }} </view>
|
||||
</view>
|
||||
|
||||
<view class="menu ss-m-t-70">
|
||||
<view class="title ss-m-b-30">我的服务</view>
|
||||
<view class="items">
|
||||
<view class="item" v-for="item in state.menus">
|
||||
<view class="item" v-for="item in state.menus" :key="item.name">
|
||||
<image class="icon" :src="item.icon" mode="aspectFill"></image>
|
||||
<view class="label">{{ item.name }}</view>
|
||||
</view>
|
||||
|
@ -40,26 +40,17 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { ref, computed } from 'vue'
|
||||
import $store from '@/peach/store'
|
||||
import peach from '@/peach'
|
||||
|
||||
const bgStyle = {
|
||||
backgroundImage: '/static/bg-page.png',
|
||||
imageType: 'local',
|
||||
backgroundColor: '#fff',
|
||||
description: '',
|
||||
}
|
||||
|
||||
const state = ref({
|
||||
userInfo: {
|
||||
name: 'Ankkaya',
|
||||
avatar: '/static/logo.png',
|
||||
description: '测试商家描述',
|
||||
},
|
||||
statistic: {
|
||||
remain: 2222222222,
|
||||
cent: 10000,
|
||||
},
|
||||
menus: [
|
||||
{
|
||||
name: '余额提现',
|
||||
|
@ -83,6 +74,17 @@ const state = ref({
|
|||
},
|
||||
],
|
||||
})
|
||||
|
||||
const userStore = $store('user')
|
||||
console.log(userStore)
|
||||
|
||||
const remain = computed(() => {
|
||||
return userStore.userWallet?.balance
|
||||
})
|
||||
|
||||
const userInfo = computed(() => {
|
||||
return userStore.userInfo
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<template>
|
||||
<view></view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import $store from '@/peach/store'
|
||||
import peach from '@/peach'
|
||||
|
||||
const userStore = $store('user')
|
||||
|
||||
async function redirectFn() {
|
||||
// 判断是否登录
|
||||
if (!userStore.isLogin) {
|
||||
userStore.logOut()
|
||||
peach.$router.redirect('/pages/index/login')
|
||||
} else {
|
||||
await userStore.loginAfter()
|
||||
|
||||
if (userStore.lastRoutePage) {
|
||||
peach.$router.redirect(userStore.lastRoutePage)
|
||||
} else {
|
||||
peach.$router.redirect('/pages/index/index')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
redirectFn()
|
||||
})
|
||||
</script>
|
|
@ -1,39 +1,40 @@
|
|||
import request from "@/peach/request";
|
||||
import request from '@/peach/request'
|
||||
|
||||
const AuthUtil = {
|
||||
smsLogin: (data) => {
|
||||
return request({
|
||||
url: "/particulars/member/auth/sms-login",
|
||||
method: "POST",
|
||||
url: '/particulars/member/auth/sms-login',
|
||||
method: 'POST',
|
||||
data,
|
||||
custom: {
|
||||
showSuccess: true,
|
||||
loadingMsg: "登陆中",
|
||||
successMsg: "登陆成功",
|
||||
loadingMsg: '登陆中',
|
||||
successMsg: '登陆成功',
|
||||
auth: false,
|
||||
},
|
||||
});
|
||||
})
|
||||
},
|
||||
// 发送手机验证码
|
||||
sendSmsCode: (mobile, scene) => {
|
||||
return request({
|
||||
url: "/member/auth/send-sms-code",
|
||||
method: "POST",
|
||||
url: '/member/auth/send-sms-code',
|
||||
method: 'POST',
|
||||
data: {
|
||||
mobile,
|
||||
scene,
|
||||
},
|
||||
custom: {
|
||||
loadingMsg: "发送中",
|
||||
loadingMsg: '发送中',
|
||||
showSuccess: true,
|
||||
successMsg: "发送成功",
|
||||
successMsg: '发送成功',
|
||||
},
|
||||
});
|
||||
})
|
||||
},
|
||||
// 刷新令牌
|
||||
refreshToken: (refreshToken) => {
|
||||
return request({
|
||||
url: "/member/auth/refresh-token",
|
||||
method: "POST",
|
||||
url: '/member/auth/refresh-token',
|
||||
method: 'POST',
|
||||
params: {
|
||||
refreshToken,
|
||||
},
|
||||
|
@ -41,8 +42,8 @@ const AuthUtil = {
|
|||
loading: false, // 不用加载中
|
||||
showError: false, // 不展示错误提示
|
||||
},
|
||||
});
|
||||
})
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default AuthUtil;
|
||||
export default AuthUtil
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import request from '@/peach/request'
|
||||
|
||||
const UserUtil = {
|
||||
// 获取用户信息
|
||||
getUserInfo: () => {
|
||||
return request({
|
||||
url: '/particulars/member/get',
|
||||
method: 'GET',
|
||||
})
|
||||
},
|
||||
|
||||
// 获取钱包
|
||||
getWalletInfo: () => {
|
||||
return request({
|
||||
url: '/pay/wallet/get',
|
||||
method: 'GET',
|
||||
})
|
||||
},
|
||||
|
||||
// 首页统计
|
||||
getHomeStatistics: () => {
|
||||
return request({
|
||||
url: '/statistics/index/get-count',
|
||||
method: 'GET',
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
export default UserUtil
|
|
@ -3,34 +3,34 @@
|
|||
* @description api 模块管理,loading 配置,请求拦截,错误处理
|
||||
*/
|
||||
|
||||
import Request from "luch-request";
|
||||
import { baseUrl, apiPath } from "@/peach/config";
|
||||
import peach from "@/peach";
|
||||
import $store from "@/peach/store";
|
||||
import AuthUtil from "@/peach/api/member/auth";
|
||||
import Request from 'luch-request'
|
||||
import { baseUrl, apiPath } from '@/peach/config'
|
||||
import peach from '@/peach'
|
||||
import $store from '@/peach/store'
|
||||
import AuthUtil from '@/peach/api/member/auth'
|
||||
|
||||
const options = {
|
||||
// 显示操作成功消息 默认不显示
|
||||
showSuccess: false,
|
||||
// 成功提醒 默认使用后端返回值
|
||||
successMsg: "",
|
||||
successMsg: '',
|
||||
// 显示失败消息 默认显示
|
||||
showError: true,
|
||||
// 失败提醒 默认使用后端返回信息
|
||||
errorMsg: "",
|
||||
errorMsg: '',
|
||||
// 显示请求时loading模态框 默认显示
|
||||
showLoading: true,
|
||||
// loading提醒文字
|
||||
loadingMsg: "加载中",
|
||||
loadingMsg: '加载中',
|
||||
// 需要授权才能请求 默认放开
|
||||
auth: false,
|
||||
};
|
||||
auth: true,
|
||||
}
|
||||
|
||||
// Loading全局实例
|
||||
let LoadingInstance = {
|
||||
target: null,
|
||||
count: 0,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Ankkaya
|
||||
|
@ -39,21 +39,21 @@ let LoadingInstance = {
|
|||
* @returns {Type}
|
||||
*/
|
||||
function closeLoading() {
|
||||
if (LoadingInstance.count > 0) LoadingInstance.count--;
|
||||
if (LoadingInstance.count === 0) uni.hideLoading();
|
||||
if (LoadingInstance.count > 0) LoadingInstance.count--
|
||||
if (LoadingInstance.count === 0) uni.hideLoading()
|
||||
}
|
||||
|
||||
// 请求实例
|
||||
const http = new Request({
|
||||
baseURL: baseUrl + apiPath,
|
||||
timeout: 8000,
|
||||
method: "GET",
|
||||
method: 'GET',
|
||||
header: {
|
||||
Accept: "text/json",
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
Accept: 'text/json',
|
||||
'Content-Type': 'application/json;charset=UTF-8',
|
||||
},
|
||||
custom: options,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
* @author Ankkaya
|
||||
|
@ -65,37 +65,38 @@ const http = new Request({
|
|||
http.interceptors.request.use(
|
||||
(config) => {
|
||||
// 自定义处理【auth 授权】:必须登录的接口,否则提示登录
|
||||
if (config.custom.auth && !$store("user").isLogin) {
|
||||
if (config.custom.auth && !$store('user').isLogin) {
|
||||
// 处理登录
|
||||
peach.$router.go("/pages/index/login");
|
||||
return Promise.reject();
|
||||
peach.$router.go('/pages/index/login')
|
||||
return Promise.reject()
|
||||
}
|
||||
|
||||
// 自定义处理【loading 加载中】:如果需要显示 loading,则显示 loading
|
||||
if (config.custom.showLoading) {
|
||||
LoadingInstance.count++;
|
||||
LoadingInstance.count++
|
||||
LoadingInstance.count === 1 &&
|
||||
uni.showLoading({
|
||||
title: config.custom.loadingMsg,
|
||||
mask: true,
|
||||
fail: () => {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
},
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 增加 token 令牌、terminal 终端、tenant 租户的请求头
|
||||
const token = getAccessToken();
|
||||
const token = getAccessToken()
|
||||
if (token) {
|
||||
config.header["Authorization"] = token;
|
||||
config.header['Authorization'] = token
|
||||
}
|
||||
config.header["Accept"] = "*/*";
|
||||
return config;
|
||||
config.header['Accept'] = '*/*'
|
||||
config.header['tenant-id'] = '1'
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
return Promise.reject(error)
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
/**
|
||||
* @author Ankkaya
|
||||
|
@ -105,105 +106,97 @@ http.interceptors.request.use(
|
|||
*/
|
||||
http.interceptors.response.use(
|
||||
(response) => {
|
||||
console.log("response", response);
|
||||
console.log('response', response)
|
||||
// 约定:如果是 /auth/ 下的 URL 地址,并且返回了 accessToken 说明是登录相关的接口,则自动设置登陆令牌
|
||||
if (
|
||||
response.config.url.indexOf("/member/auth/") >= 0 &&
|
||||
response.data?.data?.accessToken
|
||||
) {
|
||||
$store("user").setToken(
|
||||
response.data.data.accessToken,
|
||||
response.data.data.refreshToken
|
||||
);
|
||||
if (response.config.url.indexOf('/member/auth/') >= 0 && response.data?.data?.accessToken) {
|
||||
$store('user').setToken(response.data.data.accessToken, response.data.data.refreshToken)
|
||||
}
|
||||
|
||||
// 自定处理【loading 加载中】:如果需要显示 loading,则关闭 loading
|
||||
response.config.custom.showLoading && closeLoading();
|
||||
response.config.custom.showLoading && closeLoading()
|
||||
|
||||
// 自定义处理【error 错误提示】:如果需要显示错误提示,则显示错误提示
|
||||
if (response.data.code !== 0) {
|
||||
// 特殊:如果 401 错误码,则跳转到登录页 or 刷新令牌
|
||||
if (response.data.code === 401) {
|
||||
return refreshToken(response.config);
|
||||
return refreshToken(response.config)
|
||||
}
|
||||
|
||||
// 错误提示
|
||||
if (response.config.custom.showError) {
|
||||
uni.showToast({
|
||||
title: response.data.msg || "服务器开小差啦,请稍后再试~",
|
||||
icon: "none",
|
||||
title: response.data.msg || '服务器开小差啦,请稍后再试~',
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
});
|
||||
return Promise.reject(false);
|
||||
})
|
||||
return Promise.reject(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义处理【showSuccess 成功提示】:如果需要显示成功提示,则显示成功提示
|
||||
if (
|
||||
response.config.custom.showSuccess &&
|
||||
response.config.custom.successMsg !== "" &&
|
||||
response.config.custom.successMsg !== '' &&
|
||||
response.data.code === 0
|
||||
) {
|
||||
uni.showToast({
|
||||
title: response.config.custom.successMsg,
|
||||
icon: "none",
|
||||
});
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
|
||||
// 返回结果:包括 code + data + msg
|
||||
return Promise.resolve(response.data);
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
(error) => {
|
||||
console.log("error", error);
|
||||
const userStore = $store("user");
|
||||
const isLogin = userStore.isLogin;
|
||||
let errorMessage = "网络请求出错";
|
||||
console.log('error', error)
|
||||
const userStore = $store('user')
|
||||
const isLogin = userStore.isLogin
|
||||
let errorMessage = '网络请求出错'
|
||||
if (error !== undefined) {
|
||||
switch (error.statusCode) {
|
||||
case 400:
|
||||
errorMessage = "请求错误";
|
||||
break;
|
||||
errorMessage = '请求错误'
|
||||
break
|
||||
case 401:
|
||||
errorMessage = isLogin ? "您的登陆已过期" : "请先登录";
|
||||
errorMessage = isLogin ? '您的登陆已过期' : '请先登录'
|
||||
// 正常情况下,后端不会返回 401 错误,所以这里不处理 handleAuthorized
|
||||
break;
|
||||
break
|
||||
case 403:
|
||||
errorMessage = "拒绝访问";
|
||||
break;
|
||||
errorMessage = '拒绝访问'
|
||||
break
|
||||
case 404:
|
||||
errorMessage = "请求出错";
|
||||
break;
|
||||
errorMessage = '请求出错'
|
||||
break
|
||||
case 408:
|
||||
errorMessage = "请求超时";
|
||||
break;
|
||||
errorMessage = '请求超时'
|
||||
break
|
||||
case 429:
|
||||
errorMessage = "请求频繁, 请稍后再访问";
|
||||
break;
|
||||
errorMessage = '请求频繁, 请稍后再访问'
|
||||
break
|
||||
case 500:
|
||||
errorMessage = "服务器开小差啦,请稍后再试~";
|
||||
break;
|
||||
errorMessage = '服务器开小差啦,请稍后再试~'
|
||||
break
|
||||
case 501:
|
||||
errorMessage = "服务未实现";
|
||||
break;
|
||||
errorMessage = '服务未实现'
|
||||
break
|
||||
case 502:
|
||||
errorMessage = "网络错误";
|
||||
break;
|
||||
errorMessage = '网络错误'
|
||||
break
|
||||
case 503:
|
||||
errorMessage = "服务不可用";
|
||||
break;
|
||||
errorMessage = '服务不可用'
|
||||
break
|
||||
case 504:
|
||||
errorMessage = "网络超时";
|
||||
break;
|
||||
errorMessage = '网络超时'
|
||||
break
|
||||
case 505:
|
||||
errorMessage = "HTTP 版本不受支持";
|
||||
break;
|
||||
errorMessage = 'HTTP 版本不受支持'
|
||||
break
|
||||
}
|
||||
if (error.errMsg.includes("timeout")) errorMessage = "请求超时";
|
||||
if (error.errMsg.includes('timeout')) errorMessage = '请求超时'
|
||||
// #ifdef H5
|
||||
if (error.errMsg.includes("Network"))
|
||||
errorMessage = window.navigator.onLine
|
||||
? "服务器异常"
|
||||
: "请检查您的网络连接";
|
||||
if (error.errMsg.includes('Network'))
|
||||
errorMessage = window.navigator.onLine ? '服务器异常' : '请检查您的网络连接'
|
||||
// #endif
|
||||
}
|
||||
|
||||
|
@ -211,95 +204,95 @@ http.interceptors.response.use(
|
|||
if (error.config.custom.showError === true) {
|
||||
uni.showToast({
|
||||
title: error.data?.msg || errorMessage,
|
||||
icon: "none",
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
});
|
||||
})
|
||||
}
|
||||
error.config.custom.showLoading && closeLoading();
|
||||
error.config.custom.showLoading && closeLoading()
|
||||
}
|
||||
|
||||
return Promise.reject(false);
|
||||
return Promise.reject(false)
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
let requestList = []; // 请求队列
|
||||
let isRefreshToken = false; // 是否正在刷新中
|
||||
let requestList = [] // 请求队列
|
||||
let isRefreshToken = false // 是否正在刷新中
|
||||
const refreshToken = async (config) => {
|
||||
// 如果当前已经是 refresh-token 的 URL 地址,并且还是 401 错误,说明是刷新令牌失败了,直接返回 Promise.reject(error)
|
||||
if (config.url.indexOf("/member/auth/refresh-token") >= 0) {
|
||||
return Promise.reject("error");
|
||||
if (config.url.indexOf('/member/auth/refresh-token') >= 0) {
|
||||
return Promise.reject('error')
|
||||
}
|
||||
|
||||
// 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
|
||||
if (!isRefreshToken) {
|
||||
isRefreshToken = true;
|
||||
isRefreshToken = true
|
||||
// 1. 如果获取不到刷新令牌,则只能执行登出操作
|
||||
const refreshToken = getRefreshToken();
|
||||
const refreshToken = getRefreshToken()
|
||||
if (!refreshToken) {
|
||||
return handleAuthorized();
|
||||
return handleAuthorized()
|
||||
}
|
||||
// 2. 进行刷新访问令牌
|
||||
try {
|
||||
const refreshTokenResult = await AuthUtil.refreshToken(refreshToken);
|
||||
const refreshTokenResult = await AuthUtil.refreshToken(refreshToken)
|
||||
if (refreshTokenResult.code !== 0) {
|
||||
// 如果刷新不成功,直接抛出 e 触发 2.2 的逻辑
|
||||
// noinspection ExceptionCaughtLocallyJS
|
||||
throw new Error("刷新令牌失败");
|
||||
throw new Error('刷新令牌失败')
|
||||
}
|
||||
// 2.1 刷新成功,则回放队列的请求 + 当前请求
|
||||
config.header.Authorization = "Bearer " + getAccessToken();
|
||||
config.header.Authorization = 'Bearer ' + getAccessToken()
|
||||
requestList.forEach((cb) => {
|
||||
cb();
|
||||
});
|
||||
requestList = [];
|
||||
return request(config);
|
||||
cb()
|
||||
})
|
||||
requestList = []
|
||||
return request(config)
|
||||
} catch (e) {
|
||||
// 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。
|
||||
// 2.2 刷新失败,只回放队列的请求
|
||||
requestList.forEach((cb) => {
|
||||
cb();
|
||||
});
|
||||
cb()
|
||||
})
|
||||
// 提示是否要登出。即不回放当前请求!不然会形成递归
|
||||
return handleAuthorized();
|
||||
return handleAuthorized()
|
||||
} finally {
|
||||
requestList = [];
|
||||
isRefreshToken = false;
|
||||
requestList = []
|
||||
isRefreshToken = false
|
||||
}
|
||||
} else {
|
||||
// 添加到队列,等待刷新获取到新的令牌
|
||||
return new Promise((resolve) => {
|
||||
requestList.push(() => {
|
||||
config.header.Authorization = "Bearer " + getAccessToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
resolve(request(config));
|
||||
});
|
||||
});
|
||||
config.header.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
resolve(request(config))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** 处理 401 未登陆的错误 */
|
||||
const handleAuthorized = () => {
|
||||
const userStore = $store("user");
|
||||
userStore.logout(true);
|
||||
peach.$router.go("/pages/index/login");
|
||||
const userStore = $store('user')
|
||||
userStore.logOut()
|
||||
peach.$router.go('/pages/index/login')
|
||||
// 登录超时
|
||||
return Promise.reject({
|
||||
code: 401,
|
||||
msg: userStore.isLogin ? "您的登陆已过期" : "请先登录",
|
||||
});
|
||||
};
|
||||
msg: userStore.isLogin ? '您的登陆已过期' : '请先登录',
|
||||
})
|
||||
}
|
||||
|
||||
/** 获得访问令牌 */
|
||||
const getAccessToken = () => {
|
||||
return uni.getStorageSync("token");
|
||||
};
|
||||
return uni.getStorageSync('token')
|
||||
}
|
||||
|
||||
/** 获得刷新令牌 */
|
||||
const getRefreshToken = () => {
|
||||
return uni.getStorageSync("refresh-token");
|
||||
};
|
||||
return uni.getStorageSync('refresh-token')
|
||||
}
|
||||
|
||||
const request = (config) => {
|
||||
return http.middleware(config);
|
||||
};
|
||||
return http.middleware(config)
|
||||
}
|
||||
|
||||
export default request;
|
||||
export default request
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
import $store from "@/peach/store";
|
||||
import { showShareModal } from "@/peach/hooks/useModal";
|
||||
import {
|
||||
isNumber,
|
||||
isString,
|
||||
isEmpty,
|
||||
startsWith,
|
||||
isObject,
|
||||
isNil,
|
||||
clone,
|
||||
} from "lodash";
|
||||
import throttle from "@/peach/helper/throttle";
|
||||
import $store from '@/peach/store'
|
||||
import { showShareModal } from '@/peach/hooks/useModal'
|
||||
import { isNumber, isString, isEmpty, startsWith, isObject, isNil, clone } from 'lodash'
|
||||
import throttle from '@/peach/helper/throttle'
|
||||
|
||||
const _go = (
|
||||
path,
|
||||
|
@ -18,173 +10,173 @@ const _go = (
|
|||
redirect: false,
|
||||
}
|
||||
) => {
|
||||
let page = ""; // 跳转页面
|
||||
let query = ""; // 页面参数
|
||||
let url = ""; // 跳转页面完整路径
|
||||
let page = '' // 跳转页面
|
||||
let query = '' // 页面参数
|
||||
let url = '' // 跳转页面完整路径
|
||||
|
||||
if (isString(path)) {
|
||||
// 判断跳转类型是 path | 还是http
|
||||
if (startsWith(path, "http")) {
|
||||
if (startsWith(path, 'http')) {
|
||||
// #ifdef H5
|
||||
window.location = path;
|
||||
return;
|
||||
window.location = path
|
||||
return
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
page = `/pages/public/webview`;
|
||||
query = `url=${encodeURIComponent(path)}`;
|
||||
page = `/pages/public/webview`
|
||||
query = `url=${encodeURIComponent(path)}`
|
||||
// #endif
|
||||
} else if (startsWith(path, "action:")) {
|
||||
handleAction(path);
|
||||
return;
|
||||
} else if (startsWith(path, 'action:')) {
|
||||
handleAction(path)
|
||||
return
|
||||
} else {
|
||||
[page, query] = path.split("?");
|
||||
;[page, query] = path.split('?')
|
||||
}
|
||||
if (!isEmpty(params)) {
|
||||
let query2 = paramsToQuery(params);
|
||||
let query2 = paramsToQuery(params)
|
||||
if (isEmpty(query)) {
|
||||
query = query2;
|
||||
query = query2
|
||||
} else {
|
||||
query += "&" + query2;
|
||||
query += '&' + query2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isObject(path)) {
|
||||
page = path.url;
|
||||
page = path.url
|
||||
if (!isNil(path.params)) {
|
||||
query = paramsToQuery(path.params);
|
||||
query = paramsToQuery(path.params)
|
||||
}
|
||||
}
|
||||
|
||||
const nextRoute = ROUTES_MAP[page];
|
||||
const nextRoute = ROUTES_MAP[page]
|
||||
|
||||
// 未找到指定跳转页面
|
||||
// mark: 跳转404页
|
||||
if (!nextRoute) {
|
||||
console.log(
|
||||
`%c跳转路径参数错误<${page || "EMPTY"}>`,
|
||||
"color:red;background:yellow"
|
||||
);
|
||||
return;
|
||||
console.log(`%c跳转路径参数错误<${page || 'EMPTY'}>`, 'color:red;background:yellow')
|
||||
return
|
||||
}
|
||||
|
||||
// 页面登录拦截
|
||||
if (nextRoute.meta?.auth && !$store("user").isLogin) {
|
||||
if (nextRoute.meta?.auth && !$store('user').isLogin) {
|
||||
uni.redirectTo({
|
||||
url: "/pages/index/login",
|
||||
});
|
||||
return;
|
||||
url: '/pages/index/login',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
url = page;
|
||||
url = page
|
||||
if (!isEmpty(query)) {
|
||||
url += `?${query}`;
|
||||
url += `?${query}`
|
||||
}
|
||||
|
||||
// 保存最新的页面地址
|
||||
$store('user').lastRoutePage = url
|
||||
|
||||
// 跳转底部导航
|
||||
if (TABBAR.includes(page)) {
|
||||
uni.switchTab({
|
||||
url,
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 使用redirect跳转
|
||||
if (options.redirect) {
|
||||
uni.redirectTo({
|
||||
url,
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
// 限流 防止重复点击跳转
|
||||
function go(...args) {
|
||||
throttle(() => {
|
||||
_go(...args);
|
||||
});
|
||||
_go(...args)
|
||||
})
|
||||
}
|
||||
|
||||
function paramsToQuery(params) {
|
||||
if (isEmpty(params)) {
|
||||
return "";
|
||||
return ''
|
||||
}
|
||||
// return new URLSearchParams(Object.entries(params)).toString();
|
||||
let query = [];
|
||||
let query = []
|
||||
for (let key in params) {
|
||||
query.push(key + "=" + params[key]);
|
||||
query.push(key + '=' + params[key])
|
||||
}
|
||||
|
||||
return query.join("&");
|
||||
return query.join('&')
|
||||
}
|
||||
|
||||
function back() {
|
||||
// #ifdef H5
|
||||
history.back();
|
||||
history.back()
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
uni.navigateBack();
|
||||
uni.navigateBack()
|
||||
// #endif
|
||||
}
|
||||
|
||||
function redirect(path, params = {}) {
|
||||
go(path, params, {
|
||||
redirect: true,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 检测是否有浏览器历史
|
||||
function hasHistory() {
|
||||
// #ifndef H5
|
||||
const pages = getCurrentPages();
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length > 1) {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
return !!history.back;
|
||||
return !!history.back
|
||||
// #endif
|
||||
}
|
||||
|
||||
function getCurrentRoute(field = "") {
|
||||
let currentPage = getCurrentPage();
|
||||
function getCurrentRoute(field = '') {
|
||||
let currentPage = getCurrentPage()
|
||||
// #ifdef MP
|
||||
currentPage.$page["route"] = currentPage.route;
|
||||
currentPage.$page["options"] = currentPage.options;
|
||||
currentPage.$page['route'] = currentPage.route
|
||||
currentPage.$page['options'] = currentPage.options
|
||||
// #endif
|
||||
if (field !== "") {
|
||||
return currentPage.$page[field];
|
||||
if (field !== '') {
|
||||
return currentPage.$page[field]
|
||||
} else {
|
||||
return currentPage.$page;
|
||||
return currentPage.$page
|
||||
}
|
||||
}
|
||||
|
||||
function getCurrentPage() {
|
||||
let pages = getCurrentPages();
|
||||
return pages[pages.length - 1];
|
||||
let pages = getCurrentPages()
|
||||
return pages[pages.length - 1]
|
||||
}
|
||||
|
||||
function handleAction(path) {
|
||||
const action = path.split(":");
|
||||
const action = path.split(':')
|
||||
switch (action[1]) {
|
||||
case "showShareModal":
|
||||
showShareModal();
|
||||
break;
|
||||
case 'showShareModal':
|
||||
showShareModal()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function error(errCode, errMsg = "") {
|
||||
redirect("/pages/public/error", {
|
||||
function error(errCode, errMsg = '') {
|
||||
redirect('/pages/public/error', {
|
||||
errCode,
|
||||
errMsg,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
|
@ -195,4 +187,4 @@ export default {
|
|||
getCurrentPage,
|
||||
getCurrentRoute,
|
||||
error,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import { ref } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
import $platform from "@/peach/platform";
|
||||
import $router from "@/peach/router";
|
||||
import useUserStore from "./user";
|
||||
import useSysStore from "./sys";
|
||||
import { ref } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import $platform from '@/peach/platform'
|
||||
import $router from '@/peach/router'
|
||||
import useSysStore from './sys'
|
||||
|
||||
const useAppStore = defineStore(
|
||||
"app",
|
||||
'app',
|
||||
() => {
|
||||
/**
|
||||
* @description 应用信息
|
||||
|
@ -19,14 +18,14 @@ const useAppStore = defineStore(
|
|||
* @param string filesystem 文件系统
|
||||
*/
|
||||
const info = ref({
|
||||
name: "",
|
||||
logo: "",
|
||||
version: "",
|
||||
copyright: "",
|
||||
copytime: "",
|
||||
cdnurl: "",
|
||||
filesystem: "",
|
||||
});
|
||||
name: '',
|
||||
logo: '',
|
||||
version: '',
|
||||
copyright: '',
|
||||
copytime: '',
|
||||
cdnurl: '',
|
||||
filesystem: '',
|
||||
})
|
||||
|
||||
/**
|
||||
* @description 平台信息
|
||||
|
@ -41,12 +40,12 @@ const useAppStore = defineStore(
|
|||
methods: [],
|
||||
forwardInfo: {},
|
||||
posterInfo: {},
|
||||
linkAddress: "",
|
||||
linkAddress: '',
|
||||
},
|
||||
bindMobile: 0,
|
||||
});
|
||||
})
|
||||
|
||||
const chat = ref({});
|
||||
const chat = ref({})
|
||||
|
||||
/**
|
||||
* @description 模板信息
|
||||
|
@ -58,50 +57,46 @@ const useAppStore = defineStore(
|
|||
tabbar: {
|
||||
items: [
|
||||
{
|
||||
activeIconUrl:
|
||||
"http://mall.yudao.iocoder.cn/static/images/1-002.png",
|
||||
iconUrl: "http://mall.yudao.iocoder.cn/static/images/1-001.png",
|
||||
text: "首页",
|
||||
url: "/pages/index/index",
|
||||
activeIconUrl: 'http://mall.yudao.iocoder.cn/static/images/1-002.png',
|
||||
iconUrl: 'http://mall.yudao.iocoder.cn/static/images/1-001.png',
|
||||
text: '首页',
|
||||
url: '/pages/index/index',
|
||||
},
|
||||
{
|
||||
activeIconUrl:
|
||||
"http://mall.yudao.iocoder.cn/static/images/2-002.png",
|
||||
iconUrl: "http://mall.yudao.iocoder.cn/static/images/2-001.png",
|
||||
text: "产品",
|
||||
url: "/pages/index/product",
|
||||
activeIconUrl: 'http://mall.yudao.iocoder.cn/static/images/2-002.png',
|
||||
iconUrl: 'http://mall.yudao.iocoder.cn/static/images/2-001.png',
|
||||
text: '产品',
|
||||
url: '/pages/index/product',
|
||||
},
|
||||
{
|
||||
activeIconUrl:
|
||||
"http://mall.yudao.iocoder.cn/static/images/3-002.png",
|
||||
iconUrl: "http://mall.yudao.iocoder.cn/static/images/3-001.png",
|
||||
text: "订单",
|
||||
url: "/pages/order/list",
|
||||
activeIconUrl: 'http://mall.yudao.iocoder.cn/static/images/3-002.png',
|
||||
iconUrl: 'http://mall.yudao.iocoder.cn/static/images/3-001.png',
|
||||
text: '订单',
|
||||
url: '/pages/order/list',
|
||||
},
|
||||
{
|
||||
activeIconUrl:
|
||||
"http://mall.yudao.iocoder.cn/static/images/4-002.png",
|
||||
iconUrl: "http://mall.yudao.iocoder.cn/static/images/4-001.png",
|
||||
text: "我的",
|
||||
url: "/pages/index/my",
|
||||
activeIconUrl: 'http://mall.yudao.iocoder.cn/static/images/4-002.png',
|
||||
iconUrl: 'http://mall.yudao.iocoder.cn/static/images/4-001.png',
|
||||
text: '我的',
|
||||
url: '/pages/index/my',
|
||||
},
|
||||
],
|
||||
style: {
|
||||
activeColor: "#fc4141",
|
||||
bgColor: "#fff",
|
||||
bgType: "color",
|
||||
color: "#282828",
|
||||
activeColor: '#fc4141',
|
||||
bgColor: '#fff',
|
||||
bgType: 'color',
|
||||
color: '#282828',
|
||||
},
|
||||
theme: "red",
|
||||
theme: 'red',
|
||||
},
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
// 全局分享信息
|
||||
const shareInfo = ref({});
|
||||
const shareInfo = ref({})
|
||||
|
||||
// 小程序发货信息管理 0: 没有 1:有
|
||||
const hasWechatTradeManaged = ref(0);
|
||||
const hasWechatTradeManaged = ref(0)
|
||||
|
||||
/**
|
||||
* @author Ankkaya
|
||||
|
@ -111,52 +106,47 @@ const useAppStore = defineStore(
|
|||
*/
|
||||
async function init() {
|
||||
// 检查网络
|
||||
const networkStatus = await $platform.checkNetwork();
|
||||
const networkStatus = await $platform.checkNetwork()
|
||||
if (!networkStatus) {
|
||||
$router.error("NetworkError");
|
||||
$router.error('NetworkError')
|
||||
}
|
||||
|
||||
if (true) {
|
||||
this.info = {
|
||||
name: "🍑商城",
|
||||
logo: "https://static.iocoder.cn/ruoyi-vue-pro-logo.png",
|
||||
version: "1.0.0",
|
||||
copyright: "全部开源,个人与企业可 100% 免费使用",
|
||||
copytime: "Copyright© 2018-2024",
|
||||
name: '🍑商城',
|
||||
logo: 'https://static.iocoder.cn/ruoyi-vue-pro-logo.png',
|
||||
version: '1.0.0',
|
||||
copyright: '全部开源,个人与企业可 100% 免费使用',
|
||||
copytime: 'Copyright© 2018-2024',
|
||||
|
||||
cdnurl: "https://file.sheepjs.com", // 云存储域名
|
||||
filesystem: "qcloud", // 云存储平台
|
||||
};
|
||||
cdnurl: 'https://file.sheepjs.com', // 云存储域名
|
||||
filesystem: 'qcloud', // 云存储平台
|
||||
}
|
||||
this.platform = {
|
||||
share: {
|
||||
methods: ["poster", "link"],
|
||||
linkAddress: "https://shopro.sheepjs.com/#/",
|
||||
methods: ['poster', 'link'],
|
||||
linkAddress: 'https://shopro.sheepjs.com/#/',
|
||||
posterInfo: {
|
||||
user_bg: "/static/img/shop/config/user-poster-bg.png",
|
||||
goods_bg: "/static/img/shop/config/goods-poster-bg.png",
|
||||
groupon_bg: "/static/img/shop/config/groupon-poster-bg.png",
|
||||
user_bg: '/static/img/shop/config/user-poster-bg.png',
|
||||
goods_bg: '/static/img/shop/config/goods-poster-bg.png',
|
||||
groupon_bg: '/static/img/shop/config/groupon-poster-bg.png',
|
||||
},
|
||||
},
|
||||
bind_mobile: 0,
|
||||
};
|
||||
}
|
||||
this.chat = {
|
||||
chat_domain: "https://api.shopro.sheepjs.com/chat",
|
||||
room_id: "admin",
|
||||
};
|
||||
this.has_wechat_trade_managed = 0;
|
||||
chat_domain: 'https://api.shopro.sheepjs.com/chat',
|
||||
room_id: 'admin',
|
||||
}
|
||||
this.has_wechat_trade_managed = 0
|
||||
|
||||
// 加载主题
|
||||
const sysStore = useSysStore();
|
||||
sysStore.setTheme();
|
||||
const sysStore = useSysStore()
|
||||
sysStore.setTheme()
|
||||
|
||||
// 模拟用户登录
|
||||
const userStore = useUserStore();
|
||||
if (userStore.isLogin) {
|
||||
userStore.loginAfter();
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
return Promise.resolve(true)
|
||||
} else {
|
||||
$router.error("InitError", res.msg || "加载失败");
|
||||
$router.error('InitError', res.msg || '加载失败')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,18 +158,18 @@ const useAppStore = defineStore(
|
|||
shareInfo,
|
||||
hasWechatTradeManaged,
|
||||
init,
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
key: "app-store",
|
||||
key: 'app-store',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
export default useAppStore;
|
||||
export default useAppStore
|
||||
|
|
|
@ -10,7 +10,6 @@ const useSysStore = defineStore(
|
|||
const fontSize = ref(1)
|
||||
|
||||
function setTheme(stheme = '') {
|
||||
console.log('setTheme', stheme)
|
||||
theme.value = stheme ? stheme : 'orange'
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
import { ref } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
import $share from "@/peach/platform/share";
|
||||
import { isEmpty, cloneDeep, clone } from "lodash";
|
||||
import { ref } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import $share from '@/peach/platform/share'
|
||||
import $router from '@/peach/router'
|
||||
import UserUtil from '@/peach/api/member/user'
|
||||
import { isEmpty, cloneDeep, clone } from 'lodash'
|
||||
|
||||
// 默认用户信息
|
||||
const defaultUserInfo = {
|
||||
avatar: "", // 头像
|
||||
nickname: "", // 昵称
|
||||
gender: 0, // 性别
|
||||
mobile: "", // 手机号
|
||||
avatar: '', // 头像
|
||||
nickname: '', // 昵称
|
||||
mobile: '', // 手机号
|
||||
point: 0, // 积分
|
||||
};
|
||||
particulars: null,
|
||||
}
|
||||
|
||||
// 默认钱包信息
|
||||
const defaultWallet = {
|
||||
balance: 0, // 余额
|
||||
};
|
||||
totalExpense: 0, // 总消费
|
||||
totalRecharge: 0, // 总充值
|
||||
}
|
||||
|
||||
// 默认订单信息
|
||||
const defaultNumData = {
|
||||
|
@ -28,83 +32,93 @@ const defaultNumData = {
|
|||
uncommentedCount: 0,
|
||||
afterSaleCount: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const useUserStore = defineStore(
|
||||
"user",
|
||||
'user',
|
||||
() => {
|
||||
const userInfo = ref(clone(defaultUserInfo));
|
||||
const userWallet = ref(clone(defaultWallet));
|
||||
const userNumData = ref(cloneDeep(defaultNumData));
|
||||
const isLogin = ref(!!uni.getStorageSync("token"));
|
||||
const lastUpdateTime = ref(0);
|
||||
const userInfo = ref(cloneDeep(defaultUserInfo))
|
||||
const userWallet = ref(clone(defaultWallet))
|
||||
const userNumData = ref(cloneDeep(defaultNumData))
|
||||
const isLogin = ref(!!uni.getStorageSync('token'))
|
||||
const lastUpdateTime = ref(0)
|
||||
const lastRoutePage = ref(null)
|
||||
|
||||
function getUserInfo() {}
|
||||
async function getUserInfo() {
|
||||
let res = await UserUtil.getUserInfo()
|
||||
userInfo.value = res.data
|
||||
}
|
||||
|
||||
function getWallet() {}
|
||||
async function getWallet() {
|
||||
let res = await UserUtil.getWalletInfo()
|
||||
userWallet.value = res.data
|
||||
}
|
||||
|
||||
function getNumData() {}
|
||||
|
||||
function setToken(token, refreshToken) {
|
||||
if (token === "") {
|
||||
isLogin.value = false;
|
||||
uni.removeStorageSync("token");
|
||||
uni.removeStorageSync("refresh-token");
|
||||
if (token === '') {
|
||||
isLogin.value = false
|
||||
uni.removeStorageSync('token')
|
||||
uni.removeStorageSync('refresh-token')
|
||||
} else {
|
||||
isLogin.value = true;
|
||||
uni.setStorageSync("token", token);
|
||||
uni.setStorageSync("refresh-token", refreshToken);
|
||||
isLogin.value = true
|
||||
uni.setStorageSync('token', token)
|
||||
uni.setStorageSync('refresh-token', refreshToken)
|
||||
// 成功后处理
|
||||
loginAfter();
|
||||
loginAfter()
|
||||
}
|
||||
return isLogin.value;
|
||||
return isLogin.value
|
||||
}
|
||||
|
||||
function resetUserData() {
|
||||
setToken("");
|
||||
userInfo.value = clone(defaultUserInfo);
|
||||
userWallet.value = clone(defaultWallet);
|
||||
userNumData.value = cloneDeep(defaultNumData);
|
||||
setToken('')
|
||||
userInfo.value = cloneDeep(defaultUserInfo)
|
||||
userWallet.value = clone(defaultWallet)
|
||||
userNumData.value = cloneDeep(defaultNumData)
|
||||
}
|
||||
|
||||
async function updateUserData() {
|
||||
const nowTime = new Date().getTime();
|
||||
const nowTime = new Date().getTime()
|
||||
if (lastUpdateTime.value + 5000 > nowTime) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
lastUpdateTime.value = nowTime;
|
||||
|
||||
await getUserInfo();
|
||||
getWallet();
|
||||
getNumData();
|
||||
return userInfo.value;
|
||||
lastUpdateTime.value = nowTime
|
||||
await Promise.all([getUserInfo(), getWallet(), getNumData()])
|
||||
return userInfo.value
|
||||
}
|
||||
|
||||
function loginAfter() {
|
||||
updateUserData();
|
||||
$share.getShareInfo();
|
||||
async function loginAfter() {
|
||||
await updateUserData()
|
||||
$share.getShareInfo()
|
||||
$router.go('/pages/index/index')
|
||||
}
|
||||
|
||||
function logOut() {
|
||||
resetUserData();
|
||||
return !isLogin.value;
|
||||
resetUserData()
|
||||
return !isLogin.value
|
||||
}
|
||||
|
||||
return {
|
||||
userInfo,
|
||||
userWallet,
|
||||
isLogin,
|
||||
setToken,
|
||||
logOut,
|
||||
};
|
||||
loginAfter,
|
||||
lastRoutePage,
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: true,
|
||||
persist: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
key: "user-store",
|
||||
key: 'user-store',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
export default useUserStore;
|
||||
export default useUserStore
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { computed, unref } from 'vue'
|
||||
import PbSTabbar from './pb-s-tabbar.vue'
|
||||
import peach from '@/peach'
|
||||
|
@ -59,6 +60,12 @@ const props = defineProps({
|
|||
path: String,
|
||||
default: '',
|
||||
})
|
||||
|
||||
onLoad(() => {
|
||||
// 隐藏原生导航栏 使用自定义底部导航
|
||||
// app.vue 内直接调用,在首页是非 tabbar 页面时,会报错
|
||||
uni.hideTabBar()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
Loading…
Reference in New Issue