9696 </el-drawer >
9797
9898 <!-- 导出版本抽屉 -->
99- <el-drawer v-model =" exportDialogVisible" title =" 创建发版" direction =" rtl" size =" 80%" :before-close =" closeExportDialog" :show-close =" false" >
99+ <el-drawer v-model =" exportDialogVisible" title =" 创建发版" direction =" rtl" size =" 80%" :before-close =" closeExportDialog"
100+ :show-close =" false" >
100101 <template #header >
101102 <div class =" flex justify-between items-center" >
102103 <span class =" text-lg" >创建发版</span >
119120 <el-form-item label =" 发版信息" >
120121 <div class =" flex gap-3 w-full" >
121122 <!-- 菜单选择 -->
122- <div class =" flex flex -col border border-gray-300 rounded overflow-hidden h-full flex-1 w-1/3 " >
123- <div class =" flex justify-between items-center px-4 py-3 bg-gray-50 border-b border-gray-300 " >
124- <span class =" m-0 text-gray-800 text-base font-medium " >选择菜单</span >
123+ <div class =" card -col card-vertical " >
124+ <div class =" card-header " >
125+ <span class =" card-title " >选择菜单</span >
125126 </div >
126- <div class =" px-4 py-3 border-b border-gray-300 bg-gray-50 " >
127+ <div class =" card-filter " >
127128 <el-input v-model =" menuFilterText" placeholder =" 输入关键字进行过滤" clearable size =" small" />
128129 </div >
129- <div class =" flex-1 p-2 min-h-[300px] max-h-[400px] overflow-y-auto " >
130+ <div class =" card-body " >
130131 <el-tree ref =" menuTreeRef" :data =" menuTreeData" :default-checked-keys =" selectedMenuIds"
131132 :props =" menuTreeProps" default-expand-all highlight-current node-key =" ID" show-checkbox
132133 :filter-node-method =" filterMenuNode" @check =" onMenuCheck" class =" menu-tree" >
140141 </div >
141142
142143 <!-- API选择 -->
143- <div class =" flex flex -col border border-gray-300 rounded overflow-hidden h-full flex-1 w-1/3 " >
144- <div class =" flex justify-between items-center px-4 py-3 bg-gray-50 border-b border-gray-300 " >
145- <span class =" m-0 text-gray-800 text-base font-medium " >选择API</span >
144+ <div class =" card -col card-vertical " >
145+ <div class =" card-header " >
146+ <span class =" card-title " >选择API</span >
146147 </div >
147- <div class =" px-4 py-3 border-b border-gray-300 bg-gray-50 " >
148+ <div class =" card-filter " >
148149 <el-input v-model =" apiFilterTextName" placeholder =" 按名称过滤" clearable size =" small"
149150 style =" margin-bottom : 8px " />
150151 <el-input v-model =" apiFilterTextPath" placeholder =" 按路径过滤" clearable size =" small" />
151152 </div >
152- <div class =" flex-1 p-2 min-h-[300px] max-h-[400px] overflow-y-auto " >
153+ <div class =" card-body " >
153154 <el-tree ref =" apiTreeRef" :data =" apiTreeData" :default-checked-keys =" selectedApiIds"
154155 :props =" apiTreeProps" default-expand-all highlight-current node-key =" onlyId" show-checkbox
155156 :filter-node-method =" filterApiNode" @check =" onApiCheck" class =" api-tree" >
156157 <template #default =" { data } " >
157158 <div class =" flex items-center justify-between w-full pr-1" >
158159 <span >{{ data.description }}</span >
159160 <el-tooltip :content =" data.path" >
160- <span class =" max-w-[240px] break-all overflow-ellipsis overflow-hidden" >
161+ <span
162+ class =" max-w-[240px] break-all overflow-ellipsis overflow-hidden text-gray-500 dark:text-gray-400" >
161163 {{ data.path }}
162164 </span >
163165 </el-tooltip >
168170 </div >
169171
170172 <!-- 字典选择 -->
171- <div class =" flex flex -col border border-gray-300 rounded overflow-hidden h-full flex-1 w-1/3 " >
172- <div class =" flex justify-between items-center px-4 py-3 bg-gray-50 border-b border-gray-300 " >
173- <span class =" m-0 text-gray-800 text-base font-medium " >选择字典</span >
173+ <div class =" card -col card-vertical " >
174+ <div class =" card-header " >
175+ <span class =" card-title " >选择字典</span >
174176 </div >
175- <div class =" px-4 py-3 border-b border-gray-300 bg-gray-50 " >
177+ <div class =" card-filter " >
176178 <el-input v-model =" dictFilterText" placeholder =" 输入关键字进行过滤" clearable size =" small" />
177179 </div >
178- <div class =" flex-1 p-2 min-h-[300px] max-h-[400px] overflow-y-auto " >
180+ <div class =" card-body " >
179181 <el-tree ref =" dictTreeRef" :data =" dictTreeData" :default-checked-keys =" selectedDictIds"
180182 :props =" dictTreeProps" default-expand-all highlight-current node-key =" ID" show-checkbox
181183 :filter-node-method =" filterDictNode" @check =" onDictCheck" class =" dict-tree" >
182184 <template #default =" { data } " >
183185 <div class =" flex items-center justify-between w-full pr-1" >
184186 <span >{{ data.name || data.label }}</span >
185187 <el-tooltip :content =" data.desc || (data.value ? `值: ${data.value}` : '')" >
186- <span class =" text-gray-500 text-xs ml-2" >
188+ <span class =" text-gray-500 dark:text-gray-400 text-xs ml-2" >
187189 {{ data.type || (data.value ? `值: ${data.value}` : '') }}
188190 </span >
189191 </el-tooltip >
198200 </el-drawer >
199201
200202 <!-- 导入版本抽屉 -->
201- <el-drawer v-model =" importDialogVisible" title =" 导入版本" direction =" rtl" size =" 80%" :before-close =" closeImportDialog" :show-close =" false" >
203+ <el-drawer v-model =" importDialogVisible" title =" 导入版本" direction =" rtl" size =" 80%" :before-close =" closeImportDialog"
204+ :show-close =" false" >
202205 <template #header >
203206 <div class =" flex justify-between items-center" >
204207 <span class =" text-lg" >导入版本</span >
211214 </template >
212215 <el-form label-width =" 100px" >
213216 <el-form-item label =" 上传文件" >
214- <el-upload
215- ref =" uploadRef"
216- :auto-upload =" false"
217- :show-file-list =" true"
218- :limit =" 1"
219- accept =" .json"
220- :on-change =" handleFileChange"
221- :on-remove =" handleFileRemove"
222- drag
223- >
217+ <el-upload ref =" uploadRef" :auto-upload =" false" :show-file-list =" true" :limit =" 1" accept =" .json"
218+ :on-change =" handleFileChange" :on-remove =" handleFileRemove" drag >
224219 <el-icon class =" el-icon--upload" ><upload-filled /></el-icon >
225220 <div class =" el-upload__text" >
226221 将JSON文件拖到此处,或<em >点击上传</em >
237232 @input =" handleJsonContentChange" />
238233 </el-form-item >
239234 <el-form-item label =" 预览内容" v-if =" importPreviewData" >
240- <div class =" flex flex-col flex-1 gap-4 border border-gray-300 rounded p-4 bg-gray-50 " >
235+ <div class =" preview-wrap " >
241236 <div class =" flex gap-3 w-full" >
242- <div class =" border border-gray-300 rounded overflow-hidden flex-1 w-1/3 " >
243- <div class =" flex flex-col border border-gray-300 rounded overflow-hidden h-full " >
244- <div class =" flex justify-between items-center px-4 py-3 bg-gray-50 border-b border-gray-300 " >
245- <h3 class =" m-0 text-gray-800 text-base font-medium " >菜单 ({{ getTotalMenuCount() }}项)</h3 >
237+ <div class =" card-col " >
238+ <div class =" card-vertical " >
239+ <div class =" card-header " >
240+ <h3 class =" card-title " >菜单 ({{ getTotalMenuCount() }}项)</h3 >
246241 </div >
247- <div class =" flex-1 p-2 min-h-[300px] max-h-[400px] overflow-y-auto" >
248- <el-tree
249- :data =" previewMenuTreeData"
250- :props =" menuTreeProps"
251- node-key =" name"
252- :expand-on-click-node =" false"
253- :check-on-click-node =" false"
254- :show-checkbox =" false"
255- default-expand-all
256- >
242+ <div class =" card-body" >
243+ <el-tree :data =" previewMenuTreeData" :props =" menuTreeProps" node-key =" name"
244+ :expand-on-click-node =" false" :check-on-click-node =" false" :show-checkbox =" false"
245+ default-expand-all >
257246 <template #default =" { data } " >
258247 <div class =" flex-1 flex items-center justify-between text-sm pr-2" >
259248 <span >{{ data.meta?.title || data.title }}</span >
260- <span class =" text-gray-500 text-xs ml-2" >{{ data.path }}</span >
249+ <span class =" text-gray-500 dark:text-gray-400 text-xs ml-2" >{{ data.path }}</span >
261250 </div >
262251 </template >
263252 </el-tree >
264253 </div >
265254 </div >
266255 </div >
267- <div class =" border border-gray-300 rounded overflow-hidden flex-1 w-1/3 " >
268- <div class =" flex flex-col border border-gray-300 rounded overflow-hidden h-full " >
269- <div class =" flex justify-between items-center px-4 py-3 bg-gray-50 border-b border-gray-300 " >
270- <h3 class =" m-0 text-gray-800 text-base font-medium " >API ({{ importPreviewData.apis?.length || 0 }}项)</h3 >
256+ <div class =" card-col " >
257+ <div class =" card-vertical " >
258+ <div class =" card-header " >
259+ <h3 class =" card-title " >API ({{ importPreviewData.apis?.length || 0 }}项)</h3 >
271260 </div >
272- <div class =" flex-1 p-2 min-h-[300px] max-h-[400px] overflow-y-auto" >
273- <el-tree
274- :data =" previewApiTreeData"
275- :props =" apiTreeProps"
276- node-key =" ID"
277- :expand-on-click-node =" false"
278- :check-on-click-node =" false"
279- :show-checkbox =" false"
280- default-expand-all
281- >
261+ <div class =" card-body" >
262+ <el-tree :data =" previewApiTreeData" :props =" apiTreeProps" node-key =" ID"
263+ :expand-on-click-node =" false" :check-on-click-node =" false" :show-checkbox =" false"
264+ default-expand-all >
282265 <template #default =" { data } " >
283266 <div class =" flex-1 flex items-center justify-between text-sm pr-2" >
284267 <span >{{ data.description }}</span >
285- <span class =" text-gray-500 text-xs ml-2" >{{ data.path }} [{{ data.method }}]</span >
268+ <span class =" text-gray-500 dark:text-gray-400 text-xs ml-2" >{{ data.path }} [{{ data.method
269+ }}]</span >
286270 </div >
287271 </template >
288272 </el-tree >
289273 </div >
290274 </div >
291275 </div >
292- <div class =" border border-gray-300 rounded overflow-hidden flex-1 w-1/3 " >
293- <div class =" flex flex-col border border-gray-300 rounded overflow-hidden h-full " >
294- <div class =" flex justify-between items-center px-4 py-3 bg-gray-50 border-b border-gray-300 " >
295- <h3 class =" m-0 text-gray-800 text-base font-medium " >字典 ({{ importPreviewData.dictionaries?.length || 0 }}项)</h3 >
276+ <div class =" card-col " >
277+ <div class =" card-vertical " >
278+ <div class =" card-header " >
279+ <h3 class =" card-title " >字典 ({{ importPreviewData.dictionaries?.length || 0 }}项)</h3 >
296280 </div >
297- <div class =" flex-1 p-2 min-h-[300px] max-h-[400px] overflow-y-auto" >
298- <el-tree
299- :data =" previewDictTreeData"
300- :props =" dictTreeProps"
301- node-key =" ID"
302- :expand-on-click-node =" false"
303- :check-on-click-node =" false"
304- :show-checkbox =" false"
305- default-expand-all
306- >
281+ <div class =" card-body" >
282+ <el-tree :data =" previewDictTreeData" :props =" dictTreeProps" node-key =" ID"
283+ :expand-on-click-node =" false" :check-on-click-node =" false" :show-checkbox =" false"
284+ default-expand-all >
307285 <template #default =" { data } " >
308286 <div class =" flex-1 flex items-center justify-between text-sm pr-2" >
309287 <span >{{ data.name || data.label }}</span >
310- <span class =" text-gray-500 text-xs ml-2" >
288+ <span class =" text-gray-500 dark:text-gray-400 text-xs ml-2" >
311289 {{ data.type || (data.value ? `值: ${data.value}` : '') }}
312290 </span >
313291 </div >
@@ -661,11 +639,11 @@ const filterDictNode = (value, data) => {
661639 const desc = data .desc || ' '
662640 const label = data .label || ' '
663641 const dataValue = data .value || ' '
664- return name .indexOf (value) !== - 1 ||
665- type .indexOf (value) !== - 1 ||
666- desc .indexOf (value) !== - 1 ||
667- label .indexOf (value) !== - 1 ||
668- dataValue .indexOf (value) !== - 1
642+ return name .indexOf (value) !== - 1 ||
643+ type .indexOf (value) !== - 1 ||
644+ desc .indexOf (value) !== - 1 ||
645+ label .indexOf (value) !== - 1 ||
646+ dataValue .indexOf (value) !== - 1
669647}
670648
671649const onMenuCheck = (data , checked ) => {
@@ -789,14 +767,14 @@ const closeImportDialog = () => {
789767// 文件上传处理函数
790768const handleFileChange = (file ) => {
791769 if (! file .raw ) return
792-
770+
793771 // 验证文件类型
794772 if (! file .name .toLowerCase ().endsWith (' .json' )) {
795773 ElMessage .error (' 只能上传JSON文件' )
796774 uploadRef .value .clearFiles ()
797775 return
798776 }
799-
777+
800778 // 读取文件内容
801779 const reader = new FileReader ()
802780 reader .onload = (e ) => {
@@ -825,7 +803,7 @@ const handleFileRemove = () => {
825803// 计算菜单总数(递归计算所有菜单项)
826804const getTotalMenuCount = () => {
827805 if (! importPreviewData .value ? .menus ) return 0
828-
806+
829807 const countMenus = (menus ) => {
830808 let count = 0
831809 menus .forEach (menu => {
@@ -836,7 +814,7 @@ const getTotalMenuCount = () => {
836814 })
837815 return count
838816 }
839-
817+
840818 return countMenus (importPreviewData .value .menus )
841819}
842820
@@ -971,6 +949,35 @@ const downloadJson = async (row) => {
971949< / script>
972950
973951< style scoped>
952+ /* 复用卡片样式(支持暗色) */
953+ .card - col {
954+ @apply border border- gray- 300 dark: border- gray- 600 rounded overflow- hidden flex- 1 bg- white dark: bg- gray- 900 ;
955+ }
956+
957+ .card - vertical {
958+ @apply flex flex- col h- full;
959+ }
960+
961+ .card - header {
962+ @apply flex justify- between items- center px- 4 py- 3 bg- gray- 50 dark: bg- gray- 800 border- b border- gray- 300 dark: border- gray- 600 ;
963+ }
964+
965+ .card - title {
966+ @apply m- 0 text- gray- 800 dark: text- gray- 200 text- base font- medium;
967+ }
968+
969+ .card - filter {
970+ @apply px- 4 py- 3 border- b border- gray- 300 dark: border- gray- 600 bg- gray- 50 dark: bg- gray- 800 ;
971+ }
972+
973+ .card - body {
974+ @apply flex- 1 p- 2 min- h- [300px ] max- h- [400px ] overflow- y- auto;
975+ }
976+
977+ .preview - wrap {
978+ @apply flex flex- col flex- 1 gap- 4 border border- gray- 300 dark: border- gray- 600 rounded p- 4 bg- gray- 50 dark: bg- gray- 900 ;
979+ }
980+
974981/* Element Plus 树形组件样式优化 */
975982: deep (.el - tree ) {
976983 background- color: transparent;
0 commit comments