后台增加 短信日志管理
parent
1ccafe88e2
commit
4c0955b630
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\SmsLogService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SmsLogController extends Controller
|
||||
{
|
||||
public function GetList(){
|
||||
$page = request('page');
|
||||
$pagesize = request('pageSize');
|
||||
$searchInfo = request('searchInfo');
|
||||
$s = new SmsLogService();
|
||||
return $s->GetList(['page' => $page, 'pagesize' => $pagesize, 'searchInfo' => $searchInfo]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class SmsLogService
|
||||
{
|
||||
public function GetList($arr){
|
||||
$result = [];
|
||||
$page = $arr['page'] ?? 1;
|
||||
$pagesize = $arr['pagesize'] ?? 15;
|
||||
$searchInfo = $arr['searchInfo'] ?? [];
|
||||
|
||||
$query = DB::table('sms_log');
|
||||
|
||||
if (isset($searchInfo['phone']) && !empty($searchInfo['phone'])) {
|
||||
$query = $query->where('phone', 'like', '%' . $searchInfo['phone'] . '%');
|
||||
}
|
||||
|
||||
if (isset($searchInfo['status']) && !empty($searchInfo['status'])) {
|
||||
$query = $query->where('status', $searchInfo['status']);
|
||||
}
|
||||
|
||||
$count = $query->count();
|
||||
$list = $query->orderBy('id', 'desc')
|
||||
->skip(($page - 1) * $pagesize)
|
||||
->take($pagesize)
|
||||
->get();
|
||||
|
||||
$result['list'] = $list;
|
||||
$result['count'] = $count;
|
||||
|
||||
return \Yz::Return(true, '获取成功', $result);
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,165 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="head">
|
||||
<el-row>
|
||||
<el-form-item>
|
||||
<el-tag class="ml-2" type="success" style="margin-right: 20px;">电话</el-tag>
|
||||
<el-input v-model="searchInfo.phone" placeholder="请输入电话号码" clearable style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-tag class="ml-2" type="success" style="margin-right: 20px;">状态</el-tag>
|
||||
<el-select v-model="searchInfo.status" clearable placeholder="请选择状态" style="width: 150px;">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="成功" value="成功" />
|
||||
<el-option label="失败" value="失败" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" style="margin-left: 10px;" @click="Search()">搜索</el-button>
|
||||
<el-button @click="Reset()">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-table border :data="tableData" style="width: 100%;" row-key="id" v-loading="loading">
|
||||
<el-table-column prop="id" label="ID" width="80" />
|
||||
<el-table-column prop="phone" label="电话" width="120" />
|
||||
<el-table-column prop="content" label="短信内容" width="250" show-overflow-tooltip />
|
||||
<el-table-column prop="sid" label="短信ID" width="150" show-overflow-tooltip />
|
||||
<el-table-column prop="status" label="状态" width="80">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === '成功' ? 'success' : 'danger'">{{ scope.row.status || '未知' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="返回消息" width="200" show-overflow-tooltip />
|
||||
<el-table-column label="回调详情" min-width="300">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.callback_content" @click="toggleExpand(scope.row)" class="zhankai_button">
|
||||
{{ isExpanded(scope.row) ? '收起' : '展开' }}
|
||||
</div>
|
||||
<span v-else style="color: #999;">-</span>
|
||||
<div v-if="isExpanded(scope.row) && scope.row.callback_content" class="callback-content">
|
||||
<pre>{{ formatJson(scope.row.callback_content) }}</pre>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="created_at" label="发送时间" width="180" />
|
||||
</el-table>
|
||||
|
||||
<div class="page">
|
||||
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
|
||||
:page-sizes="[15, 50, 100, 200]" layout="total, sizes, prev, pager, next" :total="total"
|
||||
@size-change="PageSizeChange" @current-change="PageCurrentChange" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
onMounted
|
||||
} from 'vue'
|
||||
import {
|
||||
ElMessage
|
||||
} from 'element-plus'
|
||||
import {
|
||||
SmsLogGetList
|
||||
} from '@/api/api.js'
|
||||
|
||||
let loading = ref(false)
|
||||
let tableData = ref([])
|
||||
let currentPage = ref(1)
|
||||
let pageSize = ref(15)
|
||||
let total = 0
|
||||
let expandedRows = ref({})
|
||||
|
||||
let searchInfo = ref({
|
||||
phone: '',
|
||||
status: ''
|
||||
})
|
||||
|
||||
const GetList = () => {
|
||||
loading.value = true
|
||||
SmsLogGetList({
|
||||
page: currentPage.value,
|
||||
pageSize: pageSize.value,
|
||||
searchInfo: searchInfo.value
|
||||
}).then(res => {
|
||||
loading.value = false
|
||||
if (res.status) {
|
||||
tableData.value = res.data.list
|
||||
total = res.data.count
|
||||
} else {
|
||||
ElMessage.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const Search = () => {
|
||||
currentPage.value = 1
|
||||
GetList()
|
||||
}
|
||||
|
||||
const Reset = () => {
|
||||
searchInfo.value = {
|
||||
phone: '',
|
||||
status: ''
|
||||
}
|
||||
currentPage.value = 1
|
||||
GetList()
|
||||
}
|
||||
|
||||
const PageSizeChange = (e) => {
|
||||
pageSize.value = e
|
||||
GetList()
|
||||
}
|
||||
|
||||
const PageCurrentChange = (e) => {
|
||||
currentPage.value = e
|
||||
GetList()
|
||||
}
|
||||
|
||||
const toggleExpand = (row) => {
|
||||
expandedRows.value[row.id] = !expandedRows.value[row.id]
|
||||
}
|
||||
|
||||
const isExpanded = (row) => {
|
||||
return expandedRows.value[row.id] === true
|
||||
}
|
||||
|
||||
const formatJson = (content) => {
|
||||
try {
|
||||
const obj = typeof content === 'string' ? JSON.parse(content) : content
|
||||
return JSON.stringify(obj, null, 2)
|
||||
} catch (e) {
|
||||
return content
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
GetList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
<style scoped>
|
||||
.page {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.zhankai_button {
|
||||
color: #55aaff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.callback-content {
|
||||
background: #f5f5f5;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
.callback-content pre {
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
Reference in New Issue