gaoluyang
昨天 4d3882045d317ddb3c7416f606ac738ca6ec2c01
1.生产管理联调
已修改5个文件
已添加6个文件
1561 ■■■■ 文件已修改
src/api/productionManagement/operationScheduling.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionManagement/productionOrder.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionManagement/productionReporting.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/operationScheduling/components/formDia.vue 268 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/operationScheduling/index.vue 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionCosting/index.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionDispatching/components/formDia.vue 130 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionDispatching/index.vue 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/index.vue 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/components/formDia.vue 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/index.vue 426 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionManagement/operationScheduling.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
// å·¥åºæŽ’产页面接口
import request from "@/utils/request";
// åˆ†é¡µæŸ¥è¯¢
export function listPageProcess(query) {
  return request({
    url: "/salesLedger/scheduling/listPageProcess",
    method: "get",
    params: query,
  });
}
// å–消排产
export function productionDispatchDelete(query) {
  return request({
    url: "/salesLedger/scheduling/productionDispatchDelete",
    method: "delete",
    data: query,
  });
}
// å–消排产
export function processScheduling(query) {
  return request({
    url: "/salesLedger/scheduling/processScheduling",
    method: "post",
    data: query,
  });
}
src/api/productionManagement/productionOrder.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
// ç”Ÿäº§è®¢å•页面接口
import request from "@/utils/request";
// åˆ†é¡µæŸ¥è¯¢
export function schedulingListPage(query) {
  return request({
    url: "/salesLedger/scheduling/listPage",
    method: "get",
    params: query,
  });
}
// ç”Ÿäº§æ´¾å·¥
export function productionDispatch(query) {
  return request({
    url: "/salesLedger/scheduling/productionDispatch",
    method: "post",
    data: query,
  });
}
src/api/productionManagement/productionReporting.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
// ç”Ÿäº§æŠ¥å·¥é¡µé¢æŽ¥å£
import request from "@/utils/request";
// åˆ†é¡µæŸ¥è¯¢
export function workListPage(query) {
  return request({
    url: "/salesLedger/work/listPage",
    method: "get",
    params: query,
  });
}
// å­è¡¨æ ¼æŸ¥è¯¢
export function workListPageById(query) {
  return request({
    url: "/salesLedger/work/list",
    method: "get",
    params: query,
  });
}
// ç”Ÿäº§æŠ¥å·¥
export function productionReport(query) {
  return request({
    url: "/salesLedger/work/productionReport",
    method: "post",
    data: query,
  });
}
// ç”Ÿäº§æŠ¥å·¥-编辑
export function productionReportUpdate(query) {
  return request({
    url: "/salesLedger/work/productionReportUpdate",
    method: "post",
    data: query,
  });
}
src/views/productionManagement/operationScheduling/components/formDia.vue
@@ -2,162 +2,182 @@
  <div>
    <el-dialog
        v-model="dialogFormVisible"
        :title="operationType === 'add' ? '新增入职' : '编辑人员'"
        title="工序排产"
        width="70%"
        @close="closeDia"
    >
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="项目名称:" prop="staffNo">
              <el-input v-model="form.staffNo" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="产品大类:" prop="staffNo">
              <el-input v-model="form.staffNo" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="总数量:" prop="staffNo">
              <el-input v-model="form.staffNo" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="本次排产数量:" prop="staffNo">
                            <el-input-number
                                v-model="form.ticketsNum"
                                placeholder="请输入"
                                :min="0"
                                :step="0.1"
                                :precision="2"
                                clearable
                                style="width: 100%"
      <el-button type="primary" @click="addRow" style="margin-bottom: 10px;">新增</el-button>
            <span style="font-size: 18px;margin-left: 10px">待排产数量:{{pendingNum}}</span>
      <el-table :data="tableData" border style="width: 100%" :summary-method="summarizeMainTable" show-summary :row-key="row => row.id">
        <el-table-column label="序号" width="60">
          <template #default="scope">
            {{ scope.$index + 1 }}
          </template>
        </el-table-column>
        <el-table-column label="工序" prop="process">
          <template #default="scope">
                        <el-select v-model="scope.row.process" placeholder="请选择" clearable style="width: 100%">
                            <el-option
                                v-for="dict in work_step"
                                :key="dict.value"
                                :label="dict.label"
                                :value="dict.value"
                            />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="排产人:" prop="staffName">
                            <el-input v-model="form.staffName" placeholder="请输入" clearable/>
                        </el-form-item>
                    </el-col>
          <el-col :span="12">
            <el-form-item label="排产日期:" prop="contractStartTime">
              <el-date-picker
                  v-model="form.contractStartTime"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
                        </el-select>
          </template>
        </el-table-column>
        <el-table-column label="单位" prop="unit">
          <template #default="scope">
            <el-input v-model="scope.row.unit" placeholder="请输入单位" />
          </template>
        </el-table-column>
        <el-table-column label="排产数量" width="200" prop="schedulingNum">
          <template #default="scope">
                        <el-input-number
                            v-model="scope.row.schedulingNum"
                            placeholder="请输入"
                            :min="0"
                            :step="0.1"
                            :precision="2"
                            clearable
                            style="width: 100%"
                        />
          </template>
        </el-table-column>
        <el-table-column label="工时定额" width="200" prop="workHours">
          <template #default="scope">
                        <el-input-number
                            v-model="scope.row.workHours"
                            placeholder="请输入"
                            :min="0"
                            :step="0.1"
                            :precision="2"
                            clearable
                            style="width: 100%"
                        />
          </template>
        </el-table-column>
        <el-table-column label="排产日期" prop="schedulingDate">
          <template #default="scope">
            <el-date-picker v-model="scope.row.schedulingDate" type="date" placeholder="选择日期" style="width: 100%;" value-format="YYYY-MM-DD" format="YYYY-MM-DD"/>
          </template>
        </el-table-column>
        <el-table-column label="排产人" prop="schedulingUserId">
          <template #default="scope">
                        <el-select
                            v-model="scope.row.schedulingUserId"
                            placeholder="选择人员"
                            style="width: 100%;"
                        >
                            <el-option
                                v-for="user in userList"
                                :key="user.userId"
                                :label="user.nickName"
                                :value="user.userId"
                            />
                        </el-select>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80">
          <template #default="scope">
            <el-button type="danger" size="small" @click="removeRow(scope.$index)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitForm">确认</el-button>
                    <el-button @click="closeDia">取消</el-button>
                </div>
            </template>
    </el-dialog>
  </div>
</template>
<script setup>
import {ref} from "vue";
import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import {processScheduling} from "@/api/productionManagement/operationScheduling.js";
const { proxy } = getCurrentInstance()
const { work_step } = proxy.useDict("work_step")
const emit = defineEmits(['close'])
const dialogFormVisible = ref(false);
const operationType = ref('')
const data = reactive({
  form: {
    staffNo: "",
    staffName: "",
    sex: "",
    nativePlace: "",
    postJob: "",
    adress: "",
    firstStudy: "",
    profession: "",
    identityCard: "",
    age: 0,
    phone: "",
    emergencyContact: "",
    emergencyContactPhone: "",
    contractTerm: 0,
    contractStartTime: "",
    contractEndTime: "",
    staffState: "",
  },
  rules: {
    staffNo: [{ required: true, message: "请输入", trigger: "blur" },],
    staffName: [{ required: true, message: "请输入", trigger: "blur" }],
    sex: [{ required: true, message: "请输入", trigger: "blur" }],
    nativePlace: [{ required: true, message: "请输入", trigger: "blur" }],
    postJob: [{ required: true, message: "请输入", trigger: "blur" }],
    adress: [{ required: true, message: "请输入", trigger: "blur" }],
    firstStudy: [{ required: true, message: "请输入", trigger: "blur" }],
    profession: [{ required: true, message: "请输入", trigger: "blur" }],
    identityCard: [{ required: true, message: "请输入", trigger: "blur" }],
    age: [{ required: true, message: "请输入", trigger: "blur" }],
    phone: [{ required: true, message: "请输入", trigger: "blur" }],
    emergencyContact: [{ required: true, message: "请输入", trigger: "blur" }],
    emergencyContactPhone: [{ required: true, message: "请输入", trigger: "blur" }],
    contractTerm: [{ required: true, message: "请输入", trigger: "blur" }],
    contractStartTime: [{ required: true, message: "请输入", trigger: "blur" }],
    contractEndTime: [{ required: true, message: "请输入", trigger: "blur" }],
  },
});
const { form, rules } = toRefs(data);
const tableData = ref([
    { process: '', schedulingDate: '', schedulingNum: '', schedulingUserId: '', workHours: '', unit: '' }
]);
const unitFromRow = ref('');
const idFromRow = ref('');
const pendingNum = ref('');
const userList = ref([])
// æ‰“开弹框
const openDialog = (type, row) => {
  operationType.value = type;
  dialogFormVisible.value = true;
  if (operationType.value === 'edit') {
    getStaffJoinInfo(row.id).then(res => {
      form.value = {...res.data}
    })
    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;
    });
  } else {
    unitFromRow.value = '';
  }
}
// æäº¤äº§å“è¡¨å•
const submitForm = () => {
  proxy.$refs.formRef.validate(valid => {
    if (valid) {
      form.value.staffState = 1
      if (operationType.value === "add") {
        staffJoinAdd(form.value).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      } else {
        staffJoinUpdate(form.value).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      }
    }
  })
    // 1. æ£€æŸ¥æ¯ä¸€è¡Œæ˜¯å¦å¡«å†™å®Œæ•´
    for (let i = 0; i < tableData.value.length; i++) {
        const row = tableData.value[i];
        if (
            !row.process ||
            !row.schedulingDate ||
            row.schedulingNum === '' || row.schedulingNum === null ||
            !row.schedulingUserId ||
            row.workHours === '' || row.workHours === null ||
            !row.unit
        ) {
            proxy.$modal.msgError(`第${i + 1}行数据未填写完整`);
            return;
        }
    }
    // 2. åˆè®¡æŽ’产数量
    const totalSchedulingNum = tableData.value.reduce((sum, row) => {
        return sum + Number(row.schedulingNum || 0);
    }, 0);
    if (totalSchedulingNum > Number(pendingNum.value)) {
        proxy.$modal.msgError('排产数量合计不能超过待排产数量');
        return;
    }
    processScheduling(tableData.value).then((res) => {
        proxy.$modal.msgSuccess("提交成功");
        closeDia();
    })
}
const summarizeMainTable = (param) => {
    return proxy.summarizeTable(param, ['schedulingNum']);
};
// å…³é—­å¼¹æ¡†
const closeDia = () => {
  proxy.resetForm("formRef");
  dialogFormVisible.value = false;
  emit('close')
};
defineExpose({
  openDialog,
});
const addRow = () => {
  tableData.value.push({ id: idFromRow.value, process: '', unit: unitFromRow.value, schedulingNum: '', workHours: '', schedulingDate: '', schedulingUserId: '' });
};
const removeRow = (index) => {
  tableData.value.splice(index, 1);
};
</script>
<style scoped>
src/views/productionManagement/operationScheduling/index.vue
@@ -16,8 +16,9 @@
                </el-form-item>
                <el-form-item label="状态:">
                    <el-select v-model="searchForm.status" placeholder="请选择状态" style="width: 140px" clearable>
                        <el-option label="已排产" :value="1"></el-option>
                        <el-option label="待排产" :value="0"></el-option>
                        <el-option label="待排产" :value="1"></el-option>
                        <el-option label="已排产" :value="0"></el-option>
                        <el-option label="排产中" :value="2"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item>
@@ -27,8 +28,8 @@
        </div>
        <div class="table_list">
            <div style="text-align: right" class="mb10">
                <el-button type="primary" @click="openForm('add')">工序排产</el-button>
                <el-button type="danger" @click="openForm('delete')" plain>取消排产</el-button>
                <el-button type="primary" @click="openForm">工序排产</el-button>
                <el-button type="danger" @click="handleDelete" plain>取消排产</el-button>
            </div>
            <PIMTable
                rowKey="id"
@@ -48,15 +49,15 @@
<script setup>
import {onMounted, ref} from "vue";
import FormDia from "@/views/productionManagement/productionDispatching/components/formDia.vue";
import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
import FormDia from "@/views/productionManagement/operationScheduling/components/formDia.vue";
import {ElMessageBox} from "element-plus";
import dayjs from "dayjs";
import {listPageProcess, productionDispatchDelete} from "@/api/productionManagement/operationScheduling.js";
const data = reactive({
    searchForm: {
        staffName: "",
        status: 0,
        status: 1,
        entryDate: [
            dayjs().format("YYYY-MM-DD"),
            dayjs().add(1, "day").format("YYYY-MM-DD"),
@@ -68,54 +69,83 @@
const { searchForm } = toRefs(data);
const tableColumn = ref([
    {
        label: "录入日期",
        prop: "staffNo",
        label: "状态",
        prop: "status",
        dataType: "tag",
        formatData: (params) => {
            if (params == 0) {
                return "已排产";
            } else if (params == 1) {
                return "待排产";
            } else {
                return '排产中';
            }
        },
        formatType: (params) => {
            if (params == 0) {
                return "success";
            } else if (params == 1) {
                return "primary";
            } else {
                return 'warning';
            }
        },
    },
    {
        label: "派工日期",
        prop: "schedulingDate",
        width: 120,
    },
    {
        label: "派工人",
        prop: "schedulingUserName",
    },
    {
        label: "合同号",
        prop: "staffName",
        prop: "salesContractNo",
        width: 200,
    },
    {
        label: "客户合同号",
        prop: "addressPhone",
        width: 250,
        prop: "customerContractNo",
        width: 200,
    },
    {
        label: "客户名称",
        prop: "contactPerson",
        prop: "customerName",
        width: 200,
    },
    {
        label: "项目名称",
        prop: "contactPhone",
        width:150
        prop: "projectName",
        width:300
    },
    {
        label: "产品大类",
        prop: "basicBankAccount",
        width: 220,
        prop: "productCategory",
        width: 150,
    },
    {
        label: "规格型号",
        prop: "bankAccount",
        width: 220,
        prop: "specificationModel",
        width: 150,
    },
    {
        label: "单位",
        prop: "bankCode",
        width:220
        prop: "unit",
    },
    {
        label: "数量",
        prop: "maintainer",
        label: "排产总数",
        prop: "schedulingNum",
    },
    {
        label: "排产数量",
        prop: "maintenanceTime",
        label: "已排产数量",
        prop: "successNum",
        width: 100,
    },
    {
        label: "待排数量",
        prop: "maintenanceTime",
        label: "待排产数量",
        prop: "pendingNum",
        width: 100,
    },
]);
@@ -138,11 +168,11 @@
};
const changeDaterange = (value) => {
    if (value) {
        searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
        searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
        searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
        searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
    } else {
        searchForm.entryDateStart = undefined;
        searchForm.entryDateEnd = undefined;
        searchForm.value.entryDateStart = undefined;
        searchForm.value.entryDateEnd = undefined;
    }
    handleQuery();
};
@@ -153,9 +183,14 @@
};
const getList = () => {
    tableLoading.value = true;
    staffJoinListPage({...page, ...searchForm.value}).then(res => {
    const params = { ...searchForm.value, ...page };
    params.entryDate = undefined
    listPageProcess(params).then(res => {
        tableLoading.value = false;
        tableData.value = res.data.records
        tableData.value = res.data.records.map(item => ({
            ...item,
            pendingNum: (Number(item.schedulingNum) || 0) - (Number(item.successNum) || 0)
        }));
        page.total = res.data.total;
    }).catch(err => {
        tableLoading.value = false;
@@ -172,12 +207,12 @@
        proxy.$message.error("请选择一条数据");
        return;
    }
    if (selectedRows.value[0].unPaymentAmountTotal == 0) {
        proxy.$message.warning("无需再付款");
    if (selectedRows.value[0].pendingNum == 0) {
        proxy.$message.warning("无需再排产");
        return;
    }
    nextTick(() => {
        formDia.value?.openDialog(type, row)
        formDia.value?.openDialog(type, selectedRows.value[0])
    })
};
@@ -190,30 +225,18 @@
        proxy.$modal.msgWarning("请选择数据");
        return;
    }
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
    ElMessageBox.confirm("是否确认取消排产?", "删除提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
    })
        .then(() => {
            staffJoinDel(ids).then((res) => {
                proxy.$modal.msgSuccess("删除成功");
                getList();
            });
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
        });
};
// å¯¼å‡º
const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
    })
        .then(() => {
            proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 1}, "人员入职.xlsx");
            tableLoading.value = true;
            productionDispatchDelete(ids)
                .then((res) => {
                    proxy.$modal.msgSuccess("取消排产成功");
                    getList();
                })
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
src/views/productionManagement/productionCosting/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,183 @@
<template>
    <div class="app-container">
        <div class="search_form">
            <div>
                <span class="search_title">生产日期:</span>
                <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                                                placeholder="请选择" clearable @change="changeDaterange" />
                <span class="search_title ml10">生产人:</span>
                <el-input
                    v-model="searchForm.customerName"
                    style="width: 240px"
                    placeholder="请输入"
                    @change="handleQuery"
                    clearable
                    prefix-icon="Search"
                />
                <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
                >搜索</el-button
                >
            </div>
            <div>
                <el-button @click="handleOut">导出</el-button>
            </div>
        </div>
        <div class="table_list">
            <PIMTable
                rowKey="id"
                :column="tableColumn"
                :tableData="tableData"
                :page="page"
                :tableLoading="tableLoading"
                @pagination="pagination"
            ></PIMTable>
        </div>
    </div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import {
    listCustomer,
} from "@/api/basicData/customerFile.js";
import { ElMessageBox } from "element-plus";
import dayjs from "dayjs";
const { proxy } = getCurrentInstance();
const tableColumn = ref([
    {
        label: "生产日期",
        prop: "customerName",
        width: 120,
    },
    {
        label: "生产人",
        prop: "customerName",
        width: 120,
    },
    {
        label: "合同号",
        prop: "taxpayerIdentificationNumber",
        width: 220,
    },
    {
        label: "客户合同号",
        prop: "addressPhone",
        width: 250,
    },
    {
        label: "客户名称",
        prop: "contactPerson",
    },
    {
        label: "项目名称",
        prop: "contactPhone",
        width:150
    },
    {
        label: "产品大类",
        prop: "basicBankAccount",
        width: 220,
    },
    {
        label: "规格型号",
        prop: "bankAccount",
        width: 220,
    },
    {
        label: "单位",
        prop: "bankCode",
        width:220
    },
    {
        label: "工序",
        prop: "maintainer",
    },
    {
        label: "生产数量",
        prop: "maintenanceTime",
        width: 100,
    },
    {
        label: "工时定额",
        prop: "maintenanceTime",
        width: 100,
    },
    {
        label: "工资",
        prop: "maintenanceTime",
        width: 100,
    },
]);
const tableData = ref([]);
const tableLoading = ref(false);
const page = reactive({
    current: 1,
    size: 100,
    total: 0,
});
const data = reactive({
    searchForm: {
        customerName: "",
        entryDate: [
            dayjs().format("YYYY-MM-DD"),
            dayjs().add(1, "day").format("YYYY-MM-DD"),
        ], // å½•入日期
        entryDateStart: dayjs().format("YYYY-MM-DD"),
        entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
    },
});
const { searchForm } = toRefs(data);
// æŸ¥è¯¢åˆ—表
/** æœç´¢æŒ‰é’®æ“ä½œ */
const handleQuery = () => {
    page.current = 1;
    getList();
};
const pagination = (obj) => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
};
const changeDaterange = (value) => {
    if (value) {
        searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
        searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
    } else {
        searchForm.entryDateStart = undefined;
        searchForm.entryDateEnd = undefined;
    }
    handleQuery();
};
const getList = () => {
    tableLoading.value = true;
    listCustomer({ ...searchForm.value, ...page }).then((res) => {
        tableLoading.value = false;
        tableData.value = res.records;
        page.total = res.total;
    });
};
// å¯¼å‡º
const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
    })
        .then(() => {
            proxy.download("/basic/customer/export", {}, "生产核算.xlsx");
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
        });
};
onMounted(() => {
    getList();
});
</script>
<style scoped lang="scss"></style>
src/views/productionManagement/productionDispatching/components/formDia.vue
@@ -9,46 +9,65 @@
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="项目名称:" prop="staffNo">
              <el-input v-model="form.staffNo" placeholder="请输入" clearable disabled/>
            <el-form-item label="项目名称:" prop="projectName">
              <el-input v-model="form.projectName" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="产品大类:" prop="staffNo">
              <el-input v-model="form.staffNo" placeholder="请输入" clearable disabled/>
            <el-form-item label="产品大类:" prop="productCategory">
              <el-input v-model="form.productCategory" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="总数量:" prop="staffNo">
              <el-input v-model="form.staffNo" placeholder="请输入" clearable disabled/>
            <el-form-item label="总数量:" prop="quantity">
              <el-input v-model="form.quantity" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="本次排产数量:" prop="staffNo">
                        <el-form-item label="待排产数量:" prop="pendingQuantity">
                            <el-input v-model="form.pendingQuantity" placeholder="请输入" clearable disabled/>
                        </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
                        <el-form-item label="本次排产数量:" prop="schedulingNum">
                            <el-input-number
                                v-model="form.ticketsNum"
                                v-model="form.schedulingNum"
                                placeholder="请输入"
                                :min="0"
                                :step="0.1"
                                :precision="2"
                                clearable
                                @change="changeNum"
                                style="width: 100%"
                            />
            </el-form-item>
                        </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="排产人:" prop="staffName">
                            <el-input v-model="form.staffName" placeholder="请输入" clearable/>
                        <el-form-item label="派工人:" prop="schedulingUserId">
                            <el-select
                                v-model="form.schedulingUserId"
                                placeholder="选择人员"
                                style="width: 100%;"
                            >
                                <el-option
                                    v-for="user in userList"
                                    :key="user.userId"
                                    :label="user.nickName"
                                    :value="user.userId"
                                />
                            </el-select>
                        </el-form-item>
                    </el-col>
          <el-col :span="12">
            <el-form-item label="排产日期:" prop="contractStartTime">
            <el-form-item label="派工日期:" prop="schedulingDate">
              <el-date-picker
                  v-model="form.contractStartTime"
                  v-model="form.schedulingDate"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
@@ -73,6 +92,10 @@
<script setup>
import {ref} from "vue";
import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import {productionDispatch} from "@/api/productionManagement/productionOrder.js";
import useUserStore from "@/store/modules/user.js";
import dayjs from "dayjs";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
@@ -80,71 +103,52 @@
const operationType = ref('')
const data = reactive({
  form: {
    staffNo: "",
    staffName: "",
    sex: "",
    nativePlace: "",
    postJob: "",
    adress: "",
    firstStudy: "",
    profession: "",
    identityCard: "",
    age: 0,
    phone: "",
    emergencyContact: "",
    emergencyContactPhone: "",
    contractTerm: 0,
    contractStartTime: "",
    contractEndTime: "",
    staffState: "",
        projectName: "",
        productCategory: "",
        quantity: "",
        schedulingNum: "",
        schedulingUserId: "",
        schedulingDate: "",
        pendingQuantity: "",
  },
  rules: {
    staffNo: [{ required: true, message: "请输入", trigger: "blur" },],
    staffName: [{ required: true, message: "请输入", trigger: "blur" }],
    sex: [{ required: true, message: "请输入", trigger: "blur" }],
    nativePlace: [{ required: true, message: "请输入", trigger: "blur" }],
    postJob: [{ required: true, message: "请输入", trigger: "blur" }],
    adress: [{ required: true, message: "请输入", trigger: "blur" }],
    firstStudy: [{ required: true, message: "请输入", trigger: "blur" }],
    profession: [{ required: true, message: "请输入", trigger: "blur" }],
    identityCard: [{ required: true, message: "请输入", trigger: "blur" }],
    age: [{ required: true, message: "请输入", trigger: "blur" }],
    phone: [{ required: true, message: "请输入", trigger: "blur" }],
    emergencyContact: [{ required: true, message: "请输入", trigger: "blur" }],
    emergencyContactPhone: [{ required: true, message: "请输入", trigger: "blur" }],
    contractTerm: [{ required: true, message: "请输入", trigger: "blur" }],
    contractStartTime: [{ required: true, message: "请输入", trigger: "blur" }],
    contractEndTime: [{ required: true, message: "请输入", trigger: "blur" }],
        schedulingNum: [{ required: true, message: "请输入", trigger: "blur" },],
        schedulingUserId: [{ required: true, message: "请选择", trigger: "change" },],
        schedulingDate: [{ required: true, message: "请选择", trigger: "change" },],
  },
});
const { form, rules } = toRefs(data);
const userList = ref([])
const userStore = useUserStore()
// æ‰“开弹框
const openDialog = (type, row) => {
  operationType.value = type;
  dialogFormVisible.value = true;
  if (operationType.value === 'edit') {
    getStaffJoinInfo(row.id).then(res => {
      form.value = {...res.data}
    })
  }
    userListNoPageByTenantId().then((res) => {
        userList.value = res.data;
    });
    form.value = {...row}
    form.value.schedulingNum = 0
    form.value.schedulingUserId = userStore.id
    form.value.schedulingDate = dayjs().format("YYYY-MM-DD");
}
//
const changeNum = (value) => {
    if (value > form.value.pendingQuantity) {
        form.value.schedulingNum = form.value.pendingQuantity;
        proxy.$modal.msgWarning('排产数量不可大于待排产数量')
    }
}
// æäº¤äº§å“è¡¨å•
const submitForm = () => {
  proxy.$refs.formRef.validate(valid => {
    if (valid) {
      form.value.staffState = 1
      if (operationType.value === "add") {
        staffJoinAdd(form.value).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      } else {
        staffJoinUpdate(form.value).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      }
            productionDispatch(form.value).then(res => {
                proxy.$modal.msgSuccess("提交成功");
                closeDia();
            })
    }
  })
}
src/views/productionManagement/productionDispatching/index.vue
@@ -23,9 +23,7 @@
                <span class="search_title ml10">录入日期:</span>
                <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                                                placeholder="请选择" clearable @change="changeDaterange" />
                <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
                >搜索</el-button
                >
                <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button>
            </div>
            <div>
                <el-button type="primary" @click="openForm('add')">生产派工</el-button>
@@ -51,9 +49,8 @@
<script setup>
import {onMounted, ref} from "vue";
import FormDia from "@/views/productionManagement/productionDispatching/components/formDia.vue";
import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
import {ElMessageBox} from "element-plus";
import dayjs from "dayjs";
import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
const data = reactive({
    searchForm: {
@@ -70,53 +67,56 @@
const tableColumn = ref([
    {
        label: "录入日期",
        prop: "staffNo",
        prop: "entryDate",
        width: 120,
    },
    {
        label: "合同号",
        prop: "staffName",
        prop: "salesContractNo",
        width: 220,
    },
    {
        label: "客户合同号",
        prop: "addressPhone",
        prop: "customerContractNo",
        width: 250,
    },
    {
        label: "客户名称",
        prop: "contactPerson",
        prop: "customerName",
        width: 250,
    },
    {
        label: "项目名称",
        prop: "contactPhone",
        width:150
        prop: "projectName",
        width:300
    },
    {
        label: "产品大类",
        prop: "basicBankAccount",
        width: 220,
        prop: "productCategory",
        width: 160,
    },
    {
        label: "规格型号",
        prop: "bankAccount",
        prop: "specificationModel",
        width: 220,
    },
    {
        label: "单位",
        prop: "bankCode",
        width:220
        prop: "unit",
        width:90
    },
    {
        label: "数量",
        prop: "maintainer",
        prop: "quantity",
    },
    {
        label: "排产数量",
        prop: "maintenanceTime",
        prop: "schedulingNum",
        width: 100,
    },
    {
        label: "待排数量",
        prop: "maintenanceTime",
        prop: "pendingQuantity",
        width: 100,
    },
]);
@@ -139,11 +139,11 @@
};
const changeDaterange = (value) => {
    if (value) {
        searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
        searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
        searchForm.value.entryDateStart = value[0];
        searchForm.value.entryDateEnd = value[1];
    } else {
        searchForm.entryDateStart = undefined;
        searchForm.entryDateEnd = undefined;
        searchForm.value.entryDateStart = undefined;
        searchForm.value.entryDateEnd = undefined;
    }
    handleQuery();
};
@@ -154,11 +154,18 @@
};
const getList = () => {
    tableLoading.value = true;
    staffJoinListPage({...page, ...searchForm.value}).then(res => {
    // æž„造一个新的对象,不包含entryDate字段
    const params = { ...searchForm.value, ...page };
    params.entryDate = undefined
    schedulingListPage(params).then((res) => {
        tableLoading.value = false;
        tableData.value = res.data.records
        // å¤„理每条数据,增加pendingQuantity字段
        tableData.value = res.data.records.map(item => ({
            ...item,
            pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0)
        }));
        page.total = res.data.total;
    }).catch(err => {
    }).catch(() => {
        tableLoading.value = false;
    })
};
@@ -168,59 +175,27 @@
};
// æ‰“开弹框
const openForm = (type, row) => {
const openForm = (type) => {
    if (selectedRows.value.length !== 1) {
        proxy.$message.error("请选择一条数据");
        return;
    }
    if (selectedRows.value[0].unPaymentAmountTotal == 0) {
        proxy.$message.warning("无需再付款");
    if (selectedRows.value[0].pendingQuantity == 0) {
        proxy.$message.warning("无需再派工");
        return;
    }
    nextTick(() => {
        formDia.value?.openDialog(type, row)
        formDia.value?.openDialog(type, selectedRows.value[0])
    })
};
// åˆ é™¤
const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
        ids = selectedRows.value.map((item) => item.id);
    } else {
        proxy.$modal.msgWarning("请选择数据");
        return;
    }
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
    })
        .then(() => {
            staffJoinDel(ids).then((res) => {
                proxy.$modal.msgSuccess("删除成功");
                getList();
            });
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
        });
};
// å¯¼å‡º
const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
    })
        .then(() => {
            proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 1}, "人员入职.xlsx");
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
        });
};
onMounted(() => {
    searchForm.value.entryDate = [
        dayjs().format("YYYY-MM-DD"),
        dayjs().add(1, "day").format("YYYY-MM-DD"),
    ]
    searchForm.value.entryDateStart = dayjs().format("YYYY-MM-DD")
    searchForm.value.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD")
    getList();
});
</script>
src/views/productionManagement/productionOrder/index.vue
@@ -13,7 +13,7 @@
                />
                <span class="search_title ml10">项目名称:</span>
                <el-input
                    v-model="searchForm.customerName"
                    v-model="searchForm.projectName"
                    style="width: 240px"
                    placeholder="请输入"
                    @change="handleQuery"
@@ -46,65 +46,64 @@
<script setup>
import {onMounted, ref} from "vue";
import {
    listCustomer,
} from "@/api/basicData/customerFile.js";
import { ElMessageBox } from "element-plus";
import dayjs from "dayjs";
import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
const { proxy } = getCurrentInstance();
const tableColumn = ref([
    {
        label: "录入日期",
        prop: "customerName",
        prop: "entryDate",
        width: 120,
    },
    {
        label: "合同号",
        prop: "taxpayerIdentificationNumber",
        prop: "salesContractNo",
        width: 220,
    },
    {
        label: "客户合同号",
        prop: "addressPhone",
        prop: "customerContractNo",
        width: 250,
    },
    {
        label: "客户名称",
        prop: "contactPerson",
        prop: "customerName",
        width: 250,
    },
    {
        label: "项目名称",
        prop: "contactPhone",
        width:150
        prop: "projectName",
        width:300
    },
    {
        label: "产品大类",
        prop: "basicBankAccount",
        width: 220,
        prop: "productCategory",
        width: 160,
    },
    {
        label: "规格型号",
        prop: "bankAccount",
        prop: "specificationModel",
        width: 220,
    },
    {
        label: "单位",
        prop: "bankCode",
        width:220
        prop: "unit",
        width:90
    },
    {
        label: "数量",
        prop: "maintainer",
        prop: "quantity",
    },
    {
        label: "排产数量",
        prop: "maintenanceTime",
        prop: "schedulingNum",
        width: 100,
    },
    {
        label: "完工数量",
        prop: "maintenanceTime",
        prop: "successNum",
        width: 100,
    },
]);
@@ -119,12 +118,10 @@
const data = reactive({
    searchForm: {
        customerName: "",
        entryDate: [
            dayjs().format("YYYY-MM-DD"),
            dayjs().add(1, "day").format("YYYY-MM-DD"),
        ], // å½•入日期
        entryDateStart: dayjs().format("YYYY-MM-DD"),
        entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
        projectName: "",
        entryDate: [], // å½•入日期
        entryDateStart: '',
        entryDateEnd: '',
    },
});
const { searchForm } = toRefs(data);
@@ -142,21 +139,26 @@
};
const changeDaterange = (value) => {
    if (value) {
        searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
        searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
        searchForm.value.entryDateStart = value[0];
        searchForm.value.entryDateEnd = value[1];
    } else {
        searchForm.entryDateStart = undefined;
        searchForm.entryDateEnd = undefined;
        searchForm.value.entryDateStart = undefined;
        searchForm.value.entryDateEnd = undefined;
    }
    handleQuery();
};
const getList = () => {
    tableLoading.value = true;
    listCustomer({ ...searchForm.value, ...page }).then((res) => {
    // æž„造一个新的对象,不包含entryDate字段
    const params = { ...searchForm.value, ...page };
    params.entryDate = undefined
    schedulingListPage(params).then((res) => {
        tableLoading.value = false;
        tableData.value = res.records;
        page.total = res.total;
    });
        tableData.value = res.data.records;
        page.total = res.data.total;
    }).catch(() => {
        tableLoading.value = false;
    })
};
// å¯¼å‡º
@@ -167,7 +169,7 @@
        type: "warning",
    })
        .then(() => {
            proxy.download("/basic/customer/export", {}, "客户档案.xlsx");
            proxy.download("/salesLedger/scheduling/export", {}, "生产订单.xlsx");
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
@@ -175,6 +177,12 @@
};
onMounted(() => {
    searchForm.value.entryDate = [
        dayjs().format("YYYY-MM-DD"),
        dayjs().add(1, "day").format("YYYY-MM-DD"),
    ]
    searchForm.value.entryDateStart = dayjs().format("YYYY-MM-DD")
    searchForm.value.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD")
    getList();
});
</script>
src/views/productionManagement/productionReporting/components/formDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,155 @@
<template>
  <div>
    <el-dialog
        v-model="dialogFormVisible"
        title="生产报工"
        width="70%"
        @close="closeDia"
    >
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="排产数量:" prop="schedulingNum">
              <el-input v-model="form.schedulingNum" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="本次生产数量:" prop="finishedNum">
                            <el-input-number
                                v-model="form.finishedNum"
                                placeholder="请输入"
                                :min="0"
                                :step="0.1"
                                :precision="2"
                                clearable
                                style="width: 100%"
                                @change="changeNum"
                            />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="待生产数量:" prop="pendingNum">
              <el-input v-model="form.pendingNum" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="生产人:" prop="schedulingUserId">
                            <el-select
                                v-model="form.schedulingUserId"
                                placeholder="选择人员"
                                style="width: 100%;"
                            >
                                <el-option
                                    v-for="user in userList"
                                    :key="user.userId"
                                    :label="user.nickName"
                                    :value="user.userId"
                                />
                            </el-select>
                        </el-form-item>
                    </el-col>
          <el-col :span="12">
            <el-form-item label="生产日期:" prop="schedulingDate">
              <el-date-picker
                  v-model="form.schedulingDate"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import {ref} from "vue";
import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import {productionReport, productionReportUpdate} from "@/api/productionManagement/productionReporting.js";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
const userList = ref([])
const dialogFormVisible = ref(false);
const operationType = ref('')
const data = reactive({
  form: {
        successNum: "",
        schedulingNum: "",
        finishedNum: "",
        schedulingUserId: "",
        schedulingDate: "",
  },
  rules: {
        schedulingNum: [{ required: true, message: "请输入", trigger: "blur" },],
  },
});
const { form, rules } = toRefs(data);
// æ‰“开弹框
const openDialog = (type, row) => {
  operationType.value = type;
  dialogFormVisible.value = true;
    userListNoPageByTenantId().then((res) => {
        userList.value = res.data;
    });
    form.value = {...row}
}
const changeNum = (value) => {
    if (value > form.value.schedulingNum) {
        form.value.finishedNum = form.value.schedulingNum;
        proxy.$modal.msgWarning('本次生产数量不可大于排产数量')
    }
    form.value.pendingNum = form.value.schedulingNum - form.value.finishedNum;
}
// æäº¤äº§å“è¡¨å•
const submitForm = () => {
  proxy.$refs.formRef.validate(valid => {
    if (valid) {
      form.value.staffState = 1
      if (operationType.value === "add") {
                productionReport(form.value).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      } else {
                productionReportUpdate(form.value).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      }
    }
  })
}
// å…³é—­å¼¹æ¡†
const closeDia = () => {
  proxy.resetForm("formRef");
  dialogFormVisible.value = false;
  emit('close')
};
defineExpose({
  openDialog,
});
</script>
<style scoped>
</style>
src/views/productionManagement/productionReporting/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,426 @@
<template>
    <div class="app-container">
        <div class="search_form">
            <el-form :model="searchForm" :inline="true">
                <el-form-item label="客户名称:">
                    <el-input v-model="searchForm.customerName" placeholder="请输入" clearable prefix-icon="Search"
                                        @change="handleQuery" />
                </el-form-item>
                <el-form-item label="项目名称:">
                    <el-input v-model="searchForm.projectName" placeholder="请输入" clearable prefix-icon="Search"
                                        @change="handleQuery" />
                </el-form-item>
                <el-form-item label="排产日期:">
                    <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                                                    placeholder="请选择" clearable @change="changeDaterange" />
                </el-form-item>
                <el-form-item label="状态:">
                    <el-select v-model="searchForm.status" placeholder="请选择状态" style="width: 140px" clearable>
                        <el-option label="待生产" :value="1"></el-option>
                        <el-option label="已报工" :value="0"></el-option>
                        <el-option label="生产中" :value="2"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="handleQuery">搜索</el-button>
                </el-form-item>
            </el-form>
        </div>
        <div class="table_list">
            <div style="text-align: right" class="mb10">
                <el-button type="primary" @click="openForm('add')">生产报工</el-button>
            </div>
            <PIMTable
                rowKey="id"
                :column="tableColumn"
                :tableData="tableData"
                :page="page"
                :isSelection="true"
                :expandRowKeys="expandedRowKeys"
                @expand-change="expandChange"
                @selection-change="handleSelectionChange"
                :tableLoading="tableLoading"
                @pagination="pagination"
                :total="page.total"
            >
                <template #expand="{ row }">
                    <el-table
                        :data="expandData"
                        border
                        show-summary
                        :summary-method="summarizeMainTable"
                        v-loading="childrenLoading"
                    >
                        <el-table-column
                            align="center"
                            label="序号"
                            type="index"
                            width="60"
                        />
                        <el-table-column label="本次生产数量" prop="finishedNum" align="center">
                            <template #default="scope">
                                <el-input-number :step="0.01" :min="0" style="width: 100%"
                                                                 v-model="scope.row.finishedNum"
                                                                 :disabled="!scope.row.editType"
                                                                 :precision="2"
                                                                 placeholder="请输入"
                                                                 clearable
                                                                 @change="changeNum(scope.row)"
                                />
                            </template>
                        </el-table-column>
<!--                        <el-table-column label="待生产数量" prop="pendingNum" width="240" align="center"></el-table-column>-->
                        <el-table-column label="生产人" prop="schedulingUserId" width="240">
                            <template #default="scope">
                                <el-select
                                    v-model="scope.row.schedulingUserId"
                                    placeholder="选择人员"
                                    :disabled="!scope.row.editType"
                                    style="width: 100%;"
                                >
                                    <el-option
                                        v-for="user in userList"
                                        :key="user.userId"
                                        :label="user.nickName"
                                        :value="user.userId"
                                    />
                                </el-select>
                            </template>
                        </el-table-column>
                        <el-table-column label="生产日期" prop="schedulingDate" width="240">
                            <template #default="scope">
                                <el-date-picker
                                    v-model="scope.row.schedulingDate"
                                    type="date"
                                    :disabled="!scope.row.editType"
                                    placeholder="请选择日期"
                                    value-format="YYYY-MM-DD"
                                    format="YYYY-MM-DD"
                                    clearable
                                    style="width: 100%"
                                />
                            </template>
                        </el-table-column>
                        <el-table-column label="操作" width="60">
                            <template #default="scope">
                                <el-button
                                    link
                                    type="primary"
                                    size="small"
                                    @click="changeEditType(scope.row)"
                                    v-if="!scope.row.editType"
                                >编辑</el-button
                                >
                                <el-button
                                    link
                                    type="primary"
                                    size="small"
                                    @click="saveReceiptPayment(scope.row)"
                                    v-if="scope.row.editType"
                                >保存</el-button
                                >
                            </template>
                        </el-table-column>
                    </el-table>
                </template>
            </PIMTable>
        </div>
        <form-dia ref="formDia" @close="handleQuery"></form-dia>
    </div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import FormDia from "@/views/productionManagement/productionReporting/components/formDia.vue";
import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
import {ElMessageBox} from "element-plus";
import dayjs from "dayjs";
import {
    productionReportUpdate,
    workListPage,
    workListPageById
} from "@/api/productionManagement/productionReporting.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
const data = reactive({
    searchForm: {
        staffName: "",
        entryDate: [
            dayjs().format("YYYY-MM-DD"),
            dayjs().add(1, "day").format("YYYY-MM-DD"),
        ], // å½•入日期
        entryDateStart: dayjs().format("YYYY-MM-DD"),
        entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
    },
});
const { searchForm } = toRefs(data);
const expandedRowKeys = ref([]);
const expandData = ref([]);
const userList = ref([])
const tableColumn = ref([
    {
        type: "expand",
        dataType: "slot",
        slot: "expand",
    },
    {
        label: "状态",
        prop: "status",
        dataType: "tag",
        formatData: (params) => {
            if (params == 0) {
                return "已报工";
            } else if (params == 1) {
                return "待生产";
            } else {
                return '生产中';
            }
        },
        formatType: (params) => {
            if (params == 0) {
                return "success";
            } else if (params == 1) {
                return "primary";
            } else {
                return 'warning';
            }
        },
    },
    {
        label: "排产日期",
        prop: "schedulingDate",
        width: 120,
    },
    {
        label: "排产人",
        prop: "schedulingUserName",
    },
    {
        label: "合同号",
        prop: "salesContractNo",
        width: 200,
    },
    {
        label: "客户合同号",
        prop: "customerContractNo",
        width: 200,
    },
    {
        label: "客户名称",
        prop: "customerName",
        width: 200,
    },
    {
        label: "项目名称",
        prop: "projectName",
        width:300
    },
    {
        label: "产品大类",
        prop: "productCategory",
        width: 150,
    },
    {
        label: "规格型号",
        prop: "specificationModel",
        width: 150,
    },
    {
        label: "单位",
        prop: "unit",
    },
    {
        label: "工序",
        prop: "process",
    },
    {
        label: "排产数量",
        prop: "schedulingNum",
        width: 100,
    },
    {
        label: "生产数量",
        prop: "finishedNum",
        width: 100,
    },
    {
        label: "待生产数量",
        prop: "pendingFinishNum",
        width: 100,
    },
]);
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const childrenLoading = ref(false);
const page = reactive({
    current: 1,
    size: 100,
    total: 0,
});
const formDia = ref()
const { proxy } = getCurrentInstance()
// æŸ¥è¯¢åˆ—表
/** æœç´¢æŒ‰é’®æ“ä½œ */
const handleQuery = () => {
    page.current = 1;
    getList();
};
const changeDaterange = (value) => {
    if (value) {
        searchForm.value.entryDateStart = value[0];
        searchForm.value.entryDateEnd = value[1];
    } else {
        searchForm.value.entryDateStart = undefined;
        searchForm.value.entryDateEnd = undefined;
    }
    handleQuery();
};
const pagination = (obj) => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
};
const getList = () => {
    tableLoading.value = true;
    const params = { ...searchForm.value, ...page };
    params.entryDate = undefined
    expandedRowKeys.value = []
    workListPage(params).then(res => {
        tableLoading.value = false;
        tableData.value = res.data.records.map(item => ({
            ...item,
            pendingFinishNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0)
        }));
        page.total = res.data.total;
    }).catch(err => {
        tableLoading.value = false;
    })
};
// å±•开行
const expandChange = (row, expandedRows) => {
    userListNoPageByTenantId().then((res) => {
        userList.value = res.data;
    });
    if (expandedRows.length > 0) {
        nextTick(() => {
            expandedRowKeys.value = [];
            try {
                childrenLoading.value = true;
                workListPageById({ id: row.id }).then((res) => {
                    childrenLoading.value = false;
                    const index = tableData.value.findIndex((item) => item.id === row.id);
                    if (index > -1) {
                        expandData.value = res.data.map(item => ({
                            ...item,
                            pendingNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0)
                        }));
                    }
                    expandedRowKeys.value.push(row.id);
                });
            } catch (error) {
                childrenLoading.value = false;
                console.log(error);
            }
        })
    } else {
        expandedRowKeys.value = [];
    }
};
const changeNum = (row) => {
    // æ‰¾åˆ°çˆ¶è¡¨æ ¼æ•°æ®
    const parentRow = tableData.value.find(item => item.id === expandedRowKeys.value[0]);
    // è®¡ç®—所有子表格 finishedNum çš„æ€»å’Œ
    const totalFinishedNum = expandData.value.reduce((sum, item) => sum + (Number(item.finishedNum) || 0), 0);
    // çˆ¶è¡¨æ ¼çš„æŽ’产数量
    const schedulingNum = parentRow ? Number(parentRow.schedulingNum) : 0;
    if (totalFinishedNum > schedulingNum) {
        // å›žé€€æœ¬æ¬¡è¾“å…¥
        row.finishedNum = schedulingNum - (totalFinishedNum - Number(row.finishedNum));
        proxy.$modal.msgWarning('所有本次生产数量之和不可大于排产数量');
    }
    row.pendingNum = row.schedulingNum - row.finishedNum;
}
// ç¼–辑修改状态
const changeEditType = (row) => {
    row.editType = !row.editType;
};
// ä¿å­˜è®°å½•
const saveReceiptPayment = (row) => {
    productionReportUpdate(row).then((res) => {
        row.editType = !row.editType;
        getList();
        proxy.$modal.msgSuccess("提交成功");
    });
};
// è¡¨æ ¼é€‰æ‹©æ•°æ®
const handleSelectionChange = (selection) => {
    selectedRows.value = selection;
};
const summarizeMainTable = (param) => {
    return proxy.summarizeTable(param, [
        "finishedNum"
    ]);
};
// æ‰“开弹框
const openForm = (type, row) => {
    if (selectedRows.value.length !== 1) {
        proxy.$message.error("请选择一条数据");
        return;
    }
    if (selectedRows.value[0].pendingFinishNum == 0) {
        proxy.$message.warning("无需再报工");
        return;
    }
    nextTick(() => {
        const rowInfo = type === 'add' ? selectedRows.value[0] : row
        formDia.value?.openDialog(type, rowInfo)
    })
};
// åˆ é™¤
const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
        ids = selectedRows.value.map((item) => item.id);
    } else {
        proxy.$modal.msgWarning("请选择数据");
        return;
    }
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
    })
        .then(() => {
            staffJoinDel(ids).then((res) => {
                proxy.$modal.msgSuccess("删除成功");
                getList();
            });
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
        });
};
// å¯¼å‡º
const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
    })
        .then(() => {
            proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 1}, "人员入职.xlsx");
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
        });
};
onMounted(() => {
    getList();
});
</script>
<style scoped></style>