Files
peko-admin-web/src/views/privilege/personalHomepageResourceManagement.vue

803 lines
23 KiB
Vue
Raw Normal View History

2024-11-14 15:37:31 +08:00
<template>
<div class="box">
<!-- 查询 -->
<div class="inquire">
<span>地区</span>
<el-select v-model="inquire.partitionId" placeholder="请选择">
<el-option
v-for="item in inquire.partitionArr"
:key="item.id"
:label="item.desc"
:value="item.id"
>
</el-option>
</el-select>
</div>
<div class="inquire">
<span>名称</span>
<el-input v-model="inquire.name" placeholder="" class="input"></el-input>
</div>
<div class="inquire">
<span>状态</span>
<el-select v-model="inquire.status" placeholder="请选择">
<el-option
v-for="item in inquire.options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
<!-- 查询按钮 -->
<el-button class="primary" type="primary" @click="getData()"
>查询</el-button
>
<!-- 新增按钮 -->
<el-button
class="primary"
type="primary"
@click="
2024-11-19 15:07:59 +08:00
operationValue.partitionVal = [];
2024-11-14 15:37:31 +08:00
operationValue.nameZh = '';
operationValue.nameEn = '';
operationValue.nameAr = '';
operationValue.nameTr = '';
operationValue.price = '';
operationValue.day = '';
operationValue.imageUrl = '';
operationValue.status = '';
2024-11-19 15:07:59 +08:00
operationType = 1;
filePreview: null; // 文件预览 URL
isImage = false;
isVideo = false;
isSVGA = false;
operationDialogTitle = '新增';
operationDialog = true;
2024-11-14 15:37:31 +08:00
"
>新增</el-button
>
<!-- 表格 -->
<el-table
v-loading="loading"
:data="tableData"
border
style="width: 100%; margin-top: 25px"
>
2024-12-03 16:00:26 +08:00
<el-table-column prop="id" align="center" label="id" />
2024-11-19 15:07:59 +08:00
<el-table-column prop="partitionFlag" align="center" label="地区">
<template v-slot="scope">
{{ partitionDesc(scope.row.partitionFlag) }}
</template>
</el-table-column>
<el-table-column prop="" align="center" label="中文名称">
<template v-slot="scope">
{{ jsonFun(scope.row.name).zh }}
</template>
</el-table-column>
<el-table-column prop="" align="center" label="阿语名称">
<template v-slot="scope">
{{ jsonFun(scope.row.name).ar }}
</template>
</el-table-column>
<el-table-column prop="" align="center" label="英语名称"
><template v-slot="scope">
{{ jsonFun(scope.row.name).en }}
</template>
</el-table-column>
<el-table-column prop="" align="center" label="土耳其名称"
><template v-slot="scope">
{{ jsonFun(scope.row.name).tr }}
</template>
</el-table-column>
<el-table-column prop="" align="center" label="图片">
2024-11-14 15:37:31 +08:00
<template v-slot="scope">
<el-image
2024-11-19 15:07:59 +08:00
:src="scope.row.pic"
2024-11-14 15:37:31 +08:00
:zoom-rate="1.1"
2024-11-19 15:07:59 +08:00
:preview-src-list="[scope.row.pic]"
fit="contain"
2024-11-14 15:37:31 +08:00
preview-teleported="true"
hide-on-click-modal="true"
/>
</template>
</el-table-column>
2024-11-19 15:07:59 +08:00
<el-table-column prop="" align="center" label="装扮动效图片类型">
2024-11-14 15:37:31 +08:00
<template v-slot="scope">
2024-11-19 15:07:59 +08:00
{{
scope.row.effectType == 0
? "无"
: scope.row.effectType == 1
? "MP4"
: "SVGA"
}}
2024-11-14 15:37:31 +08:00
</template>
</el-table-column>
2024-11-21 15:52:17 +08:00
<el-table-column
prop=""
width="300"
max-height="100"
align="center"
label="装扮动效图片"
>
<template v-slot="scope">
<div v-if="scope.row.effectType == 0"></div>
<!-- 视频预览 -->
<video
v-if="scope.row.effectType == 1"
:src="scope.row.effect"
controls
style="width: 300px; max-height: 300px; display: block"
></video>
<!-- SVGA 预览 -->
<div
v-if="scope.row.effectType == 2"
:id="`svga-player${scope.row.id}`"
style="width: 300px; max-height: 300px; display: block"
>
2024-11-21 16:54:11 +08:00
{{
scope.row.effect && scope.row.id
? initSVGAList(scope.row.effect, scope.row.id)
: ""
}}
2024-11-21 15:52:17 +08:00
<!-- <img style="width: 100px; height: 100px; display: block" src="/Uploads/article/original_img/1487053722.jpg" alt="">
<el-image src=""></el-image> -->
</div>
</template>
</el-table-column>
2024-11-19 15:07:59 +08:00
<el-table-column prop="" align="center" label="状态">
<template v-slot="scope">
{{ scope.row.status == 1 ? "有效" : "无效" }}
</template>
</el-table-column>
<el-table-column prop="" align="center" label="贵族限定">
<template v-slot="scope">
{{ scope.row.type == 1 ? "普通" : "贵族" }}
</template>
</el-table-column>
<el-table-column prop="updateTime" align="center" label="操作时间" />
2024-11-14 15:37:31 +08:00
<el-table-column align="center" label="操作" width="300">
<template v-slot="scope">
<el-button
@click="
2024-11-19 15:07:59 +08:00
operationValue.partitionVal = partitionIdArr(
scope.row.partitionFlag
);
operationValue.nameZh = jsonFun(scope.row.name).zh;
operationValue.nameEn = jsonFun(scope.row.name).en;
operationValue.nameAr = jsonFun(scope.row.name).ar;
operationValue.nameTr = jsonFun(scope.row.name).tr;
operationValue.imageUrl = scope.row.pic;
operationValue.status = scope.row.status;
operationType = 2;
operationValueId = scope.row.id;
operationDialogTitle = '编辑';
filePreview: scope.row.effect; // 文件预览 URL
scope.row.effectType == 1
? (isVideo = true)
: scope.row.effectType == 2
? (isSVGA = true)
: (isImage = true);
operationValue.effectType = scope.row.effectType;
initSVGA(scope.row.effect);
2024-11-14 15:37:31 +08:00
operationDialog = true;
"
class="primary"
type="primary"
size="default"
>编辑</el-button
>
<el-button
2024-11-19 15:07:59 +08:00
@click="
sendDialog = true;
sendObj.erbanNos = send.days = send.remark = null;
sendObj.personalBackgroundId = scope.row.id;
"
2024-11-14 15:37:31 +08:00
class="primary"
type="primary"
size="default"
>赠送</el-button
>
</template>
</el-table-column>
</el-table>
2024-11-19 15:07:59 +08:00
<!-- 新增&编辑弹窗 -->
2024-11-14 15:37:31 +08:00
<el-dialog
v-model="operationDialog"
:title="operationDialogTitle"
width="28%"
center
>
2024-11-19 15:07:59 +08:00
<!-- <div class="operation">
2024-11-14 15:37:31 +08:00
<span style="margin-right: 20px">地区</span>
<el-select v-model="operationValue.partitionId" placeholder="请选择">
<el-option
v-for="item in operationValue.partitionArr"
:key="item.id"
:label="item.desc"
:value="item.id"
>
</el-option>
</el-select>
2024-11-19 15:07:59 +08:00
</div> -->
<div class="operation">
<span style="margin-right: 20px">地区</span>
<el-checkbox-group
v-model="operationValue.partitionVal"
v-for="(val, i) in inquire.partitionArr"
:key="i"
>
<el-checkbox style="margin-right: 10px" :label="val.id">{{
val.desc
}}</el-checkbox>
</el-checkbox-group>
2024-11-14 15:37:31 +08:00
</div>
<div class="operation">
<span style="margin-right: 20px">华语名称</span>
<el-input
v-model="operationValue.nameZh"
style="width: 200px"
class="input"
></el-input>
</div>
<div class="operation">
<span style="margin-right: 20px">英语名称</span>
<el-input
v-model="operationValue.nameEn"
style="width: 200px"
class="input"
></el-input>
</div>
<div class="operation">
<span style="margin-right: 20px">阿拉伯名称</span>
<el-input
v-model="operationValue.nameAr"
style="width: 200px"
class="input"
></el-input>
</div>
<div class="operation">
<span style="margin-right: 20px">土耳其名称</span>
<el-input
v-model="operationValue.nameTr"
style="width: 200px"
class="input"
></el-input>
</div>
2024-11-19 15:07:59 +08:00
<!-- <div class="operation">
2024-11-14 15:37:31 +08:00
<span style="margin-right: 20px">价格</span>
<el-input
v-model="operationValue.price"
style="width: 200px"
class="input"
></el-input>
</div>
<div class="operation">
<span style="margin-right: 20px">有效天数</span>
<el-input
v-model="operationValue.day"
style="width: 200px"
class="input"
></el-input>
2024-11-19 15:07:59 +08:00
</div> -->
2024-11-14 15:37:31 +08:00
<div class="operation">
<span class="left" style="margin-right: 20px">图片</span>
<el-upload
class="avatar-uploader"
action="/admin/tencent/cos/upload/file"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:on-error="handleAvatarError"
>
<img
v-if="operationValue.imageUrl"
:src="operationValue.imageUrl"
class="avatar"
/>
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
</div>
2024-11-19 15:07:59 +08:00
<div class="operation">
<span style="margin-right: 20px">装扮动效图片类型</span>
<el-select v-model="operationValue.effectType" placeholder="请选择">
<el-option
v-for="item in operationValue.effectTypeArr"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
<div class="operation">
<span class="left" style="margin-right: 20px">装扮动效图片</span>
<el-upload
class="avatar-uploader"
action="/admin/tencent/cos/upload/file"
accept="image/*,.mp4,.svga"
:show-file-list="false"
:on-success="handleAvatarSuccess1"
:before-upload="beforeAvatarUpload"
:on-error="handleAvatarError"
>
<!-- 文件预览 -->
<div style="margin-top: 20px">
<!-- 图片预览 -->
<img
v-if="isImage"
:src="filePreview"
alt="Uploaded Image"
style="max-width: 300px"
/>
<!-- 视频预览 -->
2024-11-21 15:52:17 +08:00
<video
2024-11-19 15:07:59 +08:00
v-else-if="isVideo"
:src="filePreview"
controls
style="max-width: 300px"
2024-11-21 15:52:17 +08:00
></video>
2024-11-19 15:07:59 +08:00
<!-- SVGA 预览 -->
2024-11-21 15:52:17 +08:00
<div
2024-11-19 15:07:59 +08:00
v-else-if="isSVGA"
:id="`svga-player`"
style="width: 200px; height: 200px"
2024-11-21 15:52:17 +08:00
></div>
2024-11-19 15:07:59 +08:00
</div>
</el-upload>
</div>
2024-11-14 15:37:31 +08:00
<div class="operation">
<span style="margin-right: 20px">状态</span>
<el-select v-model="operationValue.status" placeholder="请选择">
<el-option
v-for="item in operationValue.options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
<template #footer>
<span class="dialog-footer">
2024-11-19 15:07:59 +08:00
<el-button
@click="
operationDialog = false;
isImage = false;
isVideo = false;
isSVGA = false;
"
>取消</el-button
>
<el-button
type="primary"
@click="operation(type == 1 ? null : operationValueId)"
>
确认
</el-button>
2024-11-14 15:37:31 +08:00
</span>
</template>
</el-dialog>
<!-- 分页 -->
<el-pagination
style="margin-top: 10px"
class="paginationClass"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 30, 40, 50, 100, 200, 300, 400, 500, 999999999]"
layout="sizes, prev, pager, next"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
2024-11-19 15:07:59 +08:00
<!-- 赠送 -->
<el-dialog v-model="sendDialog" title="赠送" width="28%" center>
<div class="operation">
<span style="margin-right: 20px">用户平台ID</span>
<el-input
v-model="sendObj.erbanNos"
style="width: 200px"
class="input"
placeholder="多个请用英文“,”隔开"
></el-input>
</div>
<div class="operation">
<span style="margin-right: 20px">天数</span>
<el-input
v-model="sendObj.days"
style="width: 200px"
class="input"
placeholder=""
></el-input>
</div>
<div class="operation">
<span style="margin-right: 20px">备注</span>
<el-input
v-model="sendObj.remark"
style="width: 200px"
class="input"
placeholder=""
></el-input>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="sendDialog = false">取消</el-button>
<el-button type="primary" @click="send()"> 确认 </el-button>
</span>
</template>
</el-dialog>
2024-11-14 15:37:31 +08:00
</div>
</template>
<script>
2024-11-19 15:07:59 +08:00
import {
listPartitionInfo,
pesonalBackgroundListByPage,
pesonalBackgroundSaveOrUpdate,
pesonalBackgroundListSend,
} from "@/api/personalHomepageResourceManagement/personalHomepageResourceManagement";
2024-11-14 15:37:31 +08:00
// @ts-ignore
import { dateFormat } from "@/utils/system-helper";
2024-11-19 15:07:59 +08:00
import { partitionDesc, partitionIdArr } from "@/utils/partitionDesc.js";
2024-11-21 15:52:17 +08:00
import { ref, reactive, onMounted, onUnmounted, nextTick } from "vue";
2024-11-14 15:37:31 +08:00
// @ts-ignore
import { ElMessage } from "element-plus";
2024-11-19 15:07:59 +08:00
import SVGA from "svgaplayerweb";
2024-11-14 15:37:31 +08:00
export default {
name: "personalHomepageResourceManagement",
2024-11-21 15:52:17 +08:00
setup() {
// 响应式数据
const file = ref(null);
const filePreview = ref(null);
const isImage = ref(false);
const isVideo = ref(false);
const isSVGA = ref(false);
const loading = ref(false);
const inquire = reactive({
partitionId: "",
partitionArr: [],
name: "",
status: "",
options: [
{ label: "有效", value: 1 },
{ label: "无效", value: 2 },
{ label: "全部", value: 3 },
],
2024-11-19 15:07:59 +08:00
});
2024-11-21 15:52:17 +08:00
const operationDialog = ref(false);
const operationType = ref(null);
const operationDialogTitle = ref("新增%编辑");
const operationValueId = ref(null);
const operationValue = reactive({
partitionVal: [],
nameZh: "",
nameEn: "",
nameAr: "",
nameTr: "",
price: "",
day: "",
imageUrl: "",
status: "",
options: [
{ label: "有效", value: 1 },
{ label: "无效", value: 2 },
],
effectType: "",
effectTypeArr: [
{ label: "无", value: 0 },
{ label: "MP4", value: 1 },
{ label: "SVGA", value: 2 },
],
});
const sendDialog = ref(false);
const sendObj = reactive({
erbanNos: null,
days: null,
personalBackgroundId: null,
remark: null,
});
const tableData = ref([]);
2024-11-21 16:19:04 +08:00
const total = ref(0); // 总页数
2024-11-21 15:52:17 +08:00
const currentPage = ref(1); // 页码
const pageSize = ref(10); // 条数
// 生命周期钩子
onMounted(() => {
console.log("组件已挂载");
listPartitionInfo().then((res) => {
inquire.partitionArr = operationValue.partitionArr = res.data;
inquire.partitionId = inquire.partitionArr[0].id;
getData();
});
});
onUnmounted(() => {
console.log("组件已卸载");
});
2024-11-14 15:37:31 +08:00
// 查询接口
2024-11-21 15:52:17 +08:00
const getData = () => {
loading.value = true;
2024-11-19 15:07:59 +08:00
pesonalBackgroundListByPage({
2024-11-21 15:52:17 +08:00
partitionId: inquire.partitionId,
name: inquire.name,
status: inquire.status,
page: currentPage.value,
pageSize: pageSize.value,
2024-11-19 15:07:59 +08:00
}).then((res) => {
if (res.code == 200) {
2024-11-21 15:52:17 +08:00
loading.value = false;
total.value = res.data.total;
tableData.value = res.data.list;
2024-11-19 15:07:59 +08:00
} else {
ElMessage({
showClose: true,
message: res.message,
type: "error",
});
}
});
2024-11-21 15:52:17 +08:00
};
const operation = (id) => {
const obj = {
partitionFlag: operationValue.partitionVal.reduce(
(accumulator, currentValue) => accumulator + currentValue,
0
),
name: JSON.stringify({
ar: operationValue.nameAr,
zh: operationValue.nameZh,
en: operationValue.nameEn,
tr: operationValue.nameTr,
}),
pic: operationValue.imageUrl,
effectType: operationValue.effectType,
effect: filePreview.value,
status: operationValue.status,
type: 1, // 资料卡类型 1普通 2贵族
id,
};
2024-11-19 15:07:59 +08:00
console.log(obj);
pesonalBackgroundSaveOrUpdate(obj).then((res) => {
if (res.code == 200) {
2024-11-21 15:52:17 +08:00
operationDialog.value = false;
getData();
isImage.value = false;
isVideo.value = false;
isSVGA.value = false;
2024-11-19 15:07:59 +08:00
} else {
ElMessage({
showClose: true,
message: res.message,
type: "error",
});
}
});
2024-11-21 15:52:17 +08:00
};
const send = () => {
pesonalBackgroundListSend(sendObj).then((res) => {
2024-11-19 15:07:59 +08:00
if (res.code == 200) {
2024-11-21 15:52:17 +08:00
sendDialog.value = false;
2024-11-19 15:07:59 +08:00
ElMessage({
showClose: true,
message: "赠送成功",
type: "success",
});
} else {
ElMessage({
showClose: true,
message: res.message,
type: "error",
});
}
});
2024-11-21 15:52:17 +08:00
};
const beforeAvatarUpload = () => {
2024-11-14 15:37:31 +08:00
ElMessage({
showClose: true,
2024-11-19 15:07:59 +08:00
message: "上传中可能较慢,请等待上传成功后在进行下一步~",
2024-11-14 15:37:31 +08:00
type: "warning",
});
2024-11-21 15:52:17 +08:00
};
const handleAvatarError = () => {
2024-11-14 15:37:31 +08:00
ElMessage({
showClose: true,
message: "上传失败!",
type: "error",
});
2024-11-21 15:52:17 +08:00
};
const handleAvatarSuccess = (res, file) => {
2024-11-14 15:37:31 +08:00
console.log(file);
2024-11-21 15:52:17 +08:00
operationValue.imageUrl = file.response.data;
2024-11-19 15:07:59 +08:00
ElMessage({
showClose: true,
message: "上传成功!",
type: "success",
});
2024-11-21 15:52:17 +08:00
};
const handleAvatarSuccess1 = (res, files) => {
2024-11-19 15:07:59 +08:00
console.log(files.raw);
const selectedFile = files.raw;
if (!selectedFile) return;
// 清除旧的预览数据
2024-11-21 16:19:04 +08:00
// resetFile();
2024-11-19 15:07:59 +08:00
const fileType = selectedFile.type;
const fileName = selectedFile.name;
// 创建预览 URL
2024-11-21 15:52:17 +08:00
filePreview.value = res.data;
file.value = selectedFile;
2024-11-19 15:07:59 +08:00
// 根据文件类型判断
if (fileType.startsWith("image/")) {
2024-11-21 15:52:17 +08:00
isImage.value = true;
2024-11-19 15:07:59 +08:00
} else if (fileType === "video/mp4") {
2024-11-21 15:52:17 +08:00
isVideo.value = true;
2024-11-19 15:07:59 +08:00
} else if (fileName.endsWith(".svga")) {
2024-11-21 15:52:17 +08:00
isSVGA.value = true;
initSVGA(res.data);
2024-11-19 15:07:59 +08:00
}
2024-11-14 15:37:31 +08:00
ElMessage({
showClose: true,
message: "上传成功!",
type: "success",
});
2024-11-21 15:52:17 +08:00
};
2024-11-21 16:19:04 +08:00
// const resetFile = () => {
// nextTick(() => {
// file.value = null;
// filePreview.value = null;
// isImage.value = false;
// isVideo.value = false;
// isSVGA.value = false;
// // 清除 SVGA 容器内容
// const svgaPlayer = document.getElementById("svga-player");
// if (svgaPlayer) {
// svgaPlayer.innerHTML = "";
// }
// });
// };
2024-11-21 15:52:17 +08:00
const initSVGA = (url) => {
nextTick(() => {
2024-11-21 16:54:11 +08:00
setTimeout(function () {
const container = document.getElementById("svga-player");
if (container) {
const player = new SVGA.Player(container);
const parser = new SVGA.Parser();
parser.load(
url,
(videoItem) => {
player.setVideoItem(videoItem);
player.startAnimation();
},
(error) => {
console.log("SVGA失败", error);
}
);
}
}, 10);
2024-11-19 15:07:59 +08:00
});
2024-11-21 15:52:17 +08:00
};
2024-11-21 16:54:11 +08:00
const initializedIds = new Set();
2024-11-21 15:52:17 +08:00
const initSVGAList = (url, id) => {
2024-11-21 16:54:11 +08:00
if (initializedIds.has(id)) return; // 避免重复初始化
console.log('SVGASVGASVGASVGASVGASVGA',url,id);
2024-11-21 15:52:17 +08:00
nextTick(() => {
2024-11-19 15:07:59 +08:00
const container = document.getElementById("svga-player" + id);
2024-11-21 14:13:46 +08:00
if (!container) {
console.error(`SVGA container for ID ${id} not found`);
2024-11-21 16:54:11 +08:00
return;
2024-11-21 14:13:46 +08:00
}
try {
2024-11-19 15:07:59 +08:00
const player = new SVGA.Player(container);
const parser = new SVGA.Parser();
parser.load(url, (videoItem) => {
player.setVideoItem(videoItem);
player.startAnimation();
});
2024-11-21 16:54:11 +08:00
initializedIds.add(id); // 标记已初始化
2024-11-21 14:13:46 +08:00
} catch (error) {
console.error("SVGA initialization failed:", error);
2024-11-19 15:07:59 +08:00
}
});
2024-11-21 15:52:17 +08:00
};
const jsonFun = (val) => JSON.parse(val);
2024-11-14 15:37:31 +08:00
// 分页导航
2024-11-21 15:52:17 +08:00
const handleSizeChange = () => {
getData();
};
const handleCurrentChange = () => {
getData();
};
return {
partitionDesc,
partitionIdArr,
file,
filePreview,
isImage,
isVideo,
isSVGA,
loading,
inquire,
operationDialog,
operationType,
operationDialogTitle,
operationValueId,
operationValue,
sendDialog,
sendObj,
tableData,
total,
currentPage,
pageSize,
getData,
operation,
send,
beforeAvatarUpload,
handleAvatarError,
handleAvatarSuccess,
handleAvatarSuccess1,
2024-11-21 16:19:04 +08:00
// resetFile,
2024-11-21 15:52:17 +08:00
initSVGA,
initSVGAList,
jsonFun,
handleSizeChange,
handleCurrentChange,
};
2024-11-14 15:37:31 +08:00
},
};
</script>
<style lang="less" scoped>
.box {
padding-top: 20px;
background: #ecf0f5;
.inquire {
display: inline-block;
margin-right: 20px;
span {
margin-right: 10px;
}
.input {
width: 180px;
margin-right: 10px;
}
}
.dialogTableVisibleBut {
display: block;
margin: 30px 0 0 830px;
}
.paginationClass {
margin: 15px 0 5px 0px;
}
}
.operation {
margin-bottom: 20px;
width: 55%;
display: flex;
align-items: baseline;
justify-content: space-between;
}
2024-11-19 15:07:59 +08:00
.avatar {
width: 100%;
}
2024-11-14 15:37:31 +08:00
</style>