wui-components-v2 1.1.34 → 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/api/sys.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import req from './core/index'
2
2
  // 获取语言包
3
- export function language(language:string): Promise<any> {
3
+ export function language(language: string): Promise<any> {
4
4
  return req({
5
5
  url: `/v3/multilingual?language=${language}`,
6
6
  })
7
- }
7
+ }
@@ -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
- <wd-button v-if="morebutns.length > 0" size="small" type="info" @click="() => { showMoreButn = true }">
229
- 更多
230
- </wd-button>
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 { enums, listData, pageConfig, pageKey } from '../../api/page'
4
+ import {listData, pageConfig, pageKey } from '../../api/page'
5
5
  import foldCard from '../fold-card/fold-card.vue'
6
- import type { Config, Entities, Enums } from '../../type'
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 ControlTypeSupportor from '../../utils/control-type-supportor'
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) {
@@ -2,7 +2,8 @@
2
2
  import { computed, defineOptions } from 'vue'
3
3
  import { RainbowColorGenerator } from '../../../utils'
4
4
  import { useSectionMenus } from '../../../composables/useSectionMenus'
5
- import {useLanguageStore} from '../../../store/language'
5
+ import { useLanguageStore } from '../../../store/language'
6
+
6
7
  defineOptions({
7
8
  name: 'QuickPanel',
8
9
  })
@@ -40,7 +41,7 @@ const cstatistics = computed(() => {
40
41
  {{ item.count }}
41
42
  </view>
42
43
  <view class="text-size-3 color-gray">
43
- {{ languageStore.t(item.title)}}
44
+ {{ languageStore.t(item.title) }}
44
45
  </view>
45
46
  </view>
46
47
  </view>
@@ -2,7 +2,8 @@
2
2
  import { computed, defineOptions } from 'vue'
3
3
  import { useMenus } from '../../../composables/useMenus'
4
4
  import { RainbowColorGenerator } from '../../../utils/index'
5
- import {useLanguageStore} from '../../../store/language'
5
+ import { useLanguageStore } from '../../../store/language'
6
+
6
7
  defineOptions({
7
8
  name: 'SectionMenus',
8
9
  })
@@ -50,7 +51,7 @@ const sectionmenuColor = computed(() => {
50
51
  <text class="i-carbon:grid text-lg .dark:text-white .light:text-#FFF" />
51
52
  </view>
52
53
  <text class="recent-label .dark:text-white .light:text-#4b5563">
53
- {{languageStore.t( i.title )}}
54
+ {{ languageStore.t(i.title) }}
54
55
  </text>
55
56
  </view>
56
57
  </view>
@@ -5,12 +5,13 @@ import DemoCard from '../demo-card/demo-card.vue'
5
5
  import { useMenus } from '../../composables/useMenus'
6
6
  import type { Icon } from '../../composables/useMenus'
7
7
  import wuiNotifyInfo from '../wui-notify-info/wui-notify-info.vue'
8
+ import { useLanguageStore } from '../../store/language'
8
9
  import sectionMenus from './components/section-menus.vue'
9
10
  import navbar from './components/navbar.vue'
10
11
  import quickPanel from './components/quick-panel.vue'
11
12
  import bannerCarousel from './components/banner-carousel.vue'
12
- import searchBar from './components/search-bar.vue'
13
- import {useLanguageStore} from '../../store/language'
13
+ import searchBar from './components/search-bar.vue'
14
+
14
15
  defineOptions({
15
16
  name: 'WuiMenus1',
16
17
  })
@@ -72,12 +73,12 @@ const {
72
73
  <text class="i-carbon:apps text-sm" />
73
74
  </view> -->
74
75
  <text class="section-title .dark:text-white .light:color-#1f2937">
75
- {{languageStore.t('全部功能')}}
76
+ {{ languageStore.t('全部功能') }}
76
77
  </text>
77
78
  </view>
78
79
  <view class="section-tag">
79
80
  <text class="tag-text">
80
- {{ filtermenu.length }} {{languageStore.t('个分类')}}
81
+ {{ filtermenu.length }} {{ languageStore.t('个分类') }}
81
82
  </text>
82
83
  </view>
83
84
  </view>
@@ -106,7 +107,7 @@ const {
106
107
  <template #text>
107
108
  <view class="menu-text-wrapper">
108
109
  <view class="menu-title .dark:text-white .light:color-#1f2937">
109
- {{languageStore.t( subItem.title) }}
110
+ {{ languageStore.t(subItem.title) }}
110
111
  </view>
111
112
  <!-- <view class="menu-badge" v-if="subIndex === 0">
112
113
  <text class="badge-dot" />
@@ -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,13 @@
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'
10
+
9
11
  defineOptions({
10
12
  name: 'WuiNotifyInfo',
11
13
  })
@@ -19,22 +21,27 @@ const { rightSidebar01, rightSidebar02 } = useSectionMenus()
19
21
  // default: return BellIcon
20
22
  // }
21
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
+ }
22
41
  interface Notification {
23
42
  id: string
24
43
  title: string
25
- data: {
26
- type: 'system'
27
- read: boolean
28
- id: string
29
- primaryColumn: string
30
- primaryColumnLabel: string
31
- secondColumn: string
32
- secondColumnLabel: string
33
- primaryColumnLabelConfig: any
34
- primaryColumnConfig: any
35
- secondColumnConfig: any
36
- secondColumnLabelConfig: any
37
- }[]
44
+ data: Data[]
38
45
  }
39
46
  const router = useRouter()
40
47
  const notifications = ref<Notification[] | null>([])
@@ -56,17 +63,51 @@ const sources = computed(() => {
56
63
  }
57
64
  })
58
65
  })
59
-
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
+ }
60
99
  // 获取数据
61
100
  async function queryList(source: { id: string, title: string }): Promise<Notification | null> {
62
101
  try {
63
102
  const res = await pageConfig(source.id)
103
+ dtmplConfig.value[source.id] = res.ltmplConfig
104
+ getEnums(source.id, res.ltmplConfig)
64
105
  const res1 = await pageKey(source.id, '', '')// 获取key
65
106
  const data = await listData(res1.key, 1, 10)// 获取数据
66
107
  return {
67
108
  id: source.id,
68
109
  title: source.title,
69
- data: data.entities.map((item: any) => {
110
+ data: data.entities.map((item: Entities) => {
70
111
  return {
71
112
  type: 'system',
72
113
  read: false,
@@ -80,6 +121,7 @@ async function queryList(source: { id: string, title: string }): Promise<Notific
80
121
  secondColumnConfig: res.ltmplConfig.secondColumn,
81
122
  secondColumnLabel: item.fieldMap[res.ltmplConfig.secondColumnLabel?.sourceId] || '',
82
123
  secondColumnLabelConfig: res.ltmplConfig.secondColumnLabel,
124
+ data: item,
83
125
  }
84
126
  }),
85
127
  }
@@ -126,8 +168,22 @@ function gotoPage(item: Notification) {
126
168
  }
127
169
 
128
170
  // 跳转详情页面
129
- function gotoDetailPage(item: any) {
130
- router.push(`/pages/details-page/index?sourceId=${item.sourceid}&id=${item.id}&title=`)
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)
131
187
  }
132
188
  </script>
133
189
 
@@ -141,42 +197,44 @@ function gotoDetailPage(item: any) {
141
197
 
142
198
  <view v-for="notification in notifications" :key="notification.id" class="space-y-3">
143
199
  <view class="mt-2 flex justify-between text-size-3 color-gray .dark:text-white">
144
- <view>{{languageStore.t(notification.title) }}</view>
200
+ <view>{{ languageStore.t(notification.title) }}</view>
145
201
  <view @click="() => { gotoPage(notification) }">
146
- {{ languageStore.t('查看全部') }}
202
+ {{ languageStore.t('查看全部') }}
147
203
  </view>
148
204
  </view>
149
- <button
150
- v-for="item in notification.data"
151
- :key="item.id"
205
+ <button
206
+ v-for="item in notification.data" :key="item.id"
152
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"
153
- :class="{ 'opacity-60': item.read }"
154
- @click="handleNotificationClick(item)"
208
+ :class="{ 'opacity-60': item.read }" @click="handleNotificationClick(item)"
155
209
  >
156
- <view
210
+ <view
157
211
  :class="getIconColor(item.type)"
158
- 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"
159
213
  >
160
214
  <wd-icon name="notification" size="40rpx" color="#fff" />
161
215
  </view>
162
216
 
163
217
  <view class="min-w-0 flex-1">
164
218
  <view class="flex justify-between gap-1">
165
- <span class="text-sm text-slate-800 font-medium .dark:text-white">{{ formatItemData(item.primaryColumn, ControlTypeSupportor.getControlType(item.primaryColumnConfig)) }}</span>
166
- <span class="text-xs text-slate-400 .dark:text-white whitespace-nowrap">{{ formatItemData(item.primaryColumnLabel, ControlTypeSupportor.getControlType(item.primaryColumnLabelConfig)) }}</span>
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>
167
224
  </view>
168
225
  <p class="line-clamp-2 mt-1 text-sm text-slate-500 .dark:text-white">
169
226
  <text class="mr-1">
170
- {{ 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 || {})) }}
171
233
  </text>
172
- <text> {{ formatItemData(item.secondColumnLabel, ControlTypeSupportor.getControlType(item.secondColumnLabelConfig||{})) }}</text>
173
234
  </p>
174
235
  </view>
175
236
 
176
- <view
177
- v-if="!item.read"
178
- class="mt-2 h-2 w-2 flex-shrink-0 rounded-full bg-indigo-500"
179
- />
237
+ <view v-if="!item.read" class="mt-2 h-2 w-2 flex-shrink-0 rounded-full bg-indigo-500" />
180
238
  </button>
181
239
  </view>
182
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
- // import { useRouter } from 'vue-router'
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
- // const router = useRouter()
10
- const allMenus: any = [
11
- { id: 1, label: '打卡', icon: 'clock', color: 'bg-blue-500', description: '上下班打卡签到' },
12
- { id: 2, label: '报销', icon: 'document-text', color: 'bg-green-500', description: '提交报销单据' },
13
- { id: 3, label: '审批', icon: 'check-circle', color: 'bg-purple-500', description: '审批流程管理' },
14
- { id: 4, label: '日程', icon: 'calendar', color: 'bg-orange-500', description: '查看和安排日程' },
15
- { id: 5, label: '通讯录', icon: 'user-group', color: 'bg-indigo-500', description: '企业通讯录' },
16
- { id: 6, label: '更多', icon: 'ellipsis-horizontal', color: 'bg-slate-500', description: '更多应用' },
17
- { id: 7, label: '请假', icon: 'arrow-right-circle', color: 'bg-rose-500', description: '申请请假' },
18
- { id: 8, label: '考勤', icon: 'clipboard-check', color: 'bg-cyan-500', description: '考勤记录查询' },
19
- { id: 9, label: '会议', icon: 'video-camera', color: 'bg-violet-500', description: '会议室预约' },
20
- { id: 10, label: '文档', icon: 'folder', color: 'bg-amber-500', description: '文档管理中心' },
21
- { id: 11, label: '项目管理', icon: 'chart-bar', color: 'bg-emerald-500', description: '项目进度管理' },
22
- { id: 12, label: 'CRM', icon: 'user-circle', color: 'bg-pink-500', description: '客户关系管理' },
23
- { id: 13, label: '人力资源', icon: 'identification', color: 'bg-teal-500', description: 'HR管理' },
24
- { id: 14, label: '财务管理', icon: 'banknotes', color: 'bg-lime-500', description: '财务相关操作' },
25
- { id: 15, label: '资产管理', icon: 'cube', color: 'bg-fuchsia-500', description: '企业资产管理' },
26
- { id: 16, label: '公告', icon: 'megaphone', color: 'bg-red-500', description: '公司公告通知' },
27
- { id: 17, label: '任务', icon: 'check-badge', color: 'bg-sky-500', description: '任务分配与跟踪' },
28
- { id: 18, label: '笔记', icon: 'pencil-square', color: 'bg-yellow-500', description: '个人笔记' },
29
- { id: 19, label: '邮件', icon: 'envelope', color: 'bg-blue-600', description: '企业邮件' },
30
- { id: 20, label: '云盘', icon: 'cloud', color: 'bg-indigo-600', description: '云端文件存储' },
31
- { id: 21, label: '设置', icon: 'cog-6-tooth', color: 'bg-gray-500', description: '个人设置' },
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 allMenus
80
+ return a.value
41
81
  }
42
82
  const query = searchQuery.value.toLowerCase().trim()
43
- return allMenus.filter(menu =>
44
- menu.label.toLowerCase().includes(query)
45
- || (menu.description && menu.description.toLowerCase().includes(query)),
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: any) {
50
- if (!searchQuery.value.trim())
51
- return menu.label
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.label.toLowerCase().indexOf(query)
54
- if (index === -1)
55
- return menu.label
56
- const before = menu.label.substring(0, index)
57
- const match = menu.label.substring(index, index + query.length)
58
- const after = menu.label.substring(index + query.length)
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.value?.focus()
108
+ inputRef?.value?.focus()
69
109
  }
70
110
 
71
- function handleMenuClick(menu: any) {
111
+ function handleMenuClick(menu: MenuItem) {
72
112
  if (searchQuery.value.trim()) {
73
113
  addToHistory(searchQuery.value.trim())
74
114
  }
75
- console.log('Menu clicked:', menu.label)
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
- <XMarkIcon class="h-4 w-4 text-slate-400" />
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="w-full 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"
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
- :class="menu.color"
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.description" class="mt-0.5 text-xs text-slate-400">
174
- {{ menu.description }}
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>
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import { computed, defineOptions } from 'vue'
3
3
  import { useManualTheme } from '../../composables/useManualTheme'
4
- import {useLanguageStore} from '../../store/language'
4
+ import { useLanguageStore } from '../../store/language'
5
5
  import type { LocaleOption, ThemeColorOption } from '../../composables/useManualTheme'
6
6
  import demoBlock from '../demo-block/demo-block.vue'
7
7
 
@@ -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
+ }
@@ -8,7 +8,7 @@ import zhCN from 'wot-design-uni/locale/lang/zh-CN'
8
8
  import arSA from 'wot-design-uni/locale/lang/ar-SA'
9
9
  import { useManualThemeStore } from '../store/manualThemeStore'
10
10
 
11
- import {useLanguageStore} from '../store/language'
11
+ import { useLanguageStore } from '../store/language'
12
12
  /**
13
13
  * 简化版系统语言切换组合式API
14
14
  *
@@ -16,15 +16,14 @@ import {useLanguageStore} from '../store/language'
16
16
  export function useLocale() {
17
17
  const store = useManualThemeStore()
18
18
  const languageStore = useLanguageStore()
19
-
20
- //获取语言包
21
- async function getLanguagePack(lang: string) {
19
+
20
+ // 获取语言包
21
+ async function getLanguagePack(lang: string) {
22
22
  await languageStore.loadLanguage(lang)
23
23
  }
24
24
 
25
25
  // 系统语言切换
26
- function changeSystemLocale() {
27
-
26
+ function changeSystemLocale() {
28
27
  switch (store.Locale.value) {
29
28
  case 'en-US':
30
29
  Locale.use('en-US', enUS)
@@ -32,7 +31,7 @@ export function useLocale() {
32
31
  break
33
32
  case 'ar-SA':
34
33
  Locale.use('ar-SA', arSA)
35
-
34
+
36
35
  break
37
36
  default:
38
37
  Locale.use('zh-CN', zhCN)
@@ -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
@@ -11,7 +11,7 @@ import { useManualTheme } from './composables/useManualTheme'
11
11
  import { useGlobalLoading } from './composables/useGlobalLoading'
12
12
  import { useGlobalMessage } from './composables/useGlobalMessage'
13
13
  import { useGlobalToast } from './composables/useGlobalToast'
14
- import {useLanguageStore} from './store/language'
14
+ import { useLanguageStore } from './store/language'
15
15
  import { useUser } from './composables/useUser'
16
16
  import { req } from './api/index'
17
17
  import { useTabbar } from './composables/useTabbar'
@@ -26,8 +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
-
30
-
29
+ import enumeSelectControl from './components/enume-select-control/enume-select-control.vue'
31
30
  // 组件列表
32
31
  const coms: Array<{ name: string }> = [
33
32
  WuiSystemSettings,
@@ -73,7 +72,8 @@ export {
73
72
  persistPlugin,
74
73
  iData, // PAD扫描
75
74
  // nfc, // nfc读取
76
- useLanguageStore,// 语言
75
+ useLanguageStore, // 语言
76
+ enumeSelectControl,// 枚举选择
77
77
  }
78
78
 
79
79
  export default install
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wui-components-v2",
3
- "version": "1.1.34",
3
+ "version": "1.1.36",
4
4
  "description": "wui 组件库",
5
5
  "author": "wgxshh",
6
6
  "license": "MIT",
package/store/language.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/core-components/store/language.ts
2
2
  import { defineStore } from 'pinia'
3
- import { ref, computed } from 'vue'
4
- import {language} from '../api/sys'
3
+ import { computed, ref } from 'vue'
4
+ import { language } from '../api/sys'
5
5
  // 定义语言包类型
6
6
  type LanguagePackage = Record<string, string>
7
7
 
@@ -11,12 +11,12 @@ export const useLanguageStore = defineStore('language', () => {
11
11
  const languagePackages = ref<Record<string, LanguagePackage>>({})
12
12
  const loading = ref<boolean>(false)
13
13
  const loadedLanguages = ref<string[]>([])
14
-
14
+
15
15
  // 计算属性:当前语言包
16
16
  const currentLangPack = computed<LanguagePackage>(() => {
17
17
  return languagePackages.value[currentLanguage.value] || {}
18
18
  })
19
-
19
+
20
20
  // 计算属性:是否已加载当前语言
21
21
  const isCurrentLanguageLoaded = computed<boolean>(() => {
22
22
  return loadedLanguages.value.includes(currentLanguage.value)
@@ -28,15 +28,16 @@ export const useLanguageStore = defineStore('language', () => {
28
28
  const loadLanguageFromNetwork = async (lang: string): Promise<LanguagePackage> => {
29
29
  try {
30
30
  // 调用API获取语言包,可根据实际API调整URL
31
- const response= await language(lang)
32
-
33
- if (response.status!=="success") {
31
+ const response = await language(lang)
32
+
33
+ if (response.status !== 'success') {
34
34
  throw new Error(`Failed to fetch language package: ${response.status} ${response.statusText}`)
35
35
  }
36
-
36
+
37
37
  const data: LanguagePackage = response.value
38
38
  return data
39
- } catch (error) {
39
+ }
40
+ catch (error) {
40
41
  console.error(`Error loading language package for ${lang}:`, error)
41
42
  // 返回空对象,避免程序崩溃
42
43
  return {}
@@ -57,15 +58,16 @@ export const useLanguageStore = defineStore('language', () => {
57
58
  loading.value = true
58
59
  try {
59
60
  const langPack = await loadLanguageFromNetwork(lang)
60
-
61
+
61
62
  // 更新语言包数据
62
63
  languagePackages.value[lang] = langPack
63
64
 
64
65
  // loadedLanguages.value.push(lang)
65
-
66
+
66
67
  // 设置当前语言
67
68
  currentLanguage.value = lang
68
- } finally {
69
+ }
70
+ finally {
69
71
  loading.value = false
70
72
  }
71
73
  }
@@ -84,7 +86,7 @@ export const useLanguageStore = defineStore('language', () => {
84
86
  const preloadLanguages = async (languages: string[]): Promise<void> => {
85
87
  const promises = languages.map(lang => loadLanguageFromNetwork(lang))
86
88
  const results = await Promise.allSettled(promises)
87
-
89
+
88
90
  results.forEach((result, index) => {
89
91
  if (result.status === 'fulfilled') {
90
92
  const lang = languages[index]
@@ -92,7 +94,8 @@ export const useLanguageStore = defineStore('language', () => {
92
94
  if (!loadedLanguages.value.includes(lang)) {
93
95
  loadedLanguages.value.push(lang)
94
96
  }
95
- } else {
97
+ }
98
+ else {
96
99
  console.error(`Failed to preload language ${languages[index]}:`, result.reason)
97
100
  }
98
101
  })
@@ -138,7 +141,7 @@ export const useLanguageStore = defineStore('language', () => {
138
141
  loadedLanguages,
139
142
  currentLangPack,
140
143
  isCurrentLanguageLoaded,
141
-
144
+
142
145
  // 方法
143
146
  loadLanguage,
144
147
  switchLanguage,
@@ -146,6 +149,6 @@ export const useLanguageStore = defineStore('language', () => {
146
149
  preloadLanguages,
147
150
  addLocalLanguage,
148
151
  getLoadedLanguages,
149
- getCurrentLanguage
152
+ getCurrentLanguage,
150
153
  }
151
154
  })
package/type.ts CHANGED
@@ -108,6 +108,7 @@ export interface Groups {
108
108
  readOnly: boolean
109
109
  displayConfig: string[]
110
110
  batchAddFileField?: Fields
111
+ primaryColumn?: Columns
111
112
  }
112
113
 
113
114
  export interface Entity extends Entities {