| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- <template>
- <div class="app-container">
- <!-- 统计卡片 -->
- <el-row :gutter="16" class="mb16">
- <el-col :span="6">
- <el-card shadow="never" class="stat-card">
- <div class="stat-label">租户总数</div>
- <div class="stat-value">{{ smsCount.totalCount || 0 }}</div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card shadow="never" class="stat-card">
- <div class="stat-label">短信剩余总量</div>
- <div class="stat-value" style="color:#1890ff">{{ smsCount.totalRemain || 0 }}</div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card shadow="never" class="stat-card">
- <div class="stat-label">正常租户数</div>
- <div class="stat-value" style="color:#52c41a">{{ smsCount.activeCount || 0 }}</div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card shadow="never" class="stat-card">
- <div class="stat-label">禁用租户数</div>
- <div class="stat-value" style="color:#ff4d4f">{{ smsCount.disabledCount || 0 }}</div>
- </el-card>
- </el-col>
- </el-row>
- <!-- 搜索栏 -->
- <el-card shadow="never" class="mb16 filter-card">
- <el-form :model="queryParams" ref="queryForm" :inline="true" size="small">
- <el-form-item label="租户名称" prop="tenantId">
- <inline-tenant-selector @change="handleTenantChange" />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">查询</el-button>
- <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
- </el-form-item>
- </el-form>
- </el-card>
- <!-- 操作栏 -->
- <el-row :gutter="10" class="mb8">
- <el-col :span="1.5">
- <el-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading" @click="handleExport">导出</el-button>
- </el-col>
- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
- </el-row>
- <!-- 表格 -->
- <el-table v-loading="loading" :data="smsList" border size="small" style="width:100%">
- <el-table-column label="ID" align="center" prop="smsId" min-width="60" />
- <el-table-column label="所属租户" align="center" prop="companyName" min-width="120" />
- <el-table-column label="短信剩余条数" align="center" prop="smsRemain" min-width="110">
- <template slot-scope="scope">
- <span style="color:#1890ff;font-weight:bold">{{ scope.row.smsRemain || 0 }}</span>
- </template>
- </el-table-column>
- <el-table-column label="状态" align="center" min-width="80">
- <template slot-scope="scope">
- <el-tag v-if="scope.row.status === '0' || scope.row.status === 0" type="success" size="mini">正常</el-tag>
- <el-tag v-else type="danger" size="mini">禁用</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="创建时间" align="center" prop="createTime" min-width="150" />
- <el-table-column label="操作" align="center" width="100" fixed="right">
- <template slot-scope="scope">
- <el-button size="mini" type="text" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
- <!-- 编辑弹窗 -->
- <el-dialog title="编辑短信配置" :visible.sync="editVisible" width="500px" append-to-body>
- <el-form ref="editForm" :model="editForm" :rules="editRules" label-width="110px">
- <el-form-item label="所属租户">
- <span>{{ editForm.companyName }}</span>
- </el-form-item>
- <el-form-item label="短信剩余条数">
- <span style="color:#1890ff;font-weight:bold">{{ editForm.smsRemain || 0 }}</span>
- </el-form-item>
- <el-form-item label="调整条数" prop="adjustCount">
- <el-input-number v-model="editForm.adjustCount" :min="1" :precision="0" style="width:200px" />
- <el-radio-group v-model="editForm.adjustType" style="margin-left:10px">
- <el-radio label="add">增加</el-radio>
- <el-radio label="reduce">减少</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="状态" prop="status">
- <el-select v-model="editForm.status" placeholder="请选择状态" style="width:200px">
- <el-option label="正常" value="0" />
- <el-option label="禁用" value="1" />
- </el-select>
- </el-form-item>
- <el-form-item label="备注" prop="remark">
- <el-input v-model="editForm.remark" type="textarea" :rows="2" placeholder="请输入备注" />
- </el-form-item>
- </el-form>
- <div slot="footer">
- <el-button @click="editVisible = false">取 消</el-button>
- <el-button type="primary" :loading="submitLoading" @click="submitEdit">确 定</el-button>
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- import request from '@/utils/request'
- import InlineTenantSelector from '@/components/InlineTenantSelector'
- export default {
- name: 'AdminSms',
- components: { InlineTenantSelector },
- data() {
- return {
- loading: false,
- exportLoading: false,
- submitLoading: false,
- showSearch: true,
- total: 0,
- smsList: [],
- smsCount: {},
- queryParams: {
- pageNum: 1,
- pageSize: 10,
- companyName: null,
- tenantId: null
- },
- editVisible: false,
- editForm: {
- smsId: null,
- companyName: '',
- smsRemain: 0,
- adjustCount: 1,
- adjustType: 'add',
- status: '0',
- remark: ''
- },
- editRules: {
- adjustCount: [{ required: true, message: '请输入调整条数', trigger: 'blur' }],
- status: [{ required: true, message: '请选择状态', trigger: 'change' }]
- }
- }
- },
- created() {
- this.getList()
- this.getCount()
- },
- methods: {
- getList() {
- if (!this.queryParams.tenantId) {
- this.smsList = []
- this.total = 0
- this.loading = false
- return
- }
- this.loading = true
- request({
- url: '/admin/sms-admin/list',
- method: 'get',
- params: this.queryParams
- }).then(res => {
- this.smsList = res.rows || []
- this.total = res.total || 0
- this.loading = false
- }).catch(() => { this.loading = false })
- },
- getCount() {
- if (!this.queryParams.tenantId) {
- this.smsCount = {}
- return
- }
- request({
- url: '/admin/sms-admin/count',
- method: 'get'
- }).then(res => {
- this.smsCount = res.data || {}
- })
- },
- handleQuery() {
- if (!this.queryParams.tenantId) {
- this.$message.warning('请先选择租户')
- return
- }
- this.queryParams.pageNum = 1
- this.getList()
- },
- handleTenantChange(val) {
- this.queryParams.tenantId = val || null
- this.handleQuery()
- },
- resetQuery() {
- this.resetForm('queryForm')
- this.queryParams.tenantId = null
- this.handleQuery()
- },
- handleEdit(row) {
- request({
- url: '/admin/sms-admin/' + row.smsId,
- method: 'get'
- }).then(res => {
- const data = res.data || {}
- this.editForm = {
- smsId: data.smsId,
- companyName: data.companyName,
- smsRemain: data.smsRemain,
- adjustCount: 1,
- adjustType: 'add',
- status: String(data.status || '0'),
- remark: ''
- }
- this.editVisible = true
- })
- },
- submitEdit() {
- this.$refs['editForm'].validate(valid => {
- if (!valid) return
- this.submitLoading = true
- const data = {
- smsId: this.editForm.smsId,
- status: this.editForm.status,
- remark: this.editForm.remark
- }
- // 计算调整后的短信条数
- if (this.editForm.adjustType === 'add') {
- data.smsRemain = (this.editForm.smsRemain || 0) + (this.editForm.adjustCount || 0)
- } else {
- data.smsRemain = Math.max(0, (this.editForm.smsRemain || 0) - (this.editForm.adjustCount || 0))
- }
- request({
- url: '/admin/sms-admin',
- method: 'put',
- data: data
- }).then(() => {
- this.$message.success('修改成功')
- this.editVisible = false
- this.getList()
- this.getCount()
- }).finally(() => { this.submitLoading = false })
- })
- },
- handleExport() {
- this.exportLoading = true
- request({
- url: '/admin/sms-admin/export',
- method: 'get',
- params: this.queryParams,
- responseType: 'blob'
- }).then(res => {
- const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
- const link = document.createElement('a')
- link.href = URL.createObjectURL(blob)
- link.download = '短信管理.xlsx'
- link.click()
- URL.revokeObjectURL(link.href)
- }).catch(() => {
- this.$message.error('导出失败')
- }).finally(() => { this.exportLoading = false })
- }
- }
- }
- </script>
- <style scoped>
- .mb8 { margin-bottom: 8px; }
- .mb16 { margin-bottom: 16px; }
- .filter-card { padding-bottom: 0; }
- .stat-card { text-align: center; }
- .stat-label { font-size: 13px; color: #909399; margin-bottom: 8px; }
- .stat-value { font-size: 24px; font-weight: bold; color: #303133; }
- </style>
|