<template>
|
<view class="account-detail">
|
<PageHeader :title="pageTitle"
|
@back="goBack" />
|
<view class="form-container">
|
<up-form ref="formRef"
|
:model="form"
|
:rules="rules"
|
label-width="120"
|
input-align="right"
|
error-message-align="right">
|
<u-cell-group title="项目信息"
|
class="form-section">
|
<up-form-item label="所属项目"
|
prop="projectId"
|
required
|
border-bottom>
|
<FormPicker v-model="form.projectId"
|
:display-text="form.projectName"
|
type="select"
|
title="选择所属项目"
|
:options="projectOptions"
|
placeholder="请选择所属项目"
|
@change="onProjectChange" />
|
</up-form-item>
|
<up-form-item label="标书名称"
|
prop="bidDocName"
|
required
|
border-bottom>
|
<up-input v-model="form.bidDocName"
|
placeholder="请输入标书名称"
|
clearable />
|
</up-form-item>
|
</u-cell-group>
|
|
<u-cell-group title="招投标单位与日期"
|
class="form-section">
|
<up-form-item label="招标单位"
|
prop="tenderUnit"
|
required
|
border-bottom>
|
<up-input v-model="form.tenderUnit"
|
placeholder="请输入招标单位"
|
clearable />
|
</up-form-item>
|
<up-form-item label="投标单位"
|
prop="bidUnit"
|
required
|
border-bottom>
|
<up-input v-model="form.bidUnit"
|
placeholder="请输入投标单位"
|
clearable />
|
</up-form-item>
|
<up-form-item label="招标日期"
|
prop="tenderDate"
|
required
|
border-bottom>
|
<FormPicker v-model="form.tenderDate"
|
type="date"
|
placeholder="请选择招标日期" />
|
</up-form-item>
|
<up-form-item label="投标日期"
|
prop="bidDate"
|
required
|
border-bottom>
|
<FormPicker v-model="form.bidDate"
|
type="date"
|
placeholder="请选择投标日期" />
|
</up-form-item>
|
</u-cell-group>
|
|
<u-cell-group title="标书款与保证金"
|
class="form-section">
|
<up-form-item label="标书款金额"
|
prop="bidDocFee"
|
border-bottom>
|
<up-input v-model="form.bidDocFee"
|
type="number"
|
placeholder="请输入标书款金额"
|
clearable />
|
</up-form-item>
|
<up-form-item label="标书款状态"
|
prop="bidDocFeeStatus"
|
required
|
border-bottom>
|
<FormPicker v-model="form.bidDocFeeStatus"
|
type="select"
|
title="选择标书款状态"
|
:options="bidDocFeeStatusOptions"
|
placeholder="请选择标书款状态"
|
@change="onFeeStatusChange" />
|
</up-form-item>
|
<up-form-item label="状态变更日期"
|
prop="bidDocFeeStatusChangeDate"
|
border-bottom>
|
<FormPicker v-model="form.bidDocFeeStatusChangeDate"
|
type="date"
|
placeholder="状态变更时自动填当前日期" />
|
</up-form-item>
|
<up-form-item label="投标保证金"
|
prop="bidDeposit"
|
border-bottom>
|
<up-input v-model="form.bidDeposit"
|
type="number"
|
placeholder="请输入投标保证金金额"
|
clearable />
|
</up-form-item>
|
</u-cell-group>
|
|
<u-cell-group title="招投标结果"
|
class="form-section">
|
<up-form-item label="招投标结果"
|
prop="bidResult"
|
required
|
border-bottom>
|
<FormPicker v-model="form.bidResult"
|
type="select"
|
title="选择招投标结果"
|
:options="bidResultOptions"
|
placeholder="请选择招投标结果" />
|
</up-form-item>
|
</u-cell-group>
|
</up-form>
|
</view>
|
|
<FooterButtons :loading="loading"
|
confirmText="保存"
|
@cancel="goBack"
|
@confirm="handleSubmit" />
|
</view>
|
</template>
|
|
<script setup>
|
import { computed, ref } from "vue";
|
import { onLoad } from "@dcloudio/uni-app";
|
import PageHeader from "@/components/PageHeader.vue";
|
import FooterButtons from "@/components/FooterButtons.vue";
|
import FormPicker from "@/components/FormPicker.vue";
|
import { formatDateToYMD } from "@/utils/ruoyi";
|
import { loadDetailData } from "@/utils/detailCache";
|
import { loadProjectOptions, pickProjectName } from "@/utils/projectOptions";
|
import {
|
addOrUpdateBidding,
|
getBiddingDetail,
|
} from "@/api/salesManagement/biddingManagement";
|
|
const formRef = ref();
|
const loading = ref(false);
|
const biddingId = ref("");
|
const projectOptions = ref([]);
|
|
const bidDocFeeStatusOptions = [
|
{ name: "未交", value: "未交" },
|
{ name: "已交", value: "已交" },
|
{ name: "已退", value: "已退" },
|
];
|
|
const bidResultOptions = [
|
{ name: "废标", value: "废标" },
|
{ name: "流标", value: "流标" },
|
{ name: "未中标", value: "未中标" },
|
{ name: "中标待出通知书", value: "中标待出通知书" },
|
{ name: "已出中标通知书", value: "已出中标通知书" },
|
{ name: "已签合同", value: "已签合同" },
|
];
|
|
const form = ref({
|
id: undefined,
|
projectId: "",
|
projectName: "",
|
bidDocName: "",
|
tenderUnit: "",
|
bidUnit: "",
|
tenderDate: "",
|
bidDate: "",
|
bidDocFee: "",
|
bidDocFeeStatus: "",
|
bidDocFeeStatusChangeDate: "",
|
bidDeposit: "",
|
bidResult: "",
|
});
|
|
const rules = {
|
projectId: [{ required: true, message: "请选择所属项目", trigger: "change" }],
|
bidDocName: [{ required: true, message: "请输入标书名称", trigger: "blur" }],
|
tenderUnit: [{ required: true, message: "请输入招标单位", trigger: "blur" }],
|
bidUnit: [{ required: true, message: "请输入投标单位", trigger: "blur" }],
|
tenderDate: [{ required: true, message: "请选择招标日期", trigger: "change" }],
|
bidDate: [{ required: true, message: "请选择投标日期", trigger: "change" }],
|
bidDocFeeStatus: [
|
{ required: true, message: "请选择标书款状态", trigger: "change" },
|
],
|
bidResult: [{ required: true, message: "请选择招投标结果", trigger: "change" }],
|
};
|
|
const pageTitle = computed(() =>
|
biddingId.value ? "编辑招投标" : "新增招投标"
|
);
|
|
const goBack = () => uni.navigateBack();
|
|
const numOrNull = value =>
|
value === "" || value === null || value === undefined
|
? null
|
: Number.isNaN(Number(value))
|
? null
|
: Number(value);
|
|
const onProjectChange = (value, item) => {
|
form.value.projectName = pickProjectName(item);
|
};
|
|
// 标书款状态变更且日期为空时自动填当天
|
const onFeeStatusChange = () => {
|
if (form.value.bidDocFeeStatus && !form.value.bidDocFeeStatusChangeDate) {
|
form.value.bidDocFeeStatusChangeDate = formatDateToYMD(Date.now());
|
}
|
};
|
|
const loadOptions = async () => {
|
try {
|
projectOptions.value = await loadProjectOptions();
|
} catch (error) {
|
projectOptions.value = [];
|
}
|
};
|
|
const loadDetail = async () => {
|
let data = null;
|
try {
|
data = await loadDetailData({
|
cacheKey: "biddingDetail",
|
id: biddingId.value,
|
fetcher: getBiddingDetail,
|
});
|
} catch (error) {
|
data = null;
|
}
|
if (!data) {
|
uni.showToast({ title: "未找到招投标信息", icon: "none" });
|
return;
|
}
|
|
form.value = {
|
id: data.id,
|
projectId: data.projectId ?? "",
|
projectName: data.projectName || "",
|
bidDocName: data.bidDocName || "",
|
tenderUnit: data.tenderUnit || "",
|
bidUnit: data.bidUnit || "",
|
tenderDate: (data.tenderDate || "").slice(0, 10),
|
bidDate: (data.bidDate || "").slice(0, 10),
|
bidDocFee: data.bidDocFee ?? "",
|
bidDocFeeStatus: data.bidDocFeeStatus || "",
|
bidDocFeeStatusChangeDate: (
|
data.bidDocFeeStatusChangeDate || ""
|
).slice(0, 10),
|
bidDeposit: data.bidDeposit ?? "",
|
bidResult: data.bidResult || "",
|
};
|
};
|
|
const handleSubmit = async () => {
|
const valid = await formRef.value.validate().catch(() => false);
|
if (!valid) return;
|
|
const payload = {
|
id: form.value.id,
|
projectId: form.value.projectId,
|
projectName: form.value.projectName,
|
bidDocName: form.value.bidDocName,
|
tenderUnit: form.value.tenderUnit,
|
bidUnit: form.value.bidUnit,
|
tenderDate: form.value.tenderDate,
|
bidDate: form.value.bidDate,
|
bidDocFee: numOrNull(form.value.bidDocFee),
|
bidDocFeeStatus: form.value.bidDocFeeStatus,
|
bidDocFeeStatusChangeDate: form.value.bidDocFeeStatusChangeDate || null,
|
bidDeposit: numOrNull(form.value.bidDeposit),
|
bidResult: form.value.bidResult,
|
};
|
|
loading.value = true;
|
addOrUpdateBidding(payload)
|
.then(() => {
|
uni.showToast({ title: "保存成功", icon: "success" });
|
setTimeout(() => uni.navigateBack(), 1000);
|
})
|
.catch(() => {
|
uni.showToast({ title: "保存失败", icon: "none" });
|
})
|
.finally(() => {
|
loading.value = false;
|
});
|
};
|
|
onLoad(options => {
|
loadOptions();
|
if (options?.id) {
|
biddingId.value = options.id;
|
form.value.id = options.id;
|
loadDetail();
|
} else {
|
form.value.tenderDate = formatDateToYMD(Date.now());
|
form.value.bidDate = formatDateToYMD(Date.now());
|
}
|
});
|
</script>
|
|
<style scoped lang="scss">
|
@import "@/static/scss/form-common.scss";
|
|
.account-detail {
|
min-height: 100vh;
|
background: #f8f9fa;
|
padding-bottom: 100px;
|
}
|
|
.form-container {
|
padding: 12px 12px 0;
|
}
|
|
.form-section {
|
margin-bottom: 12px;
|
border-radius: 12px;
|
overflow: hidden;
|
box-shadow: 0 2px 10px rgba(15, 35, 95, 0.05);
|
}
|
|
:deep(.u-cell-group__title) {
|
padding: 14px 18px 10px !important;
|
font-size: 15px !important;
|
font-weight: 600 !important;
|
color: #22324d !important;
|
background: #f8fbff !important;
|
}
|
</style>
|