@skyfox2000/webui 0.1.0

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 (213) hide show
  1. package/.eslintrc.js +23 -0
  2. package/.prettierrc +11 -0
  3. package/.vscode/settings.json +25 -0
  4. package/README.md +104 -0
  5. package/env.d.ts +11 -0
  6. package/index.html +19 -0
  7. package/lib/AceEditor.d.ts +4 -0
  8. package/lib/BasicLayout.d.ts +4 -0
  9. package/lib/Error403.d.ts +4 -0
  10. package/lib/Error404.d.ts +4 -0
  11. package/lib/ExcelForm.d.ts +4 -0
  12. package/lib/UploadForm.d.ts +4 -0
  13. package/lib/assets/modules/basicLayout-YP_-EySb.js +726 -0
  14. package/lib/assets/modules/error403-Bi0E2twj.js +33 -0
  15. package/lib/assets/modules/error404-BF7vasR_.js +33 -0
  16. package/lib/assets/modules/excelForm-Dzndz-SG.js +109 -0
  17. package/lib/assets/modules/excelForm-WJVQmaDT.js +317 -0
  18. package/lib/assets/modules/index-FzWSvscZ.js +107 -0
  19. package/lib/assets/modules/index-ekkaExvB.js +49 -0
  20. package/lib/assets/modules/uploadForm-BahGnrAq.js +415 -0
  21. package/lib/assets/modules/uploadForm-DEnOjhwc.js +308 -0
  22. package/lib/components/common/button/index.vue.d.ts +42 -0
  23. package/lib/components/common/button/index.vue.d.ts.map +1 -0
  24. package/lib/components/common/icon/appicon.vue.d.ts +12 -0
  25. package/lib/components/common/icon/appicon.vue.d.ts.map +1 -0
  26. package/lib/components/common/icon/fullscreen.vue.d.ts +4 -0
  27. package/lib/components/common/icon/fullscreen.vue.d.ts.map +1 -0
  28. package/lib/components/common/icon/helper.vue.d.ts +23 -0
  29. package/lib/components/common/icon/helper.vue.d.ts.map +1 -0
  30. package/lib/components/common/icon/index.vue.d.ts +244 -0
  31. package/lib/components/common/icon/index.vue.d.ts.map +1 -0
  32. package/lib/components/common/icon/layoutIcon.vue.d.ts +44 -0
  33. package/lib/components/common/icon/layoutIcon.vue.d.ts.map +1 -0
  34. package/lib/components/common/icon/projectIcon.vue.d.ts +60 -0
  35. package/lib/components/common/icon/projectIcon.vue.d.ts.map +1 -0
  36. package/lib/components/common/icon/toolIcon.vue.d.ts +44 -0
  37. package/lib/components/common/icon/toolIcon.vue.d.ts.map +1 -0
  38. package/lib/components/common/index.d.ts +19 -0
  39. package/lib/components/common/index.d.ts.map +1 -0
  40. package/lib/components/common/tooltip/index.vue.d.ts +22 -0
  41. package/lib/components/common/tooltip/index.vue.d.ts.map +1 -0
  42. package/lib/components/content/dialog/excelForm.vue.d.ts +31 -0
  43. package/lib/components/content/dialog/excelForm.vue.d.ts.map +1 -0
  44. package/lib/components/content/dialog/index.vue.d.ts +35 -0
  45. package/lib/components/content/dialog/index.vue.d.ts.map +1 -0
  46. package/lib/components/content/dialog/uploadForm.vue.d.ts +25 -0
  47. package/lib/components/content/dialog/uploadForm.vue.d.ts.map +1 -0
  48. package/lib/components/content/drawer/index.vue.d.ts +27 -0
  49. package/lib/components/content/drawer/index.vue.d.ts.map +1 -0
  50. package/lib/components/content/form/formItem.vue.d.ts +26 -0
  51. package/lib/components/content/form/formItem.vue.d.ts.map +1 -0
  52. package/lib/components/content/form/index.vue.d.ts +26 -0
  53. package/lib/components/content/form/index.vue.d.ts.map +1 -0
  54. package/lib/components/content/index.d.ts +27 -0
  55. package/lib/components/content/index.d.ts.map +1 -0
  56. package/lib/components/content/search/index.vue.d.ts +30 -0
  57. package/lib/components/content/search/index.vue.d.ts.map +1 -0
  58. package/lib/components/content/search/searchItem.vue.d.ts +24 -0
  59. package/lib/components/content/search/searchItem.vue.d.ts.map +1 -0
  60. package/lib/components/content/table/index.vue.d.ts +37 -0
  61. package/lib/components/content/table/index.vue.d.ts.map +1 -0
  62. package/lib/components/content/table/tableOperate.vue.d.ts +19 -0
  63. package/lib/components/content/table/tableOperate.vue.d.ts.map +1 -0
  64. package/lib/components/content/toolbar/icontool.vue.d.ts +8 -0
  65. package/lib/components/content/toolbar/icontool.vue.d.ts.map +1 -0
  66. package/lib/components/content/toolbar/index.vue.d.ts +19 -0
  67. package/lib/components/content/toolbar/index.vue.d.ts.map +1 -0
  68. package/lib/components/content/tree/index.vue.d.ts +47 -0
  69. package/lib/components/content/tree/index.vue.d.ts.map +1 -0
  70. package/lib/components/error/error403.vue.d.ts +4 -0
  71. package/lib/components/error/error403.vue.d.ts.map +1 -0
  72. package/lib/components/error/error404.vue.d.ts +4 -0
  73. package/lib/components/error/error404.vue.d.ts.map +1 -0
  74. package/lib/components/form/aceEditor/aceConfig.d.ts +9 -0
  75. package/lib/components/form/aceEditor/aceConfig.d.ts.map +1 -0
  76. package/lib/components/form/aceEditor/index.vue.d.ts +13 -0
  77. package/lib/components/form/aceEditor/index.vue.d.ts.map +1 -0
  78. package/lib/components/form/autoComplete/index.vue.d.ts +140 -0
  79. package/lib/components/form/autoComplete/index.vue.d.ts.map +1 -0
  80. package/lib/components/form/cascader/index.vue.d.ts +110 -0
  81. package/lib/components/form/cascader/index.vue.d.ts.map +1 -0
  82. package/lib/components/form/checkbox/index.vue.d.ts +129 -0
  83. package/lib/components/form/checkbox/index.vue.d.ts.map +1 -0
  84. package/lib/components/form/datePicker/index.vue.d.ts +7 -0
  85. package/lib/components/form/datePicker/index.vue.d.ts.map +1 -0
  86. package/lib/components/form/index.d.ts +41 -0
  87. package/lib/components/form/index.d.ts.map +1 -0
  88. package/lib/components/form/input/index.vue.d.ts +27 -0
  89. package/lib/components/form/input/index.vue.d.ts.map +1 -0
  90. package/lib/components/form/input/inputIcon.vue.d.ts +11 -0
  91. package/lib/components/form/input/inputIcon.vue.d.ts.map +1 -0
  92. package/lib/components/form/input/inputNumber.vue.d.ts +4 -0
  93. package/lib/components/form/input/inputNumber.vue.d.ts.map +1 -0
  94. package/lib/components/form/input/inputPassword.vue.d.ts +4 -0
  95. package/lib/components/form/input/inputPassword.vue.d.ts.map +1 -0
  96. package/lib/components/form/propEditor/index.vue.d.ts +13 -0
  97. package/lib/components/form/propEditor/index.vue.d.ts.map +1 -0
  98. package/lib/components/form/radio/index.vue.d.ts +134 -0
  99. package/lib/components/form/radio/index.vue.d.ts.map +1 -0
  100. package/lib/components/form/radio/radioStatus.vue.d.ts +32 -0
  101. package/lib/components/form/radio/radioStatus.vue.d.ts.map +1 -0
  102. package/lib/components/form/rangePicker/index.vue.d.ts +17 -0
  103. package/lib/components/form/rangePicker/index.vue.d.ts.map +1 -0
  104. package/lib/components/form/select/index.vue.d.ts +143 -0
  105. package/lib/components/form/select/index.vue.d.ts.map +1 -0
  106. package/lib/components/form/switch/index.vue.d.ts +44 -0
  107. package/lib/components/form/switch/index.vue.d.ts.map +1 -0
  108. package/lib/components/form/textarea/index.vue.d.ts +4 -0
  109. package/lib/components/form/textarea/index.vue.d.ts.map +1 -0
  110. package/lib/components/form/transfer/index.vue.d.ts +39 -0
  111. package/lib/components/form/transfer/index.vue.d.ts.map +1 -0
  112. package/lib/components/form/transfer/transferTable.vue.d.ts +39 -0
  113. package/lib/components/form/transfer/transferTable.vue.d.ts.map +1 -0
  114. package/lib/components/form/treeSelect/index.vue.d.ts +39 -0
  115. package/lib/components/form/treeSelect/index.vue.d.ts.map +1 -0
  116. package/lib/components/form/upload/uploadList.vue.d.ts +477 -0
  117. package/lib/components/form/upload/uploadList.vue.d.ts.map +1 -0
  118. package/lib/components/index.d.ts +9 -0
  119. package/lib/components/index.d.ts.map +1 -0
  120. package/lib/components/layout/breadcrumb/index.vue.d.ts +4 -0
  121. package/lib/components/layout/breadcrumb/index.vue.d.ts.map +1 -0
  122. package/lib/components/layout/content/index.vue.d.ts +23 -0
  123. package/lib/components/layout/content/index.vue.d.ts.map +1 -0
  124. package/lib/components/layout/datetime/index.vue.d.ts +4 -0
  125. package/lib/components/layout/datetime/index.vue.d.ts.map +1 -0
  126. package/lib/components/layout/header/headerExits.vue.d.ts +4 -0
  127. package/lib/components/layout/header/headerExits.vue.d.ts.map +1 -0
  128. package/lib/components/layout/header/index.vue.d.ts +4 -0
  129. package/lib/components/layout/header/index.vue.d.ts.map +1 -0
  130. package/lib/components/layout/index.d.ts +17 -0
  131. package/lib/components/layout/index.d.ts.map +1 -0
  132. package/lib/components/layout/menu/index.vue.d.ts +7 -0
  133. package/lib/components/layout/menu/index.vue.d.ts.map +1 -0
  134. package/lib/components/layout/menu/menuTabs.vue.d.ts +4 -0
  135. package/lib/components/layout/menu/menuTabs.vue.d.ts.map +1 -0
  136. package/lib/components/layout/page/basicLayout.vue.d.ts +7 -0
  137. package/lib/components/layout/page/basicLayout.vue.d.ts.map +1 -0
  138. package/lib/es/AceEditor/index.js +168 -0
  139. package/lib/es/BasicLayout/index.js +4 -0
  140. package/lib/es/Error403/index.js +4 -0
  141. package/lib/es/Error404/index.js +4 -0
  142. package/lib/es/ExcelForm/index.js +5 -0
  143. package/lib/es/UploadForm/index.js +5 -0
  144. package/lib/index.d.ts +2 -0
  145. package/lib/webui.css +1 -0
  146. package/lib/webui.es.js +3349 -0
  147. package/package.json +66 -0
  148. package/plugins/vite-plugin-auto-generate-vue.ts +105 -0
  149. package/postcss.config.ts +6 -0
  150. package/src/assets/global.css +9 -0
  151. package/src/components/common/button/index.vue +126 -0
  152. package/src/components/common/icon/appicon.vue +28 -0
  153. package/src/components/common/icon/fullscreen.vue +13 -0
  154. package/src/components/common/icon/helper.vue +30 -0
  155. package/src/components/common/icon/index.vue +426 -0
  156. package/src/components/common/icon/layoutIcon.vue +33 -0
  157. package/src/components/common/icon/projectIcon.vue +41 -0
  158. package/src/components/common/icon/toolIcon.vue +33 -0
  159. package/src/components/common/index.ts +19 -0
  160. package/src/components/common/tooltip/index.vue +25 -0
  161. package/src/components/content/dialog/excelForm.vue +479 -0
  162. package/src/components/content/dialog/index.vue +149 -0
  163. package/src/components/content/dialog/uploadForm.vue +228 -0
  164. package/src/components/content/drawer/index.vue +93 -0
  165. package/src/components/content/form/formItem.vue +76 -0
  166. package/src/components/content/form/index.vue +48 -0
  167. package/src/components/content/index.ts +32 -0
  168. package/src/components/content/search/index.vue +135 -0
  169. package/src/components/content/search/searchItem.vue +52 -0
  170. package/src/components/content/table/index.vue +215 -0
  171. package/src/components/content/table/tableOperate.vue +131 -0
  172. package/src/components/content/toolbar/icontool.vue +151 -0
  173. package/src/components/content/toolbar/index.vue +107 -0
  174. package/src/components/content/tree/index.vue +140 -0
  175. package/src/components/error/error403.vue +14 -0
  176. package/src/components/error/error404.vue +14 -0
  177. package/src/components/form/aceEditor/aceConfig.ts +90 -0
  178. package/src/components/form/aceEditor/index.vue +175 -0
  179. package/src/components/form/autoComplete/index.vue +171 -0
  180. package/src/components/form/cascader/index.vue +110 -0
  181. package/src/components/form/checkbox/index.vue +108 -0
  182. package/src/components/form/datePicker/index.vue +29 -0
  183. package/src/components/form/index.ts +54 -0
  184. package/src/components/form/input/index.vue +70 -0
  185. package/src/components/form/input/inputIcon.vue +39 -0
  186. package/src/components/form/input/inputNumber.vue +23 -0
  187. package/src/components/form/input/inputPassword.vue +22 -0
  188. package/src/components/form/propEditor/index.vue +81 -0
  189. package/src/components/form/radio/index.vue +132 -0
  190. package/src/components/form/radio/radioStatus.vue +42 -0
  191. package/src/components/form/rangePicker/index.vue +64 -0
  192. package/src/components/form/select/index.vue +186 -0
  193. package/src/components/form/switch/index.vue +58 -0
  194. package/src/components/form/textarea/index.vue +23 -0
  195. package/src/components/form/transfer/index.vue +95 -0
  196. package/src/components/form/transfer/transferTable.vue +124 -0
  197. package/src/components/form/treeSelect/index.vue +108 -0
  198. package/src/components/form/upload/uploadList.vue +235 -0
  199. package/src/components/index.ts +97 -0
  200. package/src/components/layout/breadcrumb/index.vue +38 -0
  201. package/src/components/layout/content/index.vue +28 -0
  202. package/src/components/layout/datetime/index.vue +16 -0
  203. package/src/components/layout/header/headerExits.vue +28 -0
  204. package/src/components/layout/header/index.vue +43 -0
  205. package/src/components/layout/index.ts +16 -0
  206. package/src/components/layout/menu/index.vue +64 -0
  207. package/src/components/layout/menu/menuTabs.vue +56 -0
  208. package/src/components/layout/page/basicLayout.vue +67 -0
  209. package/src/vite-env.d.ts +8 -0
  210. package/tailwind.config.ts +11 -0
  211. package/tsconfig.json +53 -0
  212. package/vite.config.ts +117 -0
  213. package//344/273/243/347/240/201/350/247/204/350/214/203/345/217/212/351/243/216/346/240/274/346/214/207/345/215/227.md +116 -0
@@ -0,0 +1,235 @@
1
+ <script setup lang="ts">
2
+ import { Button } from '../../common';
3
+ import { computed, ref, watch } from 'vue';
4
+ import message from 'vue-m-message';
5
+ import type { UploadProps } from 'ant-design-vue';
6
+ import { Upload, Progress, Tag } from 'ant-design-vue';
7
+ import { UploadFile, UploadStatus, donwloadFromMinio, path } from '@skyfox2000/webbase';
8
+ import { IUrlInfo } from '@skyfox2000/fapi';
9
+
10
+ export interface UploadListProps {
11
+ /**
12
+ * 是否自动上传
13
+ */
14
+ autoUpload?: boolean;
15
+ /*
16
+ * 下载Url
17
+ */
18
+ downloadUrl: IUrlInfo;
19
+ /**
20
+ * 文件列表
21
+ */
22
+ fileList: UploadFile<any>[];
23
+ /**
24
+ * 提示文字
25
+ */
26
+ placeholder?: string;
27
+ /**
28
+ * 文件后缀列表
29
+ */
30
+ fileExt?: string[];
31
+ /**
32
+ * 最大文件大小
33
+ */
34
+ maxFileSize?: number;
35
+ /**
36
+ * 最大数量
37
+ */
38
+ maxCount?: number;
39
+ /**
40
+ * 文件路径
41
+ */
42
+ parentPath?: string;
43
+ }
44
+
45
+ const props = withDefaults(defineProps<UploadListProps>(), {
46
+ autoUpload: false,
47
+ fileList: () => [],
48
+ placeholder: '',
49
+ maxFileSize: 20,
50
+ maxCount: 5,
51
+ });
52
+
53
+ const fileList = ref<UploadFile[]>(props.fileList);
54
+ const fileUploader = ref();
55
+ const emit = defineEmits(['update:file-list']);
56
+
57
+ const acceptString = computed(() => (props.fileExt?.length ? props.fileExt.map((ext) => `.${ext}`).join(',') : ''));
58
+
59
+ const beforeUpload: UploadProps['beforeUpload'] = (file) => {
60
+ if (props.fileExt && props.fileExt.length > 0) {
61
+ const extension = file.name.split('.').pop()?.toLowerCase() || '';
62
+ if (!props.fileExt.includes(extension)) {
63
+ message.error('文件类型不支持');
64
+ return false;
65
+ }
66
+ }
67
+
68
+ if (file.size / 1024 / 1024 > props.maxFileSize) {
69
+ message.error(`文件大小超过 ${props.maxFileSize}MB 限制`);
70
+ return false;
71
+ }
72
+
73
+ if (props.maxCount > 1 && fileList.value.length >= props.maxCount) {
74
+ message.error(`最多上传 ${props.maxCount} 个文件`);
75
+ return false;
76
+ }
77
+
78
+ return props.autoUpload;
79
+ };
80
+
81
+ const updateFileList: UploadProps['onUpdate:fileList'] = (fileList) => {
82
+ fileList.forEach((file) => {
83
+ if (!file.fileName) file.fileName = file.name;
84
+ if (props.parentPath) file.name = path.join('/', props.parentPath, file.fileName);
85
+ });
86
+ };
87
+
88
+ const uploadProps = computed<UploadProps>(() => ({
89
+ accept: acceptString.value,
90
+ multiple: true,
91
+ fileList: fileList.value as UploadProps['fileList'],
92
+ 'onUpdate:fileList': updateFileList,
93
+ beforeUpload: beforeUpload,
94
+ listType: 'text',
95
+ maxCount: props.maxCount,
96
+ showUploadList: false,
97
+ onChange: (info) => {
98
+ if (!props.autoUpload) {
99
+ fileList.value = info.fileList as unknown as UploadFile[];
100
+ }
101
+ },
102
+ }));
103
+
104
+ watch(
105
+ () => fileList.value,
106
+ (newVal) => {
107
+ emit('update:file-list', newVal);
108
+ },
109
+ { deep: true },
110
+ );
111
+
112
+ const downloadFile = (index: number) => {
113
+ const fileInfo = fileList.value[index].minioFile!;
114
+ const url: IUrlInfo = {
115
+ api: props.downloadUrl.api,
116
+ authorize: props.downloadUrl.authorize,
117
+ url: props.downloadUrl.url,
118
+ // url: props.pageData.urls.download!.url,
119
+ params: {
120
+ Query: {
121
+ FileKey: fileInfo.Key,
122
+ },
123
+ },
124
+ };
125
+
126
+ donwloadFromMinio(url);
127
+ };
128
+
129
+ const onlineOrOffline = (file: UploadFile) => {
130
+ file.status = file.status === UploadStatus.Offline ? UploadStatus.Online : UploadStatus.Offline;
131
+ file.minioFile!.Status = file.status;
132
+ };
133
+
134
+ // const previewFile = (index: number) => {
135
+ // const fileInfo = fileList.value[index].minioFile;
136
+ // console.log(fileInfo);
137
+ // };
138
+
139
+ const removeFile = (index: number) => {
140
+ fileList.value.splice(index, 1);
141
+ };
142
+
143
+ const getPlaceholder = (): string => {
144
+ const typeMsg = props.fileExt && props.fileExt.length ? `文件必须为 ${props.fileExt.join('/')}` : '';
145
+ const sizeMsg = props.maxFileSize !== 0 ? `单文件最大 ${props.maxFileSize}MB` : '';
146
+ const countMsg = props.maxCount !== 0 ? `最多 ${props.maxCount} 个文件` : '';
147
+
148
+ return [sizeMsg, typeMsg, countMsg].filter(Boolean).join(',');
149
+ };
150
+
151
+ const getStatusColor = (status?: UploadStatus) => {
152
+ switch (status) {
153
+ case UploadStatus.Uploading:
154
+ return 'blue';
155
+ case UploadStatus.Success:
156
+ return 'green';
157
+ case UploadStatus.Error:
158
+ return 'red';
159
+ case UploadStatus.Online:
160
+ return 'green';
161
+ case UploadStatus.Offline:
162
+ return 'pink';
163
+ default:
164
+ return 'cyan';
165
+ }
166
+ };
167
+ const getStatus = (status?: UploadStatus) => {
168
+ switch (status) {
169
+ case UploadStatus.Uploading:
170
+ return '上传中';
171
+ case UploadStatus.Success:
172
+ return '已完成';
173
+ case UploadStatus.Error:
174
+ return '上传失败';
175
+ case UploadStatus.Online:
176
+ return '在线';
177
+ case UploadStatus.Offline:
178
+ return '已下线';
179
+ default:
180
+ return '待上传';
181
+ }
182
+ };
183
+ </script>
184
+
185
+ <template>
186
+ <div class="w-full border border-solid border-gray-100 mt-1 rounded-md py-5">
187
+ <div class="flex items-center justify-between w-full">
188
+ <div class="w-35 mx-3">
189
+ <Upload ref="fileUploader" v-bind="uploadProps">
190
+ <Button>选择文件</Button>
191
+ </Upload>
192
+ </div>
193
+ <div class="flex-1 text-sm text-gray-500">{{ getPlaceholder() }}</div>
194
+ <!-- <Button v-if="!autoUpload" @click="manualUpload" class="mr-3">开始上传</Button> -->
195
+ </div>
196
+
197
+ <div class="mt-4 px-3">
198
+ <div v-for="(file, index) in fileList" :key="index" class="mb-2 pb-1">
199
+ <div class="flex items-center justify-between">
200
+ <div class="flex items-center">
201
+ <span
202
+ class="text-gray-700 mr-2"
203
+ :class="[file.status == UploadStatus.Offline ? 'line-through' : '']"
204
+ >{{ file.fileName ?? file.name }}</span
205
+ >
206
+ <span>
207
+ <Tag :color="getStatusColor(file.status)">{{ getStatus(file.status) }}</Tag>
208
+ </span>
209
+ </div>
210
+ <div class="flex items-center">
211
+ <span
212
+ class="text-blue-500 hover:text-blue-700 mr-4 cursor-pointer"
213
+ v-if="file.status == UploadStatus.Offline || file.status == UploadStatus.Online"
214
+ @click="onlineOrOffline(file)"
215
+ >{{ file.status == UploadStatus.Offline ? '上线' : '下线' }}</span
216
+ >
217
+ <span
218
+ v-if="file.status == UploadStatus.Offline || file.status == UploadStatus.Online"
219
+ class="text-blue-500 hover:text-blue-700 mr-4 cursor-pointer"
220
+ @click="downloadFile(index)"
221
+ >下载</span
222
+ >
223
+ <!-- <span class="text-blue-500 hover:text-blue-700 mr-4" @click="previewFile(index)">预览</span> -->
224
+ <span class="text-red-500 hover:text-red-700 cursor-pointer" @click="removeFile(index)">删除</span>
225
+ </div>
226
+ </div>
227
+
228
+ <!-- 上传进度条 -->
229
+ <div>
230
+ <Progress :percent="file.percent" :stroke-width="2" :show-info="false" style="height: 2px"></Progress>
231
+ </div>
232
+ </div>
233
+ </div>
234
+ </div>
235
+ </template>
@@ -0,0 +1,97 @@
1
+ import '../assets/global.css';
2
+
3
+ import { Button, Tooltip, AppIcon, Fullscreen, Helper, Icon, LayoutIcon, ProjectIcon, ToolIcon } from './common';
4
+ import {
5
+ Dialog,
6
+ UploadForm,
7
+ ExcelForm,
8
+ Drawer,
9
+ Form,
10
+ FormItem,
11
+ Search,
12
+ SearchItem,
13
+ Table,
14
+ TableOperate,
15
+ Toolbar,
16
+ Icontool,
17
+ Tree,
18
+ } from './content';
19
+ import {
20
+ AutoComplete,
21
+ Cascader,
22
+ Checkbox,
23
+ DatePicker,
24
+ Input,
25
+ InputIcon,
26
+ InputPassword,
27
+ InputNumber,
28
+ PropEditor,
29
+ Radio,
30
+ RadioStatus,
31
+ RangePicker,
32
+ Select,
33
+ Switch,
34
+ Textarea,
35
+ Transfer,
36
+ TransferTable,
37
+ TreeSelect,
38
+ UploadList,
39
+ } from './form';
40
+
41
+ import { Breadcrumb, Content, Datetime, Header, HeaderExits, Menu, MenuTabs, BasicLayout } from './layout';
42
+
43
+ export {
44
+ Button,
45
+ Tooltip,
46
+ AppIcon,
47
+ Fullscreen,
48
+ Helper,
49
+ Icon,
50
+ LayoutIcon,
51
+ ProjectIcon,
52
+ ToolIcon,
53
+ Dialog,
54
+ UploadForm,
55
+ ExcelForm,
56
+ Drawer,
57
+ Form,
58
+ FormItem,
59
+ Search,
60
+ SearchItem,
61
+ Table,
62
+ TableOperate,
63
+ Toolbar,
64
+ Icontool,
65
+ Tree,
66
+ AutoComplete,
67
+ Cascader,
68
+ Checkbox,
69
+ DatePicker,
70
+ Input,
71
+ InputIcon,
72
+ InputPassword,
73
+ InputNumber,
74
+ PropEditor,
75
+ Radio,
76
+ RadioStatus,
77
+ RangePicker,
78
+ Select,
79
+ Switch,
80
+ Textarea,
81
+ Transfer,
82
+ TransferTable,
83
+ TreeSelect,
84
+ UploadList,
85
+ Breadcrumb,
86
+ Content,
87
+ Datetime,
88
+ Header,
89
+ HeaderExits,
90
+ Menu,
91
+ MenuTabs,
92
+ BasicLayout,
93
+ };
94
+
95
+ import Error403 from './error/error403.vue';
96
+ import Error404 from './error/error404.vue';
97
+ export { Error403, Error404 };
@@ -0,0 +1,38 @@
1
+ <script setup lang="ts">
2
+ import { onMounted, watch } from 'vue';
3
+ import { Breadcrumb, theme } from 'ant-design-vue';
4
+ import { ToolIcon } from '../../common';
5
+ import { BreadcrumbRoute, showBreadcrumb, crumbs, usePageInfo } from '@skyfox2000/webbase';
6
+
7
+ const { useToken } = theme;
8
+ const { token } = useToken();
9
+
10
+ const pageInfoStore = usePageInfo();
11
+ watch(
12
+ () => pageInfoStore.TabActive,
13
+ () => showBreadcrumb(),
14
+ );
15
+ onMounted(() => {
16
+ showBreadcrumb();
17
+ });
18
+ </script>
19
+ <template>
20
+ <div
21
+ class="ml-5 h-fit p-0 flex items-center justify-between"
22
+ :style="{
23
+ backgroundColor: token.colorBgContainer,
24
+ }"
25
+ >
26
+ <ToolIcon icon="icon-home" class="w-[15px] h-[15px]" />
27
+ <span class="leading-[2.5] mx-[6px] text-[rgba(0,0,0,0.45)]">&gt;</span>
28
+ <Breadcrumb :routes="crumbs" separator="">
29
+ <template #itemRender="{ route }: { route: BreadcrumbRoute }">
30
+ <span class="text-xs leading-[3]">{{ route.breadcrumbName }}</span>
31
+ <ToolIcon :icon="route.icon" fontsize="15px" />
32
+ <span v-if="route.index! < crumbs.length - 1" class="leading-[2.5] mx-[6px] text-[rgba(0,0,0,0.45)]"
33
+ >&gt;</span
34
+ >
35
+ </template>
36
+ </Breadcrumb>
37
+ </div>
38
+ </template>
@@ -0,0 +1,28 @@
1
+ <script lang="ts" setup>
2
+ import { LayoutContent, theme } from 'ant-design-vue';
3
+ const { useToken } = theme;
4
+ const { token } = useToken();
5
+
6
+ defineProps<{
7
+ left?: boolean;
8
+ }>();
9
+ </script>
10
+ <template>
11
+ <div class="relative h-[calc(100vh-80px)] overflow-y-auto">
12
+ <LayoutContent
13
+ class="m-[10px] p-[10px] h-[calc(100vh-100px)] !min-h-[calc(100vh-100px)]"
14
+ :style="{
15
+ backgroundColor: token.colorBgContainer,
16
+ }"
17
+ >
18
+ <div class="flex w-full h-full min-h-full">
19
+ <div class="w-1/4 pr-4 min-h-full min-w-[170px] max-w-[200px]" v-if="left">
20
+ <slot name="left"></slot>
21
+ </div>
22
+ <div class="flex-1 h-full overflow-y-auto">
23
+ <slot></slot>
24
+ </div>
25
+ </div>
26
+ </LayoutContent>
27
+ </div>
28
+ </template>
@@ -0,0 +1,16 @@
1
+ <script lang="ts" setup>
2
+ import { ref, onMounted } from 'vue'
3
+ const DateTime = ref("")
4
+ onMounted(() => {
5
+ setInterval(() => {
6
+ const curTime = new Date()
7
+ const options: any = { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' };
8
+ const formattedTime = curTime.toLocaleString(undefined, options).replace(/\//g, '-').replace(',', '');
9
+ DateTime.value = curTime.getFullYear() + "-" + formattedTime
10
+ }, 1000);
11
+ })
12
+ </script>
13
+
14
+ <template>
15
+ <div class="font-['Courier'] text-[#666]">{{ DateTime }}</div>
16
+ </template>
@@ -0,0 +1,28 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue';
3
+ import { Modal, Flex } from 'ant-design-vue';
4
+ import { useUserInfo } from '@skyfox2000/webbase';
5
+ import { mainAppApis } from '@skyfox2000/microbase';
6
+ import { ToolIcon } from '../../common';
7
+
8
+ const userInfoStore = useUserInfo();
9
+
10
+ const open = ref(false);
11
+ const confirmExit = () => {
12
+ open.value = false;
13
+ if (mainAppApis.value) {
14
+ mainAppApis.value.userLogout!();
15
+ } else {
16
+ userInfoStore.logout();
17
+ }
18
+ };
19
+ </script>
20
+ <template>
21
+ <ToolIcon icon="icon-logout" @click="open = true" clickable class="w-5 h-5" />
22
+ <Modal v-model:open="open" title="确定退出?" ok-text="确定" cancel-text="取消" :width="380" @ok="confirmExit">
23
+ <Flex align="center" justify="flex-start" :style="{ padding: '0 32px', margin: '20px 0' }">
24
+ <ToolIcon icon="icon-question-circle" color="orange" class="w-[60px] h-[60px]" />
25
+ <div style="margin: 0 0 0 20px; font-weight: 400; font-size: 16px">是否退出系统,<br />清除用户缓存信息?</div>
26
+ </Flex>
27
+ </Modal>
28
+ </template>
@@ -0,0 +1,43 @@
1
+ <script lang="ts" setup>
2
+ import { LayoutHeader, Avatar, theme, Space } from 'ant-design-vue';
3
+ import { useSettingInfo } from '@skyfox2000/webbase';
4
+ import { ToolIcon } from '../../common';
5
+ import Breadcrumb from '../breadcrumb/index.vue';
6
+ import HeaderExits from './headerExits.vue';
7
+
8
+ const { useToken } = theme;
9
+ const { token } = useToken();
10
+
11
+ const settingInfoStore = useSettingInfo();
12
+ const onCollapseClick = () => {
13
+ settingInfoStore.setMenuCollapse(!settingInfoStore.menuCollapse);
14
+ };
15
+ </script>
16
+ <template>
17
+ <LayoutHeader
18
+ class="w-full relative z-[1] shadow-[0_-3px_6px_#000] py-0 flex items-center justify-between"
19
+ :style="{
20
+ height: '40px',
21
+ lineHeight: '1',
22
+ paddingLeft: '10px',
23
+ paddingRight: '10px',
24
+ backgroundColor: token.colorBgContainer,
25
+ }"
26
+ >
27
+ <div class="flex items-center">
28
+ <ToolIcon
29
+ icon="icon-menu"
30
+ class="w-[18px] h-[18px] cursor-pointer"
31
+ :angle="settingInfoStore.menuCollapse ? 90 : 0"
32
+ @click="onCollapseClick"
33
+ />
34
+ <Breadcrumb></Breadcrumb>
35
+ </div>
36
+ <div>
37
+ <Space size="middle" class="flex items-center">
38
+ <Avatar class="avatar" :style="{ backgroundColor: '#f56a00', fontSize: '14px' }" :size="24"> U </Avatar>
39
+ <HeaderExits />
40
+ </Space>
41
+ </div>
42
+ </LayoutHeader>
43
+ </template>
@@ -0,0 +1,16 @@
1
+ import Breadcrumb from './breadcrumb/index.vue';
2
+ export { Breadcrumb };
3
+ import Content from './content/index.vue';
4
+ export { Content };
5
+ import Datetime from './datetime/index.vue';
6
+ export { Datetime };
7
+ import Header from './header/index.vue';
8
+ export { Header };
9
+ import HeaderExits from './header/headerExits.vue';
10
+ export { HeaderExits };
11
+ import Menu from './menu/index.vue';
12
+ export { Menu };
13
+ import MenuTabs from './menu/menuTabs.vue';
14
+ export { MenuTabs };
15
+ import BasicLayout from './page/basicLayout.vue';
16
+ export { BasicLayout };
@@ -0,0 +1,64 @@
1
+ <script lang="ts" setup>
2
+ import { nextTick, onMounted, reactive, ref, watch } from 'vue';
3
+ import { ItemType, Menu } from 'ant-design-vue';
4
+ import type { MenuProps } from 'ant-design-vue';
5
+ import { AppRouter, initMenu, useSettingInfo, useAppInfo, usePageInfo } from '@skyfox2000/webbase';
6
+
7
+ import { ProjectIcon } from '../../common';
8
+
9
+ const props = defineProps<{ routes: any }>();
10
+
11
+ const openKeys = ref<string[]>([]);
12
+ const selectedKeys = ref<string[]>([]);
13
+
14
+ // 转换为树形结构
15
+ const menuData: Array<ItemType> = reactive([]);
16
+
17
+ const pageInfoStore = usePageInfo();
18
+ const onMenuClick: MenuProps['onClick'] = (menuInfo) => {
19
+ useAppInfo().push(menuInfo.key.toString());
20
+ };
21
+
22
+ const settingInfoStore = useSettingInfo();
23
+ const showOpenKeys = ref<string[]>([]);
24
+ const activeMenu = () => {
25
+ let subPath = pageInfoStore.TabActive;
26
+ const paths = subPath.split('/');
27
+ paths.pop();
28
+ openKeys.value = [paths.join('/')];
29
+ if (!settingInfoStore.menuCollapse) {
30
+ showOpenKeys.value = [paths.join('/')];
31
+ }
32
+ selectedKeys.value = [subPath];
33
+ };
34
+
35
+ watch(
36
+ () => settingInfoStore.menuCollapse,
37
+ (newVal) => {
38
+ if (!newVal) {
39
+ showOpenKeys.value = [];
40
+ nextTick(() => {
41
+ showOpenKeys.value = [...openKeys.value];
42
+ });
43
+ }
44
+ },
45
+ );
46
+ watch(
47
+ () => pageInfoStore.TabActive,
48
+ () => {
49
+ activeMenu();
50
+ },
51
+ );
52
+
53
+ onMounted(() => {
54
+ initMenu<ItemType>(props.routes, menuData, ProjectIcon, { class: '!w-5 !h-5' });
55
+ pageInfoStore.setTabActive(AppRouter.currentRoute.value.path);
56
+
57
+ activeMenu();
58
+ });
59
+ </script>
60
+ <template>
61
+ <Menu v-model:openKeys="showOpenKeys" v-model:selectedKeys="selectedKeys" mode="inline" theme="dark"
62
+ :items="menuData" @click="onMenuClick">
63
+ </Menu>
64
+ </template>
@@ -0,0 +1,56 @@
1
+ <script setup lang="ts">
2
+ import { Tabs, TabPane, theme } from 'ant-design-vue';
3
+ import { useAppInfo, usePageInfo } from '@skyfox2000/webbase';
4
+
5
+ import { ToolIcon, Tooltip } from '../../common';
6
+
7
+ const { useToken } = theme;
8
+ const { token } = useToken();
9
+
10
+ const pageInfoStore = usePageInfo();
11
+
12
+ const onTabClicked = (tabKey: any) => {
13
+ useAppInfo().push(tabKey as string);
14
+ };
15
+
16
+ const closeTab = (key: string) => {
17
+ pageInfoStore.removeTabPane(key);
18
+ useAppInfo().push(pageInfoStore.TabActive);
19
+ };
20
+ </script>
21
+ <template>
22
+ <div :style="{ height: '38px', backgroundColor: token.colorBgBase }">
23
+ <Tabs
24
+ :activeKey="pageInfoStore.TabActive"
25
+ hide-add
26
+ size="small"
27
+ :tabBarStyle="{ padding: '0 20px' }"
28
+ @tabClick="onTabClicked"
29
+ >
30
+ <TabPane v-for="pane in pageInfoStore.TabPanes" :key="pane.key">
31
+ <template #tab>
32
+ <div class="flex items-center">
33
+ <span class="flex">
34
+ {{ pane.title }}
35
+ </span>
36
+ <Tooltip title="关闭" placement="top" size="small">
37
+ <div
38
+ class="inline-block mx-auto relative flex items-center"
39
+ v-if="pageInfoStore.TabPanes.length > 1 && pane.closable"
40
+ @click.stop="closeTab(pane.key)"
41
+ >
42
+ <ToolIcon
43
+ icon="icon-new"
44
+ :angle="45"
45
+ clickable
46
+ class="w-[15px] h-[15px] ml-1"
47
+ :tipcolor="token.colorBgSpotlight"
48
+ />
49
+ </div>
50
+ </Tooltip>
51
+ </div>
52
+ </template>
53
+ </TabPane>
54
+ </Tabs>
55
+ </div>
56
+ </template>