NewLife/cube-front

暂存
Yann authored at 2025-07-01 10:27:10
6777f65
Tree
1 Parent(s) 45fb228
Summary: 7 changed files with 323 additions and 0 deletions.
Added +225 -0
Modified +54 -0
Added +28 -0
Modified +6 -0
Modified +6 -0
Modified +1 -0
Modified +3 -0
Added +225 -0
diff --git a/apps/cube-admin/src/pages/admin/xcode/index.vue b/apps/cube-admin/src/pages/admin/xcode/index.vue
new file mode 100644
index 0000000..b272306
--- /dev/null
+++ b/apps/cube-admin/src/pages/admin/xcode/index.vue
@@ -0,0 +1,225 @@
+<template>
+  <div class="xcode-container">
+    <el-card class="box-card">
+      <template #header>
+        <div class="card-header">
+          <h3>XCode设置</h3>
+          <el-button type="primary" @click="handleSave">保存设置</el-button>
+        </div>
+      </template>
+
+      <el-form ref="formRef" :model="form" :rules="formRules" label-width="160px" v-loading="loading">
+        <el-form-item label="新建" prop="isNew">
+          <el-tag :type="form.isNew ? 'success' : 'info'">
+            {{ form.isNew ? '是' : '否' }}
+          </el-tag>
+        </el-form-item>
+
+        <el-divider content-position="left">基本设置</el-divider>
+        <el-form-item label="调试" prop="debug">
+          <el-switch v-model="form.debug" :active-value="true" :inactive-value="false" />
+        </el-form-item>
+        <el-form-item label="输出SQL" prop="showSQL">
+          <el-switch v-model="form.showSQL" :active-value="true" :inactive-value="false" />
+          <div class="form-tip">是否输出SQL语句,默认启用</div>
+        </el-form-item>
+        <el-form-item label="SQL目录" prop="sqlPath">
+          <el-input v-model="form.sqlPath" placeholder="设置SQL输出的单独目录" clearable />
+          <div class="form-tip">默认为空,SQL输出到当前日志中。生产环境建议输出到站点外单独的SqlLog目录</div>
+        </el-form-item>
+        <el-form-item label="SQL执行时间" prop="traceSQLTime">
+          <el-input-number v-model="form.traceSQLTime" :min="0" placeholder="毫秒" />
+          <div class="form-tip">跟踪SQL执行时间,大于该阀值将输出日志,默认1000毫秒</div>
+        </el-form-item>
+        <el-form-item label="SQL最大长度" prop="sqlMaxLength">
+          <el-input-number v-model="form.sqlMaxLength" :min="0" placeholder="字符数" />
+          <div class="form-tip">输出日志时的SQL最大长度,超长截断,默认4096,不截断用0</div>
+        </el-form-item>
+        <el-form-item label="参数化查询" prop="useParameter">
+          <el-switch v-model="form.useParameter" :active-value="true" :inactive-value="false" />
+          <div class="form-tip">参数化添删改查,默认关闭</div>
+        </el-form-item>
+
+        <el-divider content-position="left">批量操作</el-divider>
+        <el-form-item label="批大小" prop="batchSize">
+          <el-input-number v-model="form.batchSize" :min="1" placeholder="记录条数" />
+          <div class="form-tip">用于批量操作数据,抽取、删除、备份、恢复,默认5000</div>
+        </el-form-item>
+        <el-form-item label="批操作间隙" prop="batchInterval">
+          <el-input-number v-model="form.batchInterval" :min="0" placeholder="毫秒" />
+          <div class="form-tip">用于批量删除数据时的暂停间隙,单位毫秒,默认100</div>
+        </el-form-item>
+        <el-form-item label="命令超时" prop="commandTimeout">
+          <el-input-number v-model="form.commandTimeout" :min="0" placeholder="秒" />
+          <div class="form-tip">查询执行超时时间,默认0秒不限制</div>
+        </el-form-item>
+        <el-form-item label="失败重试" prop="retryOnFailure">
+          <el-input-number v-model="form.retryOnFailure" :min="0" placeholder="次数" />
+          <div class="form-tip">执行命令超时后的重试次数,默认0不重试</div>
+        </el-form-item>
+
+        <el-divider content-position="left">反向工程</el-divider>
+        <el-form-item label="检查注释" prop="checkComment">
+          <el-switch v-model="form.checkComment" :active-value="true" :inactive-value="false" />
+          <div class="form-tip">表注释或字段注释,反向工程,默认打开</div>
+        </el-form-item>
+        <el-form-item label="检查删除索引" prop="checkDeleteIndex">
+          <el-switch v-model="form.checkDeleteIndex" :active-value="true" :inactive-value="false" />
+          <div class="form-tip">反向工程,默认打开</div>
+        </el-form-item>
+        <el-form-item label="检查添加索引" prop="checkAddIndex">
+          <el-switch v-model="form.checkAddIndex" :active-value="true" :inactive-value="false" />
+          <div class="form-tip">反向工程,默认打开</div>
+        </el-form-item>
+        <el-form-item label="检查重复索引" prop="checkDuplicateIndex">
+          <el-switch v-model="form.checkDuplicateIndex" :active-value="true" :inactive-value="false" />
+          <div class="form-tip">反向工程,默认打开</div>
+        </el-form-item>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, onMounted } from 'vue';
+import { ElMessage, type FormInstance, type FormRules } from 'element-plus';
+import type { XCodeSetting } from '@/types/admin';
+
+// 表单相关
+const formRef = ref<FormInstance | null>(null);
+const loading = ref(false);
+
+// 表单数据
+const form = reactive<XCodeSetting>({
+  isNew: false,
+  debug: false,
+  showSQL: true,
+  sqlPath: '',
+  traceSQLTime: 1000,
+  sqlMaxLength: 4096,
+  useParameter: false,
+  batchSize: 5000,
+  batchInterval: 100,
+  commandTimeout: 0,
+  retryOnFailure: 0,
+  checkComment: true,
+  checkDeleteIndex: true,
+  checkAddIndex: true,
+  checkDuplicateIndex: true,
+});
+
+// 表单验证规则
+const formRules = reactive<FormRules>({
+  traceSQLTime: [
+    { required: true, message: '请输入SQL执行时间阀值', trigger: 'blur' }
+  ],
+  sqlMaxLength: [
+    { required: true, message: '请输入SQL最大长度', trigger: 'blur' }
+  ],
+  batchSize: [
+    { required: true, message: '请输入批大小', trigger: 'blur' }
+  ],
+  batchInterval: [
+    { required: true, message: '请输入批操作间隙', trigger: 'blur' }
+  ],
+});
+
+// 接口调用函数
+const api = {
+  getSettings: () => {
+    return fetch('/api/Admin/XCode').then(res => res.json());
+  },
+  updateSettings: (data: XCodeSetting) => {
+    return fetch('/api/Admin/XCode', {
+      method: 'PUT',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify(data),
+    }).then(res => res.json());
+  }
+};
+
+// 加载数据
+const loadData = async () => {
+  try {
+    loading.value = true;
+    const response = await api.getSettings();
+
+    if (response) {
+      Object.assign(form, response);
+    }
+  } catch (error) {
+    ElMessage.error('加载设置失败');
+    console.error('加载设置失败:', error);
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 保存设置
+const handleSave = async () => {
+  if (!formRef.value) return;
+
+  try {
+    await formRef.value.validate();
+    loading.value = true;
+
+    const response = await api.updateSettings(form);
+
+    if (response) {
+      ElMessage.success('保存成功');
+      Object.assign(form, response);
+    } else {
+      ElMessage.error('保存失败');
+    }
+  } catch (error) {
+    if (error instanceof Error) {
+      ElMessage.error('保存失败: ' + error.message);
+    } else {
+      ElMessage.error('表单验证失败');
+    }
+    console.error('保存失败:', error);
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 组件挂载
+onMounted(() => {
+  loadData();
+});
+</script>
+
+<style scoped>
+.xcode-container {
+  padding: 20px;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.card-header h3 {
+  margin: 0;
+  font-size: 18px;
+  font-weight: 500;
+}
+
+.form-tip {
+  font-size: 12px;
+  color: #999;
+  margin-top: 4px;
+  line-height: 1.4;
+}
+
+.el-divider {
+  margin: 24px 0 16px 0;
+}
+
+.el-input-number {
+  width: 200px;
+}
+</style>
Modified +54 -0
diff --git a/apps/cube-admin/src/routes/index.ts b/apps/cube-admin/src/routes/index.ts
index 75b7aca..4a60010 100644
--- a/apps/cube-admin/src/routes/index.ts
+++ b/apps/cube-admin/src/routes/index.ts
@@ -19,12 +19,30 @@ const routes: RouteRecordRaw[] = [
     name: 'admin-cube',
     component: () => import('../pages/admin/cube/index.vue'),
   },
+  // 数据库管理
+  {
+    path: '/Admin/Db',
+    name: 'admin-db',
+    component: () => import('../pages/admin/db/index.vue'),
+  },
   // 部门管理
   {
     path: '/Admin/Department',
     name: 'admin-department',
     component: () => import('../pages/admin/department/index.vue'),
   },
+  // 文件管理
+  {
+    path: '/Admin/File',
+    name: 'admin-file',
+    component: () => import('../pages/admin/file/index.vue'),
+  },
+  // 系统首页
+  {
+    path: '/Admin/Index',
+    name: 'admin-index',
+    component: () => import('../pages/admin/index/index.vue'),
+  },
   // 审计日志
   {
     path: '/Admin/Log',
@@ -43,6 +61,12 @@ const routes: RouteRecordRaw[] = [
     name: 'admin-oauth-config',
     component: () => import('../pages/admin/oauth-config/index.vue'),
   },
+  // OAuth日志
+  {
+    path: '/Admin/OAuthLog',
+    name: 'admin-oauth-log',
+    component: () => import('../pages/admin/oauth-log/index.vue'),
+  },
   // 参数管理
   {
     path: '/Admin/Parameter',
@@ -79,6 +103,36 @@ const routes: RouteRecordRaw[] = [
     name: 'admin-user-connect',
     component: () => import('../pages/admin/user-connect/index.vue'),
   },
+  // 租户用户管理
+  {
+    path: '/Admin/TenantUser',
+    name: 'admin-tenant-user',
+    component: () => import('../pages/admin/tenant-user/index.vue'),
+  },
+  // 在线用户管理
+  {
+    path: '/Admin/UserOnline',
+    name: 'admin-user-online',
+    component: () => import('../pages/admin/user-online/index.vue'),
+  },
+  // 用户统计
+  {
+    path: '/Admin/UserStat',
+    name: 'admin-user-stat',
+    component: () => import('../pages/admin/user-stat/index.vue'),
+  },
+  // 用户令牌管理
+  {
+    path: '/Admin/UserToken',
+    name: 'admin-user-token',
+    component: () => import('../pages/admin/user-token/index.vue'),
+  },
+  // XCode设置
+  {
+    path: '/Admin/XCode',
+    name: 'admin-xcode',
+    component: () => import('../pages/admin/xcode/index.vue'),
+  },
 ];
 
 export default routes;
Added +28 -0
diff --git a/apps/cube-admin/src/types/admin.ts b/apps/cube-admin/src/types/admin.ts
new file mode 100644
index 0000000..570e435
--- /dev/null
+++ b/apps/cube-admin/src/types/admin.ts
@@ -0,0 +1,28 @@
+// XCode 相关类型定义
+export interface XCodeSetting {
+  isNew: boolean;
+  debug: boolean;
+  showSQL: boolean;
+  sqlPath: string;
+  traceSQLTime: number;
+  sqlMaxLength: number;
+  useParameter: boolean;
+  batchSize: number;
+  batchInterval: number;
+  commandTimeout: number;
+  retryOnFailure: number;
+  migration?: Migration;
+  checkComment: boolean;
+  checkDeleteIndex: boolean;
+  checkAddIndex: boolean;
+  checkDuplicateIndex: boolean;
+}
+
+export interface Migration {
+  enable: boolean;
+  mode: number;
+  nameFormat: string;
+  onlyCreateTable: boolean;
+  backupDatabase: boolean;
+  initData: boolean;
+}
Modified +6 -0
diff --git a/components.d.ts b/components.d.ts
index ee777e7..ddbc564 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -11,16 +11,20 @@ declare module 'vue' {
     ElAvatar: typeof import('element-plus/es')['ElAvatar']
     ElButton: typeof import('element-plus/es')['ElButton']
     ElCard: typeof import('element-plus/es')['ElCard']
+    ElCol: typeof import('element-plus/es')['ElCol']
     ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
     ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
     ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
     ElDialog: typeof import('element-plus/es')['ElDialog']
+    ElDivider: typeof import('element-plus/es')['ElDivider']
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
+    ElIcon: typeof import('element-plus/es')['ElIcon']
     ElInput: typeof import('element-plus/es')['ElInput']
     ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
+    ElRow: typeof import('element-plus/es')['ElRow']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTable: typeof import('element-plus/es')['ElTable']
@@ -29,6 +33,8 @@ declare module 'vue' {
     ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTag: typeof import('element-plus/es')['ElTag']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
+    ElTree: typeof import('element-plus/es')['ElTree']
+    ElUpload: typeof import('element-plus/es')['ElUpload']
     HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
     IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default']
     IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default']
Modified +6 -0
diff --git a/env.d.ts b/env.d.ts
index 7a542d0..00b8d01 100644
--- a/env.d.ts
+++ b/env.d.ts
@@ -1,2 +1,8 @@
 /// <reference types="vite/client" />
 /// <reference types="cypress" />
+
+declare module '*.vue' {
+  import type { DefineComponent } from 'vue'
+  const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>
+  export default component
+}
Modified +1 -0
diff --git a/package.json b/package.json
index 221b56c..7706772 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
     "format": "prettier --write src/"
   },
   "dependencies": {
+    "@element-plus/icons-vue": "^2.3.1",
     "@types/lodash": "^4.17.9",
     "@vue/reactivity": "^3.5.13",
     "@vue/runtime-dom": "^3.5.13",
Modified +3 -0
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 804b561..7a359db 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,6 +8,9 @@ importers:
 
   .:
     dependencies:
+      '@element-plus/icons-vue':
+        specifier: ^2.3.1
+        version: 2.3.1(vue@3.5.13(typescript@5.8.2))
       '@types/lodash':
         specifier: ^4.17.9
         version: 4.17.16