@uxda/appkit 1.2.8 → 1.2.12
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/.eslintrc.mjs +7 -7
- package/README.md +187 -187
- package/babel.config.js +12 -12
- package/dist/appkit.css +289 -71
- package/dist/index.js +862 -341
- package/dist/styles.css +1 -0
- package/package.json +78 -78
- package/project.config.json +15 -15
- package/project.tt.json +13 -13
- package/rollup.config.mjs +54 -54
- package/src/Appkit.ts +65 -65
- package/src/balance/api/endpoints.ts +125 -122
- package/src/balance/api/index.ts +82 -82
- package/src/balance/components/AccountView.vue +754 -649
- package/src/balance/components/BalanceCard.vue +209 -209
- package/src/balance/components/BalanceReminder.vue +83 -83
- package/src/balance/components/ConsumptionFilter.vue +218 -218
- package/src/balance/components/ConsumptionRules.vue +68 -68
- package/src/balance/components/DateFilter.vue +235 -235
- package/src/balance/components/SecondBalance.vue +71 -71
- package/src/balance/components/Tip.vue +46 -0
- package/src/balance/components/index.ts +9 -9
- package/src/balance/types.ts +90 -88
- package/src/components/dd-area/index.vue +222 -222
- package/src/components/dd-icon/doc.md +21 -21
- package/src/components/dd-icon/index.vue +23 -23
- package/src/components/dd-selector/index.vue +124 -124
- package/src/components/ocr-id/index.vue +110 -110
- package/src/components/ocr-id/types.d.ts +12 -12
- package/src/global.ts +6 -6
- package/src/index.ts +88 -86
- package/src/main.scss +1 -1
- package/src/payment/api/config.ts +7 -7
- package/src/payment/api/endpoints.ts +103 -78
- package/src/payment/api/index.ts +71 -71
- package/src/payment/components/AmountPicker.vue +93 -93
- package/src/payment/components/RechargeResult.vue +66 -54
- package/src/payment/components/RechargeView.vue +154 -154
- package/src/payment/components/RightsPicker.vue +106 -0
- package/src/payment/components/TradeView.vue +298 -0
- package/src/payment/components/UserAgreement.vue +141 -141
- package/src/payment/components/index.ts +22 -19
- package/src/payment/index.ts +5 -5
- package/src/payment/services/index.ts +16 -16
- package/src/payment/services/invoke-recharge.ts +25 -25
- package/src/payment/services/request-payment.ts +58 -31
- package/src/payment/types.ts +28 -23
- package/src/register/components/SelfRegistration.vue +227 -227
- package/src/register/components/index.ts +2 -2
- package/src/shared/components/AppDrawer.vue +58 -58
- package/src/shared/components/EmptyView.vue +33 -33
- package/src/shared/components/PageHeader.vue +79 -79
- package/src/shared/components/index.ts +6 -6
- package/src/shared/composables/index.ts +2 -2
- package/src/shared/composables/useSafeArea.ts +43 -43
- package/src/shared/composables/useTabbar.ts +24 -24
- package/src/shared/http/Http.ts +126 -126
- package/src/shared/http/index.ts +1 -1
- package/src/shared/http/types.ts +157 -157
- package/src/shared/index.ts +3 -3
- package/src/shared/weixin/payment.ts +38 -38
- package/src/styles/fonts.scss +2 -2
- package/src/styles/vars.scss +3 -3
- package/tsconfig.json +30 -30
- package/types/global.d.ts +21 -21
- package/types/vue.d.ts +10 -10
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import BalanceCard from './BalanceCard.vue'
|
|
2
|
-
import AccountView from './AccountView.vue'
|
|
3
|
-
import BalanceReminder from './BalanceReminder.vue'
|
|
4
|
-
|
|
5
|
-
export {
|
|
6
|
-
BalanceCard,
|
|
7
|
-
AccountView,
|
|
8
|
-
BalanceReminder,
|
|
9
|
-
}
|
|
1
|
+
import BalanceCard from './BalanceCard.vue'
|
|
2
|
+
import AccountView from './AccountView.vue'
|
|
3
|
+
import BalanceReminder from './BalanceReminder.vue'
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
BalanceCard,
|
|
7
|
+
AccountView,
|
|
8
|
+
BalanceReminder,
|
|
9
|
+
}
|
package/src/balance/types.ts
CHANGED
|
@@ -1,88 +1,90 @@
|
|
|
1
|
-
export const consumptionTypes = [
|
|
2
|
-
"全部",
|
|
3
|
-
"充值",
|
|
4
|
-
"缴费",
|
|
5
|
-
"返额",
|
|
6
|
-
"增加",
|
|
7
|
-
"扣减",
|
|
8
|
-
"消耗",
|
|
9
|
-
"退回",
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
1
|
+
export const consumptionTypes = [
|
|
2
|
+
"全部",
|
|
3
|
+
"充值",
|
|
4
|
+
"缴费",
|
|
5
|
+
"返额",
|
|
6
|
+
"增加",
|
|
7
|
+
"扣减",
|
|
8
|
+
"消耗",
|
|
9
|
+
"退回",
|
|
10
|
+
"赠送",
|
|
11
|
+
"换购"
|
|
12
|
+
] as const;
|
|
13
|
+
|
|
14
|
+
export type ConsumptionType = (typeof consumptionTypes)[number];
|
|
15
|
+
|
|
16
|
+
export const consumptionPositions = ["全部", "云豆", "权益"] as const;
|
|
17
|
+
|
|
18
|
+
export type ConsumptionPosition = (typeof consumptionPositions)[number];
|
|
19
|
+
|
|
20
|
+
export const consumptionDirections = ["全部", "收入", "支出"] as const;
|
|
21
|
+
|
|
22
|
+
export type ConsumptionDirection = (typeof consumptionDirections)[number];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 账户流水
|
|
26
|
+
*/
|
|
27
|
+
export type 账户流水 = {
|
|
28
|
+
/**
|
|
29
|
+
* 数量
|
|
30
|
+
*/
|
|
31
|
+
amount: number;
|
|
32
|
+
/**
|
|
33
|
+
* 交易名称
|
|
34
|
+
*/
|
|
35
|
+
title: string;
|
|
36
|
+
/**
|
|
37
|
+
* 交易说明
|
|
38
|
+
*/
|
|
39
|
+
description: string;
|
|
40
|
+
/**
|
|
41
|
+
* 交易时间
|
|
42
|
+
**/
|
|
43
|
+
time: number;
|
|
44
|
+
/**
|
|
45
|
+
* 交易类型类型
|
|
46
|
+
*/
|
|
47
|
+
交易类型: ConsumptionType;
|
|
48
|
+
权益类目: string;
|
|
49
|
+
/**
|
|
50
|
+
* 账户类型
|
|
51
|
+
*/
|
|
52
|
+
账户类型: ConsumptionPosition;
|
|
53
|
+
/**
|
|
54
|
+
* 收入/支出
|
|
55
|
+
*/
|
|
56
|
+
收入还是支出: ConsumptionDirection;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 账户流水筛选项
|
|
61
|
+
*/
|
|
62
|
+
export type 账户流水筛选项 = Pick<
|
|
63
|
+
账户流水,
|
|
64
|
+
"交易类型" | "账户类型" | "收入还是支出" | "权益类目"
|
|
65
|
+
> & {
|
|
66
|
+
dateFrom: string;
|
|
67
|
+
dateTo: string;
|
|
68
|
+
page: number;
|
|
69
|
+
pageSize: 20;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export type ConsumptionGroup = {
|
|
73
|
+
date: string;
|
|
74
|
+
consumptions: 账户流水[];
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export type Privilege = {
|
|
78
|
+
title: string;
|
|
79
|
+
count: number;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export type Balance = {
|
|
83
|
+
total: number;
|
|
84
|
+
privileges: any
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export type 权益类目 = {
|
|
88
|
+
name: string;
|
|
89
|
+
code: string;
|
|
90
|
+
};
|
|
@@ -1,222 +1,222 @@
|
|
|
1
|
-
<!--* NAME: index-->
|
|
2
|
-
<!--* AUTHOR: yanglong-->
|
|
3
|
-
<!--* UPDATE: 2022-02-21 17:43-->
|
|
4
|
-
<!--* TIP: 微信原生实现多列选择器-->
|
|
5
|
-
<script setup lang="ts">
|
|
6
|
-
import {computed, ref, watch} from 'vue'
|
|
7
|
-
import Taro from '@tarojs/taro'
|
|
8
|
-
import DdIcon from '../dd-icon/index.vue'
|
|
9
|
-
|
|
10
|
-
interface AreaItem {
|
|
11
|
-
value: string
|
|
12
|
-
shortId: string
|
|
13
|
-
label: string
|
|
14
|
-
children: AreaItem[]
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export type AreaType = 'province' | 'city' | 'region'
|
|
18
|
-
|
|
19
|
-
export interface PropsType {
|
|
20
|
-
value?: string // 地址code
|
|
21
|
-
rightIcon?: boolean
|
|
22
|
-
placeholder?: string
|
|
23
|
-
disabled?: boolean
|
|
24
|
-
type?: AreaType
|
|
25
|
-
formatter?: (values: AreaItem[]) => string
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const props = withDefaults(defineProps<PropsType>(), {
|
|
29
|
-
value: '',
|
|
30
|
-
rightIcon: true,
|
|
31
|
-
placeholder: '请选择',
|
|
32
|
-
disabled: false,
|
|
33
|
-
type: 'region',
|
|
34
|
-
formatter: (values: AreaItem[]) => values.map((item:AreaItem) => item.label).join('')
|
|
35
|
-
})
|
|
36
|
-
const emit = defineEmits(['update:value', 'change', 'cancel'])
|
|
37
|
-
|
|
38
|
-
const areaFormatOptions = computed<AreaItem[]>(() => {
|
|
39
|
-
const {province_list, city_list, county_list} = JSON.parse(Taro.getStorageSync('wechat_area'))
|
|
40
|
-
const map = new Map()
|
|
41
|
-
city_list.forEach((item: any) => {
|
|
42
|
-
const provinceShortId = item.id.slice(0, 2)
|
|
43
|
-
if (!map.has(provinceShortId)) {
|
|
44
|
-
map.set(provinceShortId, [])
|
|
45
|
-
}
|
|
46
|
-
map.get(provinceShortId).push({
|
|
47
|
-
...item,
|
|
48
|
-
shortId: item.id.slice(0, 4)
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
county_list.forEach((item: any) => {
|
|
52
|
-
const cityShortId = item.id.slice(0, 4)
|
|
53
|
-
if (!map.has(cityShortId)) {
|
|
54
|
-
map.set(cityShortId, [])
|
|
55
|
-
}
|
|
56
|
-
map.get(cityShortId).push({
|
|
57
|
-
...item,
|
|
58
|
-
shortId: item.id
|
|
59
|
-
})
|
|
60
|
-
})
|
|
61
|
-
return province_list.map((province: any) => {
|
|
62
|
-
const provinceShortId = province.id.slice(0, 2)
|
|
63
|
-
return {
|
|
64
|
-
value: province.id,
|
|
65
|
-
shortId: provinceShortId,
|
|
66
|
-
label: province.name,
|
|
67
|
-
children: map.get(provinceShortId)?.map((city: any) => ({
|
|
68
|
-
value: city.id,
|
|
69
|
-
shortId: city.shortId,
|
|
70
|
-
label: city.name,
|
|
71
|
-
children: map.get(city.shortId)?.map((region: any) => ({
|
|
72
|
-
value: region.id,
|
|
73
|
-
shortId: region.shortId,
|
|
74
|
-
label: region.name,
|
|
75
|
-
children: []
|
|
76
|
-
})) ?? [],
|
|
77
|
-
})) ?? [],
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
const tmpSelectedIndex = ref<number[]>([0, 0, 0])
|
|
83
|
-
const selectedIndex = ref<number[]>([0, 0, 0])
|
|
84
|
-
const selectedItem = ref<AreaItem[]>([])
|
|
85
|
-
|
|
86
|
-
const options = computed<AreaItem[][]>(() => {
|
|
87
|
-
const provinceOption = areaFormatOptions.value
|
|
88
|
-
if (props.type === 'province') {
|
|
89
|
-
return [provinceOption]
|
|
90
|
-
}
|
|
91
|
-
const cityOption = provinceOption[tmpSelectedIndex.value[0]]?.children ?? []
|
|
92
|
-
if (props.type === 'city') {
|
|
93
|
-
return [provinceOption, cityOption]
|
|
94
|
-
}
|
|
95
|
-
const regionOption = cityOption[tmpSelectedIndex.value[1]]?.children ?? []
|
|
96
|
-
return [provinceOption, cityOption, regionOption]
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
function init() {
|
|
100
|
-
selectedIndex.value = findIndexByValue()
|
|
101
|
-
tmpSelectedIndex.value = [...selectedIndex.value]
|
|
102
|
-
if (props.value) {
|
|
103
|
-
const items = []
|
|
104
|
-
for (let index = 0; index < options.value.length; index++) {
|
|
105
|
-
const item = options.value[index]?.[selectedIndex.value[index]]
|
|
106
|
-
if (item){
|
|
107
|
-
items.push(item)
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
selectedItem.value = items
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function findIndexByValue() {
|
|
115
|
-
if (props.value) {
|
|
116
|
-
const provinceId = props.value.slice(0, 2).toString().padEnd(6, '0')
|
|
117
|
-
const cityId = props.value.slice(0, 4).toString().padEnd(6, '0')
|
|
118
|
-
const regionId = props.value.toString()
|
|
119
|
-
for (let provinceIndex = 0; provinceIndex < areaFormatOptions.value.length; provinceIndex++) {
|
|
120
|
-
const province = areaFormatOptions.value[provinceIndex]
|
|
121
|
-
if (provinceId == province.value) {
|
|
122
|
-
for (let cityIndex = 0; cityIndex < province.children.length; cityIndex++) {
|
|
123
|
-
const city = province.children[cityIndex]
|
|
124
|
-
if (cityId == city.value) {
|
|
125
|
-
for (let regionIndex = 0; regionIndex < city.children.length; regionIndex++) {
|
|
126
|
-
const region = city.children[regionIndex]
|
|
127
|
-
if (regionId == region.value) {
|
|
128
|
-
return [provinceIndex, cityIndex, regionIndex]
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return [provinceIndex, cityIndex, 0]
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return [provinceIndex, 0, 0]
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return [0, 0, 0]
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function onChange() {
|
|
142
|
-
const lastSelectedIndex = options.value.length - 1
|
|
143
|
-
const result = {
|
|
144
|
-
values: [],
|
|
145
|
-
labels: []
|
|
146
|
-
}
|
|
147
|
-
for (let index = 0; index <= lastSelectedIndex; index++) {
|
|
148
|
-
const item = options.value[index]?.[tmpSelectedIndex.value[index]]
|
|
149
|
-
if (item){
|
|
150
|
-
result.values.push(item.value)
|
|
151
|
-
result.labels.push(item.label)
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
emit('update:value', result.values[result.values.length-1])
|
|
155
|
-
emit('change', result)
|
|
156
|
-
console.log(result)
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function onCancel(e: any) {
|
|
160
|
-
init()
|
|
161
|
-
emit('cancel', e)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function onColumnChange({detail: {column, value}}) {
|
|
165
|
-
const resetIndex = Array.from({length: tmpSelectedIndex.value.length - column - 1, }).fill(0)
|
|
166
|
-
tmpSelectedIndex.value = [...tmpSelectedIndex.value.slice(0,column), value, ...resetIndex ]
|
|
167
|
-
console.log(tmpSelectedIndex.value)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
watch(
|
|
171
|
-
() => props.value,
|
|
172
|
-
() => { init() },
|
|
173
|
-
{deep: true, immediate: true}
|
|
174
|
-
)
|
|
175
|
-
</script>
|
|
176
|
-
|
|
177
|
-
<template>
|
|
178
|
-
<picker
|
|
179
|
-
:range="options"
|
|
180
|
-
range-key="label"
|
|
181
|
-
:value="tmpSelectedIndex"
|
|
182
|
-
mode="multiSelector"
|
|
183
|
-
@columnchange="onColumnChange"
|
|
184
|
-
@change="onChange"
|
|
185
|
-
@cancel="onCancel"
|
|
186
|
-
style="flex: 1"
|
|
187
|
-
:disabled="props.disabled">
|
|
188
|
-
<div class="dd-area">
|
|
189
|
-
<div
|
|
190
|
-
:class="props.value && !props.disabled ? 'dd-area-value' : 'dd-area-label'">
|
|
191
|
-
{{ props.value ? props.formatter(selectedItem) : props.placeholder }}
|
|
192
|
-
</div>
|
|
193
|
-
<slot name="icon">
|
|
194
|
-
<DdIcon
|
|
195
|
-
v-if="props.rightIcon"
|
|
196
|
-
name="icon-arrow"
|
|
197
|
-
size="11px"
|
|
198
|
-
:color="
|
|
199
|
-
props.value !== '' && !props.disabled ? '#353535' : '#DFDFDF'
|
|
200
|
-
"
|
|
201
|
-
class="icon-arrow"/>
|
|
202
|
-
</slot>
|
|
203
|
-
</div>
|
|
204
|
-
</picker>
|
|
205
|
-
</template>
|
|
206
|
-
|
|
207
|
-
<style lang="scss">
|
|
208
|
-
.dd-area {
|
|
209
|
-
display: flex;
|
|
210
|
-
justify-content: flex-end;
|
|
211
|
-
align-items: center;
|
|
212
|
-
|
|
213
|
-
&-value {
|
|
214
|
-
text-align: right;
|
|
215
|
-
color: black;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
&-label {
|
|
219
|
-
color: var(--placeholder-color);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
</style>
|
|
1
|
+
<!--* NAME: index-->
|
|
2
|
+
<!--* AUTHOR: yanglong-->
|
|
3
|
+
<!--* UPDATE: 2022-02-21 17:43-->
|
|
4
|
+
<!--* TIP: 微信原生实现多列选择器-->
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import {computed, ref, watch} from 'vue'
|
|
7
|
+
import Taro from '@tarojs/taro'
|
|
8
|
+
import DdIcon from '../dd-icon/index.vue'
|
|
9
|
+
|
|
10
|
+
interface AreaItem {
|
|
11
|
+
value: string
|
|
12
|
+
shortId: string
|
|
13
|
+
label: string
|
|
14
|
+
children: AreaItem[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type AreaType = 'province' | 'city' | 'region'
|
|
18
|
+
|
|
19
|
+
export interface PropsType {
|
|
20
|
+
value?: string // 地址code
|
|
21
|
+
rightIcon?: boolean
|
|
22
|
+
placeholder?: string
|
|
23
|
+
disabled?: boolean
|
|
24
|
+
type?: AreaType
|
|
25
|
+
formatter?: (values: AreaItem[]) => string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const props = withDefaults(defineProps<PropsType>(), {
|
|
29
|
+
value: '',
|
|
30
|
+
rightIcon: true,
|
|
31
|
+
placeholder: '请选择',
|
|
32
|
+
disabled: false,
|
|
33
|
+
type: 'region',
|
|
34
|
+
formatter: (values: AreaItem[]) => values.map((item:AreaItem) => item.label).join('')
|
|
35
|
+
})
|
|
36
|
+
const emit = defineEmits(['update:value', 'change', 'cancel'])
|
|
37
|
+
|
|
38
|
+
const areaFormatOptions = computed<AreaItem[]>(() => {
|
|
39
|
+
const {province_list, city_list, county_list} = JSON.parse(Taro.getStorageSync('wechat_area'))
|
|
40
|
+
const map = new Map()
|
|
41
|
+
city_list.forEach((item: any) => {
|
|
42
|
+
const provinceShortId = item.id.slice(0, 2)
|
|
43
|
+
if (!map.has(provinceShortId)) {
|
|
44
|
+
map.set(provinceShortId, [])
|
|
45
|
+
}
|
|
46
|
+
map.get(provinceShortId).push({
|
|
47
|
+
...item,
|
|
48
|
+
shortId: item.id.slice(0, 4)
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
county_list.forEach((item: any) => {
|
|
52
|
+
const cityShortId = item.id.slice(0, 4)
|
|
53
|
+
if (!map.has(cityShortId)) {
|
|
54
|
+
map.set(cityShortId, [])
|
|
55
|
+
}
|
|
56
|
+
map.get(cityShortId).push({
|
|
57
|
+
...item,
|
|
58
|
+
shortId: item.id
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
return province_list.map((province: any) => {
|
|
62
|
+
const provinceShortId = province.id.slice(0, 2)
|
|
63
|
+
return {
|
|
64
|
+
value: province.id,
|
|
65
|
+
shortId: provinceShortId,
|
|
66
|
+
label: province.name,
|
|
67
|
+
children: map.get(provinceShortId)?.map((city: any) => ({
|
|
68
|
+
value: city.id,
|
|
69
|
+
shortId: city.shortId,
|
|
70
|
+
label: city.name,
|
|
71
|
+
children: map.get(city.shortId)?.map((region: any) => ({
|
|
72
|
+
value: region.id,
|
|
73
|
+
shortId: region.shortId,
|
|
74
|
+
label: region.name,
|
|
75
|
+
children: []
|
|
76
|
+
})) ?? [],
|
|
77
|
+
})) ?? [],
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
const tmpSelectedIndex = ref<number[]>([0, 0, 0])
|
|
83
|
+
const selectedIndex = ref<number[]>([0, 0, 0])
|
|
84
|
+
const selectedItem = ref<AreaItem[]>([])
|
|
85
|
+
|
|
86
|
+
const options = computed<AreaItem[][]>(() => {
|
|
87
|
+
const provinceOption = areaFormatOptions.value
|
|
88
|
+
if (props.type === 'province') {
|
|
89
|
+
return [provinceOption]
|
|
90
|
+
}
|
|
91
|
+
const cityOption = provinceOption[tmpSelectedIndex.value[0]]?.children ?? []
|
|
92
|
+
if (props.type === 'city') {
|
|
93
|
+
return [provinceOption, cityOption]
|
|
94
|
+
}
|
|
95
|
+
const regionOption = cityOption[tmpSelectedIndex.value[1]]?.children ?? []
|
|
96
|
+
return [provinceOption, cityOption, regionOption]
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
function init() {
|
|
100
|
+
selectedIndex.value = findIndexByValue()
|
|
101
|
+
tmpSelectedIndex.value = [...selectedIndex.value]
|
|
102
|
+
if (props.value) {
|
|
103
|
+
const items = []
|
|
104
|
+
for (let index = 0; index < options.value.length; index++) {
|
|
105
|
+
const item = options.value[index]?.[selectedIndex.value[index]]
|
|
106
|
+
if (item){
|
|
107
|
+
items.push(item)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
selectedItem.value = items
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function findIndexByValue() {
|
|
115
|
+
if (props.value) {
|
|
116
|
+
const provinceId = props.value.slice(0, 2).toString().padEnd(6, '0')
|
|
117
|
+
const cityId = props.value.slice(0, 4).toString().padEnd(6, '0')
|
|
118
|
+
const regionId = props.value.toString()
|
|
119
|
+
for (let provinceIndex = 0; provinceIndex < areaFormatOptions.value.length; provinceIndex++) {
|
|
120
|
+
const province = areaFormatOptions.value[provinceIndex]
|
|
121
|
+
if (provinceId == province.value) {
|
|
122
|
+
for (let cityIndex = 0; cityIndex < province.children.length; cityIndex++) {
|
|
123
|
+
const city = province.children[cityIndex]
|
|
124
|
+
if (cityId == city.value) {
|
|
125
|
+
for (let regionIndex = 0; regionIndex < city.children.length; regionIndex++) {
|
|
126
|
+
const region = city.children[regionIndex]
|
|
127
|
+
if (regionId == region.value) {
|
|
128
|
+
return [provinceIndex, cityIndex, regionIndex]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return [provinceIndex, cityIndex, 0]
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return [provinceIndex, 0, 0]
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return [0, 0, 0]
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function onChange() {
|
|
142
|
+
const lastSelectedIndex = options.value.length - 1
|
|
143
|
+
const result = {
|
|
144
|
+
values: [],
|
|
145
|
+
labels: []
|
|
146
|
+
}
|
|
147
|
+
for (let index = 0; index <= lastSelectedIndex; index++) {
|
|
148
|
+
const item = options.value[index]?.[tmpSelectedIndex.value[index]]
|
|
149
|
+
if (item){
|
|
150
|
+
result.values.push(item.value)
|
|
151
|
+
result.labels.push(item.label)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
emit('update:value', result.values[result.values.length-1])
|
|
155
|
+
emit('change', result)
|
|
156
|
+
console.log(result)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function onCancel(e: any) {
|
|
160
|
+
init()
|
|
161
|
+
emit('cancel', e)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function onColumnChange({detail: {column, value}}) {
|
|
165
|
+
const resetIndex = Array.from({length: tmpSelectedIndex.value.length - column - 1, }).fill(0)
|
|
166
|
+
tmpSelectedIndex.value = [...tmpSelectedIndex.value.slice(0,column), value, ...resetIndex ]
|
|
167
|
+
console.log(tmpSelectedIndex.value)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
watch(
|
|
171
|
+
() => props.value,
|
|
172
|
+
() => { init() },
|
|
173
|
+
{deep: true, immediate: true}
|
|
174
|
+
)
|
|
175
|
+
</script>
|
|
176
|
+
|
|
177
|
+
<template>
|
|
178
|
+
<picker
|
|
179
|
+
:range="options"
|
|
180
|
+
range-key="label"
|
|
181
|
+
:value="tmpSelectedIndex"
|
|
182
|
+
mode="multiSelector"
|
|
183
|
+
@columnchange="onColumnChange"
|
|
184
|
+
@change="onChange"
|
|
185
|
+
@cancel="onCancel"
|
|
186
|
+
style="flex: 1"
|
|
187
|
+
:disabled="props.disabled">
|
|
188
|
+
<div class="dd-area">
|
|
189
|
+
<div
|
|
190
|
+
:class="props.value && !props.disabled ? 'dd-area-value' : 'dd-area-label'">
|
|
191
|
+
{{ props.value ? props.formatter(selectedItem) : props.placeholder }}
|
|
192
|
+
</div>
|
|
193
|
+
<slot name="icon">
|
|
194
|
+
<DdIcon
|
|
195
|
+
v-if="props.rightIcon"
|
|
196
|
+
name="icon-arrow"
|
|
197
|
+
size="11px"
|
|
198
|
+
:color="
|
|
199
|
+
props.value !== '' && !props.disabled ? '#353535' : '#DFDFDF'
|
|
200
|
+
"
|
|
201
|
+
class="icon-arrow"/>
|
|
202
|
+
</slot>
|
|
203
|
+
</div>
|
|
204
|
+
</picker>
|
|
205
|
+
</template>
|
|
206
|
+
|
|
207
|
+
<style lang="scss">
|
|
208
|
+
.dd-area {
|
|
209
|
+
display: flex;
|
|
210
|
+
justify-content: flex-end;
|
|
211
|
+
align-items: center;
|
|
212
|
+
|
|
213
|
+
&-value {
|
|
214
|
+
text-align: right;
|
|
215
|
+
color: black;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
&-label {
|
|
219
|
+
color: var(--placeholder-color);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
</style>
|