@skyfox2000/webui 1.4.21 → 1.4.22

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.
Files changed (42) hide show
  1. package/lib/assets/modules/{baseLayout-Da4Ox7Lj.js → baseLayout-BcSEYvus.js} +3 -3
  2. package/lib/assets/modules/{file-upload-Bu6FkNjZ.js → file-upload-D11e2io7.js} +1 -1
  3. package/lib/assets/modules/{index-BYVerdEw.js → index-CO9_YadW.js} +2 -2
  4. package/lib/assets/modules/{index-Ch3meKe4.js → index-ClMWx3tg.js} +1 -1
  5. package/lib/assets/modules/{index-BysCt107.js → index-voAmrZ30.js} +2 -2
  6. package/lib/assets/modules/{menuTabs-BqLT-YbD.js → menuTabs-C9wkt-m9.js} +2 -2
  7. package/lib/assets/modules/{toolIcon-Dd58W0UM.js → toolIcon-9zQ4jiFD.js} +1 -1
  8. package/lib/assets/modules/{upload-template-Csccple9.js → upload-template-CM0O990W.js} +386 -369
  9. package/lib/assets/modules/uploadList-DhkFSkqE.js +466 -0
  10. package/lib/components/content/index.d.ts +4 -0
  11. package/lib/components/content/list/index.vue.d.ts +126 -0
  12. package/lib/components/content/list/listOperate.vue.d.ts +18 -0
  13. package/lib/components/form/switch/index.vue.d.ts +11 -1
  14. package/lib/components/form/upload/uploadList.vue.d.ts +448 -0
  15. package/lib/components/index.d.ts +1 -1
  16. package/lib/const/options.d.ts +4 -2
  17. package/lib/es/AceEditor/index.js +3 -3
  18. package/lib/es/BasicLayout/index.js +2 -2
  19. package/lib/es/Error403/index.js +1 -1
  20. package/lib/es/Error404/index.js +1 -1
  21. package/lib/es/ExcelForm/index.js +5 -5
  22. package/lib/es/MenuLayout/index.js +2 -2
  23. package/lib/es/TemplateFile/index.js +4 -4
  24. package/lib/es/UploadForm/index.js +70 -56
  25. package/lib/index.d.ts +1 -1
  26. package/lib/typings/upload.d.ts +10 -0
  27. package/lib/webui.css +1 -1
  28. package/lib/webui.es.js +1418 -1167
  29. package/package.json +1 -1
  30. package/src/components/content/dialog/uploadForm.vue +96 -13
  31. package/src/components/content/index.ts +5 -0
  32. package/src/components/content/list/index.vue +198 -0
  33. package/src/components/content/list/listOperate.vue +122 -0
  34. package/src/components/content/table/index.vue +1 -1
  35. package/src/components/content/table/tableOperate.vue +19 -37
  36. package/src/components/form/switch/index.vue +27 -14
  37. package/src/components/form/upload/uploadList.vue +46 -3
  38. package/src/components/index.ts +2 -0
  39. package/src/const/options.ts +11 -1
  40. package/src/index.ts +2 -0
  41. package/src/typings/upload.d.ts +10 -0
  42. package/lib/assets/modules/uploadList-D8scq04c.js +0 -423
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyfox2000/webui",
3
- "version": "1.4.21",
3
+ "version": "1.4.22",
4
4
  "description": "后台前端通用组件定义",
5
5
  "type": "module",
6
6
  "keywords": [],
@@ -9,19 +9,10 @@ import message from 'vue-m-message';
9
9
  import { AsyncUploader } from '@/utils/file-upload';
10
10
 
11
11
  const props = defineProps<{
12
- /**
13
- * 文件后缀限制
14
- */
15
- fileExt?: string[];
16
12
  /**
17
13
  * 表格控制器
18
14
  */
19
15
  gridCtrl: GridControl<AnyData>;
20
- /**
21
- * 最大文件数
22
- * 默认1个
23
- */
24
- maxCount?: number;
25
16
  /**
26
17
  * 并发上传文件数
27
18
  * 默认3个
@@ -39,19 +30,90 @@ const props = defineProps<{
39
30
  * 下载地址和参数
40
31
  */
41
32
  downloadUrl?: IUrlInfo;
33
+ /**
34
+ * 删除Url
35
+ */
36
+ deleteUrl?: IUrlInfo;
37
+ /**
38
+ * 文件列表
39
+ */
40
+ fileList: UploadFile[];
41
+
42
42
  /**
43
43
  * 部分错误上传是否继续保存
44
44
  */
45
45
  continueOnError?: boolean;
46
+
47
+ /**
48
+ * 预览Url
49
+ */
50
+ previewUrl?: IUrlInfo;
51
+
52
+ /**
53
+ * Upload配置参数
54
+ */
55
+ upload?: {
56
+ /**
57
+ * 是否自动上传
58
+ */
59
+ autoUpload?: boolean;
60
+ /**
61
+ * 提示文字
62
+ */
63
+ placeholder?: string;
64
+ /**
65
+ * 文件后缀列表
66
+ */
67
+ fileExt?: string[];
68
+ /**
69
+ * 最大文件大小
70
+ */
71
+ maxFileSize?: number;
72
+ /**
73
+ * 最大数量
74
+ */
75
+ maxCount?: number;
76
+ /**
77
+ * 最大数量提示
78
+ */
79
+ maxCountTip?: boolean;
80
+ /**
81
+ * 文件大小提示
82
+ */
83
+ maxFileSizeTip?: boolean;
84
+ /**
85
+ * 文件类型提示
86
+ */
87
+ fileExtTip?: boolean;
88
+ /**
89
+ * 文件路径
90
+ */
91
+ parentPath?: string;
92
+ /**
93
+ * 显示操作文字
94
+ */
95
+ showActionText?: boolean;
96
+ /**
97
+ * 是否显示上线或下线
98
+ */
99
+ showOnlineSwitch?: boolean;
100
+ /**
101
+ * 是否显示删除
102
+ */
103
+ showDelete?: boolean;
104
+ /**
105
+ * 是否显示目录上传按钮
106
+ */
107
+ showFolderUpload?: boolean;
108
+ };
46
109
  }>();
47
110
 
48
111
  const uploadFormCtrl = props.uploadForm;
49
112
  const open = ref<boolean>(false);
50
113
 
51
- const maxCount = props.maxCount ?? 1;
52
114
  const maxConcurrent = props.maxConcurrent ?? 3;
53
115
 
54
- const fileList = ref<UploadFile[]>([]);
116
+ const fileList = ref<UploadFile[]>(props.fileList ?? []);
55
117
  const emit = defineEmits<{
56
118
  /**
57
119
  * 显示预处理
@@ -80,6 +142,22 @@ watch(
80
142
  const uploadUrl = ref(props.uploadUrl);
81
143
  const downloadUrl = ref(props.downloadUrl);
82
144
 
145
+ // Upload默认配置
146
+ const uploadConfig = ref({
147
+ autoUpload: false,
148
+ placeholder: '',
149
+ maxFileSize: 20,
150
+ maxCount: 5,
151
+ maxCountTip: false,
152
+ maxFileSizeTip: true,
153
+ fileExtTip: true,
154
+ showActionText: true,
155
+ showOnlineSwitch: false,
156
+ showDelete: true,
157
+ showFolderUpload: false,
158
+ ...props.upload
159
+ });
160
+
83
161
  const dialogSave = async () => {
84
162
  emit('before:upload', fileList.value);
85
163
  const uploader = new AsyncUploader(uploadUrl.value!, maxConcurrent);
@@ -139,8 +217,13 @@ const dialogClose = () => {
139
217
  <Modal title="文件上传" v-model:open="open"
140
218
  :wrapClassName="'modal mx-auto ' + ($attrs.width ? 'w-[' + $attrs.width + ']' : 'w-[500px]')"
141
219
  @close="dialogClose">
142
- <UploadList v-model:file-list="fileList" :upload-url="uploadUrl!" :download-url="downloadUrl"
143
- :max-count="maxCount" :file-ext="fileExt" />
220
+ <UploadList
221
+ v-model:file-list="fileList"
222
+ :upload-url="uploadUrl!"
223
+ :download-url="downloadUrl"
224
+ :preview-url="props.previewUrl"
225
+ v-bind="uploadConfig"
226
+ />
144
227
  <template #footer>
145
228
  <Space>
146
229
  <Button @click="dialogClose">取消</Button>
@@ -13,6 +13,11 @@ export { Form };
13
13
  import FormItem from './form/formItem.vue';
14
14
  export { FormItem };
15
15
 
16
+ import List from './list/index.vue';
17
+ export { List };
18
+ import ListOperate from './list/listOperate.vue';
19
+ export { ListOperate };
20
+
16
21
  import Search from './search/index.vue';
17
22
  export { Search };
18
23
  import SearchItem from './search/searchItem.vue';
@@ -0,0 +1,198 @@
1
+ <script lang="ts" setup>
2
+ import { onMounted, Ref, ref, watch, provide, useAttrs, onActivated, computed } from 'vue';
3
+ import { Card, List, ListItem, PaginationProps, ListProps } from 'ant-design-vue';
4
+ import {
5
+ AppRouter,
6
+ gridQueryFind,
7
+ gridStatusUpdate,
8
+ OPTIONS,
9
+ gridQueryList,
10
+ GridControl,
11
+ } from '@/index';
12
+ import ListOperate from './listOperate.vue';
13
+ import Toolbar from '../toolbar/index.vue';
14
+ import Switch from '../../form/switch/index.vue';
15
+ import { AnyData } from '@skyfox2000/fapi';
16
+ import { ProviderKeys } from '@/index';
17
+
18
+ const props = withDefaults(defineProps<{
19
+ /**
20
+ * 列表数据控制
21
+ */
22
+ gridCtrl: GridControl<AnyData>;
23
+ /**
24
+ * 主键字段名
25
+ */
26
+ primaryKey?: string;
27
+ /**
28
+ * 自定义列表数据
29
+ */
30
+ listData?: Record<string, AnyData>[];
31
+ /**
32
+ * 网格配置
33
+ */
34
+ grid?: ListProps['grid'];
35
+ /**
36
+ * 自定义分页控制
37
+ */
38
+ pagination?: false | PaginationProps;
39
+ /**
40
+ * 卡片标题字段
41
+ */
42
+ titleField?: string;
43
+ /**
44
+ * 是否禁用启用状态
45
+ */
46
+ statusDisabled?: Function;
47
+ }>(), {
48
+ grid: () => ({ gutter: 16, column: 4 }),
49
+ titleField: 'Title',
50
+ pagination: undefined,
51
+ });
52
+
53
+ // 关闭自动继承属性到根元素
54
+ defineOptions({
55
+ inheritAttrs: false,
56
+ });
57
+ const attrs = useAttrs(); // 手动获取 $attrs
58
+
59
+ const gridCtrl = props.gridCtrl;
60
+
61
+ // 响应式获取当前路由路径
62
+ const currentPath = computed(() => AppRouter.currentRoute.value.path);
63
+
64
+ if (gridCtrl) {
65
+ gridCtrl.pageNo.value = 1;
66
+ gridCtrl.total.value = 0;
67
+ gridCtrl.pageSize.value = gridCtrl.pageSize.value;
68
+ }
69
+ const curPageSize = ref(gridCtrl.pageSize.value);
70
+ const curPageNo = ref(gridCtrl.pageNo.value);
71
+
72
+ const dataList = ref<Record<string, AnyData>[]>([]);
73
+ const pagination: Ref<false | PaginationProps> = ref<false | PaginationProps>({
74
+ ...{
75
+ total: 0,
76
+ current: 1,
77
+ pageSize: curPageSize.value,
78
+ showTotal: (total: number) => {
79
+ return `共 ${total} 条记录`;
80
+ },
81
+ onChange: (page: number, pageSize: number) => {
82
+ if (pagination.value !== false) {
83
+ pagination.value.current = page;
84
+ pagination.value.pageSize = pageSize;
85
+ }
86
+ curPageSize.value = pageSize;
87
+ curPageNo.value = page;
88
+ if (gridCtrl) {
89
+ gridCtrl.pageNo.value = page;
90
+ gridCtrl.pageSize.value = pageSize;
91
+ if (gridCtrl.remotePage) gridQueryFind(gridCtrl);
92
+ }
93
+ },
94
+ },
95
+ ...(props.pagination === false ? {} : props.pagination),
96
+ });
97
+
98
+ if (props.pagination === false) {
99
+ pagination.value = false;
100
+ }
101
+
102
+ watch(
103
+ () => gridCtrl.tableData.value,
104
+ (newVal) => {
105
+ if (newVal) {
106
+ dataList.value = newVal;
107
+ if (pagination.value !== false) {
108
+ pagination.value.total = gridCtrl.total.value ?? 0;
109
+ pagination.value.current = gridCtrl.pageNo.value ?? 1;
110
+ pagination.value.pageSize = gridCtrl.pageSize.value ?? 10;
111
+ }
112
+ }
113
+ },
114
+ { immediate: true },
115
+ );
116
+
117
+ watch(
118
+ () => props.listData,
119
+ (newVal) => {
120
+ if (newVal) {
121
+ dataList.value = newVal;
122
+ if (pagination.value !== false) {
123
+ pagination.value.total = newVal.length;
124
+ pagination.value.current = gridCtrl.pageNo.value ?? 1;
125
+ pagination.value.pageSize = gridCtrl.pageSize.value ?? 10;
126
+ }
127
+ }
128
+ },
129
+ { immediate: true },
130
+ );
131
+
132
+ const visible = ref(false);
133
+ onActivated(() => {
134
+ if (visible.value && gridCtrl && gridCtrl.autoload) gridCtrl.reload.value = true;
135
+ });
136
+
137
+ onMounted(async () => {
138
+ provide(ProviderKeys.GridControl, gridCtrl);
139
+
140
+ if (gridCtrl.page && gridCtrl.gridUrl?.url) {
141
+ if (gridCtrl.gridUrl?.url === gridCtrl.page.urls.list?.url) {
142
+ gridCtrl.remotePage = false;
143
+ }
144
+ if (gridCtrl.gridUrl?.url === gridCtrl.page.urls.find?.url) {
145
+ gridCtrl.remotePage = true;
146
+ }
147
+ }
148
+
149
+ if (gridCtrl.tableData.value) {
150
+ dataList.value = gridCtrl.tableData.value;
151
+ gridCtrl.total.value = dataList.value.length;
152
+ if (pagination.value !== false) {
153
+ pagination.value.total = gridCtrl.total.value ?? 0;
154
+ }
155
+ } else if (gridCtrl.autoload !== false) {
156
+ if (gridCtrl.remotePage) {
157
+ dataList.value = (await gridQueryFind(gridCtrl)).rows;
158
+ } else {
159
+ dataList.value = await gridQueryList(gridCtrl);
160
+ }
161
+ }
162
+
163
+ setTimeout(() => {
164
+ // 延时显示,避免列表无数据显示异常
165
+ visible.value = true;
166
+ }, 50);
167
+ });
168
+ </script>
169
+ <template>
170
+ <Toolbar :grid-ctrl="gridCtrl" :editor-ctrl="gridCtrl.editor!"
171
+ v-if="gridCtrl.buttons?.value.length || gridCtrl.tools?.length" />
172
+ <List v-if="visible" class="w-full min-h-[480px]" :grid="props.grid" :data-source="dataList"
173
+ :loading="gridCtrl.isGridLoading.value" :pagination="pagination" v-bind="attrs">
174
+ <template #renderItem="{ item }">
175
+ <ListItem class="!m-0 !p-0">
176
+ <Card class="!m-0" :head-style="{ fontSize: '14px', padding: '8px', minHeight: '36px', height: '36px' }"
177
+ :body-style="{ padding: '4px' }">
178
+ <template #title>
179
+ <div class="flex items-center justify-between">
180
+ <span>{{ item[props.titleField] }}</span>
181
+ <div class="flex items-center space-x-2">
182
+ <Switch v-model:checked="item[gridCtrl.statusKey]"
183
+ v-auth:disable="{ url: currentPath, role: ['Super', 'Admin'], permit: ':enabled' }"
184
+ :disabled="statusDisabled ? statusDisabled(item) : false" :data="OPTIONS.EnableDisable"
185
+ @click="gridStatusUpdate(gridCtrl, item)" size="small" :class="[
186
+ 'relative mt-[3px] transform scale-[1.1]',
187
+ statusDisabled && statusDisabled(item) ? 'cursor-not-allowed disabled' : '',
188
+ ]" :loading="item.isLoading" />
189
+ <ListOperate :record="item" :grid-ctrl="gridCtrl" />
190
+ </div>
191
+ </div>
192
+ </template>
193
+ <slot name="cardContent" :record="item"></slot>
194
+ </Card>
195
+ </ListItem>
196
+ </template>
197
+ </List>
198
+ </template>
@@ -0,0 +1,122 @@
1
+ <script setup lang="ts" generic="T">
2
+ import {
3
+ AppRouter,
4
+ ButtonTool,
5
+ getToolGroup,
6
+ getToolVisible,
7
+ getToolStatus,
8
+ onToolClicked,
9
+ onGridRowEdit,
10
+ onGridRowDelete,
11
+ GridControl,
12
+ ToolIcon,
13
+ } from '@/index';
14
+ import { ConfigProvider, Space, DropdownButton, Menu, MenuItem, Popconfirm } from 'ant-design-vue';
15
+ import { computed } from 'vue';
16
+
17
+ const props = defineProps<{
18
+ /**
19
+ * 数据行记录
20
+ */
21
+ record: Record<string, any>;
22
+ /**
23
+ * 表格数据控制
24
+ */
25
+ gridCtrl: GridControl<T>;
26
+ }>();
27
+
28
+ const gridCtrl = props.gridCtrl;
29
+
30
+ // 响应式获取当前路由路径
31
+ const currentPath = computed(() => AppRouter.currentRoute.value.path);
32
+
33
+ /// 兼容其它按钮操作参数
34
+ const defaultOperates: ButtonTool[] = [
35
+ {
36
+ key: 'Edit',
37
+ label: '',
38
+ icon: 'icon-edit',
39
+ type: 'text',
40
+ visible: true,
41
+ role: ['Super', 'Admin'],
42
+ permit: ':edit',
43
+ click: () => onGridRowEdit<T>(gridCtrl, props.record as T),
44
+ },
45
+ {
46
+ key: 'Delete',
47
+ label: '',
48
+ icon: 'icon-delete',
49
+ type: 'text',
50
+ visible: true,
51
+ danger: true,
52
+ role: ['Super', 'Admin'],
53
+ permit: ':delete',
54
+ confirm: true,
55
+ confirmText: '是否删除此记录?',
56
+ click: () => onGridRowDelete<T>(gridCtrl, props.record as T),
57
+ },
58
+ ];
59
+
60
+ const { buttons, menus } = getToolGroup(defaultOperates, 0, gridCtrl.operates);
61
+
62
+ const disabled = (item: ButtonTool): boolean => {
63
+ if (typeof item.disabled == 'boolean') {
64
+ return item.disabled;
65
+ }
66
+ if (typeof item.disabled == 'function') {
67
+ return getToolStatus(item, props.record) ?? false;
68
+ }
69
+ if (props.record.hasOwnProperty(gridCtrl.statusKey)) {
70
+ switch (item.key) {
71
+ case 'Edit':
72
+ return props.record[gridCtrl.statusKey] ? false : true;
73
+ case 'Delete':
74
+ return props.record[gridCtrl.statusKey] ? true : false;
75
+ }
76
+ }
77
+ return false;
78
+ };
79
+ </script>
80
+ <template>
81
+ <ConfigProvider :theme="{
82
+ token: {
83
+ fontSize: 13,
84
+ },
85
+ }">
86
+ <Space>
87
+ <template v-for="item in buttons" :key="item.key">
88
+ <Popconfirm v-if="getToolVisible(item, props.record)" :disabled="disabled(item) || !item.confirm"
89
+ cancelText="否" okText="是" :title="item.confirmText" :okButtonProps="{ size: 'small' }"
90
+ :cancelButtonProps="{ size: 'small' }"
91
+ @confirm="onToolClicked(item, gridCtrl.page, gridCtrl, props.record, true)">
92
+ <ToolIcon :key="item.key" :icon="item.icon" :danger="item.danger"
93
+ v-if="getToolVisible(item, props.record)" :disabled="disabled(item)"
94
+ v-auth="{ url: currentPath, role: item.role, permit: item.permit }"
95
+ @click="!disabled(item) && onToolClicked(item, gridCtrl.page, gridCtrl, props.record)"
96
+ :clickable="!disabled(item)" :class="[
97
+ 'w-4 h-4',
98
+ item.danger ? 'text-red-500' : 'text-gray-600',
99
+ disabled(item) ? 'opacity-30 cursor-not-allowed' : 'hover:text-gray-800',
100
+ ]" />
101
+ </Popconfirm>
102
+ </template>
103
+
104
+ <ConfigProvider :autoInsertSpaceInButton="false" v-if="record[gridCtrl.statusKey] == 1">
105
+ <DropdownButton v-if="menus.length > 0" size="small">
106
+ 更多
107
+ <template #overlay>
108
+ <Menu>
109
+ <template v-for="item in menus" :key="item.key">
110
+ <MenuItem v-if="getToolVisible(item, props.record)" :disabled="disabled(item)"
111
+ v-auth="{ url: currentPath, role: item.role, permit: item.permit }"
112
+ @click="onToolClicked(item, gridCtrl.page, gridCtrl, props.record)">
113
+ {{ item.label }}
114
+ </MenuItem>
115
+ </template>
116
+ </Menu>
117
+ </template>
118
+ </DropdownButton>
119
+ </ConfigProvider>
120
+ </Space>
121
+ </ConfigProvider>
122
+ </template>
@@ -212,7 +212,7 @@ onMounted(async () => {
212
212
  <template #bodyCell="bodyCell">
213
213
  <slot name="bodyCell" :column="bodyCell?.column" :record="bodyCell?.record"></slot>
214
214
  <template v-if="gridCtrl && bodyCell?.column?.dataIndex === 'enabled'">
215
- <Switch v-model:checked="bodyCell.record.Enabled"
215
+ <Switch v-model:checked="bodyCell.record[gridCtrl.statusKey]"
216
216
  v-auth:disable="{ url: currentPath, role: ['Super', 'Admin'], permit: ':enabled' }"
217
217
  :disabled="statusDisabled ? statusDisabled(bodyCell.record) : false" :data="OPTIONS.EnableDisable"
218
218
  @click="gridStatusUpdate(gridCtrl, bodyCell.record)" :class="[
@@ -63,68 +63,50 @@ const disabled = (item: ButtonTool): boolean => {
63
63
  if (typeof item.disabled == 'function') {
64
64
  return getToolStatus(item, props.record) ?? false;
65
65
  }
66
- if (props.record.hasOwnProperty('Enabled')) {
66
+ if (props.record.hasOwnProperty(gridCtrl.statusKey)) {
67
67
  switch (item.key) {
68
68
  case 'Edit':
69
- return props.record.Enabled ? false : true;
69
+ return props.record[gridCtrl.statusKey] ? false : true; // 启用时可编辑,停用时不可编辑
70
70
  case 'Delete':
71
- return props.record.Enabled ? true : false;
71
+ return props.record[gridCtrl.statusKey] ? true : false; // 启用时不可删除,停用时可删除
72
72
  }
73
73
  }
74
74
  return false;
75
75
  };
76
76
  </script>
77
77
  <template>
78
- <ConfigProvider
79
- :theme="{
80
- token: {
81
- fontSize: 13,
82
- },
83
- }"
84
- >
78
+ <ConfigProvider :theme="{
79
+ token: {
80
+ fontSize: 13,
81
+ },
82
+ }">
85
83
  <Space>
86
84
  <template v-for="item in buttons" :key="item.key">
87
- <Popconfirm
88
- v-if="getToolVisible(item, props.record)"
89
- :disabled="disabled(item) || !item.confirm"
90
- cancelText="否"
91
- okText="是"
92
- :title="item.confirmText"
93
- :okButtonProps="{ size: 'small' }"
85
+ <Popconfirm v-if="getToolVisible(item, props.record)" :disabled="disabled(item) || !item.confirm"
86
+ cancelText="否" okText="是" :title="item.confirmText" :okButtonProps="{ size: 'small' }"
94
87
  :cancelButtonProps="{ size: 'small' }"
95
- @confirm="onToolClicked(item, gridCtrl.page, gridCtrl, props.record, true)"
96
- >
97
- <Button
98
- :key="item.key"
99
- :type="item.type ?? 'text'"
100
- :danger="item.danger"
101
- v-if="getToolVisible(item, props.record)"
102
- :disabled="disabled(item)"
88
+ @confirm="onToolClicked(item, gridCtrl.page, gridCtrl, props.record, true)">
89
+ <Button :key="item.key" :type="item.type ?? 'text'" :danger="item.danger"
90
+ v-if="getToolVisible(item, props.record)" :disabled="disabled(item)"
103
91
  v-auth="{ url: currentPath, role: item.role, permit: item.permit }"
104
- @click="onToolClicked(item, gridCtrl.page, gridCtrl, props.record)"
105
- size="small"
106
- :style="{
92
+ @click="onToolClicked(item, gridCtrl.page, gridCtrl, props.record)" size="small" :style="{
107
93
  padding: item.type ?? '0px 4px',
108
- }"
109
- >
94
+ }">
110
95
  {{ item.label }}
111
96
  </Button>
112
97
  </Popconfirm>
113
98
  </template>
114
99
 
115
- <ConfigProvider :autoInsertSpaceInButton="false" v-if="record.Enabled == 1">
100
+ <ConfigProvider :autoInsertSpaceInButton="false" v-if="record[gridCtrl.statusKey] == 1">
116
101
  <DropdownButton v-if="menus.length > 0" size="small">
117
102
  更多
118
103
  <template #overlay>
119
104
  <Menu>
120
105
  <template v-for="item in menus" :key="item.key">
121
- <MenuItem
122
- v-if="getToolVisible(item, props.record)"
123
- :disabled="disabled(item)"
106
+ <MenuItem v-if="getToolVisible(item, props.record)" :disabled="disabled(item)"
124
107
  v-auth="{ url: currentPath, role: item.role, permit: item.permit }"
125
- @click="onToolClicked(item, gridCtrl.page, gridCtrl, props.record)"
126
- >
127
- {{ item.label }}
108
+ @click="onToolClicked(item, gridCtrl.page, gridCtrl, props.record)">
109
+ {{ item.label }}
128
110
  </MenuItem>
129
111
  </template>
130
112
  </Menu>
@@ -4,6 +4,7 @@ import { formValidate, useInputFactory, OptionItemProps, loadOption, unloadOptio
4
4
  import { Switch } from 'ant-design-vue';
5
5
  import message from 'vue-m-message';
6
6
  import { useOptionFactory } from '@/utils/page';
7
+ import { computed } from 'vue';
7
8
 
8
9
  const props = defineProps({
9
10
  ...OptionCommProps,
@@ -14,6 +15,10 @@ const props = defineProps({
14
15
  type: Array as PropType<OptionItemProps[]>,
15
16
  required: true,
16
17
  },
18
+ size: {
19
+ type: String as PropType<'small' | 'default' | undefined>,
20
+ default: 'default',
21
+ },
17
22
  });
18
23
 
19
24
  const inputFactory = useInputFactory();
@@ -42,6 +47,15 @@ const emit = defineEmits<{
42
47
  }>();
43
48
 
44
49
  const { editorCtrl, errInfo } = useInputFactory();
50
+
51
+ const customSize = computed(() => {
52
+ switch (props.size) {
53
+ case 'small':
54
+ return 'w-[46px]';
55
+ default:
56
+ return 'w-[58px]';
57
+ }
58
+ });
45
59
  const onChange = (checked: boolean | string | number) => {
46
60
  if (errInfo?.value.errClass && editorCtrl) {
47
61
  /// 重新开始验证
@@ -63,18 +77,17 @@ onUnmounted(() => {
63
77
  });
64
78
  </script>
65
79
  <template>
66
- <Switch
67
- v-if="switchOptions.length === 2"
68
- :class="[
69
- errInfo?.errClass === 'error' ? 'error !border-red-300 shadow-[0_0_3px_0px_#ff4d4f]' : '',
70
- 'bg-blue-300',
71
- 'w-[58px]',
72
- ]"
73
- :checkedChildren="switchOptions[0].label"
74
- :checkedValue="switchOptions[0].value"
75
- :unCheckedChildren="switchOptions[1].label"
76
- :unCheckedValue="switchOptions[1].value"
77
- @change="onChange"
78
- v-bind="$attrs"
79
- />
80
+ <Switch v-if="switchOptions.length === 2" :size="size" :class="[
81
+ errInfo?.errClass === 'error' ? 'error !border-red-300 shadow-[0_0_3px_0px_#ff4d4f]' : '',
82
+ 'bg-blue-300',
83
+ customSize,
84
+ ]" :checkedChildren="switchOptions[0].label" :checkedValue="switchOptions[0].value"
85
+ :unCheckedChildren="switchOptions[1].label" :unCheckedValue="switchOptions[1].value" @change="onChange"
86
+ v-bind="$attrs" />
80
87
  </template>
88
+ <style>
89
+ .ant-switch-small .ant-switch-inner-checked,
90
+ .ant-switch-small .ant-switch-inner-unchecked {
91
+ font-size: 10px !important;
92
+ }
93
+ </style>