@uxda/appkit 4.0.12 → 4.0.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/balance/components/DateFilter.vue +12 -11
- package/src/balance/components/DateRange.vue +26 -10
- package/src/balance/components/ListFilter.vue +26 -2
- package/src/balance/components/ListFilterPicker.vue +41 -49
- package/src/shared/components/AppVerify.vue +33 -19
- package/src/shared/composables/index.ts +1 -0
- package/src/shared/composables/useCrypto.ts +76 -0
- package/src/user/components/UserEntry.vue +6 -11
- package/dist/appkit.css +0 -2470
- package/dist/assets/asset-DcH8Kg-2 +0 -1
- package/dist/index.js +0 -7658
package/package.json
CHANGED
|
@@ -22,18 +22,18 @@
|
|
|
22
22
|
<div class="btn confirm" @click="onOkClick">确定</div>
|
|
23
23
|
</div>
|
|
24
24
|
<div class="bottom"></div>
|
|
25
|
+
<nut-popup v-model:visible="datePickerOpen" position="bottom">
|
|
26
|
+
<nut-date-picker
|
|
27
|
+
v-model="focusedDate"
|
|
28
|
+
:min-date="minDate"
|
|
29
|
+
:max-date="maxDate"
|
|
30
|
+
:is-show-chinese="false"
|
|
31
|
+
:three-dimensional="false"
|
|
32
|
+
@cancel="datePickerOpen = false"
|
|
33
|
+
@confirm="onDatePickerComplete"
|
|
34
|
+
></nut-date-picker>
|
|
35
|
+
</nut-popup>
|
|
25
36
|
</div>
|
|
26
|
-
<nut-popup v-model:visible="datePickerOpen" position="bottom">
|
|
27
|
-
<nut-date-picker
|
|
28
|
-
v-model="focusedDate"
|
|
29
|
-
:min-date="minDate"
|
|
30
|
-
:max-date="maxDate"
|
|
31
|
-
:is-show-chinese="false"
|
|
32
|
-
:three-dimensional="false"
|
|
33
|
-
@cancel="datePickerOpen = false"
|
|
34
|
-
@confirm="onDatePickerComplete"
|
|
35
|
-
></nut-date-picker>
|
|
36
|
-
</nut-popup>
|
|
37
37
|
</template>
|
|
38
38
|
|
|
39
39
|
<script lang="ts" setup>
|
|
@@ -126,6 +126,7 @@ function switchDateInput(shift: string) {
|
|
|
126
126
|
display: flex;
|
|
127
127
|
flex-direction: column;
|
|
128
128
|
width: 100%;
|
|
129
|
+
position: relative;
|
|
129
130
|
.date-filter-header {
|
|
130
131
|
text-align: center;
|
|
131
132
|
height: 44px;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="date-range" @click="
|
|
2
|
+
<div class="date-range" @click="openDateRangePicker">
|
|
3
3
|
<div class="text number">{{ dateRangeDisplay }}</div>
|
|
4
4
|
<img
|
|
5
5
|
style="margin-top: -2px"
|
|
@@ -10,31 +10,47 @@
|
|
|
10
10
|
</template>
|
|
11
11
|
|
|
12
12
|
<script lang="ts" setup>
|
|
13
|
-
import { computed, reactive } from 'vue'
|
|
13
|
+
import { computed, PropType, reactive } from 'vue'
|
|
14
14
|
import { useNutshell } from '@uxda/nutshell/taro'
|
|
15
15
|
import DateFilter from './DateFilter.vue'
|
|
16
16
|
import dayjs from 'dayjs'
|
|
17
17
|
|
|
18
18
|
const $n = useNutshell()
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
from:
|
|
22
|
-
to:
|
|
20
|
+
export type DateRangeModel = {
|
|
21
|
+
from: string,
|
|
22
|
+
to: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const model = defineModel({
|
|
26
|
+
type: Object as PropType<DateRangeModel>,
|
|
27
|
+
required: false,
|
|
28
|
+
default: {
|
|
29
|
+
from: dayjs().add(-1, 'M').format('YYYY-MM-DD'),
|
|
30
|
+
to: dayjs().format('YYYY-MM-DD')
|
|
31
|
+
}
|
|
23
32
|
})
|
|
24
33
|
|
|
25
|
-
const
|
|
34
|
+
const openDateRangePicker = () => {
|
|
26
35
|
$n.sheet({
|
|
27
36
|
component: DateFilter,
|
|
28
37
|
props: {
|
|
29
|
-
from:
|
|
30
|
-
to:
|
|
38
|
+
from: model.value.from,
|
|
39
|
+
to: model.value.to,
|
|
40
|
+
},
|
|
41
|
+
onComplete (result: any) {
|
|
42
|
+
console.log('===openDateFilter complete', result)
|
|
43
|
+
model.value = {
|
|
44
|
+
from: result.from,
|
|
45
|
+
to: result.to
|
|
46
|
+
}
|
|
31
47
|
}
|
|
32
48
|
})
|
|
33
49
|
}
|
|
34
50
|
|
|
35
51
|
const dateRangeDisplay = computed(() => {
|
|
36
|
-
let startTime = (
|
|
37
|
-
let endTime = (
|
|
52
|
+
let startTime = (model.value.from || '').replace(/-/g, '.').substring(2)
|
|
53
|
+
let endTime = (model.value.to || '').replace(/-/g, '.').substring(2)
|
|
38
54
|
return startTime + ' - ' + endTime
|
|
39
55
|
})
|
|
40
56
|
|
|
@@ -9,16 +9,40 @@
|
|
|
9
9
|
</template>
|
|
10
10
|
|
|
11
11
|
<script lang="ts" setup>
|
|
12
|
-
import { computed, reactive } from 'vue'
|
|
12
|
+
import { computed, PropType, reactive } from 'vue'
|
|
13
13
|
import { useNutshell } from '@uxda/nutshell/taro'
|
|
14
14
|
import ListFilterPicker from './ListFilterPicker.vue'
|
|
15
15
|
|
|
16
16
|
const $n = useNutshell()
|
|
17
17
|
|
|
18
|
+
export type ListFilterValue = {
|
|
19
|
+
type: string,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const model = defineModel({
|
|
23
|
+
type: Object as PropType<ListFilterValue>,
|
|
24
|
+
default: {
|
|
25
|
+
type: ''
|
|
26
|
+
},
|
|
27
|
+
required: false,
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const emit = defineEmits<{
|
|
31
|
+
(e: 'update:modelValue', v: ListFilterValue): void,
|
|
32
|
+
(e: 'change'): void,
|
|
33
|
+
}>()
|
|
34
|
+
|
|
18
35
|
const openPicker = () => {
|
|
19
36
|
$n.sheet({
|
|
20
37
|
component: ListFilterPicker,
|
|
21
|
-
|
|
38
|
+
props: {
|
|
39
|
+
modelValue: model,
|
|
40
|
+
onComplete: (result) => {
|
|
41
|
+
emit('update:modelValue', {
|
|
42
|
+
type: result[0]
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
}
|
|
22
46
|
})
|
|
23
47
|
}
|
|
24
48
|
</script>
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="
|
|
3
|
-
<div class="
|
|
2
|
+
<div class="list-filter-picker">
|
|
3
|
+
<div class="list-filter-picker-title">
|
|
4
4
|
<h3>选择筛选项</h3>
|
|
5
5
|
</div>
|
|
6
6
|
<div class="consumption-filter-content">
|
|
7
7
|
<template v-for="(item, index) in filterSections" :key="index">
|
|
8
|
-
<div class="title">{{ item.
|
|
8
|
+
<div class="title">{{ item.label }}</div>
|
|
9
9
|
<div class="info">
|
|
10
10
|
<div
|
|
11
11
|
v-for="(it, i) in item.data"
|
|
12
|
-
@click="() => onFilterSectionClick(
|
|
13
|
-
:class="getItemClass(
|
|
12
|
+
@click="() => onFilterSectionClick(item.name, it.value)"
|
|
13
|
+
:class="getItemClass(item.name, it.value)"
|
|
14
14
|
class="info-item"
|
|
15
15
|
:key="i">
|
|
16
|
-
{{ typeof it === 'string' ? it : it.
|
|
16
|
+
{{ typeof it === 'string' ? it : it.label }}
|
|
17
17
|
</div>
|
|
18
18
|
</div>
|
|
19
19
|
</template>
|
|
@@ -33,21 +33,22 @@ import { UniData, UniDataItem } from '@uxda/nutshell/taro'
|
|
|
33
33
|
|
|
34
34
|
const $http = useHttp()
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
type ListFilterPickerModel = Record<string, string[]>
|
|
37
|
+
|
|
38
|
+
interface ListFilterPickerProps {
|
|
39
|
+
modelValue: ListFilterPickerModel
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
const props =
|
|
41
|
-
defineProps<
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
)
|
|
42
|
+
const props =
|
|
43
|
+
defineProps<ListFilterPickerProps>()
|
|
44
|
+
|
|
45
45
|
const emit = defineEmits(['complete'])
|
|
46
46
|
|
|
47
|
-
const result =
|
|
47
|
+
const result = ref<ListFilterPickerModel>(props.modelValue)
|
|
48
48
|
|
|
49
49
|
type FilterSecion = {
|
|
50
|
-
|
|
50
|
+
label: string,
|
|
51
|
+
name: string,
|
|
51
52
|
data: UniDataItem[]
|
|
52
53
|
}
|
|
53
54
|
|
|
@@ -56,54 +57,45 @@ type FilterSecion = {
|
|
|
56
57
|
*/
|
|
57
58
|
const filterSections = ref<FilterSecion[]>([
|
|
58
59
|
{
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
label: '明细类型',
|
|
61
|
+
name: 'type',
|
|
62
|
+
data: [
|
|
63
|
+
{
|
|
64
|
+
label: '全部',
|
|
65
|
+
value: ''
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
label: '提现',
|
|
69
|
+
value: 'withdrawal'
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
label: '收益',
|
|
73
|
+
value: 'income'
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
label: '兑换',
|
|
77
|
+
value: 'exchange'
|
|
78
|
+
}
|
|
79
|
+
]
|
|
69
80
|
},
|
|
70
|
-
{
|
|
71
|
-
title: '权益类目',
|
|
72
|
-
data: []
|
|
73
|
-
}
|
|
74
81
|
])
|
|
75
82
|
|
|
76
|
-
const getItemClass = (
|
|
83
|
+
const getItemClass = (name: string, value: string) => result.value[name]?.includes(value) ? ['current'] : ['']
|
|
77
84
|
|
|
78
|
-
const onFilterSectionClick = (index:
|
|
79
|
-
result[index] = value
|
|
85
|
+
const onFilterSectionClick = (index: string, value: string) => {
|
|
86
|
+
result.value[index] = [value]
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
const reset = () => {
|
|
83
|
-
result
|
|
84
|
-
result[1] = '全部'
|
|
85
|
-
result[2] = '全部'
|
|
86
|
-
result[3] = ''
|
|
90
|
+
result.value = {}
|
|
87
91
|
}
|
|
88
92
|
|
|
89
|
-
const 请求权益类目 = () => {
|
|
90
|
-
$http.get<权益类目[]>(endpoints.获取权益类目).then(data => {
|
|
91
|
-
filterSections.value[3].data = [
|
|
92
|
-
{ code: '', name: '全部' },
|
|
93
|
-
...data
|
|
94
|
-
]
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
请求权益类目()
|
|
99
|
-
|
|
100
93
|
const onOkClick = () => {
|
|
101
94
|
emit('complete', result)
|
|
102
95
|
}
|
|
103
96
|
</script>
|
|
104
97
|
<style lang="scss">
|
|
105
|
-
.
|
|
106
|
-
height: 100%;
|
|
98
|
+
.list-filter-picker {
|
|
107
99
|
display: flex;
|
|
108
100
|
flex-direction: column;
|
|
109
101
|
width: 100%;
|
|
@@ -4,20 +4,33 @@
|
|
|
4
4
|
<p class="caption">{{ message || '短信将发送至账号绑定手机号' }}</p>
|
|
5
5
|
<p class="number">{{ phone }}</p>
|
|
6
6
|
<ns-form v-model="formData">
|
|
7
|
-
<ns-input
|
|
7
|
+
<ns-input
|
|
8
|
+
name="code"
|
|
9
|
+
v-model="formData.code"
|
|
10
|
+
placeholder="请输入验证码"
|
|
11
|
+
variant="solid"
|
|
12
|
+
:rules="['required', {
|
|
8
13
|
name: 'function',
|
|
9
14
|
message: '输入错误, 请重新输入',
|
|
10
|
-
method: (value: string) => value.length ===
|
|
11
|
-
}]"
|
|
15
|
+
method: (value: string) => value.length === 6,
|
|
16
|
+
}]"
|
|
17
|
+
>
|
|
12
18
|
<template #append>
|
|
13
|
-
<ns-button
|
|
19
|
+
<ns-button
|
|
20
|
+
v-if="!sent"
|
|
21
|
+
size="xs"
|
|
22
|
+
variant="plain"
|
|
23
|
+
color="primary"
|
|
24
|
+
@click="send"
|
|
25
|
+
label="获取验证码"
|
|
26
|
+
/>
|
|
14
27
|
<div class="caption" v-if="sent">{{ countdown }} 秒收重新发送</div>
|
|
15
28
|
</template>
|
|
16
29
|
</ns-input>
|
|
17
30
|
</ns-form>
|
|
18
31
|
<div class="row buttons">
|
|
19
|
-
<ns-button round>取消</ns-button>
|
|
20
|
-
<ns-button round gradient="#FFEBC1,#FFD7A7,#FFB875/90">确认</ns-button>
|
|
32
|
+
<ns-button round @click="emits('cancel')">取消</ns-button>
|
|
33
|
+
<ns-button round gradient="#FFEBC1,#FFD7A7,#FFB875/90" @click="onOk">确认</ns-button>
|
|
21
34
|
</div>
|
|
22
35
|
</div>
|
|
23
36
|
</template>
|
|
@@ -27,27 +40,29 @@ import { NsForm, NsInput, NsButton } from '@uxda/nutshell/taro'
|
|
|
27
40
|
import { reactive, ref } from 'vue'
|
|
28
41
|
|
|
29
42
|
export interface AppVerifyProps {
|
|
30
|
-
phone: string
|
|
31
|
-
title?: string
|
|
32
|
-
message?: string
|
|
43
|
+
phone: string
|
|
44
|
+
title?: string
|
|
45
|
+
message?: string
|
|
46
|
+
onSend?: Function
|
|
33
47
|
}
|
|
34
48
|
|
|
35
|
-
const
|
|
36
|
-
(event: 'update:modelValue', value: boolean): void
|
|
37
|
-
}>()
|
|
49
|
+
const emits = defineEmits(['complete', 'cancel'])
|
|
38
50
|
|
|
39
51
|
const sent = ref(false),
|
|
40
52
|
countdown = ref(60)
|
|
41
53
|
|
|
42
54
|
let formData = reactive({
|
|
43
|
-
code: ''
|
|
55
|
+
code: '',
|
|
44
56
|
})
|
|
45
57
|
|
|
46
58
|
const send = () => {
|
|
47
59
|
sent.value = true
|
|
60
|
+
|
|
61
|
+
props.onSend && props.onSend()
|
|
62
|
+
|
|
48
63
|
countdown.value = 60
|
|
49
64
|
let timer = setInterval(() => {
|
|
50
|
-
countdown.value
|
|
65
|
+
countdown.value--
|
|
51
66
|
if (countdown.value <= 0) {
|
|
52
67
|
clearInterval(timer)
|
|
53
68
|
sent.value = false
|
|
@@ -55,12 +70,11 @@ const send = () => {
|
|
|
55
70
|
}, 1000)
|
|
56
71
|
}
|
|
57
72
|
|
|
58
|
-
const
|
|
59
|
-
|
|
73
|
+
const onOk = () => {
|
|
74
|
+
emits('complete', { code: formData.code })
|
|
60
75
|
}
|
|
61
76
|
|
|
62
|
-
defineProps<AppVerifyProps>()
|
|
63
|
-
|
|
77
|
+
const props = defineProps<AppVerifyProps>()
|
|
64
78
|
</script>
|
|
65
79
|
|
|
66
80
|
<style lang="scss">
|
|
@@ -81,4 +95,4 @@ defineProps<AppVerifyProps>()
|
|
|
81
95
|
}
|
|
82
96
|
}
|
|
83
97
|
}
|
|
84
|
-
</style>
|
|
98
|
+
</style>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// 解析脱敏姓名、手机号码等
|
|
2
|
+
|
|
3
|
+
export type CryptoConfig = {
|
|
4
|
+
maskField: string,
|
|
5
|
+
secretField: string,
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const defaultCryptoConfig: CryptoConfig = {
|
|
9
|
+
maskField: 'mask',
|
|
10
|
+
secretField: 'secretKey'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type DecodeResult<T extends string> = {
|
|
14
|
+
[key in T | `${T}Secret`]: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type DefaultDecodeResult = DecodeResult<'masked'>
|
|
18
|
+
|
|
19
|
+
export type DecodeFunction = (encoded: string, key: string) => DecodeResult<`${key}`>
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 解析以及解密脱敏数据
|
|
23
|
+
* @param config
|
|
24
|
+
* @returns
|
|
25
|
+
*/
|
|
26
|
+
export function useCrypto (config?: CryptoConfig) {
|
|
27
|
+
|
|
28
|
+
const conf = config || defaultCryptoConfig
|
|
29
|
+
|
|
30
|
+
const parse: DecodeFunction = (data: string, key?: string) => {
|
|
31
|
+
let k = key || 'masked'
|
|
32
|
+
let result: Record<string, any> = {}
|
|
33
|
+
try {
|
|
34
|
+
result = JSON.parse(data)
|
|
35
|
+
result = {
|
|
36
|
+
[k]: result.mask,
|
|
37
|
+
// 字段后加$表示用于解密的 secret
|
|
38
|
+
[`${k}$`]: result.secretKey
|
|
39
|
+
}
|
|
40
|
+
} catch (e) {}
|
|
41
|
+
return result
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 批量解析数组内的数据
|
|
46
|
+
* @param list
|
|
47
|
+
* @param field
|
|
48
|
+
* @returns
|
|
49
|
+
*/
|
|
50
|
+
const resolve = (list: any[], field?: string | string[]) => {
|
|
51
|
+
const [first] = list,
|
|
52
|
+
f = field
|
|
53
|
+
? Array.isArray(field) ? field : [field]
|
|
54
|
+
// 自动探测需要解密的字段
|
|
55
|
+
// '{"secretKey":"","mask":""}' 形式
|
|
56
|
+
: Object.entries(first)
|
|
57
|
+
.filter(([_, v]) => /^\{.*\}$/.test(v as string))
|
|
58
|
+
.map(([k]) => k)
|
|
59
|
+
return list
|
|
60
|
+
.map(item => {
|
|
61
|
+
let result = { ...item }
|
|
62
|
+
f.forEach(r => {
|
|
63
|
+
result = {
|
|
64
|
+
...result,
|
|
65
|
+
...parse(item[r], r)
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
return result
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
parse,
|
|
74
|
+
resolve,
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -21,21 +21,12 @@
|
|
|
21
21
|
<div class="user-entry-bd">
|
|
22
22
|
<div v-if="!mobile" class="user-entry-bd-bigtxt" @click="toLogin">
|
|
23
23
|
请登录
|
|
24
|
-
<
|
|
25
|
-
class="user-entry-bd-bigtxt-icon"
|
|
26
|
-
mode="aspectFit"
|
|
27
|
-
src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDEiIHZpZXdCb3g9IjAgMCA0MCA0MSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggb3BhY2l0eT0iMC4wMSIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wIDQwLjM1MTZINDBWMC4zNTE1NjJIMFY0MC4zNTE2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNCA4LjM1MTU2TDI2IDIwLjM1MTZMMTQgMzIuMzUxNiIgZmlsbD0iYmxhY2siIGZpbGwtb3BhY2l0eT0iMC4wMSIvPgo8cGF0aCBkPSJNMTQgOC4zNTE1NkwyNiAyMC4zNTE2TDE0IDMyLjM1MTYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIzIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+Cg=="
|
|
28
|
-
alt=""
|
|
29
|
-
/>
|
|
24
|
+
<span class="user-entry-bd-arrow">></span>
|
|
30
25
|
</div>
|
|
31
26
|
<template v-else>
|
|
32
27
|
<div @click="toUser" class="user-entry-bd-txt">
|
|
33
28
|
{{ name }}
|
|
34
|
-
<
|
|
35
|
-
style="width: 14px; height: 14px; margin-left: 2px"
|
|
36
|
-
src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjgiIGhlaWdodD0iMjgiIHZpZXdCb3g9IjAgMCAyOCAyOCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTExLjA4MzUgN0wxOC4wODM1IDE0TDExLjA4MzUgMjEiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMS43NSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo="
|
|
37
|
-
alt=""
|
|
38
|
-
/>
|
|
29
|
+
<span class="user-entry-bd-arrow">></span>
|
|
39
30
|
</div>
|
|
40
31
|
<div @click="toUser" class="user-entry-bd-smalltxt">{{ encodePhone(mobile) }}</div>
|
|
41
32
|
</template>
|
|
@@ -137,6 +128,10 @@ const emits = defineEmits(['jump', 'login'])
|
|
|
137
128
|
font-size: 15px;
|
|
138
129
|
line-height: 21px;
|
|
139
130
|
}
|
|
131
|
+
&-arrow {
|
|
132
|
+
font-size: 12px;
|
|
133
|
+
margin-left: 8px;
|
|
134
|
+
}
|
|
140
135
|
}
|
|
141
136
|
}
|
|
142
137
|
</style>
|