Browse Source

状态管理由vuex换成pinia

tongshangming 2 years ago
parent
commit
81869cf2a6

+ 4 - 2
components/fs-upload/fs-upload.vue

@@ -50,9 +50,12 @@ export default {
 </script>
 
 <script setup>
+import { getCurrentInstance } from 'vue'
 import utils from '@/utils/utils'
 import config from '@/utils/config'
 
+const { proxy } = getCurrentInstance()
+
 const props = defineProps({
 	action: String,
 	name: {
@@ -134,7 +137,7 @@ const upload = async () => {
 			...props.chooseData
 		},
 		{
-			url: props.action,
+			url: props.action || proxy.$uploadUrl,
 			name: props.name,
 			header: props.header,
 			formData: props.formData
@@ -143,7 +146,6 @@ const upload = async () => {
 	).then(res => {
 		const fileList = [...props.modelValue, ...res]
 		fileList.length > props.count && fileList.splice(props.count)
-		console.log(fileList)
 		emit('update:modelValue', fileList)
 	})
 }

+ 18 - 15
main.js

@@ -1,15 +1,18 @@
-import store from './store'
-import App from './App'
-import http from './utils/http'
-
-import { createSSRApp } from 'vue'
-export function createApp() {
-  const app = createSSRApp(App)
-	app.use(store)
-	
-	app.config.globalProperties.$http = http
-	
-  return {
-    app
-  }
-}
+import { store } from './stores'
+import App from './App'
+import http from './utils/http'
+import config from './utils/config'
+
+import { createSSRApp } from 'vue'
+export function createApp() {
+	const app = createSSRApp(App)
+	app.use(store)
+
+	app.config.globalProperties.$http = http
+	app.config.globalProperties.$uploadUrl = config.uploadUrl
+
+	return {
+		app,
+		store
+	}
+}

+ 89 - 89
modules/common/feedback.vue

@@ -3,19 +3,19 @@
 		<fs-tab :tabs="tabs" v-model="tabActive"></fs-tab>
 		<view class="main" v-show="tabActive === 0">
 			<fs-panel title="请选择您遇到的问题">
-				<template #content>
-					<fs-radio-group v-model="curProblem">
-						<fs-radio-cell 
-							v-for="(item,index) in problemList" 
-							:key="index"
-							:label="item.label"
-							:value="item.label">
-						</fs-radio-cell>
+				<template #content>
+					<fs-radio-group v-model="curProblem">
+						<fs-radio-cell
+							v-for="(item, index) in problemList"
+							:key="index"
+							:label="item.label"
+							:value="item.label"
+						></fs-radio-cell>
 					</fs-radio-group>
-					<!-- <fs-cell
-						border
-						justify="right" 
-						:title="item.title" 
+					<!-- <fs-cell
+						border
+						justify="right" 
+						:title="item.title" 
 						@click="selectProblem(index)"
 						v-for="(item, index) in problemList">
 						<template #value>
@@ -25,49 +25,49 @@
 				</template>
 			</fs-panel>
 
-			<fs-panel title="请补充详情问题和意见(必填)">
-				<template #content>
-					<view class="textarea-box">
-						<fs-field type="textarea" height="200rpx" placeholder="请输入问题描述..." v-model="state.detail"></fs-field>
-						<view class="input-num">{{state.detail.length}}/140</view>
-					</view>
+			<fs-panel title="请补充详情问题和意见(必填)">
+				<template #content>
+					<view class="textarea-box">
+						<fs-field type="textarea" height="200rpx" placeholder="请输入问题描述..." v-model="state.detail"></fs-field>
+						<view class="input-num">{{ state.detail.length }}/140</view>
+					</view>
 				</template>
 			</fs-panel>
 
 			<fs-panel title="请上传相关问题图片">
-				<template #content>
-					<fs-upload v-model="state.photoList" cloudUpload></fs-upload>
+				<template #content>
+					<fs-upload v-model="state.photoList"></fs-upload>
 				</template>
 			</fs-panel>
 
-			<fs-button block round @click="handleSubmit">提交</fs-button>
+			<fs-button block round @click="handleSubmit">提交</fs-button>
 			<fs-gutter bgColor="#fff"></fs-gutter>
-		</view>
-		<view class="main" v-show="tabActive === 1">
-			<div v-for="item in state.adviceList" :key="item.id">
-				<div class="list-hd title-hd title-color">{{item.type}}</div>
-				<div class="list-bd list-color">回复:{{item.replyContent}}</div>
-			</div>
-			<fs-empty v-if="!state.adviceList.length"></fs-empty>
+		</view>
+		<view class="main" v-show="tabActive === 1">
+			<div v-for="item in state.adviceList" :key="item.id">
+				<div class="list-hd title-hd title-color">{{ item.type }}</div>
+				<div class="list-bd list-color">回复:{{ item.replyContent }}</div>
+			</div>
+			<fs-empty v-if="!state.adviceList.length"></fs-empty>
 		</view>
 	</view>
 </template>
 
 <script setup>
-import { ref, reactive } from 'vue'
-import { addAdvice, getAdviceList } from '@/services/common'
-
-const tabs = [
+import { ref, reactive } from 'vue'
+import { addAdvice, getAdviceList } from '@/services/common'
+
+const tabs = [
 	{
-		name: '提建议',
+		name: '提建议'
 	},
 	{
-		name: '反馈',
+		name: '反馈'
 	}
-]
-const tabActive = ref(0)
-
-const problemList = [
+]
+const tabActive = ref(0)
+
+const problemList = [
 	{
 		label: '功能异常:功能故障或不可用'
 	},
@@ -79,56 +79,56 @@ const problemList = [
 	},
 	{
 		label: '其他问题'
-	},
-]
-const curProblem = ref(problemList[0].label)
-
-const state = reactive({
-	detail: '',
-	photoList: [],
-	adviceList: []
-})
-
-const fetchList = () => {
-	getAdviceList().then(res => {
-		console.log('feed', res);
-		// state.adviceList = res.data
-	})
-}
-// fetchList()
-
-const handleSubmit = () => {
-	if (!state.detail) {
-		return uni.showToast({
-			title: '请输入问题描述',
-			icon: 'none'
-		})
+	}
+]
+const curProblem = ref(problemList[0].label)
+
+const state = reactive({
+	detail: '',
+	photoList: [],
+	adviceList: []
+})
+
+const fetchList = () => {
+	getAdviceList().then(res => {
+		console.log('feed', res)
+		// state.adviceList = res.data
+	})
+}
+// fetchList()
+
+const handleSubmit = () => {
+	if (!state.detail) {
+		return uni.showToast({
+			title: '请输入问题描述',
+			icon: 'none'
+		})
 	}
 	const images = state.photoList.map(item => item.name).join(',')
 
-	addAdvice({
-		type: curProblem.value,
-		content: state.detail,
-		images
-	}).then(res => {
-		uni.showToast({
-			icon: 'none',
-			title: '提交成功'
-		})
-		setTimeout(function() {
-			uni.navigateBack()
-		}, 1500)
+	addAdvice({
+		type: curProblem.value,
+		content: state.detail,
+		images
+	}).then(res => {
+		uni.showToast({
+			icon: 'none',
+			title: '提交成功'
+		})
+		setTimeout(function() {
+			uni.navigateBack()
+		}, 1500)
 	})
 }
 </script>
 
-<style>
-	page{
-		height: 100%;
-	}
-</style>
+<style>
+page {
+	height: 100%;
+}
+</style>
 <style lang="scss" scoped>
-.main{
+.main {
 	background-color: white;
 }
 .textarea-box {
@@ -143,21 +143,21 @@ const handleSubmit = () => {
 	position: absolute;
 	right: 30rpx;
 	bottom: 20rpx;
-	color: #AAAAAA;
+	color: #aaaaaa;
 	font-size: 30rpx;
 	z-index: 10;
 }
-.title-hd{
+.title-hd {
 	margin: 0rpx 30rpx;
-}
-.list-bd{
-	background-color: #F2F2F2;
-	border-radius: 8rpx;
+}
+.list-bd {
+	background-color: #f2f2f2;
+	border-radius: 8rpx;
 	padding: 10rpx 10rpx 40rpx 10rpx;
-	margin: 0 30rpx;
+	margin: 0 30rpx;
 }
-.list-color{
+.list-color {
 	color: #858585;
-	background-color: #F0F0F0;
+	background-color: #f0f0f0;
 }
 </style>

+ 27 - 19
modules/common/login/login.vue

@@ -19,9 +19,16 @@
 				</template>
 			</fs-field>
 			<fs-gutter height="100rpx" bgColor="#fff"></fs-gutter>
-			<fs-button full round @click="handleLogin" :customStyle="{background: 'linear-gradient(to right, #00c6fc, #9adcf1)'}">登录</fs-button>
+			<fs-button
+				full
+				round
+				@click="handleLogin"
+				:customStyle="{ background: 'linear-gradient(to right, #00c6fc, #9adcf1)' }"
+			>
+				登录
+			</fs-button>
 			<fs-gutter height="60rpx" bgColor="#fff"></fs-gutter>
-			<fs-button full round type="success"  @click="getUserProfile">微信登录</fs-button>
+			<fs-button full round type="success" @click="getUserProfile">微信登录</fs-button>
 		</fs-form>
 	</view>
 </template>
@@ -29,9 +36,9 @@
 <script setup>
 import { ref, reactive } from 'vue'
 import useForm from '@/hooks/useForm'
-import { useStore } from 'vuex'
+import { useUserStore } from '@/stores/user'
 
-const store = useStore()
+const user = useUserStore()
 const loginRules = {
 	name: {
 		required: true,
@@ -51,11 +58,13 @@ const loginRef = ref(null)
 const loginForm = useForm(loginRules, 'loginRef')
 const handleLogin = () => {
 	loginForm.validate().then(() => {
-		store.dispatch('login', {
-			...loginModel
-		}).then(res => {
-			uni.navigateBack()
-		})
+		user
+			.login({
+				...loginModel
+			})
+			.then(res => {
+				uni.navigateBack()
+			})
 	})
 }
 
@@ -64,7 +73,6 @@ const getUserProfile = () => {
 		desc: '用于完善会员资料',
 		success: res => {
 			// store.dispatch('wxLogin').then(res => {
-				
 			// })
 		}
 	})
@@ -72,12 +80,12 @@ const getUserProfile = () => {
 </script>
 
 <style>
-page{
+page {
 	background-color: #fff;
 }
 </style>
 <style lang="scss" scoped>
-.login{
+.login {
 	&-bg {
 		position: fixed;
 		top: -250rpx;
@@ -86,9 +94,9 @@ page{
 		height: 600rpx;
 		border-radius: 100%;
 		background-color: #00baef;
-		z-index: 2
+		z-index: 2;
 	}
-	
+
 	&-bg2 {
 		position: fixed;
 		top: -150rpx;
@@ -100,18 +108,18 @@ page{
 		z-index: 1;
 	}
 }
-.login-box{
+.login-box {
 	padding: 30rpx;
 }
-.login-top{
+.login-top {
 	color: #222222;
 	font-size: 30px;
 	font-weight: bold;
 	margin: 150rpx 0;
-	
-	&-sub{
+
+	&-sub {
 		font-size: 16px;
 		color: #b0b0b1;
 	}
 }
-</style>
+</style>

+ 36 - 41
modules/common/login/login1.vue

@@ -5,43 +5,37 @@
 			<view class="title bold" style="font-size: 27px;">验证手机号</view>
 			<view style="color: #999999;font-size: 14px;">请输入园区预留手机号,验证您的园区人员身份</view>
 			<fs-gutter bgColor="#fff" height="100rpx"></fs-gutter>
-			<fs-form-item>
-				<fs-field type="number" placeholder="请输入手机号" v-model="phone"></fs-field>
-			</fs-form-item>
+			<fs-form-item><fs-field type="number" placeholder="请输入手机号" v-model="phone"></fs-field></fs-form-item>
 		</view>
-		
+
 		<view class="layout-box" v-else>
 			<view class="title bold" style="font-size: 27px;">输入验证码</view>
-			<view style="color: #999999;">已将验证码发至手机号:{{phone}}</view>
+			<view style="color: #999999;">已将验证码发至手机号:{{ phone }}</view>
 			<fs-gutter bgColor="#fff" height="100rpx"></fs-gutter>
 			<view class="fs-captcha">
 				<view
 					class="fs-captcha-item"
-					:class="{'fs-captcha-item-active': curIndex === index}"
+					:class="{ 'fs-captcha-item-active': curIndex === index }"
 					v-for="(item, index) in captchaNo"
 					:key="index"
-					@click="handleInput(index)">
-						{{item}}
-					</view>
+					@click="handleInput(index)"
+				>
+					{{ item }}
+				</view>
 			</view>
 			<fs-keyboard mode="number" v-model="keyboardNum" @change="handleChange"></fs-keyboard>
 		</view>
-		
+
 		<fs-gutter bgColor="#fff" height="100rpx"></fs-gutter>
-		<fs-captcha
-			block
-			:plain="false"
-			:mobile="phone"
-			@start="handleNext">
-		</fs-captcha>
+		<fs-captcha block :plain="false" :mobile="phone" @start="handleNext"></fs-captcha>
 	</view>
 </template>
 
 <script setup>
 import { ref, reactive } from 'vue'
-import { useStore } from 'vuex'
+import { useUserStore } from '@/stores/user'
 
-const store = useStore()
+const user = useUserStore()
 
 let pageIndex = ref(0)
 let phone = ref('')
@@ -52,60 +46,61 @@ const handleNext = () => {
 const captchaNo = ref(new Array(4))
 let keyboardNum = ref(true)
 let curIndex = ref(0)
-const handleChange = (item) => {
+const handleChange = item => {
 	const length = captchaNo.value.filter(item => item).length
-	
+
 	if (item === 'del') {
 		if (length >= 1) {
 			curIndex.value--
 			captchaNo.value[curIndex.value] = ''
 		}
-	} else{
+	} else {
 		if (length <= captchaNo.value.length - 1) {
 			captchaNo.value[curIndex.value] = item
 			curIndex.value++
 		}
 	}
-	
+
 	if (captchaNo.value.filter(item => item).length === 4) {
-		store.dispatch('login', {
-			phone,
-			code: captchaNo
-		}).then(res => {
-			uni.navigateBack()
-		})
+		user
+			.login({
+				phone,
+				code: captchaNo
+			})
+			.then(res => {
+				uni.navigateBack()
+			})
 	}
 }
-const handleInput = (index) => {
+const handleInput = index => {
 	curIndex.value = index
-	
 }
 </script>
 
 <style>
-page{
+page {
 	background-color: #fff;
 }
 </style>
 <style lang="scss" scoped>
-.fs-captcha{
+.fs-captcha {
 	display: flex;
 	justify-content: center;
 	align-items: center;
-	
-	&-item{
+
+	&-item {
 		width: 120rpx;
-		height: 80rpx;		
-		line-height: 80rpx;		
-		border-bottom: 2rpx solid #CBCBCB;
+		height: 80rpx;
+		line-height: 80rpx;
+		border-bottom: 2rpx solid #cbcbcb;
 		text-align: center;
 		font-size: 18px;
-		
-		& + &{
+
+		& + & {
 			margin-left: 40rpx;
 		}
-		
-		&-active{
+
+		&-active {
 			border-color: var(--primary);
 		}
 	}

+ 107 - 107
modules/common/login/login2.vue

@@ -1,134 +1,134 @@
 <template>
 	<view class="layout-box">
-		<view class="login-bg pr">
-			<image src="/modules/common/static/images/login/login-sw.jpg" mode="widthFix" style="width: 100%;"></image>
-			<view class="bg-text">
-				<view class="bg-text-hd">您好</view>
-				<view class="bg-text-bd">欢迎登录</view>
-			</view>
+		<view class="login-bg pr">
+			<image src="/modules/common/static/images/login/login-sw.jpg" mode="widthFix" style="width: 100%;"></image>
+			<view class="bg-text">
+				<view class="bg-text-hd">您好</view>
+				<view class="bg-text-bd">欢迎登录</view>
+			</view>
 		</view>
 		<view class="login-shadow">
 			<fs-tab :tabs="tabs" v-model="curTab" barWidth="96rpx"></fs-tab>
 			<fs-form ref="loginRef" :model="curLoginModel">
-				<view v-show="curTab === 0">
-					<fs-form-item>
-						<fs-field placeholder="请输入手机号" type="number" v-model="loginModel1.phone" maxlength=11></fs-field>
-					</fs-form-item>
-					<fs-form-item>
-						<fs-field type="number" placeholder="请输入验证码" v-model="loginModel1.code" maxlength=6>
-							<template #after>
-								<fs-captcha :mobile="loginModel1.phone" @start="sendCaptcha" @end="endCaptcha"></fs-captcha>
-							</template>
-						</fs-field>
-					</fs-form-item>
-				</view>
-				<view v-show="curTab === 1">
-					<fs-form-item>
-						<fs-field placeholder="账号" v-model="loginModel2.name" maxlength=11></fs-field>
-					</fs-form-item>
-					<fs-form-item>
-						<fs-field placeholder="密码" type="password" v-model="loginModel2.password" maxlength=20></fs-field>
-					</fs-form-item>
+				<view v-show="curTab === 0">
+					<fs-form-item>
+						<fs-field placeholder="请输入手机号" type="number" v-model="loginModel1.phone" maxlength="11"></fs-field>
+					</fs-form-item>
+					<fs-form-item>
+						<fs-field type="number" placeholder="请输入验证码" v-model="loginModel1.code" maxlength="6">
+							<template #after>
+								<fs-captcha :mobile="loginModel1.phone" @start="sendCaptcha" @end="endCaptcha"></fs-captcha>
+							</template>
+						</fs-field>
+					</fs-form-item>
 				</view>
-			</fs-form>
-			
+				<view v-show="curTab === 1">
+					<fs-form-item>
+						<fs-field placeholder="账号" v-model="loginModel2.name" maxlength="11"></fs-field>
+					</fs-form-item>
+					<fs-form-item>
+						<fs-field placeholder="密码" type="password" v-model="loginModel2.password" maxlength="20"></fs-field>
+					</fs-form-item>
+				</view>
+			</fs-form>
+
 			<fs-cell justify="right">
 				<navigator class="primary fs12" slot="title" url="./forgetPwd" v-show="curTab === 1">忘记密码?</navigator>
 				<navigator class="primary fs12" slot="value" url="./register">去注册</navigator>
 			</fs-cell>
 		</view>
-		<view class="login-btn">
-			<fs-button block round type="primary" @click="handleLogin">登录</fs-button>
-		</view>
+		<view class="login-btn"><fs-button block round type="primary" @click="handleLogin">登录</fs-button></view>
 	</view>
 </template>
 
-<script setup>
-import { ref, reactive, computed, watch } from 'vue'
-import useForm from '@/hooks/useForm'
-import useValidator from '@/hooks/useValidator'
-import { useStore } from 'vuex'
-
-const store = useStore()
-const tabs = [
-	{
-		name: '验证码登录',
-	},
+<script setup>
+import { ref, reactive, computed, watch } from 'vue'
+import useForm from '@/hooks/useForm'
+import useValidator from '@/hooks/useValidator'
+import { useUserStore } from '@/stores/user'
+
+const user = useUserStore()
+const tabs = [
+	{
+		name: '验证码登录'
+	},
 	{
-		name: '密码登录',
+		name: '密码登录'
 	}
-]
-const curTab = ref(0)
-
-const validator = useValidator()
-const loginRules1 = {
-	phone: { validator: validator.mobile },
-	code: { required: true, message: '请输入验证码'}
-}
-const loginModel1 = reactive({
-	phone: '',
-	code: ''
-})
-const loginRules2 = {
-	name: { required: true, message: '请输入账号'},
-	password: { required: true, message: '请输入密码'}
-}
-const loginModel2 = reactive({
-	name: '',
-	password: ''
-})
-const curLoginModel = computed(() => curTab.value === 0 ? loginModel1 : loginModel2)
-
-const loginRef = ref(null)
-const loginForm = useForm(loginRules1, 'loginRef')
-watch(curTab, () => {
-	loginForm.setRules(curTab.value === 0 ? loginRules1 : loginRules2)
-})
-const handleLogin = () => {
-	loginForm.validate().then(() => {
-		store.dispatch('login', {
-			...loginModel
-		}).then(res => {
-			uni.navigateBack()
-		})
-	})
-} 
-
-const sendCaptcha = () => {
-	console.log('sendCaptcha');
-}
-const endCaptcha = () => {
-	console.log('endCaptcha');
+]
+const curTab = ref(0)
+
+const validator = useValidator()
+const loginRules1 = {
+	phone: { validator: validator.mobile },
+	code: { required: true, message: '请输入验证码' }
+}
+const loginModel1 = reactive({
+	phone: '',
+	code: ''
+})
+const loginRules2 = {
+	name: { required: true, message: '请输入账号' },
+	password: { required: true, message: '请输入密码' }
+}
+const loginModel2 = reactive({
+	name: '',
+	password: ''
+})
+const curLoginModel = computed(() => (curTab.value === 0 ? loginModel1 : loginModel2))
+
+const loginRef = ref(null)
+const loginForm = useForm(loginRules1, 'loginRef')
+watch(curTab, () => {
+	loginForm.setRules(curTab.value === 0 ? loginRules1 : loginRules2)
+})
+const handleLogin = () => {
+	loginForm.validate().then(() => {
+		user
+			.login({
+				...loginModel
+			})
+			.then(res => {
+				uni.navigateBack()
+			})
+	})
+}
+
+const sendCaptcha = () => {
+	console.log('sendCaptcha')
+}
+const endCaptcha = () => {
+	console.log('endCaptcha')
 }
 </script>
-
-<style>
-page {
-	background-color: #fff;
-}
+
+<style>
+page {
+	background-color: #fff;
+}
 </style>
-<style lang="scss" scoped>
-.login-bg{
-	margin-top: 20rpx;
-}
-.bg-text{
-	position: absolute;
-	left: 80rpx;
-	top: 0;
-	
-	&-hd{
-		font-size: 25px;
-		line-height: 20px;
-		margin-bottom: 20rpx;
-	}
-	&-bd{
-		font-size: 16px;
-	}
+<style lang="scss" scoped>
+.login-bg {
+	margin-top: 20rpx;
+}
+.bg-text {
+	position: absolute;
+	left: 80rpx;
+	top: 0;
+
+	&-hd {
+		font-size: 25px;
+		line-height: 20px;
+		margin-bottom: 20rpx;
+	}
+	&-bd {
+		font-size: 16px;
+	}
 }
 .login-shadow {
 	border-radius: 40rpx;
 	overflow: hidden;
-	padding-bottom: 60rpx;
+	padding-bottom: 60rpx;
 	// box-shadow: 0 0 8px 1px rgba(65, 65, 70, 0.2);
 }
 

+ 19 - 19
modules/common/login/login3.vue

@@ -1,13 +1,11 @@
 <template>
 	<view>
 		<image src="/modules/common/static/images/login/login-car.png" mode="widthFix" style="width: 100vw;"></image>
-		
+
 		<view class="login-box">
 			<view class="login-box-top">手机号登录</view>
 			<fs-form ref="loginRef" :model="loginModel">
-				<fs-form-item>
-					<fs-field placeholder="请输入手机号" v-model="loginModel.phone"></fs-field>
-				</fs-form-item>
+				<fs-form-item><fs-field placeholder="请输入手机号" v-model="loginModel.phone"></fs-field></fs-form-item>
 				<fs-form-item>
 					<fs-field placeholder="请输入验证码" v-model="loginModel.code">
 						<template #after>
@@ -27,12 +25,12 @@
 import { ref, reactive } from 'vue'
 import useForm from '@/hooks/useForm'
 import useValidator from '@/hooks/useValidator'
-import { useStore } from 'vuex'
+import { useUserStore } from '@/stores/user'
 
-const store = useStore()
+const user = useUserStore()
 const validator = useValidator()
 const loginRules = {
-	phone: { validator: validator.mobile},
+	phone: { validator: validator.mobile },
 	code: {
 		required: true,
 		message: '请输入密码'
@@ -46,31 +44,33 @@ const loginRef = ref(null)
 const loginForm = useForm(loginRules, 'loginRef')
 const handleLogin = () => {
 	loginForm.validate().then(() => {
-		store.dispatch('login', {
-			...loginModel
-		}).then(res => {
-			uni.navigateBack()
-		})
+		user
+			.login({
+				...loginModel
+			})
+			.then(res => {
+				uni.navigateBack()
+			})
 	})
 }
 
 const sendCaptcha = () => {
-	console.log('sendCaptcha');
+	console.log('sendCaptcha')
 }
 const endCaptcha = () => {
-	console.log('endCaptcha');
+	console.log('endCaptcha')
 }
 </script>
 
 <style>
-page{
+page {
 	background-color: #fff;
 	height: 100%;
 	overflow: hidden;
 }
 </style>
 <style lang="scss" scoped>
-.login-box{
+.login-box {
 	position: fixed;
 	left: 40rpx;
 	right: 40rpx;
@@ -79,15 +79,15 @@ page{
 	border-radius: 20rpx;
 	padding: 60rpx;
 	overflow: hidden;
-	
-	&-top{
+
+	&-top {
 		font-size: 20px;
 		color: #222;
 		font-weight: 500;
 		margin: 40rpx 0;
 	}
 }
-.login-top{
+.login-top {
 	color: #222222;
 	font-size: 30px;
 	font-weight: bold;

+ 17 - 11
modules/common/login/login4.vue

@@ -3,9 +3,7 @@
 		<view class="text-center">
 			<image src="/modules/common/static/images/login/logo.png" mode="widthFix" style="width: 500rpx"></image>
 		</view>
-		<view class="login-top">
-			<view>欢迎回来!</view>
-		</view>
+		<view class="login-top"><view>欢迎回来!</view></view>
 		<fs-form ref="loginRef" :model="loginModel">
 			<fs-field class="radius" placeholder="请输入账号" v-model="loginModel.name">
 				<template #before>
@@ -27,7 +25,9 @@
 <script setup>
 import { ref, reactive } from 'vue'
 import useForm from '@/hooks/useForm'
+import { useUserStore } from '@/stores/user'
 
+const user = useUserStore()
 const loginRules = {
 	name: {
 		required: true,
@@ -47,27 +47,33 @@ const loginRef = ref(null)
 const loginForm = useForm(loginRules, 'loginRef')
 const handleLogin = () => {
 	loginForm.validate().then(() => {
-		console.log('success')
+		user
+			.login('login', {
+				...loginModel
+			})
+			.then(res => {
+				uni.navigateBack()
+			})
 	})
 }
 </script>
 
 <style>
-page{
-	background-color: #F6F7FB;
+page {
+	background-color: #f6f7fb;
 }
 </style>
 <style lang="scss" scoped>
-.login-box{
+.login-box {
 	padding: 30rpx;
 }
-.login-top{
-	color: #041B3D;
+.login-top {
+	color: #041b3d;
 	font-size: 24px;
 	font-family: Source Han Sans SC;
 	margin: 50rpx 0;
-	
-	&-sub{
+
+	&-sub {
 		font-size: 18px;
 		color: #b0b0b1;
 	}

+ 17 - 17
modules/common/login/login5.vue

@@ -3,9 +3,7 @@
 		<view class="text-center">
 			<image src="/modules/common/static/images/login/logo.png" mode="widthFix" style="width: 500rpx"></image>
 		</view>
-		<view class="login-top">
-			<view>欢迎回来!</view>
-		</view>
+		<view class="login-top"><view>欢迎回来!</view></view>
 		<fs-form ref="loginRef" :model="loginModel">
 			<fs-field class="radius" placeholder="请输入账号" v-model="loginModel.name">
 				<template #before>
@@ -27,9 +25,9 @@
 <script setup>
 import { ref, reactive } from 'vue'
 import useForm from '@/hooks/useForm'
-import { useStore } from 'vuex'
+import { useUserStore } from '@/stores/user'
 
-const store = useStore()
+const user = useUserStore()
 const loginRules = {
 	name: {
 		required: true,
@@ -49,31 +47,33 @@ const loginRef = ref(null)
 const loginForm = useForm(loginRules, 'loginRef')
 const handleLogin = () => {
 	loginForm.validate().then(() => {
-		store.dispatch('login', {
-			...loginModel
-		}).then(res => {
-			uni.navigateBack()
-		})
+		user
+			.login('login', {
+				...loginModel
+			})
+			.then(res => {
+				uni.navigateBack()
+			})
 	})
 }
 </script>
 
 <style>
-page{
-	background-color: #F6F7FB;
+page {
+	background-color: #f6f7fb;
 }
 </style>
 <style lang="scss" scoped>
-.login-box{
+.login-box {
 	padding: 30rpx;
 }
-.login-top{
-	color: #041B3D;
+.login-top {
+	color: #041b3d;
 	font-size: 24px;
 	font-family: Source Han Sans SC;
 	margin: 50rpx 0;
-	
-	&-sub{
+
+	&-sub {
 		font-size: 18px;
 		color: #b0b0b1;
 	}

+ 76 - 74
modules/common/login/login6.vue

@@ -1,66 +1,68 @@
-<template>
-	<view class="login-box">
-		<view class="top-right-corner"></view>
-		<view class="lower-left-corner"></view>
-		<view class="login-top">欢迎登录</view>
-		<fs-form ref="loginRef" :model="loginModel">
-			<fs-field bgColor="#f8f7fc" placeholder="请输入账号" v-model="loginModel.name">
-				<template #before>
-					<fs-icon type="icon-user" color="#666666"></fs-icon>
-				</template>
-			</fs-field>
-			<fs-gutter height="40rpx" bgColor="#fff"></fs-gutter>
-			<fs-field bgColor="#f8f7fc" placeholder="请输入密码" v-model="loginModel.password">
-				<template #before>
-					<fs-icon type="icon-password" color="#666666"></fs-icon>
-				</template>
-			</fs-field>
-			<fs-gutter height="100rpx" bgColor="#fff"></fs-gutter>
-			<fs-button full round @click="handleLogin" type="danger">登录</fs-button>
-		</fs-form>
-	</view>
-</template>
-
-<script setup>
-import { ref, reactive } from 'vue'
-import useForm from '@/hooks/useForm'
-import { useStore } from 'vuex'
-
-const store = useStore()
-const loginRules = {
-	name: {
-		required: true,
-		message: '请输入账号'
-	},
-	password: {
-		required: true,
-		message: '请输入密码'
-	}
-}
-const loginModel = reactive({
-	name: '',
-	password: ''
-})
-const loginRef = ref(null)
-
-const loginForm = useForm(loginRules, 'loginRef')
-const handleLogin = () => {
-	loginForm.validate().then(() => {
-		store.dispatch('login', {
-			...loginModel
-		}).then(res => {
-			uni.navigateBack()
-		})
-	})
-}
-</script>
-
-<style>
-page{
-	background-color: #fff;
-}
-</style>
-<style lang="scss" scoped>
+<template>
+	<view class="login-box">
+		<view class="top-right-corner"></view>
+		<view class="lower-left-corner"></view>
+		<view class="login-top">欢迎登录</view>
+		<fs-form ref="loginRef" :model="loginModel">
+			<fs-field bgColor="#f8f7fc" placeholder="请输入账号" v-model="loginModel.name">
+				<template #before>
+					<fs-icon type="icon-user" color="#666666"></fs-icon>
+				</template>
+			</fs-field>
+			<fs-gutter height="40rpx" bgColor="#fff"></fs-gutter>
+			<fs-field bgColor="#f8f7fc" placeholder="请输入密码" v-model="loginModel.password">
+				<template #before>
+					<fs-icon type="icon-password" color="#666666"></fs-icon>
+				</template>
+			</fs-field>
+			<fs-gutter height="100rpx" bgColor="#fff"></fs-gutter>
+			<fs-button full round @click="handleLogin" type="danger">登录</fs-button>
+		</fs-form>
+	</view>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue'
+import useForm from '@/hooks/useForm'
+import { useUserStore } from '@/stores/user'
+
+const user = useUserStore()
+const loginRules = {
+	name: {
+		required: true,
+		message: '请输入账号'
+	},
+	password: {
+		required: true,
+		message: '请输入密码'
+	}
+}
+const loginModel = reactive({
+	name: '',
+	password: ''
+})
+const loginRef = ref(null)
+
+const loginForm = useForm(loginRules, 'loginRef')
+const handleLogin = () => {
+	loginForm.validate().then(() => {
+		user
+			.login({
+				...loginModel
+			})
+			.then(res => {
+				uni.navigateBack()
+			})
+	})
+}
+</script>
+
+<style>
+page {
+	background-color: #fff;
+}
+</style>
+<style lang="scss" scoped>
 .top-right-corner {
 	position: fixed;
 	top: -280rpx;
@@ -83,15 +85,15 @@ page{
 	border: 100rpx solid #c7e1fa;
 	transform: rotate(-45deg);
 	z-index: 1;
-}
-.login-box{
-	padding: 30rpx;
-}
-.login-top{
-	font-size: 50rpx;
-	letter-spacing: 5rpx;
-	font-weight: bold;
-	text-align: center;
-	margin: 300rpx 0 100rpx;
-}
+}
+.login-box {
+	padding: 30rpx;
+}
+.login-top {
+	font-size: 50rpx;
+	letter-spacing: 5rpx;
+	font-weight: bold;
+	text-align: center;
+	margin: 300rpx 0 100rpx;
+}
 </style>

+ 109 - 105
pages/index/welcome.vue

@@ -1,133 +1,137 @@
 <template>
-	<view class="wrapper">
-		<view class="circle"></view>
-		<view class="circle"></view>
-		<view class="circle"></view>
-		<view class="shadow"></view>
-		<view class="shadow"></view>
-		<view class="shadow"></view>
-		<text>加载中...</text>
+	<view class="wrapper">
+		<view class="circle"></view>
+		<view class="circle"></view>
+		<view class="circle"></view>
+		<view class="shadow"></view>
+		<view class="shadow"></view>
+		<view class="shadow"></view>
+		<text>加载中...</text>
 	</view>
 </template>
 
-<script setup>
+<script setup>
 import { onLoad } from '@dcloudio/uni-app'
-import { useStore } from 'vuex'
-
-const store = useStore()
-
-onLoad(() => {
-	store.dispatch('loginByOpenId').finally(() => {
-		uni.switchTab({
-			url: '/pages/index/index'
-		})
-	})
+import { useUserStore } from '@/stores/user'
+
+const user = useUserStore()
+
+onLoad(() => {
+	// 静默登录
+	// user.loginByCode().finally(() => {
+	// 	uni.switchTab({
+	// 		url: '/pages/index/index'
+	// 	})
+	// })
+	uni.switchTab({
+		url: '/pages/index/index'
+	})
 })
 </script>
 
 <style>
-	page {
-		background-color: #fff;
-	}
+page {
+	background-color: #fff;
+}
 </style>
 <style lang="scss" scoped>
-	.wrapper{
-		width:200px;
-		height:60px;
-		position: absolute;
-		left:50%;
-		top:50%;
-		transform: translate(-50%, -50%);
-	}
-	.circle {
-		width: 20px;
-		height: 20px;
-		position: absolute;
-		border-radius: 50%;
-		background-color: var(--primary);
-		left: 15%;
-		transform-origin: 50%;
-		animation: circle .5s alternate infinite ease;
-	}
+.wrapper {
+	width: 200px;
+	height: 60px;
+	position: absolute;
+	left: 50%;
+	top: 50%;
+	transform: translate(-50%, -50%);
+}
+.circle {
+	width: 20px;
+	height: 20px;
+	position: absolute;
+	border-radius: 50%;
+	background-color: var(--primary);
+	left: 15%;
+	transform-origin: 50%;
+	animation: circle 0.5s alternate infinite ease;
+}
 
-	@keyframes circle {
-		0% {
-			top: 60px;
-			height: 5px;
-			border-radius: 50px 50px 25px 25px;
-			transform: scaleX(1.7);
-		}
-
-		40% {
-			height: 20px;
-			border-radius: 50%;
-			transform: scaleX(1);
-		}
-
-		100% {
-			top: 0%;
-		}
+@keyframes circle {
+	0% {
+		top: 60px;
+		height: 5px;
+		border-radius: 50px 50px 25px 25px;
+		transform: scaleX(1.7);
 	}
 
-	.circle:nth-child(2) {
-		left: 45%;
-		animation-delay: .2s;
+	40% {
+		height: 20px;
+		border-radius: 50%;
+		transform: scaleX(1);
 	}
 
-	.circle:nth-child(3) {
-		left: auto;
-		right: 15%;
-		animation-delay: .3s;
+	100% {
+		top: 0%;
 	}
+}
 
-	.shadow {
-		width: 20px;
-		height: 4px;
-		border-radius: 50%;
-		background-color: rgba(0, 0, 0, .5);
-		position: absolute;
-		top: 62px;
-		transform-origin: 50%;
-		z-index: -1;
-		left: 15%;
-		filter: blur(1px);
-		animation: shadow .5s alternate infinite ease;
-	}
+.circle:nth-child(2) {
+	left: 45%;
+	animation-delay: 0.2s;
+}
 
-	@keyframes shadow {
-		0% {
-			transform: scaleX(1.5);
-		}
+.circle:nth-child(3) {
+	left: auto;
+	right: 15%;
+	animation-delay: 0.3s;
+}
 
-		40% {
-			transform: scaleX(1);
-			opacity: .7;
-		}
+.shadow {
+	width: 20px;
+	height: 4px;
+	border-radius: 50%;
+	background-color: rgba(0, 0, 0, 0.5);
+	position: absolute;
+	top: 62px;
+	transform-origin: 50%;
+	z-index: -1;
+	left: 15%;
+	filter: blur(1px);
+	animation: shadow 0.5s alternate infinite ease;
+}
 
-		100% {
-			transform: scaleX(.2);
-			opacity: .4;
-		}
+@keyframes shadow {
+	0% {
+		transform: scaleX(1.5);
 	}
 
-	.shadow:nth-child(4) {
-		left: 45%;
-		animation-delay: .2s
+	40% {
+		transform: scaleX(1);
+		opacity: 0.7;
 	}
 
-	.shadow:nth-child(5) {
-		left: auto;
-		right: 15%;
-		animation-delay: .3s;
+	100% {
+		transform: scaleX(0.2);
+		opacity: 0.4;
 	}
+}
 
-	text {
-		position: absolute;
-		top: 75px;
-		font-family: 'Lato';
-		font-size: 18px;
-		letter-spacing: 12px;
-		color: var(--primary);
-		left: 15%;
-	}
+.shadow:nth-child(4) {
+	left: 45%;
+	animation-delay: 0.2s;
+}
+
+.shadow:nth-child(5) {
+	left: auto;
+	right: 15%;
+	animation-delay: 0.3s;
+}
+
+text {
+	position: absolute;
+	top: 75px;
+	font-family: 'Lato';
+	font-size: 18px;
+	letter-spacing: 12px;
+	color: var(--primary);
+	left: 15%;
+}
 </style>

+ 23 - 25
pages/my/my.vue

@@ -5,10 +5,10 @@
 			<view class="radius-lg top-box">
 				<view class="user-info" v-if="userInfo.name">
 					<fs-avatar link="./userInfo" size="130rpx" :src="userInfo.photo || userAvatar"></fs-avatar>
-					
+
 					<view class="top-box-content">
-						<view class="top-box-title">{{userInfo.name}}</view>
-						<view>{{userInfo.phone}}</view>
+						<view class="top-box-title">{{ userInfo.name }}</view>
+						<view>{{ userInfo.mobile }}</view>
 					</view>
 				</view>
 				<view v-else class="text-center">
@@ -16,19 +16,19 @@
 				</view>
 			</view>
 		</view>
-		
+
 		<view class="short-list">
 			<fs-divide-list :list="shortcutList">
 				<template #default="{item}">
-					<view class="top-box-hd">{{item.num || 0}}</view>
-					<view class="content">{{item.title}}</view>
+					<view class="top-box-hd">{{ item.num || 0 }}</view>
+					<view class="content">{{ item.title }}</view>
 				</template>
 			</fs-divide-list>
 		</view>
-		
-		<fs-card gutter :titleStyle="{padding: '0'}">
+
+		<fs-card gutter :titleStyle="{ padding: '0' }">
 			<template #title>
-				<view class="title-hd" >常用工具</view>
+				<view class="title-hd">常用工具</view>
 			</template>
 			<fs-grid :columnNum="4">
 				<fs-grid-item v-for="(item, index) in 4" :key="index">
@@ -37,7 +37,7 @@
 				</fs-grid-item>
 			</fs-grid>
 		</fs-card>
-		
+
 		<fs-cell-group arrow border gutter>
 			<fs-cell link="/modules/common/licensePlate/list" value="车辆管理">
 				<template #title>
@@ -87,14 +87,12 @@
 <script setup>
 import { computed, ref } from 'vue'
 import { onShow } from '@dcloudio/uni-app'
-import useUser from '@/hooks/useUser'
+import { useUserStore } from '@/stores/user'
 import userAvatar from '/static/images/user-avatar.png'
 import wx from '@/business/wx-login.vue'
 
-const userInfo = ref('')
-onShow(() => {
-	userInfo.value = useUser()
-})
+const user = useUserStore()
+const userInfo = computed(() => user.userInfo)
 
 const shortcutList = ref([
 	{
@@ -111,39 +109,39 @@ const showLogin = ref(false)
 </script>
 
 <style lang="scss" scoped>
-.status-bar{
+.status-bar {
 	height: var(--status-bar-height);
 }
-.my-top{
+.my-top {
 	background-color: var(--primary);
 	padding: 60rpx var(--gutter) 0;
 	margin-bottom: var(--gutter);
 }
-.top-box{
+.top-box {
 	position: relative;
 	padding: 60rpx 0;
 	color: #fff;
-	
-	&-hd{
+
+	&-hd {
 		font-size: 23px;
 		font-weight: bold;
 	}
-	&-title{
+	&-title {
 		font-size: 16px;
 		font-weight: 500;
 		margin-bottom: 10rpx;
 	}
-	
-	&-content{
+
+	&-content {
 		padding: 10rpx 0;
 		margin-left: 20rpx;
 	}
 }
-.short-list{
+.short-list {
 	margin-top: -80rpx;
 	padding: var(--gutter);
 }
-.user-info{
+.user-info {
 	display: flex;
 }
 </style>

+ 20 - 16
pages/my/userInfo.vue

@@ -25,14 +25,15 @@
 </template>
 
 <script setup>
-import { ref, computed } from 'vue'
+import { ref, computed, getCurrentInstance } from 'vue'
 import useForm from '@/hooks/useForm'
 import useValidator from '@/hooks/useValidator'
-import useUser from '@/hooks/useUser'
+import { useUserStore } from '@/stores/user'
 import utils from '@/utils/utils'
 
+const user = useUserStore()
+const userInfo = computed(() => user.userInfo)
 const validator = useValidator()
-const userInfo = { ...useUser() }
 
 const rules = {
 	name: {
@@ -44,25 +45,28 @@ const rules = {
 const formRef = ref(null)
 const form = useForm(rules, 'formRef')
 
+const { proxy } = getCurrentInstance()
 const handleUpload = () => {
-	utils.chooseAndUploadImage(
-		{}, 
-		{
-			url: ''
-		}
-	).then(res => {
-		userInfo.photo = res
-	})
+	utils
+		.chooseAndUploadImage(
+			{},
+			{
+				url: proxy.$uploadUrl
+			}
+		)
+		.then(res => {
+			userInfo.value.photo = res
+		})
 }
 
 const handleSave = () => {
 	form.validate().then(() => {
-		console.log('success')
-		uni.navigateBack()
+		user.setUserInfo(userInfo.value)
+		uni.switchTab({
+			url: '/pages/my/my'
+		})
 	})
 }
 </script>
 
-<style lang="scss" scoped>
-
-</style>
+<style lang="scss" scoped></style>

+ 19 - 0
pnpm-lock.yaml

@@ -0,0 +1,19 @@
+lockfileVersion: 5.4
+
+specifiers:
+  async-validator: ^4.0.2
+  dayjs: ^1.10.6
+
+dependencies:
+  async-validator: 4.2.5
+  dayjs: 1.11.5
+
+packages:
+
+  /async-validator/4.2.5:
+    resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
+    dev: false
+
+  /dayjs/1.11.5:
+    resolution: {integrity: sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==}
+    dev: false

+ 69 - 69
services/common.js

@@ -1,79 +1,79 @@
-import http from '@/utils/http'
-
-// const appId = uni.getAccountInfoSync().miniProgram.appId
-
-export function loginByOpenId(data) {
-	return new Promise((resolve, reject) => {
-		uni.login({
-		  provider: 'weixin',
-		  success: function (res) {
-		    http.post('wxMini/login', {
-					code: res.code,
-				}, {
-		    	isAuth: false,
-		    	showLoading: false
-		    }).then(res => {
-					resolve(res)
-				}).catch(err => {
-					reject(err)
-				})
-		  }
-		})
+import http from '@/utils/http'
+
+// const appId = uni.getAccountInfoSync().miniProgram.appId
+
+export function loginByCode(data) {
+	return new Promise((resolve, reject) => {
+		uni.login({
+			provider: 'weixin',
+			success: function(res) {
+				http.post('wxMini/login', {
+					code: res.code,
+				}, {
+					isAuth: false,
+					showLoading: false
+				}).then(res => {
+					resolve(res)
+				}).catch(err => {
+					reject(err)
+				})
+			}
+		})
 	})
-}
+}
 export function login(data) {
 	return http.post('user/login', data)
-}
-export function wxLogin(data) {
-	return new Promise((resolve, reject) => {
-		uni.login({
-		  provider: 'weixin',
-		  success: function (res) {
-		    http.post('wxMini/authLogin', {
-					encryptedData: data.encryptedData,
-					ivStr: data.iv,
-					userInfo: JSON.stringify(data.userInfo),
-					code: res.code,
-				}, {
-		    	isAuth: false,
-		    	loadingTitle: '登录中...'
-		    }).then(res => {
-					resolve(res)
-				}).catch(err => {
-					reject(err)
-				})
-		  }
-		})
-	})
-}
+}
+export function wxLogin(data) {
+	return new Promise((resolve, reject) => {
+		uni.login({
+			provider: 'weixin',
+			success: function(res) {
+				http.post('wxMini/authLogin', {
+					encryptedData: data.encryptedData,
+					ivStr: data.iv,
+					userInfo: JSON.stringify(data.userInfo),
+					code: res.code,
+				}, {
+					isAuth: false,
+					loadingTitle: '登录中...'
+				}).then(res => {
+					resolve(res)
+				}).catch(err => {
+					reject(err)
+				})
+			}
+		})
+	})
+}
 export function logout(data) {
 	return http.post('user/logout', data)
-}
-
-
-// 意见反馈
+}
+
+
+// 意见反馈
 export function addAdvice(data) {
 	return http.post('user/advice', data)
-}
+}
 export function getAdviceList() {
 	return http.get('user/advice/list')
-}
-
-// 版本信息
-export function getVersionList(data) {
-	return http.get('user/version', data)
-}
-
-
-// 通讯录
-export function getAddrbookList() {
-	return http.get('user/advice/list')
-}
-
-// 协议、隐私
-export function getPolicy() {
-	return http.get('user/privacyPolicy')
-}
-export function getAgreement() {
-	return http.get('user/userServiceAgreement')
+}
+
+// 版本信息
+export function getVersionList(data) {
+	return http.get('user/version', data)
+}
+
+
+// 通讯录
+export function getAddrbookList() {
+	return http.get('user/advice/list')
+}
+
+// 协议、隐私
+export function getPolicy() {
+	return http.get('user/privacyPolicy')
+}
+export function getAgreement() {
+	return http.get('user/userServiceAgreement')
 }

+ 0 - 52
store/index.js

@@ -1,52 +0,0 @@
-import { createStore } from 'vuex'
-import { login, wxLogin, loginByOpenId, logout } from '../services/common'
-
-const store = createStore({
-  state: {
-    userInfo: uni.getStorageSync('userInfo'),
-		token: uni.getStorageSync('token')
-  },
-  mutations: {
-    setUserInfo(state, userInfo) {
-      state.userInfo = userInfo
-			uni.setStorageSync('userInfo', userInfo)
-    },
-		setToken(state, token) {
-			state.token = token
-			uni.setStorageSync('token', token)
-		}
-  },
-	actions: {
-		login({ commit }, data) {
-			return login(data).then(res => {
-				commit('setToken', res.token)
-				commit('setUserInfo', res.userInfo)
-			})
-		},
-		wxLogin({ commit }, data) {
-			return wxLogin(data).then(res => {
-				commit('setToken', res.token)
-				commit('setUserInfo', res.userInfo)
-			})
-		},
-		loginByOpenId({ commit }) {
-			return loginByOpenId().then(res => {
-				commit('setToken', res.token)
-				commit('setUserInfo', res.userInfo)
-			})
-		},
-		logout({ commit }) {
-			// return http.post('auth/user/logout').then(res => {
-			// 	commit('setToken', '')
-			// 	commit('setUserInfo', {})
-			// })
-			return new Promise(resolve => {
-				commit('setToken', '')
-				commit('setUserInfo', null)
-				resolve()
-			})
-		}
-	}
-})
-
-export default store

+ 7 - 0
stores/index.js

@@ -0,0 +1,7 @@
+import { createPinia } from 'pinia'
+
+const store = createPinia()
+
+export {
+	store
+}

+ 47 - 0
stores/user.js

@@ -0,0 +1,47 @@
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+import { login, loginByCode, logout } from '../services/common'
+
+export const useUserStore = defineStore('user', () => {
+	const userInfo = ref(uni.getStorageSync('userInfo') || { name: 'ming' })
+	const setUserInfo = data => {
+		userInfo.value = data
+		uni.setStorageSync('userInfo', data)
+	}
+
+	const token = ref(uni.getStorageSync('token') || '')
+	const setToken = data => {
+		token.value = data
+		uni.setStorageSync('token', data)
+	}
+
+	const login = data => {
+		return login(data).then(res => {
+			setUserInfo(res.userInfo)
+			setToken(res.token)
+		})
+	}
+	const loginByOpenId = data => {
+		return loginByCode().then(res => {
+			setUserInfo(res.userInfo)
+			setToken(res.token)
+		})
+	}
+	const logout = () => {
+		return new Promise(resolve => {
+			setUserInfo({})
+			setToken('')
+			resolve()
+		})
+	}
+
+	return {
+		userInfo,
+		setUserInfo,
+		token,
+		setToken,
+		login,
+		loginByOpenId,
+		logout
+	}
+})

+ 6 - 5
utils/config.js

@@ -1,13 +1,14 @@
-const baseUrl = process.env.NODE_ENV === 'development' ? 'http://johnny-ttj.vaiwan.com' : 'https://zhswapi.sxidc.com'
-
-const config = {
+const baseUrl = process.env.NODE_ENV === 'development' ? 'http://johnny-ttj.vaiwan.com' : 'https://zhswapi.sxidc.com'
+
+const config = {
 	baseUrl,
 	apiBaseUrl: baseUrl + '/api/',
+	uploadUrl: 'upload',
 	httpDefaultOption: {
-		showLoading: true,
+		showLoading: true,
 		showErrorMsg: true,
 		isAuth: true,
-	},
+	},
 	defaultErrorImg: ''
 }
 

+ 6 - 4
utils/http.js

@@ -1,8 +1,10 @@
-import store from '@/store'
+import { useUserStore } from '@/stores/user'
 import config from './config'
 import utils from './utils'
 
 const request = (method, url, data, opt) => {
+	const user = useUserStore()
+
 	return new Promise((resolve, reject) => {
 		opt.showLoading && uni.showLoading({
 			title: opt.loadingTitle,
@@ -13,7 +15,7 @@ const request = (method, url, data, opt) => {
 			method,
 			url: utils.isHttp(url) ? url : config.apiBaseUrl + url,
 			header: {
-				Authorization: store.state.token,
+				Authorization: user.token,
 				...opt.header
 			},
 			data
@@ -22,8 +24,8 @@ const request = (method, url, data, opt) => {
 
 			const data = res.data
 			if (data.code === 201) {
-				store.commit('setUserInfo', null)
-				store.commit('token', '')
+				user.setUserInfo({})
+				user.setToken('')
 
 				// opt.isAuth && uni.navigateTo({
 				// 	url: '/pages/login/login'