Przeglądaj źródła

服务类型基本完成

Huanyi 2 tygodni temu
rodzic
commit
ef947bd62f

+ 74 - 0
src/api/service/classification/index.ts

@@ -0,0 +1,74 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { ClassificationVO, ClassificationForm, ClassificationQuery } from '@/api/service/classification/types';
+
+/**
+ * 查询服务分类列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listClassification = (query?: ClassificationQuery): AxiosPromise<ClassificationVO[]> => {
+  return request({
+    url: '/service/classification/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询所有服务分类列表
+ * @returns {*}
+ */
+export const listAllClassification = (): AxiosPromise<ClassificationVO[]> => {
+  return request({
+    url: '/service/classification/listAll',
+    method: 'get'
+  });
+};
+
+/**
+ * 查询服务分类详细
+ * @param id
+ */
+export const getClassification = (id: string | number): AxiosPromise<ClassificationVO> => {
+  return request({
+    url: '/service/classification/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增服务分类
+ * @param data
+ */
+export const addClassification = (data: ClassificationForm) => {
+  return request({
+    url: '/service/classification',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改服务分类
+ * @param data
+ */
+export const updateClassification = (data: ClassificationForm) => {
+  return request({
+    url: '/service/classification',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除服务分类
+ * @param id
+ */
+export const delClassification = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/service/classification/' + id,
+    method: 'delete'
+  });
+};

+ 68 - 0
src/api/service/classification/types.ts

@@ -0,0 +1,68 @@
+export interface ClassificationVO {
+
+  id: string | number;
+  /**
+   * 类型名称
+   */
+  name: string;
+
+  /**
+   * 排序
+   */
+  sort: number;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+  /**
+   * 创建时间
+   */
+  createTime: string;
+
+}
+
+export interface ClassificationForm extends BaseEntity {
+  /**
+   * 序号
+   */
+  id?: string | number;
+
+  /**
+   * 类型名称
+   */
+  name?: string;
+
+  /**
+   * 排序
+   */
+  sort?: number;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface ClassificationQuery extends PageQuery {
+
+  /**
+   * 类型名称
+   */
+  name?: string;
+
+  /**
+   * 排序
+   */
+  sort?: number;
+
+  /**
+   * 日期范围参数
+   */
+  params?: any;
+}
+
+
+

+ 30 - 0
src/api/service/list/types.ts

@@ -38,6 +38,21 @@ export interface ServiceVO {
    */
   clockInRemark: string;
 
+  /**
+   * 服务介绍
+   */
+  introduction: string;
+
+  /**
+   * 下单须知
+   */
+  orderInstruction: string;
+
+  /**
+   * 所属分类ID
+   */
+  classificationId: number;
+
   /**
    * 创建时间
    */
@@ -79,6 +94,21 @@ export interface ServiceForm extends BaseEntity {
    * 打卡备注信息
    */
   clockInRemark?: string;
+
+  /**
+   * 服务介绍
+   */
+  introduction?: string;
+
+  /**
+   * 下单须知
+   */
+  orderInstruction?: string;
+
+  /**
+   * 所属分类ID
+   */
+  classificationId?: number;
 }
 
 export interface ServiceQuery extends PageQuery {

+ 1 - 0
src/api/types.ts

@@ -15,6 +15,7 @@ export type RegisterForm = {
  * 登录请求
  */
 export interface LoginData {
+  userSource?: number;
   platformId?: number;
   tenantId?: string;
   username?: string;

+ 1 - 1
src/views/login.vue

@@ -35,7 +35,7 @@
         </div>
       </el-form-item>
       <el-checkbox v-model="loginForm.rememberMe" style="margin: 0 0 25px 0">{{ proxy.$t('login.rememberPassword')
-        }}</el-checkbox>
+      }}</el-checkbox>
       <!--      <el-form-item style="float: right">-->
       <!--        <el-button circle :title="proxy.$t('login.social.wechat')" @click="doSocialLogin('wechat')">-->
       <!--          <svg-icon icon-class="wechat" />-->

+ 302 - 0
src/views/service/classification/index.vue

@@ -0,0 +1,302 @@
+<template>
+  <div class="gen-container">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div v-show="showSearch" class="search-wrapper">
+        <el-card shadow="hover" class="search-card">
+          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
+            <el-form-item label="类型名称" prop="name">
+              <el-input v-model="queryParams.name" placeholder="请输入类型名称" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="排序" prop="sort">
+              <el-input v-model="queryParams.sort" placeholder="请输入排序" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="handleQuery">搜索</el-button>
+              <el-button @click="resetQuery">重置</el-button>
+            </el-form-item>
+          </el-form>
+        </el-card>
+      </div>
+    </transition>
+
+    <el-card shadow="hover" class="table-card">
+      <template #header>
+        <div class="card-header">
+          <div class="header-left">
+            <span class="header-title">服务分类列表</span>
+          </div>
+          <div class="header-right">
+            <el-button type="primary" size="small" @click="handleAdd" v-hasPermi="['service:classification:add']">新增</el-button>
+            <el-button type="success" size="small" :disabled="single" @click="handleUpdate()" v-hasPermi="['service:classification:edit']">修改</el-button>
+            <el-button type="danger" size="small" :disabled="multiple" @click="handleDelete()" v-hasPermi="['service:classification:remove']">删除</el-button>
+            <el-button type="warning" size="small" @click="handleExport" v-hasPermi="['service:classification:export']">导出</el-button>
+            <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+          </div>
+        </div>
+      </template>
+
+      <el-table v-loading="loading" stripe :data="classificationList" @selection-change="handleSelectionChange" class="gen-table">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="序号" align="center" prop="id" v-if="false" />
+        <el-table-column label="类型名称" align="center" prop="name" />
+        <el-table-column label="排序" align="center" prop="sort" />
+        <el-table-column label="备注" align="center" prop="remark" />
+        <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" width="160" fixed="right">
+          <template #default="scope">
+            <el-button link type="primary" size="small" @click="handleUpdate(scope.row)" v-hasPermi="['service:classification:edit']">编辑</el-button>
+            <el-button link type="danger" size="small" @click="handleDelete(scope.row)" v-hasPermi="['service:classification:remove']">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 添加或修改服务分类对话框 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="classificationFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="类型名称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入类型名称" />
+        </el-form-item>
+        <el-form-item label="排序" prop="sort">
+          <el-input v-model="form.sort" placeholder="请输入排序" />
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+            <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="Classification" lang="ts">
+import { listClassification, getClassification, delClassification, addClassification, updateClassification } from '@/api/service/classification';
+import { ClassificationVO, ClassificationQuery, ClassificationForm } from '@/api/service/classification/types';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const classificationList = ref<ClassificationVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+
+const queryFormRef = ref<ElFormInstance>();
+const classificationFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const initFormData: ClassificationForm = {
+  id: undefined,
+  name: undefined,
+  sort: undefined,
+  remark: undefined,
+}
+const data = reactive<PageData<ClassificationForm, ClassificationQuery>>({
+  form: {...initFormData},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    name: undefined,
+    sort: undefined,
+    params: {
+    }
+  },
+  rules: {
+    id: [
+      { required: true, message: "序号不能为空", trigger: "blur" }
+    ],
+    name: [
+      { required: true, message: "类型名称不能为空", trigger: "blur" }
+    ],
+    sort: [
+      { required: true, message: "排序不能为空", trigger: "blur" }
+    ],
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 查询服务分类列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listClassification(queryParams.value);
+  classificationList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+}
+
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+  form.value = {...initFormData};
+  classificationFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: ClassificationVO[]) => {
+  ids.value = selection.map(item => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = "添加服务分类";
+}
+
+/** 修改按钮操作 */
+const handleUpdate = async (row?: ClassificationVO) => {
+  reset();
+  const _id = row?.id || ids.value[0]
+  const res = await getClassification(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改服务分类";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+  classificationFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateClassification(form.value).finally(() =>  buttonLoading.value = false);
+      } else {
+        await addClassification(form.value).finally(() =>  buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("操作成功");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: ClassificationVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('是否确认删除服务分类编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+  await delClassification(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download('service/classification/export', {
+    ...queryParams.value
+  }, `classification_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+  getList();
+});
+</script>
+
+<style lang="scss" scoped>
+.gen-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: calc(100vh - 84px);
+}
+
+.search-wrapper {
+  margin-bottom: 20px;
+}
+
+.search-card {
+  :deep(.el-card__body) {
+    padding: 20px;
+  }
+}
+
+.table-card {
+  :deep(.el-card__header) {
+    padding: 16px 20px;
+    border-bottom: 1px solid #f0f0f0;
+  }
+
+  :deep(.el-card__body) {
+    padding: 20px;
+  }
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+
+  .header-left {
+    .header-title {
+      font-size: 16px;
+      font-weight: 600;
+      color: #303133;
+    }
+  }
+
+  .header-right {
+    display: flex;
+    gap: 8px;
+    align-items: center;
+    flex-wrap: nowrap;
+  }
+}
+
+.gen-table {
+  :deep(.el-table__header) {
+    th {
+      background-color: #f5f7fa;
+      color: #606266;
+      font-weight: 600;
+      border-bottom: 1px solid #ebeef5;
+    }
+  }
+
+  :deep(.el-table__body) {
+    td {
+      border-bottom: 1px solid #ebeef5;
+    }
+  }
+
+  :deep(.el-table__row) {
+    &:last-child td {
+      border-bottom: none;
+    }
+  }
+}
+</style>

+ 101 - 21
src/views/service/list/index.vue

@@ -7,12 +7,18 @@
             <span class="title">服务管理 (列表)</span>
           </div>
           <div class="header-right">
+            <el-select v-model="queryParams.classificationId" placeholder="全部分类" clearable @change="handleQuery"
+              style="width: 180px; margin-right: 12px;">
+              <el-option label="全部" :value="undefined" />
+              <el-option v-for="item in classificationList" :key="item.id" :label="item.name" :value="item.id" />
+            </el-select>
             <el-button type="primary" icon="Plus" @click="handleAdd" v-hasPermi="['service:list:add']">新增服务</el-button>
           </div>
         </div>
       </template>
 
-      <el-table v-loading="loading" :data="serviceList" style="width: 100%" :header-cell-style="{ background: '#f8f9fb', color: '#606266' }">
+      <el-table v-loading="loading" :data="serviceList" style="width: 100%"
+        :header-cell-style="{ background: '#f8f9fb', color: '#606266' }">
         <el-table-column label="排序权重" align="center" prop="sort" width="100" />
         <el-table-column label="服务名称" prop="name" min-width="150">
           <template #default="scope">
@@ -26,6 +32,11 @@
             </div>
           </template>
         </el-table-column>
+        <el-table-column label="所属分类" align="center" width="120">
+          <template #default="scope">
+            <span>{{ getClassificationName(scope.row.classificationId) }}</span>
+          </template>
+        </el-table-column>
         <el-table-column label="服务模式" align="center" width="150">
           <template #default="scope">
             <el-tag :type="getModeTagType(scope.row.mode)" size="small" effect="light" class="mode-tag">
@@ -42,21 +53,18 @@
         <el-table-column label="操作" align="right" width="140" fixed="right">
           <template #default="scope">
             <div class="op-btns">
-              <el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['service:list:edit']">编辑</el-button>
-              <el-button link type="danger" @click="handleDelete(scope.row)" v-hasPermi="['service:list:remove']">删除</el-button>
+              <el-button link type="primary" @click="handleUpdate(scope.row)"
+                v-hasPermi="['service:list:edit']">编辑</el-button>
+              <el-button link type="danger" @click="handleDelete(scope.row)"
+                v-hasPermi="['service:list:remove']">删除</el-button>
             </div>
           </template>
         </el-table-column>
       </el-table>
 
       <div class="pagination-container">
-        <pagination
-          v-show="total > 0"
-          v-model:total="total"
-          v-model:page="queryParams.pageNum"
-          v-model:limit="queryParams.pageSize"
-          @pagination="getList"
-        />
+        <pagination v-show="total > 0" v-model:total="total" v-model:page="queryParams.pageNum"
+          v-model:limit="queryParams.pageSize" @pagination="getList" />
       </div>
     </el-card>
 
@@ -76,9 +84,20 @@
             </el-radio>
           </el-radio-group>
         </el-form-item>
+        <el-form-item label="所属分类" prop="classificationId">
+          <el-select v-model="form.classificationId" placeholder="请选择所属分类" clearable style="width: 100%">
+            <el-option v-for="item in classificationList" :key="item.id" :label="item.name" :value="item.id" />
+          </el-select>
+        </el-form-item>
         <el-form-item label="排序权重" prop="sort">
           <el-input-number v-model="form.sort" :min="0" controls-position="right" style="width: 100%" />
         </el-form-item>
+        <el-form-item label="服务介绍" prop="introduction">
+          <editor v-model="form.introduction" :min-height="300" />
+        </el-form-item>
+        <el-form-item label="下单须知" prop="orderInstruction">
+          <editor v-model="form.orderInstruction" :min-height="300" />
+        </el-form-item>
         <el-form-item label="备注说明" prop="remark">
           <el-input v-model="form.remark" placeholder="请输入备注说明" type="textarea" :rows="2" />
         </el-form-item>
@@ -115,6 +134,8 @@ import { listService, getService, delService, addService, updateService } from '
 import { ServiceVO, ServiceQuery, ServiceForm } from '@/api/service/list/types';
 import { list as listMode } from '@/api/service/mode';
 import { SysServiceModeVo } from '@/api/service/mode/types';
+import { listAllClassification } from '@/api/service/classification';
+import { ClassificationVO } from '@/api/service/classification/types';
 
 interface ClockInRemarkItem {
   step: number;
@@ -130,6 +151,7 @@ const buttonLoading = ref(false);
 const loading = ref(true);
 const total = ref(0);
 const modeList = ref<SysServiceModeVo[]>([]);
+const classificationList = ref<ClassificationVO[]>([]);
 
 const serviceFormRef = ref<ElFormInstance>();
 
@@ -146,6 +168,9 @@ const initFormData: ServiceForm = {
   sort: undefined,
   remark: undefined,
   clockInRemark: undefined,
+  introduction: undefined,
+  orderInstruction: undefined,
+  classificationId: undefined,
   tenantId: undefined
 };
 
@@ -154,6 +179,7 @@ const data = reactive<PageData<ServiceForm, ServiceQuery>>({
   queryParams: {
     pageNum: 1,
     pageSize: 10,
+    classificationId: undefined,
     params: {}
   },
   rules: {
@@ -174,6 +200,12 @@ const getList = async () => {
   loading.value = false;
 };
 
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+};
+
 /** 获取服务模式列表 */
 const getModeList = async () => {
   try {
@@ -184,6 +216,16 @@ const getModeList = async () => {
   }
 };
 
+/** 获取分类列表 */
+const getClassificationList = async () => {
+  try {
+    const res = await listAllClassification();
+    classificationList.value = res.data || [];
+  } catch (error) {
+    console.error('获取分类列表失败:', error);
+  }
+};
+
 /** 根据服务模式获取 Tag 类型 */
 const getModeTagType = (value: any) => {
   const map: any = { 'round': 'primary', 'one-way': 'info' };
@@ -196,6 +238,13 @@ const getModeLabel = (value: any): string => {
   return mode ? mode.label : value;
 };
 
+/** 根据分类ID获取分类名称 */
+const getClassificationName = (classificationId: number): string => {
+  if (!classificationId) return '-';
+  const classification = classificationList.value.find((item) => item.id === classificationId);
+  return classification ? classification.name : '-';
+};
+
 /** 取消按钮 */
 const cancel = () => {
   reset();
@@ -230,13 +279,30 @@ const handleUpdate = async (row: ServiceVO) => {
   reset();
   const res = await getService(row.id);
   Object.assign(form.value, res.data);
+
+  // 解码富文本字段
+  if (form.value.introduction) {
+    try {
+      form.value.introduction = decodeURIComponent(atob(form.value.introduction));
+    } catch (e) {
+      console.error('服务介绍解码失败:', e);
+    }
+  }
+  if (form.value.orderInstruction) {
+    try {
+      form.value.orderInstruction = decodeURIComponent(atob(form.value.orderInstruction));
+    } catch (e) {
+      console.error('下单须知解码失败:', e);
+    }
+  }
+
   if (form.value.clockInRemark) {
     try {
       const parsed = JSON.parse(form.value.clockInRemark);
       if (Array.isArray(parsed)) {
         clockInRemarkList.value = getInitialClockInRemarks().map((item, index) => {
           return parsed[index] ? { ...item, ...parsed[index] } : item;
-          });
+        });
       }
     } catch (e) {
       clockInRemarkList.value = getInitialClockInRemarks();
@@ -251,11 +317,21 @@ const submitForm = () => {
   serviceFormRef.value?.validate(async (valid: boolean) => {
     if (valid) {
       form.value.clockInRemark = clockInRemarkList.value.length > 0 ? JSON.stringify(clockInRemarkList.value) : undefined;
+
+      // 编码富文本字段
+      const submitData = { ...form.value };
+      if (submitData.introduction) {
+        submitData.introduction = btoa(encodeURIComponent(submitData.introduction));
+      }
+      if (submitData.orderInstruction) {
+        submitData.orderInstruction = btoa(encodeURIComponent(submitData.orderInstruction));
+      }
+
       buttonLoading.value = true;
-      if (form.value.id) {
-        await updateService(form.value).finally(() => (buttonLoading.value = false));
+      if (submitData.id) {
+        await updateService(submitData).finally(() => (buttonLoading.value = false));
       } else {
-        await addService(form.value).finally(() => (buttonLoading.value = false));
+        await addService(submitData).finally(() => (buttonLoading.value = false));
       }
       proxy?.$modal.msgSuccess('操作成功');
       dialog.visible = false;
@@ -276,6 +352,7 @@ const handleDelete = async (row: ServiceVO) => {
 onMounted(() => {
   getList();
   getModeList();
+  getClassificationList();
 });
 </script>
 
@@ -289,7 +366,7 @@ onMounted(() => {
 .table-card {
   border: none;
   border-radius: 8px;
-  
+
   :deep(.el-card__header) {
     padding: 20px 24px;
     border-bottom: 1px solid #f0f0f0;
@@ -347,18 +424,21 @@ onMounted(() => {
   margin-bottom: 12px;
   background-color: #f8f9fb;
   border: 1px solid #ebeef5;
-  
+
   .step-header {
     font-size: 13px;
     font-weight: 600;
     color: #606266;
   }
-  
+
   .inner-form-item {
     margin-bottom: 12px;
-    &.last { margin-bottom: 0; }
+
+    &.last {
+      margin-bottom: 0;
+    }
   }
-  
+
   :deep(.el-card__header) {
     padding: 8px 16px;
     background-color: #f0f2f5;
@@ -367,11 +447,11 @@ onMounted(() => {
 
 :deep(.el-table) {
   --el-table-border-color: #f0f0f0;
-  
+
   th.el-table__cell {
     font-weight: 600;
   }
-  
+
   td.el-table__cell {
     padding: 12px 0;
   }

+ 5 - 2
src/views/systemConfig/protocol/index.vue

@@ -5,8 +5,10 @@
       <el-alert :closable="false" type="info" class="custom-alert">
         <template #title>
           <div class="alert-content">
-            <el-icon class="info-icon"><InfoFilled /></el-icon>
-            <span>协议配置:目前支持用户协议、隐私政策、履约者说明;请确保内容准确合规。</span>
+            <el-icon class="info-icon">
+              <InfoFilled />
+            </el-icon>
+            <span>协议配置:目前支持用户协议、隐私政策、履约者说明、托运协议;请确保内容准确合规。</span>
           </div>
         </template>
       </el-alert>
@@ -23,6 +25,7 @@
             <el-radio :label="1" border>用户协议</el-radio>
             <el-radio :label="2" border>隐私政策</el-radio>
             <el-radio :label="3" border>履约者说明</el-radio>
+            <el-radio :label="4" border>托运协议</el-radio>
           </el-radio-group>
         </el-form-item>
 

+ 6 - 6
src/views/tool/gen/basicInfoForm.vue

@@ -1,29 +1,29 @@
 <template>
   <el-form ref="basicInfoForm" :model="infoForm" :rules="rules" label-width="150px">
-    <el-row>
+    <el-row :gutter="16">
       <el-col :span="12">
         <el-form-item label="表名称" prop="tableName">
-          <el-input v-model="infoForm.tableName" placeholder="请输入仓库名称" />
+          <el-input v-model="infoForm.tableName" placeholder="请输入表名称" style="width: 100%;" />
         </el-form-item>
       </el-col>
       <el-col :span="12">
         <el-form-item label="表描述" prop="tableComment">
-          <el-input v-model="infoForm.tableComment" placeholder="请输入" />
+          <el-input v-model="infoForm.tableComment" placeholder="请输入表描述" style="width: 100%;" />
         </el-form-item>
       </el-col>
       <el-col :span="12">
         <el-form-item label="实体类名称" prop="className">
-          <el-input v-model="infoForm.className" placeholder="请输入" />
+          <el-input v-model="infoForm.className" placeholder="请输入实体类名称" style="width: 100%;" />
         </el-form-item>
       </el-col>
       <el-col :span="12">
         <el-form-item label="作者" prop="functionAuthor">
-          <el-input v-model="infoForm.functionAuthor" placeholder="请输入" />
+          <el-input v-model="infoForm.functionAuthor" placeholder="请输入作者" style="width: 100%;" />
         </el-form-item>
       </el-col>
       <el-col :span="24">
         <el-form-item label="备注" prop="remark">
-          <el-input v-model="infoForm.remark" type="textarea" :rows="3"></el-input>
+          <el-input v-model="infoForm.remark" type="textarea" :rows="3" placeholder="请输入备注" style="width: 100%;"></el-input>
         </el-form-item>
       </el-col>
     </el-row>

+ 13 - 15
src/views/tool/gen/editTable.vue

@@ -1,12 +1,12 @@
 <template>
-  <el-card>
-    <el-tabs v-model="activeName">
+  <el-card shadow="hover">
+    <el-tabs v-model="activeName" type="border-card">
       <el-tab-pane label="基本信息" name="basic">
         <basic-info-form ref="basicInfo" :info="info" />
       </el-tab-pane>
       <el-tab-pane label="字段信息" name="columnInfo">
-        <el-table ref="dragTable" border :data="columns" row-key="columnId" :max-height="tableHeight">
-          <el-table-column label="序号" type="index" min-width="5%" />
+        <el-table ref="dragTable" border stripe :data="columns" row-key="columnId" :max-height="tableHeight">
+          <el-table-column label="序号" type="index" min-width="5%" align="center" />
           <el-table-column label="字段列名" prop="columnName" min-width="10%" :show-overflow-tooltip="true" />
           <el-table-column label="字段描述" min-width="10%">
             <template #default="scope">
@@ -33,22 +33,22 @@
             </template>
           </el-table-column>
 
-          <el-table-column label="插入" min-width="5%">
+          <el-table-column label="插入" min-width="5%" align="center">
             <template #default="scope">
               <el-checkbox v-model="scope.row.isInsert" true-value="1" false-value="0"></el-checkbox>
             </template>
           </el-table-column>
-          <el-table-column label="编辑" min-width="5%">
+          <el-table-column label="编辑" min-width="5%" align="center">
             <template #default="scope">
               <el-checkbox v-model="scope.row.isEdit" true-value="1" false-value="0"></el-checkbox>
             </template>
           </el-table-column>
-          <el-table-column label="列表" min-width="5%">
+          <el-table-column label="列表" min-width="5%" align="center">
             <template #default="scope">
               <el-checkbox v-model="scope.row.isList" true-value="1" false-value="0"></el-checkbox>
             </template>
           </el-table-column>
-          <el-table-column label="查询" min-width="5%">
+          <el-table-column label="查询" min-width="5%" align="center">
             <template #default="scope">
               <el-checkbox v-model="scope.row.isQuery" true-value="1" false-value="0"></el-checkbox>
             </template>
@@ -67,7 +67,7 @@
               </el-select>
             </template>
           </el-table-column>
-          <el-table-column label="必填" min-width="5%">
+          <el-table-column label="必填" min-width="5%" align="center">
             <template #default="scope">
               <el-checkbox v-model="scope.row.isRequired" true-value="1" false-value="0"></el-checkbox>
             </template>
@@ -104,12 +104,10 @@
         <gen-info-form ref="genInfo" :info="info" :tables="tables" />
       </el-tab-pane>
     </el-tabs>
-    <el-form label-width="100px">
-      <div style="text-align: center; margin-left: -100px; margin-top: 10px">
-        <el-button type="primary" @click="submitForm()">提交</el-button>
-        <el-button @click="close()">返回</el-button>
-      </div>
-    </el-form>
+    <div style="display: flex; justify-content: center; gap: 12px; margin-top: 20px; padding: 16px 0; border-top: 1px solid #e4e7ed;">
+      <el-button type="primary" size="default" @click="submitForm()">提交</el-button>
+      <el-button size="default" @click="close()">返回</el-button>
+    </div>
   </el-card>
 </template>
 

+ 17 - 16
src/views/tool/gen/genInfoForm.vue

@@ -1,10 +1,10 @@
 <template>
   <el-form ref="genInfoForm" :model="infoForm" :rules="rules" label-width="150px">
-    <el-row>
+    <el-row :gutter="16">
       <el-col :span="12">
         <el-form-item prop="tplCategory">
           <template #label>生成模板</template>
-          <el-select v-model="infoForm.tplCategory" @change="tplSelectChange">
+          <el-select v-model="infoForm.tplCategory" @change="tplSelectChange" style="width: 100%;">
             <el-option label="单表(增删改查)" value="crud" />
             <el-option label="树表(增删改查)" value="tree" />
           </el-select>
@@ -19,7 +19,7 @@
               <el-icon><question-filled /></el-icon>
             </el-tooltip>
           </template>
-          <el-input v-model="infoForm.packageName" />
+          <el-input v-model="infoForm.packageName" style="width: 100%;" />
         </el-form-item>
       </el-col>
 
@@ -31,7 +31,7 @@
               <el-icon><question-filled /></el-icon>
             </el-tooltip>
           </template>
-          <el-input v-model="infoForm.moduleName" />
+          <el-input v-model="infoForm.moduleName" style="width: 100%;" />
         </el-form-item>
       </el-col>
 
@@ -43,7 +43,7 @@
               <el-icon><question-filled /></el-icon>
             </el-tooltip>
           </template>
-          <el-input v-model="infoForm.businessName" />
+          <el-input v-model="infoForm.businessName" style="width: 100%;" />
         </el-form-item>
       </el-col>
 
@@ -55,7 +55,7 @@
               <el-icon><question-filled /></el-icon>
             </el-tooltip>
           </template>
-          <el-input v-model="infoForm.functionName" />
+          <el-input v-model="infoForm.functionName" style="width: 100%;" />
         </el-form-item>
       </el-col>
 
@@ -67,7 +67,7 @@
               <el-icon><question-filled /></el-icon>
             </el-tooltip>
           </template>
-          <el-select v-model="infoForm.platformId" placeholder="请选择平台" @change="handlePlatformChange">
+          <el-select v-model="infoForm.platformId" placeholder="请选择平台" @change="handlePlatformChange" style="width: 100%;">
             <el-option v-for="platform in platformOptions" :key="platform.id" :label="platform.label" :value="platform.id" />
           </el-select>
         </el-form-item>
@@ -92,6 +92,7 @@
             filterable
             clearable
             highlight-current
+            style="width: 100%;"
           />
         </el-form-item>
       </el-col>
@@ -137,8 +138,8 @@
     </el-row>
 
     <template v-if="info.tplCategory == 'tree'">
-      <h4 class="form-header">其他信息</h4>
-      <el-row v-show="info.tplCategory == 'tree'">
+      <h4 class="form-header" style="margin: 20px 0 16px 0; padding-bottom: 8px; border-bottom: 1px solid #e4e7ed; color: #303133;">其他信息</h4>
+      <el-row v-show="info.tplCategory == 'tree'" :gutter="16">
         <el-col :span="12">
           <el-form-item>
             <template #label>
@@ -147,7 +148,7 @@
                 <el-icon><question-filled /></el-icon>
               </el-tooltip>
             </template>
-            <el-select v-model="infoForm.treeCode" placeholder="请选择">
+            <el-select v-model="infoForm.treeCode" placeholder="请选择" style="width: 100%;">
               <el-option
                 v-for="(column, index) in info.columns"
                 :key="index"
@@ -165,7 +166,7 @@
                 <el-icon><question-filled /></el-icon>
               </el-tooltip>
             </template>
-            <el-select v-model="infoForm.treeParentCode" placeholder="请选择">
+            <el-select v-model="infoForm.treeParentCode" placeholder="请选择" style="width: 100%;">
               <el-option
                 v-for="(column, index) in infoForm.columns"
                 :key="index"
@@ -183,7 +184,7 @@
                 <el-icon><question-filled /></el-icon>
               </el-tooltip>
             </template>
-            <el-select v-model="infoForm.treeName" placeholder="请选择">
+            <el-select v-model="infoForm.treeName" placeholder="请选择" style="width: 100%;">
               <el-option
                 v-for="(column, index) in info.columns"
                 :key="index"
@@ -197,8 +198,8 @@
     </template>
 
     <template v-if="info.tplCategory == 'sub'">
-      <h4 class="form-header">关联信息</h4>
-      <el-row>
+      <h4 class="form-header" style="margin: 20px 0 16px 0; padding-bottom: 8px; border-bottom: 1px solid #e4e7ed; color: #303133;">关联信息</h4>
+      <el-row :gutter="16">
         <el-col :span="12">
           <el-form-item>
             <template #label>
@@ -207,7 +208,7 @@
                 <el-icon><question-filled /></el-icon>
               </el-tooltip>
             </template>
-            <el-select v-model="infoForm.subTableName" placeholder="请选择" @change="subSelectChange">
+            <el-select v-model="infoForm.subTableName" placeholder="请选择" @change="subSelectChange" style="width: 100%;">
               <el-option v-for="(t, index) in table" :key="index" :label="t.tableName + ':' + t.tableComment" :value="t.tableName"></el-option>
             </el-select>
           </el-form-item>
@@ -220,7 +221,7 @@
                 <el-icon><question-filled /></el-icon>
               </el-tooltip>
             </template>
-            <el-select v-model="infoForm.subTableFkName" placeholder="请选择">
+            <el-select v-model="infoForm.subTableFkName" placeholder="请选择" style="width: 100%;">
               <el-option
                 v-for="(column, index) in subColumns"
                 :key="index"

+ 15 - 15
src/views/tool/gen/importTable.vue

@@ -1,30 +1,30 @@
 <template>
   <!-- 导入表 -->
   <el-dialog v-model="visible" title="导入表" width="1100px" top="5vh" append-to-body>
-    <el-form ref="queryFormRef" :model="queryParams" :inline="true">
-      <el-form-item label="数据源" prop="dataName">
-        <el-select v-model="queryParams.dataName" filterable placeholder="请选择/输入数据源名称">
+    <el-form ref="queryFormRef" :model="queryParams" :inline="true" style="display: flex; flex-wrap: wrap; gap: 8px;">
+      <el-form-item label="数据源" prop="dataName" style="margin-bottom: 8px;">
+        <el-select v-model="queryParams.dataName" filterable placeholder="请选择/输入数据源名称" style="width: 180px;">
           <el-option v-for="item in dataNameList" :key="item" :label="item" :value="item"> </el-option>
         </el-select>
       </el-form-item>
-      <el-form-item label="表名称" prop="tableName">
-        <el-input v-model="queryParams.tableName" placeholder="请输入表名称" clearable @keyup.enter="handleQuery" />
+      <el-form-item label="表名称" prop="tableName" style="margin-bottom: 8px;">
+        <el-input v-model="queryParams.tableName" placeholder="请输入表名称" clearable @keyup.enter="handleQuery" style="width: 180px;" />
       </el-form-item>
-      <el-form-item label="表描述" prop="tableComment">
-        <el-input v-model="queryParams.tableComment" placeholder="请输入表描述" clearable @keyup.enter="handleQuery" />
+      <el-form-item label="表描述" prop="tableComment" style="margin-bottom: 8px;">
+        <el-input v-model="queryParams.tableComment" placeholder="请输入表描述" clearable @keyup.enter="handleQuery" style="width: 180px;" />
       </el-form-item>
-      <el-form-item>
+      <el-form-item style="margin-bottom: 8px; margin-left: auto;">
         <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
         <el-button icon="Refresh" @click="resetQuery">重置</el-button>
       </el-form-item>
     </el-form>
-    <el-row>
-      <el-table ref="tableRef" border :data="dbTableList" height="260px" @row-click="clickRow" @selection-change="handleSelectionChange">
-        <el-table-column type="selection" width="55"></el-table-column>
-        <el-table-column prop="tableName" label="表名称" :show-overflow-tooltip="true"></el-table-column>
-        <el-table-column prop="tableComment" label="表描述" :show-overflow-tooltip="true"></el-table-column>
-        <el-table-column prop="createTime" label="创建时间"></el-table-column>
-        <el-table-column prop="updateTime" label="更新时间"></el-table-column>
+    <el-row style="margin-top: 12px;">
+      <el-table ref="tableRef" border :data="dbTableList" height="260px" @row-click="clickRow" @selection-change="handleSelectionChange" stripe>
+        <el-table-column type="selection" width="55" align="center"></el-table-column>
+        <el-table-column prop="tableName" label="表名称" :show-overflow-tooltip="true" min-width="150"></el-table-column>
+        <el-table-column prop="tableComment" label="表描述" :show-overflow-tooltip="true" min-width="150"></el-table-column>
+        <el-table-column prop="createTime" label="创建时间" width="160" align="center"></el-table-column>
+        <el-table-column prop="updateTime" label="更新时间" width="160" align="center"></el-table-column>
       </el-table>
       <pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
     </el-row>

+ 219 - 79
src/views/tool/gen/index.vue

@@ -1,91 +1,101 @@
 <template>
-  <div class="p-2">
+  <div class="gen-container">
     <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-      <div v-show="showSearch" class="mb-[10px]">
-        <el-card shadow="hover">
-          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
-            <el-form-item label="数据源" prop="dataName">
-              <el-select v-model="queryParams.dataName" filterable clearable placeholder="请选择/输入数据源名称">
-                <el-option key="" label="全部" value="" />
-                <el-option v-for="item in dataNameList" :key="item" :label="item" :value="item"> </el-option>
-              </el-select>
-            </el-form-item>
-            <el-form-item label="表名称" prop="tableName">
-              <el-input v-model="queryParams.tableName" placeholder="请输入表名称" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="表描述" prop="tableComment">
-              <el-input v-model="queryParams.tableComment" placeholder="请输入表描述" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="创建时间" style="width: 308px">
-              <el-date-picker
-                v-model="dateRange"
-                value-format="YYYY-MM-DD"
-                type="daterange"
-                range-separator="-"
-                start-placeholder="开始日期"
-                end-placeholder="结束日期"
-              ></el-date-picker>
-            </el-form-item>
-            <el-form-item>
-              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-            </el-form-item>
+      <div v-show="showSearch" class="search-wrapper">
+        <el-card shadow="hover" class="search-card">
+          <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="80px">
+            <el-row :gutter="20">
+              <el-col :span="6">
+                <el-form-item label="数据源" prop="dataName">
+                  <el-select v-model="queryParams.dataName" filterable clearable placeholder="请选择数据源" style="width: 100%">
+                    <el-option key="" label="全部" value="" />
+                    <el-option v-for="item in dataNameList" :key="item" :label="item" :value="item"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="表名称" prop="tableName">
+                  <el-input v-model="queryParams.tableName" placeholder="请输入表名称" clearable @keyup.enter="handleQuery" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="表描述" prop="tableComment">
+                  <el-input v-model="queryParams.tableComment" placeholder="请输入表描述" clearable @keyup.enter="handleQuery" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="创建时间" prop="dateRange">
+                  <el-date-picker
+                    v-model="dateRange"
+                    value-format="YYYY-MM-DD"
+                    type="daterange"
+                    range-separator="-"
+                    start-placeholder="开始日期"
+                    end-placeholder="结束日期"
+                    style="width: 100%"
+                  ></el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="24" class="search-btn-group">
+                <el-button type="primary" @click="handleQuery">搜索</el-button>
+                <el-button @click="resetQuery">重置</el-button>
+              </el-col>
+            </el-row>
           </el-form>
         </el-card>
       </div>
     </transition>
 
-    <el-card shadow="hover">
+    <el-card shadow="hover" class="table-card">
       <template #header>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="1.5">
-            <el-button v-hasPermi="['tool:gen:code']" type="primary" plain icon="Download" @click="handleGenTable()">生成</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button v-hasPermi="['tool:gen:import']" type="info" plain icon="Upload" @click="openImportTable">导入</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button v-hasPermi="['tool:gen:edit']" type="success" plain icon="Edit" :disabled="single" @click="handleEditTable()">修改</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button v-hasPermi="['tool:gen:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">
-              删除
-            </el-button>
-          </el-col>
-          <right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
-        </el-row>
+        <div class="card-header">
+          <div class="header-left">
+            <span class="header-title">代码生成列表</span>
+          </div>
+          <div class="header-right">
+            <el-button v-hasPermi="['tool:gen:code']" type="primary" size="small" @click="handleGenTable()">生成代码</el-button>
+            <el-button v-hasPermi="['tool:gen:import']" type="success" size="small" @click="openImportTable">导入表</el-button>
+            <el-button v-hasPermi="['tool:gen:edit']" type="warning" size="small" :disabled="single" @click="handleEditTable()">修改</el-button>
+            <el-button v-hasPermi="['tool:gen:remove']" type="danger" size="small" :disabled="multiple" @click="handleDelete()">删除</el-button>
+            <right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
+          </div>
+        </div>
       </template>
 
-      <el-table v-loading="loading" border :data="tableList" @selection-change="handleSelectionChange">
+      <el-table v-loading="loading" :data="tableList" stripe @selection-change="handleSelectionChange" class="gen-table">
         <el-table-column type="selection" align="center" width="55"></el-table-column>
-        <el-table-column label="序号" type="index" width="50" align="center">
+        <el-table-column label="序号" type="index" width="60" align="center">
           <template #default="scope">
             <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="数据源" align="center" prop="dataName" :show-overflow-tooltip="true" />
-        <el-table-column label="表名称" align="center" prop="tableName" :show-overflow-tooltip="true" />
-        <el-table-column label="表描述" align="center" prop="tableComment" :show-overflow-tooltip="true" />
-        <el-table-column label="实体" align="center" prop="className" :show-overflow-tooltip="true" />
+        <el-table-column label="数据源" align="center" prop="dataName" :show-overflow-tooltip="true" width="120">
+          <template #default="{ row }">
+            <el-tag size="small" effect="plain">{{ row.dataName || '默认' }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="表名称" align="center" prop="tableName" :show-overflow-tooltip="true" min-width="150">
+          <template #default="{ row }">
+            <span class="table-name">{{ row.tableName }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="表描述" align="center" prop="tableComment" :show-overflow-tooltip="true" min-width="150" />
+        <el-table-column label="实体类名" align="center" prop="className" :show-overflow-tooltip="true" min-width="150">
+          <template #default="{ row }">
+            <el-tag type="info" size="small" effect="plain">{{ row.className }}</el-tag>
+          </template>
+        </el-table-column>
         <el-table-column label="创建时间" align="center" prop="createTime" width="160" />
         <el-table-column label="更新时间" align="center" prop="updateTime" width="160" />
-        <el-table-column label="操作" align="center" width="330" class-name="small-padding fixed-width">
+        <el-table-column label="操作" align="center" width="260" fixed="right">
           <template #default="scope">
-            <el-tooltip content="预览" placement="top">
-              <el-button v-hasPermi="['tool:gen:preview']" link type="primary" icon="View" @click="handlePreview(scope.row)"></el-button>
-            </el-tooltip>
-            <el-tooltip content="编辑" placement="top">
-              <el-button v-hasPermi="['tool:gen:edit']" link type="primary" icon="Edit" @click="handleEditTable(scope.row)"></el-button>
-            </el-tooltip>
-            <el-tooltip content="删除" placement="top">
-              <el-button v-hasPermi="['tool:gen:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
-            </el-tooltip>
-            <el-tooltip content="同步" placement="top">
-              <el-button v-hasPermi="['tool:gen:edit']" link type="primary" icon="Refresh" @click="handleSynchDb(scope.row)"></el-button>
-            </el-tooltip>
-            <el-tooltip content="生成代码" placement="top">
-              <el-button v-hasPermi="['tool:gen:code']" link type="primary" icon="Download" @click="handleGenTable(scope.row)"></el-button>
-            </el-tooltip>
+            <el-button v-hasPermi="['tool:gen:preview']" link type="primary" size="small" @click="handlePreview(scope.row)">预览</el-button>
+            <el-button v-hasPermi="['tool:gen:edit']" link type="primary" size="small" @click="handleEditTable(scope.row)">编辑</el-button>
+            <el-button v-hasPermi="['tool:gen:edit']" link type="warning" size="small" @click="handleSynchDb(scope.row)">同步</el-button>
+            <el-button v-hasPermi="['tool:gen:code']" link type="success" size="small" @click="handleGenTable(scope.row)">生成</el-button>
+            <el-button v-hasPermi="['tool:gen:remove']" link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -93,18 +103,23 @@
     </el-card>
 
     <!-- 预览界面 -->
-    <el-dialog v-model="dialog.visible" :title="dialog.title" width="80%" top="5vh" append-to-body class="scrollbar">
-      <el-tabs v-model="preview.activeName">
+    <el-dialog v-model="dialog.visible" :title="dialog.title" width="85%" top="5vh" append-to-body class="preview-dialog">
+      <el-tabs v-model="preview.activeName" type="border-card" class="preview-tabs">
         <el-tab-pane
           v-for="(value, key) in preview.data"
           :key="value"
           :label="key.substring(key.lastIndexOf('/') + 1, key.indexOf('.vm'))"
           :name="key.substring(key.lastIndexOf('/') + 1, key.indexOf('.vm'))"
         >
-          <el-link v-copyText="value" v-copyText:callback="copyTextSuccess" :underline="false" icon="DocumentCopy" style="float: right">
-            &nbsp;复制
-          </el-link>
-          <highlightjs :code="value" />
+          <div class="code-header">
+            <span class="file-name">{{ key.substring(key.lastIndexOf('/') + 1, key.indexOf('.vm')) }}</span>
+            <el-button v-copyText="value" v-copyText:callback="copyTextSuccess" type="primary" size="small">
+              复制代码
+            </el-button>
+          </div>
+          <div class="code-content">
+            <highlightjs :code="value" />
+          </div>
         </el-tab-pane>
       </el-tabs>
     </el-dialog>
@@ -225,6 +240,10 @@ const handleSelectionChange = (selection: TableVO[]) => {
 /** 修改按钮操作 */
 const handleEditTable = (row?: TableVO) => {
   const tableId = row?.tableId || ids.value[0];
+  if (!tableId) {
+    proxy?.$modal.msgError('请选择要修改的数据');
+    return;
+  }
   router.push({ path: '/tool/gen-edit/index/' + tableId, query: { pageNum: queryParams.value.pageNum } });
 };
 /** 删除按钮操作 */
@@ -250,10 +269,131 @@ onMounted(() => {
 </script>
 
 <style lang="scss" scoped>
-.el-tab-pane {
+.gen-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: calc(100vh - 84px);
+}
+
+.search-wrapper {
+  margin-bottom: 20px;
+}
+
+.search-card {
+  :deep(.el-card__body) {
+    padding: 20px;
+  }
+}
+
+.search-btn-group {
+  text-align: right;
+  padding-top: 10px;
+}
+
+.table-card {
+  :deep(.el-card__header) {
+    padding: 16px 20px;
+    border-bottom: 1px solid #f0f0f0;
+  }
+
+  :deep(.el-card__body) {
+    padding: 0;
+  }
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+
+  .header-left {
+    .header-title {
+      font-size: 16px;
+      font-weight: 600;
+      color: #303133;
+    }
+  }
+
+  .header-right {
+    display: flex;
+    gap: 8px;
+    align-items: center;
+    flex-wrap: nowrap;
+  }
+}
+
+.gen-table {
+  :deep(.el-table__header) {
+    th {
+      background-color: #f5f7fa;
+      color: #606266;
+      font-weight: 600;
+    }
+  }
+
+  .table-name {
+    color: #409eff;
+    font-weight: 500;
+  }
+}
+
+.preview-dialog {
+  :deep(.el-dialog__body) {
+    padding: 0;
+  }
+}
+
+.preview-tabs {
+  border: none;
+  box-shadow: none;
+
+  :deep(.el-tabs__header) {
+    background-color: #f5f7fa;
+    border-bottom: 1px solid #e4e7ed;
+    margin: 0;
+  }
+
+  :deep(.el-tabs__content) {
+    padding: 0;
+  }
+
+  :deep(.el-tab-pane) {
+    background-color: #282c34;
+    min-height: 500px;
+  }
+}
+
+.code-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 12px 20px;
+  background-color: #21252b;
+  border-bottom: 1px solid #181a1f;
+
+  .file-name {
+    color: #abb2bf;
+    font-size: 14px;
+    font-weight: 500;
+  }
+}
+
+.code-content {
+  padding: 20px;
   background-color: #282c34;
-  .el-link {
-    color: #fff;
+  overflow-x: auto;
+
+  :deep(pre) {
+    margin: 0;
+    background-color: transparent !important;
+  }
+
+  :deep(code) {
+    background-color: transparent !important;
+    color: #abb2bf;
+    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
+    font-size: 13px;
+    line-height: 1.6;
   }
 }
 </style>