vue2-client 1.21.13 → 1.21.14
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/package.json +1 -1
- package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +50 -24
- package/src/base-client/components/common/XFormGroup/XFormGroup.vue +13 -6
- package/src/base-client/components/common/XFormGroup/demo.vue +478 -66
- package/src/router/async/router.map.js +2 -2
- package/src/utils/reg.js +166 -0
package/package.json
CHANGED
|
@@ -201,7 +201,7 @@ import { formatDate, setDataByRealKey } from '@vue2-client/utils/util'
|
|
|
201
201
|
import * as util from '@vue2-client/utils/util'
|
|
202
202
|
import { mapState } from 'vuex'
|
|
203
203
|
import { addOrModify, getConfigByName, getConfigByNameAsync, runLogic } from '@vue2-client/services/api/common'
|
|
204
|
-
import {checkIdNumber, REG_EMAIL, REG_LANDLINE, REG_PHONE
|
|
204
|
+
import { checkIdNumber, isMaskedPhone, REG_EMAIL, REG_LANDLINE, REG_PHONE } from '@vue2-client/utils/reg'
|
|
205
205
|
import moment from 'moment/moment'
|
|
206
206
|
import { executeStrFunction, executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
|
|
207
207
|
import formValidationMixin from '@vue2-client/mixins/formValidationMixin'
|
|
@@ -855,14 +855,19 @@ export default {
|
|
|
855
855
|
this.rules[rulesArrayKey].push({
|
|
856
856
|
type: 'userPhone',
|
|
857
857
|
validator: (rule, value, callback) => {
|
|
858
|
-
if
|
|
858
|
+
if (!value) {
|
|
859
859
|
callback()
|
|
860
|
+
return
|
|
860
861
|
}
|
|
861
|
-
if (
|
|
862
|
-
callback(new Error('请输入正确的手机号码'))
|
|
863
|
-
} else {
|
|
862
|
+
if (isMaskedPhone(value)) {
|
|
864
863
|
callback()
|
|
864
|
+
return
|
|
865
|
+
}
|
|
866
|
+
if (!REG_PHONE.test(value)) {
|
|
867
|
+
callback(new Error('请输入正确的手机号码'))
|
|
868
|
+
return
|
|
865
869
|
}
|
|
870
|
+
callback()
|
|
866
871
|
},
|
|
867
872
|
message: '请输入正确的手机号码',
|
|
868
873
|
trigger: 'blur'
|
|
@@ -872,11 +877,15 @@ export default {
|
|
|
872
877
|
case 'idNumber': {
|
|
873
878
|
this.rules[rulesArrayKey].push({
|
|
874
879
|
validator: (rule, value, callback) => {
|
|
875
|
-
if (
|
|
876
|
-
callback(new Error('请输入正确的身份证号码'))
|
|
877
|
-
} else {
|
|
880
|
+
if (!value) {
|
|
878
881
|
callback()
|
|
882
|
+
return
|
|
883
|
+
}
|
|
884
|
+
if (!checkIdNumber(value)) {
|
|
885
|
+
callback(new Error('请输入正确的身份证号码'))
|
|
886
|
+
return
|
|
879
887
|
}
|
|
888
|
+
callback()
|
|
880
889
|
},
|
|
881
890
|
trigger: 'blur'
|
|
882
891
|
})
|
|
@@ -885,11 +894,19 @@ export default {
|
|
|
885
894
|
case 'landlineNumber': {
|
|
886
895
|
this.rules[rulesArrayKey].push({
|
|
887
896
|
validator: (rule, value, callback) => {
|
|
888
|
-
if (
|
|
889
|
-
callback(
|
|
890
|
-
|
|
897
|
+
if (!value) {
|
|
898
|
+
callback()
|
|
899
|
+
return
|
|
900
|
+
}
|
|
901
|
+
if (isMaskedPhone(value)) {
|
|
891
902
|
callback()
|
|
903
|
+
return
|
|
904
|
+
}
|
|
905
|
+
if (!REG_LANDLINE.test(value)) {
|
|
906
|
+
callback(new Error('请输入正确的座机号码'))
|
|
907
|
+
return
|
|
892
908
|
}
|
|
909
|
+
callback()
|
|
893
910
|
},
|
|
894
911
|
trigger: 'blur'
|
|
895
912
|
})
|
|
@@ -1064,24 +1081,33 @@ export default {
|
|
|
1064
1081
|
},
|
|
1065
1082
|
|
|
1066
1083
|
async asyncSubmit() {
|
|
1084
|
+
const selectForm = this.$refs.selectForm
|
|
1085
|
+
if (!selectForm) {
|
|
1086
|
+
return Promise.reject(new Error('表单尚未加载完成'))
|
|
1087
|
+
}
|
|
1067
1088
|
return new Promise((resolve, reject) => {
|
|
1068
|
-
|
|
1089
|
+
selectForm.validate(async valid => {
|
|
1069
1090
|
if (!valid) {
|
|
1070
1091
|
reject(new Error('Form validation failed'))
|
|
1071
1092
|
return
|
|
1072
1093
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1094
|
+
try {
|
|
1095
|
+
this.loading = true
|
|
1096
|
+
const requestForm = this.prepareForm()
|
|
1097
|
+
await this.appendSilenceAddFields(requestForm)
|
|
1098
|
+
const realForm = this.handleFormKeys(requestForm)
|
|
1099
|
+
resolve({
|
|
1100
|
+
realForm,
|
|
1101
|
+
businessType: this.businessType,
|
|
1102
|
+
serviceName: this.serviceName,
|
|
1103
|
+
currUserName: this.currUser.name,
|
|
1104
|
+
currUserId: this.currUser.id,
|
|
1105
|
+
orgId: this.currUser.orgid
|
|
1106
|
+
})
|
|
1107
|
+
} catch (error) {
|
|
1108
|
+
this.loading = false
|
|
1109
|
+
reject(error)
|
|
1110
|
+
}
|
|
1085
1111
|
})
|
|
1086
1112
|
})
|
|
1087
1113
|
},
|
|
@@ -319,10 +319,11 @@ export default {
|
|
|
319
319
|
})
|
|
320
320
|
},
|
|
321
321
|
scrollToGroup(index) {
|
|
322
|
-
const groupElement = this.$refs[`group-${index}`][0]
|
|
323
|
-
if (groupElement)
|
|
324
|
-
|
|
325
|
-
|
|
322
|
+
const groupElement = this.$refs[`group-${index}`]?.[0]
|
|
323
|
+
if (!groupElement) return
|
|
324
|
+
|
|
325
|
+
this.activeTab = index
|
|
326
|
+
groupElement.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
326
327
|
},
|
|
327
328
|
/**
|
|
328
329
|
* 控制表单组的显示/隐藏
|
|
@@ -413,6 +414,7 @@ export default {
|
|
|
413
414
|
},
|
|
414
415
|
async onSubmit() {
|
|
415
416
|
let pass = true
|
|
417
|
+
let firstFailedIndex = -1
|
|
416
418
|
const promises = this.groups.map((item, index) => {
|
|
417
419
|
const nativeFormRef = this.$refs[`nativeForm-${index}`] ? this.$refs[`nativeForm-${index}`][0] : undefined
|
|
418
420
|
if ((item.groupName || item.slotName) && nativeFormRef && typeof nativeFormRef.asyncSubmit === 'function') {
|
|
@@ -424,7 +426,10 @@ export default {
|
|
|
424
426
|
})
|
|
425
427
|
.catch(_err => {
|
|
426
428
|
pass = false
|
|
427
|
-
|
|
429
|
+
// 记录最靠前的失败组,避免并行校验时多次 scrollToGroup 互相覆盖
|
|
430
|
+
if (firstFailedIndex === -1 || index < firstFailedIndex) {
|
|
431
|
+
firstFailedIndex = index
|
|
432
|
+
}
|
|
428
433
|
})
|
|
429
434
|
} else {
|
|
430
435
|
console.warn(item.groupName + '未找到组件,或者组件没有 asyncSubmit 方法')
|
|
@@ -435,10 +440,12 @@ export default {
|
|
|
435
440
|
|
|
436
441
|
try {
|
|
437
442
|
await Promise.all(promises)
|
|
438
|
-
|
|
439
443
|
if (pass) {
|
|
440
444
|
return Promise.resolve(this.allFormData)
|
|
441
445
|
} else {
|
|
446
|
+
if (firstFailedIndex !== -1) {
|
|
447
|
+
this.scrollToGroup(firstFailedIndex)
|
|
448
|
+
}
|
|
442
449
|
this.$message.error('请检查表单填写是否正确')
|
|
443
450
|
return Promise.reject(new Error('Form validation failed'))
|
|
444
451
|
}
|
|
@@ -1,88 +1,500 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<a-card :bordered="false">
|
|
3
|
+
<x-form-table
|
|
4
|
+
title="档案管理"
|
|
5
|
+
:queryParamsName="queryParamsName"
|
|
6
|
+
@edit="editUser"
|
|
7
|
+
@afterQuery="afterQuery"
|
|
8
|
+
serviceName="af-revenue"
|
|
9
|
+
ref="xFormTable"
|
|
10
|
+
>
|
|
11
|
+
</x-form-table>
|
|
12
|
+
<a-modal
|
|
13
|
+
:confirm-loading="confirmLoading"
|
|
14
|
+
v-model="formModalVisible"
|
|
15
|
+
:dialog-style="{ top: '30px' }"
|
|
16
|
+
:bodyStyle="{ height: '70vh' }"
|
|
17
|
+
:destroy-on-close="true"
|
|
18
|
+
:title="formTitle"
|
|
19
|
+
:keyboard="false"
|
|
20
|
+
@ok="submitAddForm"
|
|
21
|
+
width="85vw"
|
|
22
|
+
>
|
|
23
|
+
<x-form-group ref="xFormGroupDemo" @x-form-item-emit-func="groupFromItemEmitFunc">
|
|
24
|
+
<template #devices="{ data, index }">
|
|
25
|
+
<user-devices
|
|
26
|
+
@setRef="setRef(`nativeForm-${index}`)"
|
|
27
|
+
:ref="`nativeForm-${index}`"
|
|
28
|
+
:data="data"
|
|
29
|
+
></user-devices>
|
|
30
|
+
</template>
|
|
31
|
+
<template #security="{ data, index }">
|
|
32
|
+
<user-security
|
|
33
|
+
@setRef="setRef1(`nativeForm-${index}`)"
|
|
34
|
+
:ref="`nativeForm-${index}`"
|
|
35
|
+
:data="data"
|
|
36
|
+
></user-security>
|
|
37
|
+
</template>
|
|
38
|
+
</x-form-group>
|
|
39
|
+
</a-modal>
|
|
40
|
+
</a-card>
|
|
41
|
+
</template>
|
|
42
|
+
|
|
1
43
|
<script>
|
|
2
|
-
import
|
|
3
|
-
import
|
|
44
|
+
import XFormTable from '@vue2-client/base-client/components/common/XFormTable'
|
|
45
|
+
import XFormGroup from '@vue2-client/base-client/components/common/XFormGroup'
|
|
46
|
+
import XAddNativeForm from '@vue2-client/base-client/components/common/XAddNativeForm'
|
|
47
|
+
import XDescriptionsGroup from '@vue2-client/base-client/components/common/XDescriptions/XDescriptionsGroup.vue'
|
|
48
|
+
import XAddForm from '@vue2-client/base-client/components/common/XAddForm'
|
|
49
|
+
import { mapState } from 'vuex'
|
|
50
|
+
import {getConfigByNameAsync, runLogic} from '@vue2-client/services/api/common'
|
|
51
|
+
import { getRealKeyData } from '@vue2-client/utils/formatter'
|
|
52
|
+
import userInfoDetailManage from '@vue2-client/pages/userInfoDetailManage'
|
|
4
53
|
|
|
5
54
|
export default {
|
|
6
|
-
name: '
|
|
7
|
-
components: {
|
|
55
|
+
name: 'UserFilesManage',
|
|
56
|
+
components: {
|
|
57
|
+
XFormTable,
|
|
58
|
+
XFormGroup,
|
|
59
|
+
XDescriptionsGroup,
|
|
60
|
+
XAddNativeForm,
|
|
61
|
+
XAddForm,
|
|
62
|
+
userInfoDetailManage
|
|
63
|
+
},
|
|
8
64
|
data() {
|
|
9
65
|
return {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
66
|
+
// 查询配置名称
|
|
67
|
+
queryParamsName: 'UserFilesListCRUD',
|
|
68
|
+
// 查询表单赋值
|
|
69
|
+
fixedQueryForm: {},
|
|
70
|
+
// 是否显示详情抽屉
|
|
71
|
+
detailVisible: false,
|
|
72
|
+
userInfoDetailVisible: false,
|
|
73
|
+
// 提交加载动画
|
|
74
|
+
confirmLoading: false,
|
|
75
|
+
// 是否显示详情抽屉
|
|
76
|
+
formModalVisible: false,
|
|
77
|
+
// 是否展示选择地址组件
|
|
78
|
+
selectAddressVisible: false,
|
|
79
|
+
accountClosureShow: false,
|
|
80
|
+
batchCancelUser: false,
|
|
81
|
+
accountClosureType: '',
|
|
82
|
+
oneUserManyMetersShow: false,
|
|
83
|
+
isSyncUser: false,
|
|
84
|
+
keyboard: false,
|
|
85
|
+
// 当前记录
|
|
86
|
+
record: {},
|
|
87
|
+
// 销户启用相关
|
|
88
|
+
enableUserVisible: false,
|
|
89
|
+
enableUserRecord: null,
|
|
90
|
+
enableUserReason: '',
|
|
91
|
+
enableUserLoading: false,
|
|
92
|
+
// 表单组title
|
|
93
|
+
formTitle: '新建档案',
|
|
94
|
+
// 修改设备列表
|
|
95
|
+
editDevices: [],
|
|
96
|
+
// 记录当前页面数据
|
|
97
|
+
curPageData: undefined,
|
|
98
|
+
// 查询参数
|
|
99
|
+
conditionParams: undefined,
|
|
100
|
+
securityDevices: [],
|
|
101
|
+
// 修改备用电话列表
|
|
102
|
+
rentPhone: [],
|
|
103
|
+
// 是否修改过备用电话标识
|
|
104
|
+
isEditRentPhone: false,
|
|
105
|
+
// 选择的省市区列表
|
|
106
|
+
divisions: undefined,
|
|
107
|
+
form: {
|
|
108
|
+
f_address_type: '',
|
|
109
|
+
f_residential_area_id: '',
|
|
110
|
+
f_street: '',
|
|
111
|
+
f_residential_area: '',
|
|
112
|
+
f_iscity: ''
|
|
113
|
+
},
|
|
114
|
+
addressModel: [
|
|
115
|
+
{
|
|
116
|
+
expression: '{f_building}楼号{f_unit}单元{f_floor}楼层{f_room}门牌号',
|
|
117
|
+
label: '城市',
|
|
118
|
+
value: '城市'
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
expression: '{f_building}组{f_unit}号',
|
|
122
|
+
label: '乡镇',
|
|
123
|
+
value: '乡镇'
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
expression: '{f_address}',
|
|
127
|
+
label: '自定义',
|
|
128
|
+
value: '自定义'
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
config: {
|
|
132
|
+
showStreet: false, // 新增地址展示街道
|
|
133
|
+
autoEdit: false, // 选择小区后自动填充表单
|
|
134
|
+
isAutoEdit: false, // 选择小区后自动填充表单
|
|
135
|
+
addAddress: false // 获取定位后重新新建地址
|
|
136
|
+
},
|
|
137
|
+
addAddressFlag: false,
|
|
138
|
+
labelCol: { span: 4 },
|
|
139
|
+
wrapperCol: { span: 20 },
|
|
140
|
+
formItems: [],
|
|
141
|
+
areaList: [],
|
|
142
|
+
streetList: [],
|
|
143
|
+
street: '',
|
|
144
|
+
signContractVisible: false,
|
|
145
|
+
// 当前同步的用户记录
|
|
146
|
+
currentSyncRecord: {},
|
|
147
|
+
// 选中数据
|
|
148
|
+
finalSelectedRows: [],
|
|
149
|
+
// 销户启用表单数据
|
|
150
|
+
enableUserForm: {}
|
|
13
151
|
}
|
|
14
152
|
},
|
|
15
153
|
created() {
|
|
16
|
-
getConfigByNameAsync('
|
|
17
|
-
this
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
})
|
|
154
|
+
getConfigByNameAsync('UserFilesManageConfig', 'af-revenue').then(res => {
|
|
155
|
+
this.config = Object.assign(this.config, res)
|
|
156
|
+
console.log(this.config)
|
|
157
|
+
if (this.config.showStreet) {
|
|
158
|
+
this.getStreetList('')
|
|
159
|
+
} else {
|
|
160
|
+
this.getAreaList('')
|
|
161
|
+
}
|
|
26
162
|
})
|
|
27
163
|
},
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
164
|
+
mounted() {
|
|
165
|
+
this.batchCancelUser = this.$login.r.includes('V4批量销户')
|
|
166
|
+
},
|
|
167
|
+
watch: {
|
|
168
|
+
'form.f_address_type'(newVal, oldVal) {
|
|
169
|
+
this.onAddressTypeChange(newVal, oldVal)
|
|
35
170
|
}
|
|
36
171
|
},
|
|
37
172
|
methods: {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
173
|
+
refresh() {
|
|
174
|
+
this.$refs.xFormTable.refreshTable(true)
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
cancel() {
|
|
178
|
+
this.formCancelUser = false
|
|
179
|
+
this.$refs.xFormTable.refreshTable(true)
|
|
180
|
+
},
|
|
181
|
+
afterQuery(res, conditionParams) {
|
|
182
|
+
console.log('查询触发之后', res, conditionParams)
|
|
183
|
+
res.then(r => {
|
|
184
|
+
this.curPageData = r
|
|
185
|
+
this.conditionParams = conditionParams
|
|
49
186
|
})
|
|
50
187
|
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
188
|
+
|
|
189
|
+
handleSearch(value) {
|
|
190
|
+
this.getAreaList(value)
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
getStreetList(value) {
|
|
194
|
+
runLogic(
|
|
195
|
+
'getStreetListByName',
|
|
196
|
+
{
|
|
197
|
+
orgId: this.currUser.orgid,
|
|
198
|
+
name: value
|
|
199
|
+
},
|
|
200
|
+
'af-revenue'
|
|
201
|
+
).then(res => {
|
|
202
|
+
console.log(res)
|
|
203
|
+
this.streetList = res
|
|
204
|
+
})
|
|
205
|
+
},
|
|
206
|
+
async getAreaList(name) {
|
|
207
|
+
// 新版必须带街道ID
|
|
208
|
+
const params = this.config.showStreet
|
|
209
|
+
? { orgId: this.currUser.orgid, f_street_id: this.street, name }
|
|
210
|
+
: { orgId: this.currUser.orgid, name }
|
|
211
|
+
const res = await runLogic('getAreaListByName', params, 'af-revenue')
|
|
212
|
+
this.areaList = res
|
|
213
|
+
},
|
|
214
|
+
handleChange(value) {
|
|
215
|
+
this.form.f_residential_area = this.areaList.find(item => item.value === value).label
|
|
216
|
+
this.street = this.areaList.find(item => item.value === value).f_street
|
|
217
|
+
},
|
|
218
|
+
onAddressTypeChange(newVal, oldVal) {
|
|
219
|
+
const selectedModel = this.addressModel.find(item => item.value === this.form.f_address_type)
|
|
220
|
+
Object.keys(this.form).forEach(key => {
|
|
221
|
+
if (key.endsWith('_suffix')) {
|
|
222
|
+
this.form[key] = ''
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
console.log('selectedModel' + selectedModel)
|
|
226
|
+
if (selectedModel) {
|
|
227
|
+
const matches = selectedModel.expression.match(/{(.*?)}([^{}]*)(?={|$)/g)
|
|
228
|
+
this.formItems = matches.map(item => {
|
|
229
|
+
const value = item.match(/{(.*?)}/)[1]
|
|
230
|
+
const label = item.replace(/{.*?}/, '').trim()
|
|
231
|
+
// 处理后缀
|
|
232
|
+
this.form[`${value}_suffix`] = label
|
|
233
|
+
return {
|
|
234
|
+
label: label || (value === 'f_address' || value === 'f_room' ? '' : value), // 如果存在后面的文字,就使用后面的文字作为 label,否则使用原来的值
|
|
235
|
+
value: `${value}`
|
|
236
|
+
}
|
|
237
|
+
})
|
|
54
238
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
239
|
+
},
|
|
240
|
+
columnClick(key, value, record) {
|
|
241
|
+
this.record = record
|
|
242
|
+
this.record.f_userinfo_id = record.u_f_userinfo_id
|
|
243
|
+
this.record.f_userinfo_code = record.u_f_userinfo_code
|
|
244
|
+
this.userInfoDetailVisible = true
|
|
245
|
+
},
|
|
246
|
+
setRef(refName) {
|
|
247
|
+
// 给表单组赋值ref
|
|
248
|
+
// 因为提交的时候 表单组需要循环便利 ref 的 提交事件
|
|
249
|
+
this.$refs.xFormGroupDemo.setRef(refName, [this.$refs[refName]])
|
|
250
|
+
this.$refs[refName].init(this.editDevices)
|
|
251
|
+
},
|
|
252
|
+
setRef1(refName) {
|
|
253
|
+
// 给表单组赋值ref
|
|
254
|
+
// 因为提交的时候 表单组需要循环便利 ref 的 提交事件
|
|
255
|
+
this.$refs.xFormGroupDemo.setRef(refName, [this.$refs[refName]])
|
|
256
|
+
this.$refs[refName].init(this.securityDevices)
|
|
257
|
+
},
|
|
258
|
+
editUser(record, id, type) {
|
|
259
|
+
this.confirmLoading = false
|
|
260
|
+
this.formTitle = '编辑档案'
|
|
261
|
+
this.config.autoEdit = false // 编辑档案时选择地址不自动回填
|
|
262
|
+
const _record = getRealKeyData(record)
|
|
263
|
+
getConfigByNameAsync('editUserGeneralInfoFrom', 'af-revenue').then(configRes => {
|
|
264
|
+
runLogic(
|
|
265
|
+
'getFileDetailForEdit',
|
|
266
|
+
{
|
|
267
|
+
f_userinfo_id: _record.f_userinfo_id
|
|
268
|
+
},
|
|
269
|
+
'af-revenue',
|
|
270
|
+
false,
|
|
271
|
+
{
|
|
272
|
+
globalLoading: true
|
|
273
|
+
}
|
|
274
|
+
).then(res => {
|
|
275
|
+
this.formModalVisible = true
|
|
276
|
+
// 组织修改表单
|
|
277
|
+
this.$nextTick(() => {
|
|
278
|
+
this.$refs.xFormGroupDemo.init({
|
|
279
|
+
...configRes,
|
|
280
|
+
serviceName: 'af-revenue',
|
|
281
|
+
showLeftTab: true,
|
|
282
|
+
businessType: '编辑',
|
|
283
|
+
modifyModelData: res
|
|
284
|
+
})
|
|
285
|
+
this.editDevices = res.devices
|
|
286
|
+
this.securityDevices = res.security
|
|
287
|
+
this.rentPhone = res.phones
|
|
288
|
+
})
|
|
289
|
+
})
|
|
290
|
+
})
|
|
291
|
+
},
|
|
292
|
+
addUser() {
|
|
293
|
+
this.formTitle = '新建档案'
|
|
294
|
+
if (this.config.isAutoEdit) {
|
|
295
|
+
this.config.autoEdit = true
|
|
296
|
+
} // 新建档案时选择地址自动回填
|
|
297
|
+
getConfigByNameAsync('addUserGeneralInfoFrom', 'af-revenue').then(res => {
|
|
298
|
+
this.formModalVisible = true
|
|
299
|
+
this.$nextTick(() => {
|
|
300
|
+
this.$refs.xFormGroupDemo.init({
|
|
301
|
+
...res,
|
|
302
|
+
serviceName: 'af-revenue',
|
|
303
|
+
showLeftTab: true,
|
|
304
|
+
businessType: '新增'
|
|
305
|
+
})
|
|
306
|
+
})
|
|
58
307
|
})
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
308
|
+
},
|
|
309
|
+
async submitAddForm() {
|
|
310
|
+
if (this.confirmLoading) return
|
|
311
|
+
this.confirmLoading = true
|
|
312
|
+
await this.$refs.xFormGroupDemo
|
|
313
|
+
.onSubmit()
|
|
314
|
+
.then(res => {
|
|
315
|
+
console.warn('走到这个then了')
|
|
316
|
+
let saveData = Object.assign(res, { divisions: this.divisions })
|
|
317
|
+
if (this.formTitle === '编辑档案') {
|
|
318
|
+
saveData = Object.assign(saveData, {
|
|
319
|
+
f_operator_record: this.currUser.name,
|
|
320
|
+
f_operatorid_record: this.currUser.id,
|
|
321
|
+
f_orgid_record: this.currUser.orgid,
|
|
322
|
+
f_orgname_record: this.currUser.orgs,
|
|
323
|
+
f_depid_record: this.currUser.depids,
|
|
324
|
+
f_depname_record: this.currUser.dops
|
|
325
|
+
})
|
|
326
|
+
}
|
|
327
|
+
// 备用电话赋值
|
|
328
|
+
if (this.isEditRentPhone) {
|
|
329
|
+
saveData = Object.assign(saveData, {
|
|
330
|
+
rentPhone: this.rentPhone
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
if (this.isSyncUser) {
|
|
334
|
+
saveData = Object.assign(saveData, {
|
|
335
|
+
f_send_state: '已同步'
|
|
336
|
+
})
|
|
337
|
+
}
|
|
338
|
+
runLogic('userFIleSaveLogic', saveData, 'af-revenue')
|
|
339
|
+
.then(() => {
|
|
340
|
+
this.confirmLoading = false
|
|
341
|
+
this.formModalVisible = false
|
|
342
|
+
this.isSyncUser = false
|
|
343
|
+
this.$message.success('操作成功')
|
|
344
|
+
this.$refs.xFormTable.refreshTable(true)
|
|
345
|
+
})
|
|
346
|
+
.catch(() => {
|
|
347
|
+
this.confirmLoading = false
|
|
348
|
+
})
|
|
349
|
+
.finally(() => {
|
|
350
|
+
this.confirmLoading = false
|
|
351
|
+
})
|
|
352
|
+
})
|
|
353
|
+
.catch(() => {
|
|
354
|
+
console.warn('走到这个catch了')
|
|
355
|
+
this.confirmLoading = false
|
|
356
|
+
})
|
|
357
|
+
.finally(() => {
|
|
358
|
+
console.warn('走到这个finally了')
|
|
359
|
+
this.confirmLoading = false
|
|
360
|
+
})
|
|
361
|
+
this.confirmLoading = false
|
|
362
|
+
},
|
|
363
|
+
action(record, id, actionType) {
|
|
364
|
+
runLogic(
|
|
365
|
+
'querySingleUserDetail',
|
|
366
|
+
{
|
|
367
|
+
f_userinfo_code: record.u_f_userinfo_code,
|
|
368
|
+
f_userinfo_id: record.u_f_userinfo_id
|
|
369
|
+
},
|
|
370
|
+
'af-revenue'
|
|
371
|
+
).then(res => {
|
|
372
|
+
this.record = res
|
|
373
|
+
this.detailVisible = true
|
|
374
|
+
})
|
|
375
|
+
},
|
|
376
|
+
onClose() {
|
|
377
|
+
this.detailVisible = false
|
|
378
|
+
// 关闭详情之后重新查询表单
|
|
379
|
+
this.$refs.xFormTable.refreshTable(true)
|
|
380
|
+
},
|
|
381
|
+
selAddress(record) {
|
|
382
|
+
// 先填充基本地址信息
|
|
383
|
+
const basicForm = {
|
|
384
|
+
f_address: record.tua_f_address,
|
|
385
|
+
f_address_id: record.tua_id
|
|
386
|
+
}
|
|
387
|
+
this.$refs.xFormGroupDemo.getNativeFormRef('t_userinfo')[0].setForm(basicForm)
|
|
388
|
+
if (!this.config.autoEdit) {
|
|
389
|
+
this.selectAddressVisible = false
|
|
390
|
+
return
|
|
391
|
+
}
|
|
392
|
+
console.log('hy 租户,执行自动填充功能')
|
|
393
|
+
// 通过后端逻辑重新查询t_area表获取完整信息
|
|
394
|
+
runLogic(
|
|
395
|
+
'getAddressDetailById',
|
|
396
|
+
{
|
|
397
|
+
id: record.tua_f_residential_area_id
|
|
398
|
+
},
|
|
399
|
+
'af-revenue'
|
|
400
|
+
)
|
|
401
|
+
.then(res => {
|
|
402
|
+
// 后端返回的是数组,取第一个元素
|
|
403
|
+
const areaData = Array.isArray(res) ? res[0] : res
|
|
404
|
+
if (!areaData) {
|
|
405
|
+
return
|
|
406
|
+
}
|
|
407
|
+
// 给用户信息表单赋值
|
|
408
|
+
const userInfoForm = {}
|
|
409
|
+
if (areaData.f_customer_type) {
|
|
410
|
+
userInfoForm.f_customer_type = areaData.f_customer_type
|
|
411
|
+
}
|
|
412
|
+
if (areaData.f_route_name) {
|
|
413
|
+
userInfoForm.f_route_name = areaData.f_route_name
|
|
414
|
+
}
|
|
415
|
+
if (areaData.f_accounting_area) {
|
|
416
|
+
userInfoForm.f_accounting_area = areaData.f_accounting_area
|
|
417
|
+
}
|
|
418
|
+
if (Object.keys(userInfoForm).length > 0) {
|
|
419
|
+
this.$refs.xFormGroupDemo.getNativeFormRef('t_userinfo')[0].setForm(userInfoForm)
|
|
420
|
+
}
|
|
421
|
+
// 给表具信息表单赋值
|
|
422
|
+
// 1. 先获取当前所有表单数据
|
|
423
|
+
const allFormData = {
|
|
424
|
+
t_userinfo: this.$refs.xFormGroupDemo.getNativeForm('t_userinfo') || {},
|
|
425
|
+
t_userfiles: this.$refs.xFormGroupDemo.getNativeForm('t_userfiles') || {},
|
|
426
|
+
t_userfiles_Other: this.$refs.xFormGroupDemo.getNativeForm('t_userfiles_Other') || {}
|
|
427
|
+
}
|
|
428
|
+
// 2. 合并 t_area 数据
|
|
429
|
+
if (areaData.f_area_code) {
|
|
430
|
+
allFormData.t_userfiles.f_area_code = areaData.f_area_code
|
|
431
|
+
}
|
|
432
|
+
if (areaData.f_meter_brand) {
|
|
433
|
+
allFormData.t_userfiles.f_gasbrand_id = Number(areaData.f_meter_brand)
|
|
434
|
+
}
|
|
435
|
+
if (areaData.f_meter_style) {
|
|
436
|
+
allFormData.t_userfiles.f_gasmodel_id = areaData.f_meter_style
|
|
437
|
+
}
|
|
438
|
+
if (areaData.f_price_name) {
|
|
439
|
+
allFormData.t_userfiles.f_price_id = Number(areaData.f_price_name)
|
|
440
|
+
}
|
|
441
|
+
console.log('准备重新打开表单弹窗,数据:', allFormData)
|
|
442
|
+
// 3. 关闭表单弹窗
|
|
443
|
+
this.formModalVisible = false
|
|
444
|
+
// 4. 延迟后重新打开(让组件完全销毁后重新渲染)
|
|
445
|
+
this.$nextTick(() => {
|
|
446
|
+
setTimeout(() => {
|
|
447
|
+
this.formModalVisible = true
|
|
448
|
+
// 5. 重新初始化表单组
|
|
449
|
+
this.$nextTick(() => {
|
|
450
|
+
getConfigByNameAsync('addUserGeneralInfoFrom', 'af-revenue').then(configRes => {
|
|
451
|
+
this.$refs.xFormGroupDemo.init({
|
|
452
|
+
...configRes,
|
|
453
|
+
serviceName: 'af-revenue',
|
|
454
|
+
showLeftTab: true,
|
|
455
|
+
businessType: '新增',
|
|
456
|
+
modifyModelData: allFormData // 带上合并后的完整数据
|
|
457
|
+
})
|
|
458
|
+
})
|
|
459
|
+
})
|
|
460
|
+
}, 300)
|
|
461
|
+
})
|
|
462
|
+
// 给表具其他信息表单赋值
|
|
463
|
+
const userFilesOtherForm = {}
|
|
464
|
+
if (areaData.f_inputtor) {
|
|
465
|
+
userFilesOtherForm.f_inputtor = areaData.f_inputtor
|
|
466
|
+
}
|
|
467
|
+
if (areaData.f_position) {
|
|
468
|
+
userFilesOtherForm.f_position = areaData.f_position
|
|
469
|
+
}
|
|
470
|
+
if (areaData.f_meter_book_num) {
|
|
471
|
+
userFilesOtherForm.f_meter_book_num = areaData.f_meter_book_num
|
|
472
|
+
}
|
|
473
|
+
if (areaData.f_changetube_date) {
|
|
474
|
+
userFilesOtherForm.f_changetube_date = areaData.f_changetube_date
|
|
475
|
+
}
|
|
476
|
+
if (Object.keys(userFilesOtherForm).length > 0) {
|
|
477
|
+
this.$refs.xFormGroupDemo.getNativeFormRef('t_userfiles_Other')[0].setForm(userFilesOtherForm)
|
|
478
|
+
}
|
|
479
|
+
})
|
|
480
|
+
.catch(err => {
|
|
481
|
+
console.warn('查询t_area表详情失败:', err)
|
|
482
|
+
})
|
|
483
|
+
|
|
484
|
+
this.selectAddressVisible = false
|
|
62
485
|
}
|
|
486
|
+
},
|
|
487
|
+
computed: {
|
|
488
|
+
inputWidth() {
|
|
489
|
+
if (this.formItems.length === 1) {
|
|
490
|
+
return '85%'
|
|
491
|
+
}
|
|
492
|
+
return this.formItems.length ? `${65 / this.formItems.length}%` : '85%'
|
|
493
|
+
},
|
|
494
|
+
...mapState('account', { currUser: 'user' }),
|
|
495
|
+
...mapState('setting', { isMobile: 'isMobile' })
|
|
63
496
|
}
|
|
64
497
|
}
|
|
65
498
|
</script>
|
|
66
499
|
|
|
67
|
-
<
|
|
68
|
-
<a-card>
|
|
69
|
-
<a-button @click="submitForm">提交测试</a-button>
|
|
70
|
-
<a-divider orientation="left">总表单数据</a-divider>
|
|
71
|
-
<pre class="all-form-data-preview">{{ allFormDataJson }}</pre>
|
|
72
|
-
<XFormGroup ref="xFormGroupDemo" @x-form-group-data-change="xFormGroupDataChange" @meter-base-change="meterBaseChange"></XFormGroup>
|
|
73
|
-
</a-card>
|
|
74
|
-
</template>
|
|
75
|
-
|
|
76
|
-
<style scoped lang="less">
|
|
77
|
-
.all-form-data-preview {
|
|
78
|
-
max-height: 320px;
|
|
79
|
-
overflow: auto;
|
|
80
|
-
padding: 12px;
|
|
81
|
-
margin-bottom: 16px;
|
|
82
|
-
font-size: 12px;
|
|
83
|
-
line-height: 1.5;
|
|
84
|
-
background: #fafafa;
|
|
85
|
-
border: 1px solid #f0f0f0;
|
|
86
|
-
border-radius: 4px;
|
|
87
|
-
}
|
|
88
|
-
</style>
|
|
500
|
+
<style scoped></style>
|
|
@@ -60,7 +60,7 @@ routerResource.example = {
|
|
|
60
60
|
// component: () => import('@vue2-client/base-client/components/common/XDescriptions/demo.vue')
|
|
61
61
|
// component: () => import('@vue2-client/base-client/components/his/HChart/demo.vue'),
|
|
62
62
|
// component: () => import('@vue2-client/pages/WorkflowDetail/WorkFlowDemo.vue'),
|
|
63
|
-
component: () => import('@vue2-client/base-client/components/common/XFormTable/demo.vue')
|
|
63
|
+
// component: () => import('@vue2-client/base-client/components/common/XFormTable/demo.vue')
|
|
64
64
|
// component: () => import('@vue2-client/base-client/components/common/AfMap/demo.vue')
|
|
65
65
|
// component: () => import('@vue2-client/base-client/components/common/ImagePreviewModal/demo.vue'),
|
|
66
66
|
// component: () => import('@vue2-client/base-client/components/common/XImagePreview/demo.vue'),
|
|
@@ -70,7 +70,7 @@ routerResource.example = {
|
|
|
70
70
|
// component: () => import('@vue2-client/base-client/components/common/XDescriptions/demo.vue'),
|
|
71
71
|
// component: () => import('@vue2-client/base-client/components/common/XAddNativeForm/demo.vue')
|
|
72
72
|
// component: () => import('@vue2-client/base-client/components/common/XInspectionDetailDrawer/demo.vue')
|
|
73
|
-
|
|
73
|
+
component: () => import('@vue2-client/base-client/components/common/XFormGroup/demo.vue')
|
|
74
74
|
// component: () => import('@vue2-client/base-client/components/common/XReport/XReportDemo.vue'),
|
|
75
75
|
// component: () => import('@vue2-client/base-client/components/common/XReportGrid/XReportDemo.vue'),
|
|
76
76
|
// component: () => import('@vue2-client/base-client/components/common/HIS/demo.vue'),
|
package/src/utils/reg.js
CHANGED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/** 手机号 */
|
|
2
|
+
export const REG_PHONE =
|
|
3
|
+
/^[1](([3][0-9])|([4][01456789])|([5][012356789])|([6][2567])|([7][0-8])|([8][0-9])|([9][012356789]))[0-9]{8}$/
|
|
4
|
+
|
|
5
|
+
/** 邮箱 */
|
|
6
|
+
export const REG_EMAIL = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
|
|
7
|
+
|
|
8
|
+
/** url */
|
|
9
|
+
export const REG_URL =
|
|
10
|
+
/(((^https?:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)$/
|
|
11
|
+
|
|
12
|
+
/** 身份证号校验 */
|
|
13
|
+
export function checkIdNumber (value) {
|
|
14
|
+
if (isMaskedIdNumber(value)) return true
|
|
15
|
+
const psidno = String(value)
|
|
16
|
+
// 1.校验身份证号格式和长度
|
|
17
|
+
const regPsidno = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[X])$)$/
|
|
18
|
+
if (!regPsidno.test(psidno)) {
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
// 2.校验前两位的省份编码是否正确
|
|
22
|
+
const province = { 11: '北京', 12: '天津', 13: '河北', 14: '山西', 15: '内蒙古', 21: '辽宁', 22: '吉林', 23: '黑龙江 ', 31: '上海', 32: '江苏', 33: '浙江', 34: '安徽', 35: '福建', 36: '江西', 37: '山东', 41: '河南', 42: '湖北 ', 43: '湖南', 44: '广东', 45: '广西', 46: '海南', 50: '重庆', 51: '四川', 52: '贵州', 53: '云南', 54: '西藏 ', 61: '陕西', 62: '甘肃', 63: '青海', 64: '宁夏', 65: '新疆', 71: '台湾', 81: '香港', 82: '澳门', 91: '国外' }
|
|
23
|
+
if (!province[Number(psidno.slice(0, 2))]) {
|
|
24
|
+
return false
|
|
25
|
+
}
|
|
26
|
+
// 3.校验出生日期
|
|
27
|
+
if (psidno.length === 15) {
|
|
28
|
+
// 15位号码 省(2位)市(2位)县(2位)年(2位)月(2位)日(2位)校验码(3位)
|
|
29
|
+
const reg = /^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/
|
|
30
|
+
const arrSplit = psidno.match(reg)
|
|
31
|
+
// 15位号码在年份前补 19 或 20
|
|
32
|
+
const year = Number(arrSplit[2].charAt(0)) > 0 ? '19' + arrSplit[2] : '20' + arrSplit[2]
|
|
33
|
+
const month = arrSplit[3]
|
|
34
|
+
const day = arrSplit[4]
|
|
35
|
+
if (!validateBirthday(year, month, day)) {
|
|
36
|
+
return false
|
|
37
|
+
}
|
|
38
|
+
} else if (psidno.length === 18) {
|
|
39
|
+
// 18位号码 省(2位)市(2位)县(2位)年(4位)月(2位)日(2位)校验码(4位)
|
|
40
|
+
const reg = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/
|
|
41
|
+
const arrSplit = psidno.match(reg)
|
|
42
|
+
const year = arrSplit[2]
|
|
43
|
+
const month = arrSplit[3]
|
|
44
|
+
const day = arrSplit[4]
|
|
45
|
+
if (!validateBirthday(year, month, day)) {
|
|
46
|
+
return false
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
// 校验出生日期是否合理
|
|
52
|
+
function validateBirthday (year, month, day) {
|
|
53
|
+
year = Number(year) // 年
|
|
54
|
+
month = Number(month) // 月
|
|
55
|
+
day = Number(day) // 日
|
|
56
|
+
const nowTime = new Date().getTime() // 当前时间戳
|
|
57
|
+
const birthTime = new Date(`${year}-${month}-${day}`).getTime() // 获取出生日期的时间戳
|
|
58
|
+
// 不能是明天出生的吧
|
|
59
|
+
if (birthTime > nowTime) {
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
// 一般人活不到150岁吧
|
|
63
|
+
const nowYear = new Date().getFullYear()
|
|
64
|
+
if ((nowYear - year) > 150) {
|
|
65
|
+
return false
|
|
66
|
+
}
|
|
67
|
+
// 不能是13月出生的吧
|
|
68
|
+
if (month < 1 || month > 12) {
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
71
|
+
// 不能是2月30号、4月31号、5月32号出生的吧
|
|
72
|
+
const date = new Date(year, month, 0) // 获取当月的最后一天
|
|
73
|
+
if (day < 1 || day > date.getDate()) {
|
|
74
|
+
return false
|
|
75
|
+
}
|
|
76
|
+
return true
|
|
77
|
+
}
|
|
78
|
+
// 4.18位号码校验生成的校验码
|
|
79
|
+
if (psidno.length === 18) {
|
|
80
|
+
const Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] // 加权因子
|
|
81
|
+
const parity = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'] // 校验码
|
|
82
|
+
let sum = 0
|
|
83
|
+
for (let i = 0; i < 17; i++) {
|
|
84
|
+
sum += Number(psidno.charAt(i)) * Wi[i]
|
|
85
|
+
}
|
|
86
|
+
if (parity[sum % 11] !== psidno[17]) {
|
|
87
|
+
return false
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return true
|
|
91
|
+
}
|
|
92
|
+
/** 座机号 */
|
|
93
|
+
export const REG_LANDLINE = /\d{3}-\d{8}|\d{4}-\d{7}/
|
|
94
|
+
|
|
95
|
+
/** 营业执照 */
|
|
96
|
+
export const REG_BUSINESS_LICENSE = /^[0-9a-zA-Z]{15}$/
|
|
97
|
+
|
|
98
|
+
/** 手机号 8~11 位脱敏:前 3 + **** + 后 4,如 138****1234 */
|
|
99
|
+
const REG_PHONE_MASKED_MOBILE = /^\d{3}\*{4}\d{4}$/
|
|
100
|
+
|
|
101
|
+
/** 4~7 位号码脱敏:前 2 + (1~4 个 *) + 后 1 */
|
|
102
|
+
const REG_PHONE_MASKED_SHORT = /^\d{2}\*{1,4}\d{1}$/
|
|
103
|
+
|
|
104
|
+
/** 超过 11 位号码脱敏:前 3 + (>=5 个 *) + 后 4 */
|
|
105
|
+
const REG_PHONE_MASKED_LONG = /^\d{3}\*{5,}\d{4}$/
|
|
106
|
+
|
|
107
|
+
/** 带分隔符的座机/手机号脱敏,如 010-1234****5678、0371-123****4567 */
|
|
108
|
+
const REG_PHONE_MASKED_FORMATTED = /^[\d\s\-()]*\*{2,}[\d\s\-()]*$/
|
|
109
|
+
|
|
110
|
+
/** 18 位身份证脱敏:前 6 + ******** + 后 4 */
|
|
111
|
+
const REG_ID_NUMBER_MASKED_18 = /^\d{6}\*{8}[\dX]{4}$/i
|
|
112
|
+
|
|
113
|
+
/** 15 位身份证脱敏:前 6 + ****** + 后 3 */
|
|
114
|
+
const REG_ID_NUMBER_MASKED_15 = /^\d{6}\*{6}\d{3}$/
|
|
115
|
+
|
|
116
|
+
/** 其它长度身份证脱敏:前 6 + (1~8 个 *) + 后 1~4 位 */
|
|
117
|
+
const REG_ID_NUMBER_MASKED_DEFAULT = /^\d{6}\*{1,8}[\dX]{1,4}$/i
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* 判断是否为后端脱敏后的手机号/座机号(脱敏数据跳过格式校验)
|
|
121
|
+
* 规则对齐后端 maskPhone:按纯数字长度分档保留前后位数,中间替换为 *
|
|
122
|
+
*/
|
|
123
|
+
export function isMaskedPhone (phone) {
|
|
124
|
+
if (phone == null || phone === '') return false
|
|
125
|
+
const value = String(phone).trim()
|
|
126
|
+
if (!value.includes('*')) return false
|
|
127
|
+
|
|
128
|
+
if (
|
|
129
|
+
REG_PHONE_MASKED_MOBILE.test(value) ||
|
|
130
|
+
REG_PHONE_MASKED_SHORT.test(value) ||
|
|
131
|
+
REG_PHONE_MASKED_LONG.test(value)
|
|
132
|
+
) {
|
|
133
|
+
return true
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!REG_PHONE_MASKED_FORMATTED.test(value)) return false
|
|
137
|
+
|
|
138
|
+
const digitsOnly = value.replace(/\D/g, '')
|
|
139
|
+
const digitLen = digitsOnly.length
|
|
140
|
+
const starCount = (value.match(/\*/g) || []).length
|
|
141
|
+
|
|
142
|
+
// 8~11 位:保留前 3 后 4,中间 4 个 *
|
|
143
|
+
if (digitLen === 7 && starCount >= 4) return true
|
|
144
|
+
// 4~7 位:保留前 2 后 1
|
|
145
|
+
if (digitLen === 3 && starCount >= 1 && starCount <= 4) return true
|
|
146
|
+
// 超过 11 位:保留前 3 后 4,中间 length-7 个 *
|
|
147
|
+
if (digitLen === 7 && starCount >= 5) return true
|
|
148
|
+
|
|
149
|
+
return starCount >= 2 && digitLen >= 3
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* 判断是否为后端脱敏后的身份证号(脱敏数据跳过格式校验)
|
|
154
|
+
* 规则对齐后端 maskIdNumber
|
|
155
|
+
*/
|
|
156
|
+
export function isMaskedIdNumber (value) {
|
|
157
|
+
if (value == null || value === '') return false
|
|
158
|
+
const idNumber = String(value).trim().toUpperCase()
|
|
159
|
+
if (!idNumber.includes('*')) return false
|
|
160
|
+
|
|
161
|
+
if (idNumber.length === 18 && REG_ID_NUMBER_MASKED_18.test(idNumber)) return true
|
|
162
|
+
if (idNumber.length === 15 && REG_ID_NUMBER_MASKED_15.test(idNumber)) return true
|
|
163
|
+
if (idNumber.length >= 10 && REG_ID_NUMBER_MASKED_DEFAULT.test(idNumber)) return true
|
|
164
|
+
|
|
165
|
+
return false
|
|
166
|
+
}
|