733 行
35 KiB
HTML
733 行
35 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>系统消息管理</title>
|
||
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
|
||
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
|
||
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
||
<style>
|
||
.page-container {
|
||
padding: 20px;
|
||
background-color: #f5f5f5;
|
||
min-height: 100vh;
|
||
}
|
||
.stats-cards {
|
||
display: flex;
|
||
gap: 20px;
|
||
margin-bottom: 20px;
|
||
}
|
||
.stats-card {
|
||
flex: 1;
|
||
background: white;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
}
|
||
.stats-number {
|
||
font-size: 24px;
|
||
font-weight: bold;
|
||
color: #409EFF;
|
||
}
|
||
.stats-label {
|
||
color: #666;
|
||
margin-top: 5px;
|
||
}
|
||
.search-form {
|
||
background: white;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
margin-bottom: 20px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
}
|
||
.table-container {
|
||
background: white;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
}
|
||
.message-content {
|
||
max-width: 200px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.priority-tag {
|
||
font-size: 12px;
|
||
}
|
||
.rider-selector {
|
||
max-height: 200px;
|
||
overflow-y: auto;
|
||
border: 1px solid #ddd;
|
||
padding: 10px;
|
||
border-radius: 4px;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="app" class="page-container">
|
||
<div class="stats-cards">
|
||
<div class="stats-card">
|
||
<div class="stats-number">{{ stats.total_messages || 0 }}</div>
|
||
<div class="stats-label">消息总数</div>
|
||
</div>
|
||
<div class="stats-card">
|
||
<div class="stats-number">{{ stats.sent_messages || 0 }}</div>
|
||
<div class="stats-label">已发送消息</div>
|
||
</div>
|
||
<div class="stats-card">
|
||
<div class="stats-number">{{ stats.read_messages || 0 }}</div>
|
||
<div class="stats-label">已读消息</div>
|
||
</div>
|
||
<div class="stats-card">
|
||
<div class="stats-number">{{ stats.read_rate || 0 }}%</div>
|
||
<div class="stats-label">阅读率</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="search-form">
|
||
<el-form :inline="true" :model="searchForm" class="search-form">
|
||
<el-form-item label="关键词">
|
||
<el-input v-model="searchForm.keyword" placeholder="消息标题/内容" clearable style="width: 200px;"></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="消息类型">
|
||
<el-select v-model="searchForm.message_type" placeholder="请选择" clearable style="width: 120px;">
|
||
<el-option label="全部" value=""></el-option>
|
||
<el-option label="系统公告" value="system"></el-option>
|
||
<el-option label="政策变更" value="policy"></el-option>
|
||
<el-option label="活动通知" value="activity"></el-option>
|
||
<el-option label="紧急通知" value="urgent"></el-option>
|
||
<el-option label="其他" value="other"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="发送状态">
|
||
<el-select v-model="searchForm.send_status" placeholder="请选择" clearable style="width: 120px;">
|
||
<el-option label="全部" value=""></el-option>
|
||
<el-option label="草稿" value="draft"></el-option>
|
||
<el-option label="已发送" value="sent"></el-option>
|
||
<el-option label="定时发送" value="scheduled"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="优先级">
|
||
<el-select v-model="searchForm.priority" placeholder="请选择" clearable style="width: 100px;">
|
||
<el-option label="全部" value=""></el-option>
|
||
<el-option label="高" value="high"></el-option>
|
||
<el-option label="中" value="medium"></el-option>
|
||
<el-option label="低" value="low"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="发送时间">
|
||
<el-date-picker
|
||
v-model="searchForm.send_time_range"
|
||
type="daterange"
|
||
range-separator="至"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
format="yyyy-MM-dd"
|
||
value-format="yyyy-MM-dd"
|
||
style="width: 240px;">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" @click="loadData">查询</el-button>
|
||
<el-button @click="resetSearch">重置</el-button>
|
||
<el-button type="success" @click="addMessage">新增消息</el-button>
|
||
<el-button type="info" @click="exportData">导出数据</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
|
||
<div class="table-container">
|
||
<el-table :data="tableData" v-loading="loading" style="width: 100%">
|
||
<el-table-column type="selection" width="55"></el-table-column>
|
||
<el-table-column prop="title" label="消息标题" width="200" show-overflow-tooltip></el-table-column>
|
||
<el-table-column prop="message_type" label="消息类型" width="100">
|
||
<template slot-scope="scope">
|
||
{{ getMessageTypeText(scope.row.message_type) }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="content" label="消息内容" width="250">
|
||
<template slot-scope="scope">
|
||
<div class="message-content" :title="scope.row.content">
|
||
{{ scope.row.content }}
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="priority" label="优先级" width="80">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="getPriorityColor(scope.row.priority)" class="priority-tag">
|
||
{{ getPriorityText(scope.row.priority) }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="target_type" label="发送对象" width="100">
|
||
<template slot-scope="scope">
|
||
{{ getTargetTypeText(scope.row.target_type) }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="send_count" label="发送数量" width="100">
|
||
<template slot-scope="scope">
|
||
<span style="color: #409EFF;">{{ scope.row.send_count }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="read_count" label="已读数量" width="100">
|
||
<template slot-scope="scope">
|
||
<span style="color: #67C23A;">{{ scope.row.read_count }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="send_status" label="发送状态" width="100">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="getStatusColor(scope.row.send_status)" size="small">
|
||
{{ getStatusText(scope.row.send_status) }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="send_time" label="发送时间" width="180">
|
||
<template slot-scope="scope">
|
||
{{ formatDateTime(scope.row.send_time) }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="250" fixed="right">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewDetail(scope.row)">详情</el-button>
|
||
<el-button v-if="scope.row.send_status === 'draft'" size="mini" type="primary" @click="editMessage(scope.row)">编辑</el-button>
|
||
<el-button v-if="scope.row.send_status === 'draft'" size="mini" type="success" @click="sendMessage(scope.row)">发送</el-button>
|
||
<el-button size="mini" type="info" @click="viewReadStatus(scope.row)">阅读状态</el-button>
|
||
<el-button size="mini" type="danger" @click="deleteMessage(scope.row)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div style="padding: 20px;">
|
||
<div style="margin-bottom: 10px;">
|
||
<el-button size="small" type="primary" @click="batchSend" :disabled="selectedMessages.length === 0">批量发送</el-button>
|
||
<el-button size="small" type="danger" @click="batchDelete" :disabled="selectedMessages.length === 0">批量删除</el-button>
|
||
</div>
|
||
<el-pagination
|
||
@size-change="handleSizeChange"
|
||
@current-change="handleCurrentChange"
|
||
@selection-change="handleSelectionChange"
|
||
:current-page="pagination.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="pagination.pageSize"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="pagination.total">
|
||
</el-pagination>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 消息详情对话框 -->
|
||
<el-dialog title="消息详情" :visible.sync="detailDialogVisible" width="700px">
|
||
<div v-if="currentMessage">
|
||
<el-descriptions :column="2" border>
|
||
<el-descriptions-item label="消息标题">{{ currentMessage.title }}</el-descriptions-item>
|
||
<el-descriptions-item label="消息类型">{{ getMessageTypeText(currentMessage.message_type) }}</el-descriptions-item>
|
||
<el-descriptions-item label="优先级">
|
||
<el-tag :type="getPriorityColor(currentMessage.priority)">
|
||
{{ getPriorityText(currentMessage.priority) }}
|
||
</el-tag>
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="发送对象">{{ getTargetTypeText(currentMessage.target_type) }}</el-descriptions-item>
|
||
<el-descriptions-item label="发送数量">{{ currentMessage.send_count }}</el-descriptions-item>
|
||
<el-descriptions-item label="已读数量">{{ currentMessage.read_count }}</el-descriptions-item>
|
||
<el-descriptions-item label="发送状态">
|
||
<el-tag :type="getStatusColor(currentMessage.send_status)">
|
||
{{ getStatusText(currentMessage.send_status) }}
|
||
</el-tag>
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="发送时间">{{ formatDateTime(currentMessage.send_time) }}</el-descriptions-item>
|
||
</el-descriptions>
|
||
|
||
<h4 style="margin-top: 20px;">消息内容</h4>
|
||
<div style="padding: 15px; background: #f9f9f9; border-radius: 4px; white-space: pre-wrap;">
|
||
{{ currentMessage.content }}
|
||
</div>
|
||
|
||
<div v-if="currentMessage.attachment_url" style="margin-top: 20px;">
|
||
<h4>附件</h4>
|
||
<el-link :href="currentMessage.attachment_url" target="_blank">{{ currentMessage.attachment_name }}</el-link>
|
||
</div>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 新增/编辑消息对话框 -->
|
||
<el-dialog :title="messageForm.id ? '编辑消息' : '新增消息'" :visible.sync="messageDialogVisible" width="800px">
|
||
<el-form :model="messageForm" :rules="messageRules" ref="messageForm" label-width="120px">
|
||
<el-form-item label="消息标题" prop="title">
|
||
<el-input v-model="messageForm.title" placeholder="请输入消息标题"></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="消息类型" prop="message_type">
|
||
<el-select v-model="messageForm.message_type" placeholder="请选择消息类型" style="width: 200px;">
|
||
<el-option label="系统公告" value="system"></el-option>
|
||
<el-option label="政策变更" value="policy"></el-option>
|
||
<el-option label="活动通知" value="activity"></el-option>
|
||
<el-option label="紧急通知" value="urgent"></el-option>
|
||
<el-option label="其他" value="other"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="优先级" prop="priority">
|
||
<el-radio-group v-model="messageForm.priority">
|
||
<el-radio label="high">高</el-radio>
|
||
<el-radio label="medium">中</el-radio>
|
||
<el-radio label="low">低</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item label="发送对象" prop="target_type">
|
||
<el-radio-group v-model="messageForm.target_type" @change="handleTargetTypeChange">
|
||
<el-radio label="all">全部骑手</el-radio>
|
||
<el-radio label="active">活跃骑手</el-radio>
|
||
<el-radio label="area">指定区域</el-radio>
|
||
<el-radio label="custom">指定骑手</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item v-if="messageForm.target_type === 'area'" label="选择区域">
|
||
<el-select v-model="messageForm.target_areas" multiple placeholder="请选择区域" style="width: 100%;">
|
||
<el-option
|
||
v-for="area in areaList"
|
||
:key="area.id"
|
||
:label="area.name"
|
||
:value="area.id">
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item v-if="messageForm.target_type === 'custom'" label="选择骑手">
|
||
<div class="rider-selector">
|
||
<el-checkbox-group v-model="messageForm.target_riders">
|
||
<el-checkbox
|
||
v-for="rider in riderList"
|
||
:key="rider.id"
|
||
:label="rider.id"
|
||
style="display: block; margin-bottom: 5px;">
|
||
{{ rider.name }} ({{ rider.phone }})
|
||
</el-checkbox>
|
||
</el-checkbox-group>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="消息内容" prop="content">
|
||
<el-input type="textarea" v-model="messageForm.content" placeholder="请输入消息内容" :rows="5"></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="发送方式">
|
||
<el-radio-group v-model="messageForm.send_type">
|
||
<el-radio label="immediate">立即发送</el-radio>
|
||
<el-radio label="scheduled">定时发送</el-radio>
|
||
<el-radio label="draft">保存草稿</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item v-if="messageForm.send_type === 'scheduled'" label="发送时间">
|
||
<el-date-picker
|
||
v-model="messageForm.scheduled_time"
|
||
type="datetime"
|
||
placeholder="选择发送时间"
|
||
format="yyyy-MM-dd HH:mm:ss"
|
||
value-format="yyyy-MM-dd HH:mm:ss"
|
||
style="width: 200px;">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
<el-form-item label="附件">
|
||
<el-upload
|
||
class="upload-demo"
|
||
action="/upload"
|
||
:on-success="handleUploadSuccess"
|
||
:file-list="fileList">
|
||
<el-button size="small" type="primary">点击上传</el-button>
|
||
<div slot="tip" class="el-upload__tip">只能上传jpg/png/pdf文件,且不超过2MB</div>
|
||
</el-upload>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button @click="messageDialogVisible = false">取消</el-button>
|
||
<el-button type="primary" @click="saveMessage">保存</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 阅读状态对话框 -->
|
||
<el-dialog title="阅读状态" :visible.sync="readStatusDialogVisible" width="800px">
|
||
<div v-if="currentMessage">
|
||
<div style="margin-bottom: 20px;">
|
||
<el-statistic title="发送总数" :value="currentMessage.send_count" suffix="人"></el-statistic>
|
||
<el-statistic title="已读数量" :value="currentMessage.read_count" suffix="人" style="margin-left: 50px;"></el-statistic>
|
||
<el-statistic title="阅读率" :value="((currentMessage.read_count / currentMessage.send_count) * 100).toFixed(1)" suffix="%" style="margin-left: 50px;"></el-statistic>
|
||
</div>
|
||
|
||
<el-table :data="readStatusList" style="width: 100%">
|
||
<el-table-column prop="rider_name" label="骑手姓名" width="120"></el-table-column>
|
||
<el-table-column prop="rider_phone" label="手机号" width="140"></el-table-column>
|
||
<el-table-column prop="is_read" label="阅读状态" width="100">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.is_read ? 'success' : 'info'" size="small">
|
||
{{ scope.row.is_read ? '已读' : '未读' }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="read_time" label="阅读时间" width="180">
|
||
<template slot-scope="scope">
|
||
{{ scope.row.read_time ? formatDateTime(scope.row.read_time) : '-' }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="send_time" label="发送时间" width="180">
|
||
<template slot-scope="scope">
|
||
{{ formatDateTime(scope.row.send_time) }}
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
|
||
<script>
|
||
new Vue({
|
||
el: '#app',
|
||
data() {
|
||
return {
|
||
loading: false,
|
||
tableData: [],
|
||
stats: {},
|
||
selectedMessages: [],
|
||
areaList: [],
|
||
riderList: [],
|
||
readStatusList: [],
|
||
searchForm: {
|
||
keyword: '',
|
||
message_type: '',
|
||
send_status: '',
|
||
priority: '',
|
||
send_time_range: []
|
||
},
|
||
pagination: {
|
||
page: 1,
|
||
pageSize: 20,
|
||
total: 0
|
||
},
|
||
detailDialogVisible: false,
|
||
messageDialogVisible: false,
|
||
readStatusDialogVisible: false,
|
||
currentMessage: null,
|
||
messageForm: {
|
||
id: null,
|
||
title: '',
|
||
message_type: '',
|
||
priority: 'medium',
|
||
target_type: 'all',
|
||
target_areas: [],
|
||
target_riders: [],
|
||
content: '',
|
||
send_type: 'immediate',
|
||
scheduled_time: '',
|
||
attachment_url: '',
|
||
attachment_name: ''
|
||
},
|
||
messageRules: {
|
||
title: [
|
||
{ required: true, message: '请输入消息标题', trigger: 'blur' }
|
||
],
|
||
message_type: [
|
||
{ required: true, message: '请选择消息类型', trigger: 'change' }
|
||
],
|
||
content: [
|
||
{ required: true, message: '请输入消息内容', trigger: 'blur' }
|
||
]
|
||
},
|
||
fileList: []
|
||
}
|
||
},
|
||
mounted() {
|
||
this.loadData();
|
||
this.loadStats();
|
||
this.loadAreaList();
|
||
this.loadRiderList();
|
||
},
|
||
methods: {
|
||
loadData() {
|
||
this.loading = true;
|
||
const params = {
|
||
page: this.pagination.page,
|
||
pageSize: this.pagination.pageSize,
|
||
...this.searchForm
|
||
};
|
||
|
||
// 模拟API调用
|
||
setTimeout(() => {
|
||
this.tableData = [
|
||
{
|
||
id: 1,
|
||
title: '春节配送安排通知',
|
||
message_type: 'system',
|
||
content: '各位骑手,春节期间配送安排如下:1月22日-1月28日正常配送,配送费上调20%...',
|
||
priority: 'high',
|
||
target_type: 'all',
|
||
send_count: 156,
|
||
read_count: 142,
|
||
send_status: 'sent',
|
||
send_time: '2024-01-20 10:00:00',
|
||
attachment_url: '',
|
||
attachment_name: ''
|
||
},
|
||
{
|
||
id: 2,
|
||
title: '新版APP功能介绍',
|
||
message_type: 'activity',
|
||
content: '新版骑手APP已上线,新增功能包括:实时导航优化、订单智能分配、收入统计等...',
|
||
priority: 'medium',
|
||
target_type: 'active',
|
||
send_count: 89,
|
||
read_count: 76,
|
||
send_status: 'sent',
|
||
send_time: '2024-01-18 14:30:00',
|
||
attachment_url: '/uploads/app_guide.pdf',
|
||
attachment_name: 'APP使用指南.pdf'
|
||
},
|
||
{
|
||
id: 3,
|
||
title: '雨天配送安全提醒',
|
||
message_type: 'urgent',
|
||
content: '近期雨水较多,请各位骑手注意配送安全,雨天配送注意事项...',
|
||
priority: 'high',
|
||
target_type: 'all',
|
||
send_count: 0,
|
||
read_count: 0,
|
||
send_status: 'draft',
|
||
send_time: null,
|
||
attachment_url: '',
|
||
attachment_name: ''
|
||
}
|
||
];
|
||
this.pagination.total = 3;
|
||
this.loading = false;
|
||
}, 500);
|
||
},
|
||
loadStats() {
|
||
// 模拟统计数据
|
||
this.stats = {
|
||
total_messages: 25,
|
||
sent_messages: 22,
|
||
read_messages: 18,
|
||
read_rate: 81.8
|
||
};
|
||
},
|
||
loadAreaList() {
|
||
// 模拟区域列表
|
||
this.areaList = [
|
||
{ id: 1, name: '万达商圈' },
|
||
{ id: 2, name: '清华大学' },
|
||
{ id: 3, name: '中关村' }
|
||
];
|
||
},
|
||
loadRiderList() {
|
||
// 模拟骑手列表
|
||
this.riderList = [
|
||
{ id: 1, name: '张三', phone: '13800138001' },
|
||
{ id: 2, name: '李四', phone: '13800138002' },
|
||
{ id: 3, name: '王五', phone: '13800138003' }
|
||
];
|
||
},
|
||
handleSizeChange(val) {
|
||
this.pagination.pageSize = val;
|
||
this.loadData();
|
||
},
|
||
handleCurrentChange(val) {
|
||
this.pagination.page = val;
|
||
this.loadData();
|
||
},
|
||
handleSelectionChange(selection) {
|
||
this.selectedMessages = selection;
|
||
},
|
||
resetSearch() {
|
||
this.searchForm = {
|
||
keyword: '',
|
||
message_type: '',
|
||
send_status: '',
|
||
priority: '',
|
||
send_time_range: []
|
||
};
|
||
this.pagination.page = 1;
|
||
this.loadData();
|
||
},
|
||
addMessage() {
|
||
this.messageForm = {
|
||
id: null,
|
||
title: '',
|
||
message_type: '',
|
||
priority: 'medium',
|
||
target_type: 'all',
|
||
target_areas: [],
|
||
target_riders: [],
|
||
content: '',
|
||
send_type: 'immediate',
|
||
scheduled_time: '',
|
||
attachment_url: '',
|
||
attachment_name: ''
|
||
};
|
||
this.fileList = [];
|
||
this.messageDialogVisible = true;
|
||
},
|
||
editMessage(row) {
|
||
this.messageForm = {
|
||
id: row.id,
|
||
title: row.title,
|
||
message_type: row.message_type,
|
||
priority: row.priority,
|
||
target_type: row.target_type,
|
||
target_areas: row.target_areas || [],
|
||
target_riders: row.target_riders || [],
|
||
content: row.content,
|
||
send_type: 'immediate',
|
||
scheduled_time: '',
|
||
attachment_url: row.attachment_url || '',
|
||
attachment_name: row.attachment_name || ''
|
||
};
|
||
this.fileList = row.attachment_url ? [{ name: row.attachment_name, url: row.attachment_url }] : [];
|
||
this.messageDialogVisible = true;
|
||
},
|
||
saveMessage() {
|
||
this.$refs.messageForm.validate((valid) => {
|
||
if (valid) {
|
||
// 模拟保存操作
|
||
this.$message.success('保存成功');
|
||
this.messageDialogVisible = false;
|
||
this.loadData();
|
||
}
|
||
});
|
||
},
|
||
sendMessage(row) {
|
||
this.$confirm('确定要发送该消息吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
// 模拟发送操作
|
||
this.$message.success('发送成功');
|
||
this.loadData();
|
||
});
|
||
},
|
||
deleteMessage(row) {
|
||
this.$confirm('确定要删除该消息吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
// 模拟删除操作
|
||
this.$message.success('删除成功');
|
||
this.loadData();
|
||
});
|
||
},
|
||
batchSend() {
|
||
this.$confirm(`确定要发送选中的 ${this.selectedMessages.length} 条消息吗?`, '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
// 模拟批量发送操作
|
||
this.$message.success('批量发送成功');
|
||
this.loadData();
|
||
});
|
||
},
|
||
batchDelete() {
|
||
this.$confirm(`确定要删除选中的 ${this.selectedMessages.length} 条消息吗?`, '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
// 模拟批量删除操作
|
||
this.$message.success('批量删除成功');
|
||
this.loadData();
|
||
});
|
||
},
|
||
viewDetail(row) {
|
||
this.currentMessage = row;
|
||
this.detailDialogVisible = true;
|
||
},
|
||
viewReadStatus(row) {
|
||
this.currentMessage = row;
|
||
// 模拟加载阅读状态
|
||
this.readStatusList = [
|
||
{
|
||
rider_name: '张三',
|
||
rider_phone: '13800138001',
|
||
is_read: true,
|
||
read_time: '2024-01-20 10:30:00',
|
||
send_time: '2024-01-20 10:00:00'
|
||
},
|
||
{
|
||
rider_name: '李四',
|
||
rider_phone: '13800138002',
|
||
is_read: false,
|
||
read_time: null,
|
||
send_time: '2024-01-20 10:00:00'
|
||
}
|
||
];
|
||
this.readStatusDialogVisible = true;
|
||
},
|
||
handleTargetTypeChange(value) {
|
||
// 重置选择
|
||
this.messageForm.target_areas = [];
|
||
this.messageForm.target_riders = [];
|
||
},
|
||
handleUploadSuccess(response, file) {
|
||
this.messageForm.attachment_url = response.url;
|
||
this.messageForm.attachment_name = file.name;
|
||
},
|
||
exportData() {
|
||
// 模拟导出操作
|
||
this.$message.success('导出成功');
|
||
},
|
||
getMessageTypeText(type) {
|
||
const typeMap = {
|
||
'system': '系统公告',
|
||
'policy': '政策变更',
|
||
'activity': '活动通知',
|
||
'urgent': '紧急通知',
|
||
'other': '其他'
|
||
};
|
||
return typeMap[type] || type;
|
||
},
|
||
getPriorityText(priority) {
|
||
const priorityMap = {
|
||
'high': '高',
|
||
'medium': '中',
|
||
'low': '低'
|
||
};
|
||
return priorityMap[priority] || priority;
|
||
},
|
||
getPriorityColor(priority) {
|
||
const colorMap = {
|
||
'high': 'danger',
|
||
'medium': 'warning',
|
||
'low': 'info'
|
||
};
|
||
return colorMap[priority] || '';
|
||
},
|
||
getTargetTypeText(type) {
|
||
const typeMap = {
|
||
'all': '全部骑手',
|
||
'active': '活跃骑手',
|
||
'area': '指定区域',
|
||
'custom': '指定骑手'
|
||
};
|
||
return typeMap[type] || type;
|
||
},
|
||
getStatusText(status) {
|
||
const statusMap = {
|
||
'draft': '草稿',
|
||
'sent': '已发送',
|
||
'scheduled': '定时发送'
|
||
};
|
||
return statusMap[status] || status;
|
||
},
|
||
getStatusColor(status) {
|
||
const colorMap = {
|
||
'draft': 'info',
|
||
'sent': 'success',
|
||
'scheduled': 'warning'
|
||
};
|
||
return colorMap[status] || '';
|
||
},
|
||
formatDateTime(timestamp) {
|
||
if (!timestamp) return '';
|
||
return new Date(timestamp).toLocaleString('zh-CN');
|
||
}
|
||
}
|
||
});
|
||
</script>
|
||
</body>
|
||
</html> |