af-mobile-client-vue3 1.1.40 → 1.1.41
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/index.html +1 -0
- package/package.json +5 -4
- package/src/components/core/ImageUploader/index.vue +160 -160
- package/src/components/data/XCellList/index.vue +8 -9
- package/src/components/data/XCellListFilter/index.vue +28 -10
- package/src/components/data/XForm/index.vue +114 -23
- package/src/components/data/XOlMap/utils/wgs84ToGcj02.js +154 -154
- package/src/components/data/XReportForm/index.vue +380 -45
- package/src/utils/queryFormDefaultRangePicker.ts +57 -57
- package/src/views/component/XCellListView/index.vue +19 -59
- package/src/views/component/XFormGroupView/index.vue +2 -42
- package/src/views/component/XFormView/index.vue +13 -119
- package/src/views/component/XFormView/oldindex.vue +70 -0
- package/src/views/component/XOlMapView/XLocationPicker/index.vue +118 -118
- package/src/views/component/XReportFormView/index.vue +1 -1
|
@@ -4,6 +4,8 @@ import XReportFormJsonRender from '@af-mobile-client-vue3/components/data/XRepor
|
|
|
4
4
|
import XSignature from '@af-mobile-client-vue3/components/data/XSignature/index.vue'
|
|
5
5
|
import { getConfigByNameWithoutIndexedDB } from '@af-mobile-client-vue3/services/api/common'
|
|
6
6
|
import {
|
|
7
|
+
showFailToast,
|
|
8
|
+
Toast,
|
|
7
9
|
Button as vanButton,
|
|
8
10
|
Cell as vanCell,
|
|
9
11
|
CellGroup as vanCellGroup,
|
|
@@ -15,6 +17,9 @@ import {
|
|
|
15
17
|
Skeleton as vanSkeleton,
|
|
16
18
|
} from 'vant'
|
|
17
19
|
import { defineEmits, nextTick, reactive, ref, watch } from 'vue'
|
|
20
|
+
// https://calendar.hxkj.vip/
|
|
21
|
+
import VueHashCalendar from 'vue3-hash-calendar'
|
|
22
|
+
import 'vue3-hash-calendar/es/index.css'
|
|
18
23
|
|
|
19
24
|
// ------------------------- 类型定义 -------------------------
|
|
20
25
|
interface configDefine {
|
|
@@ -61,6 +66,12 @@ let timer: NodeJS.Timeout
|
|
|
61
66
|
const scanFinish = ref(false)
|
|
62
67
|
// 折叠面板当前激活的值
|
|
63
68
|
const activeCollapseName = ref('副标题')
|
|
69
|
+
// 日期选择器显示状态
|
|
70
|
+
const showDatePicker = ref(false)
|
|
71
|
+
const showTimePicker = ref(false)
|
|
72
|
+
// 当前操作的日期时间字段
|
|
73
|
+
const currentDateField = ref('')
|
|
74
|
+
const currentTimeField = ref('')
|
|
64
75
|
|
|
65
76
|
watch(() => props.configName, () => {
|
|
66
77
|
// 这里是你的处理逻辑
|
|
@@ -107,8 +118,128 @@ function onClickLeft(): void {
|
|
|
107
118
|
history.back()
|
|
108
119
|
}
|
|
109
120
|
|
|
121
|
+
function generateDefaultRequiredMessage(field: any): string {
|
|
122
|
+
const label = field.label || field.text || field.valueText || ''
|
|
123
|
+
|
|
124
|
+
switch (field.type) {
|
|
125
|
+
case 'input':
|
|
126
|
+
return `请填写${label || '此项'}`
|
|
127
|
+
case 'datePicker':
|
|
128
|
+
return `请选择${label || '日期'}`
|
|
129
|
+
case 'timePicker':
|
|
130
|
+
return `请选择${label || '时间'}`
|
|
131
|
+
case 'curDateInput':
|
|
132
|
+
return `请设置${label || '时间'}`
|
|
133
|
+
case 'signature':
|
|
134
|
+
return `请完成${label || '签名'}`
|
|
135
|
+
case 'images':
|
|
136
|
+
return `请上传${label || '图片'}`
|
|
137
|
+
case 'inputs':
|
|
138
|
+
return `请完成${label || '此项'}的填写`
|
|
139
|
+
default:
|
|
140
|
+
return `请完成${label || '此项'}的填写`
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 检查字段值是否为空
|
|
145
|
+
function isFieldEmpty(value: any): boolean {
|
|
146
|
+
if (value === null || value === undefined || value === '') {
|
|
147
|
+
return true
|
|
148
|
+
}
|
|
149
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
150
|
+
return true
|
|
151
|
+
}
|
|
152
|
+
if (typeof value === 'object' && Object.keys(value).length === 0) {
|
|
153
|
+
return true
|
|
154
|
+
}
|
|
155
|
+
return false
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 表单校验
|
|
159
|
+
function validateForm(): boolean {
|
|
160
|
+
const errors: string[] = []
|
|
161
|
+
|
|
162
|
+
// 校验主表单字段
|
|
163
|
+
activatedConfig.columns.forEach((row: any) => {
|
|
164
|
+
if (row.required === true) {
|
|
165
|
+
const dataIndex = row.dataIndex
|
|
166
|
+
let value
|
|
167
|
+
|
|
168
|
+
if (dataIndex.includes('@@@')) {
|
|
169
|
+
value = activatedConfig.tempData?.[dataIndex]
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
if (row.type === 'images') {
|
|
173
|
+
value = activatedConfig.data.images?.[dataIndex]
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
value = activatedConfig.data[dataIndex]
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (isFieldEmpty(value)) {
|
|
181
|
+
const message = row.requiredMessage || generateDefaultRequiredMessage(row)
|
|
182
|
+
errors.push(message)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// 校验动态行中的字段
|
|
187
|
+
if (row.type === 'inputColumns' && row.definition) {
|
|
188
|
+
const dynamicData = activatedConfig.data[row.dataIndex]
|
|
189
|
+
if (Array.isArray(dynamicData)) {
|
|
190
|
+
dynamicData.forEach((item: any, index: number) => {
|
|
191
|
+
row.definition.forEach((def: any) => {
|
|
192
|
+
if (def.required === true) {
|
|
193
|
+
const value = item[def.dataIndex]
|
|
194
|
+
if (isFieldEmpty(value)) {
|
|
195
|
+
const message = def.requiredMessage || generateDefaultRequiredMessage(def)
|
|
196
|
+
errors.push(`第${index + 1}行:${message}`)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
// 校验副标题字段(如果有的话)
|
|
206
|
+
if (activatedConfig.subTitle) {
|
|
207
|
+
activatedConfig.subTitle.forEach((subCell: any) => {
|
|
208
|
+
if (subCell.required === true) {
|
|
209
|
+
const value = activatedConfig.data[subCell.dataIndex]
|
|
210
|
+
if (isFieldEmpty(value)) {
|
|
211
|
+
const message = subCell.requiredMessage || generateDefaultRequiredMessage(subCell)
|
|
212
|
+
errors.push(message)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (errors.length > 0) {
|
|
219
|
+
// 显示第一个错误信息
|
|
220
|
+
showFailToast(errors[0])
|
|
221
|
+
|
|
222
|
+
return false
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return true
|
|
226
|
+
}
|
|
227
|
+
|
|
110
228
|
// 提交按钮
|
|
111
229
|
function onSubmit(): void {
|
|
230
|
+
// 调试:打印所有字段的required状态
|
|
231
|
+
console.log('所有字段配置:', activatedConfig.columns.map(row => ({
|
|
232
|
+
type: row.type,
|
|
233
|
+
label: row.label,
|
|
234
|
+
required: row.required,
|
|
235
|
+
dataIndex: row.dataIndex,
|
|
236
|
+
})))
|
|
237
|
+
|
|
238
|
+
// 先进行表单校验
|
|
239
|
+
if (!validateForm()) {
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
|
|
112
243
|
if (activatedConfig.tempData) {
|
|
113
244
|
const keys = Object.keys(activatedConfig.tempData)
|
|
114
245
|
keys.forEach((key) => {
|
|
@@ -339,6 +470,8 @@ function formatConfigToForm(config: configDefine): void {
|
|
|
339
470
|
inputReadOnly?: boolean
|
|
340
471
|
content?: Array<any>
|
|
341
472
|
text?: string
|
|
473
|
+
required?: boolean
|
|
474
|
+
requiredMessage?: string
|
|
342
475
|
} = {
|
|
343
476
|
label: '',
|
|
344
477
|
type: undefined,
|
|
@@ -411,16 +544,31 @@ function formatConfigToForm(config: configDefine): void {
|
|
|
411
544
|
tempObj.type = 'input'
|
|
412
545
|
if (row[j].inputReadOnly)
|
|
413
546
|
tempObj.inputReadOnly = true
|
|
547
|
+
tempObj.required = row[j].required
|
|
414
548
|
break
|
|
415
549
|
case 'curDateInput' :
|
|
416
550
|
tempObj.dataIndex = row[j].dataIndex
|
|
417
551
|
tempObj.text = row[j].text
|
|
418
552
|
tempObj.type = 'curDateInput'
|
|
553
|
+
tempObj.required = row[j].required
|
|
554
|
+
break
|
|
555
|
+
case 'datePicker' :
|
|
556
|
+
tempObj.dataIndex = row[j].dataIndex
|
|
557
|
+
tempObj.text = row[j].text
|
|
558
|
+
tempObj.type = 'datePicker'
|
|
559
|
+
tempObj.required = row[j].required
|
|
560
|
+
break
|
|
561
|
+
case 'timePicker' :
|
|
562
|
+
tempObj.dataIndex = row[j].dataIndex
|
|
563
|
+
tempObj.text = row[j].text
|
|
564
|
+
tempObj.type = 'timePicker'
|
|
565
|
+
tempObj.required = row[j].required
|
|
419
566
|
break
|
|
420
567
|
case 'signature' :
|
|
421
568
|
tempObj.dataIndex = row[j].dataIndex
|
|
422
569
|
tempObj.text = row[j].text
|
|
423
570
|
tempObj.type = 'signature'
|
|
571
|
+
tempObj.required = row[j].required
|
|
424
572
|
break
|
|
425
573
|
case 'inputs' :
|
|
426
574
|
if (!tempObj.format)
|
|
@@ -598,21 +746,33 @@ function initComponent() {
|
|
|
598
746
|
Object.assign(activatedConfig.data, props.configData)
|
|
599
747
|
|
|
600
748
|
activatedConfig.columns.forEach((row) => {
|
|
601
|
-
row.
|
|
602
|
-
if (
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
749
|
+
if (row.dataIndex && row.dataIndex.includes('@@@')) {
|
|
750
|
+
if (!activatedConfig.tempData) {
|
|
751
|
+
activatedConfig.tempData = {}
|
|
752
|
+
}
|
|
753
|
+
if (row.type === 'images') {
|
|
754
|
+
activatedConfig.tempData[row.dataIndex] = getDeepObject(activatedConfig.data.images, row.dataIndex)
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
activatedConfig.tempData[row.dataIndex] = getDeepObject(activatedConfig.data, row.dataIndex)
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
// 为了兼容旧的结构,保留原有的逻辑
|
|
761
|
+
if (row.forEach) {
|
|
762
|
+
row.forEach((item) => {
|
|
763
|
+
if (item.dataIndex && item.dataIndex.includes('@@@')) {
|
|
764
|
+
if (!activatedConfig.tempData) {
|
|
765
|
+
activatedConfig.tempData = {}
|
|
766
|
+
}
|
|
767
|
+
if (item.type === 'images') {
|
|
612
768
|
activatedConfig.tempData[item.dataIndex] = getDeepObject(activatedConfig.data.images, item.dataIndex)
|
|
769
|
+
}
|
|
770
|
+
else {
|
|
771
|
+
activatedConfig.tempData[item.dataIndex] = getDeepObject(activatedConfig.data, item.dataIndex)
|
|
772
|
+
}
|
|
613
773
|
}
|
|
614
|
-
}
|
|
615
|
-
}
|
|
774
|
+
})
|
|
775
|
+
}
|
|
616
776
|
})
|
|
617
777
|
console.warn('初始化完成,配置:', activatedConfig)
|
|
618
778
|
}
|
|
@@ -694,6 +854,46 @@ function getNow() {
|
|
|
694
854
|
const seconds = String(date.getSeconds()).padStart(2, '0')
|
|
695
855
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
|
696
856
|
}
|
|
857
|
+
|
|
858
|
+
// 打开日期选择器
|
|
859
|
+
function openDatePicker(dataIndex: string) {
|
|
860
|
+
console.log('打开日期选择器:', dataIndex)
|
|
861
|
+
currentDateField.value = dataIndex
|
|
862
|
+
showDatePicker.value = true
|
|
863
|
+
console.log('日期选择器状态:', showDatePicker.value)
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// 打开时间选择器
|
|
867
|
+
function openTimePicker(dataIndex: string) {
|
|
868
|
+
console.log('打开时间选择器:', dataIndex)
|
|
869
|
+
currentTimeField.value = dataIndex
|
|
870
|
+
showTimePicker.value = true
|
|
871
|
+
console.log('时间选择器状态:', showTimePicker.value)
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// 确认选择日期
|
|
875
|
+
function onConfirmDate(value: any) {
|
|
876
|
+
console.log('onConfirmDate', value)
|
|
877
|
+
activatedConfig.data[currentDateField.value] = value
|
|
878
|
+
showDatePicker.value = false
|
|
879
|
+
currentDateField.value = ''
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
// 确认选择时间
|
|
883
|
+
function onConfirmTime(value: any) {
|
|
884
|
+
console.log('onConfirmTime', value)
|
|
885
|
+
activatedConfig.data[currentTimeField.value] = value
|
|
886
|
+
showTimePicker.value = false
|
|
887
|
+
currentTimeField.value = ''
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
// 取消选择
|
|
891
|
+
function onCancelPicker() {
|
|
892
|
+
showDatePicker.value = false
|
|
893
|
+
showTimePicker.value = false
|
|
894
|
+
currentDateField.value = ''
|
|
895
|
+
currentTimeField.value = ''
|
|
896
|
+
}
|
|
697
897
|
</script>
|
|
698
898
|
|
|
699
899
|
<template>
|
|
@@ -760,7 +960,7 @@ function getNow() {
|
|
|
760
960
|
<van-cell center :title="row.label" :value="row.valueText" />
|
|
761
961
|
</van-cell-group>
|
|
762
962
|
<!-- input -->
|
|
763
|
-
<van-cell-group v-else-if="row.type === 'input'" inset class="cell_group" :title="row.label">
|
|
963
|
+
<van-cell-group v-else-if="row.type === 'input'" inset class="cell_group" :title="row.label" :class="{ 'required-field': row.required }">
|
|
764
964
|
<template v-if="row.inputReadOnly === true">
|
|
765
965
|
<template v-if="row.dataIndex.includes('@@@')">
|
|
766
966
|
<van-field
|
|
@@ -814,21 +1014,34 @@ function getNow() {
|
|
|
814
1014
|
</van-cell-group>
|
|
815
1015
|
<!-- curDateInput -->
|
|
816
1016
|
<van-cell-group v-else-if="row.type === 'curDateInput'" inset style="margin-top: 4vh">
|
|
817
|
-
<
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
<
|
|
827
|
-
<van-button
|
|
828
|
-
|
|
1017
|
+
<div class="cur-date-input-container">
|
|
1018
|
+
<div class="cur-date-input-content">
|
|
1019
|
+
<div class="cur-date-input-label">
|
|
1020
|
+
{{ row.valueText || '当前时间' }}
|
|
1021
|
+
</div>
|
|
1022
|
+
<div class="cur-date-input-value">
|
|
1023
|
+
{{ activatedConfig.data[row.dataIndex] || '未设置' }}
|
|
1024
|
+
</div>
|
|
1025
|
+
</div>
|
|
1026
|
+
<div class="cur-date-input-action">
|
|
1027
|
+
<van-button
|
|
1028
|
+
v-if="!activatedConfig.data[row.dataIndex]"
|
|
1029
|
+
size="small"
|
|
1030
|
+
type="primary"
|
|
1031
|
+
@click="activatedConfig.data[row.dataIndex] = getNow()"
|
|
1032
|
+
>
|
|
1033
|
+
{{ row.text || '设置时间' }}
|
|
829
1034
|
</van-button>
|
|
830
|
-
|
|
831
|
-
|
|
1035
|
+
<van-button
|
|
1036
|
+
v-else
|
|
1037
|
+
size="small"
|
|
1038
|
+
type="default"
|
|
1039
|
+
@click="activatedConfig.data[row.dataIndex] = getNow()"
|
|
1040
|
+
>
|
|
1041
|
+
{{ row.text || '重新设置' }}
|
|
1042
|
+
</van-button>
|
|
1043
|
+
</div>
|
|
1044
|
+
</div>
|
|
832
1045
|
</van-cell-group>
|
|
833
1046
|
<!-- signature -->
|
|
834
1047
|
<van-cell-group v-else-if="row.type === 'signature'" inset style="margin-top: 4vh">
|
|
@@ -843,8 +1056,28 @@ function getNow() {
|
|
|
843
1056
|
</template>
|
|
844
1057
|
</van-field>
|
|
845
1058
|
</van-cell-group>
|
|
1059
|
+
<!-- datePicker -->
|
|
1060
|
+
<van-cell-group v-else-if="row.type === 'datePicker'" inset :title="row.label" :class="{ 'required-field': row.required }">
|
|
1061
|
+
<van-field
|
|
1062
|
+
v-model="activatedConfig.data[row.dataIndex]"
|
|
1063
|
+
:label="`${row.label || '日期'}:`"
|
|
1064
|
+
placeholder="请选择日期"
|
|
1065
|
+
readonly
|
|
1066
|
+
@click="openDatePicker(row.dataIndex)"
|
|
1067
|
+
/>
|
|
1068
|
+
</van-cell-group>
|
|
1069
|
+
<!-- timePicker -->
|
|
1070
|
+
<van-cell-group v-else-if="row.type === 'timePicker'" inset :title="row.label" :class="{ 'required-field': row.required }">
|
|
1071
|
+
<van-field
|
|
1072
|
+
v-model="activatedConfig.data[row.dataIndex]"
|
|
1073
|
+
:label="`${row.label || '时间'}:`"
|
|
1074
|
+
placeholder="请选择时间"
|
|
1075
|
+
readonly
|
|
1076
|
+
@click="openTimePicker(row.dataIndex)"
|
|
1077
|
+
/>
|
|
1078
|
+
</van-cell-group>
|
|
846
1079
|
<!-- inputs -->
|
|
847
|
-
<van-cell-group v-else-if="row.type === 'inputs'" inset :title="row.label">
|
|
1080
|
+
<van-cell-group v-else-if="row.type === 'inputs'" inset :title="row.label || ''" :class="{ 'required-field': row.required }">
|
|
848
1081
|
<template v-if="row.inputReadOnly === true">
|
|
849
1082
|
<template v-for="(item, _index) in formatInputs(row)" :key="_index">
|
|
850
1083
|
<van-field
|
|
@@ -902,22 +1135,36 @@ function getNow() {
|
|
|
902
1135
|
<van-cell-group inset :title="row.label" style="background-color: #eff2f5">
|
|
903
1136
|
<van-cell-group v-for="(_item, _index) in activatedConfig.data[row.dataIndex]" :key="_index" inset class="my-cell-group" style="margin: 0 0 10px 0">
|
|
904
1137
|
<div v-for="(def, defIndex) in row.definition" :key="defIndex">
|
|
905
|
-
<
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1138
|
+
<template v-if="def.type === 'curDateInput'">
|
|
1139
|
+
<div class="cur-date-input-container">
|
|
1140
|
+
<div class="cur-date-input-content">
|
|
1141
|
+
<div class="cur-date-input-label">
|
|
1142
|
+
{{ def.label }}
|
|
1143
|
+
</div>
|
|
1144
|
+
<div class="cur-date-input-value">
|
|
1145
|
+
{{ activatedConfig.data[row.dataIndex][_index][def.dataIndex] || '未设置' }}
|
|
1146
|
+
</div>
|
|
1147
|
+
</div>
|
|
1148
|
+
<div class="cur-date-input-action">
|
|
1149
|
+
<van-button
|
|
1150
|
+
v-if="!activatedConfig.data[row.dataIndex][_index][def.dataIndex]"
|
|
1151
|
+
size="small"
|
|
1152
|
+
type="primary"
|
|
1153
|
+
@click="activatedConfig.data[row.dataIndex][_index][def.dataIndex] = getNow()"
|
|
1154
|
+
>
|
|
1155
|
+
{{ def.text || '设置时间' }}
|
|
1156
|
+
</van-button>
|
|
1157
|
+
<van-button
|
|
1158
|
+
v-else
|
|
1159
|
+
size="small"
|
|
1160
|
+
type="default"
|
|
1161
|
+
@click="activatedConfig.data[row.dataIndex][_index][def.dataIndex] = getNow()"
|
|
1162
|
+
>
|
|
1163
|
+
{{ def.text || '重新设置' }}
|
|
1164
|
+
</van-button>
|
|
1165
|
+
</div>
|
|
1166
|
+
</div>
|
|
1167
|
+
</template>
|
|
921
1168
|
<van-field
|
|
922
1169
|
v-else
|
|
923
1170
|
v-model="activatedConfig.data[row.dataIndex][_index][def.dataIndex]"
|
|
@@ -927,6 +1174,7 @@ function getNow() {
|
|
|
927
1174
|
autosize
|
|
928
1175
|
:placeholder="`请输入${def.label}`"
|
|
929
1176
|
clearable
|
|
1177
|
+
:class="{ 'required-field': def.required }"
|
|
930
1178
|
/>
|
|
931
1179
|
</div>
|
|
932
1180
|
</van-cell-group>
|
|
@@ -986,6 +1234,10 @@ function getNow() {
|
|
|
986
1234
|
<div v-else class="skeleton">
|
|
987
1235
|
<van-skeleton title :row="5" />
|
|
988
1236
|
</div>
|
|
1237
|
+
|
|
1238
|
+
<!-- 日期选择器弹窗 -->
|
|
1239
|
+
<VueHashCalendar v-model:visible="showDatePicker" format="YY-MM-DD" model="dialog" picker-type="date" @confirm="onConfirmDate" />
|
|
1240
|
+
<VueHashCalendar v-model:visible="showTimePicker" format="YY-MM-DD hh:mm:ss" picker-type="datetime" model="dialog" @confirm="onConfirmTime" />
|
|
989
1241
|
</template>
|
|
990
1242
|
|
|
991
1243
|
<style scoped lang="less">
|
|
@@ -1069,6 +1321,25 @@ function getNow() {
|
|
|
1069
1321
|
:deep(.van-field__label) {
|
|
1070
1322
|
font-weight: 600;
|
|
1071
1323
|
}
|
|
1324
|
+
|
|
1325
|
+
// 必填字段星号样式 - 只对星号生效
|
|
1326
|
+
:deep(.van-field__label) {
|
|
1327
|
+
// 将包含星号的文本进行特殊处理
|
|
1328
|
+
&[style*="color"] {
|
|
1329
|
+
color: #323233 !important;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
// 使用自定义类名来处理必填字段
|
|
1334
|
+
.required-field :deep(.van-field__label) {
|
|
1335
|
+
color: #323233;
|
|
1336
|
+
|
|
1337
|
+
&::before {
|
|
1338
|
+
content: '*';
|
|
1339
|
+
color: #ee0a24;
|
|
1340
|
+
margin-right: 2px;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1072
1343
|
:deep(.van-uploader__wrapper){
|
|
1073
1344
|
padding: 10px;
|
|
1074
1345
|
display: flex;
|
|
@@ -1076,4 +1347,68 @@ function getNow() {
|
|
|
1076
1347
|
justify-content: space-between; /* 水平方向上左右分散对齐 */
|
|
1077
1348
|
align-items: center; /* 垂直方向上上下中心对齐 */
|
|
1078
1349
|
}
|
|
1350
|
+
|
|
1351
|
+
// 自定义的当前日期输入框样式
|
|
1352
|
+
.cur-date-input-container {
|
|
1353
|
+
padding: 16px;
|
|
1354
|
+
display: flex;
|
|
1355
|
+
align-items: flex-start;
|
|
1356
|
+
justify-content: space-between;
|
|
1357
|
+
background: white;
|
|
1358
|
+
border-radius: 8px;
|
|
1359
|
+
|
|
1360
|
+
.cur-date-input-content {
|
|
1361
|
+
flex: 1;
|
|
1362
|
+
margin-right: 12px;
|
|
1363
|
+
min-width: 0; // 防止flex子元素撑破容器
|
|
1364
|
+
|
|
1365
|
+
.cur-date-input-label {
|
|
1366
|
+
font-size: 14px;
|
|
1367
|
+
font-weight: 600;
|
|
1368
|
+
color: #323233;
|
|
1369
|
+
line-height: 1.4;
|
|
1370
|
+
margin-bottom: 4px;
|
|
1371
|
+
word-wrap: break-word;
|
|
1372
|
+
white-space: normal;
|
|
1373
|
+
display: -webkit-box;
|
|
1374
|
+
-webkit-line-clamp: 2; // 最多显示2行
|
|
1375
|
+
-webkit-box-orient: vertical;
|
|
1376
|
+
overflow: hidden;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
.cur-date-input-value {
|
|
1380
|
+
font-size: 15px;
|
|
1381
|
+
font-weight: 600;
|
|
1382
|
+
color: #666;
|
|
1383
|
+
line-height: 1.3;
|
|
1384
|
+
word-wrap: break-word;
|
|
1385
|
+
white-space: normal;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
.cur-date-input-action {
|
|
1390
|
+
flex-shrink: 0;
|
|
1391
|
+
display: flex;
|
|
1392
|
+
align-items: center;
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
// 动态行中的当前日期输入框样式调整
|
|
1397
|
+
.my-cell-group .cur-date-input-container {
|
|
1398
|
+
padding: 12px;
|
|
1399
|
+
margin: 8px 0;
|
|
1400
|
+
|
|
1401
|
+
.cur-date-input-content {
|
|
1402
|
+
margin-right: 8px;
|
|
1403
|
+
|
|
1404
|
+
.cur-date-input-label {
|
|
1405
|
+
font-size: 13px;
|
|
1406
|
+
margin-bottom: 2px;
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
.cur-date-input-value {
|
|
1410
|
+
font-size: 12px;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1079
1414
|
</style>
|
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 根据类型获取日期区间字符串
|
|
3
|
-
* @param type '当年' | 'curMonth' | '当日'
|
|
4
|
-
* @param show 区分实际值还是显示值, true为实际值, false为显示值
|
|
5
|
-
* @returns [start, end] 例:['2024-01-01 00:00:00', '2024-12-31 23:59:59']
|
|
6
|
-
*/
|
|
7
|
-
export function getRangeByType(type: string, show: boolean): [string, string] {
|
|
8
|
-
const now = new Date()
|
|
9
|
-
const year = now.getFullYear()
|
|
10
|
-
const month = (now.getMonth() + 1).toString().padStart(2, '0')
|
|
11
|
-
const day = now.getDate().toString().padStart(2, '0')
|
|
12
|
-
|
|
13
|
-
if (!show) {
|
|
14
|
-
if (type === 'curYear') {
|
|
15
|
-
return [
|
|
16
|
-
`${year}-01-01 00:00:00`,
|
|
17
|
-
`${year}-12-31 23:59:59`,
|
|
18
|
-
]
|
|
19
|
-
}
|
|
20
|
-
if (type === 'curMonth') {
|
|
21
|
-
const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
|
|
22
|
-
return [
|
|
23
|
-
`${year}-${month}-01 00:00:00`,
|
|
24
|
-
`${year}-${month}-${lastDay.toString().padStart(2, '0')} 23:59:59`,
|
|
25
|
-
]
|
|
26
|
-
}
|
|
27
|
-
if (type === 'curDay') {
|
|
28
|
-
return [
|
|
29
|
-
`${year}-${month}-${day} 00:00:00`,
|
|
30
|
-
`${year}-${month}-${day} 23:59:59`,
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
if (show) {
|
|
35
|
-
if (type === 'curYear') {
|
|
36
|
-
return [
|
|
37
|
-
`${year}-01-01`,
|
|
38
|
-
`${year}-12-31`,
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
if (type === 'curMonth') {
|
|
42
|
-
const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
|
|
43
|
-
return [
|
|
44
|
-
`${year}-${month}-01`,
|
|
45
|
-
`${year}-${month}-${lastDay.toString().padStart(2, '0')}`,
|
|
46
|
-
]
|
|
47
|
-
}
|
|
48
|
-
if (type === 'curDay') {
|
|
49
|
-
return [
|
|
50
|
-
`${year}-${month}-${day}`,
|
|
51
|
-
`${year}-${month}-${day}`,
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// 兜底返回空字符串数组
|
|
56
|
-
return ['', '']
|
|
57
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 根据类型获取日期区间字符串
|
|
3
|
+
* @param type '当年' | 'curMonth' | '当日'
|
|
4
|
+
* @param show 区分实际值还是显示值, true为实际值, false为显示值
|
|
5
|
+
* @returns [start, end] 例:['2024-01-01 00:00:00', '2024-12-31 23:59:59']
|
|
6
|
+
*/
|
|
7
|
+
export function getRangeByType(type: string, show: boolean): [string, string] {
|
|
8
|
+
const now = new Date()
|
|
9
|
+
const year = now.getFullYear()
|
|
10
|
+
const month = (now.getMonth() + 1).toString().padStart(2, '0')
|
|
11
|
+
const day = now.getDate().toString().padStart(2, '0')
|
|
12
|
+
|
|
13
|
+
if (!show) {
|
|
14
|
+
if (type === 'curYear') {
|
|
15
|
+
return [
|
|
16
|
+
`${year}-01-01 00:00:00`,
|
|
17
|
+
`${year}-12-31 23:59:59`,
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
if (type === 'curMonth') {
|
|
21
|
+
const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
|
|
22
|
+
return [
|
|
23
|
+
`${year}-${month}-01 00:00:00`,
|
|
24
|
+
`${year}-${month}-${lastDay.toString().padStart(2, '0')} 23:59:59`,
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
if (type === 'curDay') {
|
|
28
|
+
return [
|
|
29
|
+
`${year}-${month}-${day} 00:00:00`,
|
|
30
|
+
`${year}-${month}-${day} 23:59:59`,
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (show) {
|
|
35
|
+
if (type === 'curYear') {
|
|
36
|
+
return [
|
|
37
|
+
`${year}-01-01`,
|
|
38
|
+
`${year}-12-31`,
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
if (type === 'curMonth') {
|
|
42
|
+
const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
|
|
43
|
+
return [
|
|
44
|
+
`${year}-${month}-01`,
|
|
45
|
+
`${year}-${month}-${lastDay.toString().padStart(2, '0')}`,
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
if (type === 'curDay') {
|
|
49
|
+
return [
|
|
50
|
+
`${year}-${month}-${day}`,
|
|
51
|
+
`${year}-${month}-${day}`,
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// 兜底返回空字符串数组
|
|
56
|
+
return ['', '']
|
|
57
|
+
}
|