818 lines
31 KiB
Vue
818 lines
31 KiB
Vue
<template>
|
||
<div class="procurementPlan">
|
||
<el-row :gutter="20">
|
||
<el-col :span="13">
|
||
<el-card>
|
||
<div style="display: flex;align-items: center;height: 120px;justify-content: space-around;">
|
||
<div class="img">
|
||
<img src="/assets/caigou.png" alt="">
|
||
</div>
|
||
<div class="item">
|
||
<div class="text">
|
||
待审批计划
|
||
</div>
|
||
<div class="count" style="color: rgba(255, 178, 30, 1);">
|
||
12
|
||
</div>
|
||
</div>
|
||
<div class="item">
|
||
<div class="text">
|
||
已批准计划
|
||
</div>
|
||
<div class="count" style="color: rgba(67, 101, 220, 1);">
|
||
28
|
||
</div>
|
||
</div>
|
||
<div class="item">
|
||
<div class="text">
|
||
采购中计划
|
||
</div>
|
||
<div class="count" style="color: rgba(113, 214, 213, 1);">
|
||
15
|
||
</div>
|
||
</div>
|
||
<div class="item">
|
||
<div class="text">
|
||
已完成计划
|
||
</div>
|
||
<div class="count" style="color: rgba(0, 184, 122, 1);">
|
||
86
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-card>
|
||
</el-col>
|
||
<el-col :span="11">
|
||
<el-card>
|
||
<div style="display: flex;align-items: center;height: 120px;justify-content: space-around;">
|
||
<div class="img">
|
||
<img src="/assets/qian.jpg" alt="">
|
||
</div>
|
||
<div class="item">
|
||
<div class="text">
|
||
本年度已采购金额
|
||
</div>
|
||
<div class="count" style="color: rgba(255, 153, 0, 1);">
|
||
520,000.00
|
||
</div>
|
||
</div>
|
||
<div class="item">
|
||
<div class="text">
|
||
本年度采购预算金额
|
||
</div>
|
||
<div class="count" style="color: rgba(67, 101, 220, 1);">
|
||
3,000,000.00
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-card>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row style="margin-top: 20px;">
|
||
<el-col :span="24">
|
||
<el-card style="border-radius: 10px;">
|
||
<div class="content">
|
||
<div class="tabs">
|
||
<el-button type="success">导出</el-button>
|
||
<el-button type="primary" @click="isNewProcurementDialogVisible = true">新建采购申请单</el-button>
|
||
</div>
|
||
|
||
<!-- 标签页导航 -->
|
||
<div class="tabs">
|
||
<!-- <el-badge :value="pendingCount" type="warning">
|
||
<el-button :type="activeTab === 'pending' ? 'primary' : ''"
|
||
@click="changeTab('pending')">待审批</el-button>
|
||
</el-badge>
|
||
<el-badge :value="purchasingCount" type="info">
|
||
<el-button :type="activeTab === 'purchasing' ? 'primary' : ''"
|
||
@click="changeTab('purchasing')">采购中</el-button>
|
||
</el-badge>
|
||
<el-badge :value="rejectedCount" type="danger">
|
||
<el-button :type="activeTab === 'rejected' ? 'primary' : ''"
|
||
@click="changeTab('rejected')">
|
||
未通过
|
||
</el-button>
|
||
</el-badge>
|
||
<el-badge :value="approvedCount" type="primary">
|
||
<el-button :type="activeTab === 'approved' ? 'primary' : ''"
|
||
@click="changeTab('approved')">已通过</el-button>
|
||
</el-badge>
|
||
<el-badge :value="completedCount" type="success">
|
||
<el-button :type="activeTab === 'completed' ? 'primary' : ''"
|
||
@click="changeTab('completed')">已完成</el-button>
|
||
</el-badge> -->
|
||
</div>
|
||
<!-- 表格 -->
|
||
<el-table :data="caigouPlanList" border style="width: 100%;margin-top: 15px;">
|
||
<el-table-column label="计划编号" align="center" prop="jihuaBianhao" />
|
||
<el-table-column label="计划名称" align="center" prop="jihuaName" />
|
||
<el-table-column label="申请部门" align="center" prop="caigouDanweiName" />
|
||
<el-table-column label="申请人" align="center" prop="jingbanrenName" />
|
||
<el-table-column prop="createTime" label="申请日期" align="center" />
|
||
<el-table-column label="预计金额" align="center" prop="yujiJine" />
|
||
<el-table-column label="状态" align="center" prop="status">
|
||
<template #default="scope">
|
||
<dict-tag :options="wz_caigou_examine" :value="scope.row.status" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" fixed="right" width="80" align="center">
|
||
<template #default="scope">
|
||
<el-button type="text" @click="handleView(scope.row)">查看</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<!-- 分页 -->
|
||
<div class="pagination-section">
|
||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||
</div>
|
||
</div>
|
||
</el-card>
|
||
</el-col>
|
||
</el-row>
|
||
<el-dialog v-model="isNewProcurementDialogVisible" title="新建采购申请单" width="60%" :close-on-click-modal="false">
|
||
<div class="new-procurement-form">
|
||
<!-- 基础信息 -->
|
||
<div class="form-section">
|
||
<h3>基础信息</h3>
|
||
<!-- 输入框行 -->
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="计划名称">
|
||
<el-input v-model="form.jihuaName" placeholder="请填写计划名称" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="合同名称">
|
||
<el-input v-model="form.hetonName" placeholder="请填写合同名称" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<!-- 下拉框行 -->
|
||
<el-row :gutter="20">
|
||
<el-col :span="8">
|
||
<el-form-item label="合同类型">
|
||
<el-select v-model="form.hetonType" placeholder="请选择">
|
||
<el-option v-for="option in wz_contract_type" :key="option.value"
|
||
:label="option.label" :value="option.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="采购类型">
|
||
<el-select v-model="form.caigouType" placeholder="请选择">
|
||
<el-option v-for="option in wz_purchase_type" :key="option.value"
|
||
:label="option.label" :value="option.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="仓库地址">
|
||
<el-input v-model="form.cangkuUrl" placeholder="请输入仓库地址" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
|
||
<!-- 供应商信息 -->
|
||
<div class="form-section">
|
||
<h3>供应商信息</h3>
|
||
<el-row :gutter="20">
|
||
<el-col :span="6">
|
||
<el-form-item label="供应商单位">
|
||
<el-select v-model="form.danwei" placeholder="请选择">
|
||
<!-- <el-option v-for="option in supplierList" :key="option.value" :label="option.label"
|
||
:value="option.value" /> -->
|
||
<el-option label="供应商1" value="供应商1" />
|
||
<el-option label="供应商1" value="供应商1" />
|
||
<el-option label="供应商1" value="供应商1" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="送货时间">
|
||
<el-date-picker v-model="form.chuhuoTime" type="date" placeholder="请选择送货日期"
|
||
value-format="YYYY-MM-DD" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
|
||
<!-- 产品信息 -->
|
||
<div class="form-section">
|
||
<h3>产品信息</h3>
|
||
<el-table :data="form.opsCaigouPlanChanpinBos" border style="width: 100%">
|
||
<el-table-column prop="chanpinName" label="产品名称">
|
||
<template #default="scope">
|
||
<el-input v-model="scope.row.chanpinName" placeholder="请填写" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="chanpinType" label="产品型号">
|
||
<template #default="scope">
|
||
<el-input v-model="scope.row.chanpinType" placeholder="请填写" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="chanpinMonovalent" label="产品单价">
|
||
<template #default="scope">
|
||
<el-input v-model="scope.row.chanpinMonovalent" placeholder="请填写" type="number"
|
||
@change="calculateTotalPrice(scope.row)" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="goumaiNumber" label="购买数量">
|
||
<template #default="scope">
|
||
<el-input v-model="scope.row.goumaiNumber" placeholder="请填写" type="number"
|
||
@change="calculateTotalPrice(scope.row)" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="danwei" label="单位">
|
||
<template #default="scope">
|
||
<el-input v-model="scope.row.danwei" placeholder="请填写" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="totalPrice" label="合计" :formatter="calculateTotalPrice">
|
||
<template #default="scope">
|
||
<span>{{ calculateTotalPrice(scope.row) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" fixed="right" width="80">
|
||
<template #default="scope">
|
||
<el-button type="text" @click="removeProduct(scope.$index)"
|
||
:disabled="form.opsCaigouPlanChanpinBos.length <= 1">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<el-button type="primary" size="small" @click="addProduct" style="margin-top: 10px">添加产品</el-button>
|
||
</div>
|
||
|
||
<!-- 合同条款 -->
|
||
<div class="form-section">
|
||
<h3>合同条款</h3>
|
||
<el-row :gutter="20">
|
||
<el-col :span="6">
|
||
<el-form-item label="付款方式">
|
||
<el-select v-model="form.fukuantiaojian" placeholder="请选择">
|
||
<el-option v-for="option in wz_payment_terms" :key="option.value"
|
||
:label="option.label" :value="option.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="发票开具方式">
|
||
<el-select v-model="form.fapiaoKjfs" placeholder="请选择">
|
||
<el-option v-for="option in wz_invoicing_way" :key="option.value"
|
||
:label="option.label" :value="option.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
|
||
<!-- 附件上传 -->
|
||
<div class="form-section">
|
||
<h3>附件上传</h3>
|
||
<file-upload ref="fileUploadRef" :isDrag="true" :file-list="form.opsCaigouPlanFilesBos"
|
||
:is-show-tip="false"
|
||
@update:file-list="handleUpdateFileList"
|
||
:file-type="['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf', 'png', 'jpg', 'jpeg']" />
|
||
</div>
|
||
</div>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button @click="cancelNewProcurement">取消</el-button>
|
||
<el-button @click="saveDraft" :loading="buttonLoading">保存草稿</el-button>
|
||
<el-button type="primary" @click="submitProcurement" :loading="buttonLoading">提交申请</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
<style sc oped lang="scss">
|
||
.procurementPlan {
|
||
background-color: #F2F8FC;
|
||
padding: 20px;
|
||
}
|
||
|
||
.img {
|
||
img {
|
||
display: block;
|
||
width: 80px;
|
||
height: 80px;
|
||
}
|
||
}
|
||
|
||
.item {
|
||
text-align: center;
|
||
|
||
.text {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.count {
|
||
font-size: 25px;
|
||
font-weight: 600;
|
||
text-align: left;
|
||
margin-top: 10px;
|
||
}
|
||
}
|
||
|
||
.tabs {
|
||
display: flex;
|
||
gap: 10px;
|
||
padding: 10px 0;
|
||
}
|
||
|
||
.content {
|
||
padding: 10px 0;
|
||
}
|
||
|
||
/* 分页区域样式 */
|
||
.pagination-section {
|
||
background-color: #fff;
|
||
border-radius: 8px;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
margin-top: 15px;
|
||
padding: 10px 0;
|
||
}
|
||
|
||
.pagination-controls .el-pagination {
|
||
margin: 0;
|
||
}
|
||
|
||
.pagination-controls .el-pagination button {
|
||
min-width: 32px;
|
||
height: 32px;
|
||
line-height: 32px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.pagination-controls .el-pagination .el-pager li {
|
||
min-width: 32px;
|
||
height: 32px;
|
||
line-height: 32px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.pagination-controls .el-pagination .el-pager li.active {
|
||
background-color: #409eff;
|
||
color: #fff;
|
||
}
|
||
</style>
|
||
<script setup lang="ts">
|
||
import { ref, reactive, computed } from 'vue';
|
||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||
import { useProcurementDraftStore } from '@/store/modules/procurementDraft';
|
||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||
const { wz_invoicing_way, wz_payment_terms, wz_purchase_type, wz_contract_type, wz_caigou_examine } = toRefs<any>(proxy?.useDict('wz_invoicing_way', 'wz_payment_terms', 'wz_purchase_type', 'wz_contract_type', 'wz_caigou_examine'));
|
||
|
||
import { listCaigouPlan, getSupplierList, addCaigouPlan } from '@/api/wuziguanli/caigouPlan';
|
||
import { CaigouPlanVO, CaigouPlanQuery, CaigouPlanForm } from '@/api/wuziguanli/caigouPlan/types';
|
||
|
||
import { useRouter } from 'vue-router';
|
||
const router = useRouter();
|
||
|
||
|
||
// 导入用户store
|
||
import { useUserStore } from '@/store/modules/user';
|
||
// 获取用户store
|
||
const userStore = useUserStore();
|
||
|
||
const caigouPlanList = ref<CaigouPlanVO[]>([]);
|
||
const buttonLoading = ref(false);
|
||
const loading = ref(true);
|
||
const total = ref(0);
|
||
|
||
const initFormData: CaigouPlanForm = {
|
||
id: undefined,
|
||
projectId: undefined,
|
||
jihuaName: undefined,
|
||
jihuaBianhao: undefined,
|
||
caigouDanwei: undefined,
|
||
caigouDanweiName: undefined,
|
||
jingbanren: undefined,
|
||
jingbanrenName: undefined,
|
||
hetonType: undefined,
|
||
caigouType: undefined,
|
||
cangkuUrl: undefined,
|
||
hetonName: undefined,
|
||
gonyingshangId: 1,
|
||
chuhuoTime: undefined,
|
||
fukuantiaojian: undefined,
|
||
fapiaoKjfs: undefined,
|
||
status: undefined,
|
||
shenheStatus: undefined,
|
||
yujiJine: undefined,
|
||
shijiJine: undefined,
|
||
opsCaigouPlanFilesBos: [],
|
||
opsCaigouPlanChanpinBos: [
|
||
{
|
||
chanpinName: '',
|
||
chanpinType: '',
|
||
chanpinMonovalent: 0,
|
||
goumaiNumber: 0,
|
||
danwei: '',
|
||
totalPrice: 0
|
||
}
|
||
],
|
||
}
|
||
const data = reactive<PageData<CaigouPlanForm, CaigouPlanQuery>>({
|
||
form: { ...initFormData },
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
projectId: undefined,
|
||
jihuaName: undefined,
|
||
jihuaBianhao: undefined,
|
||
caigouDanwei: undefined,
|
||
caigouDanweiName: undefined,
|
||
jingbanren: undefined,
|
||
jingbanrenName: undefined,
|
||
hetonType: undefined,
|
||
caigouType: undefined,
|
||
cangkuUrl: undefined,
|
||
hetonName: undefined,
|
||
gonyingshangId: 1,
|
||
chuhuoTime: undefined,
|
||
fukuantiaojian: undefined,
|
||
fapiaoKjfs: undefined,
|
||
status: undefined,
|
||
shenheStatus: undefined,
|
||
yujiJine: undefined,
|
||
shijiJine: undefined,
|
||
opsCaigouPlanChanpinBos: [
|
||
{
|
||
chanpinName: '',
|
||
chanpinType: '',
|
||
chanpinMonovalent: 0,
|
||
goumaiNumber: 0,
|
||
danwei: '',
|
||
totalPrice: 0
|
||
}
|
||
],
|
||
opsCaigouPlanFilesBos: undefined,
|
||
params: {
|
||
}
|
||
},
|
||
rules: {}
|
||
});
|
||
|
||
const { queryParams, form, rules } = toRefs(data);
|
||
|
||
/** 查询运维-物资-采购计划单列表 */
|
||
const getList = async () => {
|
||
loading.value = true;
|
||
const res = await listCaigouPlan(queryParams.value);
|
||
caigouPlanList.value = res.rows;
|
||
total.value = res.total;
|
||
loading.value = false;
|
||
}
|
||
// 新增采购计划单
|
||
const addCaigouPlans = async () => {
|
||
buttonLoading.value = true; // 显示按钮加载状态
|
||
try {
|
||
// 提交表单数据到后端
|
||
const res = await addCaigouPlan(form.value);
|
||
|
||
if (res.code === 200) {
|
||
ElMessage({ message: '采购申请单已成功提交,等待审批!', type: 'success' });
|
||
|
||
// 刷新列表数据
|
||
getList();
|
||
|
||
// 关闭对话框并重置表单
|
||
resetNewProcurementForm();
|
||
isNewProcurementDialogVisible.value = false;
|
||
} else {
|
||
// 显示详细的错误信息
|
||
ElMessage({
|
||
message: res.msg || '新增采购计划单失败,请重试',
|
||
type: 'error'
|
||
});
|
||
}
|
||
} catch (error) {
|
||
ElMessage({ message: '失败', type: 'error' });
|
||
} finally {
|
||
buttonLoading.value = false; // 无论成功失败,都关闭加载状态
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// 采购商列表
|
||
const supplierList = ref([]);
|
||
const getSupplierLists = async () => {
|
||
const res = await getSupplierList({
|
||
projectId: userStore.selectedProject.id
|
||
});
|
||
supplierList.value = res.rows;
|
||
|
||
}
|
||
|
||
|
||
|
||
onMounted(() => {
|
||
getList();
|
||
getSupplierLists();
|
||
});
|
||
// 监听用户选择的项目变化
|
||
watch(() => userStore.selectedProject, (newProject) => {
|
||
if (newProject && newProject.id) {
|
||
queryParams.value.projectId = newProject.id;
|
||
// 只在新增表单时设置projectId,编辑表单保留原有值
|
||
if (!form.value.id) {
|
||
form.value.projectId = newProject.id;
|
||
}
|
||
// 调用getList刷新数据
|
||
getList();
|
||
}
|
||
}, { immediate: true, deep: true });
|
||
// 新建采购申请单对话框是否可见
|
||
const isNewProcurementDialogVisible = ref(false);
|
||
|
||
// 跳转查看详情
|
||
const handleView = (row) => {
|
||
router.push({
|
||
path: '/materialManagement/planDetails',
|
||
query: {
|
||
id: row.id
|
||
}
|
||
});
|
||
};
|
||
// 计算产品总价
|
||
const calculateTotalPrice = (row) => {
|
||
if (!row.chanpinMonovalent || !row.goumaiNumber) {
|
||
row.totalPrice = '0.00'; // 保存计算结果到对象中
|
||
return '0.00';
|
||
}
|
||
const price = parseFloat(row.chanpinMonovalent);
|
||
const quantity = parseInt(row.goumaiNumber);
|
||
if (isNaN(price) || isNaN(quantity)) {
|
||
row.totalPrice = '0.00'; // 保存计算结果到对象中
|
||
return '0.00';
|
||
}
|
||
const result = (price * quantity).toFixed(2);
|
||
row.totalPrice = result; // 保存计算结果到对象中
|
||
return result;
|
||
};
|
||
|
||
// 添加产品
|
||
const addProduct = () => {
|
||
form.value.opsCaigouPlanChanpinBos.push({
|
||
chanpinName: '',
|
||
chanpinType: '',
|
||
chanpinMonovalent: 0,
|
||
goumaiNumber: 0,
|
||
danwei: '',
|
||
totalPrice: 0
|
||
});
|
||
};
|
||
|
||
// 删除产品
|
||
const removeProduct = (index) => {
|
||
if (form.value.opsCaigouPlanChanpinBos.length <= 1) {
|
||
ElMessage({ message: '至少保留一个产品信息', type: 'warning' });
|
||
return;
|
||
}
|
||
form.value.opsCaigouPlanChanpinBos.splice(index, 1);
|
||
};
|
||
|
||
// 重置新建采购申请表单
|
||
const resetNewProcurementForm = () => {
|
||
form.value.jihuaName = '';
|
||
form.value.hetonName = '';
|
||
form.value.hetonType = '';
|
||
form.value.caigouType = '';
|
||
form.value.cangkuUrl = '';
|
||
form.value.danwei = '';
|
||
form.value.chuhuoTime = '';
|
||
form.value.fukuantiaojian = '';
|
||
form.value.fapiaoKjfs = '';
|
||
form.value.opsCaigouPlanChanpinBos = [{
|
||
chanpinName: '',
|
||
chanpinType: '',
|
||
chanpinMonovalent: '',
|
||
goumaiNumber: '',
|
||
danwei: '',
|
||
totalPrice: ''
|
||
}];
|
||
form.value.opsCaigouPlanFilesBos = [];
|
||
};
|
||
|
||
// 取消新建采购申请
|
||
const cancelNewProcurement = () => {
|
||
// 检查是否有未保存的内容
|
||
const hasContent = Object.values(form.value).some(value => {
|
||
if (Array.isArray(value)) {
|
||
return value.length > 0 &&
|
||
value.some(item =>
|
||
typeof item === 'object' &&
|
||
Object.values(item).some(v => v)
|
||
);
|
||
}
|
||
return !!value;
|
||
});
|
||
|
||
if (hasContent) {
|
||
ElMessageBox.confirm('表单内容尚未保存,确定要关闭吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
resetNewProcurementForm();
|
||
isNewProcurementDialogVisible.value = false;
|
||
});
|
||
} else {
|
||
resetNewProcurementForm();
|
||
isNewProcurementDialogVisible.value = false;
|
||
}
|
||
};
|
||
|
||
// 草稿校验函数
|
||
const validateDraft = () => {
|
||
// 草稿只需要计划名称作为必填项
|
||
if (!form.value.jihuaName.trim()) {
|
||
ElMessage({ message: '请填写计划名称', type: 'error' });
|
||
return false;
|
||
}
|
||
|
||
// 检查已填写的产品信息的有效性
|
||
for (let i = 0; i < form.value.opsCaigouPlanChanpinBos.length; i++) {
|
||
const product = form.value.opsCaigouPlanChanpinBos[i];
|
||
if (product.chanpinName && !product.chanpinType) {
|
||
ElMessage({ message: `第${i + 1}行产品:填写了产品名称,请也填写产品型号`, type: 'warning' });
|
||
}
|
||
if (product.productPrice && parseFloat(product.productPrice) <= 0) {
|
||
ElMessage({ message: `第${i + 1}行产品:产品单价应大于0`, type: 'warning' });
|
||
}
|
||
if (product.purchaseQuantity && parseInt(product.purchaseQuantity) <= 0) {
|
||
ElMessage({ message: `第${i + 1}行产品:购买数量应大于0`, type: 'warning' });
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
// 保存草稿
|
||
const saveDraft = async () => {
|
||
// 验证草稿
|
||
if (!validateDraft()) {
|
||
return;
|
||
}
|
||
|
||
buttonLoading.value = true; // 显示按钮加载状态
|
||
try {
|
||
// 使用pinia store保存草稿
|
||
const draftStore = useProcurementDraftStore();
|
||
const savedDraft = draftStore.saveDraft(form.value.jihuaName, form.value);
|
||
|
||
console.log('保存草稿:', {
|
||
draftNumber: savedDraft.draftNumber,
|
||
saveTime: savedDraft.saveTime,
|
||
content: savedDraft.content
|
||
});
|
||
|
||
ElMessage({ message: `草稿已成功保存(编号:${savedDraft.draftNumber}),您可以在草稿箱中查看`, type: 'success' });
|
||
} catch (error) {
|
||
console.error('保存草稿失败:', error);
|
||
ElMessage({
|
||
message: '保存草稿失败,请重试',
|
||
type: 'error'
|
||
});
|
||
} finally {
|
||
buttonLoading.value = false; // 无论成功失败,都关闭加载状态
|
||
}
|
||
};
|
||
|
||
// 表单校验函数
|
||
const validateForm = () => {
|
||
// 基础信息校验
|
||
if (!form.value.jihuaName.trim()) {
|
||
ElMessage({ message: '请填写计划名称', type: 'error' });
|
||
return false;
|
||
}
|
||
|
||
if (!form.value.hetonName.trim()) {
|
||
ElMessage({ message: '请填写合同名称', type: 'error' });
|
||
return false;
|
||
}
|
||
|
||
if (!form.value.hetonType) {
|
||
ElMessage({ message: '请选择合同类型', type: 'error' });
|
||
return false;
|
||
}
|
||
|
||
if (!form.value.caigouType) {
|
||
ElMessage({ message: '请选择采购类型', type: 'error' });
|
||
return false;
|
||
}
|
||
|
||
if (!form.value.cangkuUrl) {
|
||
ElMessage({ message: '请选择仓库地址', type: 'error' });
|
||
return false;
|
||
}
|
||
|
||
if (!form.value.danwei) {
|
||
ElMessage({ message: '请选择供应商单位', type: 'error' });
|
||
return false;
|
||
}
|
||
|
||
// 产品信息校验
|
||
const hasValidProduct = form.value.opsCaigouPlanChanpinBos.some(product => {
|
||
return product.chanpinName &&
|
||
product.chanpinType &&
|
||
product.chanpinMonovalent && parseFloat(product.chanpinMonovalent) > 0 &&
|
||
product.goumaiNumber && parseInt(product.goumaiNumber) > 0 &&
|
||
product.danwei;
|
||
});
|
||
|
||
if (!hasValidProduct) {
|
||
ElMessage({ message: '请至少填写一个有效的产品信息', type: 'error' });
|
||
return false;
|
||
}
|
||
|
||
// 检查每个产品的有效性
|
||
for (let i = 0; i < form.value.opsCaigouPlanChanpinBos.length; i++) {
|
||
const product = form.value.opsCaigouPlanChanpinBos[i];
|
||
if (product.chanpinName || product.chanpinType || product.chanpinMonovalent || product.goumaiNumber) {
|
||
if (!product.chanpinName) {
|
||
ElMessage({ message: `第${i + 1}行产品:请填写产品名称`, type: 'error' });
|
||
return false;
|
||
}
|
||
if (!product.chanpinType) {
|
||
ElMessage({ message: `第${i + 1}行产品:请填写产品型号`, type: 'error' });
|
||
return false;
|
||
}
|
||
if (!product.chanpinMonovalent) {
|
||
ElMessage({ message: `第${i + 1}行产品:请填写产品单价`, type: 'error' });
|
||
return false;
|
||
}
|
||
if (parseFloat(product.chanpinMonovalent) <= 0) {
|
||
ElMessage({ message: `第${i + 1}行产品:产品单价必须大于0`, type: 'error' });
|
||
return false;
|
||
}
|
||
if (!product.goumaiNumber) {
|
||
ElMessage({ message: `第${i + 1}行产品:请填写购买数量`, type: 'error' });
|
||
return false;
|
||
}
|
||
if (parseInt(product.goumaiNumber) <= 0) {
|
||
ElMessage({ message: `第${i + 1}行产品:购买数量必须大于0`, type: 'error' });
|
||
return false;
|
||
}
|
||
if (!product.danwei) {
|
||
ElMessage({ message: `第${i + 1}行产品:请填写单位`, type: 'error' });
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
// 提交申请
|
||
const submitProcurement = async () => {
|
||
// 在提交前,为所有产品行重新计算并保存总价
|
||
form.value.opsCaigouPlanChanpinBos.forEach(product => {
|
||
calculateTotalPrice(product);
|
||
});
|
||
|
||
// 表单验证
|
||
if (!validateForm()) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
// 确认提交
|
||
await ElMessageBox.confirm(
|
||
'确定要提交采购申请单吗?提交后将进入审批流程,不可撤销。',
|
||
'确认提交',
|
||
{
|
||
confirmButtonText: '确认提交',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}
|
||
);
|
||
|
||
// 调用提交函数
|
||
await addCaigouPlans();
|
||
|
||
} catch (error) {
|
||
// 处理用户取消或其他错误
|
||
if (error !== 'cancel') {
|
||
console.error('提交采购申请单时发生错误:', error);
|
||
ElMessage({ message: '提交过程中发生错误,请重试', type: 'error' });
|
||
}
|
||
}
|
||
}
|
||
// });
|
||
|
||
// 处理文件上传完成后获取完整文件列表
|
||
const handleUpdateFileList = (fileList) => {
|
||
form.value.opsCaigouPlanFilesBos = fileList.map(file => ({
|
||
fileId: file.ossId,
|
||
fileName: file.name,
|
||
fileUrl: file.url,
|
||
}));
|
||
};
|
||
</script> |