@skyfox2000/webui 1.3.2 → 1.3.3

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 (28) hide show
  1. package/lib/assets/modules/{file-upload-BVB9c-eZ.js → file-upload-D4Pqs8h3.js} +1 -1
  2. package/lib/assets/modules/{form-excel-CsQBtfkA.js → form-excel-D1vXB4c4.js} +1 -1
  3. package/lib/assets/modules/{index-k_AnrbPY.js → index-CSnwbbQT.js} +2 -2
  4. package/lib/assets/modules/{index-CaaMz5sz.js → index-V1j9haWy.js} +1 -1
  5. package/lib/assets/modules/{menuTabs-_Ph7P8ES.js → menuTabs-e8XoJN7m.js} +2 -2
  6. package/lib/assets/modules/{toolIcon-QMXCkImG.js → toolIcon-BSF7eiPf.js} +1 -1
  7. package/lib/assets/modules/uploadList-Bcf7g1bf.js +382 -0
  8. package/lib/assets/modules/{uploadList-D-FOtndj.js → uploadList-DA4TRDWR.js} +482 -508
  9. package/lib/components/form/autoComplete/index.vue.d.ts +10 -48
  10. package/lib/components/form/upload/uploadList.vue.d.ts +1 -0
  11. package/lib/es/AceEditor/index.js +3 -3
  12. package/lib/es/BasicLayout/index.js +3 -3
  13. package/lib/es/Error403/index.js +1 -1
  14. package/lib/es/Error404/index.js +1 -1
  15. package/lib/es/ExcelForm/index.js +4 -4
  16. package/lib/es/UploadForm/index.js +4 -4
  17. package/lib/index.d.ts +1 -1
  18. package/lib/utils/download.d.ts +2 -0
  19. package/lib/webui.css +1 -1
  20. package/lib/webui.es.js +207 -205
  21. package/package.json +1 -1
  22. package/src/components/content/table/index.vue +22 -10
  23. package/src/components/form/autoComplete/index.vue +29 -60
  24. package/src/components/form/upload/uploadList.vue +50 -11
  25. package/src/index.ts +1 -1
  26. package/src/utils/download.ts +31 -0
  27. package/src/utils/options.ts +0 -1
  28. package/lib/assets/modules/uploadList-CXa3siDj.js +0 -327
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyfox2000/webui",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "后台前端通用组件定义",
5
5
  "type": "module",
6
6
  "keywords": [],
@@ -67,7 +67,7 @@ const curPageSize = ref(gridCtrl.pageSize.value);
67
67
  const curPageNo = ref(gridCtrl.pageNo.value);
68
68
 
69
69
  const dataList = ref<Record<string, AnyData>[]>([]);
70
- const pagination: Ref<TablePaginationConfig> = ref<TablePaginationConfig>({
70
+ const pagination: Ref<false | TablePaginationConfig> = ref<false | TablePaginationConfig>({
71
71
  ...{
72
72
  total: 0,
73
73
  current: 1,
@@ -76,8 +76,10 @@ const pagination: Ref<TablePaginationConfig> = ref<TablePaginationConfig>({
76
76
  return `共 ${total} 条记录`;
77
77
  },
78
78
  onChange: (page: number, pageSize: number) => {
79
- pagination.value.current = page;
80
- pagination.value.pageSize = pageSize;
79
+ if (pagination.value !== false) {
80
+ pagination.value.current = page;
81
+ pagination.value.pageSize = pageSize;
82
+ }
81
83
  curPageSize.value = pageSize;
82
84
  curPageNo.value = page;
83
85
  if (gridCtrl) {
@@ -90,14 +92,20 @@ const pagination: Ref<TablePaginationConfig> = ref<TablePaginationConfig>({
90
92
  ...props.pagination,
91
93
  });
92
94
 
95
+ if (props.pagination === false) {
96
+ pagination.value = false;
97
+ }
98
+
93
99
  watch(
94
100
  () => gridCtrl.tableData.value,
95
101
  (newVal) => {
96
102
  if (newVal) {
97
103
  dataList.value = newVal;
98
- pagination.value.total = gridCtrl.total.value ?? 0;
99
- pagination.value.current = gridCtrl.pageNo.value ?? 1;
100
- pagination.value.pageSize = gridCtrl.pageSize.value ?? 10;
104
+ if (pagination.value !== false) {
105
+ pagination.value.total = gridCtrl.total.value ?? 0;
106
+ pagination.value.current = gridCtrl.pageNo.value ?? 1;
107
+ pagination.value.pageSize = gridCtrl.pageSize.value ?? 10;
108
+ }
101
109
  }
102
110
  },
103
111
  { immediate: true },
@@ -108,9 +116,11 @@ watch(
108
116
  (newVal) => {
109
117
  if (newVal) {
110
118
  dataList.value = newVal;
111
- pagination.value.total = newVal.length;
112
- pagination.value.current = gridCtrl.pageNo.value ?? 1;
113
- pagination.value.pageSize = gridCtrl.pageSize.value ?? 10;
119
+ if (pagination.value !== false) {
120
+ pagination.value.total = newVal.length;
121
+ pagination.value.current = gridCtrl.pageNo.value ?? 1;
122
+ pagination.value.pageSize = gridCtrl.pageSize.value ?? 10;
123
+ }
114
124
  }
115
125
  },
116
126
  { immediate: true },
@@ -162,7 +172,9 @@ onMounted(async () => {
162
172
  if (gridCtrl.tableData.value) {
163
173
  dataList.value = gridCtrl.tableData.value;
164
174
  gridCtrl.total.value = dataList.value.length;
165
- pagination.value.total = gridCtrl.total.value ?? 0;
175
+ if (pagination.value !== false) {
176
+ pagination.value.total = gridCtrl.total.value ?? 0;
177
+ }
166
178
  } else if (gridCtrl.autoload !== false) {
167
179
  if (gridCtrl.remotePage) {
168
180
  dataList.value = (await gridQueryFind(gridCtrl)).rows;
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { ref, onMounted, onUnmounted, useAttrs, watch, shallowRef } from 'vue';
2
+ import { ref, onUnmounted, useAttrs, watch, shallowRef, PropType } from 'vue';
3
3
  import { AutoComplete } from 'ant-design-vue';
4
4
  import {
5
5
  useInputFactory,
@@ -13,35 +13,23 @@ import {
13
13
  formValidate,
14
14
  outFormDataFields,
15
15
  } from '@/index';
16
- import { ReqParams, IUrlInfo } from '@skyfox2000/fapi';
16
+ import { ReqParams } from '@skyfox2000/fapi';
17
17
  import { useOptionFactory } from '@/utils/page';
18
+ import { combineParams } from '@skyfox2000/microbase';
18
19
 
19
20
  const props = defineProps({
20
21
  ...OptionCommProps,
21
22
  value: {
22
- type: [String, Number, null, Array],
23
+ type: [String, Number, Array, null] as PropType<string | number | string[] | null>,
23
24
  default: undefined,
24
25
  },
25
- /**
26
- * 查询字段
27
- * - 模糊查询
28
- */
29
- searchField: {
30
- type: [String, Array<string>],
31
- },
32
- /**
33
- * 自定义查询参数
34
- * - 查询参数
35
- * - query参数
36
- */
37
- onsearch: {
38
- type: Function,
39
- },
40
26
  /**
41
27
  * 修改输入数据则自动清空关联数据
28
+ * - FormData: 表单数据
29
+ * - outFields: 输出字段
42
30
  */
43
31
  autoClean: {
44
- type: Boolean,
32
+ type: Boolean as PropType<boolean>,
45
33
  default: true,
46
34
  },
47
35
  });
@@ -56,14 +44,18 @@ const inputFactory = useInputFactory();
56
44
  const defaultCtrl = useOptionFactory(props.url, props);
57
45
  const optionCtrl = props.optionCtrl ?? defaultCtrl.optionCtrl;
58
46
  optionCtrl.inputFactory = shallowRef(inputFactory);
59
-
60
- const url = ref<IUrlInfo>({
61
- ...optionCtrl?.url,
62
- url: optionCtrl?.url?.url || '',
63
- fieldMap: optionCtrl?.fieldMap || optionCtrl?.url?.fieldMap,
64
- params: optionCtrl?.params || optionCtrl?.url?.params,
65
- loadingText: false,
66
- });
47
+ /***
48
+ * 默认字段映射
49
+ * - label: 显示字段 支持模板 ${}
50
+ * - value: 值字段
51
+ */
52
+ optionCtrl.fieldMap = {
53
+ ...{
54
+ label: 'Name',
55
+ value: 'Id',
56
+ },
57
+ ...optionCtrl?.fieldMap,
58
+ };
67
59
 
68
60
  /// 避免类型错误
69
61
  const innerValue = ref<SelectValue | undefined>(optionCtrl?.selected.value || undefined);
@@ -103,7 +95,7 @@ if (optionCtrl) {
103
95
  (newOptions) => {
104
96
  selectOptions.value = newOptions || [];
105
97
  },
106
- { immediate: true, deep: true }
98
+ { immediate: true, deep: true },
107
99
  );
108
100
  }
109
101
 
@@ -112,29 +104,14 @@ const onSearch = (value: string) => {
112
104
  if (value === '') return;
113
105
  let search_value = value.trim();
114
106
  let query: ReqParams = {
115
- ...url.value.params,
116
107
  Query: {
117
- ...url.value.params?.Query,
108
+ SearchField: '%' + search_value + '%',
118
109
  },
119
110
  };
120
- if (props.searchField) {
121
- if (Array.isArray(props.searchField)) {
122
- props.searchField.forEach((field) => {
123
- query.Query![field] = {
124
- $like: '%' + search_value + '%',
125
- };
126
- });
127
- } else {
128
- query.Query![props.searchField] = {
129
- $like: '%' + search_value + '%',
130
- };
131
- }
132
- }
133
- if (props.onsearch) {
134
- props.onsearch(search_value, query);
135
- }
136
111
 
137
- if (optionCtrl) loadOption(optionCtrl.autoload, optionCtrl, props);
112
+ optionCtrl.params = combineParams(optionCtrl.params, query);
113
+
114
+ if (optionCtrl) loadOption(true, optionCtrl, props);
138
115
  };
139
116
 
140
117
  const onSelected = (value: any) => {
@@ -153,17 +130,6 @@ const onSelected = (value: any) => {
153
130
  }
154
131
  };
155
132
 
156
- onMounted(() => {
157
- if (url.value && !url.value.fieldMap) {
158
- url.value.fieldMap = {
159
- title: 'Name',
160
- label: 'Name',
161
- value: 'Name',
162
- key: 'Id',
163
- };
164
- }
165
- });
166
-
167
133
  onUnmounted(() => {
168
134
  if (optionCtrl) unloadOption(optionCtrl, props);
169
135
  });
@@ -173,13 +139,16 @@ onUnmounted(() => {
173
139
  <div>
174
140
  <AutoComplete
175
141
  v-model:value="innerValue"
176
- :class="[errInfo?.errClass, 'error w-full']"
142
+ :class="['w-full', errInfo?.errClass]"
177
143
  :options="selectOptions"
178
144
  @search="onSearch"
179
145
  @select="onSelected"
180
- :placeholder="optionCtrl?.url?.loading ? '请输入并选择' + labelText : ''"
146
+ :placeholder="'请输入并选择' + labelText"
181
147
  v-bind="attrs"
182
148
  >
149
+ <template #option="{ label }">
150
+ {{ label }}
151
+ </template>
183
152
  </AutoComplete>
184
153
  </div>
185
154
  </template>
@@ -4,7 +4,7 @@ import { computed, ref, watch } from 'vue';
4
4
  import message from 'vue-m-message';
5
5
  import type { UploadProps } from 'ant-design-vue';
6
6
  import { Upload, Progress, Tag, Popconfirm } from 'ant-design-vue';
7
- import { UploadFile, UploadStatus, donwloadFromMinio, path, Switch } from '@/index';
7
+ import { UploadFile, UploadStatus, donwloadFromMinio, path, Switch, previewFromMinio } from '@/index';
8
8
  import { useInputFactory } from '@/utils/form-validate';
9
9
  import { IUrlInfo } from '@skyfox2000/fapi';
10
10
 
@@ -22,6 +22,10 @@ export interface UploadListProps {
22
22
  * 下载Url
23
23
  */
24
24
  downloadUrl?: IUrlInfo;
25
+ /**
26
+ * 预览Url
27
+ */
28
+ previewUrl?: IUrlInfo;
25
29
  /**
26
30
  * 文件列表
27
31
  */
@@ -168,12 +172,11 @@ watch(
168
172
  );
169
173
 
170
174
  const downloadFile = (index: number) => {
171
- if (!props.downloadUrl) return;
172
175
  const minioFile = fileList.value[index].minioFile!;
173
176
  const url: IUrlInfo = {
174
- api: props.downloadUrl.api,
175
- authorize: props.downloadUrl.authorize,
176
- url: props.downloadUrl.url,
177
+ api: props.downloadUrl!.api,
178
+ authorize: props.downloadUrl!.authorize,
179
+ url: props.downloadUrl!.url,
177
180
  params: {
178
181
  Query: {
179
182
  FileKey: minioFile.Key,
@@ -190,10 +193,21 @@ const onlineOrOffline = (file: UploadFile) => {
190
193
  }
191
194
  };
192
195
 
193
- // const previewFile = (index: number) => {
194
- // const fileInfo = internalFileList.value[index].minioFile;
195
- // console.log(fileInfo);
196
- // };
196
+ const previewFile = (index: number) => {
197
+ const minioFile = fileList.value[index].minioFile!;
198
+ const url: IUrlInfo = {
199
+ api: props.previewUrl!.api,
200
+ authorize: props.previewUrl!.authorize,
201
+ url: props.previewUrl!.url,
202
+ params: {
203
+ Query: {
204
+ FileKey: minioFile.Key,
205
+ },
206
+ },
207
+ };
208
+
209
+ previewFromMinio(url, minioFile.FileName!);
210
+ };
197
211
 
198
212
  const removeFile = (index: number) => {
199
213
  fileList.value.splice(index, 1);
@@ -322,7 +336,26 @@ const getStatus = (status?: UploadStatus) => {
322
336
  >
323
337
  </Tooltip>
324
338
  </div>
325
- <!-- <span class="text-blue-500 hover:text-blue-700 mr-4" @click="previewFile(index)">预览</span> -->
339
+ <div
340
+ class="flex items-center text-blue-500 hover:text-blue-700 mr-1 cursor-pointer"
341
+ v-if="previewUrl && (file.status == UploadStatus.Online || file.status == UploadStatus.Offline)"
342
+ >
343
+ <Tooltip title="预览">
344
+ <ToolIcon
345
+ icon="icon-eye"
346
+ v-auth="{ role: ['Super', 'Admin'], permit: ':uploadlist:preview' }"
347
+ clickable
348
+ @click="previewFile(index)"
349
+ />
350
+ <span
351
+ v-if="showActionText"
352
+ class="mr-2 text-sm text-nowrap"
353
+ v-auth="{ role: ['Super', 'Admin'], permit: ':uploadlist:preview' }"
354
+ @click="previewFile(index)"
355
+ >预览</span
356
+ >
357
+ </Tooltip>
358
+ </div>
326
359
  <div class="flex items-center text-red-500 hover:text-red-700 cursor-pointer">
327
360
  <Popconfirm
328
361
  v-model:open="confirmOpen"
@@ -356,7 +389,13 @@ const getStatus = (status?: UploadStatus) => {
356
389
  </div>
357
390
 
358
391
  <!-- 上传进度条 -->
359
- <div v-if="file.status !== UploadStatus.Online && file.status !== UploadStatus.Offline && file.status !== UploadStatus.Success">
392
+ <div
393
+ v-if="
394
+ file.status !== UploadStatus.Online &&
395
+ file.status !== UploadStatus.Offline &&
396
+ file.status !== UploadStatus.Success
397
+ "
398
+ >
360
399
  <Progress :percent="file.percent" :stroke-width="2" :show-info="false" style="height: 2px"></Progress>
361
400
  </div>
362
401
  </div>
package/src/index.ts CHANGED
@@ -129,7 +129,7 @@ export {
129
129
  } from '@/utils/options';
130
130
 
131
131
  // download 工具
132
- export { downloadBlob, donwloadFromMinio } from '@/utils/download';
132
+ export { downloadBlob, donwloadFromMinio, previewFromMinio, CanPreviewFileExt } from '@/utils/download';
133
133
 
134
134
  // icon-loader 工具
135
135
  export {
@@ -78,3 +78,34 @@ export const donwloadFromMinio = <T>(url: IUrlInfo, params?: ReqParams, pageCtrl
78
78
  message.error('文件下载失败,请稍后重试');
79
79
  }
80
80
  };
81
+
82
+ export const CanPreviewFileExt = ['xlsx', 'xls', 'csv', 'txt'];
83
+
84
+ export const previewFromMinio = (url: IUrlInfo, fileName: string, params?: ReqParams) => {
85
+ const fileExt = fileName.split('.').pop();
86
+ if (CanPreviewFileExt.includes(fileExt!)) {
87
+ console.log(url);
88
+ } else {
89
+ message.error('文件类型不支持预览');
90
+ return false;
91
+ }
92
+
93
+ const newParams = combineParams(url.params, params);
94
+ return httpPost(url, newParams).then((result: ApiResponse<any> | null) => {
95
+ if (result?.status === ResStatus.SUCCESS && result.data) {
96
+ const minioFile: MinioFile = result.data as unknown as MinioFile;
97
+ // 提取内容和文件名
98
+ const base64String = minioFile.Content!;
99
+
100
+ // 解码 Base64 字符串
101
+ const byteCharacters = atob(base64String);
102
+ const byteArrays = [];
103
+ for (let b = 0; b < byteCharacters.length; b++) {
104
+ byteArrays.push(byteCharacters.charCodeAt(b));
105
+ }
106
+ } else {
107
+ message.error('文件预览失败!');
108
+ }
109
+ return undefined;
110
+ });
111
+ };
@@ -159,7 +159,6 @@ const queryOptions = <T>(
159
159
  ...rest,
160
160
  };
161
161
  optionUrl.loadingText = false;
162
- console.log(optionUrl.fieldMap, params);
163
162
  if (!params) params = {};
164
163
  if (!params.Query) params.Query = {};
165
164
  optionCtrl.optionQuery = params;