spring
17 小时以前 c466b7f253a93d3a9b58c658adf6ec75574f5bd8
公司logo动态切换,整体样式修改
已修改8个文件
已添加6个文件
1116 ■■■■ 文件已修改
src/assets/logo/上海郢昱网络科技有限公司.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/logo/南通云从工业互联网有限公司.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/logo/新缆(江苏)数字科技有限公司.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/logo/芯导软件(江苏)有限公司.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/styles/sidebar.scss 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/styles/variables.module.scss 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Breadcrumb/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Navbar.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/Logo.vue 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/index.vue 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index.vue 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/issueManagement/index.vue 359 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/index.vue 359 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 107 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/logo/ÉϺ£Û«êÅÍøÂç¿Æ¼¼ÓÐÏÞ¹«Ë¾.png
src/assets/logo/ÄÏÍ¨ÔÆ´Ó¹¤Òµ»¥ÁªÍøÓÐÏÞ¹«Ë¾.png
src/assets/logo/ÐÂÀ£¨½­ËÕ£©Êý×ֿƼ¼ÓÐÏÞ¹«Ë¾.png
src/assets/logo/оµ¼Èí¼þ£¨½­ËÕ£©ÓÐÏÞ¹«Ë¾.png
src/assets/styles/sidebar.scss
@@ -1,11 +1,10 @@
#app {
  .main-container {
    min-height: 100%;
    transition: margin-left .28s;
    transition: margin-left 0.28s;
    margin-left: $base-sidebar-width;
    position: relative;
    background: #F5F7FB;
    background: #f5f7fb;
  }
  .sidebarHide {
@@ -23,12 +22,13 @@
    left: 0;
    z-index: 1001;
    overflow: hidden;
    -webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
    -webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
    box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
    // reset element-ui css
    .horizontal-collapse-transition {
      transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
      transition: 0s width ease-in-out, 0s padding-left ease-in-out,
        0s padding-right ease-in-out;
    }
    .scrollbar-wrapper {
@@ -69,7 +69,8 @@
      width: 100% !important;
    }
    .el-menu-item, .menu-title {
    .el-menu-item,
    .menu-title {
      overflow: hidden !important;
      text-overflow: ellipsis !important;
      white-space: nowrap !important;
@@ -83,11 +84,11 @@
    .sub-menu-title-noDropdown,
    .el-sub-menu__title {
      &:hover {
        background-color: rgba(212,221,255,0.56) !important;
        background-color: rgba(212, 221, 255, 0.8) !important;
      }
    }
    & .theme-light .is-active > .el-sub-menu__title {
      color: #000000 !important;
      color: #fff !important;
    }
    & .nest-menu .el-sub-menu>.el-sub-menu__title,
@@ -95,10 +96,10 @@
      min-width: $base-sidebar-width !important;
      &:hover {
        background-color: rgba(212,221,255,0.56) !important;
        background-color: rgba(212, 221, 255, 0.8) !important;
      }
      &.is-active {
        background-color: rgba(212,221,255,0.56) !important;
        background-color: #fff !important;
      }
    }
@@ -107,7 +108,7 @@
      //background-color: transparent;
      &:hover {
        background-color: rgba(212,221,255,0.56) !important;
        background-color: rgba(212, 221, 255, 0.8) !important;
      }
    }
  }
@@ -142,7 +143,6 @@
        .svg-icon {
          margin-left: 20px;
        }
      }
    }
@@ -179,7 +179,7 @@
    }
    .sidebar-container {
      transition: transform .28s;
      transition: transform 0.28s;
      width: $base-sidebar-width !important;
    }
@@ -193,7 +193,6 @@
  }
  .withoutAnimation {
    .main-container,
    .sidebar-container {
      transition: none;
src/assets/styles/variables.module.scss
@@ -1,12 +1,12 @@
// base color
$blue: #324157;
$light-blue: #333c46;
$red: #C03639;
$pink: #E65D6E;
$green: #30B08F;
$tiffany: #4AB7BD;
$yellow: #FEC171;
$panGreen: #30B08F;
$red: #c03639;
$pink: #e65d6e;
$green: #30b08f;
$tiffany: #4ab7bd;
$yellow: #fec171;
$panGreen: #30b08f;
// é»˜è®¤ä¸»é¢˜å˜é‡
$menuText: #bfcbd9;
@@ -15,10 +15,10 @@
$menuHover: #263445;
// æµ…色主题theme-light
$menuLightBg: #ffffff;
$menuLightBg: #002fa7;
$menuLightHover: #f0f1f5;
$menuLightText: #303133;
$menuLightActiveText: #409EFF;
$menuLightText: #fff;
$menuLightActiveText: #002fa7;
// åŸºç¡€å˜é‡
$base-sidebar-width: 200px;
@@ -29,13 +29,13 @@
$base-menu-color-active: #f4f4f5;
$base-menu-background: #304156;
$base-sub-menu-background: #1f2d3d;
$base-sub-menu-hover: #001528;
$base-sub-menu-hover: #fff;
// ç»„件变量
$--color-primary: #409EFF;
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
$--color-primary: #409eff;
$--color-success: #67c23a;
$--color-warning: #e6a23c;
$--color-danger: #f56c6c;
$--color-info: #909399;
:export {
@@ -77,7 +77,6 @@
  
  /* splitpanes default-theme å˜é‡ */
  --splitpanes-default-bg: #ffffff;
}
// æš—黑模式变量
@@ -128,7 +127,8 @@
  /* ä¾§è¾¹æ èœå•覆盖 */
   .sidebar-container {
    .el-menu-item, .menu-title {
    .el-menu-item,
    .menu-title {
      color: var(--el-text-color-regular);
    }
    & .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title,
@@ -180,9 +180,10 @@
    --el-table-border-color: var(--el-border-color-light) !important;
    --el-table-row-hover-bg-color: var(--el-bg-color-overlay) !important;
    .el-table__header-wrapper, .el-table__fixed-header-wrapper {
    .el-table__header-wrapper,
    .el-table__fixed-header-wrapper {
      th {
        background-color: var(--el-bg-color-overlay, #F0F1F5) !important;
        background-color: var(--el-bg-color-overlay, #f0f1f5) !important;
        color: var(--el-text-color-regular, #515a6e);
      }
    }
@@ -201,7 +202,8 @@
  }
  
  /* ä¸‹æ‹‰èœå•样式覆盖 */
  .el-dropdown-menu__item:not(.is-disabled):focus, .el-dropdown-menu__item:not(.is-disabled):hover{
  .el-dropdown-menu__item:not(.is-disabled):focus,
  .el-dropdown-menu__item:not(.is-disabled):hover {
    background-color: var(--navbar-hover) !important;
  }
@@ -216,6 +218,4 @@
  .popup-result .title {
    background: var(--cron-border);
  }
}
src/components/Breadcrumb/index.vue
@@ -2,7 +2,8 @@
  <el-breadcrumb class="app-breadcrumb" separator="/">
    <transition-group name="breadcrumb">
      <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
        <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
        <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{
          item.meta.title }}</span>
        <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
      </el-breadcrumb-item>
    </transition-group>
@@ -91,7 +92,7 @@
  margin-left: 8px;
  .no-redirect {
    color: #97a8be;
    color: #002FA7;
    cursor: text;
  }
}
src/layout/components/Navbar.vue
@@ -1,7 +1,8 @@
<template>
  <div class="navbar">
    <div>
      <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
      <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container"
        @toggleClick="toggleSideBar" />
      <breadcrumb v-if="!settingsStore.topNav" id="breadcrumb-container" class="breadcrumb-container" />
    </div>
<!--    <top-nav v-if="settingsStore.topNav" id="topmenu-container" class="topmenu-container" />-->
@@ -9,15 +10,13 @@
      <span class="label">{{userStore.currentFactoryName}}</span>
      <el-dropdown @command="handleFactoryChange" class="right-menu-item hover-effect" trigger="click">
        <div>
          <el-icon size="20"><Switch /></el-icon>
          <el-icon size="20">
            <Switch />
          </el-icon>
        </div>
        <template #dropdown>
          <el-dropdown-menu >
            <el-dropdown-item
                v-for="item in factoryList"
                :key="item.deptId"
                :command="item"
            >
            <el-dropdown-item v-for="item in factoryList" :key="item.deptId" :command="item">
              {{ item.deptName }}
            </el-dropdown-item>
          </el-dropdown-menu>
@@ -157,6 +156,7 @@
  position: relative;
  background: var(--navbar-bg);
  box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
  .center-menu {
    line-height: 50px;
    position: absolute;
@@ -164,6 +164,7 @@
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    .label {
      font-weight: bold;
      font-size: 18px;
src/layout/components/Sidebar/Logo.vue
@@ -2,21 +2,21 @@
  <div class="sidebar-logo-container" :class="{ 'collapse': collapse }">
    <transition name="sidebarLogoFade">
      <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
        <img v-if="logo" :src="logo" class="sidebar-logo" />
        <img v-if="logoUrl" :src="logoUrl" class="sidebar-logo" @error="handleImageError" alt="公司Logo" />
        <h1 v-else class="sidebar-title">{{ title }}</h1>
      </router-link>
      <router-link v-else key="expand" class="sidebar-logo-link" to="/">
        <img v-if="logo" :src="logo" class="sidebar-logo" />
        <h1 class="sidebar-title">{{ title }}</h1>
        <img v-if="logoUrl" :src="logoUrl" class="sidebar-logo" @error="handleImageError" alt="公司Logo" />
        <h1 v-else class="sidebar-title">{{ title }}</h1>
      </router-link>
    </transition>
  </div>
</template>
<script setup>
import logo from '@/assets/logo/logo.png'
import useSettingsStore from '@/store/modules/settings'
import variables from '@/assets/styles/variables.module.scss'
import { ref, computed, onMounted, watch } from 'vue'
import useUserStore from '@/store/modules/user'
import defaultLogo from '@/assets/logo/logo.png' // å¯¼å…¥é»˜è®¤logo
defineProps({
  collapse: {
@@ -26,24 +26,53 @@
})
const title = import.meta.env.VITE_APP_TITLE
const settingsStore = useSettingsStore()
const sideTheme = computed(() => settingsStore.sideTheme)
const userStore = useUserStore()
// èŽ·å–Logo背景色
const getLogoBackground = computed(() => {
  if (settingsStore.isDark) {
    return 'var(--sidebar-bg)'
  }
  return sideTheme.value === 'theme-dark' ? variables.menuBg : variables.menuLightBg
// å¤„理工厂名称,生成合法的文件名
const cleanFactoryName = computed(() => {
  if (!userStore.currentFactoryName) return ''
  return userStore.currentFactoryName.trim()
})
// èŽ·å–Logo文字颜色
const getLogoTextColor = computed(() => {
  if (settingsStore.isDark) {
    return 'var(--sidebar-text)'
// åŠ¨æ€logo路径
const logoUrl = ref('')
// æ£€æŸ¥logo是否存在并设置url
const updateLogoUrl = () => {
  if (!cleanFactoryName.value) {
    logoUrl.value = defaultLogo
    return
  }
  return sideTheme.value === 'theme-dark' ? '#fff' : variables.menuLightText
  // ä½¿ç”¨Vite的动态导入
  try {
    const dynamicLogo = import.meta.glob('/src/assets/logo/*.png', { eager: true })
    const logoPath = `/src/assets/logo/${cleanFactoryName.value}.png`
    if (dynamicLogo[logoPath]) {
      logoUrl.value = dynamicLogo[logoPath].default
    } else {
      logoUrl.value = defaultLogo
    }
  } catch (error) {
    console.error('加载工厂Logo失败:', error)
    logoUrl.value = defaultLogo
  }
}
// åˆå§‹åŒ–和监听变化
onMounted(() => {
  updateLogoUrl()
  // ç›‘听工厂名称变化
  watch(() => userStore.currentFactoryName, updateLogoUrl)
})
// å›¾ç‰‡åŠ è½½é”™è¯¯å¤„ç†
const handleImageError = (event) => {
  console.warn('Logo加载失败,使用默认Logo')
  logoUrl.value = defaultLogo
}
</script>
<style lang="scss" scoped>
@@ -63,7 +92,7 @@
  width: 100%;
  height: 50px;
  line-height: 50px;
  background: v-bind(getLogoBackground);
  background: #fff;
  text-align: center;
  overflow: hidden;
@@ -72,8 +101,9 @@
    width: 100%;
    & .sidebar-logo {
      width: 32px;
      height: 32px;
      width: 100%;
      height: 100%;
      // height: 32px;
      vertical-align: middle;
      margin-right: 12px;
    }
src/layout/components/Sidebar/index.vue
@@ -2,23 +2,11 @@
  <div :class="{ 'has-logo': showLogo }" class="sidebar-container">
    <logo v-if="showLogo" :collapse="isCollapse" />
    <el-scrollbar wrap-class="scrollbar-wrapper">
      <el-menu
        :default-active="activeMenu"
        :collapse="isCollapse"
        :background-color="getMenuBackground"
        :text-color="getMenuTextColor"
        :unique-opened="true"
        :active-text-color="theme"
        :collapse-transition="false"
        mode="vertical"
        :class="sideTheme"
      >
        <sidebar-item
          v-for="(route, index) in sidebarRouters"
          :key="route.path + index"
          :item="route"
          :base-path="route.path"
        />
      <el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="getMenuBackground"
        :text-color="getMenuTextColor" :unique-opened="true" :active-text-color="theme" :collapse-transition="false"
        mode="vertical" :class="sideTheme">
        <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route"
          :base-path="route.path" />
      </el-menu>
    </el-scrollbar>
  </div>
@@ -42,6 +30,7 @@
const sideTheme = computed(() => settingsStore.sideTheme)
const theme = computed(() => settingsStore.theme)
const isCollapse = computed(() => !appStore.sidebar.opened)
console.log(44444, settingsStore.isDark, sideTheme.value)
// èŽ·å–èœå•èƒŒæ™¯è‰²
const getMenuBackground = computed(() => {
@@ -81,7 +70,8 @@
    height: 100%;
    width: 100% !important;
    
    .el-menu-item, .el-sub-menu__title {
    .el-menu-item,
    .el-sub-menu__title {
      &:hover {
        background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important;
      }
src/views/index.vue
@@ -38,16 +38,14 @@
            <div class="card-group">
              <div class="pie-group">
                <div style="margin-right: 80px">
                  <Echarts ref="chart"
                           :legend="pieLegend"
                           :chartStyle="chartStyle"
                           :series="materialPieSeries"
                  <Echarts ref="chart" :legend="pieLegend" :chartStyle="chartStyle" :series="materialPieSeries"
                           :tooltip="pieTooltip"></Echarts>
                </div>
                <div class="info-message2">
                  <div class="info-message1">
                    <div class="pie-title">本月回款金额</div>
                    <div class="pie-info"><span class="pie-number">{{receiveAmount}}</span>元   <span class="pie-number">{{receiveAmountPercentage}}</span>%</div>
                    <div class="pie-info"><span class="pie-number">{{ receiveAmount }}</span>元 <span
                        class="pie-number">{{ receiveAmountPercentage }}</span>%</div>
                  </div>
                  <div class="info-message1">
                    <div class="pie-title">应收款金额</div>
@@ -59,17 +57,14 @@
            <div class="card-group">
              <div class="pie-group">
                <div style="margin-right: 80px">
                  <Echarts ref="chart"
                           :options="options"
                           :legend="pieLegend"
                           :chartStyle="chartStyle"
                           :series="materialPieSeries1"
                           :tooltip="pieTooltip1"></Echarts>
                  <Echarts ref="chart" :options="options" :legend="pieLegend" :chartStyle="chartStyle"
                    :series="materialPieSeries1" :tooltip="pieTooltip1"></Echarts>
                </div>
                <div class="info-message2">
                  <div class="info-message1">
                    <div class="pie-title1">本月付款金额</div>
                    <div class="pie-info"><span class="pie-number1">{{paymentAmount}}</span>元   <span class="pie-number1">{{payableAmountPercentage}}</span>%</div>
                    <div class="pie-info"><span class="pie-number1">{{ paymentAmount }}</span>元 <span
                        class="pie-number1">{{ payableAmountPercentage }}</span>%</div>
                  </div>
                  <div class="info-message1">
                    <div class="pie-title1">应付款金额</div>
@@ -87,15 +82,8 @@
            <span style="font-weight: bold">客户合同金额TOP5统计</span>
          </div>
          <div>
            <Echarts ref="chart"
                     :chartStyle="chartStyle1"
                     :grid="grid"
                     :legend="barLegend"
                     :series="barSeries"
                     :tooltip="tooltip"
                     :xAxis="xAxis1"
                     :yAxis="yAxis1"
                     style="height: 42vh;"></Echarts>
            <Echarts ref="chart" :chartStyle="chartStyle1" :grid="grid" :legend="barLegend" :series="barSeries"
              :tooltip="tooltip" :xAxis="xAxis1" :yAxis="yAxis1" style="height: 42vh;"></Echarts>
          </div>
        </div>
      </div>
@@ -107,15 +95,8 @@
            <span style="font-weight: bold">回款、开票近半年走势图</span>
          </div>
          <div>
            <Echarts ref="chart"
                     :chartStyle="chartStyle1"
                     :grid="grid"
                     :legend="barLegend"
                     :series="lineSeries"
                     :tooltip="tooltipLine"
                     :xAxis="xAxis2"
                     :yAxis="yAxis2"
                     style="height: 27vh;"></Echarts>
            <Echarts ref="chart" :chartStyle="chartStyle1" :grid="grid" :legend="barLegend" :series="lineSeries"
              :tooltip="tooltipLine" :xAxis="xAxis2" :yAxis="yAxis2" style="height: 27vh;"></Echarts>
          </div>
        </div>
      </div>
@@ -458,6 +439,7 @@
  width: 56vw;
  margin-bottom: 20px;
}
.card-top-right {
  padding: 16px;
  background: #fff;
@@ -466,6 +448,7 @@
  margin-bottom: 20px;
  margin-left: 20px;
}
.card-bottom {
  padding: 16px;
  background: #fff;
@@ -473,6 +456,7 @@
  width: 85.2vw;
  margin-bottom: 20px;
}
.title {
  position: relative;
  font-size: 18px;
@@ -481,6 +465,7 @@
  padding-left: 10px;
  margin-bottom: 26px;
}
.title::before {
  position: absolute;
  left: 0;
@@ -488,12 +473,14 @@
  content: '';
  width: 4px;
  height: 18px;
  background-color: #3A7BFA;
  background-color: #002FA7;
  border-radius: 2px;
}
.card-group {
  display: flex;
}
.info-card {
  width: 300px;
  height: 126px;
@@ -503,6 +490,7 @@
  justify-content: space-around;
  align-items: center;
}
.info-card1 {
  width: 300px;
  height: 126px;
@@ -513,6 +501,7 @@
  justify-content: space-around;
  align-items: center;
}
.info-card2 {
  width: 300px;
  height: 126px;
@@ -522,12 +511,14 @@
  justify-content: space-around;
  align-items: center;
}
.info-message {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.info-message1 {
  font-weight: bold;
  display: flex;
@@ -535,6 +526,7 @@
  justify-content: center;
  align-items: flex-start;
}
.info-message2 {
  font-weight: bold;
  display: flex;
@@ -542,25 +534,30 @@
  align-items: center;
  justify-content: space-around;
}
.info-number {
  font-weight: bold;
  font-size: 32px;
  color: #FFFFFF;
  margin-bottom: 10px;
}
.info-title {
  font-weight: bold;
  font-size: 18px;
  color: #FFFFFF;
}
.pie {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}
.pie-group {
  display: flex;
}
.pie-title {
  font-size: 14px;
  line-height: 24px;
@@ -568,16 +565,24 @@
  padding-left: 16px;
  position: relative;
}
.pie-title::before {
  content: '';
  width: 6px; /* è“ç‚¹çš„宽度 */
  height: 6px; /* è“ç‚¹çš„高度 */
  background-color: #2853FD; /* è“ç‚¹çš„颜色 */
  border-radius: 50%; /* å°†æ­£æ–¹å½¢å˜ä¸ºåœ†å½¢ */
  width: 6px;
  /* è“ç‚¹çš„宽度 */
  height: 6px;
  /* è“ç‚¹çš„高度 */
  background-color: #2853FD;
  /* è“ç‚¹çš„颜色 */
  border-radius: 50%;
  /* å°†æ­£æ–¹å½¢å˜ä¸ºåœ†å½¢ */
  position: absolute;
  left: 0; /* å®šä½åˆ°å·¦è¾¹ */
  top: 9px; /* åž‚直居中对齐,根据行高调整 */
  left: 0;
  /* å®šä½åˆ°å·¦è¾¹ */
  top: 9px;
  /* åž‚直居中对齐,根据行高调整 */
}
.pie-title1 {
  font-size: 14px;
  line-height: 24px;
@@ -585,26 +590,35 @@
  padding-left: 16px;
  position: relative;
}
.pie-title1::before {
  content: '';
  width: 6px; /* è“ç‚¹çš„宽度 */
  height: 6px; /* è“ç‚¹çš„高度 */
  background-color: #1EBFAC; /* è“ç‚¹çš„颜色 */
  border-radius: 50%; /* å°†æ­£æ–¹å½¢å˜ä¸ºåœ†å½¢ */
  width: 6px;
  /* è“ç‚¹çš„宽度 */
  height: 6px;
  /* è“ç‚¹çš„高度 */
  background-color: #1EBFAC;
  /* è“ç‚¹çš„颜色 */
  border-radius: 50%;
  /* å°†æ­£æ–¹å½¢å˜ä¸ºåœ†å½¢ */
  position: absolute;
  left: 0; /* å®šä½åˆ°å·¦è¾¹ */
  top: 9px; /* åž‚直居中对齐,根据行高调整 */
  left: 0;
  /* å®šä½åˆ°å·¦è¾¹ */
  top: 9px;
  /* åž‚直居中对齐,根据行高调整 */
}
.pie-info {
  padding-left: 16px;
  font-size: 14px;
  line-height: 24px;
}
.pie-number {
  color: #2853FD;
}
.pie-number1 {
  color: #1EBFAC;
}
</style>
src/views/inventoryManagement/issueManagement/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,359 @@
<template>
  <div class="app-container">
    <div class="search_form">
      <div>
        <span class="search_title">供应商名称:</span>
        <el-input v-model="searchForm.customerName" style="width: 240px" placeholder="请输入" @change="handleQuery"
          clearable prefix-icon="Search" />
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button>
      </div>
      <div>
        <el-button type="primary" @click="openForm('add')">新增</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
      </div>
    </div>
    <div class="table_list">
      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
        :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="出库时间" prop="salesContractNo" width="180" show-overflow-tooltip />
        <el-table-column label="出库批次" prop="customerContractNo" width="180" show-overflow-tooltip />
        <el-table-column label="供应商名称" prop="customerName" width="300" show-overflow-tooltip />
        <el-table-column label="产品大类" prop="salesman" width="100" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="projectName" width="180" show-overflow-tooltip />
        <el-table-column label="单位" prop="contractAmount" width="180" show-overflow-tooltip />
        <el-table-column label="出库数量" prop="entryPersonName" width="100" show-overflow-tooltip />
        <el-table-column label="含税单价" prop="entryDate" width="120" show-overflow-tooltip />
        <el-table-column label="含税总价" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column label="税率" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column label="不含税总价" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column label="出库人" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column fixed="right" label="操作" min-width="60" align="center">
          <template #default="scope">
            <el-button link type="primary" size="small" @click="openForm('edit', scope.row);">编辑</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
        :page="page.current" :limit="page.size" @pagination="paginationChange" />
    </div>
    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '新增入库' : '编辑入库'" width="70%"
      @close="closeDia">
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="供应商名称:" prop="salesContractNo">
              <el-input v-model="form.salesContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="产品大类:" prop="salesman">
              <el-select v-model="form.salesman" placeholder="请选择" clearable>
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
                  :value="item.nickName" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="customerContractNo">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="单位:" prop="customerId">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="入库时间:" prop="projectName">
              <el-date-picker style="width: 100%" v-model="form.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
                type="date" placeholder="请选择" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="入库批次:" prop="entryPerson">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="入库数量:" prop="customerContractNo">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="含税单价:" prop="customerId">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="含税总价:" prop="customerContractNo">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="税率:" prop="customerId">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="不含税总价:" prop="entryDate">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="入库人:" prop="entryPerson">
              <el-select v-model="form.entryPerson" placeholder="请选择" clearable>
                <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import pagination from '@/components/PIMTable/Pagination.vue'
import { ref } from 'vue'
import { ElMessageBox } from "element-plus";
import useUserStore from '@/store/modules/user'
import { userListNoPage } from "@/api/system/user.js";
import {
  ledgerListPage,
  customerList,
  addOrUpdateSalesLedger,
  getSalesLedgerWithProducts, delLedger
} from "@/api/salesManagement/salesLedger.js";
const userStore = useUserStore()
const { proxy } = getCurrentInstance()
const tableData = ref([])
const productData = ref([])
const selectedRows = ref([])
const userList = ref([])
const customerOption = ref([])
const tableLoading = ref(false)
const page = reactive({
  current: 1,
  size: 100,
})
const total = ref(0)
const fileList = ref([])
// ç”¨æˆ·ä¿¡æ¯è¡¨å•弹框数据
const operationType = ref('')
const dialogFormVisible = ref(false)
const data = reactive({
  searchForm: {
    customerName: '',
  },
  form: {
    salesContractNo: '',
    salesman: '',
    customerContractNo: '',
    customerId: '',
    projectName: '',
    entryPerson: '',
    entryDate: '',
    maintenanceTime: '',
    productData: [],
    executionDate: ''
  },
  rules: {
    salesman: [{ required: true, message: "请选择", trigger: "change" }],
    customerContractNo: [{ required: true, message: "请输入", trigger: "blur" }],
    customerId: [{ required: true, message: "请选择", trigger: "change" }],
    projectName: [{ required: true, message: "请输入", trigger: "blur" }],
    entryPerson: [{ required: true, message: "请选择", trigger: "change" }],
    entryDate: [{ required: true, message: "请选择", trigger: "change" }],
    executionDate: [{ required: true, message: "请选择", trigger: "change" }],
  }
})
const { searchForm, form, rules } = toRefs(data)
// æŸ¥è¯¢åˆ—表
/** æœç´¢æŒ‰é’®æ“ä½œ */
const handleQuery = () => {
  page.current = 1
  getList()
}
const paginationChange = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  getList()
}
const getList = () => {
  tableLoading.value = true
  ledgerListPage({ ...searchForm.value, ...page }).then(res => {
    tableLoading.value = false
    tableData.value = res.records
    tableData.value.map(item => {
      item.children = []
    })
    total.value = res.total
  }).catch(() => {
    tableLoading.value = false
  })
}
const findNodeById = (nodes, productId) => {
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].value === productId) {
      return nodes[i].label; // æ‰¾åˆ°èŠ‚ç‚¹ï¼Œè¿”å›žè¯¥èŠ‚ç‚¹
    }
    if (nodes[i].children && nodes[i].children.length > 0) {
      const foundNode = findNodeById(nodes[i].children, productId);
      if (foundNode) {
        return foundNode.label; // åœ¨å­èŠ‚ç‚¹ä¸­æ‰¾åˆ°ï¼Œè¿”å›žè¯¥èŠ‚ç‚¹
      }
    }
  }
  return null; // æ²¡æœ‰æ‰¾åˆ°èŠ‚ç‚¹ï¼Œè¿”å›žnull
};
// è¡¨æ ¼é€‰æ‹©æ•°æ®
const handleSelectionChange = (selection) => {
  // è¿‡æ»¤æŽ‰å­æ•°æ®
  selectedRows.value = selection.filter(item => item.children !== undefined);
  console.log('selection', selectedRows.value)
}
const expandedRowKeys = ref([])
// ä¸»è¡¨åˆè®¡æ–¹æ³•
const summarizeMainTable = (param) => {
  return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
};
// æ‰“开弹框
const openForm = async (type, row) => {
  operationType.value = type
  form.value = {}
  productData.value = []
  let userLists = await userListNoPage()
  userList.value = userLists.data
  customerList().then(res => {
    customerOption.value = res
  })
  console.log('userStore.id', userStore.id)
  form.value.entryPerson = userStore.id
  if (type === 'edit') {
    currentId.value = row.id;
    getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(res => {
      form.value = { ...res }
      form.value.entryPerson = Number(res.entryPerson)
      productData.value = form.value.productData
      fileList.value = form.value.salesLedgerFiles
    })
  }
  // let userAll = await userStore.getInfo()
  // userList.value.forEach(element => {
  //   if(userAll.user.nickName === element.nickName && userAll.user.userName === element.userName) {
  //     form.value.entryPerson = userAll.user.userId // è®¾ç½®é»˜è®¤ä¸šåŠ¡å‘˜ä¸ºå½“å‰ç”¨æˆ·
  //   }
  // });
  form.value.entryDate = getCurrentDate() // è®¾ç½®é»˜è®¤å½•入日期为当前日期
  dialogFormVisible.value = true
}
// æäº¤è¡¨å•
const submitForm = () => {
  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      if (productData.value.length > 0) {
        form.value.productData = proxy.HaveJson(productData.value)
      } else {
        proxy.$modal.msgWarning('请添加产品信息')
        return
      }
      let tempFileIds = []
      if (fileList.value.length > 0) {
        tempFileIds = fileList.value.map(item => item.tempId)
      }
      form.value.tempFileIds = tempFileIds
      form.value.type = 1
      addOrUpdateSalesLedger(form.value).then(res => {
        proxy.$modal.msgSuccess("提交成功")
        closeDia()
        getList()
      })
    }
  })
}
// å…³é—­å¼¹æ¡†
const closeDia = () => {
  proxy.resetForm("formRef")
  dialogFormVisible.value = false
}
// å¯¼å‡º
const handleOut = () => {
  ElMessageBox.confirm(
    '选中的内容将被导出,是否确认导出?',
    '导出', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  }
  ).then(() => {
    proxy.download("/sales/ledger/export", {}, '入库台账.xlsx')
  }).catch(() => {
    proxy.$modal.msg("已取消")
  })
}
// åˆ é™¤
const handleDelete = () => {
  let ids = []
  if (selectedRows.value.length > 0) {
    ids = selectedRows.value.map(item => item.id);
  } else {
    proxy.$modal.msgWarning('请选择数据')
    return
  }
  ElMessageBox.confirm(
    '选中的内容将被删除,是否确认删除?',
    '导出', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  }
  ).then(() => {
    delLedger(ids).then(res => {
      proxy.$modal.msgSuccess("删除成功")
      getList()
    })
  }).catch(() => {
    proxy.$modal.msg("已取消")
  })
}
// èŽ·å–å½“å‰æ—¥æœŸå¹¶æ ¼å¼åŒ–ä¸º YYYY-MM-DD
function getCurrentDate() {
  const today = new Date();
  const year = today.getFullYear();
  const month = String(today.getMonth() + 1).padStart(2, '0'); // æœˆä»½ä»Ž0开始
  const day = String(today.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}
onMounted(() => {
  getList()
})
</script>
<style scoped lang="scss"></style>
src/views/inventoryManagement/receiptManagement/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,359 @@
<template>
  <div class="app-container">
    <div class="search_form">
      <div>
        <span class="search_title">供应商名称:</span>
        <el-input v-model="searchForm.customerName" style="width: 240px" placeholder="请输入" @change="handleQuery"
          clearable prefix-icon="Search" />
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button>
      </div>
      <div>
        <el-button type="primary" @click="openForm('add')">新增</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
      </div>
    </div>
    <div class="table_list">
      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
        :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="入库时间" prop="salesContractNo" width="180" show-overflow-tooltip />
        <el-table-column label="入库批次" prop="customerContractNo" width="180" show-overflow-tooltip />
        <el-table-column label="供应商名称" prop="customerName" width="300" show-overflow-tooltip />
        <el-table-column label="产品大类" prop="salesman" width="100" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="projectName" width="180" show-overflow-tooltip />
        <el-table-column label="单位" prop="contractAmount" width="180" show-overflow-tooltip />
        <el-table-column label="入库数量" prop="entryPersonName" width="100" show-overflow-tooltip />
        <el-table-column label="含税单价" prop="entryDate" width="120" show-overflow-tooltip />
        <el-table-column label="含税总价" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column label="税率" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column label="不含税总价" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column label="入库人" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column fixed="right" label="操作" min-width="60" align="center">
          <template #default="scope">
            <el-button link type="primary" size="small" @click="openForm('edit', scope.row);">编辑</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
        :page="page.current" :limit="page.size" @pagination="paginationChange" />
    </div>
    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '新增入库' : '编辑入库'" width="70%"
      @close="closeDia">
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="供应商名称:" prop="salesContractNo">
              <el-input v-model="form.salesContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="产品大类:" prop="salesman">
              <el-select v-model="form.salesman" placeholder="请选择" clearable>
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
                  :value="item.nickName" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="customerContractNo">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="单位:" prop="customerId">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="入库时间:" prop="projectName">
              <el-date-picker style="width: 100%" v-model="form.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
                type="date" placeholder="请选择" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="入库批次:" prop="entryPerson">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="入库数量:" prop="customerContractNo">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="含税单价:" prop="customerId">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="含税总价:" prop="customerContractNo">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="税率:" prop="customerId">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="不含税总价:" prop="entryDate">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="入库人:" prop="entryPerson">
              <el-select v-model="form.entryPerson" placeholder="请选择" clearable>
                <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import pagination from '@/components/PIMTable/Pagination.vue'
import { ref } from 'vue'
import { ElMessageBox } from "element-plus";
import useUserStore from '@/store/modules/user'
import { userListNoPage } from "@/api/system/user.js";
import {
  ledgerListPage,
  customerList,
  addOrUpdateSalesLedger,
  getSalesLedgerWithProducts, delLedger
} from "@/api/salesManagement/salesLedger.js";
const userStore = useUserStore()
const { proxy } = getCurrentInstance()
const tableData = ref([])
const productData = ref([])
const selectedRows = ref([])
const userList = ref([])
const customerOption = ref([])
const tableLoading = ref(false)
const page = reactive({
  current: 1,
  size: 100,
})
const total = ref(0)
const fileList = ref([])
// ç”¨æˆ·ä¿¡æ¯è¡¨å•弹框数据
const operationType = ref('')
const dialogFormVisible = ref(false)
const data = reactive({
  searchForm: {
    customerName: '',
  },
  form: {
    salesContractNo: '',
    salesman: '',
    customerContractNo: '',
    customerId: '',
    projectName: '',
    entryPerson: '',
    entryDate: '',
    maintenanceTime: '',
    productData: [],
    executionDate: ''
  },
  rules: {
    salesman: [{ required: true, message: "请选择", trigger: "change" }],
    customerContractNo: [{ required: true, message: "请输入", trigger: "blur" }],
    customerId: [{ required: true, message: "请选择", trigger: "change" }],
    projectName: [{ required: true, message: "请输入", trigger: "blur" }],
    entryPerson: [{ required: true, message: "请选择", trigger: "change" }],
    entryDate: [{ required: true, message: "请选择", trigger: "change" }],
    executionDate: [{ required: true, message: "请选择", trigger: "change" }],
  }
})
const { searchForm, form, rules } = toRefs(data)
// æŸ¥è¯¢åˆ—表
/** æœç´¢æŒ‰é’®æ“ä½œ */
const handleQuery = () => {
  page.current = 1
  getList()
}
const paginationChange = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  getList()
}
const getList = () => {
  tableLoading.value = true
  ledgerListPage({ ...searchForm.value, ...page }).then(res => {
    tableLoading.value = false
    tableData.value = res.records
    tableData.value.map(item => {
      item.children = []
    })
    total.value = res.total
  }).catch(() => {
    tableLoading.value = false
  })
}
const findNodeById = (nodes, productId) => {
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].value === productId) {
      return nodes[i].label; // æ‰¾åˆ°èŠ‚ç‚¹ï¼Œè¿”å›žè¯¥èŠ‚ç‚¹
    }
    if (nodes[i].children && nodes[i].children.length > 0) {
      const foundNode = findNodeById(nodes[i].children, productId);
      if (foundNode) {
        return foundNode.label; // åœ¨å­èŠ‚ç‚¹ä¸­æ‰¾åˆ°ï¼Œè¿”å›žè¯¥èŠ‚ç‚¹
      }
    }
  }
  return null; // æ²¡æœ‰æ‰¾åˆ°èŠ‚ç‚¹ï¼Œè¿”å›žnull
};
// è¡¨æ ¼é€‰æ‹©æ•°æ®
const handleSelectionChange = (selection) => {
  // è¿‡æ»¤æŽ‰å­æ•°æ®
  selectedRows.value = selection.filter(item => item.children !== undefined);
  console.log('selection', selectedRows.value)
}
const expandedRowKeys = ref([])
// ä¸»è¡¨åˆè®¡æ–¹æ³•
const summarizeMainTable = (param) => {
  return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
};
// æ‰“开弹框
const openForm = async (type, row) => {
  operationType.value = type
  form.value = {}
  productData.value = []
  let userLists = await userListNoPage()
  userList.value = userLists.data
  customerList().then(res => {
    customerOption.value = res
  })
  console.log('userStore.id', userStore.id)
  form.value.entryPerson = userStore.id
  if (type === 'edit') {
    currentId.value = row.id;
    getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(res => {
      form.value = { ...res }
      form.value.entryPerson = Number(res.entryPerson)
      productData.value = form.value.productData
      fileList.value = form.value.salesLedgerFiles
    })
  }
  // let userAll = await userStore.getInfo()
  // userList.value.forEach(element => {
  //   if(userAll.user.nickName === element.nickName && userAll.user.userName === element.userName) {
  //     form.value.entryPerson = userAll.user.userId // è®¾ç½®é»˜è®¤ä¸šåŠ¡å‘˜ä¸ºå½“å‰ç”¨æˆ·
  //   }
  // });
  form.value.entryDate = getCurrentDate() // è®¾ç½®é»˜è®¤å½•入日期为当前日期
  dialogFormVisible.value = true
}
// æäº¤è¡¨å•
const submitForm = () => {
  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      if (productData.value.length > 0) {
        form.value.productData = proxy.HaveJson(productData.value)
      } else {
        proxy.$modal.msgWarning('请添加产品信息')
        return
      }
      let tempFileIds = []
      if (fileList.value.length > 0) {
        tempFileIds = fileList.value.map(item => item.tempId)
      }
      form.value.tempFileIds = tempFileIds
      form.value.type = 1
      addOrUpdateSalesLedger(form.value).then(res => {
        proxy.$modal.msgSuccess("提交成功")
        closeDia()
        getList()
      })
    }
  })
}
// å…³é—­å¼¹æ¡†
const closeDia = () => {
  proxy.resetForm("formRef")
  dialogFormVisible.value = false
}
// å¯¼å‡º
const handleOut = () => {
  ElMessageBox.confirm(
    '选中的内容将被导出,是否确认导出?',
    '导出', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  }
  ).then(() => {
    proxy.download("/sales/ledger/export", {}, '入库台账.xlsx')
  }).catch(() => {
    proxy.$modal.msg("已取消")
  })
}
// åˆ é™¤
const handleDelete = () => {
  let ids = []
  if (selectedRows.value.length > 0) {
    ids = selectedRows.value.map(item => item.id);
  } else {
    proxy.$modal.msgWarning('请选择数据')
    return
  }
  ElMessageBox.confirm(
    '选中的内容将被删除,是否确认删除?',
    '导出', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  }
  ).then(() => {
    delLedger(ids).then(res => {
      proxy.$modal.msgSuccess("删除成功")
      getList()
    })
  }).catch(() => {
    proxy.$modal.msg("已取消")
  })
}
// èŽ·å–å½“å‰æ—¥æœŸå¹¶æ ¼å¼åŒ–ä¸º YYYY-MM-DD
function getCurrentDate() {
  const today = new Date();
  const year = today.getFullYear();
  const month = String(today.getMonth() + 1).padStart(2, '0'); // æœˆä»½ä»Ž0开始
  const day = String(today.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}
onMounted(() => {
  getList()
})
</script>
<style scoped lang="scss"></style>
src/views/salesManagement/salesLedger/index.vue
@@ -3,14 +3,8 @@
    <div class="search_form">
      <div>
        <span class="search_title">客户名称:</span>
        <el-input
            v-model="searchForm.customerName"
            style="width: 240px"
            placeholder="请输入"
            @change="handleQuery"
            clearable
            prefix-icon="Search"
        />
        <el-input v-model="searchForm.customerName" style="width: 240px" placeholder="请输入" @change="handleQuery"
          clearable prefix-icon="Search" />
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button>
      </div>
      <div>
@@ -20,21 +14,13 @@
      </div>
    </div>
    <div class="table_list">
      <el-table :data="tableData" border v-loading="tableLoading"
                @selection-change="handleSelectionChange"
                :expand-row-keys="expandedRowKeys"
                :row-key="row => row.id"
                show-summary
                style="width: 100%"
                :summary-method="summarizeMainTable"
                @expand-change="expandChange"
                height="calc(100vh - 18.5em)">
      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
        :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
        :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)">
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column type="expand">
          <template #default="props">
            <el-table :data="props.row.children" border
                      show-summary
                      :summary-method="summarizeChildrenTable">
            <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable">
              <el-table-column align="center" label="序号" type="index" width="60" />
              <el-table-column label="产品大类"   prop="productCategory" />
              <el-table-column label="规格型号"  prop="specificationModel" />
@@ -53,7 +39,8 @@
        <el-table-column label="客户名称" prop="customerName" width="300" show-overflow-tooltip/>
        <el-table-column label="业务员" prop="salesman" width="100" show-overflow-tooltip/>
        <el-table-column label="项目名称" prop="projectName" width="180" show-overflow-tooltip/>
        <el-table-column label="合同金额(元)" prop="contractAmount" width="180" show-overflow-tooltip :formatter="formattedNumber"/>
        <el-table-column label="合同金额(元)" prop="contractAmount" width="180" show-overflow-tooltip
          :formatter="formattedNumber" />
        <el-table-column label="录入人" prop="entryPersonName" width="100" show-overflow-tooltip/>
        <el-table-column label="录入日期" prop="entryDate" width="120" show-overflow-tooltip/>
        <el-table-column label="签订日期" prop="executionDate" width="120" show-overflow-tooltip/>
@@ -63,10 +50,11 @@
          </template>
        </el-table-column>
      </el-table>
      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" :page="page.current"
                  :limit="page.size" @pagination="paginationChange" />
      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
        :page="page.current" :limit="page.size" @pagination="paginationChange" />
    </div>
    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '新增销售台账页面' : '编辑销售台账页面'" width="70%" @close="closeDia">
    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '新增销售台账页面' : '编辑销售台账页面'" width="70%"
      @close="closeDia">
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
@@ -77,7 +65,8 @@
          <el-col :span="12">
            <el-form-item label="业务员:" prop="salesman">
              <el-select v-model="form.salesman" placeholder="请选择" clearable>
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
                  :value="item.nickName" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -115,29 +104,14 @@
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="录入日期:" prop="entryDate">
              <el-date-picker
                  style="width: 100%"
                  v-model="form.entryDate"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  type="date"
                  placeholder="请选择"
                  clearable
                  disabled
              />
              <el-date-picker style="width: 100%" v-model="form.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
                type="date" placeholder="请选择" clearable disabled />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="签订日期:" prop="executionDate">
              <el-date-picker
                  style="width: 100%"
                  v-model="form.executionDate"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  type="date"
                  placeholder="请选择"
                  clearable
              />
              <el-date-picker style="width: 100%" v-model="form.executionDate" value-format="YYYY-MM-DD"
                format="YYYY-MM-DD" type="date" placeholder="请选择" clearable />
            </el-form-item>
          </el-col>
        </el-row>
@@ -147,7 +121,8 @@
            <el-button plain type="danger" @click="deleteProduct">删除</el-button>
          </el-form-item>
        </el-row>
        <el-table :data="productData" border @selection-change="productSelected"   show-summary :summary-method="summarizeMainTable">
        <el-table :data="productData" border @selection-change="productSelected" show-summary
          :summary-method="summarizeMainTable">
          <el-table-column align="center" type="selection" width="55" />
          <el-table-column align="center" label="序号" type="index" width="60" />
          <el-table-column label="产品大类" prop="productCategory" />
@@ -174,18 +149,9 @@
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="附件材料:" prop="remark">
              <el-upload
                  v-model:file-list="fileList"
                  :action="upload.url"
                  multiple
                  ref="fileUpload"
                  auto-upload
                  :headers="upload.headers"
                  :before-upload="handleBeforeUpload"
                  :on-error="handleUploadError"
                  :on-success="handleUploadSuccess"
                  :on-remove="handleRemove"
              >
              <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
                :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
                :on-success="handleUploadSuccess" :on-remove="handleRemove">
                <el-button type="primary">上传</el-button>
                <template #tip>
                  <div class="el-upload__tip">
@@ -204,27 +170,17 @@
        </div>
      </template>
    </el-dialog>
    <el-dialog v-model="productFormVisible" :title="productOperationType === 'add' ? '新增产品' : '编辑产品'" width="40%" @close="closeProductDia">
      <el-form :model="productForm"
               label-width="140px"
               label-position="top"
               :rules="productRules"
               ref="productFormRef">
    <el-dialog v-model="productFormVisible" :title="productOperationType === 'add' ? '新增产品' : '编辑产品'" width="40%"
      @close="closeProductDia">
      <el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="产品大类:" prop="productCategory">
              <!-- <el-select v-model="productForm.productCategory" placeholder="请选择" clearable>
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
              </el-select> -->
              <el-tree-select
                  v-model="productForm.productCategory"
                  placeholder="请选择" clearable
                  check-strictly
                  @change="getModels"
                  :data="productOptions"
                  :render-after-expand="false"
                  style="width: 100%"
              />
              <el-tree-select v-model="productForm.productCategory" placeholder="请选择" clearable check-strictly
                @change="getModels" :data="productOptions" :render-after-expand="false" style="width: 100%" />
            </el-form-item>
          </el-col>
@@ -246,7 +202,8 @@
          </el-col>
          <el-col :span="12">
            <el-form-item label="数量:" prop="quantity">
              <el-input type="number" :step="0.1" :min="0" v-model="productForm.quantity" placeholder="请输入" clearable @change="mathNum" />
              <el-input type="number" :step="0.1" :min="0" v-model="productForm.quantity" placeholder="请输入" clearable
                @change="mathNum" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -758,6 +715,4 @@
getList()
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>