feat: 添加用户注册和密码登录功能,更新页面路由和样式
This commit is contained in:
parent
a38e1bd4e6
commit
77d24ecb54
2
App.vue
2
App.vue
@ -29,7 +29,7 @@
|
|||||||
if (this.envVersion === 'trial') {
|
if (this.envVersion === 'trial') {
|
||||||
return 'XHJ'
|
return 'XHJ'
|
||||||
}
|
}
|
||||||
return 'XHJ'
|
return 'DEV'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
12
api/system.js
Normal file
12
api/system.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import request from '../utils/request'
|
||||||
|
|
||||||
|
// system 系统模块
|
||||||
|
|
||||||
|
// 获取国家列表
|
||||||
|
export function getCountryListRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/system/listCountry',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
18
api/user.js
18
api/user.js
@ -65,6 +65,24 @@ export function loginRequest(data) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 密码登录
|
||||||
|
export function passwordLoginRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/register',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册
|
||||||
|
export function registerRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/login',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 注册
|
// 注册
|
||||||
export function phoneLoginRequest(data) {
|
export function phoneLoginRequest(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
15
components/verify/utils/ase.js
Normal file
15
components/verify/utils/ase.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import CryptoJS from 'crypto-js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @word 要加密的内容
|
||||||
|
* @keyWord String 服务器随机返回的关键字
|
||||||
|
* */
|
||||||
|
export function aesEncrypt(word, keyWord = 'XwKsGlMcdPMEhR1B') {
|
||||||
|
let key = CryptoJS.enc.Utf8.parse(keyWord)
|
||||||
|
let src = CryptoJS.enc.Utf8.parse(word)
|
||||||
|
let encrypted = CryptoJS.AES.encrypt(src, key, {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.Pkcs7
|
||||||
|
})
|
||||||
|
return encrypted.toString()
|
||||||
|
}
|
||||||
43
components/verify/utils/request.js
Normal file
43
components/verify/utils/request.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import env from '@/config/env'
|
||||||
|
|
||||||
|
export const myRequest = async (option = {}) => {
|
||||||
|
const envConfig = getApp().globalData.getEnvConfig()
|
||||||
|
const baseConfig = env[envConfig]
|
||||||
|
|
||||||
|
console.log('=== 请求入参 ===')
|
||||||
|
console.log('URL:', baseConfig.baseUrl + option.url)
|
||||||
|
console.log('Data:', JSON.stringify(option.data || {}, null, 2))
|
||||||
|
console.log('Method:', option.method || 'GET')
|
||||||
|
console.log('================')
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
uni.request({
|
||||||
|
url: baseConfig.baseUrl + option.url,
|
||||||
|
data: option.data || {},
|
||||||
|
method: option.method || 'GET',
|
||||||
|
timeout: 30000,
|
||||||
|
header: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
...option.header
|
||||||
|
},
|
||||||
|
success: result => {
|
||||||
|
console.log('=== 请求出参 ===')
|
||||||
|
console.log('StatusCode:', result.statusCode)
|
||||||
|
console.log('Response:', JSON.stringify(result.data, null, 2))
|
||||||
|
console.log('================')
|
||||||
|
|
||||||
|
if (result.statusCode === 200) {
|
||||||
|
resolve(result)
|
||||||
|
} else {
|
||||||
|
reject(new Error(`HTTP ${result.statusCode}: ${result.errMsg || 'Request failed'}`))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: error => {
|
||||||
|
console.log('=== 请求失败 ===')
|
||||||
|
console.log('Error:', error)
|
||||||
|
console.log('================')
|
||||||
|
reject(new Error(error.errMsg || 'Network request failed'))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
476
components/verify/verify.vue
Normal file
476
components/verify/verify.vue
Normal file
File diff suppressed because one or more lines are too long
781
components/verify/verifySlider/verifySlider.vue
Normal file
781
components/verify/verifySlider/verifySlider.vue
Normal file
File diff suppressed because one or more lines are too long
3
constant/reg.js
Normal file
3
constant/reg.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const PHONE_REG = /^\d{7,12}$/
|
||||||
|
export const EMAIL_REG = /^[\w.-]+@([\w-]+\.)+[\w-]{2,4}$/
|
||||||
|
export const PASSWORD_REG = /^(?!\d+$)(?![a-z]+$)(?![^0-9a-z]+$).{8,20}$/i
|
||||||
7
package-lock.json
generated
7
package-lock.json
generated
@ -5,6 +5,7 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
"pinia": "^2.2.0",
|
"pinia": "^2.2.0",
|
||||||
"pinia-plugin-unistorage": "^0.1.2",
|
"pinia-plugin-unistorage": "^0.1.2",
|
||||||
"uview-plus": "^3.3.12"
|
"uview-plus": "^3.3.12"
|
||||||
@ -3106,6 +3107,12 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crypto-js": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/css-functions-list": {
|
"node_modules/css-functions-list": {
|
||||||
"version": "3.2.3",
|
"version": "3.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz",
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
"pinia": "^2.2.0",
|
"pinia": "^2.2.0",
|
||||||
"pinia-plugin-unistorage": "^0.1.2",
|
"pinia-plugin-unistorage": "^0.1.2",
|
||||||
"uview-plus": "^3.3.12"
|
"uview-plus": "^3.3.12"
|
||||||
|
|||||||
45
pages.json
45
pages.json
@ -112,6 +112,36 @@
|
|||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "验证邮箱"
|
"navigationBarTitleText": "验证邮箱"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "login",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "登录"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "register",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "注册"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "forgotPassword",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "忘记密码"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "countryList",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "你所在的国家/地区"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "safeVerify",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "安全验证"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -593,22 +623,13 @@
|
|||||||
],
|
],
|
||||||
"preloadRule": {
|
"preloadRule": {
|
||||||
"pages/main/home": {
|
"pages/main/home": {
|
||||||
"packages": [
|
"packages": ["pages/others", "pages/addDevice", "pages/p2p"]
|
||||||
"pages/others",
|
|
||||||
"pages/addDevice",
|
|
||||||
"pages/p2p"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"pages/main/lockDetail": {
|
"pages/main/lockDetail": {
|
||||||
"packages": [
|
"packages": ["pages/feature", "pages/setting"]
|
||||||
"pages/feature",
|
|
||||||
"pages/setting"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"pages/main/mine": {
|
"pages/main/mine": {
|
||||||
"packages": [
|
"packages": ["pages/user"]
|
||||||
"pages/user"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
|
|||||||
@ -408,6 +408,12 @@
|
|||||||
homeLogin() {
|
homeLogin() {
|
||||||
const that = this
|
const that = this
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
that.routeJump({
|
||||||
|
name: 'login',
|
||||||
|
type: 'reLaunch'
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
uni.login({
|
uni.login({
|
||||||
provider: 'weixin',
|
provider: 'weixin',
|
||||||
|
|||||||
97
pages/user/countryList.vue
Normal file
97
pages/user/countryList.vue
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<view class="flex flex-col" style="height: 100vh">
|
||||||
|
<view class="flex-shrink-0 p-4">
|
||||||
|
<up-input
|
||||||
|
v-model="searchKeyword"
|
||||||
|
placeholder="搜索"
|
||||||
|
:customStyle="{
|
||||||
|
padding: '0 16rpx',
|
||||||
|
height: '80rpx',
|
||||||
|
backgroundColor: '#f4f4f4'
|
||||||
|
}"
|
||||||
|
border="surround"
|
||||||
|
clearable
|
||||||
|
@input="onSearch"
|
||||||
|
></up-input>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="flex-1" style="overflow: hidden">
|
||||||
|
<up-index-list :index-list="indexList" :sticky="true">
|
||||||
|
<up-index-item
|
||||||
|
v-for="(item, index) in countryList"
|
||||||
|
:key="index"
|
||||||
|
v-show="getFilteredGroup(item).length > 0"
|
||||||
|
>
|
||||||
|
<up-index-anchor :text="indexList[index]"></up-index-anchor>
|
||||||
|
<view
|
||||||
|
v-for="country in getFilteredGroup(item)"
|
||||||
|
:key="country.id"
|
||||||
|
class="px-4 py-2.5 border-b border-gray-2"
|
||||||
|
@click="handleCountryClick(country)"
|
||||||
|
>
|
||||||
|
{{ country.name }}
|
||||||
|
</view>
|
||||||
|
</up-index-item>
|
||||||
|
<view style="padding-bottom: calc(300rpx + env(safe-area-inset-bottom))"></view>
|
||||||
|
</up-index-list>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, getCurrentInstance } from 'vue'
|
||||||
|
import { getCountryListRequest } from '@/api/system'
|
||||||
|
|
||||||
|
const instance = getCurrentInstance().proxy
|
||||||
|
const eventChannel = instance.getOpenerEventChannel()
|
||||||
|
|
||||||
|
const indexList = ref(['★', ...Array.from({ length: 26 }, (_, i) => String.fromCharCode(65 + i))])
|
||||||
|
|
||||||
|
const countryList = ref(new Array(27).fill().map(() => []))
|
||||||
|
const searchKeyword = ref('')
|
||||||
|
|
||||||
|
const getFilteredGroup = group => {
|
||||||
|
if (!searchKeyword.value) return group
|
||||||
|
const keyword = searchKeyword.value.toLowerCase()
|
||||||
|
return group.filter(country => country.name.toLowerCase().includes(keyword))
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSearch = () => {}
|
||||||
|
|
||||||
|
const getCountryList = async () => {
|
||||||
|
uni.showLoading({ title: '加载中...' })
|
||||||
|
try {
|
||||||
|
const { code, data, message } = await getCountryListRequest()
|
||||||
|
if (code === 0) {
|
||||||
|
const newGroups = data
|
||||||
|
.filter(item => !indexList.value.includes(item.group))
|
||||||
|
.map(item => item.group)
|
||||||
|
.filter((group, index, arr) => arr.indexOf(group) === index)
|
||||||
|
|
||||||
|
indexList.value = [...indexList.value, ...newGroups]
|
||||||
|
countryList.value = new Array(indexList.value.length).fill().map(() => [])
|
||||||
|
|
||||||
|
if (data.length > 0) countryList.value[0].push(data[0])
|
||||||
|
|
||||||
|
data.forEach(item => {
|
||||||
|
const groupIndex = indexList.value.indexOf(item.group)
|
||||||
|
if (groupIndex !== -1) countryList.value[groupIndex].push(item)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({ title: message, icon: 'none' })
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
uni.showToast({ title: '获取国家列表失败', icon: 'none' })
|
||||||
|
} finally {
|
||||||
|
uni.hideLoading()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => getCountryList())
|
||||||
|
|
||||||
|
const handleCountryClick = country => {
|
||||||
|
eventChannel.emit('country', country)
|
||||||
|
uni.navigateBack()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
5
pages/user/forgotPassword.vue
Normal file
5
pages/user/forgotPassword.vue
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<view>忘记密码</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup></script>
|
||||||
170
pages/user/login.vue
Normal file
170
pages/user/login.vue
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="mx-4 mt-10 text-base">
|
||||||
|
<view class="font-bold text-2xl">欢迎使用星星锁</view>
|
||||||
|
<view class="mt-4 flex items-center w-full" @click="toJump('countryList')">
|
||||||
|
<view class="w-200">国家/地区</view>
|
||||||
|
<view class="text-#63b8af">{{ country.name }} +{{ country.code }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="mt-4">
|
||||||
|
<up-input
|
||||||
|
fontSize="32rpx"
|
||||||
|
:placeholderStyle="{
|
||||||
|
color: '#333333',
|
||||||
|
fontSize: '32rpx'
|
||||||
|
}"
|
||||||
|
placeholder="请输入手机号或邮箱"
|
||||||
|
:customStyle="{
|
||||||
|
padding: '0',
|
||||||
|
height: '80rpx'
|
||||||
|
}"
|
||||||
|
border="bottom"
|
||||||
|
clearable
|
||||||
|
v-model="username"
|
||||||
|
:maxlength="50"
|
||||||
|
@change="handleUsernameInput"
|
||||||
|
></up-input>
|
||||||
|
</view>
|
||||||
|
<view class="mt-4">
|
||||||
|
<up-input
|
||||||
|
fontSize="32rpx"
|
||||||
|
:placeholderStyle="{
|
||||||
|
color: '#333333',
|
||||||
|
fontSize: '32rpx'
|
||||||
|
}"
|
||||||
|
:customStyle="{
|
||||||
|
padding: '0',
|
||||||
|
height: '80rpx'
|
||||||
|
}"
|
||||||
|
placeholder="请输入内容"
|
||||||
|
type="password"
|
||||||
|
border="bottom"
|
||||||
|
clearable
|
||||||
|
v-model="password"
|
||||||
|
:maxlength="20"
|
||||||
|
@change="handlePasswordInput"
|
||||||
|
></up-input>
|
||||||
|
</view>
|
||||||
|
<view class="mt-4 flex items-center text-sm" @click="agreeAgreement">
|
||||||
|
<image
|
||||||
|
class="w-35 h-35"
|
||||||
|
v-if="select"
|
||||||
|
src="https://oss-lock.xhjcn.ltd/mp/icon_select.png"
|
||||||
|
></image>
|
||||||
|
<image
|
||||||
|
v-else
|
||||||
|
class="w-35 h-35"
|
||||||
|
src="https://oss-lock.xhjcn.ltd/mp/icon_not_select.png"
|
||||||
|
></image>
|
||||||
|
<view class="ml-2">
|
||||||
|
我已阅读并同意
|
||||||
|
<span class="text-#63b8af" @click="toWebview('userAgreement')">《用户协议》 </span>
|
||||||
|
<span class="text-#63b8af" @click="toWebview('privacy')">《隐私协议》</span>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="mt-4 w-full rounded-full h-88 text-center leading-[88rpx] text-white"
|
||||||
|
:class="[canLogin ? 'bg-#63b8af' : 'bg-#9d9da1']"
|
||||||
|
@click="login"
|
||||||
|
>
|
||||||
|
登录
|
||||||
|
</view>
|
||||||
|
<view class="mt-4 mx-2 flex items-center justify-between">
|
||||||
|
<view class="text-#63b8af" @click="toJump('forgotPassword')">忘记密码</view>
|
||||||
|
<view class="text-#63b8af" @click="toJump('register')">注册</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import { useBasicStore } from '@/stores/basic'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
import { PHONE_REG, EMAIL_REG, PASSWORD_REG } from '@/constant/reg'
|
||||||
|
|
||||||
|
const $basic = useBasicStore()
|
||||||
|
const $user = useUserStore()
|
||||||
|
|
||||||
|
const country = ref({
|
||||||
|
countryId: 0,
|
||||||
|
name: '中国',
|
||||||
|
code: '86',
|
||||||
|
flag: 'https://lock.xhjcn.ltd/storage/country-flags/86.png',
|
||||||
|
abbreviation: 'CN',
|
||||||
|
group: 'Z'
|
||||||
|
})
|
||||||
|
const username = ref('')
|
||||||
|
const password = ref('')
|
||||||
|
|
||||||
|
const select = ref(false)
|
||||||
|
|
||||||
|
const isValidUsername = computed(() => {
|
||||||
|
if (!username.value) return false
|
||||||
|
return PHONE_REG.test(username.value) || EMAIL_REG.test(username.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
const isValidPassword = computed(() => {
|
||||||
|
if (!password.value) return false
|
||||||
|
return PASSWORD_REG.test(password.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
const canLogin = computed(() => {
|
||||||
|
return isValidUsername.value && isValidPassword.value
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleUsernameInput = text => {
|
||||||
|
username.value = text
|
||||||
|
}
|
||||||
|
const handlePasswordInput = text => {
|
||||||
|
password.value = text
|
||||||
|
}
|
||||||
|
|
||||||
|
const agreeAgreement = () => {
|
||||||
|
select.value = !select.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const toJump = path => {
|
||||||
|
$basic.routeJump({
|
||||||
|
name: path,
|
||||||
|
events: {
|
||||||
|
country(data) {
|
||||||
|
country.value = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const toWebview = type => {
|
||||||
|
$basic.routeJump({
|
||||||
|
name: 'webview',
|
||||||
|
params: {
|
||||||
|
type
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const login = async () => {
|
||||||
|
if (!canLogin.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!select.value) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请先同意用户协议及隐私协议',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const res = await $user.passwordLogin({
|
||||||
|
username: username.value,
|
||||||
|
password: password.value,
|
||||||
|
countryCode: country.value.code
|
||||||
|
})
|
||||||
|
if (res) {
|
||||||
|
$basic.routeJump({
|
||||||
|
name: 'home',
|
||||||
|
type: 'reLaunch'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
317
pages/user/register.vue
Normal file
317
pages/user/register.vue
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<up-tabs
|
||||||
|
:list="list"
|
||||||
|
@click="click"
|
||||||
|
class="mx-4"
|
||||||
|
lineWidth="300rpx"
|
||||||
|
lineColor="#63b8af"
|
||||||
|
:activeStyle="{
|
||||||
|
color: '#63b8af',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
transform: 'scale(1.05)'
|
||||||
|
}"
|
||||||
|
itemStyle="width: 343rpx;height: 108rpx;font-size: 32rpx"
|
||||||
|
></up-tabs>
|
||||||
|
<view class="mx-6 mt-10">
|
||||||
|
<view class="mt-4 flex items-center w-full" @click="toJump('countryList')">
|
||||||
|
<view class="w-200">国家/地区</view>
|
||||||
|
<view class="text-#63b8af">
|
||||||
|
{{ country.name }}
|
||||||
|
<span v-if="type === 1">+{{ country.code }}</span>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="mt-4">
|
||||||
|
<up-input
|
||||||
|
:placeholder="type === 1 ? '请输入手机号' : '请输入邮箱'"
|
||||||
|
fontSize="32rpx"
|
||||||
|
:placeholderStyle="{
|
||||||
|
color: '#333333',
|
||||||
|
fontSize: '32rpx'
|
||||||
|
}"
|
||||||
|
:customStyle="{
|
||||||
|
padding: '0',
|
||||||
|
height: '80rpx'
|
||||||
|
}"
|
||||||
|
border="bottom"
|
||||||
|
clearable
|
||||||
|
v-model="username"
|
||||||
|
:maxlength="50"
|
||||||
|
@change="handleUsernameInput"
|
||||||
|
></up-input>
|
||||||
|
</view>
|
||||||
|
<view class="mt-4">
|
||||||
|
<up-input
|
||||||
|
fontSize="32rpx"
|
||||||
|
:placeholderStyle="{
|
||||||
|
color: '#333333',
|
||||||
|
fontSize: '32rpx'
|
||||||
|
}"
|
||||||
|
:customStyle="{
|
||||||
|
padding: '0',
|
||||||
|
height: '80rpx'
|
||||||
|
}"
|
||||||
|
placeholder="请输入内容"
|
||||||
|
type="password"
|
||||||
|
border="bottom"
|
||||||
|
clearable
|
||||||
|
v-model="password"
|
||||||
|
:maxlength="20"
|
||||||
|
@change="handlePasswordInput"
|
||||||
|
></up-input>
|
||||||
|
<view class="text-#999999 text-sm mt-1">
|
||||||
|
密码必须是8-20位,至少包括数字/字母/符号中的2种
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="mt-4">
|
||||||
|
<up-input
|
||||||
|
fontSize="32rpx"
|
||||||
|
:placeholderStyle="{
|
||||||
|
color: '#333333',
|
||||||
|
fontSize: '32rpx'
|
||||||
|
}"
|
||||||
|
:customStyle="{
|
||||||
|
padding: '0',
|
||||||
|
height: '80rpx'
|
||||||
|
}"
|
||||||
|
placeholder="确认密码"
|
||||||
|
type="password"
|
||||||
|
border="bottom"
|
||||||
|
clearable
|
||||||
|
v-model="confirmPassword"
|
||||||
|
:maxlength="20"
|
||||||
|
@change="handleConfirmPasswordInput"
|
||||||
|
></up-input>
|
||||||
|
</view>
|
||||||
|
<view class="mt-4 flex items-center">
|
||||||
|
<up-input
|
||||||
|
fontSize="32rpx"
|
||||||
|
:placeholderStyle="{
|
||||||
|
color: '#333333',
|
||||||
|
fontSize: '32rpx'
|
||||||
|
}"
|
||||||
|
:customStyle="{
|
||||||
|
padding: '0',
|
||||||
|
height: '80rpx'
|
||||||
|
}"
|
||||||
|
placeholder="请输入验证码"
|
||||||
|
type="password"
|
||||||
|
border="bottom"
|
||||||
|
clearable
|
||||||
|
v-model="code"
|
||||||
|
:maxlength="20"
|
||||||
|
@change="handleCodeInput"
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<up-button @tap="getCode" :disabled="!canGetCode" color="#63b8af">
|
||||||
|
{{ tips }}
|
||||||
|
</up-button>
|
||||||
|
<up-code
|
||||||
|
:seconds="seconds"
|
||||||
|
ref="uCodeRef"
|
||||||
|
changeText="X秒后重新获取"
|
||||||
|
endText="获取验证码"
|
||||||
|
@change="codeChange"
|
||||||
|
></up-code
|
||||||
|
></template>
|
||||||
|
</up-input>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="my-6 flex items-center text-sm" @click="agreeAgreement">
|
||||||
|
<image
|
||||||
|
class="w-35 h-35"
|
||||||
|
v-if="select"
|
||||||
|
src="https://oss-lock.xhjcn.ltd/mp/icon_select.png"
|
||||||
|
></image>
|
||||||
|
<image
|
||||||
|
v-else
|
||||||
|
class="w-35 h-35"
|
||||||
|
src="https://oss-lock.xhjcn.ltd/mp/icon_not_select.png"
|
||||||
|
></image>
|
||||||
|
<view class="ml-2">
|
||||||
|
我已阅读并同意
|
||||||
|
<span class="text-#63b8af" @click="toWebview('userAgreement')">《用户协议》 </span>
|
||||||
|
<span class="text-#63b8af" @click="toWebview('privacy')">《隐私协议》</span>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="w-full rounded-full h-88 text-center leading-[88rpx] text-white"
|
||||||
|
:class="[canRegister ? 'bg-#63b8af' : 'bg-#9d9da1']"
|
||||||
|
@click="register"
|
||||||
|
>
|
||||||
|
注册
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed, onMounted } from 'vue'
|
||||||
|
import { useBasicStore } from '@/stores/basic'
|
||||||
|
import { PHONE_REG, EMAIL_REG, PASSWORD_REG } from '@/constant/reg'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
|
const $basic = useBasicStore()
|
||||||
|
const $user = useUserStore()
|
||||||
|
|
||||||
|
const list = ref([
|
||||||
|
{ name: '手机', receiverType: 1 },
|
||||||
|
{ name: '邮箱', receiverType: 2 }
|
||||||
|
])
|
||||||
|
|
||||||
|
const type = ref(1)
|
||||||
|
const username = ref('')
|
||||||
|
const password = ref('')
|
||||||
|
const confirmPassword = ref('')
|
||||||
|
const code = ref('')
|
||||||
|
|
||||||
|
const tips = ref('')
|
||||||
|
const seconds = ref(120)
|
||||||
|
const uCodeRef = ref(null)
|
||||||
|
const select = ref(false)
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const res = await $basic.getDeviceInfo()
|
||||||
|
if (res.language !== 'zh-CN') {
|
||||||
|
list.value.reverse()
|
||||||
|
type.value = 2
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const codeChange = text => {
|
||||||
|
tips.value = text
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCode = () => {
|
||||||
|
if (!uCodeRef.value.canGetCode) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const params = {
|
||||||
|
account: username.value,
|
||||||
|
codeType: 1,
|
||||||
|
channel: type.value,
|
||||||
|
countryCode: country.value.code
|
||||||
|
}
|
||||||
|
$basic.routeJump({
|
||||||
|
name: 'safeVerify',
|
||||||
|
events: {
|
||||||
|
successEvent() {
|
||||||
|
uCodeRef.value.start()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const country = ref({
|
||||||
|
countryId: 0,
|
||||||
|
name: '中国',
|
||||||
|
code: '86',
|
||||||
|
flag: 'https://lock.xhjcn.ltd/storage/country-flags/86.png',
|
||||||
|
abbreviation: 'CN',
|
||||||
|
group: 'Z'
|
||||||
|
})
|
||||||
|
|
||||||
|
const isValidUsername = computed(() => {
|
||||||
|
if (!username.value) return false
|
||||||
|
if (type.value === 1) {
|
||||||
|
return PHONE_REG.test(username.value)
|
||||||
|
}
|
||||||
|
return EMAIL_REG.test(username.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
const isValidPassword = computed(() => {
|
||||||
|
if (!password.value) return false
|
||||||
|
return PASSWORD_REG.test(password.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
const isValidConfirmPassword = computed(() => {
|
||||||
|
if (!confirmPassword.value) return false
|
||||||
|
return confirmPassword.value === password.value
|
||||||
|
})
|
||||||
|
|
||||||
|
const isValidCode = computed(() => {
|
||||||
|
if (!code.value) return false
|
||||||
|
return code.value.length === 6
|
||||||
|
})
|
||||||
|
|
||||||
|
const canGetCode = computed(() => {
|
||||||
|
return isValidUsername.value
|
||||||
|
})
|
||||||
|
|
||||||
|
const canRegister = computed(() => {
|
||||||
|
return (
|
||||||
|
isValidUsername.value &&
|
||||||
|
isValidPassword.value &&
|
||||||
|
isValidConfirmPassword.value &&
|
||||||
|
isValidCode.value
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const agreeAgreement = () => {
|
||||||
|
select.value = !select.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const register = async () => {
|
||||||
|
if (!canRegister.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!select.value) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请先同意用户协议及隐私协议',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const res = await $user.register({
|
||||||
|
account: username.value,
|
||||||
|
password: password.value,
|
||||||
|
receiverType: type.value,
|
||||||
|
countryCode: country.value.code,
|
||||||
|
verificationCode: code.value
|
||||||
|
})
|
||||||
|
if (res) {
|
||||||
|
$basic.routeJump({
|
||||||
|
name: 'home',
|
||||||
|
type: 'reLaunch'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const click = item => {
|
||||||
|
type.value = item.receiverType
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUsernameInput = text => {
|
||||||
|
username.value = text
|
||||||
|
}
|
||||||
|
const handlePasswordInput = text => {
|
||||||
|
password.value = text
|
||||||
|
}
|
||||||
|
const handleConfirmPasswordInput = text => {
|
||||||
|
confirmPassword.value = text
|
||||||
|
}
|
||||||
|
const handleCodeInput = text => {
|
||||||
|
code.value = text
|
||||||
|
}
|
||||||
|
|
||||||
|
const toJump = path => {
|
||||||
|
$basic.routeJump({
|
||||||
|
name: path,
|
||||||
|
events: {
|
||||||
|
country(data) {
|
||||||
|
country.value = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const toWebview = type => {
|
||||||
|
$basic.routeJump({
|
||||||
|
name: 'webview',
|
||||||
|
params: {
|
||||||
|
type
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
52
pages/user/safeVerify.vue
Normal file
52
pages/user/safeVerify.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="main">
|
||||||
|
<view v-if="params" class="content">
|
||||||
|
<verify
|
||||||
|
:imgSize="{ width: '330px', height: '155px' }"
|
||||||
|
:mode="'fixed'"
|
||||||
|
:params="params"
|
||||||
|
captchaType="blockPuzzle"
|
||||||
|
@success="success"
|
||||||
|
></verify>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { getCurrentInstance, ref } from 'vue'
|
||||||
|
import verify from '@/components/verify/verify.vue'
|
||||||
|
|
||||||
|
const instance = getCurrentInstance().proxy
|
||||||
|
const eventChannel = instance.getOpenerEventChannel()
|
||||||
|
|
||||||
|
const params = ref(null)
|
||||||
|
|
||||||
|
onLoad(async options => {
|
||||||
|
params.value = options
|
||||||
|
})
|
||||||
|
|
||||||
|
const success = result => {
|
||||||
|
eventChannel.emit('successEvent', result || {})
|
||||||
|
uni.navigateBack()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background: $uni-bg-color;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.main {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -246,47 +246,47 @@
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.view {
|
.view {
|
||||||
margin-top: 32rpx;
|
|
||||||
border-radius: 32rpx;
|
|
||||||
width: 710rpx;
|
width: 710rpx;
|
||||||
|
margin-top: 32rpx;
|
||||||
margin-left: 20rpx;
|
margin-left: 20rpx;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
|
border-radius: 32rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.view-button {
|
.view-button {
|
||||||
padding: 0 20rpx 0 40rpx;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #292826;
|
justify-content: space-between;
|
||||||
|
padding: 0 20rpx 0 40rpx;
|
||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 80rpx;
|
line-height: 80rpx;
|
||||||
|
color: #292826;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
text-align: right;
|
|
||||||
width: 400rpx;
|
width: 400rpx;
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
margin-right: 20rpx;
|
margin-right: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
text-align: right;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name-info {
|
.name-info {
|
||||||
|
width: 520rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
line-height: 40rpx;
|
line-height: 40rpx;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
width: 520rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
margin-right: 20rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-dot {
|
.red-dot {
|
||||||
margin-right: 20rpx;
|
|
||||||
background: #ec433c;
|
|
||||||
width: 20rpx;
|
width: 20rpx;
|
||||||
height: 20rpx;
|
height: 20rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
background: #ec433c;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,9 +304,9 @@
|
|||||||
.avatar {
|
.avatar {
|
||||||
width: 80rpx;
|
width: 80rpx;
|
||||||
height: 80rpx;
|
height: 80rpx;
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 20rpx;
|
|
||||||
margin-top: 20rpx;
|
margin-top: 20rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -406,11 +406,36 @@ const pages = [
|
|||||||
name: 'videoEdit',
|
name: 'videoEdit',
|
||||||
path: '/pages/p2p/videoEdit',
|
path: '/pages/p2p/videoEdit',
|
||||||
tabBar: false
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'login',
|
||||||
|
path: '/pages/user/login',
|
||||||
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'register',
|
||||||
|
path: '/pages/user/register',
|
||||||
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'forgotPassword',
|
||||||
|
path: '/pages/user/forgotPassword',
|
||||||
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'countryList',
|
||||||
|
path: '/pages/user/countryList',
|
||||||
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'safeVerify',
|
||||||
|
path: '/pages/user/safeVerify',
|
||||||
|
tabBar: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
export const useBasicStore = defineStore('basic', {
|
export const useBasicStore = defineStore('basic', {
|
||||||
state () {
|
state() {
|
||||||
return {
|
return {
|
||||||
// 设备信息
|
// 设备信息
|
||||||
deviceInfo: null,
|
deviceInfo: null,
|
||||||
@ -424,7 +449,7 @@ export const useBasicStore = defineStore('basic', {
|
|||||||
// 路由跳转
|
// 路由跳转
|
||||||
/* data 入参 name string页面名称 type string跳转方式 params object传递参数 delta number返回页面数
|
/* data 入参 name string页面名称 type string跳转方式 params object传递参数 delta number返回页面数
|
||||||
* 具体入参查看文档 https://www.uviewui.com/js/route.html */
|
* 具体入参查看文档 https://www.uviewui.com/js/route.html */
|
||||||
routeJump (data) {
|
routeJump(data) {
|
||||||
const page = pages.find(page => {
|
const page = pages.find(page => {
|
||||||
return page.name === data.name
|
return page.name === data.name
|
||||||
})
|
})
|
||||||
@ -453,10 +478,10 @@ export const useBasicStore = defineStore('basic', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 获取当前网络状态
|
// 获取当前网络状态
|
||||||
getNetworkType () {
|
getNetworkType() {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
uni.getNetworkType({
|
uni.getNetworkType({
|
||||||
success (res) {
|
success(res) {
|
||||||
if (res.networkType === 'none') {
|
if (res.networkType === 'none') {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '网络访问失败,请检查网络是否正常',
|
title: '网络访问失败,请检查网络是否正常',
|
||||||
@ -467,14 +492,14 @@ export const useBasicStore = defineStore('basic', {
|
|||||||
}
|
}
|
||||||
resolve(true)
|
resolve(true)
|
||||||
},
|
},
|
||||||
fail () {
|
fail() {
|
||||||
resolve(false)
|
resolve(false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 获取设备信息
|
// 获取设备信息
|
||||||
getDeviceInfo () {
|
getDeviceInfo() {
|
||||||
const that = this
|
const that = this
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
if (that.deviceInfo?.model) {
|
if (that.deviceInfo?.model) {
|
||||||
@ -482,29 +507,31 @@ export const useBasicStore = defineStore('basic', {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
uni.getSystemInfo({
|
uni.getSystemInfo({
|
||||||
success (res) {
|
success(res) {
|
||||||
that.deviceInfo = res
|
that.deviceInfo = res
|
||||||
resolve(that.deviceInfo)
|
resolve(that.deviceInfo)
|
||||||
},
|
},
|
||||||
fail () {
|
fail() {
|
||||||
resolve({})
|
resolve({})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 获取胶囊信息
|
// 获取胶囊信息
|
||||||
getButtonInfo () {
|
getButtonInfo() {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
if (this.buttonInfo?.top) {
|
if (this.buttonInfo?.top) {
|
||||||
resolve(this.buttonInfo)
|
resolve(this.buttonInfo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.buttonInfo = uni.getMenuButtonBoundingClientRect()
|
this.buttonInfo = uni.getMenuButtonBoundingClientRect()
|
||||||
|
// #endif
|
||||||
resolve(this.buttonInfo)
|
resolve(this.buttonInfo)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 计算字符串长度
|
// 计算字符串长度
|
||||||
calculateStringTotalWidth (str) {
|
calculateStringTotalWidth(str) {
|
||||||
let totalWidth = 0
|
let totalWidth = 0
|
||||||
// 遍历字符串中的每一个字符
|
// 遍历字符串中的每一个字符
|
||||||
for (let i = 0; i < str.length; i++) {
|
for (let i = 0; i < str.length; i++) {
|
||||||
@ -521,10 +548,10 @@ export const useBasicStore = defineStore('basic', {
|
|||||||
return totalWidth
|
return totalWidth
|
||||||
},
|
},
|
||||||
// 回退页面并弹出toast提示
|
// 回退页面并弹出toast提示
|
||||||
backAndToast (message, delta = 1) {
|
backAndToast(message, delta = 1) {
|
||||||
uni.navigateBack({
|
uni.navigateBack({
|
||||||
delta,
|
delta,
|
||||||
complete () {
|
complete() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: message,
|
title: message,
|
||||||
@ -535,7 +562,7 @@ export const useBasicStore = defineStore('basic', {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 分享跳转
|
// 分享跳转
|
||||||
shareJump (data = this.shareConfig) {
|
shareJump(data = this.shareConfig) {
|
||||||
if (data.path) {
|
if (data.path) {
|
||||||
const target = data.path.split('/')
|
const target = data.path.split('/')
|
||||||
if (target.length > 1) {
|
if (target.length > 1) {
|
||||||
@ -563,7 +590,7 @@ export const useBasicStore = defineStore('basic', {
|
|||||||
}
|
}
|
||||||
this.shareConfig = data
|
this.shareConfig = data
|
||||||
|
|
||||||
function getParams (params) {
|
function getParams(params) {
|
||||||
let paramStr = ''
|
let paramStr = ''
|
||||||
Object.keys(params).forEach(item => {
|
Object.keys(params).forEach(item => {
|
||||||
if (paramStr === '') {
|
if (paramStr === '') {
|
||||||
|
|||||||
@ -2,10 +2,17 @@
|
|||||||
* @description 用户信息数据持久化
|
* @description 用户信息数据持久化
|
||||||
*/
|
*/
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { getUserInfoRequest, getWebUrlRequest, loginRequest, phoneLoginRequest } from '@/api/user'
|
import {
|
||||||
|
getUserInfoRequest,
|
||||||
|
getWebUrlRequest,
|
||||||
|
loginRequest,
|
||||||
|
phoneLoginRequest,
|
||||||
|
registerRequest
|
||||||
|
} from '@/api/user'
|
||||||
import { useLockStore } from '@/stores/lock'
|
import { useLockStore } from '@/stores/lock'
|
||||||
import { setStorage, getStorage } from '@/utils/storage'
|
import { setStorage, getStorage } from '@/utils/storage'
|
||||||
import { useNotificationStore } from '@/stores/notification'
|
import { useNotificationStore } from '@/stores/notification'
|
||||||
|
import { useBasicStore } from '@/stores/basic'
|
||||||
|
|
||||||
export const useUserStore = defineStore('user', {
|
export const useUserStore = defineStore('user', {
|
||||||
state() {
|
state() {
|
||||||
@ -34,6 +41,65 @@ export const useUserStore = defineStore('user', {
|
|||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
},
|
},
|
||||||
|
async register(params) {
|
||||||
|
const { account, password, receiverType, countryCode, verificationCode } = params
|
||||||
|
const $basic = useBasicStore()
|
||||||
|
const deviceInfo = await $basic.getDeviceInfo()
|
||||||
|
const info = {
|
||||||
|
deviceBrand: deviceInfo.deviceBrand,
|
||||||
|
deviceId: deviceInfo.deviceId,
|
||||||
|
deviceModel: deviceInfo.deviceModel,
|
||||||
|
model: deviceInfo.model,
|
||||||
|
system: deviceInfo.system
|
||||||
|
}
|
||||||
|
const { code, data, message } = await registerRequest({
|
||||||
|
receiverType,
|
||||||
|
countryCode,
|
||||||
|
account,
|
||||||
|
password,
|
||||||
|
verificationCode,
|
||||||
|
platId: 2,
|
||||||
|
deviceInfo: info
|
||||||
|
})
|
||||||
|
if (code === 0) {
|
||||||
|
setStorage('token', data.accessToken)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
async passwordLogin(params) {
|
||||||
|
const { username, password, countryCode } = params
|
||||||
|
const $basic = useBasicStore()
|
||||||
|
const deviceInfo = await $basic.getDeviceInfo()
|
||||||
|
const info = {
|
||||||
|
deviceBrand: deviceInfo.deviceBrand,
|
||||||
|
deviceId: deviceInfo.deviceId,
|
||||||
|
deviceModel: deviceInfo.deviceModel,
|
||||||
|
model: deviceInfo.model,
|
||||||
|
system: deviceInfo.system
|
||||||
|
}
|
||||||
|
const { code, data, message } = await registerRequest({
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
countryCode,
|
||||||
|
loginType: 1,
|
||||||
|
platId: 2,
|
||||||
|
deviceInfo: info
|
||||||
|
})
|
||||||
|
if (code === 0) {
|
||||||
|
setStorage('token', data.accessToken)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
},
|
||||||
async phoneLogin(params) {
|
async phoneLogin(params) {
|
||||||
const { iv, encryptedData, code: js_code } = params
|
const { iv, encryptedData, code: js_code } = params
|
||||||
const openid = await getStorage('openid')
|
const openid = await getStorage('openid')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user