af-mobile-client-vue3 1.5.69 → 1.5.71
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/api/map/trackApi.ts +94 -0
- package/src/assets/img/map/start.png +0 -0
- package/src/assets/img/map/terminus.png +0 -0
- package/src/components/common/otherCharge/ChargePrintSelectorAndRemarks.vue +137 -137
- package/src/components/common/otherCharge/CodePayment.vue +357 -357
- package/src/components/common/otherCharge/FileUploader.vue +602 -602
- package/src/components/common/otherCharge/GridFileUploader.vue +846 -846
- package/src/components/common/otherCharge/PaymentMethodSelector.vue +202 -202
- package/src/components/common/otherCharge/PaymentMethodSelectorCard.vue +45 -45
- package/src/components/common/otherCharge/ReceiptModal.vue +273 -273
- package/src/components/common/otherCharge/index.ts +43 -43
- package/src/components/data/OtherCharge/OtherChargeItemModal.vue +547 -547
- package/src/components/data/XForm/index.vue +1 -0
- package/src/components/data/XFormItem/index.vue +5 -0
- package/src/components/data/XOlMap/index.vue +117 -1
- package/src/components/data/XOlMap/types.ts +26 -0
- package/src/utils/map/track.ts +294 -0
- package/src/utils/map/trackUtils.ts +107 -0
- package/src/utils/queryFormDefaultRangePicker.ts +57 -57
- package/src/views/component/XCellListView/index.vue +101 -101
- package/src/views/component/XFormGroupView/index.vue +7 -11
- package/src/views/component/XFormView/index.vue +18 -20
- package/src/views/component/XOlMapView/index.vue +10 -0
package/package.json
CHANGED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { getConfigByNameAsync } from '@af-mobile-client-vue3/services/api/common'
|
|
2
|
+
import { post } from '@af-mobile-client-vue3/services/restTools'
|
|
3
|
+
import useUserStore from '@af-mobile-client-vue3/stores/modules/user'
|
|
4
|
+
import { trajectoryThinning } from '@af-mobile-client-vue3/utils/map/track'
|
|
5
|
+
import { trajectoryGrouping } from '@af-mobile-client-vue3/utils/map/trackUtils'
|
|
6
|
+
import dayjs from 'dayjs/esm/index'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* trajectoryThinning 是否抽稀 默认 false
|
|
10
|
+
* trajectoryCorrection 是否高德纠偏 默认 false
|
|
11
|
+
* group 是否分组 默认 false 要进行高德纠偏必须分组
|
|
12
|
+
* AMAP_KEY 高德key 用来纠偏
|
|
13
|
+
* gapMs 分组时间间隔 毫秒 默认 30分钟
|
|
14
|
+
* rdpEpsilon RDP 精度(度) 默认 0.000001
|
|
15
|
+
* dbscanEpsilon DBSCAN聚类半径(km) 默认 0.01
|
|
16
|
+
* minPuts DBSCAN聚类 最小开始聚类点数 默认 20
|
|
17
|
+
* minDistance 分组数据进行高德纠偏起始纠偏数 默认 20 不能低于20 否则就会纠偏失败,失败也算次数
|
|
18
|
+
*/
|
|
19
|
+
export interface TrajectoryParams {
|
|
20
|
+
trajectoryThinning?: boolean
|
|
21
|
+
trajectoryCorrection?: boolean
|
|
22
|
+
group?: boolean
|
|
23
|
+
AMAP_KEY?: string
|
|
24
|
+
gapMs?: number
|
|
25
|
+
rdpEpsilon?: number
|
|
26
|
+
dbscanEpsilon?: number
|
|
27
|
+
minPuts?: number
|
|
28
|
+
minDistance?: number
|
|
29
|
+
orderTime?: string
|
|
30
|
+
serviceName?: string
|
|
31
|
+
}
|
|
32
|
+
export const defaultTrajectoryParams: Required<TrajectoryParams> = {
|
|
33
|
+
trajectoryThinning: false,
|
|
34
|
+
trajectoryCorrection: false,
|
|
35
|
+
group: false,
|
|
36
|
+
AMAP_KEY: '',
|
|
37
|
+
gapMs: 1800000,
|
|
38
|
+
rdpEpsilon: 0.000001,
|
|
39
|
+
dbscanEpsilon: 0.01,
|
|
40
|
+
minPuts: 20,
|
|
41
|
+
minDistance: 20,
|
|
42
|
+
orderTime: 'f_realtime asc',
|
|
43
|
+
serviceName: 'af-linepatrol',
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param userId 查询的用户id
|
|
48
|
+
* @param dateStr 查询的轨迹日期
|
|
49
|
+
* @param trajectoryParams 后台轨迹纠偏参数
|
|
50
|
+
*/
|
|
51
|
+
export async function getDeviceState(
|
|
52
|
+
userId: string = useUserStore().getLogin().id,
|
|
53
|
+
dateStr: string = dayjs().format('YYYY-MM-DD'),
|
|
54
|
+
trajectoryParams: TrajectoryParams = defaultTrajectoryParams,
|
|
55
|
+
) {
|
|
56
|
+
const condition = `1 = 1 and f_user_id = ${userId} and (f_realtime between '${dateStr} 00:00:00' and '${dateStr} 23:59:59'`
|
|
57
|
+
const param = {
|
|
58
|
+
condition,
|
|
59
|
+
dateStr,
|
|
60
|
+
userId,
|
|
61
|
+
...trajectoryParams,
|
|
62
|
+
}
|
|
63
|
+
// 获取轨迹
|
|
64
|
+
const trackPoint = await post(`/api/${trajectoryParams.serviceName}/logic/getDeviceStateLogic`, param)
|
|
65
|
+
// 轨迹数据未处理,需要对原始数据进行 处理
|
|
66
|
+
if (trackPoint.state === 'error') {
|
|
67
|
+
// 轨迹抽稀
|
|
68
|
+
if (trackPoint.points.length >= 30) {
|
|
69
|
+
// 轨迹抽稀
|
|
70
|
+
let path = trajectoryThinning(trackPoint.points)
|
|
71
|
+
// 存储 path 数据供表格使用
|
|
72
|
+
const webConfig = await getConfigByNameAsync('webConfig')
|
|
73
|
+
if (webConfig?.setting?.lesseeName === 'jinbin') {
|
|
74
|
+
path = path.filter(item => item.sp !== '0.0')
|
|
75
|
+
}
|
|
76
|
+
// 轨迹分组
|
|
77
|
+
const trajectoryGroupingResult = trajectoryGrouping(path, {})
|
|
78
|
+
console.warn('>>>> trajectoryGroupingResult', trajectoryGroupingResult)
|
|
79
|
+
return trajectoryGroupingResult
|
|
80
|
+
|
|
81
|
+
// const graspRoadCorrectRes = await graspRoadCorrect(trajectoryGroupingResult)
|
|
82
|
+
// console.warn('>>>> graspRoadCorrect', graspRoadCorrectRes)
|
|
83
|
+
// console.warn('>>>> graspRoadCorrect', graspRoadCorrectRes.value)
|
|
84
|
+
// 返回数据
|
|
85
|
+
// return JSON.parse(graspRoadCorrectRes.value)
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
console.warn('当日使用app时间较短或行程较少,不足够生成轨迹')
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (trackPoint.state === 'success') {
|
|
92
|
+
return trackPoint.points
|
|
93
|
+
}
|
|
94
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -1,137 +1,137 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import CardContainer from '@af-mobile-client-vue3/components/data/CardContainer/CardContainer.vue'
|
|
3
|
-
import CardHeader from '@af-mobile-client-vue3/components/data/CardContainer/CardHeader.vue'
|
|
4
|
-
import {
|
|
5
|
-
Field as VanField,
|
|
6
|
-
Picker as VanPicker,
|
|
7
|
-
Popup as VanPopup,
|
|
8
|
-
} from 'vant'
|
|
9
|
-
import { ref, watch } from 'vue'
|
|
10
|
-
|
|
11
|
-
const props = defineProps<{
|
|
12
|
-
modelValue: string
|
|
13
|
-
remarks: string
|
|
14
|
-
}>()
|
|
15
|
-
|
|
16
|
-
const emit = defineEmits<{
|
|
17
|
-
(e: 'update:modelValue', value: string): void
|
|
18
|
-
(e: 'update:remarks', value: string): void
|
|
19
|
-
}>()
|
|
20
|
-
|
|
21
|
-
const printOptions = [
|
|
22
|
-
{ text: '电子发票', value: '电子发票' },
|
|
23
|
-
{ text: '普通收据', value: '普通收据' },
|
|
24
|
-
{ text: '两者都需要', value: 'both' },
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
const selectedOption = ref(getOptionText(props.modelValue))
|
|
28
|
-
const remarks = ref(props.remarks)
|
|
29
|
-
const showPicker = ref(false)
|
|
30
|
-
|
|
31
|
-
function getOptionText(value: string): string {
|
|
32
|
-
const option = printOptions.find(opt => opt.value === value)
|
|
33
|
-
return option ? option.text : ''
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function onConfirm({ selectedValues }: { selectedValues: string[] }) {
|
|
37
|
-
selectedOption.value = selectedValues[0]
|
|
38
|
-
emit('update:modelValue', selectedValues[0])
|
|
39
|
-
showPicker.value = false
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
watch(() => remarks.value, (newValue) => {
|
|
43
|
-
emit('update:remarks', newValue)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
// 当从外部更新值时更新内部状态
|
|
47
|
-
watch(() => props.modelValue, (newValue) => {
|
|
48
|
-
selectedOption.value = getOptionText(newValue)
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
watch(() => props.remarks, (newValue) => {
|
|
52
|
-
remarks.value = newValue
|
|
53
|
-
})
|
|
54
|
-
</script>
|
|
55
|
-
|
|
56
|
-
<template>
|
|
57
|
-
<CardContainer class="charge-print-and-remarks">
|
|
58
|
-
<CardHeader title="打印及备注" />
|
|
59
|
-
<div class="charge-print-options">
|
|
60
|
-
<div class="charge-print-options__section">
|
|
61
|
-
<label class="charge-print-options__label">收据打印选项</label>
|
|
62
|
-
<div class="charge-print-options__selector">
|
|
63
|
-
<VanField
|
|
64
|
-
v-model="selectedOption"
|
|
65
|
-
is-link
|
|
66
|
-
readonly
|
|
67
|
-
placeholder="请选择打印方式"
|
|
68
|
-
@click="showPicker = true"
|
|
69
|
-
/>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
|
|
73
|
-
<div class="charge-print-options__section">
|
|
74
|
-
<label class="charge-print-options__label">备注</label>
|
|
75
|
-
<div class="charge-print-options__selector">
|
|
76
|
-
<VanField
|
|
77
|
-
v-model="remarks"
|
|
78
|
-
type="textarea"
|
|
79
|
-
placeholder="可选填写备注信息"
|
|
80
|
-
rows="2"
|
|
81
|
-
autosize
|
|
82
|
-
maxlength="200"
|
|
83
|
-
show-word-limit
|
|
84
|
-
/>
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
|
|
88
|
-
<VanPopup v-model:show="showPicker" position="bottom" round teleport="body">
|
|
89
|
-
<VanPicker
|
|
90
|
-
:columns="printOptions"
|
|
91
|
-
show-toolbar
|
|
92
|
-
title="选择打印方式"
|
|
93
|
-
@confirm="onConfirm"
|
|
94
|
-
@cancel="showPicker = false"
|
|
95
|
-
/>
|
|
96
|
-
</VanPopup>
|
|
97
|
-
</div>
|
|
98
|
-
</CardContainer>
|
|
99
|
-
</template>
|
|
100
|
-
|
|
101
|
-
<style scoped lang="less">
|
|
102
|
-
.charge-print-and-remarks {
|
|
103
|
-
margin-bottom: 16px;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.charge-print-options {
|
|
107
|
-
&__section {
|
|
108
|
-
margin-bottom: 16px;
|
|
109
|
-
|
|
110
|
-
&:last-child {
|
|
111
|
-
margin-bottom: 0;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
&__label {
|
|
116
|
-
display: block;
|
|
117
|
-
font-size: 12px;
|
|
118
|
-
font-weight: 500;
|
|
119
|
-
color: #6b7280;
|
|
120
|
-
margin-bottom: 4px;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
&__selector {
|
|
124
|
-
position: relative;
|
|
125
|
-
|
|
126
|
-
:deep(.van-field) {
|
|
127
|
-
background-color: #f9fafb;
|
|
128
|
-
border-radius: 6px;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
:deep(.van-field__control) {
|
|
133
|
-
background-color: #f9fafb;
|
|
134
|
-
border-radius: 6px;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
</style>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import CardContainer from '@af-mobile-client-vue3/components/data/CardContainer/CardContainer.vue'
|
|
3
|
+
import CardHeader from '@af-mobile-client-vue3/components/data/CardContainer/CardHeader.vue'
|
|
4
|
+
import {
|
|
5
|
+
Field as VanField,
|
|
6
|
+
Picker as VanPicker,
|
|
7
|
+
Popup as VanPopup,
|
|
8
|
+
} from 'vant'
|
|
9
|
+
import { ref, watch } from 'vue'
|
|
10
|
+
|
|
11
|
+
const props = defineProps<{
|
|
12
|
+
modelValue: string
|
|
13
|
+
remarks: string
|
|
14
|
+
}>()
|
|
15
|
+
|
|
16
|
+
const emit = defineEmits<{
|
|
17
|
+
(e: 'update:modelValue', value: string): void
|
|
18
|
+
(e: 'update:remarks', value: string): void
|
|
19
|
+
}>()
|
|
20
|
+
|
|
21
|
+
const printOptions = [
|
|
22
|
+
{ text: '电子发票', value: '电子发票' },
|
|
23
|
+
{ text: '普通收据', value: '普通收据' },
|
|
24
|
+
{ text: '两者都需要', value: 'both' },
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const selectedOption = ref(getOptionText(props.modelValue))
|
|
28
|
+
const remarks = ref(props.remarks)
|
|
29
|
+
const showPicker = ref(false)
|
|
30
|
+
|
|
31
|
+
function getOptionText(value: string): string {
|
|
32
|
+
const option = printOptions.find(opt => opt.value === value)
|
|
33
|
+
return option ? option.text : ''
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function onConfirm({ selectedValues }: { selectedValues: string[] }) {
|
|
37
|
+
selectedOption.value = selectedValues[0]
|
|
38
|
+
emit('update:modelValue', selectedValues[0])
|
|
39
|
+
showPicker.value = false
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
watch(() => remarks.value, (newValue) => {
|
|
43
|
+
emit('update:remarks', newValue)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// 当从外部更新值时更新内部状态
|
|
47
|
+
watch(() => props.modelValue, (newValue) => {
|
|
48
|
+
selectedOption.value = getOptionText(newValue)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
watch(() => props.remarks, (newValue) => {
|
|
52
|
+
remarks.value = newValue
|
|
53
|
+
})
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<template>
|
|
57
|
+
<CardContainer class="charge-print-and-remarks">
|
|
58
|
+
<CardHeader title="打印及备注" />
|
|
59
|
+
<div class="charge-print-options">
|
|
60
|
+
<div class="charge-print-options__section">
|
|
61
|
+
<label class="charge-print-options__label">收据打印选项</label>
|
|
62
|
+
<div class="charge-print-options__selector">
|
|
63
|
+
<VanField
|
|
64
|
+
v-model="selectedOption"
|
|
65
|
+
is-link
|
|
66
|
+
readonly
|
|
67
|
+
placeholder="请选择打印方式"
|
|
68
|
+
@click="showPicker = true"
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div class="charge-print-options__section">
|
|
74
|
+
<label class="charge-print-options__label">备注</label>
|
|
75
|
+
<div class="charge-print-options__selector">
|
|
76
|
+
<VanField
|
|
77
|
+
v-model="remarks"
|
|
78
|
+
type="textarea"
|
|
79
|
+
placeholder="可选填写备注信息"
|
|
80
|
+
rows="2"
|
|
81
|
+
autosize
|
|
82
|
+
maxlength="200"
|
|
83
|
+
show-word-limit
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<VanPopup v-model:show="showPicker" position="bottom" round teleport="body">
|
|
89
|
+
<VanPicker
|
|
90
|
+
:columns="printOptions"
|
|
91
|
+
show-toolbar
|
|
92
|
+
title="选择打印方式"
|
|
93
|
+
@confirm="onConfirm"
|
|
94
|
+
@cancel="showPicker = false"
|
|
95
|
+
/>
|
|
96
|
+
</VanPopup>
|
|
97
|
+
</div>
|
|
98
|
+
</CardContainer>
|
|
99
|
+
</template>
|
|
100
|
+
|
|
101
|
+
<style scoped lang="less">
|
|
102
|
+
.charge-print-and-remarks {
|
|
103
|
+
margin-bottom: 16px;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.charge-print-options {
|
|
107
|
+
&__section {
|
|
108
|
+
margin-bottom: 16px;
|
|
109
|
+
|
|
110
|
+
&:last-child {
|
|
111
|
+
margin-bottom: 0;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&__label {
|
|
116
|
+
display: block;
|
|
117
|
+
font-size: 12px;
|
|
118
|
+
font-weight: 500;
|
|
119
|
+
color: #6b7280;
|
|
120
|
+
margin-bottom: 4px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
&__selector {
|
|
124
|
+
position: relative;
|
|
125
|
+
|
|
126
|
+
:deep(.van-field) {
|
|
127
|
+
background-color: #f9fafb;
|
|
128
|
+
border-radius: 6px;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
:deep(.van-field__control) {
|
|
133
|
+
background-color: #f9fafb;
|
|
134
|
+
border-radius: 6px;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
</style>
|