yaowanxin
2025-09-22 f80d798b83fabb038cf10d745acd34c9c42fed4c
Merge remote-tracking branch 'origin/ywx' into dev
已修改5个文件
334 ■■■■■ 文件已修改
src/api/inventoryManagement/stockReport.js 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/salesManagement/salesQuotation.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/index.vue 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockReport/index.vue 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesQuotation/index.vue 137 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/inventoryManagement/stockReport.js
@@ -3,16 +3,15 @@
// 获取库存日报统计
export const getStockDailyReport = (params) => {
    return request({
        url: "/stockreport/daily",
        url: "/stockin/getReportList",
        method: "get",
        params,
    });
};
// 获取库存月报统计
export const getStockMonthlyReport = (params) => {
    return request({
        url: "/stockreport/monthly",
        url: "/stockin/getReportList",
        method: "get",
        params,
    });
@@ -21,7 +20,7 @@
// 获取作业报表统计
export const getWorkReport = (params) => {
    return request({
        url: "/stockreport/work",
        url: "/stockin/getReportList",
        method: "get",
        params,
    });
@@ -30,7 +29,7 @@
// 获取库存进出存统计
export const getStockInOutReport = (params) => {
    return request({
        url: "/stockreport/inout",
        url: "/stockin/getReportList",
        method: "get",
        params,
    });
@@ -39,8 +38,8 @@
// 导出库存报表
export const exportStockReport = (params) => {
    return request({
        url: "/stockreport/export",
        method: "get",
        url: "/stockin/exportCopy",
        method: "post",
        params,
        responseType: 'blob'
    });
src/api/salesManagement/salesQuotation.js
@@ -2,7 +2,7 @@
import request from "@/utils/request";
// 分页查询报价单列表
export function quotationList(query) {
export function getQuotationList(query) {
  return request({
    url: "/sales/quotation/list",
    method: "get",
@@ -32,7 +32,7 @@
export function updateQuotation(data) {
  return request({
    url: "/sales/quotation/update",
    method: "put",
    method: "post",
    data: data,
  });
}
src/views/inventoryManagement/stockManagement/index.vue
@@ -122,11 +122,11 @@
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
          <!-- <el-col :span="12">
          <el-form-item label="最低库存:" prop="minStock">
            <el-input v-model="form.minStock" placeholder="请输入最低库存" clearable />
          </el-form-item>
        </el-col>
        </el-col> -->
        </el-row>
      </el-form>
      <template #footer>
@@ -153,9 +153,11 @@
  exportStockManage
} from "@/api/inventoryManagement/stockManage.js";
import {
  updateManagement,
  updateManagement,addSutockIn,selectProductRecordListByPuechaserId
} from "@/api/inventoryManagement/stockIn.js";
const userStore = useUserStore()
const { proxy } = getCurrentInstance()
const tableData = ref([])
@@ -235,11 +237,13 @@
  getStockManagePage({ ...searchForm.value, ...page }).then(res => {
    tableLoading.value = false
    tableData.value = res.data.records
    console.log('res', res)
    // console.log('res', res)
    // tableData.value.map(item => {
    //   item.children = []
    // })
    total.value = res.data.total
    // 数据加载完成后检查库存
    checkStockAndCreatePurchase();
  }).catch(() => {
    tableLoading.value = false
  })
@@ -301,35 +305,61 @@
  console.log(form.value)
  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
      updateManagement(form.value).then(res => {
        proxy.$modal.msgSuccess("提交成功")
        closeDia()
        getList()
        // 提交后检查库存并尝试创建请购单
        checkStockAndAutoCreatePurchase();
        checkStockAndCreatePurchase();
      })
    }
  })
}
// 检查库存并自动创建请购单
const checkStockAndAutoCreatePurchase = async () => {
  try {
    await checkStockAndCreatePurchase();
  } catch (error) {
    console.error('自动补货失败:', error);
    proxy.$modal.msgError('自动补货失败,请手动处理');
// const handList = () => {
//   selectProductRecordListByPuechaserId().then(res => {
//     productModelList.value = res.data.filter(item => item.productName === value)
//     console.log('productModelList.value', productModelList.value)
//   })
// }
// 检查库存并创建请购单
const checkStockAndCreatePurchase = async () => {
  const stockList = tableData.value;
  handList()
  for (const item of stockList) {
    if (item.inboundNum0 < item.minStock) {
      try {
          const stockInData = {
            nickName: userStore.nickName,// 使用新格式化函数
            details: selectedRows.value.map(product => ({
              id: product.id,
              inboundQuantity: Number(product.quantityStock)
            })),
          };
        console.log('准备提交的数据:', JSON.parse(JSON.stringify(stockInData)));
          // 调用API
          loading.value = true
          await addSutockIn(stockInData)
          proxy.$modal.msgSuccess('新增入库成功')
          loading.value = false
        // // 生成请购单
        // const createRes = await createPurchaseRequest({
        //   productId: item.productId,
        //   requiredQuantity: item.minStock - item.inboundNum0,
        //   supplierId: item.supplierId
        // });
        // if (createRes.code === 200) {
        //   // 流转请购单到采购模块
        //   await transferPurchaseRequest({ requestId: createRes.data.id });
        //   proxy.$modal.msgSuccess(`产品 ${item.productName} 请购单已生成并流转`);
        // }
      } catch (error) {
        console.error(`产品 ${item.productName} 生成请购单失败:`, error);
        proxy.$modal.msgError(`产品 ${item.productName} 生成请购单失败,请手动处理`);
      }
    }
  }
};
// 关闭弹框
@@ -394,7 +424,14 @@
}
onMounted(() => {
  getList()
  checkStockAndAutoCreatePurchase();
  checkStockAndCreatePurchase();
    // 每小时检查一次库存
    const intervalId = setInterval(checkStockAndCreatePurchase, 60 * 60 * 1000);
onUnmounted(() => {
  // 组件卸载时清除定时器
  clearInterval(intervalId);
});
})
</script>
src/views/inventoryManagement/stockReport/index.vue
@@ -33,8 +33,8 @@
          range-separator="至"
          start-placeholder="开始月份"
          end-placeholder="结束月份"
          format="YYYY-MM"
          value-format="YYYY-MM"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
          style="width: 240px;"
        />
        <el-date-picker
@@ -165,14 +165,14 @@
           <el-table-column
             v-if="searchForm.reportType === 'daily'"
             label="日期"
             prop="date"
             prop="createTime"
             width="100"
             align="center"
           />
           <el-table-column
             v-if="searchForm.reportType === 'monthly'"
             label="月份"
             prop="month"
             prop="createTime"
             width="100"
             align="center"
           />
@@ -212,27 +212,27 @@
             width="70"
             show-overflow-tooltip
           />
           <el-table-column
           <!-- <el-table-column
             label="期初库存"
             prop="beginStock"
             width="100"
             align="center"
           />
           /> -->
           <el-table-column
             label="入库数量"
             prop="inboundNum"
             width="100"
             align="center"
           />
           <el-table-column
           <!-- <el-table-column
             label="出库数量"
             prop="outboundNum"
             prop=""
             width="100"
             align="center"
           />
           /> -->
           <el-table-column
             label="期末库存"
             prop="endStock"
             label="现在库存"
             prop="inboundNum0"
             width="100"
             align="center"
           />
@@ -298,6 +298,8 @@
  exportStockReport
} from '@/api/inventoryManagement/stockReport'
const { proxy } = getCurrentInstance()
// 响应式数据
const tableLoading = ref(false)
const trendChart = ref(null)
@@ -365,10 +367,14 @@
    }
    
    if (response.code === 200) {
      reportData.value = response.data
      // generateMockData()
      reportData.value.tableData = response.data.tableData
      reportData.value.summary = response.data.summary
      reportData.value.chartData = response.data.chartData
      nextTick(() => {
        initCharts()
      })
    }
  } catch (error) {
    ElMessage.error('查询失败:' + error.message)
@@ -376,7 +382,37 @@
    tableLoading.value = false
  }
}
// // 生成假数据
// const generateMockData = () => {
//   // 生成统计卡片假数据
//   const summary = {
//     totalIn: 1000,
//     totalOut: 600,
//     currentStock: 400,
//     turnoverRate: 30
//   }
//   // 生成图表假数据
//   const trendDates = ['2025-09-15', '2025-09-16', '2025-09-17', '2025-09-18', '2025-09-19']
//   const trendValues = [300, 350, 400, 380, 420]
//   const comparisonDates = ['2025-09-15', '2025-09-16', '2025-09-17']
//   const inValues = [100, 150, 200]
//   const outValues = [80, 120, 100]
//   const chartData = {
//     trendDates,
//     trendValues,
//     comparisonDates,
//     inValues,
//     outValues
//   }
//   reportData.value = {
//     summary,
//     chartData,
//     tableData: []
//   }
// }
// 验证搜索表单
const validateSearchForm = () => {
  if (searchForm.reportType === 'daily') {
@@ -401,7 +437,12 @@
// 获取查询参数
const getQueryParams = () => {
  const params = {
    reportType: searchForm.reportType
    reportType: searchForm.reportType,
    reportDate: "",
    startMonth: "",
    endMonth: "",
    startDate: "",
    endDate: ""
  }
  
  if (searchForm.reportType === 'daily') {
@@ -438,20 +479,20 @@
  
  try {
    const params = getQueryParams()
    const response = await exportStockReport(params)
    // const response = await exportStockReport(params)
    proxy.download("/stockin/exportCopy", params, '库存报表.xlsx')
    // 创建下载链接
    const blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `${getTableTitle()}_${new Date().getTime()}.xlsx`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    // const blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
    // const url = window.URL.createObjectURL(blob)
    // const link = document.createElement('a')
    // link.href = url
    // link.download = `${getTableTitle()}_${new Date().getTime()}.xlsx`
    // document.body.appendChild(link)
    // link.click()
    // document.body.removeChild(link)
    // window.URL.revokeObjectURL(url)
    
    ElMessage.success('导出成功')
    // ElMessage.success('导出成功')
  } catch (error) {
    ElMessage.error('导出失败:' + error.message)
  }
src/views/salesManagement/salesQuotation/index.vue
@@ -166,9 +166,9 @@
            </div>
          </template>
          <el-table :data="form.products" border style="width: 100%">
            <el-table-column prop="productName" label="产品名称" width="200">
            <el-table-column prop="product" label="产品名称" width="200">
              <template #default="scope">
                <el-input v-model="scope.row.productName" placeholder="请输入产品名称" />
                <el-input v-model="scope.row.product" placeholder="请输入产品名称" />
              </template>
            </el-table-column>
            <el-table-column prop="specification" label="规格型号" width="150">
@@ -284,7 +284,7 @@
      <div style="margin-top: 20px;">
        <h4>产品明细</h4>
        <el-table :data="currentQuotation.products" border style="width: 100%">
          <el-table-column prop="productName" label="产品名称" />
          <el-table-column prop="product" label="产品名称" />
          <el-table-column prop="specification" label="规格型号" />
          <el-table-column prop="quantity" label="数量" />
          <el-table-column prop="unit" label="单位" />
@@ -310,10 +310,11 @@
</template>
<script setup>
import { ref, reactive, computed } from 'vue'
import { ref, reactive, computed,onMounted  } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
import Pagination from '@/components/PIMTable/Pagination.vue'
// import Pagination from '@/components/PIMTable/Pagination.vue'
import {getQuotationList,addQuotation,updateQuotation,deleteQuotation} from '@/api/salesManagement/salesQuotation.js'
// 响应式数据
const loading = ref(false)
@@ -323,56 +324,7 @@
  status: ''
})
const quotationList = ref([
  {
    id: 1,
    quotationNo: 'QT202312001',
    customer: '上海科技有限公司',
    salesperson: '陈志强',
    quotationDate: '2023-12-01',
    validDate: '2023-12-31',
    totalAmount: 50000.00,
    paymentMethod: '全款到付',
    deliveryPeriod: '30天',
    status: '已发送',
    remark: '重要客户报价',
    products: [
      { productName: '工业传感器', specification: 'SEN-001', quantity: 10, unit: '个', unitPrice: 5000, amount: 50000 }
    ]
  },
  {
    id: 2,
    quotationNo: 'QT202312002',
    customer: '深圳电子有限公司',
    salesperson: '刘雅婷',
    quotationDate: '2023-12-02',
    validDate: '2023-12-31',
    totalAmount: 35000.00,
    paymentMethod: '分期付款',
    deliveryPeriod: '20天',
    status: '客户确认',
    remark: '常规报价',
    products: [
      { productName: '控制模块', specification: 'CTL-002', quantity: 5, unit: '个', unitPrice: 7000, amount: 35000 }
    ]
  },
  {
    id: 3,
    quotationNo: 'QT202312003',
    customer: '北京贸易公司',
    salesperson: '王建国',
    quotationDate: '2023-12-03',
    validDate: '2023-12-31',
    totalAmount: 28000.00,
    paymentMethod: '月结',
    deliveryPeriod: '15天',
    status: '草稿',
    remark: '新客户报价',
    products: [
      { productName: '数据采集器', specification: 'DAQ-003', quantity: 4, unit: '个', unitPrice: 7000, amount: 28000 }
    ]
  }
])
const quotationList = ref([])
const pagination = reactive({
  total: 3,
@@ -384,6 +336,7 @@
const viewDialogVisible = ref(false)
const dialogTitle = ref('新增报价')
const form = reactive({
  quotationNo: '',
  customer: '',
  salesperson: '',
  quotationDate: '',
@@ -441,10 +394,6 @@
  return statusMap[status] || 'info'
}
const handleSearch = () => {
  // 搜索逻辑已在computed中处理
}
const resetSearch = () => {
  searchForm.quotationNo = ''
  searchForm.customer = ''
@@ -480,9 +429,16 @@
  }).then(() => {
    const index = quotationList.value.findIndex(item => item.id === row.id)
    if (index > -1) {
      quotationList.value.splice(index, 1)
      pagination.total--
      ElMessage.success('删除成功')
      deleteQuotation(row.id).then(res=>{
        // console.log(res)
        if(res.code===200){
          ElMessage.success('删除成功')
          handleSearch()
        }
      })
      // quotationList.value.splice(index, 1)
      // pagination.total--
      // ElMessage.success('删除成功')
    }
  })
}
@@ -552,22 +508,40 @@
        // 编辑
        const index = quotationList.value.findIndex(item => item.id === editId.value)
        if (index > -1) {
          quotationList.value[index] = { ...form, id: editId.value }
          ElMessage.success('编辑成功')
          updateQuotation(form).then(res=>{
            // console.log(res)
            if(res.code===200){
              ElMessage.success('编辑成功')
              dialogVisible.value = false
              handleSearch()
            }
          })
          // quotationList.value[index] = { ...form, id: editId.value }
          // ElMessage.success('编辑成功')
        }
      } else {
        // 新增
        const newId = Math.max(...quotationList.value.map(item => item.id)) + 1
        const quotationNo = `QT${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(new Date().getDate()).padStart(2, '0')}${String(newId).padStart(3, '0')}`
        quotationList.value.push({
          ...form,
          id: newId,
          quotationNo: quotationNo
        // const newId = Math.max(...quotationList.value.map(item => item.id)) + 1
        form.quotationNo = `QT${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(new Date().getDate()).padStart(2, '0')}`
        addQuotation(form).then(res=>{
          // console.log(res)
          if(res.code===200){
            ElMessage.success('新增成功')
            dialogVisible.value = false
            handleSearch()
          }
        })
        pagination.total++
        ElMessage.success('新增成功')
        // quotationList.value.push({
        //   ...form,
        //   // id: newId,
        //   quotationNo: quotationNo
        // })
        // pagination.total++
        // ElMessage.success('新增成功')
      }
      dialogVisible.value = false
    }
  })
}
@@ -576,6 +550,23 @@
  pagination.currentPage = val.page
  pagination.pageSize = val.limit
}
const handleSearch = ()=>{
  const params = {
    page:pagination,
    ...searchForm
  }
  getQuotationList(params).then(res=>{
    // console.log(res)
    if(res.code===200){
      quotationList.value = res.data.records
      pagination.total = res.data.total
    }
  })
}
onMounted(()=>{
  handleSearch()
})
</script>
<style scoped>