gaoluyang
2026-06-03 dcc3a4d842740f7ff6e79a58ddec945f50ea9b5d
Merge branch 'dev_NEW_pro' into dev_宁夏_英泽防锈

# Conflicts:
# multiple/config.json
# src/assets/styles/sidebar.scss
已添加9个文件
已修改24个文件
2161 ■■■■■ 文件已修改
multiple/assets/favicon/QFSWfavicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/favicon/RFSYLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/favicon/RFSYfavicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/favicon/XHKSfavicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/favicon/ZDJCfavicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/logo/QFSWLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/logo/RFSYLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/logo/XHKSLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/logo/ZDJCLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/api/procurementManagement/procurementLedger.js 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/styles/sidebar.scss 1333 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/SidebarItem.vue 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/parameterMaintenance/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/sealManagement/index.vue 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/assets/fixedAssets.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/assets/intangibleAssets.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/payable/paymentApply.vue 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/receivable/invoiceApply.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/receivable/receipt.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-list/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-template/index.vue 73 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementLedger/index.vue 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementPlan/index.vue 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/purchaseOrder/index.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/qualityInspection/index.vue 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productManagement/productIdentifier/index.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionPlan/productionPlan/index.vue 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeProduction/safetyTrainingAssessment/index.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/favicon/QFSWfavicon.ico
multiple/assets/favicon/RFSYLogo.png
multiple/assets/favicon/RFSYfavicon.ico
multiple/assets/favicon/XHKSfavicon.ico
multiple/assets/favicon/ZDJCfavicon.ico
multiple/assets/logo/QFSWLogo.png
multiple/assets/logo/RFSYLogo.png
multiple/assets/logo/XHKSLogo.png
multiple/assets/logo/ZDJCLogo.png
src/api/procurementManagement/procurementLedger.js
@@ -74,53 +74,61 @@
  });
}
export function updateApprovalStatus(query) {
    return request({
        url: "/purchase/ledger/updateApprovalStatus",
        method: "post",
        data: query,
    });
  return request({
    url: "/purchase/ledger/updateApprovalStatus",
    method: "post",
    data: query,
  });
}
// 保存采购模板
export function addPurchaseTemplate(data) {
    return request({
        url: "/purchaseLedgerTemplate/add",
        method: "post",
        data: data,
    });
  return request({
    url: "/purchaseLedgerTemplate/add",
    method: "post",
    data: data,
  });
}
// 修改采购模板
export function updatePurchaseTemplate(data) {
    return request({
        url: "/purchaseLedgerTemplate/update",
        method: "post",
        data: data,
    });
  return request({
    url: "/purchaseLedgerTemplate/update",
    method: "post",
    data: data,
  });
}
// 查询采购模板
export function getPurchaseTemplateList(query) {
    return request({
        url: "/purchase/ledger/getPurchaseTemplateList",
        method: "get",
        params: query,
    });
  return request({
    url: "/purchase/ledger/getPurchaseTemplateList",
    method: "get",
    params: query,
  });
}
// 删除采购模板
export function delPurchaseTemplate(id) {
    return request({
        url: "/purchaseLedgerTemplate/delete",
        method: "delete",
        data: id,
    });
  return request({
    url: "/purchaseLedgerTemplate/delete",
    method: "delete",
    data: id,
  });
}
// 查询采购详情
export function getPurchaseByCode(id) {
    return request({
        url: "/purchase/ledger/getPurchaseByCode",
        method: "get",
        params: id,
    });
}
  return request({
    url: "/purchase/ledger/getPurchaseByCode",
    method: "get",
    params: id,
  });
}
export function batchGeneratePurchaseInboundSteps(query) {
  return request({
    url: "/purchase/ledger/batchInsertPurchaseSteps",
    method: "post",
    data: query,
  });
}
src/assets/styles/sidebar.scss
@@ -1,664 +1,669 @@
#app {
  .main-container {
    min-height: 100vh;
    margin-left: var(--sidebar-width);
    transition: margin-left 0.25s ease;
    position: relative;
    background: transparent;
  }
  .sidebarHide {
    margin-left: 0 !important;
  }
  .sidebar-container {
    transition: width 0.25s ease;
    width: var(--sidebar-width) !important;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1001;
    overflow: hidden;
    padding: 0;
    font-size: 0;
    background: var(--sidebar-bg);
    border-right: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 8px 0 24px rgba(15, 23, 42, 0.08);
    isolation: isolate;
    &::before {
      content: "";
      position: absolute;
      inset: -28% -52% -18% -38%;
      z-index: 0;
      pointer-events: none;
      background:
        radial-gradient(circle at 9% 12%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.62), transparent 44%),
        radial-gradient(circle at 87% 18%, rgba(56, 189, 248, 0.4), transparent 48%),
        radial-gradient(circle at 20% 82%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.3), transparent 43%),
        radial-gradient(circle at 66% 62%, rgba(125, 211, 252, 0.24), transparent 50%),
        conic-gradient(
          from 210deg at 58% 38%,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14) 0deg,
          rgba(56, 189, 248, 0.05) 76deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.16) 180deg,
          rgba(125, 211, 252, 0.04) 290deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14) 360deg
        );
      filter: blur(7px) saturate(1.24) contrast(1.05);
      opacity: 0.96;
      transform: translate3d(0, 0, 0);
      transform-origin: 44% 58%;
      animation:
        sidebarAuroraDrift 17.9s cubic-bezier(0.31, 0.03, 0.18, 0.99) infinite,
        sidebarAuroraBreath 9.7s ease-in-out infinite,
        sidebarAuroraSkew 6.9s steps(23, end) infinite;
    }
    &::after {
      content: "";
      position: absolute;
      inset: 0;
      z-index: 0;
      pointer-events: none;
      background:
        linear-gradient(
          108deg,
          transparent 10%,
          rgba(255, 255, 255, 0.17) 34%,
          rgba(255, 255, 255, 0.04) 48%,
          transparent 72%
        ),
        linear-gradient(
          202deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.24) 0%,
          transparent 34%,
          rgba(56, 189, 248, 0.18) 66%,
          transparent 100%
        ),
        radial-gradient(circle at 74% 12%, rgba(125, 211, 252, 0.25), transparent 50%),
        radial-gradient(circle at 22% 84%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14), transparent 56%);
      background-size: 236% 100%, 186% 186%, 164% 164%, 180% 180%;
      background-position: 224% 0, 14% 16%, 78% 10%, 18% 82%;
      opacity: 0.52;
      transform: translate3d(0, 0, 0);
      animation:
        sidebarSheenSweep 13.1s linear infinite,
        sidebarSheenJitter 4.7s steps(31, end) infinite;
    }
    > * {
      position: relative;
      z-index: 1;
    }
    .horizontal-collapse-transition {
      transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
    }
    .scrollbar-wrapper {
      overflow-x: hidden !important;
      overflow-y: auto !important;
    }
    .el-scrollbar__bar.is-vertical {
      right: 2px;
    }
    .el-scrollbar {
      height: 100%;
    }
    &.has-logo {
      .el-scrollbar {
        height: calc(100% - 78px);
      }
    }
    .is-horizontal {
      display: none;
    }
    a {
      display: inline-block;
      width: 100%;
      overflow: hidden;
    }
    .el-menu {
      border: none !important;
      height: 100%;
      width: 100% !important;
      padding: 10px 0 16px;
      border-radius: 0;
      background: transparent !important;
      box-shadow: none;
      backdrop-filter: none;
    }
    .el-menu-item,
    .el-sub-menu__title,
    .menu-title {
      overflow: hidden !important;
      text-overflow: ellipsis !important;
      white-space: nowrap !important;
    }
    .el-menu-item .el-menu-tooltip__trigger {
      display: inline-flex !important;
      width: 100%;
      align-items: center;
    }
    .submenu-title-noDropdown,
    .el-sub-menu__title,
    .el-menu-item {
      min-width: 0 !important;
      width: calc(100% - 24px) !important;
      margin: 0 12px 8px !important;
      height: 50px;
      line-height: 50px;
      border-radius: 14px;
      padding-left: 16px !important;
      padding-right: 36px !important;
      box-sizing: border-box;
      transition: all 0.28s ease;
      color: var(--sidebar-text);
      background: linear-gradient(128deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.01));
      border: 1px solid rgba(255, 255, 255, 0.06) !important;
      position: relative;
      overflow: hidden;
    }
    .submenu-title-noDropdown::after,
    .el-sub-menu__title::after,
    .el-menu-item::after {
      content: "";
      position: absolute;
      inset: 0;
      background: linear-gradient(115deg, transparent 12%, rgba(255, 255, 255, 0.16), transparent 78%);
      transform: translateX(-100%);
      opacity: 0;
      transition: transform 0.45s ease, opacity 0.26s ease;
      pointer-events: none;
    }
    .submenu-title-noDropdown:hover,
    .el-sub-menu__title:hover,
    .el-menu-item:hover {
      background: linear-gradient(128deg, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.28), rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.08)) !important;
      border-color: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.32) !important;
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 8px 18px rgba(8, 36, 76, 0.24);
      transform: translateX(3px);
    }
    .submenu-title-noDropdown:hover::after,
    .el-sub-menu__title:hover::after,
    .el-menu-item:hover::after,
    .el-menu-item.is-active::after,
    .el-sub-menu.is-active > .el-sub-menu__title::after {
      transform: translateX(100%);
      opacity: 1;
    }
    & .theme-light .is-active > .el-sub-menu__title,
    & .theme-dark .is-active > .el-sub-menu__title,
    & .el-menu-item.is-active {
      color: #fff !important;
      background: var(--menu-active-bg, linear-gradient(135deg, var(--el-color-primary), var(--el-color-primary-light-3))) !important;
      background-size: 180% 180%;
      box-shadow: var(--menu-active-glow, 0 10px 24px rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.34));
      border-color: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.5) !important;
      animation: sidebarActiveFlow 4.6s ease infinite;
    }
    & .nest-menu .el-sub-menu > .el-sub-menu__title,
    & .el-sub-menu .el-menu-item {
      min-width: 0 !important;
      width: calc(100% - 24px) !important;
      margin: 0 12px 8px !important;
      height: 46px;
      line-height: 46px;
      padding-left: 14px !important;
      padding-right: 14px !important;
      border-radius: 12px;
      transition: all 0.24s ease;
      color: var(--sidebar-text);
      border: 1px solid rgba(255, 255, 255, 0.06) !important;
      background: linear-gradient(128deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.01));
      &:hover {
        background: linear-gradient(128deg, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.24), rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.07)) !important;
        border-color: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.3) !important;
        transform: translateX(2px);
      }
      &.is-active {
        background: var(--menu-active-bg, linear-gradient(135deg, var(--el-color-primary), var(--el-color-primary-light-3))) !important;
        background-size: 180% 180%;
        color: #fff !important;
        font-weight: 500;
        box-shadow: var(--menu-active-glow, 0 10px 24px rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.34));
        animation: sidebarActiveFlow 4.6s ease infinite;
      }
    }
  }
  .hideSidebar {
    .sidebar-container {
      width: var(--sidebar-collapsed-width) !important;
    }
    .main-container {
      margin-left: var(--sidebar-collapsed-width);
    }
    .submenu-title-noDropdown {
      padding: 0 !important;
      position: relative;
      display: flex !important;
      align-items: center;
      justify-content: center;
      .svg-icon {
        margin-right: 0;
      }
      .el-tooltip {
        padding: 0 !important;
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        width: 100%;
        .svg-icon {
          margin-left: 0;
        }
      }
      .el-menu-tooltip__trigger {
        width: 100%;
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        .svg-icon {
          width: 22px;
          height: 22px;
          margin-right: 0;
          flex-shrink: 0;
        }
      }
    }
    .el-sub-menu {
      overflow: hidden;
      & > .el-sub-menu__title {
        padding: 0 !important;
        display: flex !important;
        align-items: center;
        justify-content: center;
        .svg-icon {
          margin-left: 0;
          margin-right: 0;
        }
      }
    }
    .el-menu--collapse {
      width: 100% !important;
      padding: 12px 0 16px;
      > .el-menu-item,
      .el-sub-menu {
        & > .el-sub-menu__title,
        &.el-menu-item {
          width: calc(100% - 12px) !important;
          margin: 0 6px 8px !important;
          padding-left: 0 !important;
          padding-right: 0 !important;
          box-sizing: border-box;
          display: flex !important;
          align-items: center;
          justify-content: center;
          .svg-icon {
            width: 22px;
            height: 22px;
            margin-right: 0;
            flex-shrink: 0;
          }
          & > span {
            height: 0;
            width: 0;
            overflow: hidden;
            visibility: hidden;
            display: inline-block;
          }
        }
      }
    }
  }
  .el-menu--collapse .el-menu .el-sub-menu {
    min-width: var(--sidebar-width) !important;
  }
  .mobile {
    .main-container {
      margin-left: 0;
    }
    .sidebar-container {
      transition: transform 0.25s;
      width: var(--sidebar-width) !important;
    }
    &.hideSidebar {
      .sidebar-container {
        pointer-events: none;
        transition-duration: 0.3s;
        transform: translate3d(calc(-1 * var(--sidebar-width)), 0, 0);
      }
    }
  }
  .withoutAnimation {
    .main-container,
    .sidebar-container {
      transition: none;
    }
  }
}
.el-menu--vertical {
  & > .el-menu {
    .svg-icon {
      margin-right: 10px;
    }
  }
  .nest-menu .el-sub-menu > .el-sub-menu__title,
  .el-menu-item {
    min-width: 0 !important;
    margin: 0 10px 8px;
    width: calc(100% - 20px);
    height: 46px;
    line-height: 46px;
    padding-left: 12px !important;
    padding-right: 12px !important;
    box-sizing: border-box;
    border-radius: 12px;
    color: var(--sidebar-text);
    border: 1px solid rgba(255, 255, 255, 0.06) !important;
    background: linear-gradient(128deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.01));
    transition: all 0.24s ease;
    &:hover {
      background: linear-gradient(128deg, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.24), rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.07)) !important;
      border-color: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.3) !important;
      transform: translateX(2px);
    }
    &.is-active {
      background: var(--menu-active-bg, linear-gradient(135deg, var(--el-color-primary), var(--el-color-primary-light-3))) !important;
      background-size: 180% 180%;
      color: #fff !important;
      border-radius: 12px;
      box-shadow: var(--menu-active-glow, 0 10px 24px rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.34));
      border-color: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.5) !important;
      animation: sidebarActiveFlow 4.6s ease infinite;
    }
  }
  > .el-menu--popup {
    max-height: 100vh;
    overflow: hidden;
    padding: 10px;
    border-radius: 14px;
    position: relative;
    isolation: isolate;
    border: 1px solid rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.26);
    box-shadow:
      0 18px 40px rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.16),
      var(--shadow-md);
    background: var(--sidebar-bg);
    backdrop-filter: blur(16px);
    &::before {
      content: "";
      position: absolute;
      inset: -28% -52% -18% -38%;
      z-index: 0;
      pointer-events: none;
      background:
        radial-gradient(circle at 9% 12%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.62), transparent 44%),
        radial-gradient(circle at 87% 18%, rgba(56, 189, 248, 0.4), transparent 48%),
        radial-gradient(circle at 20% 82%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.3), transparent 43%),
        radial-gradient(circle at 66% 62%, rgba(125, 211, 252, 0.24), transparent 50%),
        conic-gradient(
          from 210deg at 58% 38%,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14) 0deg,
          rgba(56, 189, 248, 0.05) 76deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.16) 180deg,
          rgba(125, 211, 252, 0.04) 290deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14) 360deg
        );
      filter: blur(7px) saturate(1.24) contrast(1.05);
      opacity: 0.96;
      transform: translate3d(0, 0, 0);
      transform-origin: 44% 58%;
      animation:
        sidebarAuroraDrift 17.9s cubic-bezier(0.31, 0.03, 0.18, 0.99) infinite,
        sidebarAuroraBreath 9.7s ease-in-out infinite,
        sidebarAuroraSkew 6.9s steps(23, end) infinite;
    }
    &::after {
      content: "";
      position: absolute;
      inset: 0;
      z-index: 0;
      pointer-events: none;
      background:
        linear-gradient(
          108deg,
          transparent 10%,
          rgba(255, 255, 255, 0.17) 34%,
          rgba(255, 255, 255, 0.04) 48%,
          transparent 72%
        ),
        linear-gradient(
          202deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.24) 0%,
          transparent 34%,
          rgba(56, 189, 248, 0.18) 66%,
          transparent 100%
        ),
        radial-gradient(circle at 74% 12%, rgba(125, 211, 252, 0.25), transparent 50%),
        radial-gradient(circle at 22% 84%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14), transparent 56%);
      background-size: 236% 100%, 186% 186%, 164% 164%, 180% 180%;
      background-position: 224% 0, 14% 16%, 78% 10%, 18% 82%;
      opacity: 0.52;
      transform: translate3d(0, 0, 0);
      animation:
        sidebarSheenSweep 13.1s linear infinite,
        sidebarSheenJitter 4.7s steps(31, end) infinite;
    }
    > * {
      position: relative;
      z-index: 1;
    }
    > .el-menu {
      max-height: calc(100vh - 20px);
      overflow-y: auto;
      overflow-x: hidden;
      &::-webkit-scrollbar-track-piece {
        background: var(--surface-muted);
      }
      &::-webkit-scrollbar {
        width: 5px;
      }
      &::-webkit-scrollbar-thumb {
        background: var(--accent-light);
        border-radius: 10px;
      }
    }
  }
}
@keyframes sidebarActiveFlow {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}
@keyframes sidebarAuroraDrift {
  0% {
    transform: translate3d(-6.3%, -1.8%, 0) scale(1.05) rotate(-1.8deg);
  }
  6% {
    transform: translate3d(2.2%, -4.6%, 0) scale(1.08) rotate(0.7deg);
  }
  17% {
    transform: translate3d(-3.7%, 4.4%, 0) scale(1.11) rotate(2deg);
  }
  27% {
    transform: translate3d(5.6%, 1.2%, 0) scale(1.03) rotate(-1deg);
  }
  39% {
    transform: translate3d(-4.8%, -3.1%, 0) scale(1.09) rotate(1.5deg);
  }
  52% {
    transform: translate3d(2.9%, 4.8%, 0) scale(1.04) rotate(-1.4deg);
  }
  64% {
    transform: translate3d(-6.4%, 0.3%, 0) scale(1.08) rotate(0.5deg);
  }
  73% {
    transform: translate3d(4.8%, -3.9%, 0) scale(1.05) rotate(1.6deg);
  }
  81% {
    transform: translate3d(-2.4%, 2.9%, 0) scale(1.1) rotate(-0.8deg);
  }
  92% {
    transform: translate3d(3.7%, -1.7%, 0) scale(1.06) rotate(-1.6deg);
  }
  100% {
    transform: translate3d(-5.9%, 0.8%, 0) scale(1.08) rotate(1.2deg);
  }
}
@keyframes sidebarAuroraBreath {
  0% {
    opacity: 0.76;
    filter: blur(5px) saturate(1.08);
  }
  15% {
    opacity: 1;
    filter: blur(7px) saturate(1.28);
  }
  37% {
    opacity: 0.84;
    filter: blur(8px) saturate(1.12);
  }
  61% {
    opacity: 0.98;
    filter: blur(6px) saturate(1.24);
  }
  83% {
    opacity: 0.86;
    filter: blur(7px) saturate(1.16);
  }
  100% {
    opacity: 0.94;
    filter: blur(6px) saturate(1.2);
  }
}
@keyframes sidebarAuroraSkew {
  0% {
    transform-origin: 44% 58%;
  }
  21% {
    transform-origin: 62% 42%;
  }
  43% {
    transform-origin: 31% 66%;
  }
  66% {
    transform-origin: 68% 74%;
  }
  100% {
    transform-origin: 39% 45%;
  }
}
@keyframes sidebarSheenSweep {
  0% {
    background-position: 232% 0, 10% 18%, 80% 12%, 20% 82%;
  }
  8% {
    background-position: 186% 0, 16% 30%, 74% 18%, 28% 74%;
  }
  21% {
    background-position: 116% 0, 34% 10%, 62% 26%, 18% 64%;
  }
  37% {
    background-position: 52% 0, 50% 24%, 46% 12%, 32% 58%;
  }
  52% {
    background-position: -4% 0, 34% 54%, 22% 22%, 12% 46%;
  }
  69% {
    background-position: -62% 0, 14% 36%, 32% 34%, 24% 56%;
  }
  84% {
    background-position: -106% 0, 20% 20%, 46% 20%, 34% 70%;
  }
  100% {
    background-position: -136% 0, 10% 18%, 80% 12%, 20% 82%;
  }
}
@keyframes sidebarSheenJitter {
  0% {
    opacity: 0.28;
    transform: translate3d(0, 0, 0);
  }
  17% {
    opacity: 0.56;
    transform: translate3d(1.8%, -0.5%, 0);
  }
  38% {
    opacity: 0.34;
    transform: translate3d(-1.2%, 0.8%, 0);
  }
  63% {
    opacity: 0.6;
    transform: translate3d(2.3%, -0.3%, 0);
  }
  81% {
    opacity: 0.3;
    transform: translate3d(-1.6%, 0.7%, 0);
  }
  100% {
    opacity: 0.52;
    transform: translate3d(2%, -0.1%, 0);
  }
}
#app {
  .main-container {
    min-height: 100vh;
    margin-left: var(--sidebar-width);
    transition: margin-left 0.25s ease;
    position: relative;
    background: transparent;
  }
  .sidebarHide {
    margin-left: 0 !important;
  }
  .sidebar-container {
    transition: width 0.25s ease;
    width: var(--sidebar-width) !important;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1001;
    overflow: hidden;
    padding: 0;
    font-size: 0;
    background: var(--sidebar-bg);
    border-right: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 8px 0 24px rgba(15, 23, 42, 0.08);
    isolation: isolate;
    &::before {
      content: "";
      position: absolute;
      inset: -28% -52% -18% -38%;
      z-index: 0;
      pointer-events: none;
      background:
        radial-gradient(circle at 9% 12%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.62), transparent 44%),
        radial-gradient(circle at 87% 18%, rgba(56, 189, 248, 0.4), transparent 48%),
        radial-gradient(circle at 20% 82%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.3), transparent 43%),
        radial-gradient(circle at 66% 62%, rgba(125, 211, 252, 0.24), transparent 50%),
        conic-gradient(
          from 210deg at 58% 38%,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14) 0deg,
          rgba(56, 189, 248, 0.05) 76deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.16) 180deg,
          rgba(125, 211, 252, 0.04) 290deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14) 360deg
        );
      filter: blur(7px) saturate(1.24) contrast(1.05);
      opacity: 0.96;
      transform: translate3d(0, 0, 0);
      transform-origin: 44% 58%;
      animation:
        sidebarAuroraDrift 17.9s cubic-bezier(0.31, 0.03, 0.18, 0.99) infinite,
        sidebarAuroraBreath 9.7s ease-in-out infinite,
        sidebarAuroraSkew 6.9s steps(23, end) infinite;
    }
    &::after {
      content: "";
      position: absolute;
      inset: 0;
      z-index: 0;
      pointer-events: none;
      background:
        linear-gradient(
          108deg,
          transparent 10%,
          rgba(255, 255, 255, 0.17) 34%,
          rgba(255, 255, 255, 0.04) 48%,
          transparent 72%
        ),
        linear-gradient(
          202deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.24) 0%,
          transparent 34%,
          rgba(56, 189, 248, 0.18) 66%,
          transparent 100%
        ),
        radial-gradient(circle at 74% 12%, rgba(125, 211, 252, 0.25), transparent 50%),
        radial-gradient(circle at 22% 84%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14), transparent 56%);
      background-size: 236% 100%, 186% 186%, 164% 164%, 180% 180%;
      background-position: 224% 0, 14% 16%, 78% 10%, 18% 82%;
      opacity: 0.52;
      transform: translate3d(0, 0, 0);
      animation:
        sidebarSheenSweep 13.1s linear infinite,
        sidebarSheenJitter 4.7s steps(31, end) infinite;
    }
    > * {
      position: relative;
      z-index: 1;
    }
    .horizontal-collapse-transition {
      transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
    }
    .scrollbar-wrapper {
      overflow-x: hidden !important;
      overflow-y: auto !important;
    }
    .el-scrollbar__bar.is-vertical {
      right: 2px;
    }
    .el-scrollbar {
      height: 100%;
    }
    &.has-logo {
      .el-scrollbar {
        height: calc(100% - 78px);
      }
    }
    .is-horizontal {
      display: none;
    }
    a {
      display: inline-block;
      width: 100%;
      overflow: hidden;
    }
    .el-menu {
      border: none !important;
      height: 100%;
      width: 100% !important;
      padding: 10px 0 16px;
      border-radius: 0;
      background: transparent !important;
      box-shadow: none;
      backdrop-filter: none;
    }
    .el-menu-item,
    .el-sub-menu__title,
    .menu-title {
      overflow: hidden !important;
      text-overflow: ellipsis !important;
      white-space: nowrap !important;
    }
    .el-menu-item .el-menu-tooltip__trigger {
      display: inline-flex !important;
      width: 100%;
      align-items: center;
    }
    .submenu-title-noDropdown,
    .el-sub-menu__title,
    .el-menu-item {
      min-width: 0 !important;
      width: calc(100% - 24px) !important;
      margin: 0 12px 8px !important;
      height: 50px;
      line-height: 50px;
      border-radius: 14px;
      padding-left: 16px !important;
      padding-right: 36px !important;
      box-sizing: border-box;
      transition: all 0.28s ease;
      color: var(--sidebar-text);
      background: linear-gradient(128deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.01));
      border: 1px solid rgba(255, 255, 255, 0.06) !important;
      position: relative;
      overflow: hidden;
    }
    .submenu-title-noDropdown::after,
    .el-sub-menu__title::after,
    .el-menu-item::after {
      content: "";
      position: absolute;
      inset: 0;
      background: linear-gradient(115deg, transparent 12%, rgba(255, 255, 255, 0.16), transparent 78%);
      transform: translateX(-100%);
      opacity: 0;
      transition: transform 0.45s ease, opacity 0.26s ease;
      pointer-events: none;
    }
    .submenu-title-noDropdown:hover,
    .el-sub-menu__title:hover,
    .el-menu-item:hover {
      background: linear-gradient(128deg, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.28), rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.08)) !important;
      border-color: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.32) !important;
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 8px 18px rgba(8, 36, 76, 0.24);
      transform: translateX(3px);
    }
    .submenu-title-noDropdown:hover::after,
    .el-sub-menu__title:hover::after,
    .el-menu-item:hover::after,
    .el-menu-item.is-active::after,
    .el-sub-menu.is-active > .el-sub-menu__title::after {
      transform: translateX(100%);
      opacity: 1;
    }
    & .theme-light .is-active > .el-sub-menu__title,
    & .theme-dark .is-active > .el-sub-menu__title,
    & .el-menu-item.is-active {
      color: #fff !important;
      background: var(--menu-active-bg, linear-gradient(135deg, var(--el-color-primary), var(--el-color-primary-light-3))) !important;
      background-size: 180% 180%;
      box-shadow: var(--menu-active-glow, 0 10px 24px rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.34));
      border-color: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.5) !important;
      animation: sidebarActiveFlow 4.6s ease infinite;
    }
    & .nest-menu .el-sub-menu > .el-sub-menu__title,
    & .el-sub-menu .el-menu-item {
      min-width: 0 !important;
      width: calc(100% - 32px) !important;
      margin: 0 16px 6px !important;
      height: 40px;
      line-height: 40px;
      padding-left: 12px !important;
      padding-right: 12px !important;
      border-radius: 8px;
      transition: all 0.24s ease;
      color: var(--sidebar-text);
      border: none !important;
      background: transparent;
      font-size: 13px;
      &:hover {
        background: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.12) !important;
        transform: translateX(4px);
      }
      &.is-active {
        background: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.85) !important;
        color: #fff !important;
        font-weight: 500;
        box-shadow: 0 4px 12px rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.25);
      }
    }
    // 子菜单容器样式 - 增加缩进和视觉层次
    & .el-sub-menu .el-menu {
      padding: 4px 0 8px;
      margin-left: 8px;
      border-left: 2px solid rgba(255, 255, 255, 0.08);
    }
  }
  .hideSidebar {
    .sidebar-container {
      width: var(--sidebar-collapsed-width) !important;
    }
    .main-container {
      margin-left: var(--sidebar-collapsed-width);
    }
    .submenu-title-noDropdown {
      padding: 0 !important;
      position: relative;
      display: flex !important;
      align-items: center;
      justify-content: center;
      .svg-icon {
        margin-right: 0;
      }
      .el-tooltip {
        padding: 0 !important;
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        width: 100%;
        .svg-icon {
          margin-left: 0;
        }
      }
      .el-menu-tooltip__trigger {
        width: 100%;
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        .svg-icon {
          width: 22px;
          height: 22px;
          margin-right: 0;
          flex-shrink: 0;
        }
      }
    }
    .el-sub-menu {
      overflow: hidden;
      & > .el-sub-menu__title {
        padding: 0 !important;
        display: flex !important;
        align-items: center;
        justify-content: center;
        .svg-icon {
          margin-left: 0;
          margin-right: 0;
        }
      }
    }
    .el-menu--collapse {
      width: 100% !important;
      padding: 12px 0 16px;
      > .el-menu-item,
      .el-sub-menu {
        & > .el-sub-menu__title,
        &.el-menu-item {
          width: calc(100% - 12px) !important;
          margin: 0 6px 8px !important;
          padding-left: 0 !important;
          padding-right: 0 !important;
          box-sizing: border-box;
          display: flex !important;
          align-items: center;
          justify-content: center;
          .svg-icon {
            width: 22px;
            height: 22px;
            margin-right: 0;
            flex-shrink: 0;
          }
          & > span {
            height: 0;
            width: 0;
            overflow: hidden;
            visibility: hidden;
            display: inline-block;
          }
        }
      }
    }
  }
  .el-menu--collapse .el-menu .el-sub-menu {
    min-width: var(--sidebar-width) !important;
  }
  .mobile {
    .main-container {
      margin-left: 0;
    }
    .sidebar-container {
      transition: transform 0.25s;
      width: var(--sidebar-width) !important;
    }
    &.hideSidebar {
      .sidebar-container {
        pointer-events: none;
        transition-duration: 0.3s;
        transform: translate3d(calc(-1 * var(--sidebar-width)), 0, 0);
      }
    }
  }
  .withoutAnimation {
    .main-container,
    .sidebar-container {
      transition: none;
    }
  }
}
.el-menu--vertical {
  & > .el-menu {
    .svg-icon {
      margin-right: 10px;
    }
  }
  .nest-menu .el-sub-menu > .el-sub-menu__title,
  .el-menu-item {
    min-width: 0 !important;
    margin: 0 10px 8px;
    width: calc(100% - 20px);
    height: 46px;
    line-height: 46px;
    padding-left: 12px !important;
    padding-right: 12px !important;
    box-sizing: border-box;
    border-radius: 12px;
    color: var(--sidebar-text);
    border: 1px solid rgba(255, 255, 255, 0.06) !important;
    background: linear-gradient(128deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.01));
    transition: all 0.24s ease;
    &:hover {
      background: linear-gradient(128deg, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.24), rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.07)) !important;
      border-color: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.3) !important;
      transform: translateX(2px);
    }
    &.is-active {
      background: var(--menu-active-bg, linear-gradient(135deg, var(--el-color-primary), var(--el-color-primary-light-3))) !important;
      background-size: 180% 180%;
      color: #fff !important;
      border-radius: 12px;
      box-shadow: var(--menu-active-glow, 0 10px 24px rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.34));
      border-color: rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.5) !important;
      animation: sidebarActiveFlow 4.6s ease infinite;
    }
  }
  > .el-menu--popup {
    max-height: 100vh;
    overflow: hidden;
    padding: 10px;
    border-radius: 14px;
    position: relative;
    isolation: isolate;
    border: 1px solid rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.26);
    box-shadow:
      0 18px 40px rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.16),
      var(--shadow-md);
    background: var(--sidebar-bg);
    backdrop-filter: blur(16px);
    &::before {
      content: "";
      position: absolute;
      inset: -28% -52% -18% -38%;
      z-index: 0;
      pointer-events: none;
      background:
        radial-gradient(circle at 9% 12%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.62), transparent 44%),
        radial-gradient(circle at 87% 18%, rgba(56, 189, 248, 0.4), transparent 48%),
        radial-gradient(circle at 20% 82%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.3), transparent 43%),
        radial-gradient(circle at 66% 62%, rgba(125, 211, 252, 0.24), transparent 50%),
        conic-gradient(
          from 210deg at 58% 38%,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14) 0deg,
          rgba(56, 189, 248, 0.05) 76deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.16) 180deg,
          rgba(125, 211, 252, 0.04) 290deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14) 360deg
        );
      filter: blur(7px) saturate(1.24) contrast(1.05);
      opacity: 0.96;
      transform: translate3d(0, 0, 0);
      transform-origin: 44% 58%;
      animation:
        sidebarAuroraDrift 17.9s cubic-bezier(0.31, 0.03, 0.18, 0.99) infinite,
        sidebarAuroraBreath 9.7s ease-in-out infinite,
        sidebarAuroraSkew 6.9s steps(23, end) infinite;
    }
    &::after {
      content: "";
      position: absolute;
      inset: 0;
      z-index: 0;
      pointer-events: none;
      background:
        linear-gradient(
          108deg,
          transparent 10%,
          rgba(255, 255, 255, 0.17) 34%,
          rgba(255, 255, 255, 0.04) 48%,
          transparent 72%
        ),
        linear-gradient(
          202deg,
          rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.24) 0%,
          transparent 34%,
          rgba(56, 189, 248, 0.18) 66%,
          transparent 100%
        ),
        radial-gradient(circle at 74% 12%, rgba(125, 211, 252, 0.25), transparent 50%),
        radial-gradient(circle at 22% 84%, rgba(var(--el-color-primary-rgb, 37, 99, 235), 0.14), transparent 56%);
      background-size: 236% 100%, 186% 186%, 164% 164%, 180% 180%;
      background-position: 224% 0, 14% 16%, 78% 10%, 18% 82%;
      opacity: 0.52;
      transform: translate3d(0, 0, 0);
      animation:
        sidebarSheenSweep 13.1s linear infinite,
        sidebarSheenJitter 4.7s steps(31, end) infinite;
    }
    > * {
      position: relative;
      z-index: 1;
    }
    > .el-menu {
      max-height: calc(100vh - 20px);
      overflow-y: auto;
      overflow-x: hidden;
      &::-webkit-scrollbar-track-piece {
        background: var(--surface-muted);
      }
      &::-webkit-scrollbar {
        width: 5px;
      }
      &::-webkit-scrollbar-thumb {
        background: var(--accent-light);
        border-radius: 10px;
      }
    }
  }
}
@keyframes sidebarActiveFlow {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}
@keyframes sidebarAuroraDrift {
  0% {
    transform: translate3d(-6.3%, -1.8%, 0) scale(1.05) rotate(-1.8deg);
  }
  6% {
    transform: translate3d(2.2%, -4.6%, 0) scale(1.08) rotate(0.7deg);
  }
  17% {
    transform: translate3d(-3.7%, 4.4%, 0) scale(1.11) rotate(2deg);
  }
  27% {
    transform: translate3d(5.6%, 1.2%, 0) scale(1.03) rotate(-1deg);
  }
  39% {
    transform: translate3d(-4.8%, -3.1%, 0) scale(1.09) rotate(1.5deg);
  }
  52% {
    transform: translate3d(2.9%, 4.8%, 0) scale(1.04) rotate(-1.4deg);
  }
  64% {
    transform: translate3d(-6.4%, 0.3%, 0) scale(1.08) rotate(0.5deg);
  }
  73% {
    transform: translate3d(4.8%, -3.9%, 0) scale(1.05) rotate(1.6deg);
  }
  81% {
    transform: translate3d(-2.4%, 2.9%, 0) scale(1.1) rotate(-0.8deg);
  }
  92% {
    transform: translate3d(3.7%, -1.7%, 0) scale(1.06) rotate(-1.6deg);
  }
  100% {
    transform: translate3d(-5.9%, 0.8%, 0) scale(1.08) rotate(1.2deg);
  }
}
@keyframes sidebarAuroraBreath {
  0% {
    opacity: 0.76;
    filter: blur(5px) saturate(1.08);
  }
  15% {
    opacity: 1;
    filter: blur(7px) saturate(1.28);
  }
  37% {
    opacity: 0.84;
    filter: blur(8px) saturate(1.12);
  }
  61% {
    opacity: 0.98;
    filter: blur(6px) saturate(1.24);
  }
  83% {
    opacity: 0.86;
    filter: blur(7px) saturate(1.16);
  }
  100% {
    opacity: 0.94;
    filter: blur(6px) saturate(1.2);
  }
}
@keyframes sidebarAuroraSkew {
  0% {
    transform-origin: 44% 58%;
  }
  21% {
    transform-origin: 62% 42%;
  }
  43% {
    transform-origin: 31% 66%;
  }
  66% {
    transform-origin: 68% 74%;
  }
  100% {
    transform-origin: 39% 45%;
  }
}
@keyframes sidebarSheenSweep {
  0% {
    background-position: 232% 0, 10% 18%, 80% 12%, 20% 82%;
  }
  8% {
    background-position: 186% 0, 16% 30%, 74% 18%, 28% 74%;
  }
  21% {
    background-position: 116% 0, 34% 10%, 62% 26%, 18% 64%;
  }
  37% {
    background-position: 52% 0, 50% 24%, 46% 12%, 32% 58%;
  }
  52% {
    background-position: -4% 0, 34% 54%, 22% 22%, 12% 46%;
  }
  69% {
    background-position: -62% 0, 14% 36%, 32% 34%, 24% 56%;
  }
  84% {
    background-position: -106% 0, 20% 20%, 46% 20%, 34% 70%;
  }
  100% {
    background-position: -136% 0, 10% 18%, 80% 12%, 20% 82%;
  }
}
@keyframes sidebarSheenJitter {
  0% {
    opacity: 0.28;
    transform: translate3d(0, 0, 0);
  }
  17% {
    opacity: 0.56;
    transform: translate3d(1.8%, -0.5%, 0);
  }
  38% {
    opacity: 0.34;
    transform: translate3d(-1.2%, 0.8%, 0);
  }
  63% {
    opacity: 0.6;
    transform: translate3d(2.3%, -0.3%, 0);
  }
  81% {
    opacity: 0.3;
    transform: translate3d(-1.6%, 0.7%, 0);
  }
  100% {
    opacity: 0.52;
    transform: translate3d(2%, -0.1%, 0);
  }
}
src/layout/components/Sidebar/SidebarItem.vue
@@ -102,57 +102,70 @@
</script>
<style lang="scss" scoped>
.sidebar-item-wrapper {
  :deep(.menu-icon) {
    width: 26px;
    height: 26px;
    margin-right: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: color 0.2s ease;
    color: var(--sidebar-text);
    opacity: 0.88;
  }
  :deep(.el-menu-item:hover .menu-icon),
  :deep(.el-sub-menu__title:hover .menu-icon) {
    color: #ffffff;
    opacity: 1;
  }
.sidebar-item-wrapper {
  :deep(.menu-icon) {
    width: 26px;
    height: 26px;
    margin-right: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: color 0.2s ease;
    color: var(--sidebar-text);
    opacity: 0.88;
  }
  :deep(.el-menu-item:hover .menu-icon),
  :deep(.el-sub-menu__title:hover .menu-icon) {
    color: #ffffff;
    opacity: 1;
  }
  
  :deep(.el-menu-item.is-active .menu-icon) {
    color: var(--menu-active-text) !important;
    opacity: 1;
  }
  
  :deep(.menu-title) {
    font-weight: 500;
    transition: color 0.2s ease;
    color: var(--sidebar-text);
    opacity: 0.82;
  }
  :deep(.el-menu-item:hover .menu-title),
  :deep(.el-sub-menu__title:hover .menu-title) {
    color: #ffffff;
    opacity: 1;
  }
  :deep(.el-menu-item.is-active .menu-title) {
    color: var(--menu-active-text) !important;
    opacity: 1;
  }
  :deep(.nest-menu) {
    .menu-icon {
      width: 22px;
      height: 22px;
      margin-right: 10px;
    }
    .menu-title { font-size: 13px; }
  }
}
  :deep(.menu-title) {
    font-weight: 500;
    transition: color 0.2s ease;
    color: var(--sidebar-text);
    opacity: 0.82;
  }
  :deep(.el-menu-item:hover .menu-title),
  :deep(.el-sub-menu__title:hover .menu-title) {
    color: #ffffff;
    opacity: 1;
  }
  :deep(.el-menu-item.is-active .menu-title) {
    color: var(--menu-active-text) !important;
    opacity: 1;
  }
  :deep(.nest-menu) {
    .menu-icon {
      width: 18px;
      height: 18px;
      margin-right: 8px;
      opacity: 0.7;
    }
    .menu-title {
      font-size: 13px;
      opacity: 0.85;
    }
    .el-menu-item.is-active {
      .menu-icon {
        opacity: 1;
      }
      .menu-title {
        opacity: 1;
      }
    }
  }
}
</style>
src/views/basicData/parameterMaintenance/index.vue
@@ -84,7 +84,7 @@
        </el-form-item> -->
        <el-form-item label="创建时间"
                      prop="createTime">
          <el-date-picker v-model="formData.createTime"
          <el-date-picker v-model="formCreateTimeDate"
                          type="date"
                          placeholder="选择日期"
                          value-format="YYYY-MM-DD"
@@ -215,7 +215,8 @@
</template>
<script setup>
  import { onMounted, ref, reactive } from "vue";
  import { onMounted, ref, reactive, computed } from "vue";
  import dayjs from "dayjs";
  import {
    parameterListPage,
    addParameter,
@@ -369,6 +370,12 @@
        },
      },
    ],
  });
  const formCreateTimeDate = computed({
    get: () => (formData.createTime ? String(formData.createTime).split(" ")[0] : ""),
    set: (value) => {
      formData.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
    },
  });
  // const productTypes = ref([]);
  const isEdit = ref(false);
@@ -528,7 +535,7 @@
    formData.unit = "";
    formData.remark = "";
    formData.isRequired = 0;
    formData.createTime = new Date().toISOString().split("T")[0];
    formData.createTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
    dialogVisible.value = true;
  };
@@ -547,6 +554,7 @@
    formData.remark = row.remark || "";
    formData.paramFormat = row.paramFormat || "";
    formData.isRequired = row.isRequired || 0;
    formData.createTime = row.createTime || "";
    dialogVisible.value = true;
  };
src/views/collaborativeApproval/sealManagement/index.vue
@@ -7,7 +7,6 @@
        </div>
      </template>
   <!-- 用印申请管理 -->
        <div class="tab-content">
            <el-row :gutter="20" class="mb-20 ">
@@ -45,7 +44,7 @@
              :isShowPagination="true"
              @pagination="paginationChange"
            />
        </div>
        </div>
    </el-card>
    <!-- 用印申请对话框 -->
@@ -177,6 +176,7 @@
const sealFormRef = ref()
const userList = ref([])
const sealForm = reactive({
  id: null,
  applicationNum: '',
  title: '',
  sealType: '',
@@ -241,9 +241,9 @@
// 用印申请表格列配置(需在 getStatusText/getSealTypeText 等之后定义)
const sealTableColumn = ref([
  { label: '申请编号', prop: 'applicationNum',},
  { label: '申请编号', prop: 'applicationNum' },
  { label: '申请标题', prop: 'title', showOverflowTooltip: true },
  { label: '申请人', prop: 'createUserName', },
  { label: '申请人', prop: 'createUserName' },
  { label: '所属部门', prop: 'department', width: 150 },
  {
    label: '用印类型',
@@ -261,34 +261,38 @@
    formatData: (v) => getStatusText(v),
    formatType: (v) => getStatusType(v)
  },
  { label: '审批人', prop: 'approveUserName', width: 100 },
  {
    dataType: 'action',
    label: '操作',
    width: 200,
    width: 250,
    fixed: 'right',
    align: 'center',
    operation: [
      {
        name: '审批',
        clickFun: (row) => approveSeal(row),
        showHide: (row) => row.status === 'pending'
        showHide: (row) => row.status === 'pending' && Number(userStore.id) === row.approveUserId
      },
      {
        name: '拒绝',
        clickFun: (row) => rejectSeal(row),
        showHide: (row) => row.status === 'pending'
        showHide: (row) => row.status === 'pending' && Number(userStore.id) === row.approveUserId
      },
            { name: '详情', clickFun: (row) => viewSealDetail(row) }
      {
        name: '重新申请',
        clickFun: (row) => reapplySeal(row),
        showHide: (row) => row.status === 'rejected' && Number(userStore.id) === row.createUser
      },
      { name: '详情', clickFun: (row) => viewSealDetail(row) }
    ]
  }
])
// 搜索印章申请
const searchSealApplications = () => {
  page.current=1
  page.current = 1
  getSealApplicationList()
  // ElMessage.success('搜索完成')
}
// 重置印章申请搜索
const resetSealSearch = () => {
@@ -297,37 +301,58 @@
  sealSearchForm.applicationNum = ''
  searchSealApplications()
}
// 重新申请用印
const reapplySeal = (row) => {
  // 预填表单数据
  Object.assign(sealForm, {
    id: row.id,
    applicationNum: row.applicationNum,
    title: row.title,
    sealType: row.sealType,
    reason: row.reason,
    approveUserId: row.approveUserId,
    urgency: row.urgency || 'normal',
    status: 'pending',
    storageBlobDTOs: row.storageBlobVOList || []
  })
  showSealApplyDialog.value = true
}
// 提交用印申请
const submitSealApplication = async () => {
  try {
    await sealFormRef.value.validate()
    addSealApplication(sealForm).then(res => {
      if(res.code == 200){
        ElMessage.success('申请提交成功')
    const request = sealForm.id ? updateSealApplication : addSealApplication
    request(sealForm).then(res => {
      if (res.code == 200) {
        ElMessage.success(sealForm.id ? '重新申请成功' : '申请提交成功')
        closeSealApplyDialog()
        getSealApplicationList()
        Object.assign(sealForm, {
        applicationNum: '',
        title: '',
        sealType: '',
        reason: '',
        approveUserId: '',
        urgency: 'normal',
        status: 'pending',
        storageBlobDTOs: []
      })
          id: null,
          applicationNum: '',
          title: '',
          sealType: '',
          reason: '',
          approveUserId: '',
          urgency: 'normal',
          status: 'pending',
          storageBlobDTOs: []
        })
      }
    }).catch(err => {
      console.log(err.msg)
    })
  } catch (error) {
  }
}
// 关闭用印申请对话框
const closeSealApplyDialog = () => {
  // 清空表单数据
  Object.assign(sealForm, {
    id: null,
    applicationNum: '',
    title: '',
    sealType: '',
@@ -383,7 +408,7 @@
  }).then(() => {
    row.status = 'approved'
    updateSealApplication(row).then(res => {
      if(res.code == 200){
      if (res.code == 200) {
        ElMessage.success('审批通过')
        getSealApplicationList()
      }
@@ -399,8 +424,9 @@
    inputErrorMessage: '拒绝原因不能为空'
  }).then(({ value }) => {
    row.status = 'rejected'
    row.reason = value
    updateSealApplication(row).then(res => {
      if(res.code == 200){
      if (res.code == 200) {
        ElMessage.success('已拒绝申请')
        getSealApplicationList()
      }
@@ -418,13 +444,13 @@
const getSealApplicationList = async () => {
  tableLoading.value = true
  listSealApplication(page, sealSearchForm)
  .then(res => {
    sealApplications.value = res.data.records
    page.total = res.data.total
    tableLoading.value = false
  }).catch(err => {
    tableLoading.value = false
  })
    .then(res => {
      sealApplications.value = res.data.records
      page.total = res.data.total
      tableLoading.value = false
    }).catch(err => {
      tableLoading.value = false
    })
}
// 分页变化处理
const paginationChange = (obj) => {
@@ -491,4 +517,4 @@
.attachment-table {
  border-radius: 4px;
}
</style>
</style>
src/views/financialManagement/assets/fixedAssets.vue
@@ -178,7 +178,7 @@
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="创建时间" prop="createTime">
              <el-date-picker v-model="form.createTime" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 100%;" />
              <el-date-picker v-model="createTimeDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 100%;" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -196,6 +196,7 @@
<script setup>
import { ref, reactive, onMounted, computed } from "vue";
import dayjs from "dayjs";
import { ElMessage, ElMessageBox } from "element-plus";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import {
@@ -270,6 +271,12 @@
const form = reactive({
  ...createDefaultForm(),
});
const createTimeDate = computed({
  get: () => (form.createTime ? String(form.createTime).split(" ")[0] : ""),
  set: (value) => {
    form.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
  },
});
const rules = {
@@ -371,7 +378,7 @@
  dialogTitle.value = "新增固定资产";
  Object.assign(form, createDefaultForm(), {
    purchaseDate: new Date().toISOString().split('T')[0],
    createTime: new Date().toISOString().split('T')[0],
    createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
  });
  dialogVisible.value = true;
};
src/views/financialManagement/assets/intangibleAssets.vue
@@ -168,7 +168,7 @@
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="创建时间" prop="createTime">
              <el-date-picker v-model="form.createTime" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 100%;" />
              <el-date-picker v-model="createTimeDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 100%;" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -189,6 +189,7 @@
<script setup>
import { ref, reactive, onMounted, computed } from "vue";
import dayjs from "dayjs";
import { ElMessage, ElMessageBox } from "element-plus";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import {
@@ -262,6 +263,12 @@
const form = reactive({
  ...createDefaultForm(),
});
const createTimeDate = computed({
  get: () => (form.createTime ? String(form.createTime).split(" ")[0] : ""),
  set: (value) => {
    form.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
  },
});
const rules = {
@@ -369,7 +376,7 @@
  dialogTitle.value = "新增无形资产";
  Object.assign(form, createDefaultForm(), {
    acquisitionDate: new Date().toISOString().split('T')[0],
    createTime: new Date().toISOString().split('T')[0],
    createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
  });
  dialogVisible.value = true;
};
src/views/financialManagement/payable/paymentApply.vue
@@ -160,7 +160,7 @@
          <el-col :span="12">
            <el-form-item label="创建时间" prop="createTime">
              <el-date-picker
                v-model="form.createTime"
                v-model="formCreateTimeDate"
                type="date"
                placeholder="选择日期"
                value-format="YYYY-MM-DD"
@@ -260,7 +260,7 @@
          <el-col :span="12">
            <el-form-item label="创建时间" prop="createTime">
              <el-date-picker
                v-model="paymentForm.createTime"
                v-model="paymentFormCreateTimeDate"
                type="date"
                placeholder="选择日期"
                value-format="YYYY-MM-DD"
@@ -353,6 +353,7 @@
<script setup>
import { ref, reactive, computed, onMounted, nextTick, getCurrentInstance } from "vue";
import dayjs from "dayjs";
import { ElMessage, ElMessageBox } from "element-plus";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import { getOptions } from "@/api/procurementManagement/procurementLedger.js";
@@ -454,6 +455,18 @@
  inboundBatches: "",
  status: 0,
  createTime: "",
});
const formCreateTimeDate = computed({
  get: () => (form.createTime ? String(form.createTime).split(" ")[0] : ""),
  set: (value) => {
    form.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
  },
});
const paymentFormCreateTimeDate = computed({
  get: () => (paymentForm.createTime ? String(paymentForm.createTime).split(" ")[0] : ""),
  set: (value) => {
    paymentForm.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
  },
});
const rules = {
@@ -620,6 +633,7 @@
    remark: form.remark || "",
    status: 0,
    paymentAmount: form.paymentAmount,
    createTime: form.createTime,
  };
  if (forUpdate) {
    payload.id = currentId.value;
@@ -730,7 +744,7 @@
    stockInRecordIds: [],
    inboundBatches: "",
    status: 0,
    createTime: new Date().toISOString().split("T")[0],
    createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
  });
  inboundBatchList.value = [];
  inboundBatchOptions.value = [];
@@ -809,7 +823,7 @@
    bankAccount: row.bankAccountNum ?? row.bankAccount ?? "",
    bankName: row.bankAccountName ?? row.bankName ?? "",
    remark: "",
    createTime: new Date().toISOString().split("T")[0],
    createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
  });
  paymentDialogVisible.value = true;
  nextTick(() => {
src/views/financialManagement/receivable/invoiceApply.vue
@@ -193,7 +193,7 @@
          <el-col :span="12">
            <el-form-item label="创建时间" prop="createTime">
              <el-date-picker
                v-model="form.createTime"
                v-model="formCreateTimeDate"
                type="date"
                placeholder="选择日期"
                value-format="YYYY-MM-DD"
@@ -267,6 +267,7 @@
<script setup>
import { ref, reactive, computed, onMounted, nextTick, getCurrentInstance, defineAsyncComponent } from "vue";
import dayjs from "dayjs";
import { ElMessage, ElMessageBox } from "element-plus";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import { listCustomer } from "@/api/basicData/customer.js";
@@ -540,6 +541,12 @@
  remark: "",
  createTime: "",
});
const formCreateTimeDate = computed({
  get: () => (form.createTime ? String(form.createTime).split(" ")[0] : ""),
  set: (value) => {
    form.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
  },
});
const rules = {
  customerId: [{ required: true, message: "请选择客户", trigger: "change" }],
@@ -721,6 +728,7 @@
    status: normalizeStatus(row.status ?? row.auditStatus),
    outboundBatchNos,
    outboundBatches: formatOutboundBatches(row.outboundBatches),
    createTime: row.createTime ?? "",
  });
};
@@ -739,7 +747,7 @@
    applyDate: new Date().toISOString().split("T")[0],
    content: "",
    remark: "",
    createTime: new Date().toISOString().split("T")[0],
    createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
  });
  outboundBatchList.value = [];
  outboundBatchOptions.value = [];
src/views/financialManagement/receivable/receipt.vue
@@ -196,7 +196,7 @@
          <el-col :span="12">
            <el-form-item label="创建时间"
                          prop="createTime">
              <el-date-picker v-model="form.createTime"
              <el-date-picker v-model="formCreateTimeDate"
                              type="date"
                              placeholder="选择日期"
                              value-format="YYYY-MM-DD"
@@ -299,6 +299,7 @@
    nextTick,
    getCurrentInstance,
  } from "vue";
  import dayjs from "dayjs";
  import { ElMessage, ElMessageBox } from "element-plus";
  import FormDialog from "@/components/Dialog/FormDialog.vue";
  import { listCustomer } from "@/api/basicData/customer.js";
@@ -391,6 +392,12 @@
    outboundBatches: "",
    remark: "",
    createTime: "",
  });
  const formCreateTimeDate = computed({
    get: () => (form.createTime ? String(form.createTime).split(" ")[0] : ""),
    set: (value) => {
      form.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
    },
  });
  const rules = {
@@ -691,6 +698,7 @@
      stockOutRecordIds,
      outboundBatches: formatOutboundBatches(row.outboundBatches),
      remark: row.remark ?? "",
      createTime: row.createTime ?? "",
    });
  };
@@ -767,7 +775,7 @@
      stockOutRecordIds: [],
      outboundBatches: "",
      remark: "",
      createTime: new Date().toISOString().split("T")[0],
      createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
    });
    outboundBatchList.value = [];
    outboundBatchOptions.value = [];
src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
@@ -460,6 +460,9 @@
    currentNodeIndex: 0,
    approvalRecords,
    rejectReason: approvalRecords.find(r => r.result === "rejected")?.opinion || "",
    purchaseContractNumber: row.purchaseContractNumber || "",
    quotationNo: row.quotationNo || "",
    shippingNo: row.shippingNo || "",
  };
}
src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
@@ -35,9 +35,116 @@
    </div>
    <div class="detail-block">
      <div class="detail-block-title">填报内容</div>
      <FormPayloadFields :fields="formResolved.fields"
      <!-- 默认表单展示 -->
      <FormPayloadFields v-if="!isSpecialApprovalType"
                         :fields="formResolved.fields"
                         :form-payload="formResolved.formPayload"
                         readonly />
      <!-- 发货审批详情 -->
      <template v-else-if="row.businessType === 7">
        <div v-if="detailData.shippingInfo" class="shipment-detail">
          <el-divider content-position="left">发货详情</el-divider>
          <el-descriptions :column="2" border>
            <el-descriptions-item label="销售订单">{{ detailData.shippingInfo.salesContractNo || "--" }}</el-descriptions-item>
            <el-descriptions-item label="发货订单号">{{ detailData.shippingInfo.shippingNo || "--" }}</el-descriptions-item>
            <el-descriptions-item label="客户名称">{{ detailData.shippingInfo.customerName || "--" }}</el-descriptions-item>
            <el-descriptions-item label="发货类型">{{ detailData.shippingInfo.type || "--" }}</el-descriptions-item>
            <el-descriptions-item label="发货日期">{{ detailData.shippingInfo.shippingDateDate || "--" }}</el-descriptions-item>
            <el-descriptions-item label="审核状态">{{ detailData.shippingInfo.status || "--" }}</el-descriptions-item>
            <el-descriptions-item label="发货车牌号">{{ detailData.shippingInfo.shippingCarNumber || "--" }}</el-descriptions-item>
            <el-descriptions-item label="快递公司">{{ detailData.shippingInfo.expressCompany || "--" }}</el-descriptions-item>
            <el-descriptions-item label="快递单号" :span="2">{{ detailData.shippingInfo.expressNumber || "--" }}</el-descriptions-item>
          </el-descriptions>
          <div v-if="detailData.shippingProductDetailDtoList.length" style="margin-top: 20px;">
            <h4>产品明细</h4>
            <el-table :data="detailData.shippingProductDetailDtoList"
                      border
                      size="small"
                      style="width: 100%">
              <el-table-column label="批号" prop="batchNo" min-width="160" show-overflow-tooltip />
              <el-table-column label="产品名称" prop="productName" min-width="160" show-overflow-tooltip />
              <el-table-column label="规格型号" prop="specificationModel" min-width="160" show-overflow-tooltip />
              <el-table-column label="发货数量" prop="deliveryQuantity" min-width="120" align="center" />
            </el-table>
          </div>
        </div>
      </template>
      <!-- 采购审批详情 -->
      <template v-else-if="row.businessType === 5">
        <div v-if="detailData" class="procurement-detail">
          <el-divider content-position="left">采购详情</el-divider>
          <el-descriptions :column="2" border>
            <el-descriptions-item label="采购合同号">{{ detailData.purchaseContractNumber || "--" }}</el-descriptions-item>
            <el-descriptions-item label="供应商名称">{{ detailData.supplierName || "--" }}</el-descriptions-item>
            <el-descriptions-item label="项目名称">{{ detailData.projectName || "--" }}</el-descriptions-item>
            <el-descriptions-item label="销售合同号">{{ detailData.salesContractNo || "--" }}</el-descriptions-item>
            <el-descriptions-item label="签订日期">{{ detailData.executionDate || "--" }}</el-descriptions-item>
            <el-descriptions-item label="录入日期">{{ detailData.entryDate || "--" }}</el-descriptions-item>
            <el-descriptions-item label="付款方式">{{ detailData.paymentMethod || "--" }}</el-descriptions-item>
            <el-descriptions-item label="合同金额" :span="2">
              <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">
                ¥{{ Number(detailData.contractAmount ?? 0).toFixed(2) }}
              </span>
            </el-descriptions-item>
          </el-descriptions>
          <div v-if="detailData.productData.length" style="margin-top: 20px;">
            <h4>产品明细</h4>
            <el-table :data="detailData.productData"
                      border
                      style="width: 100%">
              <el-table-column prop="productCategory" label="产品名称" />
              <el-table-column prop="specificationModel" label="规格型号" />
              <el-table-column prop="unit" label="单位" />
              <el-table-column prop="quantity" label="数量" />
              <el-table-column prop="taxInclusiveUnitPrice" label="含税单价">
                <template #default="scope">¥{{ Number(scope.row.taxInclusiveUnitPrice ?? 0).toFixed(2) }}</template>
              </el-table-column>
              <el-table-column prop="taxInclusiveTotalPrice" label="含税总价">
                <template #default="scope">¥{{ Number(scope.row.taxInclusiveTotalPrice ?? 0).toFixed(2) }}</template>
              </el-table-column>
            </el-table>
          </div>
        </div>
      </template>
      <!-- 报价审批详情 -->
      <template v-else-if="row.businessType === 6">
        <div v-if="detailData" class="quotation-detail">
          <el-divider content-position="left">报价详情</el-divider>
          <el-descriptions :column="2" border>
            <el-descriptions-item label="报价单号">{{ detailData.quotationNo || "--" }}</el-descriptions-item>
            <el-descriptions-item label="客户名称">{{ detailData.customer || "--" }}</el-descriptions-item>
            <el-descriptions-item label="业务员">{{ detailData.salesperson || "--" }}</el-descriptions-item>
            <el-descriptions-item label="报价日期">{{ detailData.quotationDate || "--" }}</el-descriptions-item>
            <el-descriptions-item label="有效期至">{{ detailData.validDate || "--" }}</el-descriptions-item>
            <el-descriptions-item label="付款方式">{{ detailData.paymentMethod || "--" }}</el-descriptions-item>
            <el-descriptions-item label="报价总额" :span="2">
              <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">
                ¥{{ Number(detailData.totalAmount ?? 0).toFixed(2) }}
              </span>
            </el-descriptions-item>
          </el-descriptions>
          <div v-if="detailData.products.length" style="margin-top: 20px;">
            <h4>产品明细</h4>
            <el-table :data="detailData.products"
                      border
                      style="width: 100%">
              <el-table-column prop="product" label="产品名称" />
              <el-table-column prop="specification" label="规格型号" />
              <el-table-column prop="unit" label="单位" />
              <el-table-column prop="unitPrice" label="单价">
                <template #default="scope">¥{{ Number(scope.row.unitPrice ?? 0).toFixed(2) }}</template>
              </el-table-column>
            </el-table>
          </div>
          <div v-if="detailData.remark" style="margin-top: 20px;">
            <h4>备注</h4>
            <p>{{ detailData.remark }}</p>
          </div>
        </div>
      </template>
    </div>
    <div v-if="attachmentList.length"
         class="detail-block">
@@ -86,9 +193,21 @@
  const props = defineProps({
    row: { type: Object, default: () => ({}) },
    detailData: { type: Object, default: () => ({}) },
  });
  const formResolved = computed(() => resolveInstanceFormFields(props.row));
  // 是否为特殊审批类型(采购、发货、报价)
  const isSpecialApprovalType = computed(() => {
    return [5, 7, 6].includes(props.row.businessType);
  });
  // 详情数据(直接使用传入的 detail-data 参数)
  const detailData = computed(() => {
    return props.detailData || {};
  });
  const attachmentList = computed(() => {
    const list = props.row.storageBlobVOList || props.row.storageBlobDTOs || [];
@@ -164,4 +283,4 @@
    align-items: center;
    flex-shrink: 0;
  }
</style>
</style>
src/views/officeProcessAutomation/ApproveManage/approve-list/index.vue
@@ -174,7 +174,7 @@
      class="approve-detail-dialog"
    >
      <div class="approve-detail-body">
        <ApproveDetailPanel :row="detailRow" />
        <ApproveDetailPanel :row="detailRow" :detail-data="detailData" />
        <div class="detail-block">
          <div class="detail-block-title">
            审批流程({{ detailRow.tasks?.length || detailRow.flowNodes?.length || 0 }} 项)
@@ -292,7 +292,7 @@
      destroy-on-close
      @closed="approveOpinion = ''"
    >
      <ApproveDetailPanel :row="approveDialog.row" />
      <ApproveDetailPanel :row="approveDialog.row" :detail-data="detailData" />
      <div class="detail-block mt16">
        <div class="detail-block-title">
          审批流程({{ approveDialog.row?.tasks?.length || approveDialog.row?.flowNodes?.length || 0 }} 项)
@@ -371,6 +371,7 @@
  tableColumn,
  detailDialog,
  detailRow,
  detailData,
  reimburseDialog,
  approveDialog,
  approveOpinion,
@@ -614,4 +615,4 @@
  border-left: 3px solid var(--el-color-primary);
  line-height: 1.4;
}
</style>
</style>
src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js
@@ -10,6 +10,9 @@
  saveApprovalInstance,
  updateApprovalInstance,
} from "@/api/officeProcessAutomation/approvalInstance.js";
import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
import { getPurchaseByCode } from "@/api/procurementManagement/procurementLedger.js";
import { getDeliveryDetailByShippingNo } from "@/api/salesManagement/deliveryLedger.js";
import useUserStore from "@/store/modules/user";
import { Search } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
@@ -77,6 +80,7 @@
  const detailDialog = reactive({ visible: false });
  const detailRow = ref({});
  const detailData = ref({});
  const approveDialog = reactive({ visible: false, row: null });
  const approveOpinion = ref("");
@@ -138,7 +142,7 @@
  }));
  const tableColumn = ref([
    { label: "申请人编号", prop: "applicantNo", width: 110 },
    // { label: "申请人编号", prop: "applicantNo", width: 110 },
    { label: "申请人名称", prop: "applicantName", minWidth: 100 },
    { label: "模板类型", prop: "businessName", minWidth: 120 },
    {
@@ -223,7 +227,7 @@
        fetchBusinessTypeOptions(),
        listApprovalTemplate(TEMPLATE_TYPE_CUSTOM),
      ]);
      submitBusinessTypeOptions.value = typeOptions;
      submitBusinessTypeOptions.value = typeOptions.filter((x) => ![5, 6, 7].includes(x.value));
      allSubmitTemplates.value = unwrapTemplateList(customRes)
        .filter((row) => mapEnabledFromApi(row.enabled))
        .map(mapSubmitTemplateCard);
@@ -291,11 +295,46 @@
      await openReimburseDetail(row, "detail");
      return;
    }
    detailRow.value = { ...row };
    // 报价审批:用审批事由字段承载的"报价单号"去查报价列表
    if (row.businessType === 6) {
      const quotationNo = row?.quotationNo;
      if (quotationNo) {
        const res = await getQuotationList({ quotationNo });
        const records = res?.data?.records || [];
        detailData.value = records[0] || {};
      }
    }
    // 采购审批:用审批事由字段承载的"采购合同号"去查采购详情
    else if (row.businessType === 5) {
      const purchaseContractNumber = row?.purchaseContractNumber;
      if (purchaseContractNumber) {
        const res = await getPurchaseByCode({ purchaseContractNumber });
        detailData.value = res || {};
      }
    }
    // 发货审批:用审批事由字段承载的"发货单号"去查发货详情
    else if (row.businessType === 7) {
      const shippingNo = row?.shippingNo;
      if (shippingNo) {
        const res = await getDeliveryDetailByShippingNo({ shippingNo });
        detailData.value = res?.data || res || {};
      }
    }
    // 其他审批类型
    else {
      detailData.value = {};
    }
    detailDialog.visible = true;
  }
  async function openApprove(row) {
    if (inferReimburseModuleKeyFromInstance(row)) {
      approveOpinion.value = "";
      await openReimburseDetail(row, "approve");
@@ -303,6 +342,38 @@
    }
    approveDialog.row = { ...row };
    approveOpinion.value = "";
    // 报价审批:用审批事由字段承载的"报价单号"去查报价列表
    if (row.businessType === 6) {
      const quotationNo = row?.quotationNo;
      if (quotationNo) {
        const res = await getQuotationList({ quotationNo });
        const records = res?.data?.records || [];
        detailData.value = records[0] || {};
      }
    }
    // 采购审批:用审批事由字段承载的"采购合同号"去查采购详情
    else if (row.businessType === 5) {
      const purchaseContractNumber = row?.purchaseContractNumber;
      if (purchaseContractNumber) {
        const res = await getPurchaseByCode({ purchaseContractNumber });
        detailData.value = res || {};
      }
    }
    // 发货审批:用审批事由字段承载的"发货单号"去查发货详情
    else if (row.businessType === 7) {
      const shippingNo = row?.shippingNo;
      if (shippingNo) {
        const res = await getDeliveryDetailByShippingNo({ shippingNo });
        detailData.value = res?.data || res || {};
      }
    }
    // 其他审批类型
    else {
      detailData.value = {};
    }
    approveDialog.visible = true;
  }
@@ -632,6 +703,7 @@
    tableColumn,
    detailDialog,
    detailRow,
    detailData,
    reimburseDialog,
    approveDialog,
    approveOpinion,
@@ -673,4 +745,4 @@
    selectedRows,
    batchDelete,
  };
}
}
src/views/officeProcessAutomation/ApproveManage/approve-template/index.vue
@@ -380,23 +380,18 @@
      <template v-if="detailAttachments.length">
        <el-tag
          v-for="(f, i) in detailAttachments"
          :key="i"
          class="detail-attachment-tag"
          type="info"
          effect="plain"
        >
          {{ attachmentDisplayName(f) }}
        </el-tag>
        <div class="detail-attachment-list">
          <div
            v-for="(f, i) in detailAttachments"
            :key="i"
            class="detail-attachment-item"
            @click="openAttachmentFile(f)"
          >
            <el-icon class="attachment-icon"><Document /></el-icon>
            <span class="attachment-name">{{ attachmentDisplayName(f) }}</span>
            <el-icon class="attachment-download"><Download /></el-icon>
          </div>
        </div>
      </template>
@@ -422,7 +417,7 @@
<script setup>
import { ArrowRight, Plus, RefreshRight } from "@element-plus/icons-vue";
import { ArrowRight, Document, Download, Plus, RefreshRight } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
@@ -525,6 +520,14 @@
}
function openAttachmentFile(file) {
  const url = file?.url || file?.previewURL || file?.downloadURL || file?.previewUrl || "";
  if (url) {
    window.open(url, "_blank");
  } else {
    ElMessage.warning("无法打开该附件");
  }
}
function unwrapArray(payload) {
@@ -795,10 +798,40 @@
}
.detail-attachment-tag {
.detail-attachment-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
  margin: 0 8px 8px 0;
.detail-attachment-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background: var(--el-fill-color-light);
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.2s;
}
.detail-attachment-item:hover {
  background: var(--el-fill-color);
}
.attachment-icon {
  font-size: 16px;
  color: var(--el-text-color-regular);
}
.attachment-name {
  font-size: 14px;
  color: var(--el-text-color-primary);
}
.attachment-download {
  font-size: 14px;
  color: var(--el-text-color-secondary);
}
.text-muted {
src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js
@@ -214,10 +214,21 @@
    });
  }
  function openFormDialog(mode, row) {
  async function openFormDialog(mode, row) {
    formDialog.mode = mode;
    formDialog.title = mode === "add" ? "新建审批模板" : "编辑审批模板";
    resetForm(mode === "edit" ? row : null);
    if (mode === "edit" && row?.id) {
      // 编辑时先查询详情获取完整数据(包含附件)
      try {
        const res = await getApprovalTemplateDetail(row.id);
        const detailData = mapTemplateFromApi(unwrapTemplateDetail(res));
        resetForm(detailData);
      } catch {
        resetForm(row);
      }
    } else {
      resetForm(mode === "edit" ? row : null);
    }
    formDialog.visible = true;
  }
src/views/procurementManagement/procurementLedger/index.vue
@@ -66,6 +66,9 @@
    </div>
    <div class="table_list">
      <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
        <el-button type="success"
                   plain
                   @click="handleBatchGenerate">批量生成数据</el-button>
        <el-button type="primary"
                   @click="openForm('add')">新增台账</el-button>
        <el-button type="primary"
@@ -106,7 +109,7 @@
                               prop="specificationModel" />
              <el-table-column label="单位"
                               prop="unit" />
                               <el-table-column label="入库审核状态"
              <el-table-column label="入库审核状态"
                               prop="stockInApprovalStatus"
                               width="120">
                <template #default="scope">
@@ -721,6 +724,7 @@
    getOptions,
    getPurchaseTemplateList,
    delPurchaseTemplate,
    batchGeneratePurchaseInboundSteps,
  } from "@/api/procurementManagement/procurementLedger.js";
  import useFormData from "@/hooks/useFormData.js";
  const FileList = defineAsyncComponent(() =>
@@ -776,9 +780,9 @@
  // 获取入库状态标签类型
  const getStockInStatusType = status => {
    const typeMap = {
      "待入库": "info", // 待入库 - 灰色
      "入库中": "warning", // 入库中 - 橙色
      "完全入库": "success", // 完全入库 - 绿色
      待入库: "info", // 待入库 - 灰色
      入库中: "warning", // 入库中 - 橙色
      完全入库: "success", // 完全入库 - 绿色
    };
    return typeMap[status] || "";
  };
@@ -786,9 +790,9 @@
  // 获取入库审核状态标签类型
  const getStockInApprovalStatusType = status => {
    const typeMap = {
      "待入库": "info", // 待入库 - 灰色
      "入库中": "warning", // 入库中 - 橙色
      "完全入库": "success", // 完全入库 - 绿色
      待入库: "info", // 待入库 - 灰色
      入库中: "warning", // 入库中 - 橙色
      完全入库: "success", // 完全入库 - 绿色
    };
    return typeMap[status] || "";
  };
@@ -1274,7 +1278,7 @@
  const openForm = async (type, row) => {
    // 编辑时检查入库状态,完全入库时不能编辑
    if (type === "edit" && row) {
      if (row.stockInStatus === '完全入库') {
      if (row.stockInStatus === "完全入库") {
        proxy.$modal.msgWarning("完全入库状态的记录不能编辑");
        return;
      }
@@ -1314,7 +1318,10 @@
          form.value = { ...purchaseRes, stockInStatus: row.stockInStatus };
          fileList.value = purchaseRes.storageBlobVOS || [];
          // 使用 productList 接口获取产品列表,以获取入库审核状态
          const productRes = await productList({ salesLedgerId: row.id, type: 2 });
          const productRes = await productList({
            salesLedgerId: row.id,
            type: 2,
          });
          productData.value = productRes.data || [];
        } catch (error) {
          console.error("加载采购台账数据失败:", error);
@@ -1447,7 +1454,7 @@
  // 打开产品弹框
  const openProductForm = async (type, row, index) => {
    // 编辑时检查产品入库审核状态,完全入库时不能编辑
    if (type === "edit" && row && row.stockInApprovalStatus === '完全入库') {
    if (type === "edit" && row && row.stockInApprovalStatus === "完全入库") {
      proxy.$modal.msgWarning("完全入库状态的产品不能编辑");
      return;
    }
@@ -1636,7 +1643,7 @@
    }
    // 检查选中的产品中是否有完全入库的
    const hasFullyStocked = productSelectedRows.value.some(
      row => row.stockInApprovalStatus === '完全入库'
      row => row.stockInApprovalStatus === "完全入库"
    );
    if (hasFullyStocked) {
      proxy.$modal.msgWarning("选中的产品中包含完全入库的产品,无法删除");
@@ -1712,6 +1719,37 @@
          proxy.$modal.msgSuccess("删除成功");
          getList();
        });
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
  };
  const handleBatchGenerate = async () => {
    if (selectedRows.value.length === 0) {
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    const ids = selectedRows.value.map((item) => item.id);
    ElMessageBox.confirm("确认批量生成数据?", "批量生成", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "info",
    })
      .then(() => {
        proxy.$modal.loading("正在批量生成数据,请稍候...");
        batchGeneratePurchaseInboundSteps({ ids })
          .then((res) => {
            proxy.$modal.msgSuccess("批量生成成功");
            getList();
          })
          .catch(() => {
            proxy.$modal.msgError("批量生成失败");
          })
          .finally(() => {
            proxy.$modal.closeLoading();
          });
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
@@ -1855,7 +1893,7 @@
      contractNo: form.value.salesLedgerId,
    });
    if (code == 200) {
      productData.value = data;
      productData.value = data || [];
    }
  };
src/views/procurementManagement/procurementPlan/index.vue
@@ -183,7 +183,7 @@
              </el-col>
              <el-col :span="12">
                <el-form-item label="创建时间" prop="createTime">
                  <el-date-picker v-model="formData.createTime"
                  <el-date-picker v-model="formCreateTimeDate"
                                  type="date"
                                  placeholder="选择日期"
                                  value-format="YYYY-MM-DD"
@@ -377,7 +377,8 @@
<script setup>
  import FormDialog from "@/components/Dialog/FormDialog.vue";
  import { ref, reactive, onMounted, getCurrentInstance } from "vue";
  import { ref, reactive, onMounted, getCurrentInstance, computed } from "vue";
  import dayjs from "dayjs";
  import { ElMessage, ElMessageBox } from "element-plus";
  import { Search, Refresh, Plus, Download } from "@element-plus/icons-vue";
  import {
@@ -432,6 +433,12 @@
    summaryMaterial: false,
    summaryAuxAttributes: false,
    summaryDemandDate: false,
  });
  const formCreateTimeDate = computed({
    get: () => (formData.createTime ? String(formData.createTime).split(" ")[0] : ""),
    set: (value) => {
      formData.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
    },
  });
  // 当前激活的标签页
@@ -510,7 +517,7 @@
  const handleAdd = () => {
    dialogType.value = "add";
    resetForm();
    formData.createTime = new Date().toISOString().split("T")[0];
    formData.createTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
    dialogVisible.value = true;
  };
src/views/procurementManagement/purchaseOrder/index.vue
@@ -57,7 +57,7 @@
          </el-select>
        </el-form-item>
        <el-form-item label="创建时间">
          <el-date-picker v-model="formData.createTime"
          <el-date-picker v-model="formCreateTimeDate"
                          type="date"
                          placeholder="选择日期"
                          value-format="YYYY-MM-DD"
@@ -73,7 +73,8 @@
<script setup>
import FormDialog from '@/components/Dialog/FormDialog.vue';
import { ref, reactive } from 'vue'
import { ref, reactive, computed } from 'vue'
import dayjs from 'dayjs'
import { ElMessage, ElMessageBox } from 'element-plus'
const loading = ref(false)
@@ -90,6 +91,12 @@
  supplierName: '',
  remark: '',
  createTime: ''
})
const formCreateTimeDate = computed({
  get: () => (formData.createTime ? String(formData.createTime).split(' ')[0] : ''),
  set: (value) => {
    formData.createTime = value ? `${value} ${dayjs().format('HH:mm:ss')}` : ''
  }
})
const mockData = [
@@ -130,9 +137,9 @@
const openDialog = (type, row = {}) => {
  dialogType.value = type
  if (type === 'edit' && row.id) {
    Object.assign(formData, { supplierName: row.supplierName, remark: row.remark })
    Object.assign(formData, { supplierName: row.supplierName, remark: row.remark, createTime: row.createTime || '' })
  } else {
    Object.assign(formData, { supplierName: '', remark: '', createTime: new Date().toISOString().split('T')[0] })
    Object.assign(formData, { supplierName: '', remark: '', createTime: dayjs().format('YYYY-MM-DD HH:mm:ss') })
  }
  dialogVisible.value = true
}
src/views/procurementManagement/qualityInspection/index.vue
@@ -119,7 +119,7 @@
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="创建时间">
              <el-date-picker v-model="formData.createTime"
              <el-date-picker v-model="formCreateTimeDate"
                              type="date"
                              placeholder="选择日期"
                              value-format="YYYY-MM-DD"
@@ -138,7 +138,8 @@
<script setup>
import FormDialog from '@/components/Dialog/FormDialog.vue';
import { ref, reactive } from 'vue'
import { ref, reactive, computed } from 'vue'
import dayjs from 'dayjs'
import { ElMessage, ElMessageBox } from 'element-plus'
const loading = ref(false)
@@ -158,6 +159,12 @@
  inspector: '',
  remark: '',
  createTime: ''
})
const formCreateTimeDate = computed({
  get: () => (formData.createTime ? String(formData.createTime).split(' ')[0] : ''),
  set: (value) => {
    formData.createTime = value ? `${value} ${dayjs().format('HH:mm:ss')}` : ''
  }
})
const mockData = [
@@ -203,7 +210,8 @@
      arrivalNo: row.arrivalNo, 
      supplierName: row.supplierName, 
      inspector: row.inspector,
      remark: row.remark
      remark: row.remark,
      createTime: row.createTime || ''
    })
  } else {
    Object.assign(formData, {
@@ -212,7 +220,7 @@
      products: [],
      inspector: '',
      remark: '',
      createTime: new Date().toISOString().split('T')[0]
      createTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
    })
  }
  dialogVisible.value = true
src/views/productManagement/productIdentifier/index.vue
@@ -240,7 +240,7 @@
          <span>{{ currentProduct.identifierType }}</span>
        </el-form-item>
        <el-form-item label="创建时间">
          <el-date-picker v-model="createTime"
          <el-date-picker v-model="createTimeDate"
                          type="date"
                          placeholder="选择日期"
                          value-format="YYYY-MM-DD"
@@ -363,6 +363,7 @@
<script setup>
  import { ref, reactive, computed } from "vue";
  import dayjs from "dayjs";
  import { ElMessage, ElMessageBox } from "element-plus";
  import { Plus, Search, Loading, Download } from "@element-plus/icons-vue";
  import Pagination from "@/components/PIMTable/Pagination.vue";
@@ -449,7 +450,13 @@
  const generateQuantity = ref(1);
  const codeRule = ref("");
  const customPrefix = ref("");
  const createTime = ref(new Date().toISOString().split('T')[0]);
  const createTime = ref(dayjs().format("YYYY-MM-DD HH:mm:ss"));
  const createTimeDate = computed({
    get: () => (createTime.value ? String(createTime.value).split(" ")[0] : ""),
    set: (value) => {
      createTime.value = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
    },
  });
  const newBatchNo = ref("");
  const reassignReason = ref("");
  const formRef = ref();
src/views/productionPlan/productionPlan/index.vue
@@ -140,7 +140,7 @@
                           style="width: 100%" />
        </el-form-item>
        <el-form-item label="创建时间">
          <el-date-picker v-model="mergeForm.createTime"
          <el-date-picker v-model="mergeCreateTimeDate"
                          type="date"
                          value-format="YYYY-MM-DD"
                          style="width: 100%" />
@@ -235,7 +235,7 @@
        </el-form-item>
        <el-form-item label="创建时间"
                      prop="createTime">
          <el-date-picker v-model="form.createTime"
          <el-date-picker v-model="formCreateTimeDate"
                          type="date"
                          value-format="YYYY-MM-DD"
                          style="width: 100%"
@@ -444,7 +444,7 @@
              Number(row.qtyRequired || 0) - Number(row.quantityIssued || 0);
            mergeForm.planCompleteTime = row.requiredDate || "";
            mergeForm.productId = row.productId || "";
            mergeForm.createTime = new Date().toISOString().split("T")[0];
            mergeForm.createTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
            mergeForm.ids = [row.id];
            sumAssignedQuantity.value =
              Number(row.qtyRequired || 0) - Number(row.quantityIssued || 0);
@@ -490,6 +490,12 @@
    productId: "",
    createTime: "",
  });
  const mergeCreateTimeDate = computed({
    get: () => (mergeForm.createTime ? String(mergeForm.createTime).split(" ")[0] : ""),
    set: (value) => {
      mergeForm.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
    },
  });
  // 导入相关
  const importDialogRef = ref(null);
@@ -520,6 +526,12 @@
    promisedDeliveryDate: "",
    remark: "",
    createTime: "",
  });
  const formCreateTimeDate = computed({
    get: () => (form.createTime ? String(form.createTime).split(" ")[0] : ""),
    set: (value) => {
      form.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
    },
  });
  const rules = reactive({
    productId: [{ required: true, message: "请选择产品", trigger: "change" }],
@@ -763,6 +775,7 @@
    mergeForm.totalAssignedQuantity = totalAssignedQuantity;
    mergeForm.planCompleteTime = firstRow.requiredDate || "";
    mergeForm.productId = firstRow.productId || "";
    mergeForm.createTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
    mergeForm.ids = selectedRows.value.map(row => row.id);
    // 打开弹窗
@@ -906,7 +919,7 @@
      requiredDate: "",
      promisedDeliveryDate: "",
      remark: "",
      createTime: new Date().toISOString().split("T")[0],
      createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
    });
    dialogVisible.value = true;
    fetchProductOptions();
@@ -927,6 +940,7 @@
      requiredDate: row.requiredDate || "",
      promisedDeliveryDate: row.promisedDeliveryDate || "",
      remark: row.remark || "",
      createTime: row.createTime || "",
    });
    dialogVisible.value = true;
    fetchProductOptions();
src/views/safeProduction/safetyTrainingAssessment/index.vue
@@ -85,7 +85,7 @@
            <el-form-item label="创建时间"
                          prop="createTime">
              <el-date-picker style="width: 100%"
                              v-model="form.createTime"
                              v-model="formCreateTimeDate"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              type="date"
@@ -466,6 +466,12 @@
    dialogType: "add",
    viewDialogVisible: false,
    currentKnowledge: {},
  });
  const formCreateTimeDate = computed({
    get: () => (form.value.createTime ? String(form.value.createTime).split(" ")[0] : ""),
    set: (value) => {
      form.value.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
    },
  });
  const {
@@ -1040,7 +1046,7 @@
        trainingMode: "", // 培训方式
        placeTraining: "", // 培训地点
        classHour: "", // 课时
        createTime: new Date().toISOString().split("T")[0], // 创建时间
        createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // 创建时间
      });
    } else if (type === "edit" && row) {
      dialogTitle.value = "编辑培训";
@@ -1058,6 +1064,7 @@
        trainingMode: row.trainingMode, // 培训方式
        placeTraining: row.placeTraining, // 培训地点
        classHour: row.classHour, // 课时
        createTime: row.createTime || "", // 创建时间
      });
    }
    dialogVisible.value = true;
src/views/salesManagement/salesLedger/index.vue
@@ -117,6 +117,11 @@
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column label="审批中数量" width="120" align="center">
                <template #default="scope">
                  <span>{{ scope.row.pendingApprovalQuantity || 0 }}</span>
                </template>
              </el-table-column>
              <el-table-column
                label="快递公司"
                prop="expressCompany"
@@ -1749,7 +1754,7 @@
    // 签订日期默认为当天
    form.value.executionDate = getCurrentDate();
    // 创建时间默认为当天
    form.value.createTime = getCurrentDate();
    form.value.createTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
    // 默认自动生成销售合同号
    form.value.autoGenerateContractNo = true;
  } else {
@@ -2155,7 +2160,7 @@
};
// 打印功能
const handlePrint = async () => {
  const handlePrint = async () => {
  if (selectedRows.value.length === 0) {
    proxy.$modal.msgWarning("请选择要打印的数据");
    return;
@@ -2512,11 +2517,7 @@
// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return getCurrentDate();
  const date = new Date(dateString);
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  return `${year}/${month}/${day}`;
  return dayjs(dateString).format("YYYY/MM/DD HH:mm:ss");
};
// 格式化日期时间
const formatDateTime = (date) => {
@@ -2803,7 +2804,7 @@
/**
 * 判断是否可以发货
 * 只有在产品状态是充足,发货状态是待发货和审核拒绝的时候才可以发货
 * 只有在产品状态是充足,发货状态是待发货、审批中、审核拒绝、部分发货的时候才可以发货
 * @param row 行数据
 */
const canShip = (row) => {
@@ -2815,15 +2816,16 @@
  // 获取发货状态
  const shippingStatus = row.shippingStatus;
  // 如果已发货(有发货日期或车牌号),不能再次发货
  // 如果已发货,不能再次发货
  if (shippingStatus === "已发货") {
    return false;
  }
  // 发货状态必须是"待发货"或"审核拒绝"
  // 发货状态必须是"待发货"、"审批中"、"审核拒绝"或"部分发货"
  const statusStr = shippingStatus ? String(shippingStatus).trim() : "";
  return (
    statusStr === "待发货" ||
    statusStr === "审批中" ||
    statusStr === "审核拒绝" ||
    statusStr === "部分发货"
  );
@@ -2844,7 +2846,7 @@
  // 检查是否可以发货
  if (!canShip(row)) {
    proxy.$modal.msgWarning(
      "只有在产品状态是充足,发货状态是待发货或审核拒绝的时候才可以发货"
      "只有在产品状态是充足,发货状态是待发货、审批中、审核拒绝或部分发货的时候才可以发货"
    );
    return;
  }
@@ -3179,4 +3181,4 @@
    page-break-after: avoid;
  }
}
</style>
</style>