af-mobile-client-vue3 1.1.8 → 1.1.9
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/.env +6 -6
- package/.env.development +4 -4
- package/.env.envoiceShow +6 -6
- package/.env.production +6 -6
- package/.husky/commit-msg +1 -1
- package/.husky/pre-commit +1 -1
- package/.vscode/settings.json +61 -61
- package/mock/modules/user.mock.ts +152 -152
- package/package.json +1 -1
- package/public/favicon.svg +4 -4
- package/public/safari-pinned-tab.svg +32 -32
- package/scripts/verifyCommit.js +19 -19
- package/src/App.vue +43 -43
- package/src/api/user/index.ts +40 -40
- package/src/bootstrap.ts +18 -18
- package/src/components/core/NavBar/index.vue +12 -12
- package/src/components/core/Tabbar/index.vue +38 -38
- package/src/components/core/XGridDropOption/index.vue +151 -151
- package/src/components/core/XMultiSelect/index.vue +183 -183
- package/src/components/data/XCellDetail/index.vue +106 -106
- package/src/components/data/XFormItem/index.vue +26 -7
- package/src/components/data/XOlMap/XLocationPicker/index.vue +7 -9
- package/src/components/data/XOlMap/index.vue +103 -96
- package/src/components/data/XOlMap/utils/wgs84ToGcj02.js +154 -154
- package/src/components/data/XReportForm/XReportFormJsonRender.vue +220 -220
- package/src/components/data/XReportForm/index.vue +1079 -1079
- package/src/components/data/XReportGrid/XAddReport/index.ts +1 -1
- package/src/components/data/XReportGrid/XReportDrawer/index.ts +1 -1
- package/src/components/data/XSignature/index.vue +285 -285
- package/src/components/data/XTag/index.vue +10 -10
- package/src/components/layout/NormalDataLayout/index.vue +70 -70
- package/src/components/layout/TabBarLayout/index.vue +40 -40
- package/src/components.d.ts +53 -53
- package/src/env.d.ts +16 -16
- package/src/font-style/font.css +3 -3
- package/src/hooks/useCommon.ts +9 -9
- package/src/locales/en-US.json +25 -25
- package/src/locales/zh-CN.json +25 -25
- package/src/plugins/AppData.ts +38 -38
- package/src/router/guards.ts +59 -59
- package/src/router/index.ts +61 -61
- package/src/router/invoiceRoutes.ts +33 -33
- package/src/services/api/common.ts +109 -109
- package/src/services/api/manage.ts +8 -8
- package/src/services/api/search.ts +16 -16
- package/src/services/restTools.ts +56 -56
- package/src/services/v3Api.ts +11 -11
- package/src/stores/modules/setting.ts +52 -52
- package/src/stores/mutation-type.ts +7 -7
- package/src/utils/authority-utils.ts +84 -84
- package/src/utils/crypto.ts +39 -39
- package/src/utils/i18n.ts +41 -41
- package/src/utils/indexedDB.ts +180 -180
- package/src/utils/mobileUtil.ts +26 -26
- package/src/utils/routerUtil.ts +271 -271
- package/src/utils/runEvalFunction.ts +13 -13
- package/src/utils/wechatUtil.ts +9 -9
- package/src/views/common/LoadError.vue +64 -64
- package/src/views/common/NotFound.vue +68 -68
- package/src/views/component/EvaluateRecordView/index.vue +40 -40
- package/src/views/component/XCellDetailView/index.vue +217 -217
- package/src/views/component/XCellListView/index.vue +3 -88
- package/src/views/component/XFormGroupView/index.vue +0 -37
- package/src/views/component/XFormView/index.vue +30 -119
- package/src/views/component/XFormView/oldindex.vue +50 -0
- package/src/views/component/XOlMapView/XLocationPicker/index.vue +118 -120
- package/src/views/component/XOlMapView/index.vue +3 -5
- package/src/views/component/XReportFormIframeView/index.vue +47 -47
- package/src/views/component/XReportFormView/index.vue +13 -13
- package/src/views/component/XSignatureView/index.vue +50 -50
- package/src/views/component/menu.vue +117 -117
- package/src/views/component/notice.vue +46 -46
- package/src/views/component/topNav.vue +36 -36
- package/src/views/invoiceShow/index.vue +61 -61
- package/src/views/user/login/ForgetPasswordForm.vue +94 -94
- package/src/views/user/login/LoginTitle.vue +68 -68
- package/src/views/user/login/index.vue +22 -22
- package/src/views/user/my/index.vue +230 -230
- package/src/vue-router.d.ts +9 -9
- package/tsconfig.json +43 -43
|
@@ -1,183 +1,183 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
Cell as VanCell,
|
|
4
|
-
CellGroup as VanCellGroup,
|
|
5
|
-
Checkbox as VanCheckbox,
|
|
6
|
-
CheckboxGroup as VanCheckboxGroup,
|
|
7
|
-
Field as VanField,
|
|
8
|
-
Popup as VanPopup,
|
|
9
|
-
Search as VanSearch,
|
|
10
|
-
} from 'vant'
|
|
11
|
-
import { computed, defineEmits, defineModel, defineProps, ref, watch } from 'vue'
|
|
12
|
-
|
|
13
|
-
const props = defineProps({
|
|
14
|
-
columns: {
|
|
15
|
-
type: Array,
|
|
16
|
-
default() {
|
|
17
|
-
return []
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
selectValue: {
|
|
21
|
-
type: Array,
|
|
22
|
-
default() {
|
|
23
|
-
return []
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
option: {
|
|
27
|
-
type: Object,
|
|
28
|
-
default() {
|
|
29
|
-
return { text: 'label', value: 'value' }
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
// 是否支持搜索
|
|
33
|
-
isSearch: {
|
|
34
|
-
type: Boolean,
|
|
35
|
-
default: true,
|
|
36
|
-
},
|
|
37
|
-
})
|
|
38
|
-
const emits = defineEmits(['input', 'confirm', 'change', 'cancel'])
|
|
39
|
-
const show = ref(false)
|
|
40
|
-
const searchVal = ref('')
|
|
41
|
-
const columnsData = ref([])
|
|
42
|
-
const checkboxValue = ref(JSON.parse(JSON.stringify(props.selectValue)))
|
|
43
|
-
const checkedAll = ref(false)
|
|
44
|
-
const resultValue = defineModel()
|
|
45
|
-
const checkboxGroup = ref()
|
|
46
|
-
const checkboxes = ref()
|
|
47
|
-
function search(val) {
|
|
48
|
-
if (val) {
|
|
49
|
-
columnsData.value = props.columns.filter((item) => {
|
|
50
|
-
return item[props.option.text].includes(val)
|
|
51
|
-
})
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
columnsData.value = JSON.parse(JSON.stringify(props.columns))
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
function getData(val) {
|
|
58
|
-
const res = props.columns.filter((item) => {
|
|
59
|
-
return val.includes(item[props.option.value])
|
|
60
|
-
})
|
|
61
|
-
return res
|
|
62
|
-
}
|
|
63
|
-
function onConfirm() {
|
|
64
|
-
resultValue.value = checkboxValue.value
|
|
65
|
-
show.value = !show.value
|
|
66
|
-
emits('confirm', resultValue.value, getData(resultValue.value))
|
|
67
|
-
}
|
|
68
|
-
function change(val) {
|
|
69
|
-
emits('change', val, getData(resultValue.value))
|
|
70
|
-
}
|
|
71
|
-
function cancel() {
|
|
72
|
-
show.value = !show.value
|
|
73
|
-
emits('cancel', resultValue.value)
|
|
74
|
-
}
|
|
75
|
-
function toggle(item, _index) {
|
|
76
|
-
// 假设 checkboxValue 是一个对象,我们通过 index 来切换对应 checkbox 的值
|
|
77
|
-
const idx = checkboxValue.value.indexOf(item[props.option.value])
|
|
78
|
-
if (idx !== -1)
|
|
79
|
-
checkboxValue.value.splice(idx, 1)
|
|
80
|
-
else
|
|
81
|
-
checkboxValue.value.push(item[props.option.value])
|
|
82
|
-
}
|
|
83
|
-
function toggleAll() {
|
|
84
|
-
// 遍历 checkboxValue 并设置所有 checkbox 的值为 checkedAll 的值
|
|
85
|
-
if (checkedAll.value)
|
|
86
|
-
checkboxValue.value = columnsData.value.map(item => item[props.option.value])
|
|
87
|
-
|
|
88
|
-
else
|
|
89
|
-
checkboxValue.value = []
|
|
90
|
-
}
|
|
91
|
-
function showPopu(disabled) {
|
|
92
|
-
columnsData.value = JSON.parse(JSON.stringify(props.columns))
|
|
93
|
-
if (disabled !== undefined && disabled !== false)
|
|
94
|
-
return false
|
|
95
|
-
else
|
|
96
|
-
show.value = !show.value
|
|
97
|
-
}
|
|
98
|
-
watch(() => columnsData.value, (newVal, _oldVal) => {
|
|
99
|
-
checkedAll.value = newVal.length && newVal.length === checkboxValue.value.length
|
|
100
|
-
})
|
|
101
|
-
watch(() => checkboxValue.value.length, (newVal, _oldVal) => {
|
|
102
|
-
checkedAll.value = newVal && newVal === columnsData.value.length
|
|
103
|
-
})
|
|
104
|
-
const resultLabel = computed(() => {
|
|
105
|
-
const res = props.columns.filter((item) => {
|
|
106
|
-
return (resultValue.value as unknown as string[]).includes(item[props.option.value])
|
|
107
|
-
}).map(item => item[props.option.text])
|
|
108
|
-
return res.join(',')
|
|
109
|
-
})
|
|
110
|
-
</script>
|
|
111
|
-
|
|
112
|
-
<template>
|
|
113
|
-
<div class="dh-field">
|
|
114
|
-
<VanField
|
|
115
|
-
v-model="resultLabel"
|
|
116
|
-
v-bind="$attrs"
|
|
117
|
-
readonly
|
|
118
|
-
:border="false"
|
|
119
|
-
:is-link="$attrs.disabled === undefined"
|
|
120
|
-
error-message-align="right"
|
|
121
|
-
@click="showPopu($attrs.readonly)"
|
|
122
|
-
/>
|
|
123
|
-
<VanPopup v-model:show="show" position="bottom">
|
|
124
|
-
<div class="van-picker__toolbar">
|
|
125
|
-
<button type="button" class="van-picker__cancel" @click="cancel">
|
|
126
|
-
取消
|
|
127
|
-
</button>
|
|
128
|
-
<div class="van-ellipsis van-picker__title">
|
|
129
|
-
{{ $attrs.label }}
|
|
130
|
-
</div>
|
|
131
|
-
<button type="button" class="van-picker__confirm" @click="onConfirm">
|
|
132
|
-
确认
|
|
133
|
-
</button>
|
|
134
|
-
</div>
|
|
135
|
-
<div style="max-height:264px; overflow-y:auto;">
|
|
136
|
-
<VanSearch
|
|
137
|
-
v-if="props.isSearch"
|
|
138
|
-
v-model="searchVal"
|
|
139
|
-
placeholder="搜索"
|
|
140
|
-
@update:model-value="search"
|
|
141
|
-
@cancel="search"
|
|
142
|
-
/>
|
|
143
|
-
<VanCell title="全选">
|
|
144
|
-
<template #right-icon>
|
|
145
|
-
<VanCheckbox v-model="checkedAll" name="all" @click="toggleAll" />
|
|
146
|
-
</template>
|
|
147
|
-
</VanCell>
|
|
148
|
-
<VanCheckboxGroup ref="checkboxGroup" v-model="checkboxValue" @change="change">
|
|
149
|
-
<VanCellGroup>
|
|
150
|
-
<VanCell
|
|
151
|
-
v-for="(item, index) in columnsData"
|
|
152
|
-
:key="item[props.option.value]"
|
|
153
|
-
:title="item[props.option.text]"
|
|
154
|
-
clickable
|
|
155
|
-
@click="toggle(item, index)"
|
|
156
|
-
>
|
|
157
|
-
<template #right-icon>
|
|
158
|
-
<VanCheckbox ref="checkboxes" :name="item[props.option.value]" @click.stop />
|
|
159
|
-
</template>
|
|
160
|
-
</VanCell>
|
|
161
|
-
</VanCellGroup>
|
|
162
|
-
</VanCheckboxGroup>
|
|
163
|
-
</div>
|
|
164
|
-
</VanPopup>
|
|
165
|
-
</div>
|
|
166
|
-
</template>
|
|
167
|
-
|
|
168
|
-
<style lang="less" scoped>
|
|
169
|
-
.dh-field {
|
|
170
|
-
width: 100%;
|
|
171
|
-
padding: 0;
|
|
172
|
-
background:#fff;
|
|
173
|
-
.dh-cell.van-cell {
|
|
174
|
-
padding: 10px 0;
|
|
175
|
-
}
|
|
176
|
-
.dh-cell.van-cell--required::before {
|
|
177
|
-
left: -8px;
|
|
178
|
-
}
|
|
179
|
-
.van-popup {
|
|
180
|
-
border-radius: 20px 20px 0 0;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
</style>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
Cell as VanCell,
|
|
4
|
+
CellGroup as VanCellGroup,
|
|
5
|
+
Checkbox as VanCheckbox,
|
|
6
|
+
CheckboxGroup as VanCheckboxGroup,
|
|
7
|
+
Field as VanField,
|
|
8
|
+
Popup as VanPopup,
|
|
9
|
+
Search as VanSearch,
|
|
10
|
+
} from 'vant'
|
|
11
|
+
import { computed, defineEmits, defineModel, defineProps, ref, watch } from 'vue'
|
|
12
|
+
|
|
13
|
+
const props = defineProps({
|
|
14
|
+
columns: {
|
|
15
|
+
type: Array,
|
|
16
|
+
default() {
|
|
17
|
+
return []
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
selectValue: {
|
|
21
|
+
type: Array,
|
|
22
|
+
default() {
|
|
23
|
+
return []
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
option: {
|
|
27
|
+
type: Object,
|
|
28
|
+
default() {
|
|
29
|
+
return { text: 'label', value: 'value' }
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
// 是否支持搜索
|
|
33
|
+
isSearch: {
|
|
34
|
+
type: Boolean,
|
|
35
|
+
default: true,
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
const emits = defineEmits(['input', 'confirm', 'change', 'cancel'])
|
|
39
|
+
const show = ref(false)
|
|
40
|
+
const searchVal = ref('')
|
|
41
|
+
const columnsData = ref([])
|
|
42
|
+
const checkboxValue = ref(JSON.parse(JSON.stringify(props.selectValue)))
|
|
43
|
+
const checkedAll = ref(false)
|
|
44
|
+
const resultValue = defineModel()
|
|
45
|
+
const checkboxGroup = ref()
|
|
46
|
+
const checkboxes = ref()
|
|
47
|
+
function search(val) {
|
|
48
|
+
if (val) {
|
|
49
|
+
columnsData.value = props.columns.filter((item) => {
|
|
50
|
+
return item[props.option.text].includes(val)
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
columnsData.value = JSON.parse(JSON.stringify(props.columns))
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function getData(val) {
|
|
58
|
+
const res = props.columns.filter((item) => {
|
|
59
|
+
return val.includes(item[props.option.value])
|
|
60
|
+
})
|
|
61
|
+
return res
|
|
62
|
+
}
|
|
63
|
+
function onConfirm() {
|
|
64
|
+
resultValue.value = checkboxValue.value
|
|
65
|
+
show.value = !show.value
|
|
66
|
+
emits('confirm', resultValue.value, getData(resultValue.value))
|
|
67
|
+
}
|
|
68
|
+
function change(val) {
|
|
69
|
+
emits('change', val, getData(resultValue.value))
|
|
70
|
+
}
|
|
71
|
+
function cancel() {
|
|
72
|
+
show.value = !show.value
|
|
73
|
+
emits('cancel', resultValue.value)
|
|
74
|
+
}
|
|
75
|
+
function toggle(item, _index) {
|
|
76
|
+
// 假设 checkboxValue 是一个对象,我们通过 index 来切换对应 checkbox 的值
|
|
77
|
+
const idx = checkboxValue.value.indexOf(item[props.option.value])
|
|
78
|
+
if (idx !== -1)
|
|
79
|
+
checkboxValue.value.splice(idx, 1)
|
|
80
|
+
else
|
|
81
|
+
checkboxValue.value.push(item[props.option.value])
|
|
82
|
+
}
|
|
83
|
+
function toggleAll() {
|
|
84
|
+
// 遍历 checkboxValue 并设置所有 checkbox 的值为 checkedAll 的值
|
|
85
|
+
if (checkedAll.value)
|
|
86
|
+
checkboxValue.value = columnsData.value.map(item => item[props.option.value])
|
|
87
|
+
|
|
88
|
+
else
|
|
89
|
+
checkboxValue.value = []
|
|
90
|
+
}
|
|
91
|
+
function showPopu(disabled) {
|
|
92
|
+
columnsData.value = JSON.parse(JSON.stringify(props.columns))
|
|
93
|
+
if (disabled !== undefined && disabled !== false)
|
|
94
|
+
return false
|
|
95
|
+
else
|
|
96
|
+
show.value = !show.value
|
|
97
|
+
}
|
|
98
|
+
watch(() => columnsData.value, (newVal, _oldVal) => {
|
|
99
|
+
checkedAll.value = newVal.length && newVal.length === checkboxValue.value.length
|
|
100
|
+
})
|
|
101
|
+
watch(() => checkboxValue.value.length, (newVal, _oldVal) => {
|
|
102
|
+
checkedAll.value = newVal && newVal === columnsData.value.length
|
|
103
|
+
})
|
|
104
|
+
const resultLabel = computed(() => {
|
|
105
|
+
const res = props.columns.filter((item) => {
|
|
106
|
+
return (resultValue.value as unknown as string[]).includes(item[props.option.value])
|
|
107
|
+
}).map(item => item[props.option.text])
|
|
108
|
+
return res.join(',')
|
|
109
|
+
})
|
|
110
|
+
</script>
|
|
111
|
+
|
|
112
|
+
<template>
|
|
113
|
+
<div class="dh-field">
|
|
114
|
+
<VanField
|
|
115
|
+
v-model="resultLabel"
|
|
116
|
+
v-bind="$attrs"
|
|
117
|
+
readonly
|
|
118
|
+
:border="false"
|
|
119
|
+
:is-link="$attrs.disabled === undefined"
|
|
120
|
+
error-message-align="right"
|
|
121
|
+
@click="showPopu($attrs.readonly)"
|
|
122
|
+
/>
|
|
123
|
+
<VanPopup v-model:show="show" position="bottom">
|
|
124
|
+
<div class="van-picker__toolbar">
|
|
125
|
+
<button type="button" class="van-picker__cancel" @click="cancel">
|
|
126
|
+
取消
|
|
127
|
+
</button>
|
|
128
|
+
<div class="van-ellipsis van-picker__title">
|
|
129
|
+
{{ $attrs.label }}
|
|
130
|
+
</div>
|
|
131
|
+
<button type="button" class="van-picker__confirm" @click="onConfirm">
|
|
132
|
+
确认
|
|
133
|
+
</button>
|
|
134
|
+
</div>
|
|
135
|
+
<div style="max-height:264px; overflow-y:auto;">
|
|
136
|
+
<VanSearch
|
|
137
|
+
v-if="props.isSearch"
|
|
138
|
+
v-model="searchVal"
|
|
139
|
+
placeholder="搜索"
|
|
140
|
+
@update:model-value="search"
|
|
141
|
+
@cancel="search"
|
|
142
|
+
/>
|
|
143
|
+
<VanCell title="全选">
|
|
144
|
+
<template #right-icon>
|
|
145
|
+
<VanCheckbox v-model="checkedAll" name="all" @click="toggleAll" />
|
|
146
|
+
</template>
|
|
147
|
+
</VanCell>
|
|
148
|
+
<VanCheckboxGroup ref="checkboxGroup" v-model="checkboxValue" @change="change">
|
|
149
|
+
<VanCellGroup>
|
|
150
|
+
<VanCell
|
|
151
|
+
v-for="(item, index) in columnsData"
|
|
152
|
+
:key="item[props.option.value]"
|
|
153
|
+
:title="item[props.option.text]"
|
|
154
|
+
clickable
|
|
155
|
+
@click="toggle(item, index)"
|
|
156
|
+
>
|
|
157
|
+
<template #right-icon>
|
|
158
|
+
<VanCheckbox ref="checkboxes" :name="item[props.option.value]" @click.stop />
|
|
159
|
+
</template>
|
|
160
|
+
</VanCell>
|
|
161
|
+
</VanCellGroup>
|
|
162
|
+
</VanCheckboxGroup>
|
|
163
|
+
</div>
|
|
164
|
+
</VanPopup>
|
|
165
|
+
</div>
|
|
166
|
+
</template>
|
|
167
|
+
|
|
168
|
+
<style lang="less" scoped>
|
|
169
|
+
.dh-field {
|
|
170
|
+
width: 100%;
|
|
171
|
+
padding: 0;
|
|
172
|
+
background:#fff;
|
|
173
|
+
.dh-cell.van-cell {
|
|
174
|
+
padding: 10px 0;
|
|
175
|
+
}
|
|
176
|
+
.dh-cell.van-cell--required::before {
|
|
177
|
+
left: -8px;
|
|
178
|
+
}
|
|
179
|
+
.van-popup {
|
|
180
|
+
border-radius: 20px 20px 0 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
</style>
|
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
Col as VanCol,
|
|
4
|
-
Icon as VanIcon,
|
|
5
|
-
Row as VanRow,
|
|
6
|
-
Skeleton as VanSkeleton,
|
|
7
|
-
} from 'vant'
|
|
8
|
-
import 'animate.css'
|
|
9
|
-
|
|
10
|
-
const { title, describe, extra, loading, statusBar } = defineProps<{
|
|
11
|
-
title?: string
|
|
12
|
-
describe?: string
|
|
13
|
-
extra?: string
|
|
14
|
-
loading?: boolean
|
|
15
|
-
statusBar?: { icon: string, color: string }
|
|
16
|
-
}>()
|
|
17
|
-
</script>
|
|
18
|
-
|
|
19
|
-
<template>
|
|
20
|
-
<div class="main">
|
|
21
|
-
<VanSkeleton title :row="20" :loading="loading" class="skeleton-box">
|
|
22
|
-
<VanIcon
|
|
23
|
-
v-if="statusBar"
|
|
24
|
-
:color="statusBar.color"
|
|
25
|
-
:name="statusBar.icon"
|
|
26
|
-
class="status-icon animate__animated animate__rotateInDownRight"
|
|
27
|
-
size="70"
|
|
28
|
-
/>
|
|
29
|
-
<VanRow class="detail-header">
|
|
30
|
-
<VanCol span="16">
|
|
31
|
-
<slot name="detailHeaderTitle">
|
|
32
|
-
<div class="detail-header-title">
|
|
33
|
-
{{ title }}
|
|
34
|
-
</div>
|
|
35
|
-
</slot>
|
|
36
|
-
<slot name="detailHeaderDescribe">
|
|
37
|
-
<div class="detail-header-describe">
|
|
38
|
-
{{ describe }}
|
|
39
|
-
</div>
|
|
40
|
-
</slot>
|
|
41
|
-
</VanCol>
|
|
42
|
-
<VanCol span="8">
|
|
43
|
-
<span class="detail-header-extra">
|
|
44
|
-
{{ extra }}
|
|
45
|
-
</span>
|
|
46
|
-
</VanCol>
|
|
47
|
-
</VanRow>
|
|
48
|
-
<div class="detail-content-box">
|
|
49
|
-
<slot name="detailContent" />
|
|
50
|
-
</div>
|
|
51
|
-
<slot name="extraAction" />
|
|
52
|
-
</VanSkeleton>
|
|
53
|
-
</div>
|
|
54
|
-
</template>
|
|
55
|
-
|
|
56
|
-
<style scoped lang="less">
|
|
57
|
-
.main {
|
|
58
|
-
background-color: #f7f8fa;
|
|
59
|
-
overflow-y: auto;
|
|
60
|
-
height: 92vh;
|
|
61
|
-
.skeleton-box {
|
|
62
|
-
margin-top: 1vh;
|
|
63
|
-
}
|
|
64
|
-
.status-icon {
|
|
65
|
-
opacity: 0.5;
|
|
66
|
-
position: absolute;
|
|
67
|
-
top: 13vh;
|
|
68
|
-
right: 3vh;
|
|
69
|
-
transform: translate(-50%, -50%) rotate(-20deg);
|
|
70
|
-
}
|
|
71
|
-
.status-icon:before {
|
|
72
|
-
opacity: 0.5;
|
|
73
|
-
transform: rotate(-20deg);
|
|
74
|
-
}
|
|
75
|
-
.status-icon:after {
|
|
76
|
-
opacity: 0.5;
|
|
77
|
-
transform: rotate(-20deg);
|
|
78
|
-
}
|
|
79
|
-
.detail-header {
|
|
80
|
-
margin-top: 1vh;
|
|
81
|
-
padding: 1vh 2vh 1vh 2vh;
|
|
82
|
-
background-color: white;
|
|
83
|
-
.detail-header-title {
|
|
84
|
-
font-size: 15px;
|
|
85
|
-
margin-bottom: 5px;
|
|
86
|
-
}
|
|
87
|
-
.detail-header-describe {
|
|
88
|
-
font-size: 13px;
|
|
89
|
-
color: var(--van-text-color-2);
|
|
90
|
-
}
|
|
91
|
-
.detail-header-extra {
|
|
92
|
-
width: 100%;
|
|
93
|
-
display: inline-block;
|
|
94
|
-
text-align: right;
|
|
95
|
-
font-size: 28px;
|
|
96
|
-
color: #1989fa;
|
|
97
|
-
font-weight: bold;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
.detail-content-box {
|
|
101
|
-
background-color: white;
|
|
102
|
-
margin-top: 1vh;
|
|
103
|
-
padding: 1vh 2vh 2vh 2vh;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
</style>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
Col as VanCol,
|
|
4
|
+
Icon as VanIcon,
|
|
5
|
+
Row as VanRow,
|
|
6
|
+
Skeleton as VanSkeleton,
|
|
7
|
+
} from 'vant'
|
|
8
|
+
import 'animate.css'
|
|
9
|
+
|
|
10
|
+
const { title, describe, extra, loading, statusBar } = defineProps<{
|
|
11
|
+
title?: string
|
|
12
|
+
describe?: string
|
|
13
|
+
extra?: string
|
|
14
|
+
loading?: boolean
|
|
15
|
+
statusBar?: { icon: string, color: string }
|
|
16
|
+
}>()
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<div class="main">
|
|
21
|
+
<VanSkeleton title :row="20" :loading="loading" class="skeleton-box">
|
|
22
|
+
<VanIcon
|
|
23
|
+
v-if="statusBar"
|
|
24
|
+
:color="statusBar.color"
|
|
25
|
+
:name="statusBar.icon"
|
|
26
|
+
class="status-icon animate__animated animate__rotateInDownRight"
|
|
27
|
+
size="70"
|
|
28
|
+
/>
|
|
29
|
+
<VanRow class="detail-header">
|
|
30
|
+
<VanCol span="16">
|
|
31
|
+
<slot name="detailHeaderTitle">
|
|
32
|
+
<div class="detail-header-title">
|
|
33
|
+
{{ title }}
|
|
34
|
+
</div>
|
|
35
|
+
</slot>
|
|
36
|
+
<slot name="detailHeaderDescribe">
|
|
37
|
+
<div class="detail-header-describe">
|
|
38
|
+
{{ describe }}
|
|
39
|
+
</div>
|
|
40
|
+
</slot>
|
|
41
|
+
</VanCol>
|
|
42
|
+
<VanCol span="8">
|
|
43
|
+
<span class="detail-header-extra">
|
|
44
|
+
{{ extra }}
|
|
45
|
+
</span>
|
|
46
|
+
</VanCol>
|
|
47
|
+
</VanRow>
|
|
48
|
+
<div class="detail-content-box">
|
|
49
|
+
<slot name="detailContent" />
|
|
50
|
+
</div>
|
|
51
|
+
<slot name="extraAction" />
|
|
52
|
+
</VanSkeleton>
|
|
53
|
+
</div>
|
|
54
|
+
</template>
|
|
55
|
+
|
|
56
|
+
<style scoped lang="less">
|
|
57
|
+
.main {
|
|
58
|
+
background-color: #f7f8fa;
|
|
59
|
+
overflow-y: auto;
|
|
60
|
+
height: 92vh;
|
|
61
|
+
.skeleton-box {
|
|
62
|
+
margin-top: 1vh;
|
|
63
|
+
}
|
|
64
|
+
.status-icon {
|
|
65
|
+
opacity: 0.5;
|
|
66
|
+
position: absolute;
|
|
67
|
+
top: 13vh;
|
|
68
|
+
right: 3vh;
|
|
69
|
+
transform: translate(-50%, -50%) rotate(-20deg);
|
|
70
|
+
}
|
|
71
|
+
.status-icon:before {
|
|
72
|
+
opacity: 0.5;
|
|
73
|
+
transform: rotate(-20deg);
|
|
74
|
+
}
|
|
75
|
+
.status-icon:after {
|
|
76
|
+
opacity: 0.5;
|
|
77
|
+
transform: rotate(-20deg);
|
|
78
|
+
}
|
|
79
|
+
.detail-header {
|
|
80
|
+
margin-top: 1vh;
|
|
81
|
+
padding: 1vh 2vh 1vh 2vh;
|
|
82
|
+
background-color: white;
|
|
83
|
+
.detail-header-title {
|
|
84
|
+
font-size: 15px;
|
|
85
|
+
margin-bottom: 5px;
|
|
86
|
+
}
|
|
87
|
+
.detail-header-describe {
|
|
88
|
+
font-size: 13px;
|
|
89
|
+
color: var(--van-text-color-2);
|
|
90
|
+
}
|
|
91
|
+
.detail-header-extra {
|
|
92
|
+
width: 100%;
|
|
93
|
+
display: inline-block;
|
|
94
|
+
text-align: right;
|
|
95
|
+
font-size: 28px;
|
|
96
|
+
color: #1989fa;
|
|
97
|
+
font-weight: bold;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
.detail-content-box {
|
|
101
|
+
background-color: white;
|
|
102
|
+
margin-top: 1vh;
|
|
103
|
+
padding: 1vh 2vh 2vh 2vh;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
</style>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { FieldType } from 'vant'
|
|
3
3
|
import type { Numeric } from 'vant/es/utils'
|
|
4
|
-
import type { LocationResult } from '../XOlMap/types'
|
|
5
4
|
import Uploader from '@af-mobile-client-vue3/components/core/Uploader/index.vue'
|
|
6
5
|
import XGridDropOption from '@af-mobile-client-vue3/components/core/XGridDropOption/index.vue'
|
|
7
6
|
import XMultiSelect from '@af-mobile-client-vue3/components/core/XMultiSelect/index.vue'
|
|
@@ -216,7 +215,8 @@ const localValue = computed({
|
|
|
216
215
|
|
|
217
216
|
else
|
|
218
217
|
return props.modelValue
|
|
219
|
-
|
|
218
|
+
case 'addressSearch':
|
|
219
|
+
return props.modelValue
|
|
220
220
|
default:
|
|
221
221
|
return undefined
|
|
222
222
|
}
|
|
@@ -590,9 +590,30 @@ function onPickerCancel() {
|
|
|
590
590
|
|
|
591
591
|
const showAddressPicker = ref(false)
|
|
592
592
|
const addressValue = ref('')
|
|
593
|
+
|
|
594
|
+
// XLocationPicker 默认加载的中心点
|
|
595
|
+
const defaultMapCenter = computed(() => {
|
|
596
|
+
const lonLat = form[`${attr.model}_lon_lat`]
|
|
597
|
+
if (lonLat && typeof lonLat === 'string' && lonLat.includes(',')) {
|
|
598
|
+
const [lon, lat] = lonLat.split(',').map(Number)
|
|
599
|
+
if (!Number.isNaN(lon) && !Number.isNaN(lat)) {
|
|
600
|
+
return [lon, lat] as [number, number]
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return undefined
|
|
604
|
+
})
|
|
605
|
+
|
|
593
606
|
// 处理地址选择器确认
|
|
594
607
|
function handleAddressConfirm(location) {
|
|
595
|
-
|
|
608
|
+
// 构造新的数据格式
|
|
609
|
+
const formData = {
|
|
610
|
+
[`${attr.model}_lon_lat`]: `${location.longitude},${location.latitude}`,
|
|
611
|
+
[attr.model]: location.address,
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// 更新表单数据
|
|
615
|
+
// eslint-disable-next-line vue/custom-event-name-casing
|
|
616
|
+
emits('set-form', formData)
|
|
596
617
|
showAddressPicker.value = false
|
|
597
618
|
}
|
|
598
619
|
</script>
|
|
@@ -998,7 +1019,7 @@ function handleAddressConfirm(location) {
|
|
|
998
1019
|
<!-- 地址选择器 -->
|
|
999
1020
|
<VanField
|
|
1000
1021
|
v-if="attr.type === 'addressSearch' && showItem"
|
|
1001
|
-
v-model="
|
|
1022
|
+
v-model="localValue as string"
|
|
1002
1023
|
name="addressSearch"
|
|
1003
1024
|
:label="labelData"
|
|
1004
1025
|
:label-align="labelAlign"
|
|
@@ -1016,9 +1037,7 @@ function handleAddressConfirm(location) {
|
|
|
1016
1037
|
teleport="body"
|
|
1017
1038
|
>
|
|
1018
1039
|
<XLocationPicker
|
|
1019
|
-
|
|
1020
|
-
tian-di-tu-key="c16876b28898637c0a1a68b3fa410504"
|
|
1021
|
-
amap-key="5ebabc4536d4b42e0dd1e20175cca8ab"
|
|
1040
|
+
:default-center="defaultMapCenter"
|
|
1022
1041
|
@confirm="handleAddressConfirm"
|
|
1023
1042
|
/>
|
|
1024
1043
|
</VanPopup>
|
|
@@ -63,17 +63,15 @@ function handleConfirm() {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
// 组件挂载时初始化地图
|
|
66
|
-
onMounted(() => {
|
|
66
|
+
onMounted(async () => {
|
|
67
67
|
// 使用 nextTick 确保 DOM 已更新
|
|
68
|
-
nextTick(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
// 初始化后尝试获取地址信息
|
|
75
|
-
handleCenterChange(props.defaultCenter)
|
|
68
|
+
await nextTick()
|
|
69
|
+
await mapRef.value.init({
|
|
70
|
+
center: props.defaultCenter,
|
|
71
|
+
zoom: props.defaultZoom,
|
|
76
72
|
})
|
|
73
|
+
// 初始化后尝试获取地址信息
|
|
74
|
+
handleCenterChange(props.defaultCenter)
|
|
77
75
|
})
|
|
78
76
|
|
|
79
77
|
// 监听弹窗状态变化
|