maven
2025-09-18 997535cc8926f00fb0e2b6ccf082c84fabdcb4c7
yys  采购价格管理
已修改2个文件
526 ■■■■ 文件已修改
src/api/procurementManagement/advancedPriceManagement.js 284 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/advancedPriceManagement/index.vue 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/procurementManagement/advancedPriceManagement.js
@@ -2,301 +2,37 @@
import request from "@/utils/request";
// 分页查询价格列表
export function getPriceList(query) {
export function listPage(query) {
  return request({
    url: "/procurement/price/list",
    url: "/procurementPriceManagement/listPage",
    method: "get",
    params: query,
  });
}
// 获取价格详情
export function getPriceDetail(id) {
  return request({
    url: `/procurement/price/detail/${id}`,
    method: "get",
  });
}
// 新增价格
export function addPrice(data) {
export function add(data) {
  return request({
    url: "/procurement/price/add",
    url: "/procurementPriceManagement/add",
    method: "post",
    data: data,
  });
}
// 更新价格
export function updatePrice(data) {
export function update(data) {
  return request({
    url: "/procurement/price/update",
    method: "put",
    url: "/procurementPriceManagement/update",
    method: "post",
    data: data,
  });
}
// 删除价格
export function deletePrice(id) {
export function del(data) {
  return request({
    url: `/procurement/price/delete/${id}`,
    url: `/procurementPriceManagement/del`,
    method: "delete",
  });
}
// 批量删除价格
export function batchDeletePrice(ids) {
  return request({
    url: "/procurement/price/batchDelete",
    method: "delete",
    data: { ids },
  });
}
// 复制价格
export function copyPrice(id) {
  return request({
    url: `/procurement/price/copy/${id}`,
    method: "post",
  });
}
// 应用价格(将待生效状态改为有效)
export function applyPrice(id) {
  return request({
    url: `/procurement/price/apply/${id}`,
    method: "put",
  });
}
// 暂停价格
export function suspendPrice(id) {
  return request({
    url: `/procurement/price/suspend/${id}`,
    method: "put",
  });
}
// 批量设置折扣
export function batchSetDiscount(data) {
  return request({
    url: "/procurement/price/batchDiscount",
    method: "post",
    data: data,
  });
}
// 获取折扣配置
export function getDiscountConfig(id) {
  return request({
    url: `/procurement/price/discount/${id}`,
    method: "get",
  });
}
// 设置单个商品折扣
export function setDiscount(data) {
  return request({
    url: "/procurement/price/setDiscount",
    method: "post",
    data: data,
  });
}
// 获取阶梯折扣配置
export function getTieredDiscount(id) {
  return request({
    url: `/procurement/price/tieredDiscount/${id}`,
    method: "get",
  });
}
// 设置阶梯折扣
export function setTieredDiscount(data) {
  return request({
    url: "/procurement/price/setTieredDiscount",
    method: "post",
    data: data,
  });
}
// 获取价格控制设置
export function getPriceControlConfig() {
  return request({
    url: "/procurement/price/controlConfig",
    method: "get",
  });
}
// 更新价格控制设置
export function updatePriceControlConfig(data) {
  return request({
    url: "/procurement/price/controlConfig",
    method: "put",
    data: data,
  });
}
// 获取价格预警列表
export function getPriceWarnings(query) {
  return request({
    url: "/procurement/price/warnings",
    method: "get",
    params: query,
  });
}
// 处理价格预警
export function handlePriceWarning(id, action) {
  return request({
    url: `/procurement/price/warning/${id}`,
    method: "put",
    data: { action },
  });
}
// 获取价格历史记录
export function getPriceHistory(id, query) {
  return request({
    url: `/procurement/price/history/${id}`,
    method: "get",
    params: query,
  });
}
// 获取价格统计数据
export function getPriceStatistics(query) {
  return request({
    url: "/procurement/price/statistics",
    method: "get",
    params: query,
  });
}
// 导出价格数据
export function exportPriceData(query) {
  return request({
    url: "/procurement/price/export",
    method: "get",
    params: query,
    responseType: 'blob',
  });
}
// 导入价格数据
export function importPriceData(file) {
  const formData = new FormData();
  formData.append('file', file);
  return request({
    url: "/procurement/price/import",
    method: "post",
    data: formData,
    headers: {
      'Content-Type': 'multipart/form-data',
    },
  });
}
// 获取价格模板
export function downloadPriceTemplate() {
  return request({
    url: "/procurement/price/template",
    method: "get",
    responseType: 'blob',
  });
}
// 价格审批
export function approvePrice(id, data) {
  return request({
    url: `/procurement/price/approve/${id}`,
    method: "put",
    data: data,
  });
}
// 价格驳回
export function rejectPrice(id, data) {
  return request({
    url: `/procurement/price/reject/${id}`,
    method: "put",
    data: data,
  });
}
// 获取供应商列表(用于下拉选择)
export function getSupplierOptions() {
  return request({
    url: "/procurement/price/suppliers",
    method: "get",
  });
}
// 获取商品列表(用于下拉选择)
export function getProductOptions(query) {
  return request({
    url: "/procurement/price/products",
    method: "get",
    params: query,
  });
}
// 获取商品详细信息
export function getProductInfo(productId) {
  return request({
    url: `/procurement/price/productInfo/${productId}`,
    method: "get",
  });
}
// 价格比较分析
export function comparePrices(data) {
  return request({
    url: "/procurement/price/compare",
    method: "post",
    data: data,
  });
}
// 获取价格趋势数据
export function getPriceTrend(id, period) {
  return request({
    url: `/procurement/price/trend/${id}`,
    method: "get",
    params: { period },
  });
}
// 价格预测
export function predictPrice(id, data) {
  return request({
    url: `/procurement/price/predict/${id}`,
    method: "post",
    data: data,
  });
}
// 获取市场价格参考
export function getMarketPriceReference(productCode) {
  return request({
    url: `/procurement/price/marketRef/${productCode}`,
    method: "get",
  });
}
// 价格变动通知设置
export function updateNotificationSettings(data) {
  return request({
    url: "/procurement/price/notifications",
    method: "put",
    data: data,
  });
}
// 获取价格变动通知设置
export function getNotificationSettings() {
  return request({
    url: "/procurement/price/notifications",
    method: "get",
    data
  });
}
src/views/procurementManagement/advancedPriceManagement/index.vue
@@ -11,14 +11,6 @@
            <el-option v-for="supplier in supplierList" :key="supplier.id" :label="supplier.name" :value="supplier.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="价格状态:">
          <el-select v-model="searchForm.priceStatus" placeholder="请选择状态" clearable style="width: 150px">
            <el-option label="有效" value="active" />
            <el-option label="待生效" value="pending" />
            <el-option label="已过期" value="expired" />
            <el-option label="已暂停" value="suspended" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch" :loading="loading">
            <el-icon><Search /></el-icon>
@@ -42,10 +34,6 @@
        <el-button type="success" @click="openBatchDiscountDialog">
          <el-icon><Discount /></el-icon>
          批量折扣
        </el-button>
        <el-button type="warning" @click="openPriceControlDialog">
          <el-icon><Setting /></el-icon>
          价格控制
        </el-button>
        <el-button type="info" @click="exportData">
          <el-icon><Download /></el-icon>
@@ -81,7 +69,7 @@
        <el-table-column label="供应商" prop="supplierName" width="150" />
        <el-table-column label="基础价格" width="120" align="right">
          <template #default="{ row }">
            <span class="price-text">¥{{ row.basePrice.toFixed(2) }}</span>
            <span class="price-text">¥{{ row.basePrice }}</span>
          </template>
        </el-table-column>
        <el-table-column label="折扣信息" width="150">
@@ -97,17 +85,17 @@
        </el-table-column>
        <el-table-column label="实际价格" width="120" align="right">
          <template #default="{ row }">
            <span class="final-price">¥{{ calculateFinalPrice(row).toFixed(2) }}</span>
            <span class="final-price">¥{{ calculateFinalPrice(row) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="价格控制" width="120">
          <template #default="{ row }">
            <div class="price-control">
              <div v-if="row.priceControl?.minPrice" class="control-item">
                最低: ¥{{ row.priceControl.minPrice.toFixed(2) }}
              <div v-if="row.minPrice" class="control-item">
                最低: ¥{{ row.minPrice }}
              </div>
              <div v-if="row.priceControl?.maxPrice" class="control-item">
                最高: ¥{{ row.priceControl.maxPrice.toFixed(2) }}
              <div v-if="row.maxPrice" class="control-item">
                最高: ¥{{ row.maxPrice }}
              </div>
            </div>
          </template>
@@ -128,10 +116,6 @@
              <el-icon><Edit /></el-icon>
              编辑
            </el-button>
            <el-button type="success" link @click="openDiscountDialog(row)">
              <el-icon><Discount /></el-icon>
              折扣
            </el-button>
            <el-button type="danger" link @click="handleDelete(row)">
              <el-icon><Delete /></el-icon>
              删除
@@ -143,10 +127,10 @@
      <!-- 分页 -->
      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="pagination.currentPage"
          v-model:page-size="pagination.pageSize"
          v-model:current-page="pagination.current"
          v-model:page-size="pagination.size"
          :page-sizes="[10, 20, 50, 100]"
          :total="pagination.total"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
@@ -207,7 +191,6 @@
                <el-option label="无折扣" value="" />
                <el-option label="百分比折扣" value="percentage" />
                <el-option label="固定金额" value="fixed" />
                <el-option label="阶梯折扣" value="tiered" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -234,35 +217,6 @@
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 阶梯折扣设置 -->
        <div v-if="formData.discountType === 'tiered'">
          <el-form-item label="阶梯折扣">
            <el-table :data="formData.tieredDiscount" border size="small">
              <el-table-column label="最小数量" width="120">
                <template #default="{ row, $index }">
                  <el-input-number v-model="row.minQty" :min="0" size="small" />
                </template>
              </el-table-column>
              <el-table-column label="最大数量" width="120">
                <template #default="{ row, $index }">
                  <el-input-number v-model="row.maxQty" :min="0" size="small" />
                </template>
              </el-table-column>
              <el-table-column label="折扣率(%)" width="120">
                <template #default="{ row, $index }">
                  <el-input-number v-model="row.discount" :min="0" :max="100" :precision="2" size="small" />
                </template>
              </el-table-column>
              <el-table-column label="操作" width="80">
                <template #default="{ row, $index }">
                  <el-button type="danger" link @click="removeTieredRow($index)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
            <el-button type="primary" link @click="addTieredRow" class="mt-2">添加阶梯</el-button>
          </el-form-item>
        </div>
        <!-- 价格控制 -->
        <el-divider content-position="left">价格控制</el-divider>
@@ -378,12 +332,13 @@
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import {ref, reactive, computed, onMounted, getCurrentInstance} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Search, Refresh, Plus, Discount, Setting, Download, Delete, Edit, 
  Warning
} from '@element-plus/icons-vue'
import { listPage, update, del, add } from '@/api/procurementManagement/advancedPriceManagement'
// 响应式数据
const loading = ref(false)
@@ -398,15 +353,15 @@
// 搜索表单
const searchForm = reactive({
  productName: '',
  supplierId: '',
  priceStatus: ''
  supplierId: ''
})
const total = ref(0)
// 分页
const pagination = reactive({
  currentPage: 1,
  pageSize: 20,
  total: 0
  current: 1,
  size: 20
})
@@ -430,6 +385,8 @@
  reason: '',
  remark: ''
})
const tableData = ref([])
// 批量折扣表单
const batchDiscountForm = reactive({
@@ -456,44 +413,6 @@
  reason: [{ required: true, message: '请选择调价原因', trigger: 'change' }]
}
// 模拟数据
const tableData = ref([
  {
    id: 1,
    productName: '高强度螺栓',
    productCode: 'HQ001',
    specification: 'M12×80',
    supplierName: '优质五金供应商',
    basePrice: 2.50,
    discountType: 'percentage',
    discountValue: 10,
    priceControl: { minPrice: 2.00, maxPrice: 3.00 },
    status: 'active',
    effectiveTime: '2025-01-01 00:00:00',
    updateTime: '2025-09-17 10:30:00',
    unit: '个',
    reason: 'market',
    remark: '市场价格调整'
  },
  {
    id: 2,
    productName: '不锈钢管',
    productCode: 'BXG002',
    specification: 'Φ25×2.0',
    supplierName: '钢材贸易公司',
    basePrice: 45.80,
    discountType: 'fixed',
    discountValue: 5,
    priceControl: { minPrice: 40.00, maxPrice: 50.00 },
    status: 'pending',
    effectiveTime: '2025-10-01 00:00:00',
    updateTime: '2025-09-16 14:20:00',
    unit: '米',
    reason: 'cost',
    remark: '原材料成本上涨'
  }
])
const supplierList = ref([
  { id: 1, name: '优质五金供应商' },
  { id: 2, name: '钢材贸易公司' },
@@ -506,17 +425,6 @@
  { id: 3, name: '铝合金型材' }
])
// 计算属性
const finalTableData = computed(() => {
  return tableData.value.filter(item => {
    if (searchForm.productName && !item.productName.includes(searchForm.productName)) return false
    if (searchForm.supplierId && item.supplierId !== searchForm.supplierId) return false
    if (searchForm.priceStatus && item.status !== searchForm.priceStatus) return false
    return true
  })
})
// 方法
const calculateFinalPrice = (row) => {
@@ -541,8 +449,7 @@
const getDiscountText = (discountType) => {
  const textMap = {
    percentage: '百分比',
    fixed: '固定金额',
    tiered: '阶梯折扣'
    fixed: '固定金额'
  }
  return textMap[discountType] || '未知'
}
@@ -551,8 +458,7 @@
  const statusMap = {
    active: 'success',
    pending: 'warning',
    expired: 'info',
    suspended: 'danger'
    expired: 'info'
  }
  return statusMap[status] || 'info'
}
@@ -561,8 +467,7 @@
  const statusMap = {
    active: '有效',
    pending: '待生效',
    expired: '已过期',
    suspended: '已暂停'
    expired: '已过期'
  }
  return statusMap[status] || '未知'
}
@@ -577,16 +482,17 @@
const handleSearch = () => {
  loading.value = true
  // 模拟API调用
  setTimeout(() => {
  listPage({ ...searchForm, ...pagination}).then(res => {
    tableData.value = res.data.records
    total.value = res.data.total
    loading.value = false
  }, 500)
  })
}
const resetSearch = () => {
  Object.assign(searchForm, {
    productName: '',
    supplierId: '',
    priceStatus: ''
    supplierId: ''
  })
  handleSearch()
}
@@ -647,32 +553,28 @@
  try {
    await formRef.value.validate()
    submitLoading.value = true
    // 模拟API调用
    setTimeout(() => {
      if (dialogType.value === 'add') {
        const newItem = {
          id: Date.now(),
          ...formData,
          priceControl: {
            minPrice: formData.minPrice,
            maxPrice: formData.maxPrice
          },
          status: 'pending',
          updateTime: new Date().toLocaleString()
    if (dialogType.value === 'add') {
      add(formData).then(res => {
        if (res.code === 200){
          ElMessage.success('新增成功')
          handleSearch()
        }
        tableData.value.unshift(newItem)
        ElMessage.success('新增成功')
      } else {
        // 编辑逻辑
        ElMessage.success('编辑成功')
      }
      dialogVisible.value = false
      submitLoading.value = false
    }, 1000)
      })
    } else {
      update(formData).then(res => {
        if (res.code === 200){
          ElMessage.success('编辑成功')
          handleSearch()
        }
      })
    }
  } catch (error) {
    console.error('表单验证失败:', error)
  }finally {
    dialogVisible.value = false
    submitLoading.value = false
  }
}
@@ -689,10 +591,13 @@
  selectedRows.value.forEach(row => {
    row.discountType = batchDiscountForm.discountType
    row.discountValue = batchDiscountForm.discountValue
    update(row).then(res => {
      handleSearch()
    })
  })
  ElMessage.success(`已为 ${selectedRows.value.length} 个商品设置折扣`)
  ElMessage.success('折扣设置成功')
  batchDiscountVisible.value = false
}
const openPriceControlDialog = () => {
@@ -704,23 +609,19 @@
  priceControlVisible.value = false
}
const openDiscountDialog = (row) => {
  // 单个商品折扣设置
  openDialog('edit', row)
}
const handleDelete = (row) => {
  ElMessageBox.confirm('确定要删除这条记录吗?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    const index = tableData.value.findIndex(item => item.id === row.id)
    if (index !== -1) {
      tableData.value.splice(index, 1)
      ElMessage.success('删除成功')
    }
   let ids = [row.id]
    del(ids).then(res => {
      if(res.code === 200){
        ElMessage.success('删除成功')
        handleSearch()
      }
    })
  })
}
@@ -735,14 +636,12 @@
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    selectedRows.value.forEach(row => {
      const index = tableData.value.findIndex(item => item.id === row.id)
      if (index !== -1) {
        tableData.value.splice(index, 1)
     del(selectedRows.value.map(item => item.id)).then(i =>{
       if(i.code === 200){
        ElMessage.success('删除成功')
        handleSearch()
      }
    })
    ElMessage.success('批量删除成功')
    selectedRows.value = []
     })
  })
}
@@ -751,17 +650,28 @@
}
const handleSizeChange = (size) => {
  pagination.pageSize = size
  pagination.size = size
  handleSearch()
}
const handleCurrentChange = (page) => {
  pagination.currentPage = page
  pagination.current = page
  handleSearch()
}
const { proxy } = getCurrentInstance();
const exportData = () => {
  ElMessage.success('数据导出功能开发中...')
  ElMessageBox.confirm("内容将被导出,是否确认导出?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
      .then(() => {
        proxy.download("/procurementPriceManagement/export", {}, "采购价格管理.xlsx");
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
}
// 生命周期