292 lines
8.6 KiB
Vue
292 lines
8.6 KiB
Vue
<template>
|
||
<div>
|
||
<div class="gva-table-box">
|
||
<div class="gva-btn-list">
|
||
<el-button type="primary" icon="plus" @click="handleAdd('0')">新增广告位</el-button>
|
||
</div>
|
||
<el-table :data="tableData" row-key="ID">
|
||
<el-table-column align="left" label="ID" min-width="50" prop="ID" />
|
||
<el-table-column align="left" label="示例图片" min-width="100" prop="position">
|
||
<template #default="scope">
|
||
<el-image :src="scope.row.imgUrl" class="gva-image" fit="contain" :preview-src-list="[scope.row.imgUrl]"
|
||
preview-teleported hide-on-click-modal close-on-press-escape style="width: 100px; height: 100px" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="left" label="位置名称" min-width="120" prop="position" />
|
||
<el-table-column align="left" label="位置说明" min-width="120" prop="title" />
|
||
<el-table-column align="left" label="媒体宽" min-width="60" prop="mediaWidth" />
|
||
<el-table-column align="left" label="媒体高" min-width="60" prop="mediaHeight" />
|
||
<el-table-column align="left" fixed="right" label="操作" width="160">
|
||
<template #default="scope">
|
||
<el-button type="primary" link icon="edit" @click="handleEdit(scope.row.ID)">编辑</el-button>
|
||
<el-button type="danger" link icon="delete" @click="handleDelete(scope.row.ID)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<div class="gva-pagination">
|
||
<el-pagination layout="total, sizes, prev, pager, next, jumper" :current-page="page" :page-size="pageSize"
|
||
:page-sizes="[10, 30, 50, 100]" :total="total" @current-change="handleCurrentChange"
|
||
@size-change="handleSizeChange" />
|
||
</div>
|
||
</div>
|
||
|
||
<el-drawer v-model="dialogFormVisible" size="550" :show-close="false" :before-close="handleCloseDialog"
|
||
:close-on-click-modal="false" :close-on-press-escape="false">
|
||
<template #header>
|
||
<div class="flex justify-between items-center">
|
||
<span class="text-lg">{{ !isEdit ? '添加' : '修改' }}广告位</span>
|
||
<div>
|
||
<el-button type="primary" @click="handleFormSubmit">确 定</el-button>
|
||
<el-button @click="handleCloseDialog">取 消</el-button>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<el-form v-if="dialogFormVisible" ref="editFormRef" label-position="top" label-width="auto" :inline="true"
|
||
:model="editForm" :rules="rules">
|
||
<el-form-item label="位置名称(代码中用)" prop="position" style="width: 88%">
|
||
<el-input v-model="editForm.position" autocomplete="off" />
|
||
</el-form-item>
|
||
<el-form-item label="位置说明" prop="title" style="width: 88%">
|
||
<el-input v-model="editForm.title" autocomplete="off" />
|
||
</el-form-item>
|
||
<el-form-item label="媒体宽" prop="mediaWidth" style="width: 41%">
|
||
<el-input-number v-model="editForm.mediaWidth" autocomplete="off" style="width: 100%" />
|
||
</el-form-item>
|
||
<el-form-item label="媒体高" prop="mediaHeight" style="width: 41%">
|
||
<el-input-number v-model="editForm.mediaHeight" autocomplete="off" style="width: 100%" />
|
||
</el-form-item>
|
||
<el-form-item label="位置示例图片" prop="imgUrl" style="width: 88%">
|
||
<el-upload class="avatar-uploader" :action="`${imgUploadPath}/cms/mediaFile/upload?category=ad_pos_exa`"
|
||
:show-file-list="false" :on-success="uploadSuccess" :on-error="uploadFailure" :before-upload="beforeUpload">
|
||
<img v-if="editForm.imgUrl" :src="editForm.imgUrl" class="avatar" style="object-fit: cover;">
|
||
<el-icon v-else class="avatar-uploader-icon">
|
||
<Plus />
|
||
</el-icon>
|
||
</el-upload>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-drawer>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { reactive, ref } from 'vue'
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
import {
|
||
getAdPositionList,
|
||
addAdPosition,
|
||
updateAdPosition,
|
||
deleteAdPosition,
|
||
getAdPositionById
|
||
} from '@/api/adPosition'
|
||
import { isImageMime } from '@/utils/image'
|
||
import { isNumber } from '@/utils/validator'
|
||
|
||
const page = ref(1)
|
||
const total = ref(0)
|
||
const pageSize = ref(10)
|
||
const rules = reactive({
|
||
position: [
|
||
{ required: true, message: '请输入广告位名称', trigger: 'blur' }
|
||
],
|
||
title: [
|
||
{ required: true, message: '请输入广告位标题', trigger: 'blur' }
|
||
],
|
||
mediaWidth: [
|
||
{ required: true, validator: isNumber, message: '请输入 > 0 的整数', trigger: 'blur' }
|
||
],
|
||
mediaHeight: [
|
||
{ required: true, validator: isNumber, message: '请输入 > 0 的整数', trigger: 'blur' }
|
||
],
|
||
})
|
||
|
||
// 查询
|
||
const tableData = ref([])
|
||
const getTableData = async () => {
|
||
const res = await getAdPositionList({ page: page.value, pageSize: pageSize.value })
|
||
if (res.code === 0) {
|
||
tableData.value = res.data.list
|
||
}
|
||
}
|
||
|
||
getTableData()
|
||
|
||
// 分页
|
||
const handleSizeChange = (val) => {
|
||
pageSize.value = val
|
||
getTableData()
|
||
}
|
||
|
||
// 修改页面容量
|
||
const handleCurrentChange = (val) => {
|
||
page.value = val
|
||
getTableData()
|
||
}
|
||
|
||
// ----- 以下为 editForm 操作 -----
|
||
|
||
// 提交表单
|
||
const handleFormSubmit = async () => {
|
||
editFormRef.value.validate(async valid => {
|
||
if (!valid) {
|
||
return false
|
||
}
|
||
let res
|
||
if (isEdit.value) {
|
||
res = await updateAdPosition(editForm.value)
|
||
} else {
|
||
res = await addAdPosition(editForm.value)
|
||
}
|
||
if (res.code === 0) {
|
||
ElMessage({
|
||
type: 'success',
|
||
message: isEdit.value ? '编辑成功' : '添加成功!'
|
||
})
|
||
getTableData()
|
||
initForm()
|
||
dialogFormVisible.value = false
|
||
}
|
||
})
|
||
}
|
||
|
||
// 初始化弹窗内表格方法
|
||
const editFormRef = ref(null)
|
||
const editForm = ref({})
|
||
const checkFlag = ref(false)
|
||
const initForm = () => {
|
||
checkFlag.value = false
|
||
editForm.value = {
|
||
ID: 0,
|
||
position: '',
|
||
title: '',
|
||
imgUrl: '',
|
||
mediaHeight: 0,
|
||
mediaWidth: 0
|
||
}
|
||
}
|
||
|
||
// 关闭弹窗
|
||
const dialogFormVisible = ref(false)
|
||
const handleCloseDialog = () => {
|
||
initForm()
|
||
dialogFormVisible.value = false
|
||
}
|
||
|
||
// 删除
|
||
const handleDelete = (ID) => {
|
||
ElMessageBox.confirm('此操作将永久删除广告位, 是否继续?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
})
|
||
.then(async () => {
|
||
const res = await deleteAdPosition({ id: ID })
|
||
if (res.code === 0) {
|
||
ElMessage({
|
||
type: 'success',
|
||
message: '删除成功!'
|
||
})
|
||
if (tableData.value.length === 1 && page.value > 1) {
|
||
page.value--
|
||
}
|
||
getTableData()
|
||
}
|
||
})
|
||
.catch(() => {
|
||
ElMessage({
|
||
type: 'info',
|
||
message: '已取消删除'
|
||
})
|
||
})
|
||
}
|
||
|
||
const isEdit = ref(false)
|
||
const dialogTitle = ref('新增广告位')
|
||
const handleAdd = (id) => {
|
||
dialogTitle.value = '新增广告位'
|
||
isEdit.value = false
|
||
dialogFormVisible.value = true
|
||
}
|
||
// 修改菜单方法
|
||
const handleEdit = async (ID) => {
|
||
dialogTitle.value = '编辑广告位'
|
||
const res = await getAdPositionById({ id: ID })
|
||
editForm.value = res.data.adPosition
|
||
isEdit.value = true
|
||
dialogFormVisible.value = true
|
||
}
|
||
|
||
// ------- 图片操作 -------
|
||
const imgUploadPath = ref(import.meta.env.VITE_BASE_API)
|
||
const beforeUpload = (file) => {
|
||
const isLt500K = file.size / 1024 / 1024 < 0.5 // 500K, @todo 应支持在项目中设置
|
||
const isImage = isImageMime(file.type)
|
||
|
||
if (!isImage) {
|
||
ElMessage.error('上传图片只能是 jpg,png,svg,webp 格式!')
|
||
return false
|
||
}
|
||
if (!isLt500K && isImage) {
|
||
ElMessage.error('未压缩的上传图片大小不能超过 500KB,请使用压缩上传')
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
const uploadSuccess = (res) => {
|
||
const { code, data, msg } = res
|
||
if (code !== 0) {
|
||
ElMessage({ type: 'error', message: msg })
|
||
return
|
||
}
|
||
if (!data.mediaFile) {
|
||
ElMessage({ type: 'error', message: '返回错误,上传失败' })
|
||
return
|
||
}
|
||
editForm.value.imgUrl = data.mediaFile.url
|
||
}
|
||
|
||
const uploadFailure = () => {
|
||
ElMessage({
|
||
type: 'error',
|
||
message: '上传失败'
|
||
})
|
||
}
|
||
|
||
</script>
|
||
|
||
<style scoped>
|
||
.avatar-uploader .avatar {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: block;
|
||
}
|
||
</style>
|
||
|
||
<style>
|
||
.avatar-uploader .el-upload {
|
||
border: 1px solid var(--el-border-color);
|
||
border-radius: 6px;
|
||
cursor: pointer;
|
||
position: relative;
|
||
overflow: hidden;
|
||
transition: var(--el-transition-duration-fast);
|
||
}
|
||
|
||
.avatar-uploader .el-upload:hover {
|
||
border-color: var(--el-color-primary);
|
||
}
|
||
|
||
.el-icon.avatar-uploader-icon {
|
||
font-size: 28px;
|
||
color: #8c939d;
|
||
width: 178px;
|
||
height: 178px;
|
||
text-align: center;
|
||
}
|
||
|
||
.admin-box .el-table td .cell {
|
||
line-height: 28px;
|
||
}
|
||
</style>
|