af-mobile-client-vue3 1.2.13 → 1.2.15

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.
@@ -1,250 +1,308 @@
1
- <script setup lang="ts">
2
- import type { UserInfo } from '@af-mobile-client-vue3/stores/modules/user'
3
- import type { FormInstance } from 'vant'
4
- import { LoginStateEnum, useFormRules, useLoginState } from '@af-mobile-client-vue3/hooks/useLogin'
5
- import GetAppDataService from '@af-mobile-client-vue3/plugins/AppData'
6
- import { getUserPermissions } from '@af-mobile-client-vue3/services/api/search'
7
- import { useSettingStore } from '@af-mobile-client-vue3/stores/modules/setting'
8
- import { useUserStore } from '@af-mobile-client-vue3/stores/modules/user'
9
- import { indexedDB } from '@af-mobile-client-vue3/utils/indexedDB'
10
- import { funcToRouter, loadRoutes } from '@af-mobile-client-vue3/utils/routerUtil'
11
- import { isWechat } from '@af-mobile-client-vue3/utils/wechatUtil'
12
- import {
13
- closeToast,
14
- showDialog,
15
- showFailToast,
16
- Switch,
17
- Button as VanButton,
18
- Col as VanCol,
19
- Field as VanField,
20
- Form as VanForm,
21
- Icon as VanIcon,
22
- Loading as VanLoading,
23
- Row as VanRow,
24
- } from 'vant'
25
- import { computed, inject, onBeforeMount, onMounted, reactive, ref, unref } from 'vue'
26
- import { useRoute, useRouter } from 'vue-router'
27
- import 'vant/lib/switch/index.css'
28
-
29
- declare let WeixinJSBridge: any
30
- const { setLoginState, getLoginState } = useLoginState()
31
- const { getFormRules } = useFormRules()
32
- const userState = useUserStore()
33
- const router = useRouter()
34
-
35
- const formRef = ref<FormInstance>()
36
- const loading = ref(false)
37
- const wxloading = ref(false)
38
- const rememberMe = ref(false)
39
- const switchPassType = ref(true)
40
- const formData = reactive({
41
- username: '',
42
- password: '',
43
- })
44
- const route = useRoute()
45
- const setting = useSettingStore()
46
-
47
- const getShow = computed(() => (unref(getLoginState) === LoginStateEnum.LOGIN))
48
-
49
- const login: any = inject('$login')
50
- onBeforeMount(async () => {
51
- if (isWechat()) {
52
- // 检测是否要开放微信登录
53
- if (setting.getSetting()?.wechatLogin) {
54
- try {
55
- wxloading.value = true
56
- if (route.query.code && route.query.state) {
57
- const data = await userState.loginUnified({
58
- unifiedCode: `${route.query.code}`,
59
- tenantName: `${route.query.state}`,
60
- loginMode: 'wechat',
61
- resourceName: setting.getSetting()?.routerName || '智慧手机',
62
- })
63
- login.f = data
64
- await Promise.all([GetAppDataService.load()])
65
- const loginInfo = {
66
- f: login.f,
67
- jwt: login.f.id,
68
- r: login.r,
69
- }
70
- userState.setLogin(loginInfo)
71
- userState.setTenantName(route.query.state)
72
- await afterGeneral(data.resources)
73
-
74
- const toPath = decodeURIComponent((route.query?.redirect || '/') as string)
75
- closeToast()
76
- if (route.name === '/login')
77
- await router.replace('/')
78
- else await router.replace(toPath)
79
- }
80
- else {
81
- if (userState.getTenantName() !== '') {
82
- closeWindows()
83
- }
84
- else {
85
- await showDialog({ message: '当前用户无登录权限' })
86
- closeWindows()
87
- }
88
- }
89
- }
90
- catch {
91
- await showDialog({ message: '当前用户无登录权限' })
92
- closeWindows()
93
- }
94
- finally {
95
- wxloading.value = false
96
- }
97
- }
98
- }
99
- })
100
- function handleSubmit() {
101
- formRef.value
102
- ?.validate()
103
- .then(async () => {
104
- try {
105
- loading.value = true
106
- const data: any = await userState.Login({
107
- username: formData.username,
108
- password: formData.password,
109
- resourceName: setting.getSetting()?.routerName || '智慧手机',
110
- })
111
- login.f = data
112
- await Promise.all([GetAppDataService.load()])
113
- const loginInfo = {
114
- f: login.f,
115
- jwt: login.f.id,
116
- r: login.r,
117
- }
118
- userState.setLogin(loginInfo)
119
- const compatible = import.meta.env.VITE_APP_COMPATIBLE
120
- if (compatible === 'OA')
121
- await afterGeneral(data)
122
- else
123
- if (data.resources.data)
124
- await afterGeneral(data.resources.data)
125
- else
126
- await afterGeneral(data.resources)
127
-
128
- const toPath = decodeURIComponent((route.query?.redirect || '/') as string)
129
- closeToast()
130
- if (route.name === '/login')
131
- await router.replace('/')
132
- else await router.replace(toPath)
133
- }
134
- finally {
135
- loading.value = false
136
- }
137
- })
138
- .catch((e) => {
139
- console.error(e)
140
- showFailToast('用户名或密码错误')
141
- })
142
- }
143
- function closeWindows() {
144
- if (isWechat()) {
145
- (window as any).WeixinJSBridge.call('closeWindow')
146
- }
147
- else {
148
- // 关闭页面
149
- if (navigator.userAgent.includes('Firefox') || navigator.userAgent.includes('Chrome')) {
150
- window.open('about:blank', '_self')
151
- window.close()
152
- }
153
- else {
154
- window.opener = null
155
- window.open('', '_self')
156
- window.close()
157
- }
158
- }
159
- }
160
-
161
- async function afterGeneral(result) {
162
- console.log('用户根本---', result)
163
- const user: UserInfo = {
164
- id: result.id,
165
- username: result.ename,
166
- password: formData.password,
167
- name: result.name,
168
- avatar: result.avatar ? result.avatar : setting.getSetting()?.defaultAvatarUrl,
169
- functions: result.functions,
170
- rolestr: result.rolestr,
171
- f_operator: result.name,
172
- f_operatorid: result.id,
173
- f_orgid: result.orgid,
174
- f_orgname: result.orgs,
175
- f_depid: result.f_department_id,
176
- f_depname: result.f_department_name,
177
- }
178
- userState.setUserInfo(user)
179
- // 如果result中没有返回 权限 需要主动获取权限列表
180
- if (!result.permissions) {
181
- result.permissions = await getUserPermissions(result.id)
182
- }
183
- userState.setPermissions(result.permissions)
184
- userState.setRoles([{ id: 'admin', operation: ['add', 'edit', 'delete'] }])
185
- // 加载路由
186
- loadRoutes(funcToRouter(user.functions))
187
- // 每次重新登录时,清除indexedDB缓存
188
- indexedDB.clear()
189
- }
190
-
191
- onMounted(() => {})
192
- </script>
193
-
194
- <template>
195
- <div v-show="wxloading" class="login_form">
196
- <VanRow justify="center">
197
- <VanLoading type="spinner" size="30px" vertical color="#1989fa">
198
- 自动登录中...
199
- </VanLoading>
200
- </VanRow>
201
- </div>
202
- <div v-if="getShow && !wxloading" class="login_form form">
203
- <VanForm ref="formRef" @submit="handleSubmit">
204
- <VanField
205
- v-model="formData.username"
206
- class="form_field"
207
- name="username"
208
- label="账号"
209
- placeholder="请输入账号"
210
- label-align="top"
211
- :rules="getFormRules.username"
212
- />
213
- <VanField
214
- v-model="formData.password"
215
- class="form_field"
216
- :type="switchPassType ? 'password' : 'text'"
217
- name="password"
218
- label="密码"
219
- placeholder="请输入密码"
220
- label-align="top"
221
- :rules="getFormRules.password"
222
- @click-right-icon="switchPassType = !switchPassType"
223
- >
224
- <template #right-icon>
225
- <VanIcon v-if="switchPassType" name="closed-eye" color="rgb(56, 149, 250)" />
226
- <VanIcon v-else name="eye-o" color="rgb(56, 149, 250)" />
227
- </template>
228
- </VanField>
229
-
230
- <VanRow justify="space-between" class="extra_setting">
231
- <VanCol>
232
- <div class="extra_setting_for_remember_password">
233
- <Switch v-model="rememberMe" size="12px" />
234
- <span>记住密码</span>
235
- </div>
236
- </VanCol>
237
- <VanCol>
238
- <a class="extra_setting_for_reset_password" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)">忘记密码?</a>
239
- </VanCol>
240
- </VanRow>
241
- <VanButton class="login_btn btn" type="primary" block native-type="submit" :loading="loading">
242
-
243
- </VanButton>
244
- </VanForm>
245
- </div>
246
- </template>
247
-
248
- <style scoped lang="less">
249
- @import '@af-mobile-client-vue3/styles/login.less';
250
- </style>
1
+ <script setup lang="ts">
2
+ import type { UserInfo } from '@af-mobile-client-vue3/stores/modules/user'
3
+ import type { FormInstance } from 'vant'
4
+ import { LoginStateEnum, useFormRules, useLoginState } from '@af-mobile-client-vue3/hooks/useLogin'
5
+ import GetAppDataService from '@af-mobile-client-vue3/plugins/AppData'
6
+ import { getUserPermissions } from '@af-mobile-client-vue3/services/api/search'
7
+ import { useSettingStore } from '@af-mobile-client-vue3/stores/modules/setting'
8
+ import { useUserStore } from '@af-mobile-client-vue3/stores/modules/user'
9
+ import { indexedDB } from '@af-mobile-client-vue3/utils/indexedDB'
10
+ import { funcToRouter, loadRoutes } from '@af-mobile-client-vue3/utils/routerUtil'
11
+ import { isWechat } from '@af-mobile-client-vue3/utils/wechatUtil'
12
+ import {
13
+ closeToast,
14
+ showDialog,
15
+ showFailToast,
16
+ Switch,
17
+ Button as VanButton,
18
+ Col as VanCol,
19
+ Field as VanField,
20
+ Form as VanForm,
21
+ Icon as VanIcon,
22
+ Loading as VanLoading,
23
+ Row as VanRow,
24
+ } from 'vant'
25
+ import { computed, inject, onBeforeMount, onMounted, reactive, ref, unref } from 'vue'
26
+ import { useRoute, useRouter } from 'vue-router'
27
+ import 'vant/lib/switch/index.css'
28
+
29
+ declare let WeixinJSBridge: any
30
+ const { setLoginState, getLoginState } = useLoginState()
31
+ const { getFormRules } = useFormRules()
32
+ const userState = useUserStore()
33
+ const router = useRouter()
34
+
35
+ const formRef = ref<FormInstance>()
36
+ const loading = ref(false)
37
+ const wxloading = ref(false)
38
+ const rememberMe = ref(false)
39
+ const switchPassType = ref(true)
40
+ const formData = reactive({
41
+ username: '',
42
+ password: '',
43
+ })
44
+ const route = useRoute()
45
+ const setting = useSettingStore()
46
+
47
+ const getShow = computed(() => (unref(getLoginState) === LoginStateEnum.LOGIN))
48
+
49
+ const login: any = inject('$login')
50
+ onBeforeMount(async () => {
51
+ if (isWechat() && setting.getSetting()?.wxAutoLogin) {
52
+ // 检测是否要开放微信登录
53
+ if (setting.getSetting()?.wechatLogin) {
54
+ try {
55
+ wxloading.value = true
56
+ if (route.query.code && route.query.state) {
57
+ const data = await userState.loginUnified({
58
+ unifiedCode: `${route.query.code}`,
59
+ tenantName: `${route.query.state}`,
60
+ loginMode: 'wechat',
61
+ resourceName: setting.getSetting()?.routerName || '智慧手机',
62
+ })
63
+ login.f = data
64
+ await Promise.all([GetAppDataService.load()])
65
+ const loginInfo = {
66
+ f: login.f,
67
+ jwt: login.f.id,
68
+ r: login.r,
69
+ }
70
+ userState.setLogin(loginInfo)
71
+ userState.setTenantName(route.query.state)
72
+ await afterGeneral(data.resources)
73
+
74
+ const toPath = decodeURIComponent((route.query?.redirect || '/') as string)
75
+ closeToast()
76
+ if (route.name === '/login')
77
+ await router.replace('/')
78
+ else await router.replace(toPath)
79
+ }
80
+ else {
81
+ if (userState.getTenantName() !== '') {
82
+ closeWindows()
83
+ }
84
+ else {
85
+ await showDialog({ message: '当前用户无登录权限' })
86
+ closeWindows()
87
+ }
88
+ }
89
+ }
90
+ catch {
91
+ await showDialog({ message: '当前用户无登录权限' })
92
+ closeWindows()
93
+ }
94
+ finally {
95
+ wxloading.value = false
96
+ }
97
+ }
98
+ }
99
+ })
100
+ function handleSubmit() {
101
+ formRef.value
102
+ ?.validate()
103
+ .then(async () => {
104
+ try {
105
+ loading.value = true
106
+ const data: any = await userState.Login({
107
+ username: formData.username,
108
+ password: formData.password,
109
+ resourceName: setting.getSetting()?.routerName || '智慧手机',
110
+ })
111
+ login.f = data
112
+ await Promise.all([GetAppDataService.load()])
113
+ const loginInfo = {
114
+ f: login.f,
115
+ jwt: login.f.id,
116
+ r: login.r,
117
+ }
118
+ userState.setLogin(loginInfo)
119
+ const compatible = import.meta.env.VITE_APP_COMPATIBLE
120
+ if (compatible === 'OA')
121
+ await afterGeneral(data)
122
+ else
123
+ if (data.resources.data)
124
+ await afterGeneral(data.resources.data)
125
+ else
126
+ await afterGeneral(data.resources)
127
+
128
+ const toPath = decodeURIComponent((route.query?.redirect || '/') as string)
129
+ closeToast()
130
+ if (route.name === '/login')
131
+ await router.replace('/')
132
+ else await router.replace(toPath)
133
+ }
134
+ finally {
135
+ loading.value = false
136
+ }
137
+ })
138
+ .catch((e) => {
139
+ console.error(e)
140
+ showFailToast('用户名或密码错误')
141
+ })
142
+ }
143
+ function closeWindows() {
144
+ if (isWechat()) {
145
+ (window as any).WeixinJSBridge.call('closeWindow')
146
+ }
147
+ else {
148
+ // 关闭页面
149
+ if (navigator.userAgent.includes('Firefox') || navigator.userAgent.includes('Chrome')) {
150
+ window.open('about:blank', '_self')
151
+ window.close()
152
+ }
153
+ else {
154
+ window.opener = null
155
+ window.open('', '_self')
156
+ window.close()
157
+ }
158
+ }
159
+ }
160
+
161
+ async function afterGeneral(result) {
162
+ console.log('用户根本---', result)
163
+ const user: UserInfo = {
164
+ id: result.id,
165
+ username: result.ename,
166
+ password: formData.password,
167
+ name: result.name,
168
+ avatar: result.avatar ? result.avatar : setting.getSetting()?.defaultAvatarUrl,
169
+ functions: result.functions,
170
+ rolestr: result.rolestr,
171
+ f_operator: result.name,
172
+ f_operatorid: result.id,
173
+ f_orgid: result.orgid,
174
+ f_orgname: result.orgs,
175
+ f_depid: result.f_department_id,
176
+ f_depname: result.f_department_name,
177
+ }
178
+ userState.setUserInfo(user)
179
+ // 如果result中没有返回 权限 需要主动获取权限列表
180
+ if (!result.permissions) {
181
+ result.permissions = await getUserPermissions(result.id)
182
+ }
183
+ userState.setPermissions(result.permissions)
184
+ userState.setRoles([{ id: 'admin', operation: ['add', 'edit', 'delete'] }])
185
+ // 加载路由
186
+ loadRoutes(funcToRouter(user.functions))
187
+ // 每次重新登录时,清除indexedDB缓存
188
+ indexedDB.clear()
189
+ }
190
+ async function wxLoginFun() {
191
+ await localStorage.setItem('wechatLoginPending', 'true')
192
+ userState.getCode(setting.getSetting()?.tenantName)
193
+ }
194
+ async function wxLoginFunContinue(code, state) {
195
+ try {
196
+ wxloading.value = true
197
+ const data = await userState.loginUnified({
198
+ unifiedCode: `${code}`,
199
+ tenantName: `${state}`,
200
+ loginMode: 'wechat',
201
+ resourceName: setting.getSetting()?.routerName || '智慧手机',
202
+ })
203
+ login.f = data
204
+ await Promise.all([GetAppDataService.load()])
205
+ const loginInfo = {
206
+ f: login.f,
207
+ jwt: login.f.id,
208
+ r: login.r,
209
+ }
210
+ userState.setLogin(loginInfo)
211
+ userState.setTenantName(route.query.state)
212
+ await afterGeneral(data.resources)
213
+ const toPath = decodeURIComponent((route.query?.redirect || '/') as string)
214
+ closeToast()
215
+ if (route.name === '/login')
216
+ await router.replace('/')
217
+ else await router.replace(toPath)
218
+ }
219
+ finally {
220
+ wxloading.value = false
221
+ }
222
+ }
223
+ function getQueryParam(param: string): string | null {
224
+ const search = window.location.search || window.location.hash.split('?')[1] || ''
225
+ const params = new URLSearchParams(search)
226
+ return params.get(param)
227
+ }
228
+ onMounted(() => {
229
+ const pending = localStorage.getItem('wechatLoginPending')
230
+ const code = getQueryParam('code')
231
+ const state = getQueryParam('state')
232
+ if (pending && code && state) {
233
+ localStorage.removeItem('wechatLoginPending')
234
+ wxLoginFunContinue(code, state)
235
+ }
236
+ })
237
+ </script>
238
+
239
+ <template>
240
+ <div v-show="wxloading" class="login_form">
241
+ <VanRow justify="center">
242
+ <VanLoading type="spinner" size="30px" vertical color="#1989fa">
243
+ 自动登录中...
244
+ </VanLoading>
245
+ </VanRow>
246
+ </div>
247
+ <div v-if="getShow && !wxloading" class="login_form form">
248
+ <VanForm ref="formRef" @submit="handleSubmit">
249
+ <VanField
250
+ v-model="formData.username"
251
+ class="form_field"
252
+ name="username"
253
+ label="账号"
254
+ placeholder="请输入账号"
255
+ label-align="top"
256
+ :rules="getFormRules.username"
257
+ />
258
+ <VanField
259
+ v-model="formData.password"
260
+ class="form_field"
261
+ :type="switchPassType ? 'password' : 'text'"
262
+ name="password"
263
+ label="密码"
264
+ placeholder="请输入密码"
265
+ label-align="top"
266
+ :rules="getFormRules.password"
267
+ @click-right-icon="switchPassType = !switchPassType"
268
+ >
269
+ <template #right-icon>
270
+ <VanIcon v-if="switchPassType" name="closed-eye" color="rgb(56, 149, 250)" />
271
+ <VanIcon v-else name="eye-o" color="rgb(56, 149, 250)" />
272
+ </template>
273
+ </VanField>
274
+
275
+ <VanRow justify="space-between" class="extra_setting">
276
+ <VanCol>
277
+ <div class="extra_setting_for_remember_password">
278
+ <Switch v-model="rememberMe" size="12px" />
279
+ <span>记住密码</span>
280
+ </div>
281
+ </VanCol>
282
+ <VanCol>
283
+ <a class="extra_setting_for_reset_password" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)">忘记密码?</a>
284
+ </VanCol>
285
+ </VanRow>
286
+ <VanButton class="login_btn btn" type="primary" block native-type="submit" :loading="loading">
287
+ 登 录
288
+ </VanButton>
289
+ <VanButton
290
+ v-show="setting.getSetting()?.wxLoginAge && isWechat()"
291
+ class="wechat-login-btn btn"
292
+ type="primary"
293
+ block
294
+ native-type="button"
295
+ :loading="wxloading"
296
+ @click="wxLoginFun"
297
+ style="background-color: #07C160; border-color: #07C160; margin-top: 15px"
298
+ >
299
+ <van-icon name="wechat" size="20px"/>
300
+ 微信登录
301
+ </VanButton>
302
+ </VanForm>
303
+ </div>
304
+ </template>
305
+
306
+ <style scoped lang="less">
307
+ @import '@af-mobile-client-vue3/styles/login.less';
308
+ </style>