张诺
3 天以前 d8fead89b61acd2b1462559c2fa634b05f73c5d1
提交修改新增加工 增加煤质方案和煤质字段模块
已修改8个文件
已删除1个文件
已添加3个文件
1951 ■■■■■ 文件已修改
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicInformation/index.vue 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicInformation/mould/coalMeiZhiZiDuanWeiHu.vue 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicInformation/mould/coalQualityMaintenance.vue 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procureMent/components/ProductionDialog.vue 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procureMent/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/production/components/ProductionDetailsTable.vue 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/production/components/ProductionDetailsTableExample.vue 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/production/components/ProductionDialog.vue 528 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/production/components/SupplierDialog.vue 283 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/production/index.vue 372 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -22,6 +22,7 @@
    "axios": "0.28.1",
    "clipboard": "2.0.11",
    "echarts": "5.5.1",
    "default-passive-events": "^4.0.0",
    "element-china-area-data": "^6.1.0",
    "element-plus": "2.7.6",
    "file-saver": "2.0.5",
src/main.js
@@ -6,6 +6,7 @@
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/dark/css-vars.css'
import locale from 'element-plus/es/locale/lang/zh-cn'
import "default-passive-events";
import '@/assets/styles/index.scss' // global css
src/views/basicInformation/index.vue
@@ -1,5 +1,5 @@
<template>
  <div>    <el-form :inline="true" :model="queryParams" class="search-form" >
  <div> <el-form :inline="true" :model="queryParams" class="search-form">
      <el-form-item label="搜索" v-if="tabName === 'supplier' || tabName === 'customer'">
        <el-input v-model="queryParams.searchAll" placeholder="供应商/识别码/详细地址" clearable />
      </el-form-item>
@@ -16,7 +16,7 @@
      <el-tabs v-model="activeTab" class="info-tabs" @tab-click="handleTabClick">
        <el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.label" :name="tab.name" />
      </el-tabs>
      <!-- æ“ä½œæŒ‰é’®åŒº -->
      <el-row :gutter="24" class="table-toolbar">
        <el-button type="primary" :icon="Plus" @click="handleAdd">新建</el-button>
@@ -28,17 +28,21 @@
        <data-table :loading="loading" :table-data="tableData" :columns="columns"
          @selection-change="handleSelectionChange" @edit="handleEdit" :show-selection="true" :border="true" />
      </div>
      <pagination v-if="total>0" :page="pageNum" :limit="pageSizes" :total="total" @pagination="handPagination"
      <pagination v-if="total > 0" :page="pageNum" :limit="pageSizes" :total="total" @pagination="handPagination"
        :layout="'total, prev, pager, next, jumper'" />
      <Supplier v-if="tabName === 'supplier'" v-model:copyForm="copyForm" v-model:supplierDialogFormVisible="dialogFormVisible" :form="form"
        :title="title" @submit="handleSubmit" @beforeClose="handleBeforeClose"
        @update:dialogFormVisible="handleDialogFormVisible" :addOrEdit="addOrEdit" />
      <Customer v-if="tabName === 'customer'" v-model:copyForm="copyForm" v-model:customerDialogFormVisible="dialogFormVisible" :form="form"
        :title="title" @submit="handleSubmit" :addOrEdit="addOrEdit" @beforeClose="handleBeforeClose" />
      <Coal v-if="tabName === 'coal'" v-model:copyForm="copyForm" v-model:coalDialogFormVisible="dialogFormVisible" :form="form" :title="title"
        :addOrEdit="addOrEdit" @submit="handleSubmit" />
      <Supplier v-if="tabName === 'supplier'" v-model:copyForm="copyForm"
        v-model:supplierDialogFormVisible="dialogFormVisible" :form="form" :title="title" @submit="handleSubmit"
        @beforeClose="handleBeforeClose" @update:dialogFormVisible="handleDialogFormVisible" :addOrEdit="addOrEdit" />
      <Customer v-if="tabName === 'customer'" v-model:copyForm="copyForm"
        v-model:customerDialogFormVisible="dialogFormVisible" :form="form" :title="title" @submit="handleSubmit"
        :addOrEdit="addOrEdit" @beforeClose="handleBeforeClose" />
      <Coal v-if="tabName === 'coal'" v-model:copyForm="copyForm" v-model:coalDialogFormVisible="dialogFormVisible"
        :form="form" :title="title" :addOrEdit="addOrEdit" @submit="handleSubmit" />
      <coalQualityMaintenance v-if="tabName === 'coalQualityMaintenance'"
        v-model:coalQualityMaintenanceDialogFormVisible="dialogFormVisible" :form="form" :title="title"
        :addOrEdit="addOrEdit" @submit="handleSubmit" />
      <coalMeiZhiZiDuanWeiHu v-if="tabName === 'coalMeiZhiZiDuanWeiHu'"
        v-model:coalMaintenanceFieldDialogVisible="dialogFormVisible" :form="form" :title="title"
        :addOrEdit="addOrEdit" @submit="handleSubmit" />
    </el-card>
  </div>
@@ -54,6 +58,7 @@
import Customer from "./mould/customer.vue";
import Coal from "./mould/coal.vue";
import coalQualityMaintenance from "./mould/coalQualityMaintenance.vue";
import coalMeiZhiZiDuanWeiHu from "./mould/coalMeiZhiZiDuanWeiHu.vue";
const { proxy } = getCurrentInstance()
import { getSupply, addOrEditSupply, delSupply } from "@/api/basicInformation/supplier.js";
import { getCoalInfo, delCoalInfo } from "@/api/basicInformation/coal.js";
@@ -63,6 +68,7 @@
import { getCustomerList, delCustomer } from "@/api/basicInformation/customer.js";
// å¼¹çª—
const coalMaintenanceFieldDialogVisible = ref(false);
const coalQualityMaintenanceDialogFormVisible = ref(false);
const customerDialogFormVisible = ref(false);
const coalDialogFormVisible = ref(false);
@@ -120,19 +126,16 @@
// åœ°å€æ ¼å¼åŒ–函数
const formatAddressArray = (addressIds) => {
  // å¦‚果地址映射表还没有准备好,显示 --
  if (!addressMap.value || Object.keys(addressMap.value).length === 0||!addressIds || !Array.isArray(addressIds) || addressIds.length === 0 || addressIds.every(id => !id)) {
  if (!addressMap.value || Object.keys(addressMap.value).length === 0 || !addressIds || !Array.isArray(addressIds) || addressIds.length === 0 || addressIds.every(id => !id)) {
    return '--';
  }
  const addressNames = addressIds.map(id => {
    return addressMap.value[id]?.name || '--';
  });
  // å¦‚果所有地址名称都是 '--',则返回 '--'
  if (addressNames.every(name => name === '--')) {
    return '--';
  }
  return addressNames.filter(name => name !== '--').join(' / ');
};
// èŽ·å–ç”¨æˆ·åˆ—è¡¨æ•°æ®
@@ -149,7 +152,6 @@
    console.error('获取用户列表失败:', error);
  }
};
onMounted(async () => {
  await handleTabClick({ props: { name: "supplier" } });
  await fetchAreaOptions(); // å…ˆèŽ·å–åœ°å€é€‰æ‹©æ•°æ®å¹¶æž„å»ºæ˜ å°„è¡¨
@@ -161,7 +163,8 @@
  { name: "supplier", label: "供应商信息" },
  { name: "customer", label: "客户信息" },
  { name: "coal", label: "煤种信息" },
  { name: "coalQualityMaintenance", label: "煤质维护" },
  { name: "coalQualityMaintenance", label: "煤质方案" },
  { name: "coalMeiZhiZiDuanWeiHu", label: "煤质字段" }
]);
// æ˜¯å¦ç¼–辑
const addOrEdit = ref("add");
@@ -170,9 +173,9 @@
// supplier ä¾›åº”商数据
const supplierColumns = ref([
  { prop: "supplierName", label: "供应商名称", minWidth: 100 },
  { prop: "taxpayerId", label: "统一人识别号", minWidth: 170 },  {
    prop: "bids",
    label: "经营地址",
  { prop: "taxpayerId", label: "统一人识别号", minWidth: 170 }, {
    prop: "bids",
    label: "经营地址",
    minWidth: 150,
    showOverflowTooltip: true,
    formatter: (row, column, cellValue) => {
@@ -187,10 +190,10 @@
  { prop: "businessAddress", label: "经营详细地址", minWidth: 150 },
  { prop: "bankAccount", label: "开户行", minWidth: 120 },
  { prop: "bankName", label: "银行账号", minWidth: 150 },
  { prop: "contactPerson", label: "联系人", minWidth: 100 },
  {
    prop: "cids",
    label: "联系人地址",
  { prop: "contactPerson", label: "联系人", minWidth: 100 },
  {
    prop: "cids",
    label: "联系人地址",
    minWidth: 150,
    showOverflowTooltip: true,
    formatter: (row, column, cellValue) => {
@@ -201,7 +204,7 @@
      ]
      return formatAddressArray(arr);
    }
  },{ prop: "contactAddress", label: "联系人详细地址", minWidth: 120 },
  }, { prop: "contactAddress", label: "联系人详细地址", minWidth: 120 },
  // { 
  //   prop: "maintainerId", 
  //   label: "维护人", 
@@ -229,9 +232,9 @@
const customerColumns = ref([
  { prop: "customerName", label: "客户名称", minWidth: 100 },
  { prop: "taxpayerId", label: "统一人识别号", minWidth: 120 },
{
    prop: "bids",
    label: "经营地址",
  {
    prop: "bids",
    label: "经营地址",
    minWidth: 150,
    showOverflowTooltip: true,
    formatter: (row, column, cellValue) => {
@@ -245,12 +248,12 @@
  },
  { prop: "businessAddress", label: "详细地址", minWidth: 150 },
  { prop: "bankName", label: "开户行", minWidth: 120 },
  { prop: "bankAccount", label: "银行账号", minWidth: 150 },
  { prop: "bankAccount", label: "银行账号", minWidth: 150 },
  { prop: "contactPerson", label: "联系人", minWidth: 100 },
  { prop: "contactPhone", label: "联系人电话", minWidth: 100 },
{
    prop: "cids",
    label: "联系人地址",
  {
    prop: "cids",
    label: "联系人地址",
    minWidth: 150,
    showOverflowTooltip: true,
    formatter: (row, column, cellValue) => {
@@ -267,9 +270,9 @@
]);
// coal ç…¤ç§æ•°æ®
const coalColumns = ref([
  { prop: "coal", label: "煤种名称", minWidth: 200 },  {
    prop: "maintainerId",
    label: "维护人",
  { prop: "coal", label: "煤种名称", minWidth: 200 }, {
    prop: "maintainerId",
    label: "维护人",
    minWidth: 120,
    formatter: (row, column, cellValue) => {
      // å¦‚果用户映射表还没有准备好,显示 --
@@ -292,14 +295,18 @@
]);
// coalQualityMaintenance ç…¤è´¨ç»´æŠ¤æ•°æ®
const coalQualityMaintenanceColumns = ref([
  { prop: "supplierName", label: "全水(<)", minWidth: 200 },
  { prop: "identifyNumber", label: "水分析(<)", minWidth: 120 },
  { prop: "address", label: "灰分", minWidth: 150 },
  { prop: "bank", label: "挥发(>)", minWidth: 100 },
  { prop: "bankAccount", label: "ç¡«(<)", minWidth: 100 },
  { prop: "contacts", label: "固定碳", minWidth: 100 },
  { prop: "coal", label: "煤种名称", minWidth: 200 },
  { prop: "totalMoisture", label: "全水含量百分比 (%)", minWidth: 200 },
  { prop: "analysisMoisture", label: "分析水含量百分比 (%)", minWidth: 200 },
  { prop: "volatileMatter", label: "挥发分百分比 (%)", minWidth: 100 },
  { prop: "sulfurContent", label: "硫含量百分比 (%)", minWidth: 100 },
  { prop: "contacts", label: "固定碳百分比 (%)", minWidth: 100 },
  { prop: "contactAddress", label: "高位发热量", minWidth: 100 },
  { prop: "maintainer", label: "低位发热量", minWidth: 100 },
]);
const coalMeiZhiZiDuanWeiHuColumns = ref([
  { prop: "fieldName", label: "字段名称", minWidth: 200 },
  { prop: "fieldDescription", label: "字段描述", minWidth: 200 },
]);
// æ ‡ç­¾é¡µç‚¹å‡»
const handleTabClick = (tab) => {
@@ -318,7 +325,6 @@
      columns.value = customerColumns.value;
      dialogFormVisible.value = customerDialogFormVisible.value;
      getList("customer");
      break;
    case "coal":
      columns.value = coalColumns.value;
@@ -329,6 +335,11 @@
      columns.value = coalQualityMaintenanceColumns.value;
      dialogFormVisible.value = coalQualityMaintenanceDialogFormVisible.value;
      getList("coalQualityMaintenance");
      break;
    case "coalMeiZhiZiDuanWeiHu":
      columns.value = coalMeiZhiZiDuanWeiHuColumns.value;
      dialogFormVisible.value = coalMaintenanceFieldDialogVisible.value;
      getList("coalMeiZhiZiDuanWeiHu");
      break;
  }
};
@@ -363,7 +374,11 @@
    openDialog();
  } else if (tabName === "coalQualityMaintenance") {
    dialogFormVisible.value = true;
    title.value = title.value + "煤质维护";
    title.value = title.value + "煤质方案维护";
    openDialog();
  } else if (tabName === "coalMeiZhiZiDuanWeiHu") {
    dialogFormVisible.value = true;
    title.value = title.value + "煤质字段维护";
    openDialog();
  }
};
@@ -403,28 +418,28 @@
// ç¼–辑
const handleEdit = (row) => {
  form.value = JSON.parse(JSON.stringify(row));
  if(form.value.bprovinceId && form.value.bdistrictId && form.value.bcityId  ){
  if (form.value.bprovinceId && form.value.bdistrictId && form.value.bcityId) {
    form.value.bids = [
    row.bprovinceId,
    row.bcityId,
    row.bdistrictId,
  ];
      row.bprovinceId,
      row.bcityId,
      row.bdistrictId,
    ];
  }
   if(form.value.cprovinceId && form.value.cdistrictId && form.value.ccityId  ){
  if (form.value.cprovinceId && form.value.cdistrictId && form.value.ccityId) {
    form.value.cids = [
    row.cprovinceId,
    row.ccityId,
    row.cdistrictId,
  ];
      row.cprovinceId,
      row.ccityId,
      row.cdistrictId,
    ];
  }
  if(form.value.businessCityId && form.value.businessDistrictId && form.value.businessProvinceId) {
  if (form.value.businessCityId && form.value.businessDistrictId && form.value.businessProvinceId) {
    form.value.bids = [
      row.businessProvinceId,
      row.businessCityId,
      row.businessDistrictId,
    ];
  }
  if(form.value.cityId && form.value.districtId && form.value.provinceId) {
  if (form.value.cityId && form.value.districtId && form.value.provinceId) {
    form.value.cids = [
      row.provinceId,
      row.cityId,
@@ -452,21 +467,21 @@
    .then(async () => {
      try {
        let res;
        if( tabName.value === "supplier" ) {
        if (tabName.value === "supplier") {
          res = await delSupply(arr);
        } else if (tabName.value === "coal") {
          res = await delCoalInfo(arr);
        } else if (tabName.value === "coalQualityMaintenance") {
          res = await delCoalQuality(arr);
        } else if( tabName.value === "customer") {
        } else if (tabName.value === "customer") {
          res = await delCustomer(arr);
        }
        if(res.code !== 200 && res.meg == "操作成功") {
        if (res.code !== 200 && res.meg == "操作成功") {
          ElMessage.error("删除失败:" + res.msg);
          return;
        }
        ElMessage.success("删除成功");
        await getList();
        await getList();
      } catch (e) {
        console.error(e);
        ElMessage.error("删除失败,请稍后再试");
@@ -483,7 +498,7 @@
  form.value = {};
};
const handleExport = () => {
  if(tabName.value === "supplier") {
  if (tabName.value === "supplier") {
    Export("/supply/export", "供应商信息");
  } else if (tabName.value === "customer") {
    Export("/customer/export", "客户信息");
@@ -494,7 +509,7 @@
  }
}
const Export = (api,name) => {
const Export = (api, name) => {
  proxy.download(api, {
    ...queryParams.value
  }, `${name}${new Date().getTime()}.xlsx`)
@@ -526,6 +541,23 @@
      pageSize: pageSizes.value,
      searchAll: queryParams.searchAll,
    });
  } else if (tabName.value === "coalMeiZhiZiDuanWeiHu") {
    return {
      code: 200,
          data: {
          records: [
            { fieldName: "字段1", fieldDescription: "描述1" },
            { fieldName: "字段2", fieldDescription: "描述2" },
            { fieldName: "字段3", fieldDescription: "描述3" }
          ],
            total: 10
        }
    };
    // return getCoalQuality({
    //   current: pageNum.value,
    //   pageSize: pageSizes.value,
    //   searchAll: queryParams.searchAll,
    // });
  }
}
const search = () => {
@@ -539,7 +571,8 @@
    await fetchAreaOptions();
  } */
  let { data, code } = await selectInterface()
  if(code !== 200) {
  console.log("获取数据:", code, data);
  if (code !== 200) {
    ElMessage.error("获取数据失败:" + data.msg);
    loading.value = false;
    return;
src/views/basicInformation/mould/coalMeiZhiZiDuanWeiHu.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,101 @@
<template>
  <div>
    <el-dialog
      v-model="dialogVisible"
      :title="title"
      width="600"
      :close-on-click-modal="false"
      :before-close="handleClose"
    >
      <el-form
        ref="formRef"
        style="max-width: 400px; margin: 0 auto"
        :model="formData"
        :rules="rules"
        label-width="auto"
      >
        <el-form-item label="字段名称" prop="fieldName">
          <el-input
            v-model="formData.fieldName"
            placeholder="请输入字段名称"
          />
        </el-form-item>
        <el-form-item label="Activity form" props="dielDescription">
      <el-input v-model="formData.fieldDescription" type="textarea" placeholder="请输入字段描述" />
    </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm"> ç¡®å®š </el-button>
          <el-button v-if="addOrEdit === 'edit'" @click="resetForm"
            >重置</el-button
          >
          <el-button v-if="addOrEdit === 'add'" @click="cancelForm"
            >取消</el-button
          >
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, watch, defineProps, onMounted } from "vue";
import addressList from "@/api/jsonApi/areaList.json";
const props = defineProps({
  beforeClose: {
    type: Function,
    default: () => {},
  },
  form: {
    type: Object,
    default: () => ({}),
  },
  addOrEdit: {
    type: String,
    default: "add",
  },
  title: {
    type: String,
    default: "",
  },
});
const emit = defineEmits(["submit", "handleBeforeClose"]);
// è¡¨å•数据
const formData = ref({ ...props.form });
// å¼¹çª—可见性
const dialogVisible = defineModel("coalMaintenanceFieldDialogVisible", {
  required: true,
  type: Boolean,
});
// æäº¤è¡¨å•
const submitForm = async () => {
  if (!formRef.value) return;
  await formRef.value.validate(async (valid, fields) => {
    if (valid) {
    }
  });
};
// å–消表单
const cancelForm = () => {
  emit("update:coalMaintenanceFieldDialogVisible", false);
  formData.value = {};
};
// é‡ç½®è¡¨å•
const resetForm = () => {
};
// å…³é—­å¼¹çª—
const handleClose = () => {
  // è§¦å‘父组件的关闭函数
  emit("handleBeforeClose");
  emit("update:coalMaintenanceFieldDialogVisible", false);
};
const rules = reactive({
  coal: [
    { required: true, message: "请输入煤种名称", trigger: "blur" },
  ],
});
</script>
<style lang="sass" scoped>
</style>
src/views/basicInformation/mould/coalQualityMaintenance.vue
@@ -1,75 +1,31 @@
<template>
  <div>
    <el-dialog
      v-model="dialogVisible"
      :title="title"
      width="600"
      :close-on-click-modal="false"
      :before-close="handleClose"
    >
      <el-form
        ref="formRef"
        style="max-width: 400px; margin: 0 auto"
        :model="formData"
        :rules="rules"
        label-width="auto"
      >
        <el-form-item label="煤种类型" prop="coal">
          <el-input
            v-model="formData.coal"
            placeholder="请输入供货商名称"
          />
    <el-dialog v-model="dialogVisible" :title="title" width="600" :close-on-click-modal="false"
      :before-close="handleClose">
      <el-form ref="formRef" style="max-width: 400px; margin: 0 auto" :model="formData" :rules="rules"
        label-width="auto">
        <el-form-item label="方案名称" prop="schemeName">
          <el-input v-model="formData.schemeName" placeholder="请输入方案名称"  prop="schemeName" />
        </el-form-item>
        <el-form-item label="全水含量百分比 (%)" prop="totalMoisture">
          <el-input
            v-model="formData.totalMoisture"
            placeholder="请输入全水含量百分比"
          />
        <el-form-item label="方案类型" props="fieldName">
          <el-select v-model="formData.fieldName" placeholder="Select" style="width: 240px" clearable multiple>
            <template #label="{ label }">
              <span>{{ label }}: </span>
              <span style="font-weight: bold">{{ value }}</span>
            </template>
            <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="全水含量百分比 (%)" prop="analysisMoisture">
          <el-input
            v-model="formData.analysisMoisture"
            placeholder="请输入全水含量百分比"
          />
        </el-form-item>
        <el-form-item label="全水含量百分比 (%)" prop="volatileMatter">
          <el-input
            v-model="formData.volatileMatter"
            placeholder="请输入全水含量百分比"
          />
        </el-form-item>
        <el-form-item label="固定碳百分比 (%)" prop="fixedCarbon">
          <el-input
            v-model="formData.fixedCarbon"
            placeholder="请输入客户详细地址"
          />
        </el-form-item>
        <el-form-item label="低位发热量(单位:千卡/千克)" prop="lowerHeatValue">
          <el-input
            v-model="formData.lowerHeatValue"
            placeholder="请输入银行账户"
          />
        </el-form-item>
        <el-form-item label="高位发热量(单位:千卡/千克)" prop="higherHeatValue">
          <el-input v-model="formData.higherHeatValue" placeholder="请输入开户行" />
        </el-form-item>
        <el-form-item label="灰分百分比 (%)" prop="ashContent">
          <el-input v-model="formData.ashContent" placeholder="请输入联系人" />
        </el-form-item>
        <el-form-item label="硫含量百分比 (%)" prop="sulfurContent">
          <el-input
            v-model="formData.sulfurContent"
            placeholder="请输入联系人电话"
          />
        </el-form-item>
        <template #footer>
          <el-form-item label="字段描述" prop="fieldDescription">
            <el-input v-model="formData.fieldDescription" type="textarea" placeholder="请输入字段描述" />
          </el-form-item>
        </template>
        <el-form-item>
          <el-button type="primary" @click="submitForm"> ç¡®å®š </el-button>
          <el-button v-if="addOrEdit === 'edit'" @click="resetForm"
            >重置</el-button
          >
          <el-button v-if="addOrEdit === 'add'" @click="cancelForm"
            >取消</el-button
          >
          <el-button v-if="addOrEdit === 'edit'" @click="resetForm">重置</el-button>
          <el-button v-if="addOrEdit === 'add'" @click="cancelForm">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
@@ -79,11 +35,10 @@
<script setup>
import { ref, watch, defineProps, onMounted } from "vue";
import addressList from "@/api/jsonApi/areaList.json";
import { addOrEditCoalQuality } from "@/api/basicInformation/coalQualityMaintenance.js";
const props = defineProps({
  beforeClose: {
    type: Function,
    default: () => {},
    default: () => { },
  },
  form: {
    type: Object,
@@ -98,24 +53,30 @@
    default: "",
  },
});
const options = [
  {
    value: 'Option1',
    label: 'Label1',
  },
  {
    value: 'Option2',
    label: 'Label2',
  },
  {
    value: 'Option3',
    label: 'Label3',
  },
  {
    value: 'Option4',
    label: 'Label4',
  },
  {
    value: 'Option5',
    label: 'Label5',
  },
]
const emit = defineEmits(["submit", "handleBeforeClose"]);
onMounted(()=>{
  addressSelectOptions.value = mapAddress(addressList);
})
// åœ°å€é€‰æ‹©æ•°æ®
const addressSelectOptions = ref([]);
// å¤„理地址数据转换
function mapAddress(list) {
  return list.map(item => ({
    value: item.no,
    label: item.name,
    children: item.children ? mapAddress(item.children) : undefined
  }));
}
// è¡¨å•引用
const formRef = ref(null);
// è¡¨å•数据
const formData = ref({ ...props.form });
// å¼¹çª—可见性
@@ -123,34 +84,13 @@
  required: true,
  type: Boolean,
});
// ç›‘听外部传入的表单数据变化
watch(
  () => props.form,
  (newVal) => {
    formData.value = { ...newVal };
  },
  { deep: true }
);
// ç›‘听内部弹窗状态变化
watch(
  () => dialogVisible.value,
  (newVal) => {
    emit("update:coalQualityMaintenanceDialogFormVisible", newVal);
  }
);
// å¤„理地址选择变化
const handleChange = (value) => {
  console.log(value);
};
// æäº¤è¡¨å•
const submitForm = async () => {
  if (!formRef.value) return;
  await formRef.value.validate(async (valid, fields) => {
    if (valid) {
      let result = await addOrEditCoalQuality({...formData.value});
      console.log(result);
      // let result = await addOrEditCoalQuality({...formData.value});
      // console.log(result);
      // emit("submit", formData.value);
    }
  });
src/views/procureMent/components/ProductionDialog.vue
@@ -20,44 +20,61 @@
          <el-input v-model="form.supplierName" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="煤种" prop="coal">
          <el-input v-model="form.coal" placeholder="请输入" />
        </el-form-item>
            <el-select v-model="form.coal" placeholder="请选择煤种" clearable style="width: 100%">
              <el-option label="瘦煤" value="瘦煤" />
              <el-option label="气煤" value="气煤" />
              <el-option label="无烟煤" value="无烟煤" />
              <el-option label="长焰煤" value="长焰煤" />
              <el-option label="贫煤" value="贫煤" />
            </el-select>
          </el-form-item>
        <el-form-item label="单位" prop="unit">
          <el-input v-model="form.unit" placeholder="请输入" />
          <el-select v-model="form.unit" placeholder="请选择单位" clearable style="width: 100%">
              <el-option label="吨" value="吨" />
              <el-option label="千克" value="千克" />
            </el-select>
        </el-form-item>
        <el-form-item label="采购数量" prop="purchaseQuantity">
          <el-input v-model="form.purchaseQuantity" placeholder="请输入"  />
          <el-input v-model.number="form.purchaseQuantity" placeholder="请输入"  >
            <template v-slot:suffix>
            <i style="font-style:normal;">{{form.unit?form.unit:''}}</i>
          </template>
          </el-input>
        </el-form-item>
        <el-form-item label="单价(不含税)" prop="priceExcludingTax">
          <el-input v-model="form.priceExcludingTax" placeholder="请输入" >
          <el-input v-model.number="form.priceExcludingTax" placeholder="请输入" >
            <template v-slot:suffix>
            <i style="font-style:normal;">元</i>
          </template>
          </el-input>
        </el-form-item>
        <el-form-item label="总价(不含税)" prop="totalPriceExcludingTax">
          <el-input v-model="form.totalPriceExcludingTax" placeholder="请输入" >
          <el-input v-model.number="form.totalPriceExcludingTax" placeholder="请输入" >
            <template v-slot:suffix>
            <i style="font-style:normal;">元</i>
          </template>
          </el-input>
        </el-form-item>
        <el-form-item label="单价(含税)" prop="priceIncludingTax">
          <el-input v-model="form.priceIncludingTax" placeholder="请输入" >
          <el-input v-model.number="form.priceIncludingTax" placeholder="请输入" >
            <template v-slot:suffix>
            <i style="font-style:normal;">元</i>
          </template>
          </el-input>
        </el-form-item>
        <el-form-item label="总价(含税)" prop="totalPriceIncludingTax">
          <el-input v-model="form.totalPriceIncludingTax" placeholder="请输入" >
          <el-input v-model.number="form.totalPriceIncludingTax" placeholder="请输入" >
            <template v-slot:suffix>
            <i style="font-style:normal;">元</i>
          </template>
          </el-input>
        </el-form-item>
        <el-form-item label="税率" prop="taxRate">
          <el-input v-model="form.taxRate" placeholder="请输入" />
          <el-input v-model="form.taxRate" placeholder="请输入税率" >
            <template v-slot:suffix>
            <i style="font-style:normal;">%</i>
          </template>
            </el-input>
        </el-form-item>
        <el-form-item label="登记人" prop="registrantId">
          <el-input v-model="form.registrantId" disabled placeholder="请输入" />
@@ -131,6 +148,7 @@
  unit: [{ required: true, message: "请输入单位", trigger: "blur" }],
  purchaseQuantity: [
    { required: true, message: "请输入采购数量", trigger: "blur" },
    { type: "number", message: "采购数量必须为数字", trigger: "blur" },
  ],
  priceExcludingTax: [{ required: true, message: "请输入单价", trigger: "blur" }],
  totalPriceExcludingTax: [{ required: true, message: "请输入总价", trigger: "blur" }],
@@ -154,7 +172,6 @@
  if (formRef.value) {
    formRef.value.clearValidate();
  }
  console.log(form.value);
};
const formRef = ref(null);
// æäº¤è¡¨å•
@@ -162,7 +179,6 @@
  if (!formRef.value) return;
  await formRef.value.validate(async (valid) => {
    if (valid) {
      console.log("表单验证通过", form.value);
      const obj = ref({});
      if (props.title.includes('新增')) {
        let result = await addOrEditPR({
src/views/procureMent/index.vue
@@ -23,7 +23,7 @@
      <el-row :gutter="24" class="table-toolbar">
        <el-button type="primary" :icon="Plus" @click="handleAdd">新建</el-button>
        <el-button type="danger" :icon="Delete" @click="handleDelete">删除</el-button>
        <el-button type="info" :icon="Download" @click="handleExport">导出</el-button>
        <!-- <el-button type="info" :icon="Download" @click="handleExport">导出</el-button> -->
      </el-row>
      <!-- è¡¨æ ¼ç»„ä»¶ -->
      <data-table :loading="loading" :table-data="tableData" :columns="columns" @selection-change="handleSelectionChange"
@@ -76,9 +76,11 @@
  getList();
};
const userStore = useUserStore();
// èŽ·å–ç”¨æˆ·ä¿¡æ¯
const userInfo = ref({});
onMounted(async() => {
  let res = await userStore.getInfo()
  form.value.registrantId = res.user.userName; // è®¾ç½®ç™»è®°äººID
  userInfo.value = res.user;
});
// åˆ†é¡µå¤„理
const handlePagination = (val) => {
@@ -141,7 +143,7 @@
    priceIncludingTax: "",
    totalPriceIncludingTax: "",
    taxRate: "",
    registrantId: "",
    registrantId: userInfo.value.userName,
    registrationDate: new Date().toISOString().split('T')[0]
  };
  // æ–°å»ºæ—¶ä¹Ÿéœ€è¦è®¾ç½® copyForm ç”¨äºŽé‡ç½®åŠŸèƒ½
src/views/production/components/ProductionDetailsTable.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,222 @@
<template>
  <el-table :data="tableData" :border="border" style="width: 100%">
    <el-table-column label="煤种" min-width="120">
      <template #default="{ row, $index }">
        <el-input
          v-model="row.coalType"
          placeholder="请输入煤种"
          @input="handleInput('coalType', $index, $event)"
        />
      </template>
    </el-table-column>
    <el-table-column label="热值" min-width="120">
      <template #default="{ row, $index }">
        <el-input
          v-model="row.calorificValue"
          placeholder="请输入热值"
          @input="handleInput('calorificValue', $index, $event)"
        />
      </template>
    </el-table-column>
    <el-table-column label="生产数量" min-width="120">
      <template #default="{ row, $index }">
        <el-input
          v-model="row.productionQuantity"
          placeholder="请输入生产数量"
          type="number"
          @input="handleInput('productionQuantity', $index, $event)"
        />
      </template>
    </el-table-column>
    <el-table-column label="人工成本" min-width="120">
      <template #default="{ row, $index }">
        <el-input
          v-model="row.laborCost"
          placeholder="请输入人工成本"
          type="number"
          @input="handleInput('laborCost', $index, $event)"
        >
          <template #suffix>
            <i style="font-style:normal;">元</i>
          </template>
        </el-input>
      </template>
    </el-table-column>
    <el-table-column label="能耗成本" min-width="120">
      <template #default="{ row, $index }">
        <el-input
          v-model="row.energyCost"
          placeholder="请输入能耗成本"
          type="number"
          @input="handleInput('energyCost', $index, $event)"
        >
          <template #suffix>
            <i style="font-style:normal;">元</i>
          </template>
        </el-input>
      </template>
    </el-table-column>
    <el-table-column label="设备折旧" min-width="120">
      <template #default="{ row, $index }">
        <el-input
          v-model="row.equipmentDepreciation"
          placeholder="请输入设备折旧"
          type="number"
          @input="handleInput('equipmentDepreciation', $index, $event)"
        >
          <template #suffix>
            <i style="font-style:normal;">元</i>
          </template>
        </el-input>
      </template>
    </el-table-column>
    <el-table-column label="采购单价" min-width="120">
      <template #default="{ row, $index }">
        <el-input
          v-model="row.purchasePrice"
          placeholder="请输入采购单价"
          type="number"
          @input="handleInput('purchasePrice', $index, $event)"
        >
          <template #suffix>
            <i style="font-style:normal;">元</i>
          </template>
        </el-input>
      </template>
    </el-table-column>
    <el-table-column label="总成本" min-width="120">
      <template #default="{ row, $index }">
        <el-input
          v-model="row.totalCost"
          placeholder="总成本"
          type="number"
          :readonly="autoCalculate"
          @input="handleInput('totalCost', $index, $event)"
        >
          <template #suffix>
            <i style="font-style:normal;">元</i>
          </template>
        </el-input>
      </template>
    </el-table-column>
      <el-table-column v-if="showOperations" label="操作" width="120" fixed="right">
      <template #default="{ $index }">
        <el-button
          type="danger"
          size="small"
          @click="handleDelete($index)"
          :icon="Delete"
        >
          åˆ é™¤
        </el-button>
      </template>
    </el-table-column>
  </el-table>
</template>
<script setup name="ProductionDetailsTable">
import { ref, computed, watch } from 'vue'
import { Delete } from '@element-plus/icons-vue'
const props = defineProps({
  modelValue: {
    type: Array,
    default: () => []
  },
  border: {
    type: Boolean,
    default: false
  },
  showOperations: {
    type: Boolean,
    default: true
  },
  autoCalculate: {
    type: Boolean,
    default: true
  }
})
const emit = defineEmits(['update:modelValue', 'input-change', 'delete-row'])
// ä½¿ç”¨ v-model è¿›è¡ŒåŒå‘绑定
const tableData = computed({
  get() {
    return props.modelValue
  },
  set(value) {
    emit('update:modelValue', value)
  }
})
// å¤„理输入变化
const handleInput = (field, index, value) => {
  const newData = [...tableData.value]
  newData[index][field] = value
  // å¦‚果开启自动计算总成本
  if (props.autoCalculate && ['laborCost', 'energyCost', 'equipmentDepreciation', 'purchasePrice'].includes(field)) {
    calculateTotalCost(newData[index])
  }
  tableData.value = newData
  emit('input-change', { field, index, value, row: newData[index] })
}
// è®¡ç®—总成本
const calculateTotalCost = (row) => {
  const laborCost = parseFloat(row.laborCost) || 0
  const energyCost = parseFloat(row.energyCost) || 0
  const equipmentDepreciation = parseFloat(row.equipmentDepreciation) || 0
  const purchasePrice = parseFloat(row.purchasePrice) || 0
  row.totalCost = (laborCost + energyCost + equipmentDepreciation + purchasePrice).toFixed(2)
}
// åˆ é™¤è¡Œ
const handleDelete = (index) => {
  const newData = [...tableData.value]
  newData.splice(index, 1)
  tableData.value = newData
  emit('delete-row', index)
}
// æš´éœ²æ–¹æ³•给父组件使用
defineExpose({
  calculateTotalCost,
  addRow: (rowData = {}) => {
    const defaultRow = {
      coalType: '',
      calorificValue: '',
      productionQuantity: '',
      laborCost: '',
      energyCost: '',
      equipmentDepreciation: '',
      purchasePrice: '',
      totalCost: '',
      ...rowData
    }
    tableData.value = [...tableData.value, defaultRow]
  },
  clearData: () => {
    tableData.value = []
  }
})
</script>
<style scoped>
:deep(.el-input__inner) {
  text-align: center;
}
:deep(.el-table .el-table__cell) {
  padding: 8px 0;
}
</style>
src/views/production/components/ProductionDetailsTableExample.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,88 @@
<!-- ä½¿ç”¨ç¤ºä¾‹ -->
<template>
  <div>
    <!-- åŸºæœ¬ä½¿ç”¨ -->
    <ProductionDetailsTable v-model="tableData" />
    <!-- è‡ªå®šä¹‰é…ç½® -->
    <ProductionDetailsTable
      v-model="tableData"
      :border="true"
      :show-operations="false"
      :auto-calculate="false"
      @input-change="handleChange"
      @delete-row="handleDelete"
    />
    <!-- æ“ä½œæŒ‰é’® -->
    <el-row :gutter="10" style="margin-top: 20px;">
      <el-col :span="4">
        <el-button type="primary" @click="addRow">新增行</el-button>
      </el-col>
      <el-col :span="4">
        <el-button type="danger" @click="clearData">清空数据</el-button>
      </el-col>
      <el-col :span="4">
        <el-button type="success" @click="submitData">提交数据</el-button>
      </el-col>
    </el-row>
  </div>
</template>
<script setup>
import { ref } from 'vue'
import ProductionDetailsTable from './ProductionDetailsTable.vue'
// è¡¨æ ¼æ•°æ®
const tableData = ref([
  {
    coalType: '动力煤',
    calorificValue: '5000',
    productionQuantity: '100',
    laborCost: '1000',
    energyCost: '800',
    equipmentDepreciation: '500',
    purchasePrice: '2000',
    totalCost: '4300'
  }
])
// èŽ·å–ç»„ä»¶å®žä¾‹å¼•ç”¨
const tableRef = ref(null)
// äº‹ä»¶å¤„理
const handleChange = (data) => {
  console.log('数据变化:', data)
}
const handleDelete = (index) => {
  console.log('删除行:', index)
}
// æ“ä½œæ–¹æ³•
const addRow = () => {
  if (tableRef.value) {
    tableRef.value.addRow({
      coalType: '新煤种',
      calorificValue: '0',
      productionQuantity: '0',
      laborCost: '0',
      energyCost: '0',
      equipmentDepreciation: '0',
      purchasePrice: '0',
      totalCost: '0'
    })
  }
}
const clearData = () => {
  if (tableRef.value) {
    tableRef.value.clearData()
  }
}
const submitData = () => {
  console.log('提交的数据:', tableData.value)
  // è¿™é‡Œå¯ä»¥è°ƒç”¨API提交数据
}
</script>
src/views/production/components/ProductionDialog.vue
@@ -1,107 +1,162 @@
<template>
  <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '新增生产加工' : '编辑生产加工'" width="1200px"
    :close-on-click-modal="false" @close="handleClose">
    <el-form ref="formRef" :model="formData" :rules="rules" class="production-form">
      <el-row :gutter="24">
        <el-col :span="6">
          <el-form-item label="煤种" prop="category">
            <el-select v-model="formData.category" placeholder="请选择煤种" clearable style="width: 100%" @change="selectChange">
              <el-option label="炼焦" value="炼焦" />
              <el-option label="气煤" value="气煤" />
              <el-option label="无烟煤" value="无烟煤" />
              <el-option label="长焰煤" value="长焰煤" />
              <el-option label="贫煤" value="贫煤" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="热值" prop="Calorific">
            <el-input v-model="formData.Calorific" placeholder="请输入热值" clearable />
          </el-form-item>
        </el-col>
        <el-col :span="4" :offset="8">
          <el-button type="primary" @click="search">查询</el-button>
          <el-button @click="reset">重置</el-button>
        </el-col>
      </el-row>
    </el-form>
    <ETable :columns="columns" height="200" @cell-edit="handleCellEdit" :showOperations="false" :tableData="tableData" @row-click="handleRowClick" :editableColumns="['used']" />
    <el-row :gutter="10">
        <el-col :span="4">
          <h1>生产明细</h1>
        </el-col>
  <el-dialog
    v-model="dialogVisible"
    :title="dialogType === 'add' ? '新增生产加工' : '编辑生产加工'"
    width="1200px"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <el-button type="primary" @click="handlData">选择数据</el-button>
    <ETable
      v-if="tableData.length > 0"
      :columns="columns"
      height="200"
      @cell-edit="handleCellEdit"
      :showOperations="false"
      :tableData="tableData"
      @row-click="handleRowClick"
      :editableColumns="['used']"
    />
    <div v-if="tableData.length > 0" class="empty-table">
    <h1>生产明细</h1>
      <el-row :gutter="10">
      <el-col :span="2">
        <el-button type="primary" @click="addNewRow">
          <el-icon>
            <Plus />
          </el-icon>
          æ–°å¢ž
        </el-button>
      </el-col>
      <el-col :span="2">
        <el-button type="danger" @click="clearAllRows">
          <el-icon>
            <Delete />
          </el-icon>
          æ¸…空
        </el-button>
      </el-col>
      <!-- <el-col :span="2">
        <el-button type="warning" @click="calculateAllCosts">
          <el-icon>
            <Warning />
          </el-icon> é‡æ–°è®¡ç®—
        </el-button>
      </el-col> -->
    </el-row>
    <el-row :gutter="10">
        <el-col :span="2">
          <el-button type="primary">
            <el-icon><Plus /></el-icon> æ–°å¢ž
          </el-button>
        </el-col>
        <el-col :span="2"><el-button type="danger">
            <el-icon><Delete /></el-icon> åˆ é™¤
          </el-button></el-col>
        <el-col :span="2">
          <el-button type="warning">
            <el-icon><Warning /></el-icon> ä¿®æ”¹
          </el-button>
        </el-col>
    </el-row>
    <ProductionDetailsTable
      v-model="detailsTableData"
      :border="false"
      :show-operations="true"
      :auto-calculate="true"
      @input-change="handleDetailsChange"
      @delete-row="handleDeleteRow"
    />
    </div>
      <div style="margin-top: 20px;" v-else>暂无数据,请选择配置数据</div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取 æ¶ˆ</el-button>
        <el-button type="primary" :loading="loading" @click="handleSubmit">ç¡® å®š</el-button>
        <el-button type="primary" :loading="loading" @click="handleSubmit"
          >ç¡® å®š</el-button
        >
      </div>
    </template>
  </el-dialog>
  <el-dialog
    v-model="innerVisible"
    width="1000"
    title="选择配置数据"
    append-to-body
  >
    <ETable
      @selection-change="handleSelectionChange"
      :showOperations="false"
      :columns="formalDatabaseDataColumns"
      :tableData="formalDatabaseData"
      height="400"
      @cell-edit="handleCellEdit"
      :show-selection="true"
    />
    <el-row :gutter="24">
      <el-col :span="2" :offset="22">
        <el-button type="primary" @click="handleSelectData">确定</el-button>
      </el-col>
    </el-row>
  </el-dialog>
</template>
<script setup>
import { ref, reactive, watch } from 'vue'
import ETable from '@/components/Table/ETable.vue'
import { ElMessage } from 'element-plus'
import { Delete, Warning } from '@element-plus/icons-vue'
import { ref, reactive, watch } from "vue";
import ETable from "@/components/Table/EtableModify.vue";
import ProductionDetailsTable from "./ProductionDetailsTable.vue";
import { ElMessage } from "element-plus";
import { Delete, Warning, Plus } from "@element-plus/icons-vue";
const props = defineProps({
  visible: {
    type: Boolean,
    default: false
    default: false,
  },
  type: {
    type: String,
    default: 'add' // 'add' æˆ– 'edit'
    default: "add", // 'add' æˆ– 'edit'
  },
  rowData: {
    type: Object,
    default: () => ({})
  }
})
const dialogVisible = defineModel('visible', {
    default: () => ({}),
  },
});
const dialogVisible = defineModel("visible", {
  type: Boolean,
  default: false
})
const emit = defineEmits(['update:visible', 'success'])
  default: false,
});
const emit = defineEmits(["update:visible", "success"]);
const dialogType = ref('add')
const loading = ref(false)
const formRef = ref(null)
const tableData = ref([])
const currentRow = ref(null)
const innerVisible = ref(false);
const dialogType = ref("add");
const loading = ref(false);
const formRef = ref(null);
const tableData = ref([]);
const currentRow = ref(null);
const columns = [
  { label: '煤种', prop: 'category' },
  { label: '热值', prop: 'Calorific' },
  { label: '库存数量', prop: 'stock' },
  { label: '本次使用数量', prop: 'used' },
]
  { label: "煤种", prop: "category" },
  { label: "热值", prop: "Calorific" },
  { label: "库存数量", prop: "stock" },
  { label: "本次使用数量", prop: "used" },
];
const detailsTableData = ref([
  {
    coalType: "",
    calorificValue: "",
    productionQuantity: "",
    laborCost: "",
    energyCost: "",
    equipmentDepreciation: "",
    purchasePrice: "",
    totalCost: "",
  },
]);
const handleRowClick = (row) => {
  currentRow.value = row
  console.log('当前行数据:', currentRow.value)
}
  currentRow.value = row;
};
const formalDatabaseDataColumns = ref([
  { prop: "name", label: "供应商名称", width: 150 },
  { prop: "type", label: "煤种类型", width: 120 },
  { prop: "unit", label: "单位", width: 100 },
  { prop: "number", label: "采购数量", width: 100 },
  { prop: "money", label: "单价(含税)", width: 120 },
  { prop: "money1", label: "总价(含税)", width: 120 },
  { prop: "money2", label: "税率", width: 80 },
  { prop: "money3", label: "不含税单价", width: 120 },
  { prop: "createUser", label: "登记人", width: 100 },
  { prop: "createTime", label: "登记日期", width: 150 },
]);
// è¡¨å•数据
const formData = reactive({
  category: '',
  unit: '',
  category: "",
  unit: "",
  productionVolume: 0,
  laborCost: 0,
  materialCost: 0,
@@ -109,68 +164,218 @@
  totalCost: 0,
  totalPrice: 0,
  profit: 0,
  reviewer: '',
  date: ''
})
  reviewer: "",
  date: "",
});
const handlData = () => {
  innerVisible.value = true;
};
const formalDatabaseData = ref([]);
const formalDatabaseSelectedData = ref([]);
formalDatabaseData.value = [
  {
    id: 1,
    name: "供应商A",
    type: "动力煤",
    unit: "吨",
    number: 120,
    money: 500,
    money1: 200,
    money2: 200,
    money3: 300,
    money4: "高位",
    createUser: "admin",
    createTime: "2025-06-01",
  },
  {
    id: 2,
    name: "供应商A",
    type: "动力煤",
    unit: "吨",
    number: 100,
    money: 600,
    money1: 300,
    money2: 300,
    money3: 300,
    money4: "低位",
    createUser: "admin",
    createTime: "2025-06-01",
  },
  {
    id: 3,
    name: "供应商B",
    type: "焦煤",
    unit: "吨",
    number: 300,
    money: 789,
    money1: 400,
    money2: 400,
    money3: 400,
    money4: "高位",
    createUser: "admin",
    createTime: "2025-06-01",
  },
  {
    id: 4,
    name: "供应商B",
    type: "焦煤",
    unit: "吨",
    number: 256,
    money: 800,
    money1: 420,
    money2: 420,
    money3: 420,
    money4: "低位",
    createUser: "admin",
    createTime: "2025-06-01",
  },
  {
    id: 5,
    name: "供应商C",
    type: "无烟煤",
    unit: "吨",
    number: 256,
    money: 700,
    money1: 300,
    money2: 300,
    money3: 300,
    money4: "高位",
    createUser: "admin",
    createTime: "2025-06-01",
  },
  {
    id: 6,
    name: "供应商A",
    type: "动力煤",
    unit: "吨",
    number: 120,
    money: 500,
    money1: 200,
    money2: 200,
    money3: 300,
    money4: "高位",
    createUser: "admin",
    createTime: "2025-06-01",
  },
  {
    id: 7,
    name: "供应商A",
    type: "动力煤",
    unit: "吨",
    number: 100,
    money: 600,
    money1: 300,
    money2: 300,
    money3: 300,
    money4: "低位",
    createUser: "admin",
    createTime: "2025-06-01",
  },
  {
    id: 8,
    name: "供应商B",
    type: "焦煤",
    unit: "吨",
    number: 300,
    money: 789,
    money1: 400,
    money2: 400,
    money3: 400,
    money4: "高位",
    createUser: "admin",
    createTime: "2025-06-01",
  },
  {
    id: 9,
    name: "供应商B",
    type: "焦煤",
    unit: "吨",
    number: 256,
    money: 800,
    money1: 420,
    money2: 420,
    money3: 420,
    money4: "低位",
    createUser: "admin",
    createTime: "2025-06-01",
  },
  {
    id: 10,
    name: "供应商C",
    type: "无烟煤",
    unit: "吨",
    number: 256,
    money: 700,
    money1: 300,
    money2: 300,
    money3: 300,
    money4: "高位",
    createUser: "admin",
    createTime: "2025-06-01",
  },
];
// è¡¨å•验证规则
const rules = {
  category: [{ required: true, message: '请选择煤种', trigger: 'change' }],
}
  category: [{ required: true, message: "请选择煤种", trigger: "change" }],
};
const search = () => {
  // æŸ¥è¯¢é€»è¾‘
  if (!formData.category) {
    return this.$message.error('请选择煤种')
// åˆå§‹åŒ–
const Initialization = () => {
  console.log("初始化数据");
  tableData.value = [];
};
defineExpose({
  Initialization
});
const handleSelectData = (row) => {
  if (!innerVisible.value) return;
  // èŽ·å–é€‰ä¸­çš„æ•°æ®
  const selectedData = formalDatabaseSelectedData.value;
  if (selectedData.length === 0) {
    ElMessage.warning("请至少选择一条数据");
    return;
  }
  loading.value = true
  // æ¨¡æ‹ŸæŸ¥è¯¢æ•°æ®
  setTimeout(() => {
    // å‡æ•°æ®
    tableData.value = [
      { category: '炼焦', Calorific: '6000', stock: 100, used: 20 },
      { category: '气煤', Calorific: '5500', stock: 80, used: 15 },
      { category: '气煤', Calorific: '5500', stock: 80, used: 15 },
      { category: '气煤', Calorific: '5500', stock: 80, used: 15 },
      { category: '气煤', Calorific: '5500', stock: 80, used: 15 },
      { category: '气煤', Calorific: '5500', stock: 80, used: 15 },
      { category: '气煤', Calorific: '5500', stock: 80, used: 15 },
      { category: '无烟煤', Calorific: '7000', stock: 120, used: 30 }
    ]
    loading.value = false
  }, 1000)
}
  // å°†é€‰ä¸­çš„æ•°æ®æ ¹æ®éœ€è¦ç­›é€‰åˆ°è¡¨æ ¼ä¸­
  selectedData.forEach((item) => {
    const existingItem = tableData.value.find(
      (row) => row.id === item.id
    );
    if (!existingItem) {
      tableData.value.push({
        id: item.id,
        category: item.type,
        Calorific: item.money4,
        stock: item.number,
        used: 0, // åˆå§‹ä½¿ç”¨æ•°é‡ä¸º0
      });
    }
  });
  innerVisible.value = false;
};
const handleSelectionChange = (selection) => {
  formalDatabaseSelectedData.value = selection;
};
const reset = () => {
  // formRef
  formRef.value?.resetFields()
}
  formRef.value?.resetFields();
};
const selectChange = (value) => {
}
const selectChange = (value) => {};
// æäº¤è¡¨å•
const handleSubmit = async () => {
  if (!formRef.value) return
  await formRef.value.validate((valid) => {
    if (valid) {
      loading.value = true
      // è§¦å‘成功事件,传递表单数据
      emit('success', { ...formData })
      loading.value = false
      handleClose()
    }
  })
}
  console.log(detailsTableData.value);
  // dialogVisible.value = false;
};
// å…³é—­å¼¹çª—
const handleClose = () => {
  dialogVisible.value = false
  formRef.value?.resetFields()
  dialogVisible.value = false;
  formRef.value?.resetFields();
  Object.assign(formData, {
    category: '',
    unit: '',
    category: "",
    unit: "",
    productionVolume: 0,
    laborCost: 0,
    materialCost: 0,
@@ -178,32 +383,73 @@
    totalCost: 0,
    totalPrice: 0,
    profit: 0,
    reviewer: '',
    date: ''
  })
}
    reviewer: "",
    date: "",
  });
};
// æ·»åŠ å•å…ƒæ ¼ç¼–è¾‘å¤„ç†å‡½æ•°
const handleCellEdit = (row, prop, value) => {
  console.log('单元格编辑:',  prop)
  // console.log('单元格编辑完成:', row, prop, value)
  // è¿™é‡Œå¯ä»¥æ·»åŠ éªŒè¯é€»è¾‘ï¼Œä¾‹å¦‚æ£€æŸ¥ä½¿ç”¨é‡æ˜¯å¦å¤§äºŽåº“å­˜
  if (prop === 'used' && Number(value) > Number(row.stock)) {
    ElMessage.warning('使用数量不能大于库存数量!')
    // å¯ä»¥åœ¨è¿™é‡Œé‡ç½®å€¼
    row.used = row.stock
  if (prop === "used" && Number(value) > Number(row.stock)) {
    ElMessage.warning("使用数量不能大于库存数量!");
    row.used = row.stock;
  }
}
};
// å¤„理生产明细表格的操作
const addNewRow = () => {
  detailsTableData.value.push({
    coalType: "",
    calorificValue: "",
    productionQuantity: "",
    laborCost: "",
    energyCost: "",
    equipmentDepreciation: "",
    purchasePrice: "",
    totalCost: "",
  });
};
const clearAllRows = () => {
  detailsTableData.value = [];
  ElMessage.success("已清空所有数据");
};
const calculateAllCosts = () => {
  detailsTableData.value.forEach((row) => {
    const laborCost = parseFloat(row.laborCost) || 0;
    const energyCost = parseFloat(row.energyCost) || 0;
    const equipmentDepreciation = parseFloat(row.equipmentDepreciation) || 0;
    const purchasePrice = parseFloat(row.purchasePrice) || 0;
    row.totalCost = (
      laborCost +
      energyCost +
      equipmentDepreciation +
      purchasePrice
    ).toFixed(2);
  });
  ElMessage.success("重新计算完成");
};
const handleDetailsChange = (data) => {
  console.log("生产明细数据变化:", data);
};
const handleDeleteRow = (index) => {
  ElMessage.success(`已删除第 ${index + 1} è¡Œæ•°æ®`);
};
</script>
<style scoped lang="scss">
.el-form{
<style scoped lang="scss">
.el-form {
  .el-row {
    padding-top: 20px;
    background: rgba($color: #F8FAFB, $alpha: 0.5) ;
    background: rgba($color: #f8fafb, $alpha: 0.5);
  }
}
.el-row>.el-col>h1{
.el-row > .el-col > h1 {
  font-weight: bolder;
}
</style>
</style>
src/views/production/components/SupplierDialog.vue
ÎļþÒÑɾ³ý
src/views/production/index.vue
@@ -1,274 +1,294 @@
<template>
  <div class="production-container">
    <div class="search-bar">
      <el-input v-model="searchForm.keyword" placeholder="请输入关键词" clearable />
      <el-input v-model="searchForm.addUser" placeholder="请输入人" clearable />
      <el-button type="primary" @click="handleSearch">查询</el-button>
      <el-button @click="handleReset">重置</el-button>
    </div>
    <div class="operation-bar">
      <!-- <el-button type="primary" @click="handleAdd">新增配项</el-button> -->
        <el-form :inline="true" :model="searchForm" class="search-form" style="width: 100%">
          <el-form-item label="搜索">
            <el-input v-model="searchForm.searchAll" placeholder="请输入关键词" clearable />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch">查询</el-button>
            <el-button @click="handleReset">重置</el-button>
          </el-form-item>
        </el-form>
    <el-card>
      <el-button type="success" :icon="Plus" @click="handleAddBatch">新增加工</el-button>
      <el-button type="danger" :icon="Delete">删除</el-button>
      <el-button type="info" :icon="Download">导出</el-button>
    </div>
    <el-table :data="tableData" border style="width: 100%" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" />
      <el-table-column prop="sequence" label="序号" width="80" />
      <el-table-column prop="category" label="煤种" width="120" />
      <el-table-column prop="unit" label="单位" width="100" />
      <el-table-column prop="productionVolume" label="生产数量" width="120" />
      <el-table-column prop="laborCost" label="人工成本" width="120" />
      <el-table-column prop="materialCost" label="原料成本" width="120" />
      <el-table-column prop="equipmentCost" label="设备费用" width="120" />
      <el-table-column prop="totalCost" label="总成本" width="120" />
      <el-table-column prop="totalPrice" label="总成本" width="120" />
      <el-table-column prop="profit" label="利润" width="100" />
      <el-table-column prop="reviewer" label="复记人" width="120" />
      <el-table-column prop="date" label="日期" width="120" />
      <el-table-column label="操作" fixed="right" width="220">
        <template #default="scope">
          <el-button type="primary" link @click="handleEdit(scope.row)">登记</el-button>
          <el-button type="success" link @click="handleEdit(scope.row)">编辑</el-button>
          <el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
          <el-button type="warning" link @click="handleExport(scope.row)">导出</el-button>
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination">
      <el-pagination
        v-model:current-page="pagination.currentPage"
        v-model:page-size="pagination.pageSize"
        :page-sizes="[10, 20, 30, 50]"
        :total="pagination.total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <!-- å¼¹çª—组件 -->
    <ProductionDialog
      v-model:visible="dialogVisible"
      :type="dialogType"
      :row-data="currentRow"
      @success="handleDialogSuccess"
    />
      <ETable :loading="loading" :table-data="tableData" :columns="columns" @selection-change="handleSelectionChange"
        @edit="handleEdit" @view-detail="handleViewDetail" :show-selection="true" :border="true" :maxHeight="480" />
      <Pagination v-model:currentPage="pagination.currentPage" v-model:pageSize="pagination.pageSize"
        :total="pagination.total" @current-change="handleCurrentChange" @size-change="handleSizeChange" />
    </el-card>
    <ProductionDialog v-model:visible="dialogVisible"  ref="childRef" :type="dialogType"
      @success="handleDialogSuccess" />
  </div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Delete, Download } from "@element-plus/icons-vue";
import ProductionDialog from './components/ProductionDialog.vue'
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Plus, Delete, Download, List } from "@element-plus/icons-vue";
import ProductionDialog from "./components/ProductionDialog.vue";
import ETable from "@/components/Table/ETable.vue";
import Pagination from "@/components/Pagination/index.vue";
const childRef = ref(null);
const columns = [
  { prop: "category", label: "煤种", width: 150 },
  { prop: "unit", label: "单位", width: 120 },
  { prop: "productionVolume", label: "生产数量", width: 150 },
  { prop: "laborCost", label: "人工成本", width: 150 },
  { prop: "materialCost", label: "原料成本", width: 120 },
  { prop: "equipmentCost", label: "设备费用", width: 143 },
  { prop: "totalCost", label: "总成本", width: 150 },
  { prop: "totalPrice", label: "总售价", width: 150 },
  { prop: "profit", label: "利润", width: 100 },
  { prop: "reviewer", label: "复记人", width: 120 },
  { prop: "date", label: "日期", width: 150 },
];
// æœç´¢è¡¨å•数据
const searchForm = reactive({
  keyword: '',
  addUser: ''
})
  searchAll:""
});
// è¡¨æ ¼æ•°æ®
const tableData = ref([])
const loading = ref(false)
const tableData = ref([]);
const loading = ref(false);
// åˆ†é¡µæ•°æ®
const pagination = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0
})
  total: 0,
});
// é€‰ä¸­çš„行数据
const selectedRows = ref([])
const selectedRows = ref([]);
// å¼¹çª—相关
const dialogVisible = ref(false)
const dialogType = ref('add')
const currentRow = ref(null)
const dialogVisible = ref(false);
const dialogType = ref("add");
const currentRow = ref(null);
// ç”Ÿäº§æ˜Žç»†å¯¹è¯æ¡†æŽ§åˆ¶
const detailDialogVisible = ref(false);
const currentDetailRow = ref(null);
// èŽ·å–è¡¨æ ¼æ•°æ®
const getList = async () => {
  loading.value = true
  loading.value = true;
  try {
    const params = {
      ...searchForm,
      pageNum: pagination.currentPage,
      pageSize: pagination.pageSize
    }
      pageSize: pagination.pageSize,
    };
    // const res = await getProductionList(params)
    // å‡æ•°æ®
    const res = {
      data: {
        list: [{
          sequence: 1,
          category: '煤种',
          unit: '单位',
          productionVolume: '生产数量',
          laborCost: '人工成本',
          materialCost: '原料成本',
          equipmentCost: '设备费用',
          totalCost: '总成本',
          totalPrice: '总成本',
          profit: '利润',
          reviewer: '复记人',
          date: '日期'
        }],
        total: 0
      }
    }
        list: [
          {
            sequence: 1,
            category: "无烟煤",
            unit: "吨",
            productionVolume: 100,
            laborCost: "300",
            materialCost: "200",
            equipmentCost: "100",
            totalCost: "600",
            totalPrice: "800",
            profit: "200",
            reviewer: "张三",
            date: "2023-10-01",
          },
          {
            sequence: 12,
            category: "无烟煤",
            unit: "吨",
            productionVolume: 100,
            laborCost: "3100",
            materialCost: "2020",
            equipmentCost: "1300",
            totalCost: "6030",
            totalPrice: "8300",
            profit: "2300",
            reviewer: "张三",
            date: "2025-10-02",
          },
        ],
        total: 2,
      },
    };
    tableData.value = res.data.list
    pagination.total = res.data.total
    tableData.value = res.data.list;
    pagination.total = res.data.total;
  } catch (error) {
    ElMessage.error('获取数据失败')
    ElMessage.error("获取数据失败");
  } finally {
    loading.value = false
    loading.value = false;
  }
}
};
// å¤„理表格选择变化
const handleSelectionChange = (selection) => {
  selectedRows.value = selection
}
  selectedRows.value = selection;
};
// æœç´¢æ–¹æ³•
const handleSearch = () => {
  pagination.currentPage = 1
  getList()
}
  pagination.currentPage = 1;
  getList();
};
// é‡ç½®æœç´¢
const handleReset = () => {
  searchForm.keyword = ''
  searchForm.addUser = ''
  handleSearch()
}
// æ–°å¢žé…é¡¹
const handleAdd = () => {
  dialogType.value = 'add'
  dialogVisible.value = true
}
  searchForm.keyword = "";
  searchForm.addUser = "";
  handleSearch();
};
// æ–°å¢žåŠ å·¥
const handleAddBatch = () => {
  dialogType.value = 'add'
  dialogVisible.value = true
}
  dialogType.value = "add";
  dialogVisible.value = true;
  childRef.value.Initialization();
};
// ç¼–辑
const handleEdit = (row) => {
  currentRow.value = row
  dialogType.value = 'edit'
  dialogVisible.value = true
}
  currentRow.value = row;
  dialogType.value = "edit";
  dialogVisible.value = true;
};
// æ‰“开生产明细对话框
const handleViewDetail = (row) => {
  currentDetailRow.value = row;
  detailDialogVisible.value = true;
};
// å¤„理弹窗提交
const handleDialogSuccess = async (formData) => {
  try {
    if (dialogType.value === 'add') {
      await addProduction(formData)
      ElMessage.success('新增成功')
    if (dialogType.value === "add") {
      await addProduction(formData);
      ElMessage.success("新增成功");
    } else {
      await updateProduction({
        ...formData,
        id: currentRow.value.id
      })
      ElMessage.success('更新成功')
        id: currentRow.value.id,
      });
      ElMessage.success("更新成功");
    }
    getList()
    getList();
  } catch (error) {
    ElMessage.error(dialogType.value === 'add' ? '新增失败' : '更新失败')
    ElMessage.error(dialogType.value === "add" ? "新增失败" : "更新失败");
  }
}
};
// å¤„理生产明细弹窗提交
const handleDetailDialogSuccess = async (formData) => {
  try {
    ElMessage.success("保存成功");
    getList();
  } catch (error) {
    ElMessage.error("保存失败");
  }
};
// åˆ é™¤
const handleDelete = (row) => {
  ElMessageBox.confirm('确认删除该记录吗?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      await deleteProduction(row.id)
      ElMessage.success('删除成功')
      getList()
    } catch (error) {
      console.error('删除失败:', error)
      ElMessage.error('删除失败')
    }
  }).catch(() => {
    ElMessage.info('已取消删除')
  ElMessageBox.confirm("确认删除该记录吗?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
}
    .then(async () => {
      try {
        await deleteProduction(row.id);
        ElMessage.success("删除成功");
        getList();
      } catch (error) {
        console.error("删除失败:", error);
        ElMessage.error("删除失败");
      }
    })
    .catch(() => {
      ElMessage.info("已取消删除");
    });
};
// å¯¼å‡º
const handleExport = async (row) => {
  try {
    const res = await exportProduction({ id: row.id })
    const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
    const fileName = `生产加工记录_${new Date().getTime()}.xlsx`
    if ('download' in document.createElement('a')) {
      const elink = document.createElement('a')
      elink.download = fileName
      elink.style.display = 'none'
      elink.href = URL.createObjectURL(blob)
      document.body.appendChild(elink)
      elink.click()
      URL.revokeObjectURL(elink.href)
      document.body.removeChild(elink)
    const res = await exportProduction({ id: row.id });
    const blob = new Blob([res], { type: "application/vnd.ms-excel" });
    const fileName = `生产加工记录_${new Date().getTime()}.xlsx`;
    if ("download" in document.createElement("a")) {
      const elink = document.createElement("a");
      elink.download = fileName;
      elink.style.display = "none";
      elink.href = URL.createObjectURL(blob);
      document.body.appendChild(elink);
      elink.click();
      URL.revokeObjectURL(elink.href);
      document.body.removeChild(elink);
    } else {
      navigator.msSaveBlob(blob, fileName)
      navigator.msSaveBlob(blob, fileName);
    }
  } catch (error) {
    ElMessage.error('导出失败')
    ElMessage.error("导出失败");
  }
}
};
// å¤„理每页显示数量变化
const handleSizeChange = (val) => {
  pagination.pageSize = val
  getList()
}
  pagination.pageSize = val;
  getList();
};
// å¤„理页码变化
const handleCurrentChange = (val) => {
  pagination.currentPage = val
  getList()
}
  pagination.currentPage = val;
  getList();
};
// ç»„件挂载时加载数据
onMounted(() => {
  getList()
})
  getList();
});
</script>
<style scoped>
<style scoped lang="scss">
.production-container {
  padding: 20px;
  .el-card:nth-child(1) {
    margin-bottom: 20px;
  }
}
.search-bar {
  margin-bottom: 20px;
  display: flex;
  gap: 10px;
}
.operation-bar {
  .el-input {
    width: 20%;
  }
}
.search-form{
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  display: flex;
  gap: 10px;
}
.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
  .el-form-item {
    margin-right: 10px;
  }
  .el-button {
    margin-left: 10px;
  }
}
</style>
</style>