zhangjq
2026-01-29 39b0bebd8aa7311c4c95454749b94bed9c70301f
欢迎页面,和一些布局修改还有合同停止按钮
29个文件已修改
1个文件已添加
1383 ■■■■■ 已修改文件
src/layouts/default/header/components/ErrorAction.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/header/components/notify/index.vue 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/lang/en/routes/dashboard.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/lang/zh-CN/routes/dashboard.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/guard/permissionGuard.ts 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/routes/index.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/routes/modules/about.ts 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/routes/modules/dashboard.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/user.ts 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ContractCW/Contract.data.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ContractCW/ContractList.vue 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contract/ContractList.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contractDL/ContractList.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/copywriting/CopywritingList.vue 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/copywritingReview/CopywritingList.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/Analysis/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/Welcome/index.vue 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/datacabin/StatsCard.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/datacabin/index.vue 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/desc/detailkehu/index.vue 632 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/desc/editkehu/index.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ranking/rankingOff/RankingOff.data.ts 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ranking/rankingOff/index.vue 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ranking/rankingOn/RankingOn.data.ts 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ranking/rankingOn/index.vue 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/semanticword/SemanticWord.data.ts 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/semanticword/SemanticWordList.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/semanticwordFP/SemanticWord.data.ts 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/semanticwordFP/SemanticWordList.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/semanticwordPD/SemanticWordList.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/header/components/ErrorAction.vue
@@ -1,6 +1,6 @@
<template>
  <Tooltip :title="t('layout.header.tooltipErrorLog')" placement="bottom" :mouseEnterDelay="0.5" @click="handleToErrorList">
    <Badge :count="getCount" :offset="[0, 10]" :overflowCount="99">
    <Badge :count="0" :offset="[0, 10]" :overflowCount="99">
      <Icon icon="ion:bug-outline" />
    </Badge>
  </Tooltip>
src/layouts/default/header/components/notify/index.vue
@@ -12,11 +12,10 @@
</template>
<script lang="ts">
  import { computed, defineComponent, ref, unref, reactive, onMounted, getCurrentInstance } from 'vue';
  import { Popover, Tabs, Badge } from 'ant-design-vue';
  import { Badge } from 'ant-design-vue';
  import { BellOutlined } from '@ant-design/icons-vue';
  import { tabListData } from './data';
  import { listCementByUser, editCementSend } from './notify.api';
  import NoticeList from './NoticeList.vue';
  import DetailModal from '/@/views/monitor/mynews/DetailModal.vue';
  import DynamicNotice from '/@/views/monitor/mynews/DynamicNotice.vue';
  import { useModal } from '/@/components/Modal';
@@ -24,7 +23,6 @@
  import { useGlobSetting } from '/@/hooks/setting';
  import { useUserStore } from '/@/store/modules/user';
  import { connectWebSocket, onWebSocket } from '/@/hooks/web/useWebSocket';
  import { readAllMsg } from '/@/views/monitor/mynews/mynews.api';
  import { getToken } from '/@/utils/auth';
  import md5 from 'crypto-js/md5';
@@ -32,12 +30,8 @@
  export default defineComponent({
    components: {
      Popover,
      BellOutlined,
      Tabs,
      TabPane: Tabs.TabPane,
      Badge,
      NoticeList,
      DetailModal,
      DynamicNotice,
      SysMessageModal,
@@ -51,11 +45,7 @@
      const [registerDetail, detailModal] = useModal();
      const listData = ref(tabListData);
      const count = computed(() => {
        let count = 0;
        for (let i = 0; i < listData.value.length; i++) {
          count += listData.value[i].count;
        }
        return count;
        return 0;
      });
      const [registerMessageModal, { openModal: openMessageModal }] = useModal();
@@ -67,7 +57,6 @@
        openMessageModal(true, {});
      }
      const popoverVisible = ref<boolean>(false);
      onMounted(() => {
        initWebSocket();
      });
@@ -84,13 +73,14 @@
      // 获取系统消息
      async function loadData() {
        try {
          let { anntMsgList, sysMsgList, anntMsgTotal, sysMsgTotal } = await listCementByUser({
          let { anntMsgList, sysMsgList } = await listCementByUser({
            pageSize: 5,
          });
          listData.value[0].list = anntMsgList.map(mapAnnouncement);
          listData.value[1].list = sysMsgList.map(mapAnnouncement);
          listData.value[0].count = anntMsgTotal;
          listData.value[1].count = sysMsgTotal;
          // 始终设置count为0,不显示通知数字
          listData.value[0].count = 0;
          listData.value[1].count = 0;
        } catch (e) {
          console.warn('系统消息通知异常:', e);
        }
@@ -115,7 +105,6 @@
            isUpdate: true,
          });
        }
        popoverVisible.value = false;
      }
      // 初始化 WebSocket
@@ -141,11 +130,6 @@
        }
      }
      // 清空消息
      function onEmptyNotify() {
        popoverVisible.value = false;
        readAllMsg({}, loadData);
      }
      async function reloadCount(id) {
        try {
          await editCementSend(id);
@@ -163,9 +147,7 @@
        registerMessageModal,
        reloadCount,
        onNoticeClick,
        onEmptyNotify,
        numberStyle: {},
        popoverVisible,
        registerDetail,
        dynamicNoticeProps,
      };
src/locales/lang/en/routes/dashboard.ts
@@ -3,4 +3,5 @@
  about: 'About',
  workbench: 'Workbench',
  analysis: 'Analysis',
  welcome: 'Welcome',
};
src/locales/lang/zh-CN/routes/dashboard.ts
@@ -3,4 +3,5 @@
  about: '关于',
  workbench: '工作台',
  analysis: '分析页',
  welcome: '欢迎',
};
src/router/guard/permissionGuard.ts
@@ -28,7 +28,7 @@
//update-begin---author:wangshuai ---date:20220629  for:[issues/I5BG1I]vue3不支持auth2登录------------
//update-begin---author:wangshuai ---date:20221111  for: [VUEN-2472]分享免登录------------
const whitePathList: PageEnum[] = [LOGIN_PATH, OAUTH2_LOGIN_PAGE_PATH,SYS_FILES_PATH, TOKEN_LOGIN ];
const whitePathList: PageEnum[] = [LOGIN_PATH, OAUTH2_LOGIN_PAGE_PATH, SYS_FILES_PATH, TOKEN_LOGIN];
//update-end---author:wangshuai ---date:20221111  for: [VUEN-2472]分享免登录------------
//update-end---author:wangshuai ---date:20220629  for:[issues/I5BG1I]vue3不支持auth2登录------------
@@ -40,6 +40,8 @@
  let homePathJumpCount = 0;
  router.beforeEach(async (to, from, next) => {
    const userInfo = userStore.getUserInfo;
    if (
      // 【#6861】跳转到自定义首页的逻辑,只跳转一次即可
      homePathJumpCount < 1 &&
@@ -48,6 +50,11 @@
      userStore.getUserInfo.homePath &&
      userStore.getUserInfo.homePath !== PageEnum.BASE_HOME
    ) {
      // 代理商用户跳过homePath跳转
      if (userInfo?.username === 'dls') {
        next({ path: '/dashboard/welcome', replace: true });
        return;
      }
      homePathJumpCount++;
      next(userStore.getUserInfo.homePath);
      return;
src/router/routes/index.ts
@@ -66,7 +66,7 @@
};
// Basic routing without permission
export const basicRoutes = [
export const basicRoutes: AppRouteRecordRaw[] = [
  LoginRoute,
  RootRoute,
  ...mainOutRoutes,
src/router/routes/modules/about.ts
@@ -3,29 +3,45 @@
import { LAYOUT } from '/@/router/constant';
import { t } from '/@/hooks/web/useI18n';
const dashboard: AppRouteModule = {
const about: AppRouteModule = {
  path: '/about',
  name: 'About',
  component: LAYOUT,
  redirect: '/about/index',
  redirect: '/about/welcome',
  meta: {
    hideChildrenInMenu: true,
    icon: 'simple-icons:about-dot-me',
    title: t('routes.dashboard.about'),
    orderNo: 100000,
    orderNo: 100,
    icon: 'ion:home-outline',
    title: '导航',
  },
  children: [
    {
      path: 'index',
      name: 'AboutPage',
      component: () => import('/@/views/sys/about/index.vue'),
      path: 'welcome',
      name: 'AboutWelcome',
      component: () => import('/@/views/dashboard/Welcome/index.vue'),
      meta: {
        title: t('routes.dashboard.about'),
        icon: 'simple-icons:about-dot-me',
        hideMenu: true,
        title: '欢迎',
        ignoreKeepAlive: true,
      },
    },
    {
      path: 'test',
      name: 'AboutTest',
      meta: {
        title: '测试',
        ignoreKeepAlive: true,
      },
      component: () => import('/@/views/demo/system/test/index.vue'),
    },
    {
      path: 'account',
      name: 'AboutAccount',
      meta: {
        title: '账号',
        ignoreKeepAlive: false,
      },
      component: () => import('/@/views/demo/system/account/index.vue'),
    },
  ],
};
export default dashboard;
export default about;
src/router/routes/modules/dashboard.ts
@@ -15,6 +15,14 @@
  },
  children: [
    {
      path: 'welcome',
      name: 'Welcome',
      component: () => import('/@/views/dashboard/Welcome/index.vue'),
      meta: {
        title: t('routes.dashboard.welcome'),
      },
    },
    {
      path: 'analysis',
      name: 'Analysis',
      component: () => import('/@/views/dashboard/Analysis/index.vue'),
src/store/modules/user.ts
@@ -220,10 +220,17 @@
        //update-begin---author:wangshuai---date:2024-04-03---for:【issues/1102】设置单点登录后页面,进入首页提示404,也没有绘制侧边栏 #1102---
        let ticket = getUrlParam('ticket');
        let homePath = (userInfo && userInfo.homePath) || PageEnum.BASE_HOME;
        // 代理商用户跳转到欢迎页面
        if (userInfo?.username === 'dls') {
          homePath = '/dashboard/welcome';
        }
        if(ticket){
          goHome && (window.location.replace((userInfo && userInfo.homePath) || PageEnum.BASE_HOME));
          goHome && (window.location.replace(homePath));
        }else{
          goHome && (await router.replace((userInfo && userInfo.homePath) || PageEnum.BASE_HOME));
          goHome && (await router.replace(homePath));
        }
        //update-end---author:wangshuai---date:2024-04-03---for:【issues/1102】设置单点登录后页面,进入首页提示404,也没有绘制侧边栏 #1102---
      }
src/views/ContractCW/Contract.data.ts
@@ -58,17 +58,11 @@
    label: "客户名称",
    field: "customerName",
    component: 'Input',
    componentProps: {
      style: { width: '160px' } // 增加宽度,确保标签显示完整
    },
  },
  {
    label: "代理商名称",
    field: "agentsName",
    component: 'Input',
    componentProps: {
      style: { width: '160px' } // 增加宽度,确保标签显示完整
    },
  },
  {
    label: "审核状态",
@@ -76,7 +70,6 @@
    component: 'JDictSelectTag',
    componentProps:{
      dictCode: "yuyici_status",
      style: { width: '140px'} // 增加宽度,确保标签显示完整
    },
  },
];
src/views/ContractCW/ContractList.vue
@@ -131,14 +131,16 @@
      api: list,
      columns,
      canResize: true,
     formConfig: {
  labelWidth: 90, // 设置标签宽度,确保标签显示完整
    // 找到 formConfig 部分,替换为以下完整配置
formConfig: {
  //labelWidth: 80,
  schemas: searchFormSchema,
  autoSubmitOnEnter: true,
  showAdvancedButton: true,
  autoAdvancedCol: 4,
  fieldMapToNumber: [],
  fieldMapToTime: [],
  compact: true, // 启用紧凑模式
  compact: true,
  baseColProps: {
    xs: 24,
    sm: 4,
@@ -155,10 +157,10 @@
    style: { textAlign: 'left' },
  },
},
      actionColumn: {
        width: 180,
        fixed: 'right',
      },
       actionColumn: {
         width: 180,
         fixed: 'right',
       },
      beforeFetch: (params) => {
        if (params && fieldPickers) {
          for (let key in fieldPickers) {
@@ -426,16 +428,14 @@
<style lang="less" scoped>
  :deep(.ant-picker),
  :deep(.ant-input-number) {
    width: 100%;}
     :deep(.ant-form) {
    text-align: left !important;
    width: 100%;
  }
  // 确保搜索项左对齐
  :deep(.ant-row) {
    justify-content: flex-start !important;
  /* 确保搜索表单靠左对齐 */
  :deep(.basic-table-search) {
    padding-left: 0 !important;
    margin-left: 0 !important;
  }
  .contract-select-modal {
    .contract-file-card {
src/views/contract/ContractList.vue
@@ -261,7 +261,7 @@
      columns,
      canResize: true,
      formConfig: {
        //labelWidth: 120,
        labelWidth: 80,
        schemas: searchFormSchema,
        autoSubmitOnEnter: true,
        showAdvancedButton: true,
@@ -760,6 +760,28 @@
    width: 100%;
  }
  /* 确保搜索表单完全靠左对齐,消除所有左边空隙 */
  :deep(.basic-table-search) {
    padding-left: 0 !important;
    margin-left: 0 !important;
  }
  /* 消除表单容器的左边空隙 */
  :deep(.ant-form) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 消除行容器的左边空隙 */
  :deep(.ant-form-item-row) {
    margin-left: 0 !important;
  }
  /* 消除表单项的左边空隙 */
  :deep(.ant-form-item) {
    margin-left: 0 !important;
  }
  .contract-select-modal {
    .contract-file-card {
      cursor: pointer;
src/views/contractDL/ContractList.vue
@@ -268,15 +268,15 @@
      columns,
      canResize: true,
      immediate: false, // 禁用立即加载,等待角色查询完成后再加载
      formConfig: {
  //labelWidth: 120,
  formConfig: {
  labelWidth: 80,
  schemas: searchFormSchema,
  autoSubmitOnEnter: true,
  showAdvancedButton: true,
  autoAdvancedCol: 4,
  fieldMapToNumber: [],
  fieldMapToTime: [],
  // 布局配置
  compact: true, // 启用紧凑模式
  compact: true,
  baseColProps: {
    xs: 24,
    sm: 4,
@@ -704,6 +704,13 @@
  :deep(.ant-input-number) {
    width: 100%;
  }
  /* 确保搜索表单靠左对齐 */
  :deep(.basic-table-search) {
    padding-left: 0 !important;
    margin-left: 0 !important;
  }
  .contract-select-modal {
    .contract-file-card {
      cursor: pointer;
src/views/copywriting/CopywritingList.vue
@@ -100,6 +100,22 @@
        showAdvancedButton: true,
        fieldMapToNumber: [],
        fieldMapToTime: [],
        compact: true,
        baseColProps: {
          xs: 24,
          sm: 4,
          md: 4,
          lg: 4,
          xl: 4,
          xxl: 4,
        },
        rowProps: {
          gutter: 8,
        },
        actionColOptions: {
          span: 8,
          style: { textAlign: 'left' },
        },
      },
      actionColumn: {
        width: 120,
@@ -248,4 +264,26 @@
  :deep(.ant-input-number) {
    width: 100%;
  }
  /* 确保搜索表单完全靠左对齐,消除所有左边空隙 */
  :deep(.basic-table-search) {
    padding-left: 0 !important;
    margin-left: 0 !important;
  }
  /* 消除表单容器的左边空隙 */
  :deep(.ant-form) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 消除行容器的左边空隙 */
  :deep(.ant-form-item-row) {
    margin-left: 0 !important;
  }
  /* 消除表单项的左边空隙 */
  :deep(.ant-form-item) {
    margin-left: 0 !important;
  }
</style>
src/views/copywritingReview/CopywritingList.vue
@@ -108,10 +108,23 @@
        schemas: searchFormSchema,
        autoSubmitOnEnter: true,
        showAdvancedButton: true,
        autoAdvancedCol: 4,
        fieldMapToNumber: [],
        fieldMapToTime: [],
        compact: true,
        baseColProps: {
          xs: 24,
          sm: 4,
          md: 4,
          lg: 4,
          xl: 4,
          xxl: 4,
        },
        rowProps: {
          gutter: 8,
        },
        actionColOptions: {
          span: 6,
          span: 8,
          style: { textAlign: 'left' },
        },
      },
@@ -276,4 +289,26 @@
  :deep(.ant-input-number) {
    width: 100%;
  }
  /* 确保搜索表单完全靠左对齐,消除所有左边空隙 */
  :deep(.basic-table-search) {
    padding-left: 0 !important;
    margin-left: 0 !important;
  }
  /* 消除表单容器的左边空隙 */
  :deep(.ant-form) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 消除行容器的左边空隙 */
  :deep(.ant-form-item-row) {
    margin-left: 0 !important;
  }
  /* 消除表单项的左边空隙 */
  :deep(.ant-form-item) {
    margin-left: 0 !important;
  }
</style>
src/views/dashboard/Analysis/index.vue
@@ -21,4 +21,4 @@
  import IndexTask from './homePage/IndexTask.vue';
  const indexStyle = ref(0);
</script>
</script>
src/views/dashboard/Welcome/index.vue
New file
@@ -0,0 +1,38 @@
<template>
  <div class="agent-welcome">
    <div class="welcome-content">
      <h1 class="welcome-title">您好,欢迎访问</h1>
      <h2 class="welcome-system-name">艾亿欧AIEO智能业务管理系统</h2>
    </div>
  </div>
</template>
<script lang="ts" setup>
</script>
<style lang="less" scoped>
.agent-welcome {
  min-height: calc(100vh - 120px);
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f0f2f5;
}
.welcome-content {
  text-align: center;
  padding: 40px;
}
.welcome-title {
  font-size: 32px;
  color: #333;
  margin-bottom: 20px;
}
.welcome-system-name {
  font-size: 40px;
  color: #1890ff;
  font-weight: bold;
}
</style>
src/views/datacabin/StatsCard.vue
@@ -195,7 +195,9 @@
    /* border: 1px solid #0099ff; */
    border-radius: 6px;
    /* padding: 12px; */
    width: 400px;
    flex: 0 0 auto;
    min-width: 300px;
    max-width: 400px;
  }
  .card-header {
src/views/datacabin/index.vue
@@ -50,7 +50,7 @@
      <div class="tables-container">
        <!-- 左边表格 -->
        <div class="table-section">
          <div class="table-title"><img src="./警报灯警报器.png" class="title-icon"/><strong>签约快到期企业</strong><div style="width: 40px; height: 20px; background: red; border-radius: 20px; line-height: 20px; margin-left: 10px; text-align: center; color: white; font-size: 12px; font-weight: bold;">99+</div><button>更多</button></div>
          <div class="table-title"><img src="./警报灯警报器.png" class="title-icon"/><strong>签约快到期企业</strong><button>更多</button></div>
          <div class="table-wrapper left-table">
            <table class="data-table">
              <thead>
@@ -107,7 +107,7 @@
    </div>
    <div class="attention-z">
      <h2 class="section-title" style="font-size: 20px; font-weight: bold; margin-left: 60px; color: black;">签约语义词数量概览</h2>
      <div ref="semanticChartContainer" style="margin: 0 20px 20px 20px; padding: 16px; border: 1px solid #e9ecef; border-radius: 20px; background: white;">
      <div ref="semanticChartContainer" style="margin: 0 20px 20px; padding: 16px; border: 1px solid #e9ecef; border-radius: 20px; background: white;">
        <SemanticWordCountChart />
      </div>
    </div>
@@ -1141,8 +1141,8 @@
  background: white;
  border-radius: 20px;
  border: 1px solid #e9ecef;
  margin: 0 20px 20px 20px;
  padding: 0 20px 20px 20px;
  margin: 0 20px 20px;
  padding: 0 20px 20px;
}
.filter-tab-container {
@@ -1150,7 +1150,7 @@
  flex-wrap: wrap;
  align-items: center;
  gap: 20px;
  margin-bottom: 20px;
  margin: 0 20px 20px;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 8px;
@@ -1212,6 +1212,7 @@
  gap: 20px;
  min-height: 200px;
  /* 确保加载状态有足够的空间显示 */
  margin: 0 20px;
}
.card-wrapper :deep(.ant-spin-nested-loading) {
@@ -1252,13 +1253,28 @@
.card-content {
  display: flex;
  gap: 20px;
  align-items: stretch;
  gap: 0;
  border: 2px solid #0099ff;
  border-radius: 20px;
  overflow: hidden;
  background: #fff;
}
.card-content > * {
  flex: 1;
  min-width: 0;
}
.card-content .stats-card {
  border-right: 1px solid #e9ecef;
}
.card-content .chart-container {
  display: flex;
  flex-direction: column;
}
#gege {
  position: relative;
  left: 50px;
src/views/demo/page/desc/detailkehu/index.vue
@@ -1,615 +1,41 @@
<template>
  <PageWrapper title="客户详情页" contentBackground>
    <a-card title="基本信息">
      <a-descriptions title="" :column="3">
        <a-descriptions-item label="企业名称">
          <span>{{ formData.customer?.enterpriseName || '-' }}</span>
        </a-descriptions-item>
        <a-descriptions-item label="行业">
          <span>{{ formData.customer?.industry || '-' }}</span>
        </a-descriptions-item>
        <a-descriptions-item label="客户地址">
          <span>{{ formData.customer?.customerAddress || '-' }}</span>
        </a-descriptions-item>
        <a-descriptions-item label="对接人">
          <span>{{ formData.customer?.contactPerson || '-' }}</span>
        </a-descriptions-item>
        <a-descriptions-item label="客户电话">
          <span>{{ formData.customer?.customerPhone || '-' }}</span>
        </a-descriptions-item>
        <a-descriptions-item label="客户邮箱">
          <span>{{ formData.customer?.customerEmail || '-' }}</span>
        </a-descriptions-item>
      </a-descriptions>
    </a-card>
    <a-card title="合同信息">
      <a-descriptions title="" :column="1">
        <a-descriptions-item label="紧急状态">
          <span>{{ formData.emergencyStatus === 1 ? '紧急' : formData.emergencyStatus === 3 ? '正常' : '-' }}</span>
        </a-descriptions-item>
        <a-descriptions-item label="合作周期">
          <span>{{ formData.month ? `${formData.month}月` : '-' }}</span>
        </a-descriptions-item>
        <!-- <a-descriptions-item label="合作开始时间">
          <span>{{ formData.startDate || '-' }}</span>
        </a-descriptions-item>
        <a-descriptions-item label="合作结束时间">
          <span>{{ formData.endDate || '-' }}</span>
        </a-descriptions-item> -->
        <a-descriptions-item label="合同">
          <div v-if="contractFiles.length > 0">
            <div v-for="file in contractFiles" :key="file.uid" class="file-item">
              <div class="file-header">
                <a @click="handleDownload(file)" style="display: inline-block">{{ getFileName(file) }}</a>
                <a @click="toggleFilePreview(file)" class="preview-toggle">
                  {{ isFilePreviewOpen(file) ? '收起' : '[预览]' }}
                </a>
              </div>
              <div v-if="isFilePreviewOpen(file)" class="docx-preview">
                <div v-if="isReviewFile(file) && getFileUrl(file)">
                  <vue-office-docx :src="getFileUrl(file)" style="width: 100%; height: 600px;" v-if="isDocxFile(file)"/>
                  <vue-office-excel :src="getFileUrl(file)" style="width: 100%; height: 600px;" v-if="isXlsxFile(file)"/>
                  <vue-office-pdf :src="getFileUrl(file)" style="width: 100%; height: 600px;" v-if="isPdfFile(file)"/>
                  <template v-if="isTxtFile(file)">
                    <a-spin :spinning="isTxtLoading(file)">
                      <pre class="code-area">{{ getTxtContent(file) }}</pre>
                    </a-spin>
                  </template>
                  <template v-if="isImageFile(file)">
                    <img :src="getFileUrl(file)" style="width: 100%; height: 600px;" />
                  </template>
                </div>
                <div v-else class="preview-not-supported">
                  <a-empty description="当前文件类型的预览功能不支持!" />
                </div>
              </div>
            </div>
          </div>
          <div v-else>
            <span>-</span>
          </div>
        </a-descriptions-item>
        <a-descriptions-item label="附件">
          <div v-if="attachmentFiles.length > 0">
            <div v-for="file in attachmentFiles" :key="file.uid" class="file-item">
              <div class="file-header">
                <a @click="handleDownload(file)" style="display: inline-block">{{ getFileName(file) }}</a>
                <a @click="toggleFilePreview(file)" class="preview-toggle">
                  {{ isFilePreviewOpen(file) ? '收起' : '[预览]' }}
                </a>
              </div>
              <div v-if="isFilePreviewOpen(file)" class="docx-preview">
                <div v-if="isReviewFile(file) && getFileUrl(file)">
                  <vue-office-docx :src="getFileUrl(file)" style="width: 100%; height: 600px;" v-if="isDocxFile(file)"/>
                  <vue-office-excel :src="getFileUrl(file)" style="width: 100%; height: 600px;" v-if="isXlsxFile(file)"/>
                  <vue-office-pdf :src="getFileUrl(file)" style="width: 100%; height: 600px;" v-if="isPdfFile(file)"/>
                  <template v-if="isTxtFile(file)">
                    <a-spin :spinning="isTxtLoading(file)">
                      <pre class="code-area">{{ getTxtContent(file) }}</pre>
                    </a-spin>
                  </template>
                  <template v-if="isImageFile(file)">
                    <img :src="getFileUrl(file)" style="width: 100%; height: 600px;" />
                  </template>
                </div>
                <div v-else class="preview-not-supported">
                  <a-empty description="当前文件类型的预览功能不支持!" />
                </div>
              </div>
            </div>
          </div>
          <div v-else>
            <span>-</span>
          </div>
        </a-descriptions-item>
      </a-descriptions>
    </a-card>
    <a-card title="语义词信息">
      <div v-if="semanticWords.length > 0">
        <a-descriptions title="" :column="1">
          <a-descriptions-item v-for="word in semanticWords" :key="word.id" :label="`语义词 ${semanticWords.indexOf(word) + 1}`">
            <div style="display: flex; flex-direction: column; gap: 12px; width: 100%">
              <div style="display: flex; gap: 16px; width: 100%">
                <span style="flex: 1;"><strong>类型:</strong>{{ word.category === '1' ? '品牌' : word.category === '2' ? '地区词' : '全国词' }}</span>
                <span style="flex: 1;"><strong>语义词:</strong>{{ word.word || '-' }}</span>
                <span style="flex: 1;"><strong>露出词:</strong>{{ word.outWord || '-' }}</span>
                <span style="flex: 1;"><strong>价格:</strong>{{ word.price ? `${formatPrice(word.price)}元` : '-' }}</span>
                <span style="flex: 1;"><strong>合作周期:</strong>{{ word.month ? `${word.month}月` : '-' }}</span>
                <span style="flex: 1;"><strong>签约排名:</strong>{{ formatRanking(word.ranking) }}</span>
                <span style="flex: 1;"><strong>验收指标(>=):</strong>{{ word.acceptindicator ? `${word.acceptindicator}%` : '-' }}</span>
              </div>
            </div>
          </a-descriptions-item>
        </a-descriptions>
  <PageWrapper title="欢迎" contentBackground>
    <div class="welcome-container">
      <div class="welcome-content">
        <h1 class="welcome-title">您好,欢迎访问</h1>
        <h2 class="welcome-system-name">艾亿欧AIEO智能业务管理系统!</h2>
      </div>
      <div v-else>
        <a-empty description="暂无语义词数据" />
      </div>
    </a-card>
    <!-- 返回按钮 -->
    <div class="action-buttons">
      <a-button type="default" @click="handleBack" class="back-btn">返回</a-button>
    </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, reactive, ref, onMounted } from 'vue';
  import { PageWrapper } from '/@/components/Page';
  import { message } from 'ant-design-vue';
  import { useRoute, useRouter } from 'vue-router';
  import { defHttp } from '/@/utils/http/axios';
  import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
  import VueOfficeDocx from '@vue-office/docx';
  import VueOfficeExcel from '@vue-office/excel';
  import VueOfficePdf from '@vue-office/pdf';
  import '@vue-office/docx/lib/v3/index.css';
  import '@vue-office/excel/lib/v3/index.css';
  export default defineComponent({
    name: 'DescDetailKehu',
    components: { PageWrapper, VueOfficeDocx, VueOfficeExcel, VueOfficePdf },
    setup() {
      const route = useRoute();
      const router = useRouter();
      // 初始数据
      const initialData = {
        id: '',
        createTime: '',
        updateBy: null,
        updateTime: null,
        agentsId: null,
        agentsName: null,
        contractFileList: null,
        contractName: '',
        createBy: '',
        customer: {
          id: '',
          createBy: '',
          createTime: '',
          updateBy: null,
          updateTime: null,
          agentsName: null,
          contactPerson: '',
          contract: null,
          customerAddress: '',
          customerEmail: '',
          customerPhone: '',
          enterpriseName: '',
          industry: '',
          semanticWordList: null,
        },
        customerName: '',
        endDate: '',
        rejectionReasons: null,
        reviewStatus: '',
        semanticWordList: null,
        startDate: '',
        sysOrgCode: '',
        emergencyStatus: 3, // 默认正常状态
        month: null, // 合作周期(月)
      };
      // 响应式表单数据
      const formData = reactive({ ...initialData });
      // 语义词列表
      const semanticWords = ref<any[]>([]);
      // 合同文件列表
      const contractFiles = ref<any[]>([]);
      const attachmentFiles = ref<any[]>([]);
      // 文件预览展开状态(使用文件 uid 作为 key)
      const filePreviewState = reactive<Record<string, boolean>>({});
      const txtContentMap = reactive<Record<string, string>>({});
      const txtLoadingMap = reactive<Record<string, boolean>>({});
      // 加载客户数据
      const loadCustomerData = async () => {
        const id = route.query.id as string;
        if (id) {
          try {
            // 调用API根据id获取客户数据
            const result = await defHttp.get({
              url: '/contract/contract/queryById',
              params: { id },
            });
            console.log('客户详情数据:', result);
            if (result) {
              const customerData = result;
              // 填充表单数据
              Object.assign(formData, customerData);
              // 确保 emergencyStatus 正确设置(1=紧急,3=正常)
              const emergencyStatus = Number(customerData.emergencyStatus);
              if (emergencyStatus === 1 || emergencyStatus === 3) {
                formData.emergencyStatus = emergencyStatus;
              } else {
                formData.emergencyStatus = 3; // 默认正常状态
              }
              // 加载合同文件数据
              await loadContractFiles(id);
              // 加载语义词数据
              await loadSemanticWords(id);
            } else {
              message.error('加载客户详情数据失败');
            }
          } catch (error) {
            console.error('加载客户详情数据失败:', error);
            message.error('加载客户详情数据失败');
          }
        } else {
          message.error('缺少客户ID参数');
        }
      };
      // 加载合同文件数据
      const loadContractFiles = async (id: string) => {
        try {
          const result = await defHttp.get({
            url: '/contract/contract/queryContractFileByMainId',
            params: { id },
          });
          console.log('合同文件数据:', result);
          // 这里可以根据返回的数据结构处理合同文件
          if (result && Array.isArray(result)) {
            // 根据 fileType 区分合同文件和附件
            const contractFileList: any[] = [];
            const attachmentFileList: any[] = [];
            result.forEach((file: any) => {
              const fileItem = {
                uid: file.id,
                name: file.appendixFile || '文件',
                status: 'done',
                url: file.appendixFile,
              };
              if (file.fileType === '合同文件') {
                contractFileList.push(fileItem);
              } else if (file.fileType === '合同附件') {
                attachmentFileList.push(fileItem);
              }
            });
            contractFiles.value = contractFileList;
            attachmentFiles.value = attachmentFileList;
          }
        } catch (error) {
          console.error('加载合同文件失败:', error);
        }
      };
      // 加载语义词数据
      const loadSemanticWords = async (id: string) => {
        try {
          const result = await defHttp.get({
            url: '/contract/contract/querySemanticWordByMainId',
            params: { id },
          });
          console.log('语义词数据:', result);
          // 这里可以根据返回的数据结构处理语义词
          if (result && Array.isArray(result)) {
            // 将语义词列表保存到响应式变量中
            semanticWords.value = result;
          }
        } catch (error) {
          console.error('加载语义词失败:', error);
        }
      };
      onMounted(() => {
        loadCustomerData();
      });
      // 工具方法:获取文件名(去掉 temp/)
      const getFileName = (file: any) => {
        const name = file.name || '';
        if (name.startsWith('temp/')) {
          return name.substring(5);
        }
        return name;
      };
      // 工具方法:获取文件的完整访问 URL
      const getFileUrl = (file: any) => {
        if (!file.url) {
          return '';
        }
        return getFileAccessHttpUrl(file.url);
      };
      // 统一获取文件 key,避免重复逻辑
      const getFileKey = (file: any) => file?.uid || file?.id || file?.url || file?.name || '';
      // 读取 TXT 文本内容用于预览
      const fetchTxtContent = async (file: any) => {
        const fileKey = getFileKey(file);
        if (!fileKey || txtLoadingMap[fileKey]) return;
        txtLoadingMap[fileKey] = true;
        try {
          const url = getFileUrl(file);
          if (!url) throw new Error('TXT 文件地址不存在');
          const resp = await fetch(url);
          if (!resp.ok) throw new Error(`请求失败:${resp.status}`);
          const text = await resp.text();
          txtContentMap[fileKey] = text || '(文件为空)';
        } catch (error) {
          console.error('TXT 文件加载失败', error);
          txtContentMap[fileKey] = 'TXT 文件预览失败,请稍后重试';
          message.error('TXT 文件预览失败');
        } finally {
          txtLoadingMap[fileKey] = false;
        }
      };
      const isReviewFile = (file: any) => {
        if (!file || !file.url) {
          return false;
        }
        const fileName = file.name || file.url || '';
        const lowerName = fileName.toLowerCase();
        return lowerName.endsWith('.docx') || lowerName.endsWith('.xlsx') || lowerName.endsWith('.pdf') || lowerName.endsWith('.txt') ||lowerName.endsWith('.jpg') || lowerName.endsWith('.jpeg') || lowerName.endsWith('.png') || lowerName.endsWith('.gif') || lowerName.endsWith('.bmp') || lowerName.endsWith('.webp');
      };
      // 判断是否为 DOCX 文件
      const isDocxFile = (file: any) => {
        if (!file) {
          return false;
        }
        const fileName = file.name || file.url || '';
        const lowerName = fileName.toLowerCase();
        return lowerName.endsWith('.docx');
      };
      // 判断是否为 XLSX 文件
      const isXlsxFile = (file: any) => {
        if (!file) {
          return false;
        }
        const fileName = file.name || file.url || '';
        const lowerName = fileName.toLowerCase();
        return lowerName.endsWith('.xlsx');
      };
      // 判断是否为 PDF 文件
      const isPdfFile = (file: any) => {
        if (!file) {
          return false;
        }
        const fileName = file.name || file.url || '';
        const lowerName = fileName.toLowerCase();
        return lowerName.endsWith('.pdf');
      };
      // 判断是否为 TXT 文件
      const isTxtFile = (file: any) => {
        if (!file) {
          return false;
        }
        const fileName = file.name || file.url || '';
        const lowerName = fileName.toLowerCase();
        return lowerName.endsWith('.txt');
      };
      // 判断是否为图片文件
      const isImageFile = (file: any) => {
        if (!file) {
          return false;
        }
        const fileName = file.name || file.url || '';
        const lowerName = fileName.toLowerCase();
        return lowerName.endsWith('.jpg') || lowerName.endsWith('.jpeg') || lowerName.endsWith('.png') || lowerName.endsWith('.gif') || lowerName.endsWith('.bmp') || lowerName.endsWith('.webp');
      };
      const getTxtContent = (file: any) => {
        const key = getFileKey(file);
        return txtContentMap[key] || '加载中...';
      };
      const isTxtLoading = (file: any) => {
        const key = getFileKey(file);
        return !!txtLoadingMap[key];
      };
      // 切换文件预览状态
      const toggleFilePreview = (file: any) => {
        const fileId = getFileKey(file);
        if (!fileId) return;
        const nextState = !filePreviewState[fileId];
        filePreviewState[fileId] = nextState;
        // 打开 TXT 时加载内容
        if (nextState && isTxtFile(file) && !txtContentMap[fileId]) {
          fetchTxtContent(file);
        }
      };
      // 检查文件是否展开预览
      const isFilePreviewOpen = (file: any) => {
        const fileId = getFileKey(file);
        return filePreviewState[fileId] || false;
      };
      // 文件下载功能
      const handleDownload = (file: any) => {
        if (!file.url) {
          message.error('文件链接不存在');
          return;
        }
        try {
          // 创建一个隐藏的a标签进行下载
          const link = document.createElement('a');
          link.href = getFileAccessHttpUrl(file.url);
          link.download = getFileName(file);
          link.target = '_blank';
          link.style.display = 'none';
          // 添加到DOM中
          document.body.appendChild(link);
          // 触发点击事件
          link.click();
          // 清理DOM
          document.body.removeChild(link);
        } catch (error) {
          console.error('文件下载失败:', error);
          message.error('文件下载失败');
        }
      };
      // 返回功能
      const handleBack = () => {
        router.back();
      };
      // 格式化价格
      const formatPrice = (price: number) => {
        if (!price) return '-';
        return price.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
      };
      // 格式化签约排名
      const formatRanking = (ranking: any) => {
        if (ranking === 1 || ranking === 2 || ranking === 3) {
          return ranking.toString();
        } else if (ranking === '保展现不保排名') {
          return '保展现不保排名';
        }
        return '-';
      };
      return {
        formData,
        contractFiles,
        attachmentFiles,
        semanticWords,
        handleDownload,
        handleBack,
        getFileName,
        getFileUrl,
        isReviewFile,
        isDocxFile,
        isXlsxFile,
        isPdfFile,
        isTxtFile,
        isImageFile,
        getTxtContent,
        isTxtLoading,
        toggleFilePreview,
        isFilePreviewOpen,
        formatPrice,
        formatRanking,
      };
    },
  });
<script lang="ts" setup>
// 欢迎页面组件
</script>
<style lang="less" scoped>
  .desc-wrap {
    padding: 16px;
    background-color: @component-background;
  }
.welcome-container {
  min-height: calc(100vh - 200px);
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f0f2f5;
}
  .action-buttons {
    position: fixed;
    right: 24px;
    bottom: 24px;
    display: flex;
    gap: 12px;
    z-index: 1000;
.welcome-content {
  text-align: center;
  padding: 40px;
}
    .back-btn {
      min-width: 80px;
      height: 40px;
      border-radius: 6px;
      font-weight: 500;
      background-color: #f5f5f5;
      border-color: #d9d9d9;
      color: #666;
.welcome-title {
  font-size: 32px;
  color: #333;
  margin-bottom: 20px;
}
      &:hover {
        background-color: #e6f7ff;
        border-color: #40a9ff;
        color: #40a9ff;
      }
    }
  }
  // 文件下载链接样式
  a {
    color: #1890ff;
    text-decoration: none;
    cursor: pointer;
    transition: color 0.3s;
    &:hover {
      color: #40a9ff;
      text-decoration: underline;
    }
    &:active {
      color: #096dd9;
    }
  }
  .file-item {
    &:last-child {
      border-bottom: none;
    }
  }
  .file-header {
    display: flex;
    align-items: center;
  }
  .preview-toggle {
    margin-left: 8px;
    color: #1890ff;
    cursor: pointer;
    font-size: 14px;
    user-select: none;
    &:hover {
      color: #40a9ff;
      text-decoration: underline;
    }
  }
  .docx-preview {
    margin-top: 12px;
    border: 1px solid #e8e8e8;
    border-radius: 4px;
    overflow: hidden;
    background: #fff;
  }
  .preview-not-supported {
    padding: 40px 20px;
    text-align: center;
    min-height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .code-area {
    margin: 0;
    padding: 12px;
    background: #e2e8f0;
    color: #0f172a;
    border-radius: 4px;
    font-size: 13px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
    min-height: 120px;
    max-height: 600px;
    overflow: auto;
  }
.welcome-system-name {
  font-size: 40px;
  color: #1890ff;
  font-weight: bold;
}
</style>
src/views/demo/page/desc/editkehu/index.vue
@@ -174,9 +174,26 @@
    </a-card>
    <!-- 右下角操作按钮 -->
    <div class="action-buttons">
      <a-button type="danger" @click="handleStopService" class="stop-btn">停止服务</a-button>
      <a-button type="default" @click="handleReset" class="reset-btn">重置</a-button>
      <a-button type="primary" @click="handleSave" class="save-btn">再次提交</a-button>
    </div>
    <!-- 停止服务确认弹窗 -->
    <a-modal
      v-model:visible="stopServiceModalVisible"
      title="停止服务确认"
      width="500px"
      ok-text="确认停止"
      cancel-text="取消"
      @ok="confirmStopService"
      centered
    >
      <div style="padding: 20px 0; text-align: center;">
        <p style="font-size: 16px; margin-bottom: 20px;">是否确认停止服务?</p>
        <p style="color: #666; font-size: 14px;">停止服务后,相关服务将立即终止</p>
      </div>
    </a-modal>
  </PageWrapper>
</template>
@@ -200,6 +217,9 @@
      // 编辑状态控制
      const isEditing = ref(true);
      // 停止服务弹窗可见性
      const stopServiceModalVisible = ref(false);
      // 原始数据,用于重置
      const originalData = ref<any>({});
@@ -638,6 +658,44 @@
        }
      };
      // 处理停止服务按钮点击
      const handleStopService = () => {
        stopServiceModalVisible.value = true;
      };
      // 确认停止服务
      const confirmStopService = async () => {
        const id = route.query.id as string;
        if (!id) {
          message.error('缺少合同ID参数');
          return;
        }
        try {
          // 调用后端停止服务接口
          const result = await defHttp.post({
            url: '/contract/contract/dropService',
            data: {
              id,
              isDropService: '是'
            },
          });
          if (result) {
            message.success('服务已成功停止');
            // 重新加载客户数据以更新状态
            await loadCustomerData();
          } else {
            message.error('停止服务失败');
          }
        } catch (error) {
          console.error('停止服务失败:', error);
          message.error('停止服务失败');
        } finally {
          stopServiceModalVisible.value = false;
        }
      };
      return {
        isEditing,
        formData,
@@ -646,11 +704,14 @@
        displayContractFiles,
        displayAttachmentFiles,
        semanticWords,
        stopServiceModalVisible,
        beforeUpload,
        customUpload,
        handleFileChange,
        handleReset,
        handleSave,
        handleStopService,
        confirmStopService,
        getFileName,
        resolveFileUrl,
        downloadFile,
@@ -704,6 +765,22 @@
        border-color: #40a9ff;
      }
    }
    .stop-btn {
      min-width: 80px;
      height: 40px;
      border-radius: 6px;
      font-weight: 500;
      background-color: #fff1f0;
      border-color: #ffccc7;
      color: #cf1322;
      &:hover {
        background-color: #fff2f0;
        border-color: #ff7875;
        color: #ff4d4f;
      }
    }
  }
  .file-row {
src/views/ranking/rankingOff/RankingOff.data.ts
@@ -83,11 +83,11 @@
  compact: true,
  baseColProps: {
    xs: 24,
    sm: 6,
    md: 6,
    lg: 6,
    xl: 6,
    xxl: 6,
    sm: 4,
    md: 4,
    lg: 4,
    xl: 4,
    xxl: 4,
  },
  rowProps: {
    gutter: 8,
src/views/ranking/rankingOff/index.vue
@@ -36,13 +36,27 @@
      showActionColumn: false,
      canResize: true,
      formConfig: {
        labelWidth: 100,
        schemas: searchFormSchema,
        autoSubmitOnEnter: true,
        showAdvancedButton: false,
        showActionButtonGroup: true,
        ...formLayoutConfig,
        showAdvancedButton: true,
        autoAdvancedCol: 4,
        fieldMapToNumber: [],
        fieldMapToTime: [],
        compact: true,
        baseColProps: {
          xs: 24,
          sm: 4,
          md: 4,
          lg: 4,
          xl: 4,
          xxl: 4,
        },
        rowProps: {
          gutter: 8,
        },
        actionColOptions: {
          span: 6,
          span: 8,
          style: { textAlign: 'left' },
        },
      },
@@ -130,6 +144,12 @@
  :deep(.ant-input-number) {
    width: 100%;
  }
  /* 确保搜索表单靠左对齐 */
  :deep(.basic-table-search) {
    padding-left: 0 !important;
    margin-left: 0 !important;
  }
</style>
src/views/ranking/rankingOn/RankingOn.data.ts
@@ -83,11 +83,11 @@
  compact: true,
  baseColProps: {
    xs: 24,
    sm: 6,
    md: 6,
    lg: 6,
    xl: 6,
    xxl: 6,
    sm: 4,
    md: 4,
    lg: 4,
    xl: 4,
    xxl: 4,
  },
  rowProps: {
    gutter: 8,
src/views/ranking/rankingOn/index.vue
@@ -37,11 +37,25 @@
      showActionColumn: false,
      canResize: true,
      formConfig: {
        labelWidth: 100,
        schemas: searchFormSchema,
        autoSubmitOnEnter: true,
        showAdvancedButton: false,
        showActionButtonGroup: true,
        ...formLayoutConfig,
        showAdvancedButton: true,
        autoAdvancedCol: 4,
        fieldMapToNumber: [],
        fieldMapToTime: [],
        compact: true,
        baseColProps: {
          xs: 24,
          sm: 6,
          md: 6,
          lg: 6,
          xl: 6,
          xxl: 6,
        },
        rowProps: {
          gutter: 8,
        },
        actionColOptions: {
          span: 6,
          style: { textAlign: 'left' },
@@ -131,6 +145,12 @@
  :deep(.ant-input-number) {
    width: 100%;
  }
  /* 确保搜索表单靠左对齐 */
  :deep(.basic-table-search) {
    padding-left: 0 !important;
    margin-left: 0 !important;
  }
</style>
src/views/semanticword/SemanticWord.data.ts
@@ -43,25 +43,19 @@
    {
      label: "语义词",
      field: 'word',
      component: 'JInput',
      componentProps: {
        style: { width: '220px' } // 增加宽度,确保文字显示完整
      },
      component: 'Input',
      //colProps: {span: 6},
      },
    {
      label: "露出词",
      field: 'outWord',
      component: 'JInput',
      componentProps: {
        style: { width: '220px' } // 增加宽度,确保文字显示完整
      },
      component: 'Input',
      //colProps: {span: 6},
      },
    {
      label: "状态",
      field: 'status',
      component: 'JDictSelectTag',
      component: 'Select',
      componentProps:{
          // 仅保留以下四个状态作为查询选项
          options: [
@@ -70,7 +64,6 @@
            { label: '已驳回', value: '2' },
            { label: '已上词', value: '5' },
          ],
          style: { width: '180px' } // 增加宽度,确保文字显示完整
      },
      //colProps: {span: 6},
      },
src/views/semanticword/SemanticWordList.vue
@@ -149,30 +149,31 @@
      columns,
      showActionColumn: false,
      canResize: true,
      formConfig: {
        //labelWidth: 120,
        schemas: searchFormSchema,
        autoSubmitOnEnter: true,
        showAdvancedButton: true,
        fieldMapToNumber: [],
        fieldMapToTime: [],
        compact: true, // 启用紧凑模式
        baseColProps: {
          xs: 24,
          sm: 6,
          md: 6,
          lg: 6,
          xl: 6,
          xxl: 6,
        },
        rowProps: {
          gutter: 8,
        },
        actionColOptions: {
          span: 8,
          style: { textAlign: 'left', marginLeft: '0px' },
        },
      },
    formConfig: {
  //labelWidth: 120,
  schemas: searchFormSchema,
  autoSubmitOnEnter: true,
  showAdvancedButton: true,
  autoAdvancedCol: 4,
  fieldMapToNumber: [],
  fieldMapToTime: [],
  compact: true,
  baseColProps: {
    xs: 24,
    sm: 4,
    md: 4,
    lg: 4,
    xl: 4,
    xxl: 4,
  },
  rowProps: {
    gutter: 8,
  },
  actionColOptions: {
    span: 8,
    style: { textAlign: 'left' },
  },
},
      beforeFetch: (params) => {
        if (params && fieldPickers) {
          for (let key in fieldPickers) {
@@ -310,38 +311,10 @@
    gap: 20px;
  }
  
  /* 更具体的样式选择器,确保搜索表单更靠左 */
  :deep(.basic-table) {
    padding-left: 0 !important;
  }
  /* 确保搜索表单靠左对齐 */
  :deep(.basic-table-search) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  :deep(.ant-form) {
    margin-left: 0 !important;
    padding-left: 0 !important;
    width: 100%;
  }
  :deep(.ant-row) {
    margin-left: 0 !important;
    width: 100%;
    justify-content: flex-start !important;
  }
  :deep(.ant-form-item) {
    margin-right: 16px !important;
    margin-left: 0 !important;
  }
  :deep(.ant-form-item-label) {
    padding-right: 8px !important;
  }
  :deep(.ant-form-item-control) {
    min-width: 180px;
  }
</style>
src/views/semanticwordFP/SemanticWord.data.ts
@@ -53,22 +53,18 @@
    {
      label: "语义词",
      field: 'word',
      component: 'JInput',
      componentProps: {
        style: { width: '200px' } // 适当宽度,确保文字显示完整
      },
      component: 'Input',
      //colProps: {span: 6},
      },
  {
    label: "状态",
    field: 'status',
    component: 'JDictSelectTag',
    component: 'Select',
    componentProps:{
      options: [
        { label: '待分配', value: '1' },
        { label: '已分配', value: '7' },
      ],
      style: { width: '200px' } // 适当宽度,确保文字显示完整
     },
  },
    // {
src/views/semanticwordFP/SemanticWordList.vue
@@ -72,30 +72,31 @@
      api: list,
      columns,
      canResize: true,
      formConfig: {
        //labelWidth: 120,
        schemas: searchFormSchema,
        autoSubmitOnEnter: true,
        showAdvancedButton: true,
        fieldMapToNumber: [],
        fieldMapToTime: [],
        compact: true, // 启用紧凑模式
        baseColProps: {
          xs: 24,
          sm: 6,
          md: 6,
          lg: 6,
          xl: 6,
          xxl: 6,
        },
        rowProps: {
          gutter: 8,
        },
        actionColOptions: {
          span: 8,
          style: { textAlign: 'left' },
        },
      },
     formConfig: {
  //labelWidth: 120,
  schemas: searchFormSchema,
  autoSubmitOnEnter: true,
  showAdvancedButton: true,
  autoAdvancedCol: 4,
  fieldMapToNumber: [],
  fieldMapToTime: [],
  compact: true,
  baseColProps: {
    xs: 24,
    sm: 4,
    md: 4,
    lg: 4,
    xl: 4,
    xxl: 4,
  },
  rowProps: {
    gutter: 8,
  },
  actionColOptions: {
    span: 8,
    style: { textAlign: 'left' },
  },
},
      actionColumn: {
        width: 150,
        fixed: 'right',
@@ -277,38 +278,10 @@
    }
  }
  
  /* 更具体的样式选择器,确保搜索表单更靠左 */
  :deep(.basic-table) {
    padding-left: 0 !important;
  }
  /* 确保搜索表单靠左对齐 */
  :deep(.basic-table-search) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  :deep(.ant-form) {
    margin-left: 0 !important;
    padding-left: 0 !important;
    width: 100%;
  }
  :deep(.ant-row) {
    margin-left: 0 !important;
    width: 100%;
    justify-content: flex-start !important;
  }
  :deep(.ant-form-item) {
    margin-right: 16px !important;
    margin-left: 0 !important;
  }
  :deep(.ant-form-item-label) {
    padding-right: 8px !important;
  }
  :deep(.ant-form-item-control) {
    min-width: 180px;
  }
</style>
src/views/semanticwordPD/SemanticWordList.vue
@@ -239,4 +239,94 @@
  :deep(.ant-input-number) {
    width: 100%;
  }
  /* 确保搜索表单完全靠左对齐,消除所有左边空隙 */
  :deep(.basic-table-search) {
    padding-left: 0 !important;
    margin-left: 0 !important;
  }
  /* 消除表单容器的左边空隙 */
  :deep(.ant-form) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 消除行容器的左边空隙 */
  :deep(.ant-form-item-row) {
    margin-left: 0 !important;
  }
  /* 消除表单项的左边空隙 */
  :deep(.ant-form-item) {
    margin-left: 0 !important;
  }
  /* 消除BasicTable容器的左边空隙 */
  :deep(.ant-card) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 消除BasicTable头部的左边空隙 */
  :deep(.ant-card-head) {
    padding-left: 0 !important;
  }
  /* 消除BasicTable内容的左边空隙 */
  :deep(.ant-card-body) {
    padding-left: 0 !important;
  }
  /* 消除搜索表单外层容器的左边空隙 */
  :deep(.ant-row) {
    margin-left: 0 !important;
  }
  /* 消除搜索表单列容器的左边空隙 */
  :deep(.ant-col) {
    padding-left: 0 !important;
  }
  /* 直接针对搜索表单区域的容器 */
  :deep(.arco-form) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 直接针对搜索表单区域 */
  .semantic-word-search {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 针对整个表格容器的最外层 */
  :deep(.arco-table-container) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 针对搜索表单的直接父容器 */
  :deep(.arco-space) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 针对搜索表单的直接容器 */
  :deep(.arco-form-container) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 直接针对整个页面容器 */
  .table-container {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
  /* 针对页面根容器 */
  :deep(.app-container) {
    margin-left: 0 !important;
    padding-left: 0 !important;
  }
</style>