web-admin/src/view/ad/position.vue

292 lines
8.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>