@befly-addon/admin 1.0.11 → 1.0.13

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/addon.config.json CHANGED
@@ -8,6 +8,5 @@
8
8
  },
9
9
  "keywords": ["admin", "backend", "management"],
10
10
  "entry": "index.ts",
11
- "enabled": true,
12
11
  "license": "MIT"
13
12
  }
@@ -1,13 +1,8 @@
1
- /**
2
- * 获取管理员列表
3
- */
4
-
5
- import { Yes } from 'befly';
1
+ import { Yes } from 'befly';
6
2
 
7
3
  export default {
8
4
  name: '获取管理员列表',
9
5
  handler: async (befly, ctx) => {
10
- // 查询所有管理员(框架自动排除password字段,自动转换字段名为小驼峰)
11
6
  const result = await befly.db.getList({
12
7
  table: 'addon_admin_admin',
13
8
  page: ctx.body.page || 1,
@@ -11,11 +11,8 @@ export default {
11
11
  // 获取数据库版本
12
12
  let databaseVersion = 'Unknown';
13
13
  try {
14
- const versionResult = await befly.db.query({
15
- sql: 'SELECT VERSION() as version',
16
- type: 'one'
17
- });
18
- databaseVersion = versionResult.version || 'Unknown';
14
+ const versionResult = await befly.db.query('SELECT VERSION() as version');
15
+ databaseVersion = versionResult?.[0]?.version || 'Unknown';
19
16
  } catch (error) {
20
17
  // 忽略错误
21
18
  }
package/apis/dict/list.ts CHANGED
@@ -7,10 +7,7 @@ export default {
7
7
  fields: ['id', 'name', 'code', 'value', 'sort', 'pid', 'description', 'state', 'created_at', 'updated_at'],
8
8
  page: ctx.body.page,
9
9
  limit: ctx.body.limit,
10
- orderBy: [
11
- { field: 'sort', direction: 'ASC' },
12
- { field: 'id', direction: 'ASC' }
13
- ]
10
+ orderBy: ['sort#ASC', 'id#ASC']
14
11
  });
15
12
 
16
13
  return Yes('操作成功', result);
package/apis/menu/all.ts CHANGED
@@ -40,7 +40,7 @@ export default {
40
40
  if (allMenus.length === 0) {
41
41
  allMenus = await befly.db.getAll({
42
42
  table: 'addon_admin_menu',
43
- fields: ['id', 'pid', 'name', 'path', 'icon', 'type', 'sort'],
43
+ fields: ['id', 'pid', 'name', 'path', 'icon', 'sort'],
44
44
  orderBy: ['sort#ASC', 'id#ASC']
45
45
  });
46
46
  }
package/apis/menu/list.ts CHANGED
@@ -5,11 +5,8 @@ export default {
5
5
  try {
6
6
  const menus = await befly.db.getAll({
7
7
  table: 'addon_admin_menu',
8
- fields: ['id', 'name', 'path', 'icon', 'sort', 'pid', 'type', 'state', 'created_at', 'updated_at'],
9
- orderBy: [
10
- { field: 'sort', direction: 'ASC' },
11
- { field: 'id', direction: 'ASC' }
12
- ]
8
+ fields: ['id', 'name', 'path', 'icon', 'sort', 'pid', 'state', 'created_at', 'updated_at'],
9
+ orderBy: ['sort#ASC', 'id#ASC']
13
10
  });
14
11
 
15
12
  return Yes('操作成功', menus);
package/apis/menu/upd.ts CHANGED
@@ -14,8 +14,7 @@ export default {
14
14
  path: ctx.body.path,
15
15
  icon: ctx.body.icon,
16
16
  sort: ctx.body.sort,
17
- pid: ctx.body.pid,
18
- type: ctx.body.type
17
+ pid: ctx.body.pid
19
18
  // state 字段不在此处更新,需要禁用/启用时单独处理
20
19
  }
21
20
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@befly-addon/admin",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "Befly - 管理后台功能组件",
5
5
  "type": "module",
6
6
  "private": false,
@@ -38,13 +38,8 @@
38
38
  "url": "https://github.com/chenbimo/befly.git",
39
39
  "directory": "packages/addon-admin"
40
40
  },
41
- "gitHead": "51d86162e5f0b94ecc44a833a98ebf97c27f7bd6",
41
+ "gitHead": "82f9de50d3c014ba80f68556da05dadcdc8d4c92",
42
42
  "dependencies": {
43
- "befly": "3.8.3"
44
- },
45
- "devDependencies": {
46
- "@module-federation/vite": "^1.9.0",
47
- "@vitejs/plugin-vue": "^6.0.1",
48
- "rolldown-vite": "^7.2.2"
43
+ "befly": "3.8.5"
49
44
  }
50
45
  }
package/tables/menu.json CHANGED
@@ -63,18 +63,5 @@
63
63
  "nullable": false,
64
64
  "unsigned": true,
65
65
  "regexp": null
66
- },
67
- "type": {
68
- "name": "菜单类型",
69
- "detail": "",
70
- "type": "number",
71
- "min": 1,
72
- "max": 2,
73
- "default": 1,
74
- "index": true,
75
- "unique": false,
76
- "nullable": false,
77
- "unsigned": true,
78
- "regexp": "^(1|2)$"
79
66
  }
80
67
  }
package/util.ts CHANGED
@@ -1,75 +1,71 @@
1
- /**
2
- * Admin 插件通用工具函数
3
- */
4
-
5
- import { Logger } from 'befly';
6
- import type { BeflyContext } from 'befly/types/befly';
7
- import { readdirSync, statSync, readFileSync } from 'node:fs';
8
- import path from 'node:path';
9
-
10
- /**
11
- * 输出同步统计信息
12
- * @param stats - 统计对象
13
- * @param deletedCount - 删除数量
14
- * @param resourceName - 资源名称(如:菜单、接口)
15
- */
16
- export function logSyncStats(stats: { created: number; updated: number }, deletedCount: number, resourceName: string = '记录'): void {
17
- Logger.info(`\n=== ${resourceName}同步完成 ===`);
18
- Logger.info(`新增${resourceName}: ${stats.created} 个`);
19
- Logger.info(`更新${resourceName}: ${stats.updated} 个`);
20
- Logger.info(`删除${resourceName}: ${deletedCount} 个`);
21
- }
1
+ import type { RouteRecordRaw } from 'vue-router';
22
2
 
23
3
  /**
24
- * 获取插件列表
25
- * @returns 插件列表
4
+ * 自定义布局处理函数
5
+ * 根据文件名后缀判断使用哪个布局
6
+ * @param routes - 原始路由配置
7
+ * @param inheritLayout - 继承的布局名称(来自父级目录)
8
+ * @returns 处理后的路由配置
26
9
  */
27
- export function getAddonList(): Array<{ name: string; title: string; version: string; description: string; enabled: boolean }> {
28
- const addonList: Array<{ name: string; title: string; version: string; description: string; enabled: boolean }> = [];
10
+ export function Layouts(routes: RouteRecordRaw[], inheritLayout = ''): RouteRecordRaw[] {
11
+ const result: RouteRecordRaw[] = [];
29
12
 
30
- // 获取 addons 目录路径
31
- const addonsDir = path.join(process.cwd(), 'addons');
13
+ for (const route of routes) {
14
+ const currentPath = route.path || '';
32
15
 
33
- try {
34
- const addonNames = readdirSync(addonsDir);
16
+ // 检查当前路径是否有 _数字 格式
17
+ const pathMatch = currentPath.match(/_(\d+)$/);
18
+ const currentLayout = pathMatch ? pathMatch[1] : inheritLayout;
35
19
 
36
- for (const addonName of addonNames) {
37
- const addonPath = path.join(addonsDir, addonName);
38
- const stat = statSync(addonPath);
20
+ // 如果有子路由,递归处理(传递当前布局给子级)
21
+ if (route.children && route.children.length > 0) {
22
+ // 清理路径:如果是 xxx_数字 格式,去掉 _数字
23
+ const cleanPath = pathMatch ? currentPath.replace(/_\d+$/, '') : currentPath;
39
24
 
40
- // 只处理目录
41
- if (!stat.isDirectory()) {
42
- continue;
43
- }
25
+ result.push({
26
+ ...route,
27
+ path: cleanPath,
28
+ children: Layouts(route.children, currentLayout)
29
+ });
30
+ continue;
31
+ }
44
32
 
45
- // 读取插件配置文件
46
- const configPath = path.join(addonPath, 'addon.config.json');
33
+ // 没有子路由的叶子节点,需要包裹布局
34
+ const lastPart = currentPath;
47
35
 
48
- try {
49
- const configContent = readFileSync(configPath, 'utf-8');
50
- const config = JSON.parse(configContent);
36
+ // 匹配 _数字 格式(如 index_1, news_2)
37
+ const match = lastPart.match(/_(\d+)$/);
38
+ // 优先使用文件自己的布局,其次使用继承的布局,最后使用 default
39
+ const layoutName = match ? match[1] : currentLayout || 'default';
51
40
 
52
- addonList.push({
53
- name: config.name || addonName,
54
- title: config.title || addonName,
55
- version: config.version || '1.0.0',
56
- description: config.description || '',
57
- enabled: true
58
- });
59
- } catch (error) {
60
- // 配置文件不存在或解析失败,使用默认值
61
- addonList.push({
62
- name: addonName,
63
- title: addonName,
64
- version: '1.0.0',
65
- description: '',
66
- enabled: true
67
- });
68
- }
41
+ // 计算清理后的路径
42
+ let cleanPath: string;
43
+ if (lastPart === 'index' || (lastPart.startsWith('index_') && match)) {
44
+ // index index_数字 → 改为空路径(由父级路径表示)
45
+ cleanPath = '';
46
+ } else if (match) {
47
+ // xxx_数字 → 去掉 _数字 后缀
48
+ cleanPath = lastPart.replace(/_\d+$/, '');
49
+ } else {
50
+ // 其他 → 保持原样
51
+ cleanPath = lastPart;
69
52
  }
70
- } catch (error: any) {
71
- Logger.warn(`扫描插件目录失败:`, error?.message || '未知错误');
53
+
54
+ // 根据布局名称加载对应组件
55
+ const layoutComponent = layoutName === 'default' ? () => import('@/layouts/default.vue') : () => import(`@/layouts/${layoutName}.vue`);
56
+
57
+ // 包裹布局
58
+ result.push({
59
+ path: cleanPath,
60
+ component: layoutComponent,
61
+ children: [
62
+ {
63
+ ...route,
64
+ path: ''
65
+ }
66
+ ]
67
+ });
72
68
  }
73
69
 
74
- return addonList;
70
+ return result;
75
71
  }
@@ -124,7 +124,7 @@ const $Method = {
124
124
  const valid = await date$From.form.validate();
125
125
  if (!valid) return;
126
126
 
127
- const res = await $Http($Prop.actionType === 'upd' ? '/addon/admin/adminUpd' : '/addon/admin/adminIns', $Data.formData);
127
+ const res = await $Http($Prop.actionType === 'upd' ? '/addon/admin/admin/upd' : '/addon/admin/admin/ins', $Data.formData);
128
128
 
129
129
  Modal.message({
130
130
  message: $Prop.actionType === 'upd' ? '编辑成功' : '添加成功',
@@ -83,7 +83,7 @@ const $Method = {
83
83
  if (!$Prop.rowData.id) return;
84
84
 
85
85
  try {
86
- const res = await $Http('/addon/admin/roleDetail', {
86
+ const res = await $Http('/addon/admin/admin/roleDetail', {
87
87
  adminId: $Prop.rowData.id
88
88
  });
89
89
  $Data.checkedRoleCode = res.data.roleCode || '';
@@ -100,7 +100,7 @@ const $Method = {
100
100
  }
101
101
 
102
102
  try {
103
- const res = await $Http('/addon/admin/roleSave', {
103
+ const res = await $Http('/addon/admin/admin/roleSave', {
104
104
  adminId: $Prop.rowData.id,
105
105
  roleCode: $Data.checkedRoleCode
106
106
  });
@@ -4,7 +4,7 @@
4
4
  <div class="left">
5
5
  <tiny-button type="primary" @click="$Method.onAction('add', {})">
6
6
  <template #icon>
7
- <i-lucide:plus style="width: 16px; height: 16px" />
7
+ <i-lucide:plus />
8
8
  </template>
9
9
  添加管理员
10
10
  </tiny-button>
@@ -12,14 +12,14 @@
12
12
  <div class="right">
13
13
  <tiny-button @click="$Method.handleRefresh">
14
14
  <template #icon>
15
- <i-lucide:rotate-cw style="width: 16px; height: 16px" />
15
+ <i-lucide:rotate-cw />
16
16
  </template>
17
17
  </tiny-button>
18
18
  </div>
19
19
  <div class="right">
20
20
  <tiny-button @click="$Method.handleRefresh">
21
21
  <template #icon>
22
- <i-lucide:rotate-cw style="width: 16px; height: 16px" />
22
+ <i-lucide:rotate-cw />
23
23
  </template>
24
24
  刷新
25
25
  </tiny-button>
@@ -109,7 +109,7 @@ const $Method = {
109
109
  // 加载管理员列表
110
110
  async apiAdminList() {
111
111
  try {
112
- const res = await $Http('/addon/admin/list', {
112
+ const res = await $Http('/addon/admin/admin/list', {
113
113
  page: $Data.pagerConfig.currentPage,
114
114
  limit: $Data.pagerConfig.pageSize
115
115
  });
@@ -132,7 +132,7 @@ const $Method = {
132
132
  status: 'warning'
133
133
  }).then(async () => {
134
134
  try {
135
- const res = await $Http('/addon/admin/del', { id: row.id });
135
+ const res = await $Http('/addon/admin/admin/del', { id: row.id });
136
136
  if (res.code === 0) {
137
137
  Modal.message({ message: '删除成功', status: 'success' });
138
138
  $Method.apiAdminList();
@@ -4,7 +4,7 @@
4
4
  <div class="left">
5
5
  <tiny-button type="primary" @click="$Method.onAction('add', {})">
6
6
  <template #icon>
7
- <i-lucide:plus style="width: 16px; height: 16px" />
7
+ <i-lucide:plus />
8
8
  </template>
9
9
  添加字典
10
10
  </tiny-button>
@@ -12,7 +12,7 @@
12
12
  <div class="right">
13
13
  <tiny-button @click="$Method.handleRefresh">
14
14
  <template #icon>
15
- <i-lucide:rotate-cw style="width: 16px; height: 16px" />
15
+ <i-lucide:rotate-cw />
16
16
  </template>
17
17
  刷新
18
18
  </tiny-button>
@@ -1,13 +1,12 @@
1
1
  <template>
2
2
  <div class="section-block">
3
- <div class="section-header">
3
+ <div class="section-header flex items-center gap-2">
4
4
  <i-lucide:package style="width: 20px; height: 20px" />
5
5
  <h2>已安装插件</h2>
6
6
  </div>
7
7
  <div class="section-content">
8
8
  <div class="addon-list">
9
9
  <div v-for="addon in addonList" :key="addon.name" class="addon-item">
10
- <div class="addon-status-badge" :class="{ active: addon.enabled }"></div>
11
10
  <div class="addon-icon">
12
11
  <i-lucide:box style="width: 20px; height: 20px" />
13
12
  </div>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="section-block">
3
- <div class="section-header">
3
+ <div class="section-header flex items-center gap-2">
4
4
  <i-lucide:server style="width: 20px; height: 20px" />
5
5
  <h2>运行环境</h2>
6
6
  </div>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="section-block">
3
- <div class="section-header">
4
- <i-lucide:list style="width: 20px; height: 20px" />
3
+ <div class="section-header flex items-center gap-2">
4
+ <i-lucide:file-text style="width: 20px; height: 20px" />
5
5
  <h2>操作日志</h2>
6
6
  </div>
7
7
  <div class="section-content">
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="section-block">
3
- <div class="section-header">
4
- <i-lucide:zap style="width: 20px; height: 20px" />
3
+ <div class="section-header flex items-center gap-2">
4
+ <i-lucide:activity style="width: 20px; height: 20px" />
5
5
  <h2>性能指标</h2>
6
6
  </div>
7
7
  <div class="section-content">
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="section-block">
3
- <div class="section-header">
4
- <i-lucide:settings style="width: 20px; height: 20px" />
3
+ <div class="section-header flex items-center gap-2">
4
+ <i-lucide:check-circle style="width: 20px; height: 20px" />
5
5
  <h2>服务状态</h2>
6
6
  </div>
7
7
  <div class="section-content">
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="section-block">
3
- <div class="section-header">
3
+ <div class="section-header flex items-center gap-2">
4
4
  <i-lucide:bell style="width: 20px; height: 20px" />
5
5
  <h2>系统通知</h2>
6
6
  </div>
@@ -8,11 +8,11 @@
8
8
  <div class="notification-compact-list">
9
9
  <div v-for="notification in notifications" :key="notification.id" class="notification-compact-item">
10
10
  <div class="notification-icon" :class="`type-${notification.type}`">
11
- <i-lucide:info v-if="notification.type === 'info'" style="width: 16px; height: 16px" />
12
- <i-lucide:check-circle v-else-if="notification.type === 'success'" style="width: 16px; height: 16px" />
13
- <i-lucide:alert-triangle v-else-if="notification.type === 'warning'" style="width: 16px; height: 16px" />
14
- <i-lucide:x-circle v-else-if="notification.type === 'error'" style="width: 16px; height: 16px" />
15
- <i-lucide:bell v-else style="width: 16px; height: 16px" />
11
+ <i-lucide:info v-if="notification.type === 'info'" />
12
+ <i-lucide:check-circle v-else-if="notification.type === 'success'" />
13
+ <i-lucide:alert-triangle v-else-if="notification.type === 'warning'" />
14
+ <i-lucide:x-circle v-else-if="notification.type === 'error'" />
15
+ <i-lucide:bell v-else />
16
16
  </div>
17
17
  <div class="notification-content">
18
18
  <span class="notification-title">{{ notification.title }}</span>
@@ -1,11 +1,11 @@
1
1
  <template>
2
2
  <div class="section-block">
3
- <div class="section-header">
3
+ <div class="section-header flex items-center gap-2">
4
4
  <i-lucide:info style="width: 20px; height: 20px" />
5
5
  <h2>系统概览</h2>
6
6
  </div>
7
7
  <div class="section-content">
8
- <tiny-row :flex="true" :gap="12">
8
+ <tiny-row :flex="true">
9
9
  <tiny-col :xs="24" :sm="12" :md="12" :lg="12">
10
10
  <div class="info-block">
11
11
  <div class="stats-grid">
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="section-block">
3
- <div class="section-header">
3
+ <div class="section-header flex items-center gap-2">
4
4
  <i-lucide:activity style="width: 20px; height: 20px" />
5
5
  <h2>系统资源</h2>
6
6
  </div>
@@ -8,7 +8,7 @@
8
8
  <div class="resource-compact-list">
9
9
  <div class="resource-compact-item">
10
10
  <div class="resource-compact-header">
11
- <i-lucide:cpu style="width: 16px; height: 16px" />
11
+ <i-lucide:cpu />
12
12
  <span class="resource-label">CPU</span>
13
13
  <span class="resource-value">{{ systemResources.cpu.usage }}%</span>
14
14
  <span class="resource-desc">{{ systemResources.cpu.cores }}核心</span>
@@ -17,7 +17,7 @@
17
17
  </div>
18
18
  <div class="resource-compact-item">
19
19
  <div class="resource-compact-header">
20
- <i-lucide:hard-drive style="width: 16px; height: 16px" />
20
+ <i-lucide:hard-drive />
21
21
  <span class="resource-label">内存</span>
22
22
  <span class="resource-value">{{ systemResources.memory.percentage }}%</span>
23
23
  <span class="resource-desc">{{ systemResources.memory.used }}GB / {{ systemResources.memory.total }}GB</span>
@@ -26,7 +26,7 @@
26
26
  </div>
27
27
  <div class="resource-compact-item">
28
28
  <div class="resource-compact-header">
29
- <i-lucide:disc style="width: 16px; height: 16px" />
29
+ <i-lucide:disc />
30
30
  <span class="resource-label">磁盘</span>
31
31
  <span class="resource-value">{{ systemResources.disk.percentage }}%</span>
32
32
  <span class="resource-desc">{{ systemResources.disk.used }}GB / {{ systemResources.disk.total }}GB</span>
@@ -25,5 +25,8 @@ import EnvironmentInfo from './components/environmentInfo.vue';
25
25
  height: 100%;
26
26
  background-color: #fff;
27
27
  padding: 15px;
28
+ border: 1px solid #e8eaed;
29
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
30
+ border-radius: 8px;
28
31
  }
29
32
  </style>
@@ -10,12 +10,6 @@
10
10
  <tiny-form-item label="图标" prop="icon">
11
11
  <tiny-input v-model="$Data.formData.icon" placeholder="请输入图标名称,如:User" />
12
12
  </tiny-form-item>
13
- <tiny-form-item label="菜单类型" prop="type">
14
- <tiny-radio-group v-model="$Data.formData.type">
15
- <tiny-radio :label="0">目录</tiny-radio>
16
- <tiny-radio :label="1">菜单</tiny-radio>
17
- </tiny-radio-group>
18
- </tiny-form-item>
19
13
  <tiny-form-item label="排序" prop="sort">
20
14
  <tiny-numeric v-model="$Data.formData.sort" :min="0" :max="9999" />
21
15
  </tiny-form-item>
@@ -66,8 +60,8 @@ const $Data = $ref({
66
60
  name: '',
67
61
  path: '',
68
62
  icon: '',
69
- type: 1,
70
63
  sort: 0,
64
+ pid: 0,
71
65
  state: 1
72
66
  }
73
67
  });
@@ -75,8 +69,7 @@ const $Data = $ref({
75
69
  const $Data2 = $shallowRef({
76
70
  formRules: {
77
71
  name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
78
- path: [{ required: true, message: '请输入菜单路径', trigger: 'blur' }],
79
- type: [{ required: true, message: '请选择菜单类型', trigger: 'change' }]
72
+ path: [{ required: true, message: '请输入菜单路径', trigger: 'blur' }]
80
73
  }
81
74
  });
82
75
 
@@ -91,10 +84,9 @@ const $Method = {
91
84
  if ($Prop.actionType === 'upd' && $Prop.rowData) {
92
85
  $Data.formData.id = $Prop.rowData.id || 0;
93
86
  $Data.formData.name = $Prop.rowData.name || '';
94
- $Data.formData.path = $Prop.rowData.path || '';
95
- $Data.formData.icon = $Prop.rowData.icon || '';
96
- $Data.formData.type = $Prop.rowData.type ?? 1;
97
- $Data.formData.sort = $Prop.rowData.sort || 0;
87
+ $Data.formData.path = $Prop.rowData.path ?? '';
88
+ $Data.formData.icon = $Prop.rowData.icon ?? '';
89
+ $Data.formData.sort = $Prop.rowData.sort ?? 0;
98
90
  $Data.formData.state = $Prop.rowData.state ?? 1;
99
91
  } else {
100
92
  // 重置表单
@@ -102,7 +94,6 @@ const $Method = {
102
94
  $Data.formData.name = '';
103
95
  $Data.formData.path = '';
104
96
  $Data.formData.icon = '';
105
- $Data.formData.type = 1;
106
97
  $Data.formData.sort = 0;
107
98
  $Data.formData.state = 1;
108
99
  }
@@ -4,7 +4,7 @@
4
4
  <div class="left">
5
5
  <tiny-button type="primary" @click="$Method.onAction('add', {})">
6
6
  <template #icon>
7
- <i-lucide:plus style="width: 16px; height: 16px" />
7
+ <i-lucide:plus />
8
8
  </template>
9
9
  添加菜单
10
10
  </tiny-button>
@@ -12,7 +12,7 @@
12
12
  <div class="right">
13
13
  <tiny-button @click="$Method.handleRefresh">
14
14
  <template #icon>
15
- <i-lucide:rotate-cw style="width: 16px; height: 16px" />
15
+ <i-lucide:rotate-cw />
16
16
  </template>
17
17
  刷新
18
18
  </tiny-button>
@@ -25,16 +25,10 @@
25
25
  <tiny-grid-column field="path" title="路径" :width="200" />
26
26
  <tiny-grid-column field="icon" title="图标" :width="100">
27
27
  <template #default="{ row }">
28
- <i-lucide:square v-if="row.icon" style="width: 16px; height: 16px" />
28
+ <i-lucide:square v-if="row.icon" />
29
29
  <span v-else>-</span>
30
30
  </template>
31
31
  </tiny-grid-column>
32
- <tiny-grid-column field="type" title="类型" :width="100">
33
- <template #default="{ row }">
34
- <tiny-tag v-if="row.type === 0" type="info">目录</tiny-tag>
35
- <tiny-tag v-else type="success">菜单</tiny-tag>
36
- </template>
37
- </tiny-grid-column>
38
32
  <tiny-grid-column field="sort" title="排序" :width="80" />
39
33
  <tiny-grid-column field="state" title="状态" :width="100">
40
34
  <template #default="{ row }">
@@ -4,7 +4,7 @@
4
4
  <div class="left">
5
5
  <tiny-button type="primary" @click="$Method.onAction('add', {})">
6
6
  <template #icon>
7
- <i-lucide:plus style="width: 16px; height: 16px" />
7
+ <i-lucide:plus />
8
8
  </template>
9
9
  添加角色
10
10
  </tiny-button>
@@ -12,7 +12,7 @@
12
12
  <div class="right">
13
13
  <tiny-button @click="$Method.handleRefresh">
14
14
  <template #icon>
15
- <i-lucide:rotate-cw style="width: 16px; height: 16px" />
15
+ <i-lucide:rotate-cw />
16
16
  </template>
17
17
  刷新
18
18
  </tiny-button>
@@ -5,7 +5,7 @@
5
5
  <div class="toolbar-left">
6
6
  <t-button theme="primary" @click="$Method.handleAdd">
7
7
  <template #icon>
8
- <i-lucide:plus style="width: 16px; height: 16px" />
8
+ <i-lucide:plus />
9
9
  </template>
10
10
  添加管理员
11
11
  </t-button>
@@ -16,13 +16,13 @@
16
16
  <t-select v-model="$Data.searchState" placeholder="状态" clearable style="width: 120px" :options="$Data.stateOptions" @change="$Method.handleSearch" />
17
17
  <t-button theme="default" @click="$Method.handleSearch">
18
18
  <template #icon>
19
- <i-lucide:search style="width: 16px; height: 16px" />
19
+ <i-lucide:search />
20
20
  </template>
21
21
  搜索
22
22
  </t-button>
23
23
  <t-button theme="default" @click="$Method.handleReset">
24
24
  <template #icon>
25
- <i-lucide:rotate-cw style="width: 16px; height: 16px" />
25
+ <i-lucide:rotate-cw />
26
26
  </template>
27
27
  重置
28
28
  </t-button>
File without changes