TALL 插件商城
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

309 lines
8.8 KiB

<template>
<div class="box">
<h1 class="text-lg font-semibold">上传插件</h1>
<el-form ref="formRef" :model="form" :rules="rules" label-width="150px" class="forms">
<el-form-item prop="name">
<template v-slot:label>
<el-tooltip class="box-item" effect="dark" content="输入帮助" placement="top-end">
<div>插件名称 </div>
</el-tooltip>
</template>
<el-input v-model="form.name" placeholder="输入插件名称"></el-input>
</el-form-item>
<el-form-item label="版本:" prop="versions">
<el-input v-model="form.versions" placeholder="请输入"></el-input>
</el-form-item>
<el-form-item label="简介:" prop="intro">
<el-input v-model="form.intro" type="textarea" placeholder="请输入备注"></el-input>
</el-form-item>
<el-form-item label="行业:" prop="region">
<el-select v-model="form.region" placeholder="请选择">
<el-option value="教育"></el-option>
<el-option value="医疗"></el-option>
</el-select>
</el-form-item>
<el-form-item label="分类:" prop="sort">
<el-select v-model="form.sort" multiple placeholder="请选择,可多选">
<el-option value="康复"></el-option>
<el-option value="管理"></el-option>
</el-select>
</el-form-item>
<el-form-item label="标签:" prop="tags">
<el-select v-model="form.tags" multiple filterable allow-create default-first-option placeholder="请选择标签">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
<el-form-item label="HTML:" prop="html">
<el-input v-model="form.html" type="textarea" placeholder="请输入HTML代码片段"></el-input>
</el-form-item>
<el-form-item label="JS:" prop="js">
<el-input v-model="form.js" type="textarea" placeholder="请输入JS代码片段"></el-input>
</el-form-item>
<el-form-item label="CSS:" prop="css">
<el-input v-model="form.css" type="textarea" placeholder="请输入CSS代码片段"></el-input>
</el-form-item>
<el-form-item label="配置文件:" prop="config">
<el-input v-model="form.config" type="textarea" placeholder="请输入配置文件"></el-input>
</el-form-item>
<el-form-item label="上传预览图:" prop="preview">
<el-upload
class="avatar-uploader"
:action="`${apiUrl}/filedeal/file/upload/single`"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img v-if="form.preview" :src="form.preview" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item prop="carousel">
<template v-slot:label>
<el-tooltip class="box-item" effect="dark" content="输入帮助" placement="top-end">
<div>上传轮播图 ①:</div>
</el-tooltip>
</template>
<el-upload
class="upload-dialog"
name="files"
:action="`${apiUrl}/filedeal/file/upload/multiple`"
list-type="picture-card"
:on-success="handleBannerSuccess"
:on-remove="handleRemove"
ref="bannerUpload"
>
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="form.dialogVisible">
<img width="100%" :src="form.banner" alt="" v-if="form.dialogVisible" />
</el-dialog>
</el-form-item>
<el-form-item label="README:" prop="description">
<el-input v-model="form.description" type="textarea" placeholder="请输入markdown详细介绍信息"></el-input>
</el-form-item>
<!-- <el-form-item> <el-switch v-model="form.delivery" class="mr-3"></el-switch> 是否压缩代码 </el-form-item> -->
<el-form-item>
<el-button type="primary" @click="onSubmit()">发布</el-button>
<el-button @click="resetForm()">重置</el-button>
<!-- <el-button type="success" @click="visible = !visible">{{ !visible ? '预览' : '关闭预览' }}</el-button>
<div class="plugin-box" v-if="visible">
<div class="plugin w-full h-full overflow-y-scroll">
<Plugin :plugin="form" />
</div>
</div> -->
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { ElMessage } from 'element-plus';
import { savePlugin } from '@/apis/plugin';
const apiUrl = import.meta.env.VITE_API_URL_NEW;
const formRef = ref(null);
const bannerUpload = ref(null);
const form = reactive({
name: '',
versions: '',
intro: '',
region: '',
sort: '',
tags: '',
html: '',
js: '',
css: '',
config: '',
delivery: '',
preview: '',
carousel: [],
dialogVisible: false,
description: '',
banner: '',
});
const rules = {
name: [{ required: true, message: '请输入插件名称', trigger: 'blur' }],
versions: [{ required: true, message: '请输入版本号', trigger: 'blur' }],
// region: [{ required: true, message: '请选择行业', trigger: 'blur' }],
// sort: [{ required: true, message: '请选择分类', trigger: 'blur' }],
// tags: [{ required: true, message: '请选择标签', trigger: 'blur' }],
preview: [{ required: true, message: '请上传预览图', trigger: 'blur' }],
carousel: [{ required: true, message: '请上传轮播图', trigger: 'blur' }],
};
const options = [
{
value: 'HTML',
label: 'HTML',
},
{
value: 'CSS',
label: 'CSS',
},
{
value: 'JavaScript',
label: 'JavaScript',
},
];
/**
* 创建插件
* @param {object} params
*/
function onSubmit() {
try {
formRef.value.validate(async valid => {
if (valid) {
console.log('submit!');
const params = {};
params.param = form;
await savePlugin(params);
ElMessage.success('插件创建成功');
resetForm();
bannerUpload.value.clearFiles();
} else {
console.log('error submit!!');
return false;
}
});
} catch (error) {
ElMessage.error(error || '插件创建失败');
console.error('error: ', error);
}
}
/**
* 上传预览图
* @param {*} res
* @param {*} file
*/
function handleAvatarSuccess(res) {
if (res.data && res.data.visitUrl) {
form.preview = res.data.visitUrl;
}
}
function beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
ElMessage.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
ElMessage.error('上传头像图片大小不能超过 2MB!');
}
return isJPG && isLt2M;
}
// 删除轮播图
function handleRemove(res) {
if (res.response.data && res.response.data.length) {
const url = res.response.data[0].visitUrl;
const index = form.carousel.findIndex(item => item === url);
form.carousel.splice(index, 1);
}
}
// 上传轮播图
function handleBannerSuccess(res) {
if (res.data && res.data.length) {
form.dialogVisible = true;
form.banner = res.data[0].visitUrl;
res.data.forEach(item => {
if (item && item.id) {
form.carousel.push(item.visitUrl);
}
});
}
}
// 重置
function resetForm() {
formRef.value.resetFields();
}
</script>
<style scoped>
.box {
/* padding-left: 5%; */
}
.el-form-item {
margin-top: 1rem;
}
.tags {
width: 100%;
}
.el-select {
width: 100%;
}
.box >>> .el-form-item__label {
display: flex;
flex-direction: row-reverse;
justify-content: end;
flex: 0 0 auto;
text-align: right;
font-size: var(--el-form-label-font-size);
color: var(--el-text-color-regular);
line-height: 40px;
padding: 0 12px 0 0;
box-sizing: border-box;
}
.avatar-uploader >>> .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader >>> .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 104px;
height: 104px;
line-height: 104px;
text-align: center;
background: #fafafa;
}
.avatar {
width: 104px;
height: 104px;
display: block;
}
.upload-dialog >>> .el-upload--picture-card {
width: 104px;
height: 104px;
line-height: 104px;
background: #fafafa;
}
.upload-dialog >>> .el-upload-list--picture-card .el-upload-list__item {
width: 104px;
height: 104px;
}
.plugin-box {
position: fixed;
right: 14rem;
background: url(../../assets/iPhone13.png) no-repeat;
background-size: contain;
width: 19.375rem;
height: 39.2419rem;
top: calc(50vh - 289.93512px + 1.8rem);
padding: 2.8rem 1.2rem 2rem;
z-index: 99;
}
.plugin::-webkit-scrollbar {
display: none;
}
</style>