wui-components-v2 1.1.35 → 1.1.36
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/components/card-botom-buttons/card-botom-buttons.vue +13 -6
- package/components/enume-select-control/enume-select-control.vue +77 -0
- package/components/wui-details-page/wui-details-page.vue +3 -1
- package/components/wui-list/wui-list.vue +5 -39
- package/components/wui-notify-info/notify-handle.vue +53 -0
- package/components/wui-notify-info/wui-notify-info.vue +91 -34
- package/components/wui-search-history-babbar/components/SearchBar.vue +3 -2
- package/components/wui-search-history-babbar/wui-search-history-babbar.vue +96 -55
- package/composables/useEnumes.ts +42 -0
- package/composables/useMenus.ts +5 -3
- package/index.ts +2 -1
- package/package.json +1 -1
- package/type.ts +1 -0
|
@@ -197,7 +197,7 @@ function closeMoreButn() {
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
// 点击更多按钮
|
|
200
|
-
function select({ item }) {
|
|
200
|
+
function select({ item }: { item: any }) {
|
|
201
201
|
message.confirm({
|
|
202
202
|
msg: `确定${item.title}操作吗?`,
|
|
203
203
|
title: '提示',
|
|
@@ -225,9 +225,16 @@ function select({ item }) {
|
|
|
225
225
|
{{ subitem.title }}
|
|
226
226
|
</wd-button>
|
|
227
227
|
</view> -->
|
|
228
|
-
<
|
|
229
|
-
|
|
230
|
-
|
|
228
|
+
<view>
|
|
229
|
+
<wd-button v-if="morebutns.length > 3" size="small" type="info" @click="() => { showMoreButn = true }">
|
|
230
|
+
更多
|
|
231
|
+
</wd-button>
|
|
232
|
+
<view v-else>
|
|
233
|
+
<wd-button v-for="subitem in morebutns" :key="subitem.id" plain size="small" @click="() => { select({ item: subitem }) }">
|
|
234
|
+
{{ subitem.title }}
|
|
235
|
+
</wd-button>
|
|
236
|
+
</view>
|
|
237
|
+
</view>
|
|
231
238
|
|
|
232
239
|
<wd-button v-if="props.item.buttons.includes('dtmplEdit')" size="small" @click="edit()">
|
|
233
240
|
编辑
|
|
@@ -238,9 +245,9 @@ function select({ item }) {
|
|
|
238
245
|
<wd-button v-if="props.item.buttons.includes('singleDelete')" size="small" type="error" @click="del()">
|
|
239
246
|
删除
|
|
240
247
|
</wd-button>
|
|
241
|
-
<ActionPopup
|
|
248
|
+
<ActionPopup
|
|
242
249
|
v-model:show="actionItemShow" :enum-column="props.enumColumn" :zpaging="props.zpaging"
|
|
243
|
-
:field-group="actionItem" :code="props.code"
|
|
250
|
+
:field-group="actionItem" :code="props.code"
|
|
244
251
|
/>
|
|
245
252
|
<!-- 更多按钮 -->
|
|
246
253
|
<wd-action-sheet v-model="showMoreButn" :actions="morebutns" @close="closeMoreButn" @select="select" />
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref ,defineProps,defineEmits,onMounted,computed} from 'vue'
|
|
3
|
+
import { useEnums } from '../../composables/useEnumes'
|
|
4
|
+
import type { Config, Entities, Enums } from '../../type'
|
|
5
|
+
import {pageConfig } from '../../api/page'
|
|
6
|
+
defineOptions({
|
|
7
|
+
name: 'EnumeSelectControl',
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
const props = defineProps<{
|
|
11
|
+
sourceId: string
|
|
12
|
+
id:string
|
|
13
|
+
label?:string
|
|
14
|
+
title?:string
|
|
15
|
+
modelValue:string
|
|
16
|
+
placeholder?:string
|
|
17
|
+
disabled?:boolean
|
|
18
|
+
required?:boolean
|
|
19
|
+
rules?:any
|
|
20
|
+
zIndex?:number
|
|
21
|
+
type:'checkbox'|'radio'
|
|
22
|
+
}>()
|
|
23
|
+
const emits=defineEmits(['update:modelValue'])
|
|
24
|
+
|
|
25
|
+
const config=ref<Config>()
|
|
26
|
+
const { enumColumn,getEnums }= useEnums({ config })
|
|
27
|
+
async function getPageConfig() {
|
|
28
|
+
try {
|
|
29
|
+
const res = await pageConfig(props.sourceId)
|
|
30
|
+
|
|
31
|
+
if (res.ltmplConfig) {
|
|
32
|
+
config.value = res.ltmplConfig
|
|
33
|
+
getEnums()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.log(error)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const comEnums=computed(()=>{
|
|
42
|
+
const mstrucId=config.value?.criterias?.find((item)=>item.sourceId===props.id)?.mstrucId
|
|
43
|
+
|
|
44
|
+
if(mstrucId)return enumColumn.value[mstrucId]?.map((item)=>{
|
|
45
|
+
return {
|
|
46
|
+
id:item.id,
|
|
47
|
+
label:item.title,
|
|
48
|
+
value:`${item.id}@R@${item.value}`
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
return []
|
|
53
|
+
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
onMounted(()=>{
|
|
57
|
+
getPageConfig()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const confirm=(event:any)=>{
|
|
61
|
+
emits('update:modelValue',event.value)
|
|
62
|
+
}
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<script lang="ts">
|
|
66
|
+
export default {
|
|
67
|
+
options: {
|
|
68
|
+
virtualHost: true,
|
|
69
|
+
addGlobalClass: true,
|
|
70
|
+
styleIsolation: 'shared',
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
</script>
|
|
74
|
+
|
|
75
|
+
<template>
|
|
76
|
+
<wd-select-picker :title="props.title" :placeholder="props.placeholder" :disabled="props.disabled" :required="props.required" :rules="props.rules" :zIndex="props.zIndex" :type="$props.type" :modelValue="modelValue" :label="props.label" @confirm="confirm" :columns="comEnums"></wd-select-picker>
|
|
77
|
+
</template>
|
|
@@ -36,6 +36,7 @@ const groups = ref<Groups>({
|
|
|
36
36
|
relationNames: [],
|
|
37
37
|
readOnly: false,
|
|
38
38
|
displayConfig: [],
|
|
39
|
+
|
|
39
40
|
})
|
|
40
41
|
const loading = ref(false)
|
|
41
42
|
// 折叠面板
|
|
@@ -133,7 +134,7 @@ async function getDetailData() {
|
|
|
133
134
|
<view v-for="(field, subindex) in data.arrayMap[group.id]" :key="field.code">
|
|
134
135
|
<foldCard :index="subindex" :enum-column="{}" :groups="group" :source-id="sourceId" :columns="group.fields" model="complex" :data="field">
|
|
135
136
|
<template #buttons>
|
|
136
|
-
<CardBotomButtons :source-id="group.id" :item="groups" :code="field.code" :data="data" />
|
|
137
|
+
<CardBotomButtons :primary-column="group.primaryColumn || { controlType: '', extControlType: '', sourceId: '', mstrucId: '' }" :source-id="group.id" :item="groups" :code="field.code" :data="data" />
|
|
137
138
|
</template>
|
|
138
139
|
</foldCard>
|
|
139
140
|
</view>
|
|
@@ -141,5 +142,6 @@ async function getDetailData() {
|
|
|
141
142
|
</wd-collapse-item>
|
|
142
143
|
</wd-collapse>
|
|
143
144
|
</view>
|
|
145
|
+
<slot name="botombuttons" />
|
|
144
146
|
</view>
|
|
145
147
|
</template>
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import { defineOptions, defineProps, onMounted, onUnmounted, ref } from 'vue'
|
|
3
3
|
import { onLoad } from '@dcloudio/uni-app'
|
|
4
|
-
import {
|
|
4
|
+
import {listData, pageConfig, pageKey } from '../../api/page'
|
|
5
5
|
import foldCard from '../fold-card/fold-card.vue'
|
|
6
|
-
import type { Config, Entities
|
|
6
|
+
import type { Config, Entities } from '../../type'
|
|
7
7
|
import Search from '../search/search.vue'
|
|
8
8
|
import ListTopButtons from '../list-top-buttons/list-top-buttons.vue'
|
|
9
9
|
import CardBotomButtons from '../card-botom-buttons/card-botom-buttons.vue'
|
|
10
10
|
import { generateHighResolutionID } from '../../utils/index'
|
|
11
11
|
import productCard from '../product-card/product-card.vue'
|
|
12
12
|
import tabSearch from '../tab-search/tab-search.vue'
|
|
13
|
-
import
|
|
14
|
-
|
|
13
|
+
import {useEnums} from '../../composables/useEnumes'
|
|
15
14
|
defineOptions({
|
|
16
15
|
name: 'WuiList',
|
|
17
16
|
})
|
|
18
17
|
defineProps<{
|
|
19
18
|
detailButtonHandle?: (data: Entities) => void
|
|
20
19
|
}>()
|
|
20
|
+
|
|
21
21
|
const Zpaging = ref<any>(null)
|
|
22
22
|
const config = ref<Config>({
|
|
23
23
|
buttons: [],
|
|
@@ -57,13 +57,13 @@ const config = ref<Config>({
|
|
|
57
57
|
displayConfig: [],
|
|
58
58
|
showType: 'table',
|
|
59
59
|
})
|
|
60
|
+
const { getEnums, enumColumn} = useEnums({ config })
|
|
60
61
|
const sourceId = ref('')
|
|
61
62
|
const datas = ref<Entities[]>([])
|
|
62
63
|
const pageTitle = ref('')
|
|
63
64
|
const searchData = ref('')
|
|
64
65
|
const tabSearchData = ref('')
|
|
65
66
|
const pageType = ref('')
|
|
66
|
-
const enumColumn = ref<Enums>({})
|
|
67
67
|
const mainCode = ref('')
|
|
68
68
|
const addEvent = generateHighResolutionID()// 全局事件名称
|
|
69
69
|
onLoad((option: any) => {
|
|
@@ -143,40 +143,6 @@ async function queryList(pageNo: number, pageSize: number) {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
// 获取枚举
|
|
147
|
-
async function getEnums() {
|
|
148
|
-
try {
|
|
149
|
-
const params: string[] = []
|
|
150
|
-
const criterias = config.value?.criterias ?? []
|
|
151
|
-
const columns = config.value.columns ?? []
|
|
152
|
-
const writes = config.value.rowActions?.reduce((acc: any, cur: any) => {
|
|
153
|
-
return [...acc, ...cur.writes]
|
|
154
|
-
}, []) || []
|
|
155
|
-
columns.forEach((item: any) => {
|
|
156
|
-
if (ControlTypeSupportor.getControlType(item) === 'select' || ControlTypeSupportor.getControlType(item) === 'multiselect') {
|
|
157
|
-
params.push(`mstrucIds=${item.mstrucId}`)
|
|
158
|
-
}
|
|
159
|
-
})
|
|
160
|
-
criterias.forEach((item: any) => {
|
|
161
|
-
if (ControlTypeSupportor.getControlType(item) === 'select' || ControlTypeSupportor.getControlType(item) === 'multiselect') {
|
|
162
|
-
params.push(`mstrucIds=${item.mstrucId}`)
|
|
163
|
-
}
|
|
164
|
-
})
|
|
165
|
-
writes.forEach((item: any) => {
|
|
166
|
-
if (ControlTypeSupportor.getControlType(item) === 'select' || ControlTypeSupportor.getControlType(item) === 'multiselect') {
|
|
167
|
-
params.push(`mstrucIds=${item.mstrucId}`)
|
|
168
|
-
}
|
|
169
|
-
})
|
|
170
|
-
if (!params.length)
|
|
171
|
-
return
|
|
172
|
-
const res = await enums(params.join('&'))
|
|
173
|
-
enumColumn.value = res.enumMap || {}
|
|
174
|
-
}
|
|
175
|
-
catch (error) {
|
|
176
|
-
console.log('error:', error)
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
146
|
function submitSearch(data: any) {
|
|
181
147
|
searchData.value = data
|
|
182
148
|
// for (const key in data) {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { defineOptions, ref } from 'vue'
|
|
3
|
+
import { onLoad } from '@dcloudio/uni-app'
|
|
4
|
+
import wuiDetailsPage from '../wui-details-page/wui-details-page.vue'
|
|
5
|
+
import cardBotomButtons from '../card-botom-buttons/card-botom-buttons.vue'
|
|
6
|
+
|
|
7
|
+
defineOptions({
|
|
8
|
+
name: 'NotifyHandle',
|
|
9
|
+
})
|
|
10
|
+
const item = ref<any>(null)
|
|
11
|
+
const sourceId = ref<any>(null)
|
|
12
|
+
const pagedata = ref<any>(null)
|
|
13
|
+
const rowActions = ref<any>(null)
|
|
14
|
+
const actions = ref<any>(null)
|
|
15
|
+
const ractions = ref<any>(null)
|
|
16
|
+
const primaryColumn = ref<any>(null)
|
|
17
|
+
const enumColumn = ref<any>(null)
|
|
18
|
+
onLoad(() => {
|
|
19
|
+
console.log('load')
|
|
20
|
+
uni.$on('notify-click', (data: any) => {
|
|
21
|
+
console.log(data, 'kkkk')
|
|
22
|
+
item.value = data.item
|
|
23
|
+
sourceId.value = data.sourceId
|
|
24
|
+
pagedata.value = data.data
|
|
25
|
+
rowActions.value = data.rowActions
|
|
26
|
+
actions.value = data.actions
|
|
27
|
+
ractions.value = data.ractions
|
|
28
|
+
primaryColumn.value = data.primaryColumn
|
|
29
|
+
enumColumn.value = data.enumColumn
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
onUnload(() => {
|
|
33
|
+
console.log('unload')
|
|
34
|
+
uni.$off('notify-click')
|
|
35
|
+
})
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<view>
|
|
40
|
+
<wuiDetailsPage>
|
|
41
|
+
<template #botombuttons>
|
|
42
|
+
<view class="flex justify-end bg-#ffff p-4">
|
|
43
|
+
<cardBotomButtons v-if="sourceId" :item="item" :source-id="sourceId" :code="pagedata.code" :data="pagedata" :row-actions="rowActions" :actions="actions" :ractions="ractions" :primary-column="primaryColumn" />
|
|
44
|
+
</view>
|
|
45
|
+
</template>
|
|
46
|
+
</wuiDetailsPage>
|
|
47
|
+
<view />
|
|
48
|
+
</view>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<style scoped>
|
|
52
|
+
|
|
53
|
+
</style>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, defineOptions, watch } from 'vue'
|
|
3
3
|
import { useRouter } from 'uni-mini-router'
|
|
4
|
-
import { listData, pageConfig, pageKey } from '../../api/page'
|
|
4
|
+
import { enums, listData, pageConfig, pageKey } from '../../api/page'
|
|
5
5
|
import { useSectionMenus } from '../../composables/useSectionMenus'
|
|
6
6
|
import { formatItemData } from '../../utils'
|
|
7
7
|
import ControlTypeSupportor from '../../utils/control-type-supportor'
|
|
8
|
-
import { useLanguageStore } from '../../store/language'
|
|
8
|
+
import { useLanguageStore } from '../../store/language'
|
|
9
|
+
import type { Config, Entities, Enums } from '../../type'
|
|
9
10
|
|
|
10
11
|
defineOptions({
|
|
11
12
|
name: 'WuiNotifyInfo',
|
|
@@ -20,22 +21,27 @@ const { rightSidebar01, rightSidebar02 } = useSectionMenus()
|
|
|
20
21
|
// default: return BellIcon
|
|
21
22
|
// }
|
|
22
23
|
// }
|
|
24
|
+
const dtmplConfig = ref<{ [key: string]: Config }>({})
|
|
25
|
+
const enumColumn = ref<{ [key: string]: Enums }>({})
|
|
26
|
+
interface Data {
|
|
27
|
+
type: 'system'
|
|
28
|
+
read: boolean
|
|
29
|
+
id: string
|
|
30
|
+
primaryColumn: string
|
|
31
|
+
primaryColumnLabel: string
|
|
32
|
+
secondColumn: string
|
|
33
|
+
secondColumnLabel: string
|
|
34
|
+
primaryColumnLabelConfig: any
|
|
35
|
+
primaryColumnConfig: any
|
|
36
|
+
secondColumnConfig: any
|
|
37
|
+
secondColumnLabelConfig: any
|
|
38
|
+
sourceid: string
|
|
39
|
+
data: Entities
|
|
40
|
+
}
|
|
23
41
|
interface Notification {
|
|
24
42
|
id: string
|
|
25
43
|
title: string
|
|
26
|
-
data:
|
|
27
|
-
type: 'system'
|
|
28
|
-
read: boolean
|
|
29
|
-
id: string
|
|
30
|
-
primaryColumn: string
|
|
31
|
-
primaryColumnLabel: string
|
|
32
|
-
secondColumn: string
|
|
33
|
-
secondColumnLabel: string
|
|
34
|
-
primaryColumnLabelConfig: any
|
|
35
|
-
primaryColumnConfig: any
|
|
36
|
-
secondColumnConfig: any
|
|
37
|
-
secondColumnLabelConfig: any
|
|
38
|
-
}[]
|
|
44
|
+
data: Data[]
|
|
39
45
|
}
|
|
40
46
|
const router = useRouter()
|
|
41
47
|
const notifications = ref<Notification[] | null>([])
|
|
@@ -57,17 +63,51 @@ const sources = computed(() => {
|
|
|
57
63
|
}
|
|
58
64
|
})
|
|
59
65
|
})
|
|
60
|
-
|
|
66
|
+
// 获取枚举
|
|
67
|
+
async function getEnums(sourceId: string, config: Config) {
|
|
68
|
+
try {
|
|
69
|
+
const params: string[] = []
|
|
70
|
+
const criterias = config?.criterias ?? []
|
|
71
|
+
const columns = config?.columns ?? []
|
|
72
|
+
const writes = config?.rowActions?.reduce((acc: any, cur: any) => {
|
|
73
|
+
return [...acc, ...cur.writes]
|
|
74
|
+
}, []) || []
|
|
75
|
+
columns.forEach((item: any) => {
|
|
76
|
+
if (ControlTypeSupportor.getControlType(item) === 'select' || ControlTypeSupportor.getControlType(item) === 'multiselect') {
|
|
77
|
+
params.push(`mstrucIds=${item.mstrucId}`)
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
criterias.forEach((item: any) => {
|
|
81
|
+
if (ControlTypeSupportor.getControlType(item) === 'select' || ControlTypeSupportor.getControlType(item) === 'multiselect') {
|
|
82
|
+
params.push(`mstrucIds=${item.mstrucId}`)
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
writes.forEach((item: any) => {
|
|
86
|
+
if (ControlTypeSupportor.getControlType(item) === 'select' || ControlTypeSupportor.getControlType(item) === 'multiselect') {
|
|
87
|
+
params.push(`mstrucIds=${item.mstrucId}`)
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
if (!params.length)
|
|
91
|
+
return
|
|
92
|
+
const res = await enums(params.join('&'))
|
|
93
|
+
enumColumn.value[sourceId] = res.enumMap || {}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.log('error:', error)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
61
99
|
// 获取数据
|
|
62
100
|
async function queryList(source: { id: string, title: string }): Promise<Notification | null> {
|
|
63
101
|
try {
|
|
64
102
|
const res = await pageConfig(source.id)
|
|
103
|
+
dtmplConfig.value[source.id] = res.ltmplConfig
|
|
104
|
+
getEnums(source.id, res.ltmplConfig)
|
|
65
105
|
const res1 = await pageKey(source.id, '', '')// 获取key
|
|
66
106
|
const data = await listData(res1.key, 1, 10)// 获取数据
|
|
67
107
|
return {
|
|
68
108
|
id: source.id,
|
|
69
109
|
title: source.title,
|
|
70
|
-
data: data.entities.map((item:
|
|
110
|
+
data: data.entities.map((item: Entities) => {
|
|
71
111
|
return {
|
|
72
112
|
type: 'system',
|
|
73
113
|
read: false,
|
|
@@ -81,6 +121,7 @@ async function queryList(source: { id: string, title: string }): Promise<Notific
|
|
|
81
121
|
secondColumnConfig: res.ltmplConfig.secondColumn,
|
|
82
122
|
secondColumnLabel: item.fieldMap[res.ltmplConfig.secondColumnLabel?.sourceId] || '',
|
|
83
123
|
secondColumnLabelConfig: res.ltmplConfig.secondColumnLabel,
|
|
124
|
+
data: item,
|
|
84
125
|
}
|
|
85
126
|
}),
|
|
86
127
|
}
|
|
@@ -127,8 +168,22 @@ function gotoPage(item: Notification) {
|
|
|
127
168
|
}
|
|
128
169
|
|
|
129
170
|
// 跳转详情页面
|
|
130
|
-
function gotoDetailPage(item:
|
|
131
|
-
router.push(`/pages/
|
|
171
|
+
function gotoDetailPage(item: Data) {
|
|
172
|
+
router.push(`/pages/notify-handle/index?sourceId=${item.sourceid}&id=${item.id}&title=`)
|
|
173
|
+
|
|
174
|
+
// 延迟发送,确保事件被发送
|
|
175
|
+
setTimeout(() => {
|
|
176
|
+
uni.$emit('notify-click', {
|
|
177
|
+
item: dtmplConfig.value[item.sourceid],
|
|
178
|
+
sourceId: item.sourceid,
|
|
179
|
+
data: item.data,
|
|
180
|
+
rowActions: dtmplConfig.value[item.sourceid]?.rowActions,
|
|
181
|
+
actions: dtmplConfig.value[item.sourceid]?.actions,
|
|
182
|
+
ractions: dtmplConfig.value[item.sourceid]?.ractions,
|
|
183
|
+
primaryColumn: dtmplConfig.value[item.sourceid]?.primaryColumn,
|
|
184
|
+
enumColumn: enumColumn.value[item.sourceid],
|
|
185
|
+
})
|
|
186
|
+
}, 100)
|
|
132
187
|
}
|
|
133
188
|
</script>
|
|
134
189
|
|
|
@@ -147,37 +202,39 @@ function gotoDetailPage(item: any) {
|
|
|
147
202
|
{{ languageStore.t('查看全部') }}
|
|
148
203
|
</view>
|
|
149
204
|
</view>
|
|
150
|
-
<button
|
|
151
|
-
v-for="item in notification.data"
|
|
152
|
-
:key="item.id"
|
|
205
|
+
<button
|
|
206
|
+
v-for="item in notification.data" :key="item.id"
|
|
153
207
|
class="w-full flex cursor-pointer items-start gap-3 rounded-xl bg-white p-4 text-left shadow-[0_4px_16px_rgba(99,102,241,0.1)] transition-all duration-200 .dark:bg-black hover:shadow-md"
|
|
154
|
-
:class="{ 'opacity-60': item.read }"
|
|
155
|
-
@click="handleNotificationClick(item)"
|
|
208
|
+
:class="{ 'opacity-60': item.read }" @click="handleNotificationClick(item)"
|
|
156
209
|
>
|
|
157
|
-
<view
|
|
210
|
+
<view
|
|
158
211
|
:class="getIconColor(item.type)"
|
|
159
|
-
class="h-10 w-10 flex flex-shrink-0 items-center justify-center rounded-full"
|
|
212
|
+
class="h-10 w-10 flex flex-shrink-0 items-center justify-center rounded-full"
|
|
160
213
|
>
|
|
161
214
|
<wd-icon name="notification" size="40rpx" color="#fff" />
|
|
162
215
|
</view>
|
|
163
216
|
|
|
164
217
|
<view class="min-w-0 flex-1">
|
|
165
218
|
<view class="flex justify-between gap-1">
|
|
166
|
-
<span class="text-sm text-slate-800 font-medium .dark:text-white">{{ formatItemData(item.primaryColumn,
|
|
167
|
-
|
|
219
|
+
<span class="text-sm text-slate-800 font-medium .dark:text-white">{{ formatItemData(item.primaryColumn,
|
|
220
|
+
ControlTypeSupportor.getControlType(item.primaryColumnConfig)) }}</span>
|
|
221
|
+
<span class="whitespace-nowrap text-xs text-slate-400 .dark:text-white">{{
|
|
222
|
+
formatItemData(item.primaryColumnLabel,
|
|
223
|
+
ControlTypeSupportor.getControlType(item.primaryColumnLabelConfig)) }}</span>
|
|
168
224
|
</view>
|
|
169
225
|
<p class="line-clamp-2 mt-1 text-sm text-slate-500 .dark:text-white">
|
|
170
226
|
<text class="mr-1">
|
|
171
|
-
{{ formatItemData(item.secondColumn, ControlTypeSupportor.getControlType(item.secondColumnConfig || {}))
|
|
227
|
+
{{ formatItemData(item.secondColumn, ControlTypeSupportor.getControlType(item.secondColumnConfig || {}))
|
|
228
|
+
}}
|
|
229
|
+
</text>
|
|
230
|
+
<text>
|
|
231
|
+
{{ formatItemData(item.secondColumnLabel,
|
|
232
|
+
ControlTypeSupportor.getControlType(item.secondColumnLabelConfig || {})) }}
|
|
172
233
|
</text>
|
|
173
|
-
<text> {{ formatItemData(item.secondColumnLabel, ControlTypeSupportor.getControlType(item.secondColumnLabelConfig || {})) }}</text>
|
|
174
234
|
</p>
|
|
175
235
|
</view>
|
|
176
236
|
|
|
177
|
-
<view
|
|
178
|
-
v-if="!item.read"
|
|
179
|
-
class="mt-2 h-2 w-2 flex-shrink-0 rounded-full bg-indigo-500"
|
|
180
|
-
/>
|
|
237
|
+
<view v-if="!item.read" class="mt-2 h-2 w-2 flex-shrink-0 rounded-full bg-indigo-500" />
|
|
181
238
|
</button>
|
|
182
239
|
</view>
|
|
183
240
|
</view>
|
|
@@ -41,7 +41,7 @@ defineExpose({ addToHistory })
|
|
|
41
41
|
<view v-if="modelValue.length > 0" class="mt-4">
|
|
42
42
|
<view class="mb-3 flex items-center justify-between">
|
|
43
43
|
<view class="flex items-center gap-2">
|
|
44
|
-
<ClockIcon class="h-4 w-4 text-slate-400" />
|
|
44
|
+
<!-- <ClockIcon class="h-4 w-4 text-slate-400" /> -->
|
|
45
45
|
<view class="text-sm text-slate-600 font-medium">
|
|
46
46
|
搜索历史
|
|
47
47
|
</view>
|
|
@@ -62,7 +62,8 @@ defineExpose({ addToHistory })
|
|
|
62
62
|
>
|
|
63
63
|
<!-- <MagnifyingGlassCircleIcon class="h-3.5 w-3.5" /> -->
|
|
64
64
|
<view>{{ keyword }}</view>
|
|
65
|
-
<wd-icon name="close-normal" size="16px" class="flex items-center" @click.stop="removeFromHistory(keyword)" />
|
|
65
|
+
<wd-icon name="close-normal" size="16px" class="flex items-center" @click.stop="removeFromHistory(keyword)" />
|
|
66
|
+
<!-- <wd-icon name="close-bold" size="22px" @click.stop="removeFromHistory(keyword)" ></wd-icon> -->
|
|
66
67
|
</view>
|
|
67
68
|
</view>
|
|
68
69
|
</view>
|
|
@@ -1,61 +1,101 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, defineOptions, onMounted, ref } from 'vue'
|
|
3
|
-
|
|
3
|
+
import { useRouter } from 'uni-mini-router'
|
|
4
|
+
import { useMenus } from '../../composables/useMenus'
|
|
5
|
+
import type { MenuItem } from '../../composables/useMenus'
|
|
6
|
+
import { useGlobalToast } from '../../composables/useGlobalToast'
|
|
7
|
+
import { menu } from '../../api/menu'
|
|
4
8
|
import SearchHistory from './components/SearchBar.vue'
|
|
5
9
|
|
|
6
10
|
defineOptions({
|
|
7
11
|
name: 'WuiSearchHistoryBabbar',
|
|
8
12
|
})
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
13
|
+
|
|
14
|
+
const { gotoPage, filtermenu, menuList } = useMenus()
|
|
15
|
+
const router = useRouter()
|
|
16
|
+
const toast = useGlobalToast()
|
|
17
|
+
|
|
18
|
+
function queryList() {
|
|
19
|
+
// 此处请求仅为演示,请替换为自己项目中的请求
|
|
20
|
+
menu().then((res: any) => {
|
|
21
|
+
if (!res?.blocks?.length) {
|
|
22
|
+
toast.warning('暂无权限,请重新登录或联系管理员')
|
|
23
|
+
setTimeout(() => {
|
|
24
|
+
router.replaceAll('/pages/login/index')
|
|
25
|
+
}, 1000)
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
menuList.value = res?.blocks
|
|
29
|
+
}
|
|
30
|
+
}).catch((res: any) => {
|
|
31
|
+
console.log(res)
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 提取树形结构中最深层的数据节点
|
|
37
|
+
* @param treeData - 树形结构数据
|
|
38
|
+
* @param childrenKey - 子节点的键名,默认为 'children'
|
|
39
|
+
* @returns 最深层节点组成的数组
|
|
40
|
+
*/
|
|
41
|
+
function extractDeepestNodes<T>(
|
|
42
|
+
treeData: T[],
|
|
43
|
+
childrenKey: string = 'children',
|
|
44
|
+
): T[] {
|
|
45
|
+
const result: T[] = []
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 递归遍历树节点
|
|
49
|
+
*/
|
|
50
|
+
function traverse(nodes: T[], depth: number = 0) {
|
|
51
|
+
for (const node of nodes) {
|
|
52
|
+
// 检查当前节点是否有子节点
|
|
53
|
+
const children = (node as any)[childrenKey]
|
|
54
|
+
|
|
55
|
+
if (children && Array.isArray(children) && children.length > 0) {
|
|
56
|
+
// 如果有子节点,继续深入
|
|
57
|
+
traverse(children, depth + 1)
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// 如果没有子节点,这是最深层的节点,添加到结果中
|
|
61
|
+
result.push(node)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
traverse(treeData)
|
|
67
|
+
return result
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const a = computed(() => {
|
|
71
|
+
return extractDeepestNodes(filtermenu.value, 'items')
|
|
72
|
+
})
|
|
33
73
|
|
|
34
74
|
const searchQuery = ref('')
|
|
35
75
|
const searchHistory = ref<string[]>([])
|
|
36
76
|
const inputRef = ref<HTMLInputElement | null>(null)
|
|
37
77
|
|
|
38
|
-
const filteredMenus = computed(() => {
|
|
78
|
+
const filteredMenus = computed<MenuItem[]>(() => {
|
|
39
79
|
if (!searchQuery.value.trim()) {
|
|
40
|
-
return
|
|
80
|
+
return a.value
|
|
41
81
|
}
|
|
42
82
|
const query = searchQuery.value.toLowerCase().trim()
|
|
43
|
-
return
|
|
44
|
-
menu.
|
|
45
|
-
|| (menu.
|
|
83
|
+
return a.value.filter(menu =>
|
|
84
|
+
menu.title.toLowerCase().includes(query)
|
|
85
|
+
|| (menu.tip && menu.tip.toLowerCase().includes(query)),
|
|
46
86
|
)
|
|
47
87
|
})
|
|
48
88
|
|
|
49
|
-
function highlightedLabel(menu:
|
|
50
|
-
if (!searchQuery.value.trim())
|
|
51
|
-
return menu.
|
|
89
|
+
function highlightedLabel(menu: MenuItem) {
|
|
90
|
+
if (!searchQuery.value.trim())
|
|
91
|
+
return menu.title
|
|
52
92
|
const query = searchQuery.value.toLowerCase().trim()
|
|
53
|
-
const index = menu.
|
|
54
|
-
if (index === -1)
|
|
55
|
-
return menu.
|
|
56
|
-
const before = menu.
|
|
57
|
-
const match = menu.
|
|
58
|
-
const after = menu.
|
|
93
|
+
const index = menu.title.toLowerCase().indexOf(query)
|
|
94
|
+
if (index === -1)
|
|
95
|
+
return menu.title
|
|
96
|
+
const before = menu.title.substring(0, index)
|
|
97
|
+
const match = menu.title.substring(index, index + query.length)
|
|
98
|
+
const after = menu.title.substring(index + query.length)
|
|
59
99
|
return `${before}<mark class="bg-yellow-200 text-yellow-800 rounded px-0.5">${match}</mark>${after}`
|
|
60
100
|
}
|
|
61
101
|
|
|
@@ -65,18 +105,18 @@ function highlightedLabel(menu: any) {
|
|
|
65
105
|
|
|
66
106
|
function handleClear() {
|
|
67
107
|
searchQuery.value = ''
|
|
68
|
-
inputRef
|
|
108
|
+
inputRef?.value?.focus()
|
|
69
109
|
}
|
|
70
110
|
|
|
71
|
-
function handleMenuClick(menu:
|
|
111
|
+
function handleMenuClick(menu: MenuItem) {
|
|
72
112
|
if (searchQuery.value.trim()) {
|
|
73
113
|
addToHistory(searchQuery.value.trim())
|
|
74
114
|
}
|
|
75
|
-
|
|
115
|
+
gotoPage(menu)
|
|
76
116
|
}
|
|
77
117
|
|
|
78
118
|
function addToHistory(keyword: string) {
|
|
79
|
-
if (!keyword.trim())
|
|
119
|
+
if (!keyword.trim())
|
|
80
120
|
return
|
|
81
121
|
const current = [...searchHistory.value]
|
|
82
122
|
const index = current.indexOf(keyword)
|
|
@@ -96,16 +136,16 @@ function handleSelectHistory(keyword: string) {
|
|
|
96
136
|
}
|
|
97
137
|
|
|
98
138
|
onMounted(() => {
|
|
139
|
+
queryList()
|
|
99
140
|
const saved = localStorage.getItem('searchHistory')
|
|
100
141
|
if (saved) {
|
|
101
142
|
try {
|
|
102
143
|
searchHistory.value = JSON.parse(saved)
|
|
103
|
-
}
|
|
144
|
+
}
|
|
104
145
|
catch {
|
|
105
146
|
searchHistory.value = []
|
|
106
147
|
}
|
|
107
148
|
}
|
|
108
|
-
inputRef.value?.focus()
|
|
109
149
|
})
|
|
110
150
|
</script>
|
|
111
151
|
|
|
@@ -113,7 +153,7 @@ onMounted(() => {
|
|
|
113
153
|
<view class="min-h-screen bg-slate-50">
|
|
114
154
|
<view class="sticky top-0 z-10 bg-white shadow-sm">
|
|
115
155
|
<view class="flex items-center gap-3 px-4 py-3">
|
|
116
|
-
<view class="h-11 flex flex-1 items-center rounded-xl bg-slate-100 px-4">
|
|
156
|
+
<view class="h-11 flex flex-1 items-center rounded-xl bg-slate-100 px-4">
|
|
117
157
|
<input
|
|
118
158
|
ref="inputRef"
|
|
119
159
|
v-model="searchQuery"
|
|
@@ -126,7 +166,7 @@ onMounted(() => {
|
|
|
126
166
|
class="cursor-pointer rounded-full p-1 transition-colors hover:bg-slate-200"
|
|
127
167
|
@click="handleClear"
|
|
128
168
|
>
|
|
129
|
-
<
|
|
169
|
+
<wd-icon name="close-circle-filled" size="22px" color="#ccc" />
|
|
130
170
|
</view>
|
|
131
171
|
</view>
|
|
132
172
|
</view>
|
|
@@ -139,24 +179,24 @@ onMounted(() => {
|
|
|
139
179
|
/>
|
|
140
180
|
|
|
141
181
|
<view v-if="filteredMenus.length === 0" class="mt-6">
|
|
142
|
-
<p class="text-center text-sm text-slate-400">
|
|
143
|
-
未找到相关菜单
|
|
182
|
+
<p class="text-center text-sm text-slate-400">
|
|
183
|
+
未找到相关菜单
|
|
144
184
|
</p>
|
|
145
185
|
</view>
|
|
146
186
|
|
|
147
187
|
<view v-else class="mt-4">
|
|
148
|
-
<p class="mb-3 text-xs text-slate-400">
|
|
149
|
-
{{ searchQuery.trim() ? `找到 ${filteredMenus.length} 个相关菜单` : '全部菜单' }}
|
|
188
|
+
<p class="mb-3 text-xs text-slate-400">
|
|
189
|
+
{{ searchQuery.trim() ? `找到 ${filteredMenus.length} 个相关菜单` : '全部菜单' }}
|
|
150
190
|
</p>
|
|
151
191
|
<view class="space-y-2">
|
|
152
192
|
<view
|
|
153
193
|
v-for="menu in filteredMenus"
|
|
154
194
|
:key="menu.id"
|
|
155
|
-
class="
|
|
195
|
+
class="flex cursor-pointer items-center gap-3 rounded-xl bg-white p-3 shadow-sm transition-all duration-200 active:scale-[0.98] hover:shadow-md"
|
|
156
196
|
@click="handleMenuClick(menu)"
|
|
157
197
|
>
|
|
158
198
|
<view
|
|
159
|
-
:
|
|
199
|
+
:style="{ background: menu.color }"
|
|
160
200
|
class="h-10 w-10 flex flex-shrink-0 items-center justify-center rounded-lg"
|
|
161
201
|
>
|
|
162
202
|
<!-- <component
|
|
@@ -164,14 +204,15 @@ onMounted(() => {
|
|
|
164
204
|
:is="iconMap[menu.icon]"
|
|
165
205
|
class="w-5 h-5 text-white"
|
|
166
206
|
/> -->
|
|
207
|
+
<wd-icon name="picture" size="22px" color="#FFF" />
|
|
167
208
|
</view>
|
|
168
209
|
<view class="flex-1 text-left">
|
|
169
210
|
<p
|
|
170
211
|
class="text-base text-slate-800 font-medium"
|
|
171
212
|
v-html="highlightedLabel(menu)"
|
|
172
213
|
/>
|
|
173
|
-
<p v-if="menu.
|
|
174
|
-
{{ menu.
|
|
214
|
+
<p v-if="menu.tip" class="mt-0.5 text-xs text-slate-400">
|
|
215
|
+
{{ menu.tip }}
|
|
175
216
|
</p>
|
|
176
217
|
</view>
|
|
177
218
|
</view>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { enums, listData, pageConfig, pageKey } from '../api/page'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import ControlTypeSupportor from '../utils/control-type-supportor'
|
|
4
|
+
import type { Enums } from '../type'
|
|
5
|
+
export function useEnums({ config }: { config: any }) {
|
|
6
|
+
const enumColumn = ref<Enums>({})
|
|
7
|
+
// 获取枚举
|
|
8
|
+
async function getEnums() {
|
|
9
|
+
try {
|
|
10
|
+
const params: string[] = []
|
|
11
|
+
const criterias = config.value?.criterias ?? []
|
|
12
|
+
const columns = config.value.columns ?? []
|
|
13
|
+
const writes = config.value.rowActions?.reduce((acc: any, cur: any) => {
|
|
14
|
+
return [...acc, ...cur.writes]
|
|
15
|
+
}, []) || []
|
|
16
|
+
columns.forEach((item: any) => {
|
|
17
|
+
if (ControlTypeSupportor.getControlType(item) === 'select' || ControlTypeSupportor.getControlType(item) === 'multiselect') {
|
|
18
|
+
params.push(`mstrucIds=${item.mstrucId}`)
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
criterias.forEach((item: any) => {
|
|
22
|
+
if (ControlTypeSupportor.getControlType(item) === 'select' || ControlTypeSupportor.getControlType(item) === 'multiselect') {
|
|
23
|
+
params.push(`mstrucIds=${item.mstrucId}`)
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
writes.forEach((item: any) => {
|
|
27
|
+
if (ControlTypeSupportor.getControlType(item) === 'select' || ControlTypeSupportor.getControlType(item) === 'multiselect') {
|
|
28
|
+
params.push(`mstrucIds=${item.mstrucId}`)
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
if (!params.length)
|
|
32
|
+
return
|
|
33
|
+
const res = await enums(params.join('&'))
|
|
34
|
+
enumColumn.value = res.enumMap || {}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.log('error:', error)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return { getEnums, enumColumn }
|
|
42
|
+
}
|
package/composables/useMenus.ts
CHANGED
|
@@ -14,10 +14,12 @@ interface Props {
|
|
|
14
14
|
load: () => void
|
|
15
15
|
menuTopType: string
|
|
16
16
|
}
|
|
17
|
-
interface MenuItem {
|
|
17
|
+
export interface MenuItem {
|
|
18
18
|
id: string
|
|
19
19
|
title: string
|
|
20
20
|
icon: string
|
|
21
|
+
color: string
|
|
22
|
+
tip: string
|
|
21
23
|
pageType: string
|
|
22
24
|
children?: MenuItem[]
|
|
23
25
|
}
|
|
@@ -31,7 +33,7 @@ export function useMenus(props?: Props, pagingRef?: Ref<any>) {
|
|
|
31
33
|
const menuList = ref<MenuItem[]>([])
|
|
32
34
|
const title = ref('')
|
|
33
35
|
const navTitle = ref('')
|
|
34
|
-
const filtermenu = computed(() => {
|
|
36
|
+
const filtermenu = computed<MenuItem[]>(() => {
|
|
35
37
|
let arr = []
|
|
36
38
|
if (currentThemeColor.value.primary) {
|
|
37
39
|
arr = filterHiddenTree(menuList.value, 'items', true)
|
|
@@ -170,7 +172,7 @@ export function useMenus(props?: Props, pagingRef?: Ref<any>) {
|
|
|
170
172
|
try {
|
|
171
173
|
const res = await fastmenu()
|
|
172
174
|
if (res.fastMenu) {
|
|
173
|
-
sectionmenu.value = res.fastMenu.QuickQueryBar || []
|
|
175
|
+
sectionmenu.value = res.fastMenu.QuickQueryBar || []
|
|
174
176
|
}
|
|
175
177
|
else {
|
|
176
178
|
sectionmenu.value = []
|
package/index.ts
CHANGED
|
@@ -26,7 +26,7 @@ import WuiUser from './components/wui-user/wui-user.vue'
|
|
|
26
26
|
import WuiAutoUpdateComponent from './components/wui-auto-update-component/wui-auto-update-component.vue'
|
|
27
27
|
import iData from './utils/idata-scan'// PAD扫描
|
|
28
28
|
import wuiSearchHistoryBabbar from './components/wui-search-history-babbar/wui-search-history-babbar.vue'
|
|
29
|
-
|
|
29
|
+
import enumeSelectControl from './components/enume-select-control/enume-select-control.vue'
|
|
30
30
|
// 组件列表
|
|
31
31
|
const coms: Array<{ name: string }> = [
|
|
32
32
|
WuiSystemSettings,
|
|
@@ -73,6 +73,7 @@ export {
|
|
|
73
73
|
iData, // PAD扫描
|
|
74
74
|
// nfc, // nfc读取
|
|
75
75
|
useLanguageStore, // 语言
|
|
76
|
+
enumeSelectControl,// 枚举选择
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
export default install
|
package/package.json
CHANGED