gaoluyang
2025-11-14 7efe917a161f7c6965cfa75ac5ad7e664dcc1eb4
1.生产派工-加一个损耗率新增修改
已修改6个文件
219 ■■■■ 文件已修改
src/api/productionManagement/productionOrder.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/PIMTable/Pagination.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/scheduling/index.vue 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/operationScheduling/components/formDia.vue 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionDispatching/index.vue 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionManagement/productionOrder.js
@@ -53,3 +53,29 @@
    data: query,
  });
}
// 查询损耗率
export function getLossRate() {
  return request({
    url: "/salesLedger/scheduling/loss",
    method: "get",
  });
}
// 新增损耗率
export function addLossRate(data) {
  return request({
    url: "/salesLedger/scheduling/addLoss",
    method: "post",
    data: data,
  });
}
// 修改损耗率
export function updateLossRate(data) {
  return request({
    url: "/salesLedger/scheduling/updateLoss",
    method: "post",
    data: data,
  });
}
src/components/PIMTable/Pagination.vue
@@ -71,6 +71,7 @@
})
const handleSizeChange = (val) => {
    console.log('handleSizeChange', val)
  if (currentPage.value * val > props.total) {
    currentPage.value = 1
  }
@@ -81,6 +82,7 @@
}
const handleCurrentChange = (val) => {
    console.log('handleCurrentChange---', val)
  emit('pagination', { page: val, limit: pageSize.value })
  if (props.autoScroll) {
    scrollTo(0, 800)
src/views/personnelManagement/scheduling/index.vue
@@ -48,13 +48,13 @@
              {{ (department_type.find(i => i.value === String(scope.row.department)) || {}).label }}
          </template>
        </el-table-column> -->
        <!-- <el-table-column prop="shiftType" label="班次类型" width="100">
        <el-table-column prop="shiftType" label="班次类型" width="120">
          <template #default="scope">
            <el-tag :type="getShiftTagType(scope.row.shiftType)">
              {{ (shift_type.find(i => i.value === String(scope.row.shiftType)) || {}).label }}
              {{ (shift_type.find(i => i.value === String(scope.row.shiftType)) || {}).label || '未知' }}
            </el-tag>
          </template>
        </el-table-column> -->
        </el-table-column>
        <!-- <el-table-column prop="workDate" label="工作日期" width="120"/> -->
        <el-table-column prop="workStartTime" label="开始时间"/>
        <el-table-column prop="workEndTime" label="结束时间"/>
@@ -147,6 +147,16 @@
            </el-form-item>
          </el-col>
        </el-row> -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="班次类型:" prop="shiftType">
              <el-select v-model="scheduleForm.shiftType" placeholder="请选择班次类型" style="width: 100%">
                <el-option v-for="item in shift_type" :label="item.label" :value="item.value" :key="item.value"/>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- <el-row :gutter="20">
          <el-col :span="12">
@@ -284,7 +294,7 @@
  staffIds: [],
  // staffNo: '',
  // department: '',
  // shiftType: '',
  shiftType: '',
  // workDate: '',
  workStartTime: '',
  workEndTime: '',
@@ -300,7 +310,7 @@
const scheduleRules = reactive({
  staffIds: [{required: true, message: '请选择员工', trigger: 'change'}],
  // department: [{required: true, message: '请选择部门', trigger: 'change'}],
  // shiftType: [{required: true, message: '请选择班次类型', trigger: 'change'}],
  shiftType: [{required: true, message: '请选择班次类型', trigger: 'change'}],
  // workDate: [{required: true, message: '请选择工作日期', trigger: 'change'}],
  workStartTime: [{required: true, message: '请选择开始时间', trigger: 'change'}],
  workEndTime: [{required: true, message: '请选择结束时间', trigger: 'change'}],
@@ -488,7 +498,7 @@
      // 设置其他必要字段的默认值
      staffNo: '', // 可以根据需要从personList中获取
      department: '',
      shiftType: '',
      shiftType: scheduleForm.shiftType,
      workDate: '',
      status: '',
      remark: ''
src/views/productionManagement/operationScheduling/components/formDia.vue
@@ -8,11 +8,11 @@
    >
      <el-button type="primary" @click="addRow" style="margin-bottom: 10px;">新增</el-button>
            <span style="font-size: 18px;margin-left: 10px">待排产数量:{{pendingNum}}</span>
            <div style="margin-bottom: 10px; margin-left: 10px;">
                <el-form-item label="领用:" style="margin-bottom: 0;">
                    <el-input v-model="receive" placeholder="请输入领用" style="width: 200px;" />
                </el-form-item>
            </div>
<!--            <div style="margin-bottom: 10px; margin-left: 10px;">-->
<!--                <el-form-item label="领用:" style="margin-bottom: 0;">-->
<!--                    <el-input v-model="receive" placeholder="请输入领用" style="width: 200px;" />-->
<!--                </el-form-item>-->
<!--            </div>-->
      <el-table :data="tableData" border style="width: 100%" :summary-method="summarizeMainTable" show-summary :row-key="row => row.id">
        <el-table-column label="序号" width="60" align="center">
          <template #default="scope">
@@ -45,11 +45,6 @@
                            clearable
                            style="width: 100%"
                        />
          </template>
        </el-table-column>
        <el-table-column label="损耗" prop="loss" width="150">
          <template #default="scope">
            <el-input v-model="scope.row.loss" placeholder="请输入损耗" />
          </template>
        </el-table-column>
        <el-table-column label="工时定额" width="200" prop="workHours">
@@ -108,7 +103,7 @@
</template>
<script setup>
import {ref} from "vue";
import {ref, getCurrentInstance} from "vue";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import {processScheduling} from "@/api/productionManagement/operationScheduling.js";
const { proxy } = getCurrentInstance()
@@ -117,12 +112,11 @@
const dialogFormVisible = ref(false);
const operationType = ref('')
const tableData = ref([
    { process: '', schedulingDate: '', schedulingNum: null, schedulingUserId: '', workHours: null, unit: '', remark: '', loss: '', type: '' }
]);
const tableData = ref([]);
const unitFromRow = ref('');
const idFromRow = ref('');
const pendingNum = ref('');
const specificationModelFromRow = ref('');
const pendingNum = ref(0);
const userList = ref([])
const receive = ref('')
@@ -133,18 +127,25 @@
    userListNoPageByTenantId().then((res) => {
        userList.value = res.data;
    });
    pendingNum.value = row.pendingNum
  if (row && row.unit !== undefined) {
    unitFromRow.value = row.unit;
    idFromRow.value = row.id;
    tableData.value.forEach(item => {
      item.unit = row.unit;
      item.id = row.id;
    pendingNum.value = row?.pendingNum ?? 0;
    unitFromRow.value = row?.unit ?? '';
    idFromRow.value = row?.id ?? '';
    specificationModelFromRow.value = row?.specificationModel ?? '';
    tableData.value = [createRow()];
}
const createRow = () => ({
    id: idFromRow.value,
    process: '',
    schedulingDate: '',
    schedulingNum: null,
    schedulingUserId: '',
    workHours: null,
    unit: unitFromRow.value,
    remark: '',
    type: specificationModelFromRow.value,
    });
  } else {
    unitFromRow.value = '';
  }
}
const submitForm = () => {
    // 1. 检查每一行是否填写完整
    for (let i = 0; i < tableData.value.length; i++) {
@@ -169,11 +170,14 @@
        proxy.$modal.msgError('排产数量合计不能超过待排产数量');
        return;
    }
    // 3. 将 receive 字段添加到每条数据中
    const submitData = tableData.value.map(row => ({
        ...row,
    // 3. 将 receive 字段添加到每条数据中,并移除 loss 字段
    const submitData = tableData.value.map(row => {
        const { loss, ...rest } = row;
        return {
            ...rest,
        receive: receive.value
    }));
        };
    });
    processScheduling(submitData).then((res) => {
        proxy.$modal.msgSuccess("提交成功");
        closeDia();
@@ -186,6 +190,11 @@
const closeDia = () => {
  dialogFormVisible.value = false;
  receive.value = '';
  tableData.value = [];
  unitFromRow.value = '';
  idFromRow.value = '';
  specificationModelFromRow.value = '';
  pendingNum.value = 0;
  emit('close')
};
defineExpose({
@@ -193,7 +202,7 @@
});
const addRow = () => {
  tableData.value.push({ id: idFromRow.value, process: '', unit: unitFromRow.value, schedulingNum: null, workHours: null, schedulingDate: '', schedulingUserId: '', remark: '', loss: '', type: '' });
  tableData.value.push(createRow());
};
const removeRow = (index) => {
  tableData.value.splice(index, 1);
src/views/productionManagement/productionDispatching/index.vue
@@ -9,11 +9,21 @@
                    <span>总量(kg):</span>
                    <el-input-number v-model="machineData[machine.name].workLoad" :min="0" :step="1" size="small" />
                </div>
                <div><span>正在工作量(kg):</span><span>{{ machineData[machine.name].currentWorkLoad }}</span></div>
                <div><span> 预计投入量(kg):</span><span>{{ machineData[machine.name].currentWorkLoad }}</span></div>
                <div><span>空余工作量(kg):</span><span>{{ machineData[machine.name].vacant }}</span></div>
            </div>
            </div>
            <div class="save-button-container">
                <div class="loss-rate-container">
                    <span class="loss-rate-label">损耗率(%):</span>
                    <el-select v-model="rate" placeholder="请选择损耗率" style="width: 120px" size="small">
                        <el-option label="6" :value="6" />
                        <el-option label="7" :value="7" />
                        <el-option label="8" :value="8" />
                        <el-option label="9" :value="9" />
                        <el-option label="10" :value="10" />
                    </el-select>
                </div>
                <el-button type="primary" @click="saveMachineTotals" size="small">保存设置</el-button>
            </div>
        </div>
@@ -71,7 +81,7 @@
import FormDia from "@/views/productionManagement/productionDispatching/components/formDia.vue";
import AutoDispatchDia from "@/views/productionManagement/productionDispatching/components/autoDispatchDia.vue";
import dayjs from "dayjs";
import {schedulingListPage, schedulingList, addSpeculatTrading, updateSpeculatTrading} from "@/api/productionManagement/productionOrder.js";
import {schedulingListPage, schedulingList, addSpeculatTrading, updateSpeculatTrading, getLossRate, addLossRate, updateLossRate} from "@/api/productionManagement/productionOrder.js";
import { ElMessageBox } from "element-plus";
const data = reactive({
@@ -175,19 +185,23 @@
// 保存炒机总量设置
const saveMachineTotals = () => {
    // 验证损耗率是否已选择
    if (rate.value === null || rate.value === undefined || isNaN(rate.value)) {
        proxy.$message.warning('请选择损耗率');
        return;
    }
    // 构造保存数据数组,使用machines数组循环构建
    const saveData = machines.map(machine => {
        const saveItem = {
            name: machine.name, // 炒机名称
            workLoad: machineData[machine.name].workLoad,  // 总量
            currentWorkLoad: machineData[machine.name].currentWorkLoad, // 正在工作量
            currentWorkLoad: machineData[machine.name].currentWorkLoad, //  预计投入量
            vacant: machineData[machine.name].vacant   // 空余量
        };
        
        // 如果是修改操作,需要传递id字段
        if (hasQueryData.value) {
            // 这里需要从查询数据中获取对应的id
            // 假设查询数据中每个炒机数据都有id字段
            const queryData = getMachineQueryData(machine.id);
            if (queryData && queryData.id) {
                saveItem.id = queryData.id;
@@ -197,23 +211,44 @@
        return saveItem;
    });
    
    console.log('保存炒机设置数据:', saveData);
    // 构造损耗率数据
    const rateData = {
        rate: rate.value
    };
    // 如果有ID,说明是修改操作
    if (rateId.value) {
        rateData.id = rateId.value;
    }
    
    // 根据是否有查询数据决定调用新增接口还是修改接口
    const saveApi = hasQueryData.value ? updateSpeculatTrading : addSpeculatTrading;
    const successMessage = hasQueryData.value ? '炒机设置修改成功' : '炒机设置新增成功';
    
    console.log(`调用接口: ${hasQueryData.value ? '修改' : '新增'}`);
    // 根据是否有ID决定调用新增接口还是修改接口
    const rateApi = rateId.value ? updateLossRate : addLossRate;
    const rateSuccessMessage = rateId.value ? '损耗率修改成功' : '损耗率新增成功';
    
    // 调用后端API保存
    saveApi(saveData).then(res => {
    // 并行调用两个接口
    Promise.all([
        saveApi(saveData),
        rateApi(rateData)
    ]).then(([saveRes, rateRes]) => {
        proxy.$message.success(successMessage);
        console.log('保存成功:', res);
        proxy.$message.success(rateSuccessMessage);
        
        // 保存成功后,设置hasQueryData为true,下次保存将调用修改接口
        if (!hasQueryData.value) {
            hasQueryData.value = true;
        }
        // 如果返回了ID,保存起来
        if (rateRes && rateRes.data && rateRes.data.id) {
            rateId.value = rateRes.data.id;
        }
        // 保存成功后重新调用查询页面
        getList();
    }).catch(err => {
        proxy.$message.error('保存失败');
        console.error('保存失败:', err);
@@ -273,6 +308,10 @@
// 是否有查询数据
const hasQueryData = ref(false)
// 损耗率
const rate = ref(6)
// 损耗率ID
const rateId = ref(null)
// 获取炒机正在工作量数据
const getMachineProductionData = () => {
@@ -310,9 +349,6 @@
                    machineData[machineName].vacant = machineData[machineName].workLoad - machineData[machineName].currentWorkLoad;
                }
            });
            console.log('炒机数据初始化完成:', machineData);
            console.log('炒机查询数据:', machineQueryData.value);
        }
    }).catch(err => {
        console.error('获取炒机正在工作量数据失败:', err);
@@ -351,9 +387,29 @@
        
        // 同时获取炒机正在工作量数据
        getMachineProductionData();
        // 获取损耗率数据
        getLossRateData();
    }).catch(() => {
        tableLoading.value = false;
    })
};
// 获取损耗率数据
const getLossRateData = () => {
    getLossRate().then((res) => {
        const data = res.data || res;
        if (data && data.rate !== undefined && data.rate !== null) {
            rate.value = Number(data.rate); // 确保转换为数字
            rateId.value = data.id || null;
        } else {
            rate.value = 6;
            rateId.value = null;
        }
    }).catch(err => {
        console.error('获取损耗率数据失败:', err);
        rate.value = 6;
        rateId.value = null;
    });
};
// 表格选择数据
const handleSelectionChange = (selection) => {
@@ -412,6 +468,7 @@
onMounted(() => {
    getList();
    getLossRateData();
});
</script>
@@ -512,8 +569,21 @@
    grid-column: 1 / -1;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 16px;
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid #e9ecef;
}
.loss-rate-container{
    display: flex;
    align-items: center;
    gap: 8px;
}
.loss-rate-label{
    font-size: 14px;
    color: #6c757d;
    font-weight: 500;
    white-space: nowrap;
}
</style>
src/views/salesManagement/salesLedger/index.vue
@@ -41,7 +41,7 @@
      </div>
      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
        :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary style="width: 100%"
        :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)">
        :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 21em)">
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column type="expand">
          <template #default="props">