添加前端运行基本路径,新增平台管理(文章管理)和修改素材管理交互逻辑,修改wangeditor富文本编辑器封装组件

This commit is contained in:
Double-_-Z 2025-07-13 20:24:15 +08:00
parent 5424a94fa5
commit db5f4071ec
7 changed files with 612 additions and 23 deletions

View File

@ -6,6 +6,7 @@ VUE_APP_BASE_API = 'http://8.138.171.103/aerocraftAdminApi'
# VUE_APP_BASE_API = 'https://eladmin.vip' # VUE_APP_BASE_API = 'https://eladmin.vip'
# VUE_APP_WS_API = 'ws://localhost:8000' # VUE_APP_WS_API = 'ws://localhost:8000'
VUE_APP_WS_API = 'wss://eladmin.vip' VUE_APP_WS_API = 'wss://eladmin.vip'
# 运行基本路径
VUE_APP_BASE_PATH = 'http://localhost:8013'
# 是否启用 babel-plugin-dynamic-import-node插件 # 是否启用 babel-plugin-dynamic-import-node插件
VUE_CLI_BABEL_TRANSPILE_MODULES = true VUE_CLI_BABEL_TRANSPILE_MODULES = true

View File

@ -3,5 +3,7 @@ ENV = 'production'
# 如果使用 Nginx 代理后端接口,那么此处需要改为 '/',文件查看 Docker 部署篇Nginx 配置 # 如果使用 Nginx 代理后端接口,那么此处需要改为 '/',文件查看 Docker 部署篇Nginx 配置
# 接口地址,注意协议,如果你没有配置 ssl需要将 https 改为 http # 接口地址,注意协议,如果你没有配置 ssl需要将 https 改为 http
VUE_APP_BASE_API = 'http://8.138.171.103/aerocraftAdminApi' VUE_APP_BASE_API = 'http://8.138.171.103/aerocraftAdminApi'
# 运行基本路径
VUE_APP_BASE_PATH = 'http://8.138.171.103/aerocraftAdmin'
# 如果接口是 http 形式, wss 需要改为 ws # 如果接口是 http 形式, wss 需要改为 ws
VUE_APP_WS_API = 'wss://eladmin.vip' VUE_APP_WS_API = 'wss://eladmin.vip'

View File

@ -1,14 +1,18 @@
<template> <template>
<div ref="editor" style="border: 1px solid #ccc;"> <div ref="editor" style="border: 1px solid #ccc;z-index: 1001;">
<Toolbar <Toolbar
v-if="!disable"
style="border-bottom: 1px solid #ccc" style="border-bottom: 1px solid #ccc"
:editor="editor" :editor="editor"
:default-config="toolbarConfig" :default-config="toolbarConfig"
:mode="editMode" :mode="editMode"
/> />
<div v-else class="replace" v-if="disableShowFullscreen">
<i class="full el-icon-full-screen" @click="openCurrenFullscreen" />
</div>
<Editor <Editor
v-model="editValue" v-model="editValue"
:style="{'height': editorHeight +'px', 'overflow-y': 'hidden'}" :style="{'height': editorHeight +'px', 'overflow-y': 'hidden','background-color': '#fff'}"
:default-config="editorConfig" :default-config="editorConfig"
:mode="editMode" :mode="editMode"
@onCreated="onCreated" @onCreated="onCreated"
@ -25,6 +29,11 @@ export default {
name: 'WangEditor', name: 'WangEditor',
components: { Toolbar, Editor }, components: { Toolbar, Editor },
props: { props: {
//
disable: {
type: Boolean,
default: () => false,
},
value: { value: {
type: String, type: String,
required: false, required: false,
@ -34,13 +43,18 @@ export default {
type: Number, type: Number,
required: false, required: false,
default: 420 default: 420
} },
//
disableShowFullscreen: {
type: Boolean,
default: true,
},
}, },
data() { data() {
const _this = this const _this = this
return { return {
toolbarConfig: {}, toolbarConfig: {},
editorConfig: { placeholder: '请输入内容...', MENU_CONF: { editorConfig: { placeholder: '请输入内容...', readOnly: this.disable, MENU_CONF: {
'uploadImage': { 'uploadImage': {
// ['image/*'] [] // ['image/*'] []
allowedFileTypes: ['image/*'], allowedFileTypes: ['image/*'],
@ -55,9 +69,10 @@ export default {
} }
} }
}}, }},
editMode: 'simple', editMode: 'default',
editor: null, editor: null,
editValue: null editValue: null,
isFull: false,
} }
}, },
computed: { computed: {
@ -69,25 +84,53 @@ export default {
watch: { watch: {
editValue(newVal, oldVal) { editValue(newVal, oldVal) {
this.$emit('input', newVal) this.$emit('input', newVal)
} },
}, },
mounted() { mounted() {
}, },
methods: { methods: {
onCreated(editor) { onCreated(editor) {
this.editor = Object.seal(editor) this.editor = Object.seal(editor)
this.editValue = this.value this.editValue = this.value
},
//
openCurrenFullscreen() {
const editor = this.editor; // editor
if (editor == null) return;
this.isFull ? editor.unFullScreen() : editor.fullScreen();
this.isFull = !this.isFull;
} }
} }
} }
</script> </script>
<style src="@wangeditor/editor/dist/css/style.css"></style> <style src="@wangeditor/editor/dist/css/style.css"></style>
<style scoped> <style scoped lang="scss">
.text { .text {
text-align:left; text-align:left;
} }
::v-deep .w-e-text-container { ::v-deep .w-e-text-container {
height: 420px !important; height: 500px !important;
}
::v-deep .w-e-text-placeholder{
top: 5px !important;
}
.replace{
background-color: #ffffff;
border-top: 1px solid #e4e7ed;
border-left: 1px solid #e4e7ed;
border-right: 1px solid #e4e7ed;
display: flex;
justify-content: flex-end;
.full{
font-size: 20px;
padding: 5px 5px 0;
cursor: pointer;
&:hover{
opacity: 0.8;
}
&:active{
opacity: 0.6;
}
}
} }
</style> </style>

View File

@ -0,0 +1,272 @@
<template>
<div class="app-container">
<el-card v-loading="loading" shadow="hover" header="文章详情">
<el-form ref="articleFormRef" :model="form" :rules="rules" size="large" label-width="100px" class="article-form">
<el-row :gutter="35">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="封面:" class="coverImg" prop="fileArray">
<!-- 上传文件 -->
<el-upload ref="uploadRef" class="h100 personal-user-left-upload" action="#" list-type="picture-card" :file-list="form.fileArray"
:auto-upload="false" :limit="1" :class="{ disabled: coverHide }" :on-change="handleUploadChange" accept='image/*'>
<template #default><i class="el-icon-plus" /></template>
<template #file="{ file }">
<div>
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in" />
</span>
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete" />
</span>
</span>
</div>
</template>
</el-upload>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="模块名称:" prop="moduleName">
<el-select size="default" @change="handleChangeModule" v-model="form.moduleName" placeholder="请选择模块" clearable>
<el-option :data-op="item.id" v-for="(item,index) in moduleList" :key="index" :label="item.moduleName" :value="item.moduleName"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="标签名称:" prop="labelName">
<el-select size="default" v-model="form.labelName" placeholder="请选择标签" clearable class="ml10">
<el-option v-for="(item,index) in labelList" :key="index" :label="item.name" :value="item.name"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="标题:" prop="title">
<el-input v-model.trim="form.title" placeholder="请输入标题" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="文章类型:" prop="articletype">
<el-select size="default" v-model="form.articletype" placeholder="请选择文章类型" clearable>
<el-option label="图文" :value="0"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="是否置顶:" prop="top">
<el-switch v-model="form.top" />
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="text" label-width="0px">
<wang-editor v-model="form.text" :editorHeight="500" style="width: 100%;overflow-y: hidden;" />
</el-form-item>
<el-row class="article-btns">
<div style="width: 100%;display: flex;justify-content: flex-end;">
<el-button class="el-icon-refresh-left" size="larger" type="info" @click="cancel">
取消
</el-button>
<el-button class="el-icon-edit" size="larger" type="primary" @click="onSubmitForm">
保存
</el-button>
</div>
</el-row>
</el-form>
</el-card>
<!-- 封面预览弹窗 -->
<el-dialog :visible.sync="dialogVisible">
<img width="100%" w-full :src="dialogImageUrl" alt="预览" />
</el-dialog>
</div>
</template>
<script>
import WangEditor from '@/components/WangEditor/index'
export default {
name: 'ArticleAdd',
name: 'ArticleEdit',
components: {
WangEditor
},
data() {
//
const validText = (rule, value, callback) => {
const val = value.replace(/<[^<p>]+>/g, '') // <p> replace ''
.replace(/<[</p>$]+>/g, '') // </p> replace ''
.replace(/&nbsp;/gi, '') // replace ''
.replace(/<[^<br/>]+>/g, ''); // replace ''
if (!val) {
callback(new Error('请输入文章内容'))
} else if (/^[ ]+$/.test(val)) {
callback(new Error('请输入文章内容'))
} else {
callback()
}
}
return {
loading: false,
form:{
labelName: '',
moduleName: '',
title: '',
articletype: '',
photo: '',
text: '',
top: false,// 01
fileArray:[]//
},
//
moduleList:[
{ moduleName: '景区', moduleName: '景区' },
{ moduleName: '新闻', moduleName: '新闻' },
{ moduleName: '活动', moduleName: '活动' },
{ moduleName: '其他', moduleName: '其他' }
],
//
labelList: [],
rules:{
moduleName: { required: true, message: '请选择模块', trigger: 'change' },
labelName: { required: true, message: '请输入标签名称', trigger: 'blur' },
title: { required: true, message: '请输入标题', trigger: 'blur' },
articletype: { required: true, message: '请选择文章类型', trigger: 'change' },
top: { required: true, message: '请选择是否置顶', trigger: 'blur' },
text: { required: true, trigger: 'blur', validator: validText },
fileArray: { required: true, message: '请上传封面图', trigger: 'change' },
},
coverFile: {},
coverHide: false,
dialogImageUrl: '',
dialogVisible: false,
//
disabled: false,
}
},
created(){
const { moduleName, labelName, id } = this.$route.query;
if(moduleName && labelName && this.$route.path == '/platform/article/edit') {
this.getArticleDetailById(id);
}
},
methods: {
//
handleUploadChange(uploadFile, uploadFiles) {
if(uploadFile.raw.type.includes('image')){
const file = uploadFile.raw;
this.coverFile = file;
this.coverHide = true;
this.form.fileArray = uploadFiles;
}else{
this.$message.error('请上传图片文件!');
this.$refs['uploadRef'].clearFiles();
}
},
//
handleRemove(file) {
this.coverFile = {};
this.$refs['uploadRef'].clearFiles();
this.coverHide = false;
},
//
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
//
async handleChangeModule(val) {
try {
this.form.labelName = '';
if(!val){this.labelList=[]; return;}
this.labelList = [{name: '测试'},{name: '测试2'}];
// const op = event?.currentTarget;
// let res = await artApi.getLabelList(op.dataset.op);
// if(res?.success){
// labelList.value = res.data;
// }else{
// ElMessage.error('');
// }
} catch (error) {
this.$message.error('标签列表获取失败!');
} finally {
}
},
// -id
async getArticleDetailById(id){
try {
this.loading = true;
// let res = await artApi.getArticleDetail(id);
// if(res?.success) {
// state.data = res.data;
// // 01truefalse
// state.data.top = state.data.top === 1;
// state.data.moduleName = moduleName;
// state.data.labelName = labelName;
// state.data.textid = state.data.id;
// if(state.data.photo){
// const never = [{name:state.data.title,url:viteUrl+state.data.photo}];
// state.fileArray = never;
// state.coverHide = true;
// }
// }
const { moduleName, labelName } = this.$route.query;
this.form = {
moduleName: moduleName,
labelName: labelName,
title: '测试标题',
articletype: 0,
photo: 'https://huyun120.cn/fd/health/img/%E7%BB%84%20319@2x.f0767b46.png',
text: '测试内容',
top: false,
fileArray:[{name:'测试标题',url:'https://huyun120.cn/fd/health/img/%E7%BB%84%20319@2x.f0767b46.png'}]
};
this.coverHide = true;
} catch (error) {
this.$message.error('获取文章详情失败');
} finally {
this.loading = false;
}
},
//
cancel(){
this.$store.dispatch('tagsView/delView', this.$route);
this.$router.push('/platform/article');
},
//
onSubmitForm(){
console.log(this.form.text);
this.$refs['articleFormRef'].validate(async(valid) => {
if (valid) {
// let res = await this.$http.post('/api/article/add', this.articleForm);
// if(res.code == 200){
this.$message.success('文章添加成功!');
this.cancel();
// }
}else{
this.$message.error('请完善信息!');
}
})
},
}
}
</script>
<style scoped lang="scss">
.article-form{
margin: 20px 0;
}
.coverImg{
&::v-deep .disabled{
.el-upload--picture-card{
display: none;
}
}
&::v-deep .el-upload--picture-card,::v-deep .el-upload-list__item{
display: flex;
align-items: center;
justify-content: center;
width: 130px;
height: 130px;
}
}
.article-btns{
display: flex;
margin-top: 15px;
}
</style>

View File

@ -0,0 +1,116 @@
<template>
<div class="app-container">
<el-card v-loading="loading" shadow="hover" header="文章详情">
<el-form :model="data" size="large" label-width="100px" class="article-form">
<el-row :gutter="35">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="封面:">
<el-image
style="width: 130px;height: 130px;border-radius: 4px;"
:src="data.photo"
:zoom-rate="1.2"
:preview-src-list="[data.photo]"
fit="cover"/>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="模块名称:" prop="moduleName">
{{ data.moduleName }}
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="标签名称:" prop="labelName">
{{ data.labelName }}
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="标题:" prop="title">
{{ data.title }}
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="文章类型:" prop="articletype">
图文
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="是否置顶:" prop="top">
<el-tag type="success" v-if="data.top===1"></el-tag>
<el-tag type="error" v-else></el-tag>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="浏览数:">
{{ data.view }}
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="创建日期:">
{{ data.createtime }}
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="text" label-width="0px">
<wang-editor v-model="data.text" :editorHeight="500"
style="width: 100%;overflow-y: hidden;" :disable="true"/>
</el-form-item>
<el-row class="article-btns">
<div style="width: 100%;display: flex;justify-content: flex-end;">
<el-button class="el-icon-refresh-left" size="larger" type="info" @click="cancel">
取消
</el-button>
</div>
</el-row>
</el-form>
</el-card>
</div>
</template>
<script>
import WangEditor from '@/components/WangEditor/index'
export default {
name: 'ArticleDetail',
components: {
WangEditor
},
data(){
return{
data: {
labelName: '',
moduleName: '',
title: '测试',
articletype: 0,
createtime: '2025-01-23',
photo: 'https://huyun120.cn/fd/health/img/%E7%BB%84%20319@2x.f0767b46.png',
text: '测试',
top: 1,
view: 17,
},
loading: false,
}
},
created(){
const { moduleName, labelName, id } = this.$route.query;
// if(moduleName && labelName && this.$route.path == '/platform/article/edit') {
// this.getArticleDetailById(id);
// }
this.data.moduleName = moduleName;
this.data.labelName = labelName;
},
methods: {
//
cancel(){
this.$store.dispatch('tagsView/delView', this.$route);
this.$router.push('/platform/article');
},
}
}
</script>
<style scoped lang="scss">
.article-form{
margin: 20px 0;
}
.article-btns{
display: flex;
margin-top: 15px;
}
</style>

View File

@ -1,10 +1,150 @@
<template> <template>
<div> <div class="app-container">
123 <!--工具栏-->
<div class="head-container">
<div>
<!-- 搜索 -->
<el-select v-model="query.moduleName" placeholder="请选择模块" clearable size="small" class="filter-item"
style="width: 200px">
<el-option v-for="(item,index) in modules" :key="index" :label="item.label" :value="item.value" />
</el-select>
<el-select v-model="query.labelName" placeholder="请选择标签" clearable size="small" class="filter-item"
style="width: 200px">
<el-option v-for="(item,index) in labels" :key="index" :label="item.label" :value="item.value" />
</el-select>
<el-input v-model="query.title" clearable size="small" placeholder="请输入标题" style="width: 200px;"
class="filter-item" @keyup.enter.native="crud.toQuery"/>
<rrOperation />
<el-button v-permission="permission.add" class="filter-item" size="mini" type="primary"
icon="el-icon-plus" @click="toAddArticle">
新增{{ crud.title }}
</el-button>
</div>
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;">
<el-table-column type="index" align="center" width="55" label="序号" />
<el-table-column :show-overflow-tooltip="true" prop="title" label="标题" align="center" />
<el-table-column :show-overflow-tooltip="true" prop="articletype" label="文章类型" align="center" />
<el-table-column :show-overflow-tooltip="true" prop="top" label="置顶" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.top===1" type="success"></el-tag>
<el-tag v-else type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="moduleName" label="模块名称" align="center" />
<el-table-column :show-overflow-tooltip="true" prop="labelName" label="标签名称" align="center" />
<el-table-column :show-overflow-tooltip="true" label="链接" align="center" min-width="80">
<template slot-scope="scope">
<el-button size="mini" style="border-radius: 10px;" @click="copyLink(scope.row)">复制</el-button>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" label="创建时间" align="center" />
<el-table-column label="操作" align="center" fixed="right">
<template slot-scope="scope">
<el-button size="small" type="text" @click="toShowDetail(scope.row)">查看详情</el-button>
<el-button size="small" type="text" @click="toPreview(scope.row)">预览</el-button>
<el-button size="small" type="text" @click="toEditArticle(scope.row)">修改</el-button>
<el-button size="small" type="text" @click="deleteArticle(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</div> </div>
</template> </template>
<script> <script>
import crudArticle from '@/api/platform/article'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
export default { export default {
name: 'Article' name: 'Article',
components: { rrOperation, pagination },
//
dicts: ['material_type'],
cruds() {
return CRUD({ title: '文章', url: 'api/article', crudMethod: { ...crudArticle }, optShow: { reset: true }})
},
mixins: [presenter(), header(), crud()],
data() {
return {
permission: {
add: ['admin', 'article:add'],
edit: ['admin', 'article:edit'],
del: ['admin', 'article:del']
},
modules:[
{ label: '景区', value: '景区' },
{ label: '新闻', value: '新闻' },
{ label: '活动', value: '活动' },
{ label: '其他', value: '其他' }
],
labels:[
{ label: '图片', value: '图片' },
{ label: '视频', value: '视频' },
{ label: '音频', value: '音频' },
{ label: '文件', value: '文件' }
]
}
},
created() {
this.crud.data = [{ id: 1, title: '景区', articletype: '图文', top: 1, moduleName: '工作台', labelName: '使用教程', createTime: '2020-01-01' },
{ id: 2, title: '景区', articletype: '图文', top: 0, moduleName: '工作台', labelName: '使用教程', createTime: '2020-01-01' },
]
this.crud.resetDataStatus()
},
methods: {
//
copyLink(row){
if(row.id == null||row.id == ''){ this.$message.warning('链接为空');return;}
var aux = document.createElement("input");
aux.setAttribute("value", `${process.env.VUE_APP_BASE_PATH}/#article/content?id=${row.id}`);
document.body.appendChild(aux);
aux.select();
document.execCommand("copy");
document.body.removeChild(aux);
this.$message.success('复制成功');
aux.remove();
},
//
toShowDetail(row) {
this.$router.push({ path: '/platform/article/detail' , query: { id:row.id, moduleName: row.moduleName, labelName: row.labelName } });
},
//
toPreview(row) {
window.open(`${process.env.VUE_APP_BASE_PATH}/#article/content?id=${row.id}`);
},
//
toAddArticle() {
this.$router.push({ path: '/platform/article/add' });
},
//
toEditArticle(row) {
this.$router.push({ path: '/platform/article/edit', query: { id:row.id, moduleName: row.moduleName, labelName: row.labelName } });
},
//
deleteArticle(id) {
this.$confirm('确定要删除该文章吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(async() => {
try {
// state.tableData.loading = true;
// let res = await artApi.deleteArticle(id);
// if(res?.success){
// await getTableData();
this.$message.success('文章删除成功!');
// } else ElMessage.error('');
} catch(e) {
this.$message.error('处理失败!');
} finally {
// state.tableData.loading = false;
}
})
}
}
} }
</script> </script>

View File

@ -32,22 +32,25 @@
</el-col> </el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20"> <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="素材类型" prop="type"> <el-form-item label="素材类型" prop="type">
<el-select v-model="form.type" placeholder="请选择素材类型" clearable> <el-select @change="handleRemove" v-model="form.type" placeholder="请选择素材类型" clearable>
<el-option v-for="item in dict.material_type" :key="item.id" :label="item.label" :value="item.value" /> <el-option v-for="item in dict.material_type" :key="item.id" :label="item.label" :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20"> <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="素材资源" prop="files"> <el-form-item label="素材资源" prop="files">
<el-upload ref="uploadRef" action="#" list-type="picture-card" :class="{ disabled: uploadDisabled }" <el-upload ref="uploadRef" action="#" list-type="picture-card" :class="{ disabled: uploadDisabled }" :disabled="!form.type"
:limit="1" :file-list="form.files" :on-change="handleChange" :auto-upload="false"> :limit="1" :file-list="form.files" :on-change="handleChange" :auto-upload="false" :accept="form.type === '轮播图'?'image/*':'viedo/*'">
<div style="display: flex;flex-direction: column;align-items: center;justify-content: center;margin-top: -20px;"> <div style="display: flex;flex-direction: column;align-items: center;justify-content: center;margin-top: -20px;">
<i class="el-icon-plus" style="font-size: 30px;" /> <i class="el-icon-plus" style="font-size: 30px;" />
<span style="margin: 5px 0 -20px;line-height: 20px">上传</span> <span style="margin: 5px 0 -20px;line-height: 20px">上传</span>
</div> </div>
<template #file="{ file }"> <template #file="{ file }">
<div> <div>
<img class="el-upload-list__item-thumbnail" :src="file.url" alt=""> <img v-if="form.type === '轮播图'" class="el-upload-list__item-thumbnail" :src="file.url" alt="">
<video preload="meta" v-else class="el-upload-list__item-thumbnail" :src="file.url">
您的浏览器不支持视频预览
</video>
<span class="el-upload-list__item-actions"> <span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)"> <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in" /> <i class="el-icon-zoom-in" />
@ -60,7 +63,13 @@
</template> </template>
</el-upload> </el-upload>
<el-dialog append-to-body :visible.sync="dialogVisible" top="20vh"> <el-dialog append-to-body :visible.sync="dialogVisible" top="20vh">
<div><img :src="dialogImageUrl" style="width: 100%" alt="Preview Image"></div> <div>
<img v-if="form.type === '轮播图'" :src="dialogImageUrl" style="width: 100%" alt="Preview Image">
<video controls v-else src="el-upload-list__item-thumbnail" style="width: 100%"
:src="dialogImageUrl" preload="meta">
您的浏览器不支持视频预览
</video>
</div>
</el-dialog> </el-dialog>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -174,7 +183,13 @@ export default {
}, },
// //
handleChange(file, uploadFiles) { handleChange(file, uploadFiles) {
if (file.raw.type === 'image/png' || file.raw.type === 'image/jpeg' || file.raw.type === 'image/jpg' || file.raw.type === 'image/gif') { if(!this.form.type) {
this.$message.warning('请选择文章类型!');
return;
}
const isTypeImage = this.form.type === '轮播图';
const fileType = file.raw.type;
if ((isTypeImage&&fileType.includes('image'))||(!isTypeImage)&&fileType.includes('video')) {
this.loading = true this.loading = true
this.form.files = uploadFiles this.form.files = uploadFiles
this.uploadDisabled = true this.uploadDisabled = true
@ -184,7 +199,7 @@ export default {
// let res = await photoApi.uploadFile(formdata); // let res = await photoApi.uploadFile(formdata);
// if(res?.success){ // if(res?.success){
// this.form.url = res.data.path; // this.form.url = res.data.path;
this.$message.success('图片上传成功!') this.$message.success(`${isTypeImage?'图片':'视频'}上传成功!`)
this.loading = false this.loading = false
console.log(this.form) console.log(this.form)
// }else{ // }else{
@ -192,10 +207,10 @@ export default {
// } // }
} catch (error) { } catch (error) {
this.loading = false this.loading = false
this.$message.error('图片上传失败!') this.$message.error(`${isTypeImage?'图片':'视频'}上传失败!`)
} }
} else { } else {
this.$confirm('图片的格式不正确,请重新选择!', '提示', { this.$confirm(`${isTypeImage?'图片':'视频'}的格式不正确,请重新选择!`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
type: 'warning' type: 'warning'
}) })