zhangwei
2025-08-27 dade6a8b4772abc113383246d05ab59162630e7c
src/views/system/dept/uploadform.vue
@@ -19,19 +19,46 @@
const props = withDefaults(defineProps<TenderProps>(), {
  formInline: () => ({
    id: "", // 主键Id(必填)
    tenderId: "",
    higherDeptOptions: [],
    projectName: "",
    toubiaoStartDate: "", // 投标报名开始时间(必填,格式:yyyy-MM-dd HH:mm:ss)
    toubiaoEndDate: "", // 投标报名结束时间(必填,格式:yyyy-MM-dd HH:mm:ss)
    kaibiaoDate: "", // 开标时间(必填,格式:yyyy-MM-dd HH:mm:ss)
    zhaobiaowenjian: "", // 招标文件(必填,长度1-512字符)
    zhaobiaowenjianName: "",
    biangengwenjian: "",
    biangengwenjianName: "",
    fujian: "", // 附件(可选,最大长度512字符,可为空)
    fujianName: "", // 附件(可选,最大长度512字符,可为空)
    kaibiaodidian: "" // 开标地点(必填,长度1-250字符)
  }),
  isChange: null
  isChange: null,
  changeDetail: null
});
const gonggaoRules = reactive({
interface FormInlineType {
  // 项目标题
  projectName: string | null | undefined;
  // 投标报名开始时间(通常为ISO日期字符串格式)
  toubiaoStartDate: string | null | undefined;
  // 投标报名结束时间
  toubiaoEndDate: string | null | undefined;
  // 开标时间
  kaibiaoDate: string | null | undefined;
  // 招标文件(可能是文件路径、ID或文件对象)
  zhaobiaowenjian: string | null | undefined;
  // 招标文件名(可能是文件路径、ID或文件对象)
  zhaobiaowenjianName?: string | null | undefined;
  // 变更文件
  biangengwenjian: string | null | undefined;
  // 变更文件
  biangengwenjianName?: string | null | undefined;
  // 附件(文本描述或路径)
  fujian: string | null | undefined;
  // 开标地点
  kaibiaodidian: string | null | undefined;
}
const gonggaoRules = reactive<FormRules<FormInlineType>>({
  projectName: [{ required: true, message: "请输入标题", trigger: "change" }],
  toubiaoStartDate: [
    { required: true, message: "请选择投标报名开始时间", trigger: "change" }
@@ -93,6 +120,7 @@
const newFormInline = ref(props.formInline);
const validateForm = reactive({
  fileList: [],
  fileListFile: [],
  date: ""
});
const upload = ref<UploadInstance>();
@@ -136,20 +164,16 @@
  fetchCredentials(file);
  // upload.value!.submit();
};
// state.formDataNew = {
//   policy: res.result.policy, //表单域
//   "x-oss-signature-version": res.result.x_oss_signature_version, //指定签名的版本和算法
//   "x-oss-credential": res.result.x_oss_credential, //指明派生密钥的参数集
//   "x-oss-date": res.result.x_oss_date, //请求的时间
//   "x-oss-signature": res.result.signature, //签名认证描述信息
//   "x-oss-security-token": res.result.security_token, //安全令牌
//   success_action_status: "200" //上传成功后响应状态码
// };
const fetchCredentials = async file => {
const handleChangeFile = async file => {
  if (file.status !== "ready") return;
  // const isLt10M = file.size / 1024 / 1024 < 10;
  // fetchCredentials(file);
  // 这里应调用你自己的后端接口获取临时凭证
  let res = await getUploadToken();
  if (res.code == 200) {
    let keyVal = generateTimestampWithRandom(res.result.DirPath, file.name);
    let upUrl = res.result.url;
    let upPath = res.result.DirPath;
    let formData = new FormData();
    formData.append("policy", res.result.policy);
    formData.append(
@@ -166,17 +190,60 @@
    formData.append("key", keyVal); // 文件名
    formData.append("file", file.raw); // file 必须为最后一个表单域
    uploadFileAli(formData, res.result.url).then(res => {
      let path = res.result.url + "/" + res.result.DirPath + keyVal;
      console.log(path);
      let path = `${upUrl}${keyVal}`;
      newFormInline.value.fujian += newFormInline.value.fujian
        ? `,${path}`
        : path;
      newFormInline.value.fujianName += newFormInline.value.fujianName
        ? `,${file.name}`
        : file.name;
    });
  }
};
// state.formDataNew = {
//   policy: res.result.policy, //表单域
//   "x-oss-signature-version": res.result.x_oss_signature_version, //指定签名的版本和算法
//   "x-oss-credential": res.result.x_oss_credential, //指明派生密钥的参数集
//   "x-oss-date": res.result.x_oss_date, //请求的时间
//   "x-oss-signature": res.result.signature, //签名认证描述信息
//   "x-oss-security-token": res.result.security_token, //安全令牌
//   success_action_status: "200" //上传成功后响应状态码
// };
const fetchCredentials = async file => {
  // 这里应调用你自己的后端接口获取临时凭证
  let res = await getUploadToken();
  if (res.code == 200) {
    let keyVal = generateTimestampWithRandom(res.result.DirPath, file.name);
    let upUrl = res.result.url;
    let upPath = res.result.DirPath;
    let formData = new FormData();
    formData.append("policy", res.result.policy);
    formData.append(
      "x-oss-signature-version",
      res.result.x_oss_signature_version
    );
    formData.append("x-oss-credential", res.result.x_oss_credential);
    formData.append("x-oss-date", res.result.x_oss_date);
    // formData.append("Signature", res.result.signature);
    formData.append("x-oss-signature", res.result.signature);
    formData.append("x-oss-security-token", res.result.security_token);
    // formData.append("x-oss-content-type", "application/pdf");
    formData.append("success_action_status", "200");
    formData.append("key", keyVal); // 文件名
    formData.append("file", file.raw); // file 必须为最后一个表单域
    uploadFileAli(formData, res.result.url).then(res => {
      let path = `${upUrl}${keyVal}`;
      if (props.isChange) {
        newFormInline.value.biangengwenjian = path;
        newFormInline.value.biangengwenjianName = file.name;
      } else {
        newFormInline.value.zhaobiaowenjian = path;
        newFormInline.value.zhaobiaowenjianName = file.name;
      }
    });
  }
};
const defaultTime = new Date(2000, 1, 1, 9, 30, 0);
const beforeAvatarUpload: UploadProps["beforeUpload"] = rawFile => {
  isLoading.value = true;
  if (rawFile.type !== "application/pdf") {
@@ -201,7 +268,16 @@
  upload.value!.handleStart(file);
};
defineExpose({ getRef });
onMounted(async () => {});
onMounted(async () => {
  if (props.formInline.biangengwenjianName) {
    validateForm.fileList = [
      {
        name: props.formInline.biangengwenjianName,
        url: props.formInline.biangengwenjian
      }
    ];
  }
});
</script>
<template>
@@ -209,10 +285,21 @@
    ref="ruleFormRef"
    :model="newFormInline"
    :rules="gonggaoRules"
    label-width="140px"
    :label-width="props.changeDetail ? '50px' : '140px'"
  >
    <el-row :gutter="30">
      <div v-if="props.isChange">
    <el-row v-if="props.changeDetail" :gutter="10">
      <re-col :value="24" :xs="24" :sm="24">
        <el-form-item label="标题" prop="projectName">
          <el-input
            v-model="newFormInline.projectName"
            clearable
            placeholder="请输入标题"
          />
        </el-form-item>
      </re-col>
    </el-row>
    <el-row v-else :gutter="30">
      <div v-if="props.isChange" style="width: 100%">
        <re-col :value="24" :xs="24" :sm="24">
          <el-form-item label="标题" prop="projectName">
            <el-input
@@ -253,6 +340,7 @@
            v-model="newFormInline.toubiaoStartDate"
            type="datetime"
            clearable
            :default-time="defaultTime"
            placeholder="请选择投标报名开始时间"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
@@ -264,6 +352,7 @@
            v-model="newFormInline.toubiaoEndDate"
            type="datetime"
            clearable
            :default-time="defaultTime"
            placeholder="请选择投标报名结束时间"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
@@ -275,6 +364,7 @@
            v-model="newFormInline.kaibiaoDate"
            type="datetime"
            clearable
            :default-time="defaultTime"
            placeholder="请选择开标时间"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
@@ -301,6 +391,23 @@
          </el-upload>
        </el-form-item>
      </re-col>
      <re-col v-if="!props.isChange" :value="24" :xs="24" :sm="24">
        <el-form-item label="附件" prop="">
          <el-upload
            ref="upload"
            v-model:file-list="validateForm.fileListFile"
            multiple
            :on-exceed="handleExceed"
            :auto-upload="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
            :headers="state.headers"
            @change="handleChangeFile"
          >
            <el-button type="primary">点击上传</el-button>
          </el-upload>
        </el-form-item>
      </re-col>
      <re-col :value="24" :xs="24" :sm="24">
        <el-form-item label="开标地点" prop="kaibiaodidian">
          <el-input
@@ -319,6 +426,7 @@
.el-date-editor.el-input__wrapper {
  width: 100%;
}
.upload__tip {
  width: 100%;
}