af-mobile-client-vue3 1.3.18 → 1.3.20

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,20 +1,145 @@
1
1
  <script setup lang="ts">
2
+ import type { PhoneLocationStatus } from '~root/src/components/data/XOlMap/types'
2
3
  import useSettingStore from '@af-mobile-client-vue3/stores/modules/setting'
3
4
  import useUserStore from '@af-mobile-client-vue3/stores/modules/user'
4
5
  import { Dialog as vanDialog, Icon as vanIcon } from 'vant'
5
- import { ref } from 'vue'
6
+ import { computed, onMounted, onUnmounted, ref } from 'vue'
6
7
  import { useRouter } from 'vue-router'
8
+ import { mobileUtil } from '~root/src/utils/mobileUtil'
7
9
  import ModifyPassword from './comm/ModifyPassword.vue'
8
10
 
9
11
  const router = useRouter()
10
12
  const username = useUserStore().getUserInfo().name
11
13
  const fullnames = useUserStore().getLogin().f.resources.fullnames
14
+ const roleName = useUserStore().getLogin().f.resources.f_role_name
12
15
 
13
16
  // 修改密码弹窗显示状态
14
17
  const showModifyPassword = ref(false)
15
18
  // 退出登录确认弹窗显示状态
16
19
  const showLogoutConfirm = ref(false)
20
+ // 在setup函数中
21
+ let intervalId = null
22
+
23
+ // 定义一个变量来存储上一次的上传结果
24
+ const lastUploadResult = ref(null)
25
+
26
+ /**
27
+ * 上次上传结果类型定义
28
+ */
29
+ interface LocationInfo {
30
+ uploadTime: string
31
+ f_realtime: string
32
+ f_latitude: number
33
+ f_longitude: number
34
+ f_address?: string
35
+ f_speed?: number
36
+ f_bearing?: number
37
+ f_altitude?: number
38
+ isError: boolean
39
+ errorCode?: string
40
+ // ... 其他字段
41
+ }
42
+
43
+ interface UploadResult {
44
+ uploadTime: string
45
+ location: LocationInfo
46
+ response: {
47
+ code: number
48
+ msg?: string
49
+ [key: string]: any
50
+ }
51
+ }
52
+
53
+ // 兼容 lastUploadResult 可能为字符串或对象
54
+ const lastUploadResultObj = computed<UploadResult | null>(() => {
55
+ if (!lastUploadResult.value)
56
+ return null
57
+ if (typeof lastUploadResult.value === 'string') {
58
+ try {
59
+ return JSON.parse(lastUploadResult.value)
60
+ }
61
+ catch {
62
+ return null
63
+ }
64
+ }
65
+ return lastUploadResult.value
66
+ })
67
+
68
+ const uploadDisplayInfo = computed(() => {
69
+ const result = lastUploadResultObj.value
70
+ if (!result)
71
+ return { error: null, info: null }
72
+ // response.code 不为 200
73
+ if (result.response && result.response.code !== 200) {
74
+ return { error: result.response.msg || '未知错误', info: null }
75
+ }
76
+
77
+ // location.errorCode 存在且 isError 为 true
78
+ if (result.location && result.location.isError && result.location.errorCode) {
79
+ return { error: result.location.errorCode, info: null }
80
+ }
81
+
82
+ // 正常展示
83
+ if (result.location) {
84
+ return {
85
+ error: null,
86
+ info: {
87
+ uploadTime: result.uploadTime,
88
+ latitude: result.location.f_latitude,
89
+ longitude: result.location.f_longitude,
90
+ },
91
+ }
92
+ }
93
+
94
+ return { error: null, info: null }
95
+ })
17
96
 
97
+ const uploadStatusTag = computed(() => {
98
+ const result = uploadDisplayInfo.value
99
+ if (result.error) {
100
+ return { text: '上传定位失败', color: 'red' }
101
+ }
102
+ if (result.info) {
103
+ return { text: '正在上传定位', color: 'green' }
104
+ }
105
+ return null
106
+ })
107
+
108
+ onMounted(() => {
109
+ if (roleName.includes('需要定位人员')) {
110
+ // 立即执行一次
111
+ mobileUtil.execute({
112
+ param: {},
113
+ funcName: 'getLastRealtimeUploadResult',
114
+ callbackFunc: (result: PhoneLocationStatus) => {
115
+ if (result.status === 'success') {
116
+ lastUploadResult.value = result.data
117
+ }
118
+ },
119
+ })
120
+
121
+ // 设置每5秒执行一次的定时器
122
+ intervalId = setInterval(() => {
123
+ mobileUtil.execute({
124
+ param: {},
125
+ funcName: 'getLastRealtimeUploadResult',
126
+ callbackFunc: (result: PhoneLocationStatus) => {
127
+ if (result.status === 'success') {
128
+ lastUploadResult.value = result.data
129
+ }
130
+ },
131
+ })
132
+ }, 5000) // 5000毫秒 = 5秒
133
+ }
134
+ })
135
+
136
+ onUnmounted(() => {
137
+ // 组件卸载时清除定时器
138
+ if (intervalId) {
139
+ clearInterval(intervalId)
140
+ intervalId = null
141
+ }
142
+ })
18
143
  function exit_login() {
19
144
  showLogoutConfirm.value = true
20
145
  }
@@ -65,6 +190,12 @@ const webMobileConfig = useSettingStore().getSetting()
65
190
  <div class="user-detail">
66
191
  <h2 class="username">
67
192
  {{ username }}
193
+ <span
194
+ v-if="uploadStatusTag"
195
+ class="upload-status-tag" :class="[uploadStatusTag.color]"
196
+ >
197
+ {{ uploadStatusTag.text }}
198
+ </span>
68
199
  </h2>
69
200
  <p class="user-role">
70
201
  {{ fullnames }}
@@ -237,6 +368,25 @@ const webMobileConfig = useSettingStore().getSetting()
237
368
  color: #333;
238
369
  margin: 0 0 4px 0;
239
370
  }
371
+ .upload-status-tag {
372
+ display: inline-block;
373
+ margin-left: 8px;
374
+ padding: 2px 8px;
375
+ border-radius: 8px;
376
+ font-size: 12px;
377
+ font-weight: 400;
378
+ background: #f0f0f0;
379
+ &.green {
380
+ color: #10b981;
381
+ background: #e6f9f0;
382
+ border: 1px solid #10b981;
383
+ }
384
+ &.red {
385
+ color: #ef4444;
386
+ background: #fdeaea;
387
+ border: 1px solid #ef4444;
388
+ }
389
+ }
240
390
 
241
391
  .user-role {
242
392
  font-size: 14px;
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { openApiLogic } from '@af-mobile-client-vue3/services/api/common'
2
+ import { getConfigByName, openApiLogic } from '@af-mobile-client-vue3/services/api/common'
3
3
  import { useSettingStore } from '@af-mobile-client-vue3/stores/modules/setting'
4
4
  import {
5
5
  showFailToast,
@@ -24,6 +24,7 @@ interface FormData {
24
24
  name: string
25
25
  phone: string
26
26
  gender: string
27
+ code: string
27
28
  email: string
28
29
  username: string
29
30
  password: string
@@ -62,6 +63,7 @@ const formData = ref<FormData>({
62
63
  name: '',
63
64
  phone: '',
64
65
  gender: '',
66
+ code: '',
65
67
  email: '',
66
68
  username: '',
67
69
  password: '',
@@ -79,6 +81,8 @@ const openId = ref('')
79
81
  // 错误信息
80
82
  const errors = ref<Errors>({})
81
83
 
84
+ const registerConfig = ref({})
85
+
82
86
  // 状态管理
83
87
  const isSubmitting = ref<boolean>(false)
84
88
  const showSuccess = ref<boolean>(false)
@@ -106,6 +110,14 @@ function validateName(): boolean {
106
110
  delete errors.value.name
107
111
  return true
108
112
  }
113
+ function validateCode(): boolean {
114
+ if (!formData.value.code.trim()) {
115
+ errors.value.code = '员工编号不能为空'
116
+ return false
117
+ }
118
+ delete errors.value.code
119
+ return true
120
+ }
109
121
 
110
122
  function validatePhone(): boolean {
111
123
  const phoneRegex = /^1[3-9]\d{9}$/
@@ -205,6 +217,7 @@ function validateGender(): boolean {
205
217
  function validateAll(): boolean {
206
218
  const validations = [
207
219
  validateName(),
220
+ validateCode(),
208
221
  validatePhone(),
209
222
  validateEmail(),
210
223
  validateUsername(),
@@ -268,6 +281,18 @@ async function fetchOrganizationInfo(strategyId: any): Promise<void> {
268
281
  }
269
282
  }
270
283
 
284
+ async function initConfig(): Promise<void> {
285
+ try {
286
+ getConfigByName('registerConfig', (res: any) => {
287
+ console.log('res', res)
288
+ }, 'af-system')
289
+ }
290
+ catch (error) {
291
+ console.error('获取组织信息失败:', error)
292
+ showToast('获取组织信息失败')
293
+ }
294
+ }
295
+
271
296
  // 提交注册
272
297
  async function submitRegistration(): Promise<void> {
273
298
  if (usernameStatus.value === 'checking') {
@@ -302,6 +327,7 @@ function resetForm(): void {
302
327
  name: '',
303
328
  phone: '',
304
329
  gender: '',
330
+ code: '',
305
331
  email: '',
306
332
  username: '',
307
333
  password: '',
@@ -357,6 +383,8 @@ function goBack() {
357
383
 
358
384
  // 组件挂载时获取组织信息
359
385
  onMounted(async () => {
386
+ console.log('route.query', route.query)
387
+ console.log('route.params', route.params)
360
388
  const strategyId = route.query.strategyId || route.params.strategyId
361
389
  openId.value = route.query.openId as string || route.params.openId as string
362
390
  formData.value.openId = openId.value
@@ -450,16 +478,30 @@ onMounted(async () => {
450
478
  </template>
451
479
  <template #input>
452
480
  <VanRadioGroup v-model="formData.gender" @change="validateGender">
453
- <VanRadio name="male">
481
+ <VanRadio name="">
454
482
 
455
483
  </VanRadio>
456
- <VanRadio name="female">
484
+ <VanRadio name="">
457
485
 
458
486
  </VanRadio>
459
487
  </VanRadioGroup>
460
488
  </template>
461
489
  </VanField>
462
-
490
+ <!-- 员工编号 -->
491
+ <VanField
492
+ v-model="formData.code"
493
+ label="员工编号"
494
+ placeholder="请输入员工编号"
495
+ :error="!!errors.code"
496
+ :error-message="errors.code"
497
+ label-align="top"
498
+ @blur="validateCode"
499
+ >
500
+ <template #label>
501
+ <i class="i-solar-user-id-bold text-purple-500" />
502
+ 员工编号 <span class="required">*</span>
503
+ </template>
504
+ </VanField>
463
505
  <!-- 邮箱 -->
464
506
  <VanField
465
507
  v-model="formData.email"
@@ -1,97 +0,0 @@
1
- <script setup lang="ts">
2
- import XFormGroup from '@af-mobile-client-vue3/components/data/XFormGroup/index.vue'
3
- import { runLogic } from '@af-mobile-client-vue3/services/api/common'
4
- import { useUserStore } from '@af-mobile-client-vue3/stores/modules/user'
5
- import dayjs from 'dayjs/esm/index'
6
- import { showToast } from 'vant'
7
- import { onMounted, ref } from 'vue'
8
- import { useRoute } from 'vue-router'
9
-
10
- const configName = ref('appapplyuserinfoFormGroup')
11
- const serviceName = ref('af-apply')
12
- const route = useRoute()
13
- const userInfo = useUserStore().getUserInfo()
14
- const workflowId = ref('3045')
15
- const userinfoid = ref('93116')
16
- const model = ref('编辑')
17
- const groupFormData = ref({})
18
-
19
- function submit(res) {
20
- if (model.value === '新增') {
21
- res.t_userinfo.f_operate_date = dayjs().format('YYYY-MM-DD HH:mm:ss')
22
- res.t_userinfo.f_orgid = userInfo.f_orgid
23
- res.t_userinfo.f_orgname = userInfo.f_orgname
24
- res.t_userinfo.f_depid = userInfo.f_depid
25
- res.t_userinfo.f_depname = userInfo.f_depname
26
- res.t_userinfo.f_operatorid = userInfo.f_operatorid
27
- res.t_userinfo.f_operator = userInfo.f_operator
28
- res.t_userinfo.f_workflow_id = this.f_workflow_id
29
- res.t_userinfo.f_user_state = '预备'
30
-
31
- res.t_userfiles.f_operate_date = dayjs().format('YYYY-MM-DD HH:mm:ss')
32
- res.t_userfiles.f_orgid = userInfo.f_orgid
33
- res.t_userfiles.f_orgname = userInfo.f_orgname
34
- res.t_userfiles.f_depid = userInfo.f_depid
35
- res.t_userfiles.f_depname = userInfo.f_depname
36
- res.t_userfiles.f_operatorid = userInfo.f_operatorid
37
- res.t_userfiles.f_operator = userInfo.f_operator
38
- res.t_userfiles.f_workflow_id = this.f_workflow_id
39
- res.t_userfiles.f_table_state = '待开通'
40
- }
41
- let saveData = res
42
- if (saveData.t_userfiles.f_gasbrand_id.length > 0) {
43
- saveData.t_userfiles.f_gasbrand_id = saveData.t_userfiles.f_gasbrand_id[0]
44
- }
45
- if (saveData.t_userfiles.f_price_id.length > 0) {
46
- saveData.t_userfiles.f_price_id = saveData.t_userfiles.f_price_id[0]
47
- }
48
- if (model.value === '编辑') {
49
- saveData = Object.assign(saveData, {
50
- f_operator_record: userInfo.f_operator,
51
- f_operatorid_record: userInfo.f_operatorid,
52
- f_orgid_record: userInfo.f_orgid,
53
- f_orgname_record: userInfo.f_orgname,
54
- f_depid_record: userInfo.f_depid,
55
- f_depname_record: userInfo.f_depname,
56
- })
57
- }
58
- runLogic('userFIleSaveLogic', saveData, 'af-revenue').then((res) => {
59
- showToast('操作成功!')
60
- history.back()
61
- })
62
- }
63
- const isInit = ref(false)
64
- function init() {
65
- if (model.value === '编辑') {
66
- runLogic('getFileDetailForEdit', { f_userinfo_id: userinfoid.value }, 'af-revenue').then((res) => {
67
- // if (res.t_userfiles.f_gasmodel_id) {
68
- // res.t_userfiles.f_gasmodel_id = 76
69
- // }
70
- // if (res.t_userfiles.f_price_id) {
71
- // res.t_userfiles.f_price_id = [res.t_userfiles.f_price_id]
72
- // }
73
- console.log('1111111----,', res)
74
- groupFormData.value = res
75
- isInit.value = true
76
- })
77
- }
78
- }
79
- onMounted(() => {
80
- init()
81
- })
82
- </script>
83
-
84
- <template>
85
- <XFormGroup
86
- v-if="isInit"
87
- mode="修改"
88
- :config-name="configName"
89
- :service-name="serviceName"
90
- :group-form-data="groupFormData"
91
- @submit="submit"
92
- />
93
- </template>
94
-
95
- <style scoped lang="less">
96
-
97
- </style>