wui-components-v2 1.1.24 → 1.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/form-control/form-control.vue +3 -3
- package/components/login-form/login-form.vue +1 -10
- package/components/login-form-box/login-form-box.vue +65 -0
- package/components/phone-login-form/phone-login-form.vue +204 -0
- package/components/wui-login/wui-login.vue +4 -2
- package/components/wui-login1/wui-login.vue +4 -3
- package/package.json +1 -1
|
@@ -37,8 +37,8 @@ const form = ref<any>(null)
|
|
|
37
37
|
const model = ref<any>({})
|
|
38
38
|
const fields = computed(() => {
|
|
39
39
|
return props.fieldGroup?.fields.filter((item) => {
|
|
40
|
-
|
|
41
|
-
return !item.title?.endsWith('y')// 排除字符串的最后一个字符为y的项
|
|
40
|
+
return item
|
|
41
|
+
// return !item.title?.endsWith('y')// 排除字符串的最后一个字符为y的项
|
|
42
42
|
})
|
|
43
43
|
})
|
|
44
44
|
// 初始化表单数据
|
|
@@ -275,7 +275,7 @@ defineExpose({
|
|
|
275
275
|
@success="(e) => { handleFileChange(e, item) }"
|
|
276
276
|
/>
|
|
277
277
|
</wd-cell>
|
|
278
|
-
<wd-cell v-else-if="ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relselect'" :prop="item.sourceId" :title="item.title" title-width="100px">
|
|
278
|
+
<wd-cell v-else-if="ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relselect'" :style="{ display: item.title?.includes('y') ? 'none' : null }" :prop="item.sourceId" :title="item.title" title-width="100px">
|
|
279
279
|
<mulselectPicker v-model="model[item.sourceId]" :source-id="item.sourceId" :title="item.title" :ext-control-type="Number(item.max) === 1 ? 'relselect' : 'ss' " :readonly="item.disabled" :clearable="!item.disabled" />
|
|
280
280
|
</wd-cell>
|
|
281
281
|
<wd-cell v-else-if="ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relselectvalue'" :prop="item.sourceId" :title="item.title" title-width="100px">
|
|
@@ -15,7 +15,6 @@ const props = defineProps<Props>()
|
|
|
15
15
|
// 定义 Props 类型
|
|
16
16
|
interface Props {
|
|
17
17
|
tabbarItems: TabbarItem[]
|
|
18
|
-
showRagister?: boolean
|
|
19
18
|
}
|
|
20
19
|
const subloading = ref(false)
|
|
21
20
|
const router = useRouter()
|
|
@@ -91,14 +90,11 @@ function handleSubmit() {
|
|
|
91
90
|
console.log(error, 'error')
|
|
92
91
|
})
|
|
93
92
|
}
|
|
94
|
-
// 注册
|
|
95
|
-
function handleRe() {
|
|
96
|
-
router.push('/pages/register/register')
|
|
97
|
-
}
|
|
98
93
|
</script>
|
|
99
94
|
|
|
100
95
|
<template>
|
|
101
96
|
<view class="bg-white pa-3 dark:bg-[var(--wot-dark-background2)]">
|
|
97
|
+
<!-- //账号登录 -->
|
|
102
98
|
<wd-form ref="form" :model="model">
|
|
103
99
|
<wd-cell-group border>
|
|
104
100
|
<wd-input
|
|
@@ -120,11 +116,6 @@ function handleRe() {
|
|
|
120
116
|
登录
|
|
121
117
|
</wd-button>
|
|
122
118
|
</view>
|
|
123
|
-
<view v-if="showRagister" class="p-4 pt-0">
|
|
124
|
-
<wd-button block :round="false" type="text" @click="handleRe">
|
|
125
|
-
注册
|
|
126
|
-
</wd-button>
|
|
127
|
-
</view>
|
|
128
119
|
</wd-form>
|
|
129
120
|
</view>
|
|
130
121
|
</template>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, defineOptions, defineProps, reactive, ref } from 'vue'
|
|
3
|
+
import { useRouter } from 'uni-mini-router'
|
|
4
|
+
import type { TabbarItem } from '../../composables/useTabbar'
|
|
5
|
+
import loginForm from '../login-form/login-form.vue'
|
|
6
|
+
import phoneLoginForm from '../phone-login-form/phone-login-form.vue'
|
|
7
|
+
|
|
8
|
+
defineOptions({
|
|
9
|
+
name: 'LoginFormBox',
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const props = defineProps<Props>()
|
|
13
|
+
// 定义 Props 类型
|
|
14
|
+
interface Props {
|
|
15
|
+
tabbarItems: TabbarItem[]
|
|
16
|
+
showRagister?: boolean
|
|
17
|
+
gurl?: string// 获取验证码接口
|
|
18
|
+
url?: string// 手机号登录接口
|
|
19
|
+
}
|
|
20
|
+
const router = useRouter()
|
|
21
|
+
|
|
22
|
+
// 登录模式
|
|
23
|
+
const loginMode = ref('account')
|
|
24
|
+
|
|
25
|
+
// 注册
|
|
26
|
+
function handleRe() {
|
|
27
|
+
router.push('/pages/register/register')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 切换登录模式
|
|
31
|
+
function changeLoginMode(mode: string) {
|
|
32
|
+
loginMode.value = mode
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<template>
|
|
37
|
+
<view class="bg-white pa-3 dark:bg-[var(--wot-dark-background2)]">
|
|
38
|
+
<!-- //手机登录 -->
|
|
39
|
+
<phoneLoginForm v-if="loginMode === 'phone'" :tabbar-items="props.tabbarItems" :url="props.url" :gurl="props.gurl" />
|
|
40
|
+
<!-- //账号登录 -->
|
|
41
|
+
<loginForm v-if="loginMode === 'account'" :tabbar-items="props.tabbarItems" />
|
|
42
|
+
|
|
43
|
+
<view class="pa-3 pt-0">
|
|
44
|
+
<wd-divider v-if="props.gurl">
|
|
45
|
+
或
|
|
46
|
+
</wd-divider>
|
|
47
|
+
<view v-if="props.gurl" class="p-4 pt-0">
|
|
48
|
+
<wd-button v-show="loginMode === 'account'" block :round="false" type="info" @click="changeLoginMode('phone')">
|
|
49
|
+
手机短信登录
|
|
50
|
+
</wd-button>
|
|
51
|
+
<wd-button v-show="loginMode === 'phone'" block :round="false" type="info" @click="changeLoginMode('account')">
|
|
52
|
+
账号登录
|
|
53
|
+
</wd-button>
|
|
54
|
+
</view>
|
|
55
|
+
<view v-if="showRagister" class="p-4 pt-0">
|
|
56
|
+
<view class="flex items-center justify-center text-size-24rpx">
|
|
57
|
+
<text>还没有账户?</text>
|
|
58
|
+
<wd-button block :round="false" type="text" size="small" @click="handleRe">
|
|
59
|
+
立即注册
|
|
60
|
+
</wd-button>
|
|
61
|
+
</view>
|
|
62
|
+
</view>
|
|
63
|
+
</view>
|
|
64
|
+
</view>
|
|
65
|
+
</template>
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { defineOptions, defineProps, onUnmounted, reactive, ref } from 'vue'
|
|
3
|
+
import { useRouter } from 'uni-mini-router'
|
|
4
|
+
import { useGlobalToast } from '../../composables/useGlobalToast'
|
|
5
|
+
import { getUserConfig, login } from '../../api/login'
|
|
6
|
+
import { req } from '../../api/index'
|
|
7
|
+
import { useUser } from '../../composables/useUser'
|
|
8
|
+
import { useTabbar } from '../../composables/useTabbar'
|
|
9
|
+
import type { TabbarItem } from '../../composables/useTabbar'
|
|
10
|
+
|
|
11
|
+
defineOptions({
|
|
12
|
+
name: 'PhoneLoginForm',
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const props = defineProps<Props>()
|
|
16
|
+
// 定义 Props 类型
|
|
17
|
+
interface Props {
|
|
18
|
+
gurl?: string// 获取验证码接口
|
|
19
|
+
url?: string// 手机号登录接口
|
|
20
|
+
tabbarItems: TabbarItem[]
|
|
21
|
+
}
|
|
22
|
+
const codeLoading = ref(false) // 添加验证码按钮加载状态
|
|
23
|
+
const countdown = ref(0) // 添加倒计时
|
|
24
|
+
const timer = ref(0) // 添加定时器引用
|
|
25
|
+
const subloading = ref(false)
|
|
26
|
+
const router = useRouter()
|
|
27
|
+
const toast = useGlobalToast()
|
|
28
|
+
const { setUserInfo } = useUser()
|
|
29
|
+
const model = reactive<{
|
|
30
|
+
phone: string
|
|
31
|
+
code: string
|
|
32
|
+
}>({
|
|
33
|
+
phone: '',
|
|
34
|
+
code: '',
|
|
35
|
+
|
|
36
|
+
})
|
|
37
|
+
const { setTabbarItemActive } = useTabbar(props.tabbarItems)
|
|
38
|
+
const form = ref()
|
|
39
|
+
// 添加获取验证码函数
|
|
40
|
+
function handleGetCode() {
|
|
41
|
+
// 如果正在倒计时或加载中,则不执行
|
|
42
|
+
if (countdown.value > 0 || codeLoading.value) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 验证手机号
|
|
47
|
+
if (!model.phone) {
|
|
48
|
+
return toast.warning('请先填写手机号')
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!/^1[3-9]\d{9}$/.test(model.phone)) {
|
|
52
|
+
return toast.warning('请输入正确的手机号')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 开始获取验证码流程
|
|
56
|
+
codeLoading.value = true
|
|
57
|
+
|
|
58
|
+
// 模拟发送验证码请求
|
|
59
|
+
// // 这里应该替换为实际的API调用
|
|
60
|
+
// setTimeout(() => {
|
|
61
|
+
// codeLoading.value = false
|
|
62
|
+
// // 启动倒计时
|
|
63
|
+
// startCountdown()
|
|
64
|
+
// toast.success('验证码已发送')
|
|
65
|
+
// }, 1000)
|
|
66
|
+
if (!props.gurl)
|
|
67
|
+
return toast.error({ msg: '请设置登录接口' })
|
|
68
|
+
// 实际使用时替换上面的模拟代码
|
|
69
|
+
req({
|
|
70
|
+
url: props.gurl,
|
|
71
|
+
method: 'POST',
|
|
72
|
+
data: {
|
|
73
|
+
number: model.phone,
|
|
74
|
+
},
|
|
75
|
+
}).then((res: any) => {
|
|
76
|
+
codeLoading.value = false
|
|
77
|
+
if (res.success) {
|
|
78
|
+
// 启动倒计时
|
|
79
|
+
startCountdown()
|
|
80
|
+
toast.success('验证码已发送')
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
toast.error(res.msg)
|
|
84
|
+
}
|
|
85
|
+
}).catch(() => {
|
|
86
|
+
codeLoading.value = false
|
|
87
|
+
toast.error('验证码发送失败')
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 添加启动倒计时函数
|
|
92
|
+
function startCountdown() {
|
|
93
|
+
countdown.value = 60
|
|
94
|
+
if (timer.value) {
|
|
95
|
+
clearInterval(timer.value)
|
|
96
|
+
}
|
|
97
|
+
timer.value = setInterval(() => {
|
|
98
|
+
if (countdown.value > 0) {
|
|
99
|
+
countdown.value--
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
if (timer.value) {
|
|
103
|
+
clearInterval(timer.value)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}, 1000)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 添加清理定时器函数
|
|
110
|
+
function clearTimer() {
|
|
111
|
+
if (timer.value) {
|
|
112
|
+
clearInterval(timer.value)
|
|
113
|
+
timer.value = 0
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
onUnmounted(() => {
|
|
117
|
+
clearTimer()
|
|
118
|
+
})
|
|
119
|
+
// 提交登录表单
|
|
120
|
+
function handleSubmit() {
|
|
121
|
+
form.value
|
|
122
|
+
.validate()
|
|
123
|
+
.then(async ({ valid, errors }: any) => {
|
|
124
|
+
if (valid) {
|
|
125
|
+
if (!props.url)
|
|
126
|
+
return toast.error({ msg: '请设置登录接口' })
|
|
127
|
+
try {
|
|
128
|
+
subloading.value = true
|
|
129
|
+
// 登录
|
|
130
|
+
const res = await req({
|
|
131
|
+
url: props.url,
|
|
132
|
+
method: 'POST',
|
|
133
|
+
data: {
|
|
134
|
+
number: model.phone,
|
|
135
|
+
code: model.code,
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
if (res.success) {
|
|
140
|
+
// 保存token
|
|
141
|
+
uni.setStorageSync('TOKEN', res.msg)
|
|
142
|
+
// 获取用户配置
|
|
143
|
+
const res1 = await getUserConfig()
|
|
144
|
+
if (res1.status === 'success') {
|
|
145
|
+
// 保存用户信息
|
|
146
|
+
setUserInfo(res1.user)
|
|
147
|
+
// 跳转首页
|
|
148
|
+
router.pushTab('/pages/index/index')
|
|
149
|
+
setTabbarItemActive('index')
|
|
150
|
+
toast.success({ msg: '登录成功!' })
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
toast.error({ msg: res.msg })
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (error: any) {
|
|
158
|
+
console.log(error, 'error')
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
toast.error({ msg: '请填写登录信息' })
|
|
163
|
+
console.log(errors, 'errors')
|
|
164
|
+
}
|
|
165
|
+
subloading.value = false
|
|
166
|
+
})
|
|
167
|
+
.catch((error: any) => {
|
|
168
|
+
toast.error({ msg: error })
|
|
169
|
+
console.log(error, 'error')
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
</script>
|
|
173
|
+
|
|
174
|
+
<template>
|
|
175
|
+
<view class="bg-white pa-3 dark:bg-[var(--wot-dark-background2)]">
|
|
176
|
+
<!-- //账号登录 -->
|
|
177
|
+
<wd-form ref="form" :model="model">
|
|
178
|
+
<wd-cell-group border>
|
|
179
|
+
<wd-input
|
|
180
|
+
v-model="model.phone" label="手机号" label-width="100px" prop="phone" clearable placeholder="请输入手机号"
|
|
181
|
+
:rules="[{ required: true, message: '请填写手机号' }, { required: true, pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' }]"
|
|
182
|
+
/>
|
|
183
|
+
<wd-input
|
|
184
|
+
v-model="model.code" required type="text" :rules="[{ required: true, message: '请填写验证码' }]" label="验证码"
|
|
185
|
+
prop="code"
|
|
186
|
+
>
|
|
187
|
+
<template #suffix>
|
|
188
|
+
<wd-button
|
|
189
|
+
size="small" :round="false" :loading="codeLoading" :disabled="countdown > 0"
|
|
190
|
+
@click="handleGetCode"
|
|
191
|
+
>
|
|
192
|
+
{{ countdown > 0 ? `${countdown}s后重新获取` : '获取验证码' }}
|
|
193
|
+
</wd-button>
|
|
194
|
+
</template>
|
|
195
|
+
</wd-input>
|
|
196
|
+
</wd-cell-group>
|
|
197
|
+
<view class="p-4">
|
|
198
|
+
<wd-button block :loading="subloading" :round="false" @click="handleSubmit">
|
|
199
|
+
登录
|
|
200
|
+
</wd-button>
|
|
201
|
+
</view>
|
|
202
|
+
</wd-form>
|
|
203
|
+
</view>
|
|
204
|
+
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- 纯色风格登录页面 -->
|
|
2
2
|
<script setup lang="ts">
|
|
3
3
|
import { defineOptions, defineProps } from 'vue'
|
|
4
|
-
import
|
|
4
|
+
import loginFormBox from '../login-form-box/login-form-box.vue'
|
|
5
5
|
import { useManualTheme } from '../../composables/useManualTheme'
|
|
6
6
|
import type { TabbarItem } from '../../composables/useTabbar'
|
|
7
7
|
|
|
@@ -15,6 +15,8 @@ interface Props {
|
|
|
15
15
|
tabbarItems: TabbarItem[]
|
|
16
16
|
loginlog: any
|
|
17
17
|
showRagister?: boolean
|
|
18
|
+
gurl?: string// 获取验证码接口
|
|
19
|
+
url?: string// 手机号登录接口
|
|
18
20
|
}
|
|
19
21
|
const {
|
|
20
22
|
currentThemeColor,
|
|
@@ -35,7 +37,7 @@ const {
|
|
|
35
37
|
<image class="h-250px w-250px" src="./footerImg.png" />
|
|
36
38
|
</view>
|
|
37
39
|
<view class="flex-1 border-rd-t-2 p-y-2 .dark:bg-[--wot-dark-background2] .light:bg-white">
|
|
38
|
-
<
|
|
40
|
+
<loginFormBox :tabbar-items="props.tabbarItems" :show-ragister="showRagister" :gurl="props.gurl" :url="props.url" />
|
|
39
41
|
</view>
|
|
40
42
|
</view>
|
|
41
43
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- 自定义背景风格登录页面 -->
|
|
2
2
|
<script setup lang="ts">
|
|
3
3
|
import { defineOptions, defineProps } from 'vue'
|
|
4
|
-
import
|
|
4
|
+
import loginFormBox from '../login-form-box/login-form-box.vue'
|
|
5
5
|
import { useManualTheme } from '../../composables/useManualTheme'
|
|
6
6
|
import type { TabbarItem } from '../../composables/useTabbar'
|
|
7
7
|
|
|
@@ -13,7 +13,8 @@ const props = defineProps<{
|
|
|
13
13
|
loginBackgroundimg: string
|
|
14
14
|
tabbarItems: TabbarItem[]
|
|
15
15
|
showRagister?: boolean
|
|
16
|
-
|
|
16
|
+
gurl?: string// 获取验证码接口
|
|
17
|
+
url?: string// 手机号登录接口
|
|
17
18
|
}>()
|
|
18
19
|
const {
|
|
19
20
|
currentThemeColor,
|
|
@@ -33,7 +34,7 @@ console.log(currentThemeColor)
|
|
|
33
34
|
</text>
|
|
34
35
|
</view>
|
|
35
36
|
<view class="flex-1 border-rd-t-2 p-y-2 .dark:bg-[--wot-dark-background2] .light:bg-white">
|
|
36
|
-
<
|
|
37
|
+
<loginFormBox :tabbar-items="props.tabbarItems" :show-ragister="showRagister" :gurl="props.gurl" :url="props.url" />
|
|
37
38
|
</view>
|
|
38
39
|
</view>
|
|
39
40
|
</template>
|