This commit is contained in:
2025-10-10 02:25:27 +08:00
parent 13cf9865dd
commit f302c9ea69
4 changed files with 931 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
import request from '@/utils/request'
// 解析线报消息
export function parseLineReport(data) {
return request({
url: '/jarvis/batchPublish/parse',
method: 'post',
data: data
})
}
// 批量发品
export function batchPublish(data) {
return request({
url: '/jarvis/batchPublish/publish',
method: 'post',
data: data
})
}
// 查询批量发品任务列表
export function listTasks(query) {
return request({
url: '/jarvis/batchPublish/task/list',
method: 'get',
params: query
})
}
// 查询批量发品任务详情
export function getTask(taskId) {
return request({
url: '/jarvis/batchPublish/task/' + taskId,
method: 'get'
})
}
// 查询批量发品明细列表
export function listItems(taskId) {
return request({
url: '/jarvis/batchPublish/item/list/' + taskId,
method: 'get'
})
}

View File

@@ -204,6 +204,22 @@ export const dynamicRoutes = [
}
]
},
// 批量发品
{
path: '/batchPublish',
component: Layout,
redirect: 'noredirect',
name: 'BatchPublish',
meta: { title: '批量发品', icon: 'shopping' },
children: [
{
path: 'index',
component: () => import('@/views/jarvis/batchPublish/index'),
name: 'BatchPublishIndex',
meta: { title: '批量发品', icon: 'upload' }
}
]
},
// 线报群管理
{
path: '/xbgroup',

View File

@@ -0,0 +1,756 @@
<template>
<div class="app-container">
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<span style="font-weight: bold; font-size: 16px;">📦 线报批量发品</span>
<el-button style="float: right; padding: 3px 10px" type="text" @click="showHistory">历史记录</el-button>
</div>
<!-- 步骤条 -->
<el-steps :active="activeStep" finish-status="success" align-center style="margin-bottom: 30px">
<el-step title="输入线报消息"></el-step>
<el-step title="选择商品"></el-step>
<el-step title="设置参数"></el-step>
<el-step title="批量发品"></el-step>
</el-steps>
<!-- 第一步输入线报消息 -->
<div v-show="activeStep === 0" class="step-content">
<el-form label-width="100px">
<el-form-item label="线报消息">
<el-input
type="textarea"
v-model="lineReportMessage"
:rows="12"
placeholder="请粘贴线报消息内容,支持多个商品链接..."
@input="onMessageInput"
/>
<div style="margin-top: 10px; color: #909399; font-size: 12px;">
<i class="el-icon-info"></i> 支持京东商品链接SKUID等多种格式系统会自动识别并提取商品信息
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="parsing" @click="parseMessage" :disabled="!lineReportMessage.trim()">
解析商品 <i class="el-icon-arrow-right"></i>
</el-button>
</el-form-item>
</el-form>
</div>
<!-- 第二步选择商品 -->
<div v-show="activeStep === 1" class="step-content">
<div style="margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center;">
<div>
<el-button type="primary" size="small" @click="selectAll">全选</el-button>
<el-button size="small" @click="selectNone">取消全选</el-button>
<el-tag type="info" size="small" style="margin-left: 10px;">
已选择: {{ selectedProducts.length }} / {{ parsedProducts.length }}
</el-tag>
</div>
<el-button type="success" @click="nextStep" :disabled="selectedProducts.length === 0">
下一步 <i class="el-icon-arrow-right"></i>
</el-button>
</div>
<el-table
:data="parsedProducts"
border
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column label="商品图片" width="100" align="center">
<template slot-scope="scope">
<el-image
v-if="scope.row.productImage"
:src="scope.row.productImage"
:preview-src-list="[scope.row.productImage]"
style="width: 60px; height: 60px; border-radius: 4px;"
fit="cover"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="商品信息" min-width="300">
<template slot-scope="scope">
<div style="font-weight: bold; margin-bottom: 5px;">{{ scope.row.productName }}</div>
<div style="color: #666; font-size: 12px;">
<div>SKUID: {{ scope.row.skuid }}</div>
<div v-if="scope.row.shopName">店铺: {{ scope.row.shopName }}</div>
</div>
</template>
</el-table-column>
<el-table-column label="价格" width="120" align="center">
<template slot-scope="scope">
<div style="color: #f56c6c; font-weight: bold; font-size: 16px;">¥{{ scope.row.price }}</div>
</template>
</el-table-column>
<el-table-column label="佣金" width="100" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.commissionInfo" type="success" size="small">
{{ scope.row.commissionInfo }}
</el-tag>
<span v-else>-</span>
</template>
</el-table-column>
</el-table>
<div style="margin-top: 15px;">
<el-button @click="prevStep">
<i class="el-icon-arrow-left"></i> 上一步
</el-button>
</div>
</div>
<!-- 第三步设置参数 -->
<div v-show="activeStep === 2" class="step-content">
<el-form :model="publishForm" :rules="publishRules" ref="publishForm" label-width="120px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="任务名称" prop="taskName">
<el-input v-model="publishForm.taskName" placeholder="请输入任务名称(选填)"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="延迟上架" prop="delaySeconds">
<el-input-number v-model="publishForm.delaySeconds" :min="1" :max="60" placeholder="秒"/>
<span style="margin-left: 10px; color: #909399;">发品成功后延迟上架</span>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="目标账号" prop="targetAccounts" required>
<el-select v-model="publishForm.targetAccounts" multiple placeholder="请选择目标ERP账号" style="width: 100%;">
<el-option
v-for="account in erpAccounts"
:key="account.value"
:label="account.label"
:value="account.value"
/>
</el-select>
<div style="margin-top: 5px; color: #909399; font-size: 12px;">
<i class="el-icon-info"></i> 支持选择多个账号每个商品将发送到所有选中的账号
</div>
</el-form-item>
<el-divider content-position="left">通用参数</el-divider>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="会员名" prop="userName" required>
<el-input v-model="publishForm.userName" placeholder="请输入会员名"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="商品类型" prop="itemBizType" required>
<el-select v-model="publishForm.itemBizType" placeholder="请选择" style="width: 100%;">
<el-option label="普通商品" :value="2"/>
<el-option label="已验货" :value="0"/>
<el-option label="验货宝" :value="10"/>
<el-option label="闲鱼优品" :value="19"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="行业类型" prop="spBizType" required>
<el-select v-model="publishForm.spBizType" placeholder="请选择" style="width: 100%;">
<el-option label="手机" :value="1"/>
<el-option label="时尚" :value="2"/>
<el-option label="家电" :value="3"/>
<el-option label="数码3C" :value="9"/>
<el-option label="母婴" :value="17"/>
<el-option label="美妆" :value="18"/>
<el-option label="家居" :value="21"/>
<el-option label="其他" :value="99"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="类目ID" prop="channelCatId" required>
<el-input v-model="publishForm.channelCatId" placeholder="请输入类目ID"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="省" prop="province" required>
<el-input-number v-model="publishForm.province" placeholder="省代码" style="width: 100%;"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="市" prop="city" required>
<el-input-number v-model="publishForm.city" placeholder="市代码" style="width: 100%;"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="区" prop="district" required>
<el-input-number v-model="publishForm.district" placeholder="区代码" style="width: 100%;"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="邮费" prop="expressFee" required>
<el-input-number v-model="publishForm.expressFee" :min="0" :precision="2" placeholder="元" style="width: 100%;"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="库存" prop="stock" required>
<el-input-number v-model="publishForm.stock" :min="1" placeholder="库存数量" style="width: 100%;"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="成色" prop="stuffStatus">
<el-select v-model="publishForm.stuffStatus" placeholder="请选择" clearable style="width: 100%;">
<el-option label="全新" :value="100"/>
<el-option label="99新" :value="99"/>
<el-option label="95新" :value="95"/>
<el-option label="9成新" :value="90"/>
<el-option label="8成新" :value="80"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="服务支持" prop="serviceSupport">
<el-select v-model="publishForm.serviceSupport" multiple placeholder="请选择服务支持" style="width: 100%;">
<el-option label="七天无理由退货" value="SDR"/>
<el-option label="描述不符包邮退" value="NFR"/>
<el-option label="24小时极速发货" value="FD_24HS"/>
<el-option label="48小时极速发货" value="FD_48HS"/>
<el-option label="正品保障" value="FD_GPA"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="prevStep">
<i class="el-icon-arrow-left"></i> 上一步
</el-button>
<el-button type="success" @click="submitPublish" :loading="publishing">
开始批量发品 <i class="el-icon-upload"></i>
</el-button>
</el-form-item>
</el-form>
</div>
<!-- 第四步发品进度 -->
<div v-show="activeStep === 3" class="step-content">
<el-alert
v-if="publishResult.taskId"
title="批量发品任务已创建"
type="success"
:description="`任务ID: ${publishResult.taskId}`"
show-icon
:closable="false"
style="margin-bottom: 20px;"
/>
<el-progress
:percentage="publishProgress"
:status="publishProgress === 100 ? 'success' : null"
style="margin-bottom: 20px;"
/>
<el-table :data="publishItems" border style="width: 100%" v-if="publishItems.length > 0">
<el-table-column label="商品" prop="productName" min-width="200"/>
<el-table-column label="账号" prop="accountRemark" width="120"/>
<el-table-column label="状态" width="120" align="center">
<template slot-scope="scope">
<el-tag :type="getStatusType(scope.row.status)" size="small">
{{ getStatusText(scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="商品ID" prop="productId" width="150"/>
<el-table-column label="错误信息" prop="errorMessage" min-width="200" :show-overflow-tooltip="true"/>
</el-table>
<div style="margin-top: 20px; text-align: center;">
<el-button type="primary" @click="reset">创建新任务</el-button>
<el-button @click="showHistory">查看历史记录</el-button>
</div>
</div>
</el-card>
<!-- 历史记录对话框 -->
<el-dialog title="批量发品历史记录" :visible.sync="historyVisible" width="80%" append-to-body>
<el-table :data="historyList" border style="width: 100%">
<el-table-column label="任务ID" prop="id" width="80"/>
<el-table-column label="任务名称" prop="taskName" min-width="150"/>
<el-table-column label="商品数" prop="selectedProducts" width="80" align="center"/>
<el-table-column label="目标账号数" width="100" align="center">
<template slot-scope="scope">
{{ parseTargetAccounts(scope.row.targetAccounts).length }}
</template>
</el-table-column>
<el-table-column label="状态" width="100" align="center">
<template slot-scope="scope">
<el-tag :type="getTaskStatusType(scope.row.status)">
{{ getTaskStatusText(scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="成功/失败" width="100" align="center">
<template slot-scope="scope">
<span style="color: #67c23a;">{{ scope.row.successCount }}</span> /
<span style="color: #f56c6c;">{{ scope.row.failCount }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="createTime" width="160"/>
<el-table-column label="操作" width="100" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" @click="viewTaskDetail(scope.row)">查看详情</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="historyTotal>0"
:total="historyTotal"
:page.sync="historyQuery.pageNum"
:limit.sync="historyQuery.pageSize"
@pagination="loadHistory"
/>
</el-dialog>
<!-- 任务详情对话框 -->
<el-dialog title="任务详情" :visible.sync="detailVisible" width="80%" append-to-body>
<el-descriptions v-if="currentTask" :column="3" border>
<el-descriptions-item label="任务ID">{{ currentTask.id }}</el-descriptions-item>
<el-descriptions-item label="任务名称">{{ currentTask.taskName }}</el-descriptions-item>
<el-descriptions-item label="状态">
<el-tag :type="getTaskStatusType(currentTask.status)">
{{ getTaskStatusText(currentTask.status) }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="商品数">{{ currentTask.selectedProducts }}</el-descriptions-item>
<el-descriptions-item label="成功数">{{ currentTask.successCount }}</el-descriptions-item>
<el-descriptions-item label="失败数">{{ currentTask.failCount }}</el-descriptions-item>
<el-descriptions-item label="创建人">{{ currentTask.createUserName }}</el-descriptions-item>
<el-descriptions-item label="创建时间" :span="2">{{ currentTask.createTime }}</el-descriptions-item>
</el-descriptions>
<el-divider>发品明细</el-divider>
<el-table :data="taskItems" border style="width: 100%">
<el-table-column label="商品" prop="productName" min-width="200"/>
<el-table-column label="SKUID" prop="skuid" width="120"/>
<el-table-column label="账号" prop="accountRemark" width="120"/>
<el-table-column label="状态" width="120" align="center">
<template slot-scope="scope">
<el-tag :type="getStatusType(scope.row.status)" size="small">
{{ getStatusText(scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="商品ID" prop="productId" width="150"/>
<el-table-column label="价格" width="100" align="center">
<template slot-scope="scope">
<span v-if="scope.row.publishPrice">¥{{ (scope.row.publishPrice / 100).toFixed(2) }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="错误信息" prop="errorMessage" min-width="200" :show-overflow-tooltip="true"/>
</el-table>
</el-dialog>
</div>
</template>
<script>
import { parseLineReport, batchPublish, listTasks, getTask, listItems } from "@/api/jarvis/batchPublish";
import { getERPAccounts } from "@/api/system/jdorder";
import Pagination from "@/components/Pagination";
export default {
name: "BatchPublish",
components: { Pagination },
data() {
return {
// 步骤
activeStep: 0,
// 输入
lineReportMessage: "",
parsing: false,
// 商品列表
parsedProducts: [],
selectedProducts: [],
// 发品表单
publishForm: {
taskName: "",
targetAccounts: [],
delaySeconds: 3,
userName: "",
province: null,
city: null,
district: null,
itemBizType: 2,
spBizType: 3,
channelCatId: "",
expressFee: 0,
stock: 1,
stuffStatus: 100,
serviceSupport: [],
channelPv: ""
},
publishRules: {
targetAccounts: [{ required: true, message: "请选择目标账号", trigger: "change" }],
userName: [{ required: true, message: "请输入会员名", trigger: "blur" }],
province: [{ required: true, message: "请输入省代码", trigger: "blur" }],
city: [{ required: true, message: "请输入市代码", trigger: "blur" }],
district: [{ required: true, message: "请输入区代码", trigger: "blur" }],
itemBizType: [{ required: true, message: "请选择商品类型", trigger: "change" }],
spBizType: [{ required: true, message: "请选择行业类型", trigger: "change" }],
channelCatId: [{ required: true, message: "请输入类目ID", trigger: "blur" }],
expressFee: [{ required: true, message: "请输入邮费", trigger: "blur" }],
stock: [{ required: true, message: "请输入库存", trigger: "blur" }]
},
publishing: false,
// ERP账号
erpAccounts: [],
// 发品结果
publishResult: {
taskId: null
},
publishProgress: 0,
publishItems: [],
refreshTimer: null,
// 历史记录
historyVisible: false,
historyList: [],
historyTotal: 0,
historyQuery: {
pageNum: 1,
pageSize: 10
},
// 任务详情
detailVisible: false,
currentTask: null,
taskItems: []
};
},
created() {
this.loadERPAccounts();
},
beforeDestroy() {
if (this.refreshTimer) {
clearInterval(this.refreshTimer);
}
},
methods: {
// 加载ERP账号
async loadERPAccounts() {
try {
const res = await getERPAccounts();
if (res.code === 200) {
this.erpAccounts = res.data || [];
}
} catch (error) {
console.error("加载ERP账号失败", error);
}
},
// 输入变化
onMessageInput() {
// 可以添加实时提示
},
// 解析消息
async parseMessage() {
if (!this.lineReportMessage.trim()) {
this.$modal.msgWarning("请输入线报消息");
return;
}
this.parsing = true;
try {
const res = await parseLineReport({ message: this.lineReportMessage });
if (res.code === 200) {
this.parsedProducts = res.data || [];
if (this.parsedProducts.length === 0) {
this.$modal.msgWarning("未能识别到商品信息,请检查消息内容");
} else {
this.$modal.msgSuccess(`成功解析 ${this.parsedProducts.length} 个商品`);
this.activeStep = 1;
}
} else {
this.$modal.msgError(res.msg || "解析失败");
}
} catch (error) {
console.error("解析失败", error);
this.$modal.msgError("解析失败,请稍后重试");
} finally {
this.parsing = false;
}
},
// 选择变化
handleSelectionChange(selection) {
this.selectedProducts = selection;
},
// 全选
selectAll() {
this.$refs.productTable && this.$refs.productTable.toggleAllSelection();
},
// 取消全选
selectNone() {
this.$refs.productTable && this.$refs.productTable.clearSelection();
},
// 下一步
nextStep() {
if (this.activeStep === 1 && this.selectedProducts.length === 0) {
this.$modal.msgWarning("请至少选择一个商品");
return;
}
this.activeStep++;
},
// 上一步
prevStep() {
this.activeStep--;
},
// 提交发品
submitPublish() {
this.$refs.publishForm.validate(async (valid) => {
if (!valid) {
return;
}
if (this.publishForm.targetAccounts.length === 0) {
this.$modal.msgWarning("请至少选择一个目标账号");
return;
}
this.publishing = true;
try {
const request = {
taskName: this.publishForm.taskName || `批量发品-${new Date().toLocaleString()}`,
originalMessage: this.lineReportMessage,
products: this.selectedProducts.map(p => ({
skuid: p.skuid,
productName: p.productName,
price: p.price,
productImage: p.productImage,
shopName: p.shopName,
shopId: p.shopId,
commissionInfo: p.commissionInfo
})),
targetAccounts: this.publishForm.targetAccounts,
delaySeconds: this.publishForm.delaySeconds,
commonParams: {
userName: this.publishForm.userName,
province: this.publishForm.province,
city: this.publishForm.city,
district: this.publishForm.district,
itemBizType: this.publishForm.itemBizType,
spBizType: this.publishForm.spBizType,
channelCatId: this.publishForm.channelCatId,
expressFee: this.publishForm.expressFee,
stock: this.publishForm.stock,
stuffStatus: this.publishForm.stuffStatus,
serviceSupport: this.publishForm.serviceSupport.join(","),
channelPv: this.publishForm.channelPv
}
};
const res = await batchPublish(request);
if (res.code === 200) {
this.publishResult.taskId = res.data;
this.$modal.msgSuccess("批量发品任务已创建");
this.activeStep = 3;
this.startRefreshProgress();
} else {
this.$modal.msgError(res.msg || "提交失败");
}
} catch (error) {
console.error("提交失败", error);
this.$modal.msgError("提交失败,请稍后重试");
} finally {
this.publishing = false;
}
});
},
// 开始刷新进度
startRefreshProgress() {
this.refreshProgress();
this.refreshTimer = setInterval(() => {
this.refreshProgress();
}, 2000);
},
// 刷新进度
async refreshProgress() {
if (!this.publishResult.taskId) {
return;
}
try {
const res = await listItems(this.publishResult.taskId);
if (res.code === 200) {
this.publishItems = res.data || [];
// 计算进度
const total = this.publishItems.length;
const finished = this.publishItems.filter(item => item.status >= 2).length;
this.publishProgress = total > 0 ? Math.round((finished / total) * 100) : 0;
// 如果全部完成,停止刷新
if (finished === total) {
if (this.refreshTimer) {
clearInterval(this.refreshTimer);
this.refreshTimer = null;
}
}
}
} catch (error) {
console.error("刷新进度失败", error);
}
},
// 重置
reset() {
this.activeStep = 0;
this.lineReportMessage = "";
this.parsedProducts = [];
this.selectedProducts = [];
this.publishResult = { taskId: null };
this.publishProgress = 0;
this.publishItems = [];
if (this.refreshTimer) {
clearInterval(this.refreshTimer);
this.refreshTimer = null;
}
},
// 显示历史记录
async showHistory() {
this.historyVisible = true;
await this.loadHistory();
},
// 加载历史记录
async loadHistory() {
try {
const res = await listTasks(this.historyQuery);
if (res.code === 200) {
this.historyList = res.rows || [];
this.historyTotal = res.total || 0;
}
} catch (error) {
console.error("加载历史记录失败", error);
}
},
// 查看任务详情
async viewTaskDetail(task) {
try {
const res1 = await getTask(task.id);
if (res1.code === 200) {
this.currentTask = res1.data;
}
const res2 = await listItems(task.id);
if (res2.code === 200) {
this.taskItems = res2.data || [];
}
this.detailVisible = true;
} catch (error) {
console.error("加载任务详情失败", error);
this.$modal.msgError("加载任务详情失败");
}
},
// 解析目标账号
parseTargetAccounts(jsonStr) {
try {
return JSON.parse(jsonStr) || [];
} catch {
return [];
}
},
// 状态相关
getStatusType(status) {
const map = {
0: "info",
1: "warning",
2: "success",
3: "danger",
4: "warning",
5: "success",
6: "danger"
};
return map[status] || "info";
},
getStatusText(status) {
const map = {
0: "待发布",
1: "发布中",
2: "发布成功",
3: "发布失败",
4: "上架中",
5: "已上架",
6: "上架失败"
};
return map[status] || "未知";
},
getTaskStatusType(status) {
const map = {
0: "info",
1: "warning",
2: "success",
3: "danger"
};
return map[status] || "info";
},
getTaskStatusText(status) {
const map = {
0: "待处理",
1: "处理中",
2: "已完成",
3: "失败"
};
return map[status] || "未知";
}
}
};
</script>
<style scoped>
.step-content {
min-height: 400px;
padding: 20px 0;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both;
}
</style>

View File

@@ -156,6 +156,10 @@ export default {
if (Array.isArray(data)) this.resultList = data
else if (typeof data === 'string') this.resultList = data ? [data] : []
else this.resultList = []
// 检查是否有以[炸弹]开头的消息
this.checkBombAlert(this.resultList)
// 执行成功后刷新历史记录
this.loadHistory()
} else {
@@ -251,6 +255,9 @@ export default {
this.$message.success('已查询到今天的慢单数据')
}
// 检查是否有以[炸弹]开头的消息
this.checkBombAlert(this.resultList)
// 执行成功后刷新历史记录
this.loadHistory()
} else {
@@ -266,6 +273,39 @@ export default {
clearAll() {
this.form.command = ''
this.resultList = []
},
checkBombAlert(resultList) {
if (!resultList || resultList.length === 0) return
// 检查是否有以[炸弹]开头的消息
const bombMessages = resultList
.filter(msg => {
return msg && typeof msg === 'string' && msg.trim().startsWith('[炸弹]')
})
.map(msg => {
// 移除所有的[炸弹]标记
return msg.trim().replace(/\[炸弹\]\s*/g, '').trim()
})
if (bombMessages.length > 0) {
// 显示全屏警告弹窗
this.$alert(bombMessages.join('\n\n'), '⚠️ 警告提示', {
confirmButtonText: '我已知晓',
type: 'warning',
center: true,
customClass: 'bomb-alert-dialog',
showClose: false,
closeOnClickModal: false,
closeOnPressEscape: false,
dangerouslyUseHTMLString: false
}).catch(() => {})
}
},
copyHistoryItem(item) {
const message = this.extractMessage(item)
if (message) {
this.doCopy(message)
}
}
}
}
@@ -363,6 +403,80 @@ export default {
.history-content::-webkit-scrollbar-thumb:hover {
background: #C0C4CC;
}
.history-item-header {
display: flex;
justify-content: space-between;
align-items: center;
}
/* 炸弹警告弹窗样式 */
::v-deep .bomb-alert-dialog {
width: 80% !important;
max-width: 1920px !important;
}
::v-deep .bomb-alert-dialog .el-message-box__message {
font-size: 16px !important;
font-weight: 600 !important;
color: #E6A23C !important;
white-space: pre-wrap !important;
word-break: break-word !important;
line-height: 1.8 !important;
max-height: 60vh !important;
overflow-y: auto !important;
}
::v-deep .bomb-alert-dialog .el-message-box__btns {
text-align: center !important;
}
::v-deep .bomb-alert-dialog .el-message-box__btns .el-button {
padding: 12px 40px !important;
font-size: 16px !important;
font-weight: 600 !important;
}
</style>
<style>
/* 全局样式炸弹警告弹窗不使用scoped因为弹窗挂载在body下 */
.bomb-alert-dialog {
width: 80vw !important;
max-width: 1920px !important;
min-width: 500px !important;
}
.bomb-alert-dialog .el-message-box__header {
padding: 20px 20px 15px !important;
}
.bomb-alert-dialog .el-message-box__title {
font-size: 20px !important;
font-weight: 700 !important;
}
.bomb-alert-dialog .el-message-box__message {
font-size: 16px !important;
font-weight: 600 !important;
color: #E6A23C !important;
white-space: pre-wrap !important;
word-break: break-word !important;
line-height: 1.8 !important;
max-height: 60vh !important;
overflow-y: auto !important;
padding: 15px 20px !important;
}
.bomb-alert-dialog .el-message-box__btns {
text-align: center !important;
padding: 15px 20px 20px !important;
}
.bomb-alert-dialog .el-message-box__btns .el-button {
padding: 12px 40px !important;
font-size: 16px !important;
font-weight: 600 !important;
}
</style>