Sfoglia il codice sorgente

清除限制

master
leiyun 2 mesi fa
parent
commit
489b4036f7
3 ha cambiato i file con 81 aggiunte e 1 eliminazioni
  1. +1
    -0
      src/config/router.js
  2. +30
    -0
      src/controller/admin/system/sms.js
  3. +50
    -1
      view/admin/system/sms_index.html

+ 1
- 0
src/config/router.js Vedi File

@@ -39,6 +39,7 @@ module.exports = [
// 系统管理 - 短信记录
['/admin/system/sms', 'admin/system/sms/index'],
['/admin/system/sms/list', 'admin/system/sms/list'],
['/admin/system/sms/clearLimit', 'admin/system/sms/clearLimit', 'post'],

// 患者管理
['/admin/patient', 'admin/patient/index'],


+ 30
- 0
src/controller/admin/system/sms.js Vedi File

@@ -47,4 +47,34 @@ module.exports = class extends Base {

return this.json({ code: 0, data: list });
}

// 清除短信发送限制(手机号或IP)
async clearLimitAction() {
const { type, value } = this.post();
if (!type || !value) return this.fail('参数错误');

const dayjs = require('dayjs');
const today = dayjs().format('YYYY-MM-DD');
let cleared = [];

if (type === 'phone') {
// 清除手机号相关的所有限制
const bizTypes = ['real_name_auth', 'change_phone', 'login'];
for (const biz of bizTypes) {
await think.cache(`sms:rate_limit:${value}:${biz}`, null);
await think.cache(`sms:daily:${value}:${today}`, null);
await think.cache(`sms:code:${value}:${biz}`, null);
}
cleared = ['频率限制', '每日上限', '验证码缓存'];
} else if (type === 'ip') {
await think.cache(`sms:ip_hour:${value}`, null);
await think.cache(`sms:ip_day:${value}:${today}`, null);
cleared = ['IP小时限制', 'IP每日限制'];
} else {
return this.fail('类型错误');
}

await this.log('edit', '系统管理', `清除短信限制: ${type === 'phone' ? '手机号' : 'IP'} ${value} (${cleared.join('、')})`);
return this.success();
}
};

+ 50
- 1
view/admin/system/sms_index.html Vedi File

@@ -16,6 +16,7 @@
<el-input v-model="query.keyword" placeholder="搜索手机号..." style="width:180px;" clearable @keyup.enter="loadList"></el-input>
<el-select v-model="query.bizType" placeholder="业务类型" style="width:140px;" clearable>
<el-option label="实名认证" value="real_name_auth"></el-option>
<el-option label="登录" value="login"></el-option>
<el-option label="修改手机号" value="change_phone"></el-option>
<el-option label="审核通过" value="audit_approved"></el-option>
<el-option label="审核驳回" value="audit_rejected"></el-option>
@@ -30,6 +31,8 @@
value-format="YYYY-MM-DD" style="width:240px;" :teleported="false"></el-date-picker>
<el-button type="primary" @click="loadList">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
<div style="flex:1"></div>
<el-button type="warning" plain @click="showClearDialog = true">清除短信限制</el-button>
</div>

<!-- 信息栏 -->
@@ -68,6 +71,25 @@
<el-pagination background layout="total, sizes, prev, pager, next" :total="total" v-model:page-size="pageSize" :page-sizes="[20, 50, 100]" v-model:current-page="page" @current-change="loadList" @size-change="onSizeChange"></el-pagination>
</div>
</el-card>

<!-- 清除短信限制弹窗 -->
<el-dialog v-model="showClearDialog" title="清除短信限制" width="420px" :close-on-click-modal="false">
<el-form label-width="80px">
<el-form-item label="类型">
<el-radio-group v-model="clearForm.type">
<el-radio value="phone">手机号</el-radio>
<el-radio value="ip">IP地址</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="clearForm.type === 'phone' ? '手机号' : 'IP地址'">
<el-input v-model="clearForm.value" :placeholder="clearForm.type === 'phone' ? '请输入手机号' : '请输入IP地址'" clearable></el-input>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showClearDialog = false">取消</el-button>
<el-button type="primary" :loading="clearLoading" @click="handleClearLimit">确定</el-button>
</template>
</el-dialog>
</div>
{% endblock %}

@@ -88,6 +110,7 @@ const app = createApp({

const bizTypeMap = {
real_name_auth: { type: 'primary', text: '实名认证' },
login: { type: '', text: '登录' },
change_phone: { type: 'warning', text: '修改手机号' },
audit_approved: { type: 'success', text: '审核通过' },
audit_rejected: { type: 'danger', text: '审核驳回' }
@@ -133,7 +156,33 @@ const app = createApp({

onMounted(() => loadList());

return { loading, list, total, page, pageSize, query, dateRange, bizTypeMap, statusMap, loadList, resetQuery, onSizeChange };
// 清除短信限制
const showClearDialog = ref(false);
const clearLoading = ref(false);
const clearForm = reactive({ type: 'phone', value: '' });

async function handleClearLimit() {
if (!clearForm.value.trim()) {
return ElementPlus.ElMessage.warning('请输入' + (clearForm.type === 'phone' ? '手机号' : 'IP地址'));
}
clearLoading.value = true;
try {
const res = await fetch('/admin/system/sms/clearLimit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: clearForm.type, value: clearForm.value.trim() })
}).then(r => r.json());
if (res.errno === 0) {
ElementPlus.ElMessage.success('已清除');
showClearDialog.value = false;
clearForm.value = '';
} else {
ElementPlus.ElMessage.error(res.errmsg || '操作失败');
}
} finally { clearLoading.value = false; }
}

return { loading, list, total, page, pageSize, query, dateRange, bizTypeMap, statusMap, loadList, resetQuery, onSizeChange, showClearDialog, clearLoading, clearForm, handleClearLimit };
}
});



Caricamento…
Annulla
Salva