AIManage/src/views/manage/calculate/edit.vue

325 lines
9.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 算子管理 -->
<template>
<div class="app-container model-detail">
<!-- 算子新增表单 -->
<el-card v-loading="loading">
<template #header
><svg-icon icon-class="pause" style="width: 20px; height: 20px" /> 算子基本信息
</template>
<el-row>
<el-col :lg="12" :xs="24">
<el-form ref="formRef" :model="formData" :rules="rules" label-width="80px">
<el-form-item label="算子名称" prop="operator_name">
<el-input v-model="formData.operator_name" placeholder="请输入算子名称" />
</el-form-item>
<el-form-item label="算子类型" prop="oper_sub_type">
<el-row style="width: 100%">
<el-col :span="12">
<el-select
v-model="formData.oper_main_type"
placeholder="请选择算子主类型"
style="width: 100%"
@change="handleChange"
>
<el-option
v-for="item in listOpt.operTypeList"
:key="item.oper_main_type"
:label="item.oper_main_type_name"
:value="item.oper_main_type"
/>
</el-select>
</el-col>
<el-col :span="12">
<el-select
v-model="formData.oper_sub_type"
placeholder="请选择算子子类型"
style="width: 100%"
@change="handleChangeRules"
>
<el-option
v-for="item in listOpt.operSubTypeList"
:key="item.oper_sub_type"
:label="item.oper_sub_type_name"
:value="item.oper_sub_type"
/>
</el-select>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="算子说明" prop="operator_desc">
<el-input
v-model="formData.operator_desc"
:rows="2"
type="textarea"
placeholder="请输入算子说明"
maxlength="1024"
/>
</el-form-item>
<el-form-item label="算子文件" prop="parameters">
<el-upload
ref="uploadRef"
class="upload-demo"
:on-change="handleFileChange"
:on-remove="handleFileRemove"
:on-exceed="handleFileExceed"
:auto-upload="false"
:limit="1"
accept="application/json"
>
<el-button type="primary"
><el-icon class="el-icon--upload"> <i-ep-upload-filled /> </el-icon
>选择文件</el-button
>
<template #tip>
<div class="el-upload__tip">
请上传大小不超过 <strong style="color: red">10M</strong>,格式为
<strong style="color: red">json</strong> 的文件
</div>
</template>
</el-upload>
</el-form-item>
</el-form>
</el-col>
<el-col :lg="12" :xs="24">
<div style="padding-left: 35px" v-if="fileStatus">
<el-form label-width="100px" size="small">
<el-divider content-position="left"
><strong style="color: #409eff">算子文件预览</strong></el-divider
>
<code id="codeHtml" v-html="codeHtml"></code>
</el-form>
</div>
</el-col>
</el-row>
</el-card>
<el-card class="card-footer">
<el-button type="primary" @click="handleSubmit"><i-ep-check /> </el-button>
<el-button @click="closeBack"><i-ep-close /> </el-button>
</el-card>
</div>
</template>
<script setup lang="ts">
import ConstApi from "@/api/const";
import { useUserStore } from "@/store";
import OperatorApi from "@/api/operator";
const router = useRouter();
const formRef = ref(ElForm); // 表单
const loading = ref(false); // 加载状态
const fileStatus = ref(false); // 文件状态
const codeHtml = ref(""); // 文件信息
// 上传组件
const uploadRef = ref<UploadInstance>();
// 表单数据
const formData = reactive({
status: 1,
});
const userStore = useUserStore();
// 基础数据列表
let listOpt = reactive({
operTypeList: [],
operSubTypeList: [],
});
// 校验规则
const rules = reactive({
operator_name: [{ required: true, message: "算子名称不能为空", trigger: "blur" }],
oper_main_type: [{ required: true, message: "算子类型不能为空", trigger: "blur" }],
oper_sub_type: [{ required: true, message: "算子类型不能为空", trigger: "blur" }],
operator_desc: [{ required: true, message: "算子说明不能为空", trigger: "blur" }],
parameters: [{ required: true, message: "算子文件不能为空", trigger: "blur" }],
});
// 主动验证
function handleChangeRules() {
formRef.value.validateField("oper_main_type");
formRef.value.validateField("oper_sub_type");
}
/** 表单提交 */
const handleSubmit = useThrottleFn(() => {
formRef.value.validate((valid: any) => {
if (valid) {
loading.value = true;
formData.user_id = userStore.user?.id;
formData.create_time = new Date();
OperatorApi.add(formData)
.then((res) => {
if (res.data.code == 0) {
ElMessage.success("保存成功");
closeBack();
}
})
.finally(() => {
loading.value = false;
});
}
});
}, 3000);
/** 返回默认页面 */
function closeBack() {
router.push({ path: "/operatorLibrary/calculate" });
}
/** 算子主类型改变 */
function handleChange() {
router.pushpeList.forEach((item) => {
if (item.oper_main_type == formData.oper_main_type) {
listOpt.operSubTypeList = item.oper_sub_type_list;
}
});
}
// 文件上传
function handleFileChange(file) {
//先创建一个读文件的对象 FileReader
let reader = new FileReader();
//判断浏览器是否支持 FileReader
if (typeof FileReader === "undefined") {
this.$message({
type: "info",
message: "您的浏览器不支持文件读取。",
});
return;
}
uploadFile(file).then((res) => {
if (isJSON(res)) {
let jsonStr = JSON.stringify(res);
formData.parameters = jsonStr;
formRef.value.validateField("parameters");
//let json = JSON.parse(jsonStr);
codeHtml.value = res;//highlightJSON(json);
fileStatus.value = true;
}
});
}
/** 解析json */
function isJSON(str) {
try {
// 尝试解析输入的字符串
JSON.parse(str);
ElMessage.success("JSON文件解析成功");
return true;
// 成功解析
} catch (error) {
// 解析失败
ElMessage.error("JSON文件解析失败");
uploadRef.value.clearFiles();
fileStatus.value = false;
formData.parameters = "";
return false;
}
}
// 文件读取
function uploadFile(file) {
return new Promise(function (resolve, reject) {
let reader = new FileReader();
reader.readAsArrayBuffer(file.raw);
reader.onload = function (e) {
var ints = new Uint8Array(e.target.result); //要使用读取的内容所以将读取内容转化成Uint8Array
let snippets = new TextDecoder("UTF-8").decode(ints); //二进制缓存区内容转化成中文(即也就是读取到的内容)
resolve(snippets);
};
});
}
// 文件删除
function handleFileRemove() {
formData.parameters = "";
codeHtml.value = "<p></p>";
fileStatus.value = false;
}
// 超出限制,清空文件列表
function handleFileExceed() {
uploadRef.value.clearFiles();
ElMessage.warning("已清空文件列表,请重新上传!");
handleFileRemove();
}
// 核心算法
function highlightJSON(json) {
// 匹配key
let keyReg = new RegExp('"(.*)"(?=:)', "g");
// 匹配value
let valueReg = new RegExp('(?<=: )("(.*)"|\\d+)', "g");
if (typeof json === "object" && json !== null) {
json = JSON.stringify(json, this, 5);
}
// 颜色替换
let res = json
.replace(keyReg, (match) => {
return `<span class="green">${match}</span>`;
})
.replace(valueReg, (match) => {
if (/\d/.test(match)) {
return `<span class="blue">${match}</span>`;
}
return `<span class="black">${match}</span>`;
});
return res;
}
// 初始化选项列表
const initData = () => {
ConstApi.operMainType().then((res) => {
listOpt.operTypeList = res.data.data.oper_main_type_list || [];
});
};
onMounted(() => {
initData();
});
</script>
<style scoped lang="scss">
.model-detail {
:deep(.el-card__header) {
padding: 8px 4px;
display: flex;
align-items: center;
}
}
.sp-file {
color: #29d;
}
.tb-base-info {
line-height: 30px;
}
:deep(.svg-icon) {
margin-right: 8px;
}
.card-footer {
position: fixed;
width: calc(100% - 215px);
bottom: 0px;
:deep(.el-card__body) {
padding: 10px;
.el-pagination {
justify-content: end;
}
}
}
</style>
<style lang="scss" scope>
#codeHtml {
font-size: 16px;
color: #e36209;
font-family: "Courier New", Courier, monospace;
background: #f5f5f5;
.green {
color: #22863a;
}
.blue {
color: #005cc5;
}
.black {
color: #032f62;
}
}
</style>