品牌活动整改
This commit is contained in:
@@ -21,37 +21,61 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
content: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
// 详情数据通常在组件创建后异步回填,每次内容变化都重新识别并渲染 PDF。
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pdf: true,
|
||||
pdfObj: null,
|
||||
previewVersion: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.destroyPdf()
|
||||
const currentVersion = ++this.previewVersion
|
||||
try {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(this.content, 'text/html');
|
||||
const link = doc.querySelector('a');
|
||||
const href = link.getAttribute('href');
|
||||
if(!href) {
|
||||
const parser = new DOMParser()
|
||||
const doc = parser.parseFromString(this.content || '', 'text/html')
|
||||
const link = doc.querySelector('a')
|
||||
const href = link ? link.getAttribute('href') : ''
|
||||
if (!href) {
|
||||
this.pdf = false
|
||||
return
|
||||
}
|
||||
|
||||
const parsedUrl = new URL(href, window.location.origin)
|
||||
const linkText = (link.textContent || '').trim().toLowerCase()
|
||||
const isPdf = linkText.endsWith('.pdf') || parsedUrl.pathname.toLowerCase().endsWith('.pdf')
|
||||
if (!isPdf) {
|
||||
this.pdf = false
|
||||
return
|
||||
}
|
||||
|
||||
// 系统上传文件可能保存了其他环境的绝对域名,内部下载地址统一使用当前站点。
|
||||
const pdfUrl = parsedUrl.pathname === '/platform/sys/file/download'
|
||||
? parsedUrl.pathname + parsedUrl.search : parsedUrl.href
|
||||
this.pdf = true
|
||||
this.$nextTick(() => {
|
||||
if (currentVersion !== this.previewVersion || !this.pdf) return
|
||||
this.pdfObj = new Pdfh5('#pdf-container', {
|
||||
pdfurl: href,
|
||||
});
|
||||
this.pdfObj.on("complete", function () {
|
||||
const elements = document.querySelectorAll('[class*="canvasImg"]')
|
||||
let classArray = []
|
||||
pdfurl: pdfUrl,
|
||||
})
|
||||
this.pdfObj.on("complete", () => {
|
||||
if (currentVersion !== this.previewVersion) return
|
||||
const elements = this.$el.querySelectorAll('[class*="canvasImg"]')
|
||||
const classArray = []
|
||||
elements.forEach(element => {
|
||||
classArray.push(element.getAttribute('src'))
|
||||
})
|
||||
elements.forEach((element,index) => {
|
||||
element.addEventListener('click', function() {
|
||||
element.addEventListener('click', () => {
|
||||
vant.ImagePreview({
|
||||
images: classArray,
|
||||
startPosition: index,
|
||||
@@ -65,9 +89,17 @@ module.exports = {
|
||||
this.pdf = false
|
||||
}
|
||||
},
|
||||
destroyPdf() {
|
||||
// 内容切换或组件销毁时释放 PDF 渲染实例,避免重复打开详情产生资源残留。
|
||||
if (this.pdfObj && this.pdfObj.destroy) {
|
||||
this.pdfObj.destroy()
|
||||
}
|
||||
this.pdfObj = null
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
beforeDestroy() {
|
||||
this.previewVersion += 1
|
||||
this.destroyPdf()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -3,7 +3,175 @@ layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
|
||||
.activity-introduce-dialog {
|
||||
max-width: calc(100vw - 40px);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.activity-introduce-dialog .el-dialog__header {
|
||||
padding: 20px 24px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
.activity-introduce-dialog .el-dialog__title {
|
||||
color: #303133;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.activity-introduce-dialog .el-dialog__body {
|
||||
padding: 0;
|
||||
}
|
||||
.activity-introduce-dialog .el-dialog__footer {
|
||||
padding: 16px 24px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
}
|
||||
.activity-introduce-layout {
|
||||
display: flex;
|
||||
height: calc(86vh - 128px);
|
||||
min-height: 520px;
|
||||
max-height: 650px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.activity-introduce-summary {
|
||||
box-sizing: border-box;
|
||||
width: 280px;
|
||||
flex-shrink: 0;
|
||||
padding: 24px;
|
||||
background: #f7faff;
|
||||
border-right: 1px solid #ebeef5;
|
||||
}
|
||||
.activity-introduce-cover {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 152px;
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
background: #eef3f8;
|
||||
}
|
||||
.activity-introduce-cover-empty {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #a8abb2;
|
||||
font-size: 40px;
|
||||
}
|
||||
.activity-introduce-name {
|
||||
margin: 16px 0 18px;
|
||||
color: #303133;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.activity-introduce-meta {
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
.activity-introduce-meta-item {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.activity-introduce-meta-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.activity-introduce-meta-item > i {
|
||||
width: 20px;
|
||||
margin-top: 4px;
|
||||
color: #909399;
|
||||
font-size: 16px;
|
||||
}
|
||||
.activity-introduce-meta-label {
|
||||
color: #909399;
|
||||
}
|
||||
.activity-introduce-steps {
|
||||
height: 115px;
|
||||
margin-top: 22px;
|
||||
}
|
||||
.activity-introduce-steps .el-step__title {
|
||||
font-size: 14px;
|
||||
}
|
||||
.activity-introduce-main {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
padding: 24px;
|
||||
}
|
||||
.activity-introduce-main-title {
|
||||
margin-bottom: 16px;
|
||||
padding-left: 12px;
|
||||
border-left: 4px solid var(--color-primary);
|
||||
color: #303133;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
}
|
||||
.activity-introduce-file {
|
||||
display: flex;
|
||||
height: 38px;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
padding: 0 14px;
|
||||
border-radius: 4px;
|
||||
background: #f2f4f7;
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
}
|
||||
.activity-introduce-file i {
|
||||
margin-right: 8px;
|
||||
color: #f56c6c;
|
||||
font-size: 16px;
|
||||
}
|
||||
.activity-introduce-preview {
|
||||
min-height: 0;
|
||||
flex: 1;
|
||||
margin-top: 14px;
|
||||
overflow: hidden;
|
||||
background: #eef1f5;
|
||||
}
|
||||
.activity-introduce-pdf {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
}
|
||||
.activity-introduce-content {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
padding: 28px 36px;
|
||||
background: #fff;
|
||||
color: #303133;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
.activity-introduce-empty {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #909399;
|
||||
}
|
||||
.activity-introduce-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.activity-introduce-footer-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
.activity-introduce-footer-actions .el-button {
|
||||
min-width: 110px;
|
||||
}
|
||||
.activity-introduce-footer-actions .el-button--primary {
|
||||
min-width: 180px;
|
||||
}
|
||||
.activity-introduce-countdown {
|
||||
color: #e6a23c;
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
@@ -60,7 +228,7 @@ layout("/layouts/platform.html"){
|
||||
<template v-slot="{row}">
|
||||
<template v-if="$moment().isBefore($moment(row.activitySignUpEndTime))">
|
||||
<el-button @click="onView(row)" size="mini" type="primary">查看介绍</el-button>
|
||||
<el-button @click="onOpen(row)" size="mini" type="primary">去报名</el-button>
|
||||
<el-button @click="onView(row)" size="mini" type="primary">去报名</el-button>
|
||||
</template>
|
||||
<template v-if="$moment().isAfter($moment(row.activitySignUpEndTime))">
|
||||
<el-button size="mini" type="info">已结束</el-button>
|
||||
@@ -76,40 +244,101 @@ layout("/layouts/platform.html"){
|
||||
</template>
|
||||
</guava>
|
||||
|
||||
<el-dialog title="详细信息" :visible.sync="infoVisible" width="60%">
|
||||
<el-dialog title="活动介绍"
|
||||
custom-class="activity-introduce-dialog"
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="infoVisible"
|
||||
top="7vh"
|
||||
width="1120px">
|
||||
<div class="activity-introduce-layout">
|
||||
<aside class="activity-introduce-summary">
|
||||
<el-image class="activity-introduce-cover" :src="infoRow.cover" fit="cover">
|
||||
<div slot="error" class="activity-introduce-cover-empty">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
<div class="activity-introduce-name">{{infoRow.activityName || '品牌活动'}}</div>
|
||||
<div class="activity-introduce-meta">
|
||||
<div class="activity-introduce-meta-item">
|
||||
<i class="el-icon-date"></i>
|
||||
<div>
|
||||
<div class="activity-introduce-meta-label">报名时间</div>
|
||||
<div>{{$moment(infoRow.activitySignUpStartTime).format('YYYY-MM-DD HH:mm')}}</div>
|
||||
<div>至 {{$moment(infoRow.activitySignUpEndTime).format('YYYY-MM-DD HH:mm')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="activity-introduce-meta-item">
|
||||
<i class="el-icon-time"></i>
|
||||
<div>
|
||||
<div class="activity-introduce-meta-label">活动时间</div>
|
||||
<div>{{$moment(infoRow.activityStartTime).format('YYYY-MM-DD HH:mm')}}</div>
|
||||
<div>至 {{$moment(infoRow.activityEndTime).format('YYYY-MM-DD HH:mm')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="activity-introduce-meta-item">
|
||||
<i class="el-icon-user"></i>
|
||||
<div>
|
||||
<div class="activity-introduce-meta-label">面向对象</div>
|
||||
<div>{{infoRow.activityGroupName || '全体工会会员'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-steps class="activity-introduce-steps" direction="vertical" :active="0">
|
||||
<el-step title="阅读活动介绍"></el-step>
|
||||
<el-step title="选择报名项目"></el-step>
|
||||
</el-steps>
|
||||
</aside>
|
||||
|
||||
<activity-info ref="infoRef"></activity-info>
|
||||
<section class="activity-introduce-main">
|
||||
<div class="activity-introduce-main-title">报名须知</div>
|
||||
<div class="activity-introduce-file">
|
||||
<i :class="activityIntroducePdfUrl ? 'fa fa-file-pdf-o' : 'fa fa-file-text-o'"></i>
|
||||
<span>{{activityIntroduceFileName}}</span>
|
||||
<span v-if="activityIntroducePageCount"> · {{activityIntroducePageCount}}页</span>
|
||||
</div>
|
||||
<div class="activity-introduce-preview">
|
||||
<iframe v-if="activityIntroducePdfUrl"
|
||||
ref="activityPdfFrame"
|
||||
class="activity-introduce-pdf"
|
||||
@load="styleActivityPdf"
|
||||
:src="activityIntroducePdfUrl"></iframe>
|
||||
<div v-else-if="infoRow.introduce"
|
||||
class="activity-introduce-content"
|
||||
v-html="infoRow.introduce"></div>
|
||||
<div v-else class="activity-introduce-empty">暂无活动介绍</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-statistic
|
||||
v-if="time < 0"
|
||||
format="DD 天 HH 时 mm 分钟 ss 秒"
|
||||
:value="new Date(infoRow.activitySignUpStartTime)"
|
||||
time-indices
|
||||
title="距离开始:"
|
||||
@finish="time = 0"
|
||||
>
|
||||
</el-statistic>
|
||||
<template v-else>
|
||||
<el-button @click="infoVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="onOpen(infoRow)" :disabled="time < 0">
|
||||
去报名
|
||||
</el-button>
|
||||
</template>
|
||||
</span>
|
||||
<div slot="footer" class="activity-introduce-footer">
|
||||
<div>
|
||||
<el-checkbox v-model="activityIntroduceConfirmed" :disabled="time < 0">
|
||||
我已阅读并知晓活动说明
|
||||
</el-checkbox>
|
||||
<span class="activity-introduce-countdown" v-if="time < 0">
|
||||
报名尚未开始
|
||||
</span>
|
||||
</div>
|
||||
<div class="activity-introduce-footer-actions">
|
||||
<el-button @click="closeIntroduce">暂不报名</el-button>
|
||||
<el-button type="primary"
|
||||
:disabled="time < 0 || !activityIntroduceConfirmed"
|
||||
@click="onOpen(infoRow)">
|
||||
确定并选择报名项目
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('courseList.js'){}#-->
|
||||
<!--#include('../manage/info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"course-list": courseList,
|
||||
"activity-info": info,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -126,25 +355,89 @@ layout("/layouts/platform.html"){
|
||||
time: 0,
|
||||
infoRow: {},
|
||||
infoVisible: false,
|
||||
activityIntroducePdfUrl: '',
|
||||
activityIntroduceFileName: '活动介绍',
|
||||
activityIntroducePageCount: null,
|
||||
activityIntroduceConfirmed: false,
|
||||
|
||||
id: GetQueryString("id"),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onView(row) {
|
||||
this.infoRow = row
|
||||
this.time = this.$moment().diff(this.$moment(row.activitySignUpStartTime), 'milliseconds')
|
||||
this.infoVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.infoRef.initData(row.id)
|
||||
})
|
||||
const introduce = this.resolveActivityIntroduce(row.introduce)
|
||||
this.$set(this.$data, 'infoRow', row)
|
||||
this.$set(this.$data, 'activityIntroducePdfUrl', introduce.pdfUrl)
|
||||
this.$set(this.$data, 'activityIntroduceFileName', introduce.fileName)
|
||||
this.$set(this.$data, 'activityIntroducePageCount', null)
|
||||
this.$set(this.$data, 'activityIntroduceConfirmed', false)
|
||||
this.$set(this.$data, 'time', this.$moment().diff(this.$moment(row.activitySignUpStartTime), 'milliseconds'))
|
||||
this.$set(this.$data, 'infoVisible', true)
|
||||
},
|
||||
resolveActivityIntroduce(introduce) {
|
||||
try {
|
||||
const parser = new DOMParser()
|
||||
const doc = parser.parseFromString(introduce || '', 'text/html')
|
||||
const link = doc.querySelector('a')
|
||||
const href = link ? link.getAttribute('href') : ''
|
||||
if (!href) return {pdfUrl: '', fileName: '活动介绍'}
|
||||
|
||||
const parsedUrl = new URL(href, window.location.origin)
|
||||
const linkText = (link.textContent || '').trim().toLowerCase()
|
||||
const isPdf = linkText.endsWith('.pdf') || parsedUrl.pathname.toLowerCase().endsWith('.pdf')
|
||||
if (!isPdf) return {pdfUrl: '', fileName: '活动介绍'}
|
||||
|
||||
// 系统内部文件使用当前站点地址,避免历史环境域名导致 PDF 无法加载。
|
||||
const pdfUrl = parsedUrl.pathname === '/platform/sys/file/download'
|
||||
? parsedUrl.pathname + parsedUrl.search : parsedUrl.href
|
||||
return {
|
||||
pdfUrl: '/assets/platform/plugins/pdfJs/web/viewer.html?file=' + encodeURIComponent(pdfUrl),
|
||||
fileName: (link.textContent || '').trim() || '活动介绍.pdf'
|
||||
}
|
||||
} catch (e) {
|
||||
// 无法识别为 PDF 时按原有富文本内容展示。
|
||||
return {pdfUrl: '', fileName: '活动介绍'}
|
||||
}
|
||||
},
|
||||
styleActivityPdf() {
|
||||
try {
|
||||
const frame = this.$refs.activityPdfFrame
|
||||
const viewerDocument = frame ? frame.contentDocument : null
|
||||
if (!viewerDocument) return
|
||||
|
||||
// 报名前预览只保留文档阅读区,隐藏 PDF.js 原生工具栏以匹配确认弹框的简洁层级。
|
||||
const toolbar = viewerDocument.getElementById('toolbarContainer')
|
||||
const mainContainer = viewerDocument.getElementById('mainContainer')
|
||||
const viewerContainer = viewerDocument.getElementById('viewerContainer')
|
||||
if (toolbar) toolbar.style.display = 'none'
|
||||
if (mainContainer) mainContainer.style.top = '0'
|
||||
if (viewerContainer) viewerContainer.style.top = '0'
|
||||
|
||||
const viewerApplication = frame.contentWindow.PDFViewerApplication
|
||||
if (viewerApplication && viewerApplication.initializedPromise) {
|
||||
viewerApplication.initializedPromise.then(() => {
|
||||
viewerApplication.eventBus.on('pagesloaded', (event) => {
|
||||
this.$set(this.$data, 'activityIntroducePageCount', event.pagesCount || null)
|
||||
})
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
// PDF 查看器样式隔离失败时保留原始查看器,不影响文档阅读和报名流程。
|
||||
}
|
||||
},
|
||||
closeIntroduce() {
|
||||
this.$set(this.$data, 'infoVisible', false)
|
||||
},
|
||||
onOpen(row) {
|
||||
if(this.$moment().isBefore(this.$moment(row.activitySignUpStartTime))) {
|
||||
this.onView(row)
|
||||
return
|
||||
}
|
||||
this.infoVisible = false
|
||||
if (!this.activityIntroduceConfirmed) {
|
||||
this.$message.warning('请先确认已阅读活动说明')
|
||||
return
|
||||
}
|
||||
this.$set(this.$data, 'infoVisible', false)
|
||||
this.$nextTick(() => {
|
||||
this.$refs.guava.view(() => {
|
||||
this.$refs.courseListRef.onOpen(row)
|
||||
|
||||
@@ -55,7 +55,7 @@ const info = {
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :visible.sync="viewMapDialog" title="地点" width="60%">
|
||||
<el-dialog :visible.sync="viewMapDialog" @closed="destroyViewMap" title="地点" width="60%">
|
||||
<div id="viewMap" style="width: 100%; height: 500px"></div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -69,6 +69,8 @@ const info = {
|
||||
courseTimeList: [],
|
||||
|
||||
viewMapDialog: false,
|
||||
viewMap: null,
|
||||
viewMarkerLayer: null,
|
||||
welfareProjectName: '',
|
||||
}
|
||||
},
|
||||
@@ -103,28 +105,49 @@ const info = {
|
||||
this.courseTimeListDialog = true
|
||||
},
|
||||
openViewMap(point) {
|
||||
if (!Array.isArray(point)) {
|
||||
// 地点坐标按项目现有约定传入 [纬度, 经度],缺失或异常时不打开空白地图。
|
||||
if (!Array.isArray(point) || point.length < 2) {
|
||||
this.$message.warning("没有设置点位,无法通过地图查看")
|
||||
return
|
||||
}
|
||||
const latitude = Number(point[0])
|
||||
const longitude = Number(point[1])
|
||||
if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
|
||||
this.$message.warning("地点坐标格式有误,无法通过地图查看")
|
||||
return
|
||||
}
|
||||
// 当前公共布局加载腾讯地图,脚本异常时给出提示,避免地图弹窗直接报错。
|
||||
if (typeof TMap === "undefined") {
|
||||
this.$message.error("地图加载失败,请刷新页面后重试")
|
||||
return
|
||||
}
|
||||
this.viewMapDialog = true
|
||||
this.$nextTick(() => {
|
||||
viewMap = new AMap.Map("viewMap", {
|
||||
resizeEnable: true,
|
||||
center: point,
|
||||
zoom: 16
|
||||
const center = new TMap.LatLng(latitude, longitude)
|
||||
this.viewMap = new TMap.Map("viewMap", {
|
||||
center: center,
|
||||
zoom: 16,
|
||||
})
|
||||
if (viewMarker) {
|
||||
viewMap.remove(viewMarker)
|
||||
}
|
||||
viewMarker = new AMap.Marker({
|
||||
position: point,
|
||||
offset: new AMap.Pixel(-13, -30)
|
||||
this.viewMarkerLayer = new TMap.MultiMarker({
|
||||
map: this.viewMap,
|
||||
geometries: [{
|
||||
id: "view-location",
|
||||
position: center,
|
||||
}],
|
||||
})
|
||||
viewMap.add(viewMarker)
|
||||
viewMap.setFitView(null, false, [150, 60, 100, 60])
|
||||
})
|
||||
},
|
||||
destroyViewMap() {
|
||||
// 弹窗关闭后释放地图覆盖物和实例,避免重复查看地点时残留旧地图资源。
|
||||
if (this.viewMarkerLayer && this.viewMarkerLayer.setMap) {
|
||||
this.viewMarkerLayer.setMap(null)
|
||||
}
|
||||
if (this.viewMap && this.viewMap.destroy) {
|
||||
this.viewMap.destroy()
|
||||
}
|
||||
this.viewMarkerLayer = null
|
||||
this.viewMap = null
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
/deep/ .el-button--text {
|
||||
|
||||
Reference in New Issue
Block a user