mcwl-pc/app/components/publishWorkFlow/EditVersion.vue

267 lines
8.0 KiB
Vue

<script setup lang="ts">
import { uploadFileBatches } from "@/utils/uploadImg.ts";
import { cloneDeep } from "lodash-es";
import { Asterisk, Trash } from "lucide-vue-next";
import type { FormInst } from "naive-ui";
import { computed, ref, watch } from "vue";
// 可接受的文件类型
const props = defineProps({
modelValue: {
type: Object,
required: true,
},
});
const emit = defineEmits(["update:modelValue", "nextStep", "preStep"]);
const loading = ref(false)
const localForm = computed({
get() {
return props.modelValue;
},
set(value) {
emit("update:modelValue", value);
},
});
watch(
() => localForm.value,
(newVal: any) => {
console.log("newVal", newVal);
emit("update:modelValue", newVal);
},
{ immediate: true, deep: true }
);
const message = useMessage();
const acceptTypes = ".json,.zip";
defineExpose({
addVersion,
});
const modelVersionItem = {
versionName: "",
versionDescription: "", // 富文本
filePath: "", // 文件路径
fileName: "", // 文件名
delFlag: "0",
imagePaths: [],
id: null,
};
const rules = {
versionName: {
required: true,
message: "",
trigger: "blur",
},
};
function addVersion() {
const param = cloneDeep(modelVersionItem);
localForm.value.workFlowVersionList.unshift(param);
}
const formRefs = ref<(FormInst | null)[]>([]);
function setFormRef(el: FormInst | null, index: number) {
if (el) {
formRefs.value[index] = el;
}
}
async function nextStep() {
for (let i = 0; i < localForm.value.workFlowVersionList.length; i++) {
if (
localForm.value.workFlowVersionList[i].delFlag === "0" &&
localForm.value.workFlowVersionList[i].fileName === ""
) {
return message.error("请上传文件");
}
const regex = /[\u4E00-\u9FA5]/; // 匹配汉字的正则表达式
if (
localForm.value.workFlowVersionList[i].delFlag === "0" &&
!regex.test(localForm.value.workFlowVersionList[i].versionDescription)
) {
return message.error("请用中文填写版本介绍");
}
}
try {
const promises = formRefs.value
.filter((form: any): form is FormInst => form !== null)
.map((form: any) => form.validate());
await Promise.all(promises);
emit("nextStep");
} catch (errors) {
console.error("部分表单验证失败:", errors);
}
// formRef.value?.validate((errors) => {
// if (!errors) {
// emit('nextStep')
// }
// else {
// console.log('error', errors)
// }
// })
}
function preStep() {
emit("preStep");
}
// 上传文件
const uploadFileIndex = ref(0);
const fileInput = ref<HTMLInputElement | null>(null);
function triggerFileInput(index: number) {
(fileInput.value as HTMLInputElement)?.click();
uploadFileIndex.value = index;
}
async function handleFileChange(event: Event) {
const target = event.target as HTMLInputElement;
const files = target.files;
if (files && files.length > 0) {
const { name, size } = files[0] as { name: string; size: number };
try {
const res1 = await request.get(`/file/selectFile?type=workflow&name=${name}`);
if (res1.code == 200) {
if (res1.data === 1) {
//存在为0 不存在为1
try {
loading.value = true
const res = await uploadFileBatches(files);
localForm.value.workFlowVersionList[uploadFileIndex.value].filePath =
res[0].path;
localForm.value.workFlowVersionList[uploadFileIndex.value].objectKey =
res[0].objectKey;
localForm.value.workFlowVersionList[uploadFileIndex.value].fileName = name;
localForm.value.workFlowVersionList[uploadFileIndex.value].fileSize = size;
} catch (err) {
console.log(err);
}finally{
loading.value = false
}
} else {
message.error("该工作流名称已存在");
}
}
} catch (err) {
console.log(err);
}
}
target.value = "";
}
function computedDelFlag() {
return localForm.value.workFlowVersionList.filter((item: any) => item.delFlag === "0");
}
function onDelete(index: number) {
if (computedDelFlag().length === 1) return;
localForm.value.workFlowVersionList[index].delFlag = "2";
}
</script>
<template>
<div class="flex justify-center items-center">
<div class="w-[960px]">
<template v-for="(item, index) in localForm.workFlowVersionList" :key="index">
<div v-if="item.delFlag === '0'" class="bg-gray-100 p-4 rounded-lg mt-4 relative">
<div class="absolute -right-10 top-4 cursor-pointer">
<Trash class="cursor-pointer" @click="onDelete(index)" />
</div>
<n-form
:ref="(el:any) => setFormRef(el, index)"
:label-width="80"
:model="localForm.workFlowVersionList[index]"
:rules="rules"
size="large"
>
<n-form-item label="版本名称" path="versionName">
<n-input v-model:value="item.versionName" placeholder="请输入版本名" />
</n-form-item>
<div class="flex">
版本介绍 <Asterisk :size="10" color="#ff0000" class="mt-1" />
</div>
<div class="text-gray-400 text-[12px]">
填写类别可让模型获得更精准的流量, 平台也有权基于标准修改你的类别标签
</div>
<div class="bg-white p-3 mt-2 rounded-lg">
<client-only>
<WangEditor v-model="item.versionDescription" />
</client-only>
</div>
<div class="flex mt-4">
上传文件 <Asterisk :size="10" color="#ff0000" class="mt-1" />
</div>
<div
v-if="item.fileName"
class="flex justify-between items-center bg-white p-3 mt-2 rounded-lg"
>
<div
class="bg-[#d8e5fd] text-[12px] text-[#3162ff] w-16 h-7 rounded-lg flex justify-center items-center"
>
100%
</div>
<div class="flex-1 flex items-center line-clamp">
{{ item.fileName }}
</div>
<div>
<Trash
class="cursor-pointer"
@click="(item.fileName = ''), (item.filePath = '')"
/>
</div>
</div>
<div v-else>
<n-spin :show="loading">
<div class="upload-content">
<div
class="flex flex-col justify-center items-center w-30 h-40 border border-dashed mt-2 rounded-lg bg-white"
>
<div
class="w-24 bg-gradient-to-r from-[#2D28FF] to-[#1A7DFF] h-8 text-white rounded-sm bg-[#3162ff] cursor-pointer flex justify-center items-center"
@click="triggerFileInput(index)"
>
上传文件
</div>
<div class="my-3">点击上传文件</div>
<div class="text-[#999999] text-xs">.json/.zip</div>
</div>
</div>
</n-spin>
</div>
</n-form>
</div>
</template>
<div class="flex items-center justify-center mt-5">
<div
class="flex justify-center items-center mt-5 w-[20%] mx-2 h-10 rounded-lg bg-[#f1f2f7] cursor-pointer"
@click="preStep"
>
上一步
</div>
<div
class="flex justify-center items-center mt-5 text-white mx-2 w-[20%] h-10 rounded-lg bg-[#3162ff] cursor-pointer"
@click="nextStep"
>
下一步
</div>
</div>
</div>
</div>
<input
ref="fileInput"
type="file"
class="hidden"
:accept="acceptTypes"
@change="handleFileChange"
/>
</template>
<style lang="scss" scoped>
.line-clamp {
margin: 0 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 12px;
color: rgb(72, 71, 71);
}
</style>