telco_server/app/admin/apis/bus_apis/a_sms_manage.go
chenlin ef1a39a0a3 1、新增对外短信接口;
2、新增硕软相关接口;
2025-09-04 17:55:02 +08:00

2339 lines
60 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package bus_apis
import (
"bytes"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
"github.com/google/uuid"
"github.com/pkg/errors"
"go-admin/app/admin/models/bus_models"
"go-admin/app/admin/service/bus_service"
"go-admin/tools/app"
"go-admin/tools/crypto"
"go-admin/tools/sms"
"go-admin/tools/utils"
"gorm.io/gorm"
"io"
"log"
"net/http"
"strconv"
"strings"
"time"
)
type SmsApi struct {
api.Api
}
// MassImportPhone 导入号码(群发短信)
// @Summary 导入号码(群发短信)
// @Tags 短信管理-V1.0.0
// @Produce json
// @Accept json
// @Param file body string true "上传excel文件"
// @Success 200 {object} bus_models.MassImportPhoneResp
// @Router /api/v1/sms/mass_import_phone [post]
func (e SmsApi) MassImportPhone(c *gin.Context) {
var smsService bus_service.SmsService
// 绑定 JSON 数据,获取 secret_key
err := e.MakeContext(c).
MakeOrm().
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 获取上传的文件
file, _, err := c.Request.FormFile("file")
if err != nil {
e.Logger.Error("获取文件失败:", err)
e.Error(400, err, "请上传有效的文件")
return
}
defer file.Close()
// 读取文件内容并处理
fileBytes, err := io.ReadAll(file)
if err != nil {
e.Logger.Error("读取文件内容失败:", err)
e.Error(500, err, "读取文件失败")
return
}
// 使用 SmsService 读取 Excel 文件
phones, err := smsService.ReadExcelFile(fileBytes)
if err != nil {
e.Error(500, err, "读取文件失败")
return
}
if len(phones) == 0 {
e.Error(400, nil, "导入的手机号为空")
return
}
importSerial := uuid.New().String()
fmt.Println("uuid importSerial:", importSerial)
err = smsService.CachePhonesByShard(importSerial, phones)
if err != nil {
fmt.Println("手机号缓存失败")
e.Error(500, err, "手机号缓存失败")
return
}
// 返回加密后的数据
resp := bus_models.MassImportPhoneResp{
ImportSerialNumber: importSerial,
}
if len(phones) > bus_models.ShowCount {
resp.List = phones[0:200]
} else {
resp.List = phones
}
// 将JSON数据转换为字符串
plainText, err := json.Marshal(resp)
if err != nil {
e.Logger.Error("JSON 序列化失败:", err)
e.Error(500, err, "数据转换失败")
return
}
// 使用AES加密手机号
encryptedData, err := crypto.AESEncryptJson(bus_models.AESKey, string(plainText))
if err != nil {
e.Logger.Error("AES 加密失败:", err)
e.Error(500, err, "加密失败")
return
}
app.OK(c, encryptedData, "导入成功")
return
}
func (e SmsApi) SelfImportPhone(c *gin.Context) {
s := bus_service.ProductService{}
var req bus_models.ProductListReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
}
func (e SmsApi) FileImportPhone(c *gin.Context) {
s := bus_service.ProductService{}
var req bus_models.ProductListReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
}
func (e SmsApi) ExcelImportPhone(c *gin.Context) {
s := bus_service.ProductService{}
var req bus_models.ProductListReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
}
// ExportMessPhone 导出号码(群发短信)
// @Summary 导出号码(群发短信)
// @Tags 短信管理-V1.0.0
// @Produce json
// @Accept json
// @Param request body bus_models.ExportMessPhoneReq true "导出号码(群发短信)模型"
// @Success 200 {object} bus_models.ExportMessPhoneResp
// @Router /api/v1/sms/export_mess_phone [post]
func (e SmsApi) ExportMessPhone(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.ExportMessPhoneReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 解密
decryptedText, err := crypto.AESDecryptJson(bus_models.AESKey, req.Data)
if err != nil {
fmt.Println("解密失败:", err)
return
}
var l bus_models.ExportMessPhoneReq
err = json.Unmarshal([]byte(decryptedText), &l)
if err != nil {
err = fmt.Errorf("json Unmarshal error, %s", err.Error())
return
}
req = l
// 调用导出函数
url, err := smsService.ExportPhoneListToExcel(req.ImportSerialNumber, req.PhoneList)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
resp := bus_models.ExportMessPhoneResp{
ExportUrl: url,
}
app.OK(c, resp, "OK")
return
}
// CheckSensitiveWords 敏感词检测
// @Summary 敏感词检测
// @Tags 短信管理-V1.0.0
// @Produce json
// @Accept json
// @Param request body bus_models.CheckSensitiveWordsReq true "敏感词检测模型"
// @Success 200 {object} bus_models.CheckSensitiveWordsResponse
// @Router /api/v1/sms/check_sensitive_words [post]
func (e SmsApi) CheckSensitiveWords(c *gin.Context) {
var req bus_models.CheckSensitiveWordsReq
s := bus_service.SmsService{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
hits, err := s.CheckSensitiveWords(req.Content)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "敏感词检测失败")
return
}
hasSensitiveWords := len(hits) > 0
resp := bus_models.CheckSensitiveWordsResponse{
HasSensitiveWords: hasSensitiveWords,
SensitiveWords: hits,
}
app.OK(c, resp, "OK")
}
// SendSms 提交发送任务
// @Summary 提交发送任务
// @Tags 短信管理-V1.0.0
// @Produce json
// @Accept json
// @Param request body bus_models.SendSmsReq true "提交发送任务模型"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/send_sms [post]
func (e SmsApi) SendSms(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SendSmsReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
if coopNum != "admin" {
// 查询是否配置了短信产品
flag, err := CheckCooperativeHasProduct(e.Orm, coopNum, bus_models.ProductForSms)
if err != nil {
log.Printf("查询合作商产品失败: %v", err)
app.Error(c, http.StatusInternalServerError, errors.New("提交失败,未查询到合作商信息"), "提交失败,未查询到合作商信息")
return
}
// 只处理短信产品 (ProductType=1)
if !flag {
app.Error(c, http.StatusInternalServerError, errors.New("提交失败,未配置短信产品"), "提交失败,未配置短信产品")
return
}
}
// 解密
decryptedText, err := crypto.AESDecryptJson(bus_models.AESKey, req.Data)
if err != nil {
fmt.Println("解密失败:", err)
return
}
var l bus_models.SendSmsReq
err = json.Unmarshal([]byte(decryptedText), &l)
if err != nil {
err = fmt.Errorf("json Unmarshal error, %s", err.Error())
return
}
req = l
if req.ImportSerialNumber == "" && len(req.PhoneList) == 0 {
e.Error(400, nil, "手机号不能为空")
return
}
if req.ImportSerialNumber != "" {
// 如果有导入编号还有额外手机号,直接追加到 Redis 缓存列表
if len(req.PhoneList) > 0 {
err = smsService.AppendPhonesToRedis(req.ImportSerialNumber, req.PhoneList)
if err != nil {
e.Logger.Error("手机号追加失败:", err)
e.Error(500, err, "手机号追加失败")
return
}
}
} else {
importSerial := uuid.New().String()
fmt.Println("uuid importSerial:", importSerial)
err = smsService.CachePhonesByShard(importSerial, req.PhoneList)
if err != nil {
fmt.Println("手机号缓存失败")
e.Error(500, err, "手机号缓存失败")
return
}
req.ImportSerialNumber = importSerial
}
// 创建发送任务,使用 redis 缓存中的数据分片处理
err = smsService.SubmitSmsTaskFromRedis(c.Request.Context(), req.ImportSerialNumber, req.SmsContent,
req.SendTime, coopNum, coopName)
if err != nil {
e.Logger.Error("任务提交失败:", err)
e.Error(500, err, "短信任务提交失败")
return
}
app.OK(c, nil, "短信发送任务提交成功")
return
}
func CheckCooperativeHasProduct(db *gorm.DB, coopNum string, productType uint8) (bool, error) {
// 查询合作商信息
var coop bus_models.BusCooperative
if err := db.Model(&bus_models.BusCooperative{}).
Where("cooperative_number = ?", coopNum).
First(&coop).Error; err != nil {
log.Printf("查询合作商失败, CooperativeNumber=%s, err=%v", coopNum, err)
return false, fmt.Errorf("查询合作商失败")
}
// 查询合作商产品信息
var coopProduct []bus_models.BusCooperativeProduct
if err := db.Where("cooperative_id = ?", coop.ID).
Find(&coopProduct).Error; err != nil {
log.Printf("查询合作商产品失败: %v", err)
return false, fmt.Errorf("查询合作商产品失败")
}
productFlag := false
for _, item := range coopProduct {
// 查询产品信息
var product bus_models.BusProduct
if err := db.Where("id = ?", item.ProductID).
First(&product).Error; err != nil {
log.Printf("查询产品失败: %v", err)
return false, fmt.Errorf("查询产品失败")
}
// 校验是否指定产品类型
if product.ProductType == productType {
productFlag = true
break
}
}
// 校验是否指定产品类型
if !productFlag {
log.Printf("合作商未配置指定的产品类型[%d]", productType)
return false, nil
}
return true, nil
}
// QuerySmsTaskList 查询短信下行记录
// @Summary 查询短信下行记录
// @Tags 短信管理-V1.0.0
// @Produce json
// @Accept json
// @Param request body bus_models.SmsTaskQueryRequest true "查询短信下行记录模型"
// @Success 200 {object} bus_models.SmsTaskQueryResponse
// @Router /api/v1/sms/sms_log [post]
func (e SmsApi) QuerySmsTaskList(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsTaskQueryRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
result, err := smsService.QuerySmsTaskList(c, req, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "查询短信下行记录失败")
return
}
app.OK(c, result, "查询成功")
}
// SmsSendRecordQuery 查询短信下行明细
// @Summary 查询短信下行明细
// @Tags 短信管理-V1.0.0
// @Produce json
// @Accept json
// @Param request body bus_models.SmsTaskQueryRequest true "查询短信下行明细模型"
// @Success 200 {object} bus_models.SmsTaskQueryResponse
// @Router /api/v1/sms/sms_phone_log [post]
func (e SmsApi) SmsSendRecordQuery(c *gin.Context) {
var req bus_models.SmsSendRecordQueryReq
s := bus_service.SmsService{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "参数解析失败")
return
}
resp, err := s.QuerySmsSendRecords(c, req)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "查询失败")
return
}
app.OK(c, resp, "查询成功")
}
// GetPhonesByBatchID 根据批次ID获取手机号
// @Summary 根据批次ID获取手机号
// @Tags 短信管理-V1.0.0
// @Produce json
// @Param request body bus_models.GetPhonesByBatchIDReq true "根据批次ID获取手机号模型"
// @Success 200 {object} bus_models.GetPhonesByBatchIDResp
// @Router /api/v1/sms/get_phones [post]
func (e SmsApi) GetPhonesByBatchID(c *gin.Context) {
var smsService bus_service.SmsService
var req bus_models.GetPhonesByBatchIDReq
// 初始化服务
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
if req.BatchID == "" {
e.Error(400, nil, "缺少参数batch_id")
return
}
// 根据 batch_id 查询导入ID
var task bus_models.SmsTask
if err = e.Orm.Where("batch_id = ?", req.BatchID).First(&task).Error; err != nil {
e.Logger.Error("查询任务失败:", err)
e.Error(404, err, "未找到对应批次任务")
return
}
if task.ImportID == "" {
e.Error(400, nil, "该批次未绑定导入记录")
return
}
// 查询缓存的手机号
phones, err := smsService.GetPhonesFromCache(task.ImportID, 30)
if err != nil {
e.Logger.Error("获取手机号失败:", err)
}
// 如果缓存中没有手机号,再查询已发送记录
if len(phones) == 0 {
phones, err = smsService.GetSentPhonesByBatchID(e.Orm, req.BatchID, 30)
if err != nil {
e.Logger.Error("从数据库查询已发送手机号失败:", err)
e.Error(500, err, "获取手机号失败")
return
}
}
resp := bus_models.GetPhonesByBatchIDResp{
Phones: phones,
}
// 将JSON数据转换为字符串
plainText, err := json.Marshal(resp)
if err != nil {
e.Logger.Error("JSON 序列化失败:", err)
e.Error(500, err, "数据转换失败")
return
}
// 使用AES加密手机号
encryptedData, err := crypto.AESEncryptJson(bus_models.AESKey, string(plainText))
if err != nil {
e.Logger.Error("AES 加密失败:", err)
e.Error(500, err, "加密失败")
return
}
app.OK(c, encryptedData, "查询成功")
}
// QueryScheduledSmsTaskList 查询定时短信任务列表
// @Summary 查询定时短信任务列表
// @Tags 短信管理-V1.0.0
// @Produce json
// @Accept json
// @Param request body bus_models.SmsTaskScheduledQueryRequest true "查询定时短信任务列表请求"
// @Success 200 {object} bus_models.SmsTaskQueryResponse
// @Router /api/v1/sms/sms_timing_list [post]
func (e SmsApi) QueryScheduledSmsTaskList(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsTaskScheduledQueryRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
result, err := smsService.QueryScheduledSmsTaskList(c, req, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "查询定时短信任务失败")
return
}
app.OK(c, result, "查询成功")
}
// QuerySmsUplinkList 查询短信上行记录
// @Summary 查询短信上行记录
// @Tags 短信管理-V1.0.0
// @Produce json
// @Accept json
// @Param request body bus_models.SmsUplinkQueryRequest true "查询条件"
// @Success 200 {object} bus_models.SmsUplinkQueryResponse
// @Router /api/v1/sms/uplink_log [post]
func (e SmsApi) QuerySmsUplinkList(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsUplinkQueryRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
resp, err := smsService.QuerySmsUplinkList(c, req, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "查询短信上行记录失败")
return
}
app.OK(c, resp, "查询成功")
}
// BatchUpdateScheduledSmsContent 批量修改定时短信内容
// @Summary 批量修改定时短信内容
// @Tags 短信管理-V1.0.0
// @Accept json
// @Produce json
// @Param request body bus_models.BatchUpdateSmsContentRequest true "批量修改定时短信内容请求"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/batch_update_content [post]
func (e SmsApi) BatchUpdateScheduledSmsContent(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.BatchUpdateSmsContentRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
if len(req.TaskIDs) == 0 || strings.TrimSpace(req.SmsContent) == "" {
app.Error(c, 500, errors.New("任务ID列表和短信内容不能为空"), "")
}
if err := smsService.BatchUpdateSmsContent(req, e.Orm); err != nil {
e.Logger.Error(err)
e.Error(500, err, "批量修改短信内容失败")
return
}
app.OK(c, nil, "修改成功")
}
// BatchCancelScheduledSms 批量取消定时短信任务
// @Summary 批量取消定时短信任务
// @Tags 短信管理-V1.0.0
// @Accept json
// @Produce json
// @Param request body bus_models.BatchUpdateRequest true "任务ID列表"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/batch_cancel [post]
func (e SmsApi) BatchCancelScheduledSms(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.BatchUpdateRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
if err := smsService.BatchCancelSmsTasks(req, e.Orm); err != nil {
e.Logger.Error(err)
e.Error(500, err, "批量取消任务失败")
return
}
app.OK(c, nil, "取消成功")
}
// BatchResetScheduledSms 批量重置定时发送时间
// @Summary 批量重置定时发送时间
// @Tags 短信管理-V1.0.0
// @Accept json
// @Produce json
// @Param request body bus_models.BatchResetScheduleTimeRequest true "重置定时时间请求"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/batch_reset_schedule [post]
func (e SmsApi) BatchResetScheduledSms(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.BatchResetScheduleTimeRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
if err := smsService.BatchResetScheduleTime(req, e.Orm); err != nil {
e.Logger.Error(err)
e.Error(500, err, "重置定时时间失败")
return
}
app.OK(c, nil, "重置成功")
}
// CreateSignatureRealname 新增实名签名
// @Summary 新增实名签名
// @Tags 短信管理-V1.0.0
// @Accept json
// @Produce json
// @Param request body bus_models.SmsSignatureRealname true "实名签名信息"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/signature_realname/create [post]
func (e SmsApi) CreateSignatureRealname(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsSignatureRealname
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
req.CooperativeName = coopName
req.CooperativeNumber = coopNum
if err := smsService.CreateSignatureRealname(&req, e.Orm); err != nil {
e.Logger.Error(err)
e.Error(500, err, "创建失败")
return
}
app.OK(c, nil, "创建成功")
}
// UpdateSignatureRealname 编辑实名签名
// @Summary 编辑实名签名
// @Tags 短信管理-V1.0.0
// @Accept json
// @Produce json
// @Param request body bus_models.SmsSignatureRealname true "实名签名信息"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/signature_realname/update [post]
func (e SmsApi) UpdateSignatureRealname(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsSignatureRealname
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
if err := smsService.UpdateSignatureRealname(&req, e.Orm); err != nil {
e.Logger.Error(err)
e.Error(500, err, "更新失败")
return
}
app.OK(c, nil, "更新成功")
}
// DeleteSignatureRealname 批量删除签名实名记录
// @Summary 批量删除签名实名记录
// @Tags 短信管理-V1.0.0
// @Accept json
// @Produce json
// @Param request body bus_models.DeleteSignatureRealnameRequest true "删除请求"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/signature_realname/delete [post]
func (e SmsApi) DeleteSignatureRealname(c *gin.Context) {
var req bus_models.DeleteSignatureRealnameRequest
smsService := bus_service.SmsService{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "参数绑定失败")
return
}
if len(req.IDs) == 0 {
e.Error(400, nil, "请选择要删除的记录")
return
}
if err := smsService.BatchDeleteSignatureRealname(req.IDs, e.Orm); err != nil {
e.Logger.Error(err)
e.Error(500, err, "删除失败")
return
}
app.OK(c, nil, "删除成功")
}
// ListSignatureRealname 查询签名实名制列表
// @Summary 查询签名实名制列表
// @Tags 短信管理-V1.0.0
// @Accept json
// @Produce json
// @Param request body bus_models.SignatureRealnameQuery true "实名签名信息"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/signature_realname/list [get]
func (e SmsApi) ListSignatureRealname(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SignatureRealnameQuery
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Query).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
resp, err := smsService.ListSignatureRealname(c, req, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "查询失败")
return
}
app.OK(c, resp, "查询成功")
}
// AddContactsCategory 新增通讯录分类节点
// @Summary 新增通讯录分类节点
// @Tags 短信管理-通讯录
// @Accept json
// @Produce json
// @Param request body bus_models.AddContactCategoryReq true "分类信息"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/contacts_category/add [post]
func (e SmsApi) AddContactsCategory(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.AddContactCategoryReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
req.CooperativeNumber = coopNum
req.CooperativeName = coopName
err = smsService.AddContactsCategory(req, e.Orm)
if err != nil {
e.Error(500, err, "添加失败")
return
}
app.OK(c, nil, "添加成功")
}
// EditContactsCategory 编辑通讯录分类节点
// @Summary 编辑通讯录分类节点
// @Tags 短信管理-通讯录
// @Accept json
// @Produce json
// @Param request body bus_models.EditContactCategoryReq true "编辑信息"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/contacts_category/edit [post]
func (e SmsApi) EditContactsCategory(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.EditContactCategoryReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
req.CooperativeNumber = coopNum
req.CooperativeName = coopName
err = smsService.EditContactsCategory(req, e.Orm)
if err != nil {
e.Error(500, err, "编辑失败")
return
}
app.OK(c, nil, "编辑成功")
}
// ListContactsCategories 查询通讯录分类列表(树形结构)
// @Summary 查询通讯录分类树
// @Tags 短信管理-通讯录
// @Accept json
// @Produce json
// @Param request body bus_models.ListContactCategoryRequest true "要删除的分类ID列表"
// @Success 200 {object} bus_models.SmsContactCategoryTree
// @Router /api/v1/sms/contacts_category/list [post]
func (e SmsApi) ListContactsCategories(c *gin.Context) {
var req bus_models.ListContactCategoryRequest
smsService := bus_service.SmsService{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Error(500, err, err.Error())
return
}
data, err := smsService.GetContactsCategoryTree(c, e.Orm, req.CategoryID)
if err != nil {
e.Error(500, err, "查询失败")
return
}
app.OK(c, data, "查询成功")
}
// DeleteContactsCategories 删除通讯录分类
// @Summary 删除通讯录分类
// @Tags 短信管理-通讯录
// @Accept json
// @Produce json
// @Param request body bus_models.DeleteContactCategoryRequest true "要删除的分类ID列表"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/contacts_category/delete [post]
func (e SmsApi) DeleteContactsCategories(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.DeleteContactCategoryRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(400, err, "参数绑定失败")
return
}
err = smsService.DeleteContactsCategories(req.IDs, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
app.OK(c, nil, "删除成功")
}
// ListContacts 查询通讯录列表
// @Summary 查询通讯录列表
// @Tags 短信管理-通讯录
// @Accept json
// @Produce json
// @Param request query bus_models.ContactQuery true "查询参数"
// @Success 200 {object} bus_models.ContactQueryResp
// @Router /api/v1/sms/contacts/list [get]
func (e SmsApi) ListContacts(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.ContactQuery
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
resp, err := smsService.ListContacts(c, req, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "查询失败")
return
}
app.OK(c, resp, "查询成功")
}
// AddContact 新增联系人
// @Summary 新增联系人
// @Tags 短信管理-通讯录
// @Accept json
// @Produce json
// @Param request body bus_models.ContactInput true "联系人信息"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/contacts/add [post]
func (e SmsApi) AddContact(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.ContactInput
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 验证手机号格式(只做基础校验)
if !utils.IsValidPhone(req.PhoneNumber) {
e.Error(400, nil, "手机号格式不正确")
return
}
var birthday *time.Time
if req.BirthdayStr != "" {
t, err := time.Parse("2006-01-02", req.BirthdayStr)
if err != nil {
e.Error(400, nil, "生日格式应为 YYYY-MM-DD")
return
}
birthday = &t
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
// 遍历分类ID列表为每个分类添加联系人
for _, categoryId := range req.CategoryID {
contact := bus_models.SmsContact{
CategoryID: categoryId,
Name: req.Name,
PhoneNumber: req.PhoneNumber,
Gender: req.Gender,
Birthday: birthday,
Company: req.Company,
Address: req.Address,
Remark: req.Remark,
CooperativeName: coopName,
CooperativeNumber: coopNum,
}
err = smsService.AddContact(contact, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "新增联系人失败")
return
}
}
app.OK(c, nil, "新增联系人成功")
}
// EditContact 编辑联系人
// @Summary 编辑联系人
// @Tags 短信管理-通讯录
// @Accept json
// @Produce json
// @Param request body bus_models.EditContactInput true "联系人信息"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/contacts/edit [post]
func (e SmsApi) EditContact(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.EditContactInput
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
if req.CategoryID == 0 {
e.Error(400, nil, "分类ID不能为空")
return
}
// 手机号验证
if !utils.IsValidPhone(req.PhoneNumber) {
e.Error(400, nil, "手机号格式不正确")
return
}
// 生日格式处理
var birthday *time.Time
if req.BirthdayStr != "" {
t, err := time.Parse("2006-01-02", req.BirthdayStr)
if err != nil {
e.Error(400, nil, "生日格式应为 YYYY-MM-DD")
return
}
birthday = &t
}
userName := user.GetUserName(c)
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
e.Error(500, err, "获取合作商信息失败")
return
}
// 构造用于更新的结构体
contact := bus_models.SmsContact{
CategoryID: req.CategoryID,
Name: req.Name,
PhoneNumber: req.PhoneNumber,
Gender: req.Gender,
Birthday: birthday,
Company: req.Company,
Address: req.Address,
Remark: req.Remark,
CooperativeName: coopName,
CooperativeNumber: coopNum,
}
err = smsService.EditContact(req.ID, contact, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "编辑联系人失败")
return
}
app.OK(c, nil, "编辑联系人成功")
}
// BulkDeleteContacts 批量删除联系人
// @Summary 批量删除联系人
// @Tags 短信管理-通讯录
// @Accept json
// @Produce json
// @Param request body bus_models.ContactDeleteRequest true "删除联系人ID列表"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/contacts/batch_delete [post]
func (e SmsApi) BulkDeleteContacts(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.ContactDeleteRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = smsService.BulkDeleteContacts(req, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "批量删除联系人失败")
return
}
app.OK(c, nil, "批量删除联系人成功")
}
// BulkImportContacts 批量导入通讯录
// @Summary 批量导入通讯录
// @Tags 短信管理-通讯录
// @Accept multipart/form-data
// @Produce json
// @Param category_id formData file true "分类ID"
// @Param file formData file true "上传Excel文件"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/contacts/import [post]
func (e SmsApi) BulkImportContacts(c *gin.Context) {
smsService := bus_service.SmsService{}
err := e.MakeContext(c).
MakeOrm().
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
categoryIdStr := c.PostForm("category_id")
if categoryIdStr == "" {
e.Error(400, nil, "分类ID不能为空")
return
}
nCategoryId, err := strconv.ParseUint(categoryIdStr, 10, 64)
if err != nil {
e.Error(400, err, "分类ID格式错误")
return
}
file, err := c.FormFile("file")
if err != nil {
e.Error(400, err, "上传文件失败")
return
}
openFile, err := file.Open()
if err != nil {
e.Error(500, err, "文件打开失败")
return
}
defer openFile.Close()
userName := user.GetUserName(c)
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
e.Error(500, err, "获取合作商信息失败")
return
}
err = smsService.ImportContactsFromExcel(openFile, e.Orm, coopNum, coopName, nCategoryId)
if err != nil {
e.Error(400, err, err.Error())
return
}
app.OK(c, nil, "导入成功")
}
// BulkExportContacts 批量导出通讯录
// @Summary 批量导出通讯录
// @Tags 短信管理-通讯录
// @Accept json
// @Produce json
// @Param data body bus_models.ExportContactsRequest true "请求参数"
// @Success 200 {object} bus_models.ExportContactsResp "下载链接"
// @Router /api/v1/sms/contacts/export [post]
func (e SmsApi) BulkExportContacts(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.ExportContactsRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
url, err := smsService.ExportContactsToExcel(c, e.Orm, req)
if err != nil {
e.Error(500, err, "导出失败")
return
}
resp := bus_models.ExportContactsResp{
ExportUrl: url,
}
app.OK(c, resp, "导出成功")
}
// AddPhraseCategory 新增短语分类节点
// @Summary 新增短语分类节点
// @Tags 短信管理-通讯录-常用短语
// @Accept json
// @Produce json
// @Param request body bus_models.AddPhraseCategoryReq true "分类信息"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/phrase_category/add [post]
func (e SmsApi) AddPhraseCategory(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.AddPhraseCategoryReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
req.CooperativeNumber = coopNum
req.CooperativeName = coopName
err = smsService.AddPhraseCategory(req, e.Orm)
if err != nil {
e.Error(500, err, "添加失败")
return
}
app.OK(c, nil, "添加成功")
}
// EditPhraseCategory 编辑短语分类节点
// @Summary 编辑短语分类节点
// @Tags 短信管理-通讯录-常用短语
// @Accept json
// @Produce json
// @Param request body bus_models.EditPhraseCategoryReq true "编辑信息"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/phrase_category/edit [post]
func (e SmsApi) EditPhraseCategory(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.EditPhraseCategoryReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
req.CooperativeNumber = coopNum
req.CooperativeName = coopName
err = smsService.EditPhraseCategory(req, e.Orm)
if err != nil {
e.Error(500, err, "编辑失败")
return
}
app.OK(c, nil, "编辑成功")
}
// ListPhraseCategories 查询常用短语分类列表(树形结构)
// @Summary 查询常用短语分类树
// @Tags 短信管理-通讯录-常用短语
// @Accept json
// @Produce json
// @Param request body bus_models.ListPhraseCategoryRequest true "要删除的分类ID列表"
// @Success 200 {object} bus_models.SmsPhraseCategoryTree
// @Router /api/v1/sms/phrase_category/list [post]
func (e SmsApi) ListPhraseCategories(c *gin.Context) {
var req bus_models.ListPhraseCategoryRequest
smsService := bus_service.SmsService{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Error(500, err, err.Error())
return
}
data, err := smsService.GetPhraseCategoryTree(c, e.Orm, req.CategoryID)
if err != nil {
e.Error(500, err, "查询失败")
return
}
app.OK(c, data, "查询成功")
}
// DeletePhraseCategories 删除常用短语分类
// @Summary 删除常用短语分类
// @Tags 短信管理-通讯录-常用短语
// @Accept json
// @Produce json
// @Param request body bus_models.DeletePhraseCategoryRequest true "要删除的分类ID列表"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/phrase_category/delete [post]
func (e SmsApi) DeletePhraseCategories(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.DeletePhraseCategoryRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(400, err, "参数绑定失败")
return
}
err = smsService.DeletePhraseCategories(req.IDs, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
app.OK(c, nil, "删除成功")
}
// ListPhrases 查询常用短语列表
// @Summary 查询常用短语列表
// @Tags 短信管理-通讯录-常用短语
// @Accept json
// @Produce json
// @Param data body bus_models.SmsPhraseQuery true "短语数据"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/phrase/list [post]
func (e SmsApi) ListPhrases(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsPhraseQuery
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
resp, err := smsService.ListPhrases(c, req, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "查询失败")
return
}
app.OK(c, resp, "查询成功")
}
// AddPhrase 新增常用短语
// @Summary 新增常用短语
// @Tags 短信管理-通讯录-常用短语
// @Accept json
// @Produce json
// @Param data body bus_models.SmsPhraseAddOrEdit true "短语数据"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/phrase/add [post]
func (e SmsApi) AddPhrase(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsPhraseAddOrEdit
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
req.CooperativeNumber = coopNum
req.CooperativeName = coopName
err = smsService.AddPhrase(req, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "新增失败")
return
}
app.OK(c, nil, "新增成功")
}
// EditPhrase 编辑常用短语
// @Summary 编辑常用短语
// @Tags 短信管理-通讯录-常用短语
// @Accept json
// @Produce json
// @Param data body bus_models.SmsPhraseAddOrEdit true "短语数据"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/phrase/edit [post]
func (e SmsApi) EditPhrase(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsPhraseAddOrEdit
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
req.CooperativeNumber = coopNum
req.CooperativeName = coopName
err = smsService.EditPhrase(req, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "编辑失败")
return
}
app.OK(c, nil, "编辑成功")
}
// DeletePhrases 批量删除短语
// @Summary 批量删除短语
// @Tags 短信管理-通讯录-常用短语
// @Accept json
// @Produce json
// @Param data body bus_models.SmsPhraseBatchDeleteReq true "短语ID数组"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/phrase/delete [post]
func (e SmsApi) DeletePhrases(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsPhraseBatchDeleteReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = smsService.DeletePhrases(req.IDs, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "删除失败")
return
}
app.OK(c, nil, "删除成功")
}
// ListCommonNumbers 常用号码列表
// @Summary 常用号码列表
// @Tags 短信管理-通讯录-常用号码
// @Accept json
// @Produce json
// @Param data body bus_models.SmsCommonNumberQuery true "查询参数"
// @Success 200 {object} bus_models.SmsCommonNumberListResp
// @Router /api/v1/sms/common_number/list [post]
func (e SmsApi) ListCommonNumbers(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsCommonNumberQuery
if err := e.MakeContext(c).MakeOrm().Bind(&req, binding.JSON).MakeService(&smsService.Service).Errors; err != nil {
e.Error(500, err, err.Error())
return
}
resp, err := smsService.ListCommonNumbers(c, req, e.Orm)
if err != nil {
e.Error(500, err, "查询失败")
return
}
app.OK(c, resp, "查询成功")
}
// AddCommonNumber 添加常用号码
// @Summary 添加常用号码
// @Tags 短信管理-通讯录-常用号码
// @Accept json
// @Produce json
// @Param data body bus_models.SmsCommonNumberAddReq true "添加参数"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/common_number/add [post]
func (e SmsApi) AddCommonNumber(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsCommonNumberAddReq
if err := e.MakeContext(c).MakeOrm().Bind(&req, binding.JSON).MakeService(&smsService.Service).Errors; err != nil {
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
req.CooperativeNumber = coopNum
req.CooperativeName = coopName
err = smsService.AddCommonNumber(req, e.Orm)
if err != nil {
e.Error(500, err, "添加失败")
return
}
app.OK(c, nil, "添加成功")
}
// AppendCommonNumber 追加号码
// @Summary 追加号码
// @Tags 短信管理-通讯录-常用号码
// @Accept json
// @Produce json
// @Param data body bus_models.SmsCommonNumberAppendReq true "追加参数"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/common_number/append [post]
func (e SmsApi) AppendCommonNumber(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsCommonNumberAppendReq
if err := e.MakeContext(c).MakeOrm().Bind(&req, binding.JSON).MakeService(&smsService.Service).Errors; err != nil {
e.Error(500, err, err.Error())
return
}
err := smsService.AppendCommonNumber(req, e.Orm)
if err != nil {
e.Error(500, err, "追加失败")
return
}
app.OK(c, nil, "追加成功")
}
// CommonNumberDetail 常用号码详情
// @Summary 常用号码详情
// @Tags 短信管理-通讯录-常用号码
// @Accept json
// @Produce json
// @Param data body bus_models.SmsCommonNumberDetailReq true "常用号码详情模型"
// @Success 200 {object} bus_models.SmsCommonNumber
// @Router /api/v1/sms/common_number/detail [post]
func (e SmsApi) CommonNumberDetail(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsCommonNumberDetailReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
data, err := smsService.GetCommonNumberDetail(req.ID, e.Orm)
if err != nil {
e.Error(500, err, "获取详情失败")
return
}
app.OK(c, data, "获取成功")
}
// DeleteCommonNumbers 批量删除常用号码
// @Summary 批量删除常用号码
// @Tags 短信管理-通讯录-常用号码
// @Accept json
// @Produce json
// @Param data body bus_models.SmsCommonNumberDeleteReq true "ID列表"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/common_number/delete [post]
func (e SmsApi) DeleteCommonNumbers(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsCommonNumberDeleteReq
if err := e.MakeContext(c).MakeOrm().Bind(&req, binding.JSON).MakeService(&smsService.Service).Errors; err != nil {
e.Error(500, err, err.Error())
return
}
err := smsService.DeleteCommonNumbers(req.Ids, req.PhoneNumber, e.Orm)
if err != nil {
e.Error(500, err, "删除失败")
return
}
app.OK(c, nil, "删除成功")
}
// ExportCommonNumber 导出常用号码
// @Summary 导出常用号码
// @Tags 短信管理-通讯录-常用号码
// @Accept json
// @Produce application/octet-stream
// @Param data body bus_models.SmsCommonNumberExportReq true "ID列表"
// @Success 200 {file} bus_models.SmsCommonNumberExportResp
// @Router /api/v1/sms/common_number/export [get]
func (e SmsApi) ExportCommonNumber(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsCommonNumberExportReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
fileUrl, err := smsService.ExportCommonNumbers(c, req, e.Orm)
if err != nil {
e.Error(500, err, "导出失败")
return
}
resp := bus_models.ExportContactsResp{
ExportUrl: fileUrl,
}
app.OK(c, resp, "导出成功")
}
// AddBlacklistNumber 添加黑名单
// @Summary 添加黑名单
// @Tags 短信管理-通讯录-黑名单
// @Accept json
// @Produce json
// @Param data body bus_models.BlacklistAddReq true "黑名单添加参数"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/black_list/add [post]
func (e SmsApi) AddBlacklistNumber(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.BlacklistAddReq
if err := e.MakeContext(c).MakeOrm().Bind(&req, binding.JSON).MakeService(&smsService.Service).Errors; err != nil {
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
fmt.Println("userName is:", userName)
// 查询合作商的编号和名称
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
err = fmt.Errorf("GetCooperativeInfoByAccount error, %s", err.Error())
return
}
req.CooperativeNumber = coopNum
req.CooperativeName = coopName
if err := smsService.AddBlacklistNumber(req, e.Orm); err != nil {
e.Error(500, err, "添加失败")
return
}
app.OK(c, nil, "添加成功")
}
// ListBlacklist 黑名单列表
// @Summary 黑名单列表
// @Tags 短信管理-通讯录-黑名单
// @Accept json
// @Produce json
// @Param data body bus_models.BlacklistQuery true "查询参数"
// @Success 200 {object} bus_models.BlacklistListResp
// @Router /api/v1/sms/black_list/list [post]
func (e SmsApi) ListBlacklist(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.BlacklistQuery
if err := e.MakeContext(c).MakeOrm().Bind(&req, binding.JSON).MakeService(&smsService.Service).Errors; err != nil {
e.Error(500, err, err.Error())
return
}
resp, err := smsService.ListBlacklist(c, req, e.Orm)
if err != nil {
e.Error(500, err, "查询失败")
return
}
app.OK(c, resp, "查询成功")
}
// ExportBlacklist 批量导出黑名单
// @Summary 批量导出黑名单
// @Tags 短信管理-通讯录-黑名单
// @Accept json
// @Produce json
// @Param data body bus_models.ExportBlacklistRequest true "请求参数"
// @Success 200 {object} bus_models.ExportContactsResp "下载链接"
// @Router /api/v1/sms/black_list/export [post]
func (e SmsApi) ExportBlacklist(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.ExportBlacklistRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
url, err := smsService.ExportBlacklistToExcel(c, e.Orm, req)
if err != nil {
e.Error(500, err, "导出失败")
return
}
resp := bus_models.ExportContactsResp{
ExportUrl: url,
}
app.OK(c, resp, "导出成功")
}
// DeleteBlacklist 批量删除黑名单
// @Summary 批量删除黑名单
// @Tags 短信管理-通讯录-黑名单
// @Accept json
// @Produce json
// @Param data body bus_models.SmsBlacklistBatchDeleteReq true "黑名单ID数组"
// @Success 200 {object} app.Response
// @Router /api/v1/sms/black_list/delete [post]
func (e SmsApi) DeleteBlacklist(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsBlacklistBatchDeleteReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = smsService.DeleteBlacklist(req.IDs, e.Orm)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "删除失败")
return
}
app.OK(c, nil, "删除成功")
}
// CreateSmsTemplate 新增短信模版
// @Summary 新增短信模版
// @Description 创建一条新的短信模版,默认为待审核状态
// @Tags 短信管理-短信模版
// @Accept json
// @Produce json
// @Param request body bus_models.SmsTemplateCreateRequest true "短信模版信息"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/template/create [post]
func (e SmsApi) CreateSmsTemplate(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsTemplateCreateRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
userName := user.GetUserName(c)
coopNum, coopName, err := bus_models.GetCooperativeInfoByAccount(e.Orm, userName)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "获取合作商信息失败")
return
}
var smsTemplate bus_models.SmsTemplate
smsTemplate.CooperativeName = coopName
smsTemplate.CooperativeNumber = coopNum
smsTemplate.Content = req.Content
smsTemplate.Status = 0 // 默认待审核
smsTemplate.Remark = req.Remark
smsTemplate.ExpireAt = req.ExpireAt
if err := smsService.CreateSmsTemplate(&smsTemplate, e.Orm); err != nil {
e.Logger.Error(err)
e.Error(500, err, "创建失败")
return
}
app.OK(c, nil, "创建成功")
}
// DeleteSmsTemplates 批量删除短信模版
// @Summary 批量删除短信模版
// @Tags 短信管理-短信模版
// @Accept json
// @Produce json
// @Param request body bus_models.DeleteIdsRequest true "ID数组"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/template/delete [post]
func (e SmsApi) DeleteSmsTemplates(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.DeleteIdsRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Error(500, err, err.Error())
return
}
if err := smsService.DeleteSmsTemplates(req.IDs, e.Orm); err != nil {
e.Error(500, err, "删除失败")
return
}
app.OK(c, nil, "删除成功")
}
// UpdateSmsTemplate 修改短信模版
// @Summary 修改短信模版
// @Tags 短信管理-短信模版
// @Accept json
// @Produce json
// @Param request body bus_models.SmsTemplateUpdateRequest true "短信模版更新信息"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/template/update [post]
func (e SmsApi) UpdateSmsTemplate(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsTemplateUpdateRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Error(500, err, err.Error())
return
}
if err := smsService.UpdateSmsTemplate(&req, e.Orm); err != nil {
e.Error(500, err, "更新失败")
return
}
app.OK(c, nil, "更新成功")
}
// ApproveSmsTemplate 审核短信模版
// @Summary 审核短信模版
// @Tags 短信管理-短信模版
// @Accept json
// @Produce json
// @Param request body bus_models.ApproveTemplateRequest true "模版审核信息"
// @Success 200 {object} app.Response{msg=string}
// @Router /api/v1/sms/template/approve [post]
func (e SmsApi) ApproveSmsTemplate(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.ApproveTemplateRequest
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Error(500, err, err.Error())
return
}
if err := smsService.ApproveSmsTemplate(req.ID, req.Status, e.Orm); err != nil {
e.Error(500, err, "审核失败")
return
}
app.OK(c, nil, "审核成功")
}
// ListSmsTemplates 获取短信模版列表
// @Summary 获取短信模版列表
// @Tags 短信管理-短信模版
// @Accept json
// @Produce json
// @Param data body bus_models.SmsTemplateQuery true "查询参数"
// @Success 200 {object} bus_models.SmsTemplateListResp
// @Router /api/v1/sms/template/list [post]
func (e SmsApi) ListSmsTemplates(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsTemplateQuery
if err := e.MakeContext(c).MakeOrm().Bind(&req, binding.JSON).MakeService(&smsService.Service).Errors; err != nil {
e.Error(500, err, err.Error())
return
}
resp, err := smsService.ListSmsTemplates(c, req, e.Orm)
if err != nil {
e.Error(500, err, "查询失败")
return
}
app.OK(c, resp, "查询成功")
}
// ExportSmsTemplate 导出短信模版
// @Summary 导出短信模版
// @Tags 短信管理-短信模版
// @Accept json
// @Produce application/json
// @Param data body bus_models.SmsTemplateExportReq true "导出参数"
// @Success 200 {object} bus_models.ExportTemplateResp
// @Router /api/v1/sms/template/export [post]
func (e SmsApi) ExportSmsTemplate(c *gin.Context) {
smsService := bus_service.SmsService{}
var req bus_models.SmsTemplateExportReq
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
fileUrl, err := smsService.ExportSmsTemplates(c, req, e.Orm)
if err != nil {
e.Error(500, err, "导出失败")
return
}
app.OK(c, bus_models.ExportTemplateResp{ExportUrl: fileUrl}, "导出成功")
}
// SendMessage 发送短信
// @Summary 发送短信
// @Description 根据手机号发送短信
// @Tags 短信管理-V1.0.0
// @Accept json
// @Produce json
// @Param request body bus_models.SendMessageMassReq true "短信发送请求参数"
// @Success 200 {object} bus_models.SendMessageMassResp
// @Router /api/v1/sms/send_message [post]
func (e SmsApi) SendMessage(c *gin.Context) {
var req bus_models.SendMessageMassReq
smsService := bus_service.SmsService{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&smsService.Service).
Errors
if err != nil {
e.Logger.Error(err)
//e.Error(400, err, "参数绑定失败")
app.OK(c, bus_models.SendMessageMassResp{
Code: -1,
Msg: "参数绑定失败",
}, "OK")
return
}
// 时间戳校验3分钟内有效
nowMillis := time.Now().UnixMilli()
if nowMillis-req.Timestamp > 3*60*1000 {
//e.Error(400, nil, "时间戳已失效,请重新发起请求")
app.OK(c, bus_models.SendMessageMassResp{
Code: -8,
Msg: "时间戳已失效,请重新发起请求",
}, "OK")
return
}
// 查询账户汇总信息
var summary bus_models.SmsSummary
err = e.Orm.Where("name = ?", req.UserName).First(&summary).Error
if err != nil {
//e.Error(400, err, "未找到该账号的短信汇总信息")
app.OK(c, bus_models.SendMessageMassResp{
Code: -2,
Msg: "未找到该账号的短信汇总信息",
}, "OK")
return
}
if summary.Name == "" {
//e.Error(400, err, "未找到该账号")
app.OK(c, bus_models.SendMessageMassResp{
Code: -3,
Msg: "未找到该账号",
}, "OK")
return
}
// 检查余额
if summary.Balance <= 0 {
//e.Error(400, nil, "短信余额不足,请充值后再发送")
app.OK(c, bus_models.SendMessageMassResp{
Code: -4,
Msg: "短信余额不足,请充值后再发送",
}, "OK")
return
}
// 签名校验
expectedSign := sms.GenerateSign(req.UserName, summary.PassWord, req.Content, req.Phone, req.Timestamp)
if strings.ToLower(req.Sign) != expectedSign {
//e.Error(400, nil, "签名验证失败")
app.OK(c, bus_models.SendMessageMassResp{
Code: -5,
Msg: "签名验证失败",
}, "OK")
return
}
if req.Phone == "" || req.Content == "" {
//e.Error(400, nil, "手机号和短信内容不能为空")
app.OK(c, bus_models.SendMessageMassResp{
Code: -6,
Msg: "手机号和短信内容不能为空",
}, "OK")
return
}
var phoneList []string
phoneList = append(phoneList, req.Phone)
// 执行发送
err = sms.GtSendMessage(phoneList, req.Content)
if err != nil {
//e.Error(500, err, "短信发送失败")
app.OK(c, bus_models.SendMessageMassResp{
Code: -7,
Msg: "短信发送失败",
}, "OK")
return
}
// 更新短信使用记录
err = e.Orm.Model(&bus_models.SmsSummary{}).
Where("id = ?", summary.ID).
Updates(map[string]interface{}{
"used": gorm.Expr("used + ?", 1),
"balance": gorm.Expr("balance - ?", 1),
}).Error
if err != nil {
e.Logger.Errorf("短信发送成功,但更新短信汇总记录失败: %v", err)
}
app.OK(c, bus_models.SendMessageMassResp{
Code: 0,
Msg: "短信已发送",
}, "OK")
}
// Callback 短信状态报告回调
// @Summary 短信状态回调
// @Description 短信服务商调用此接口,推送短信发送状态
// @Tags 短信管理-V1.0.0
// @Accept json
// @Produce json
// @Param request body bus_models.SmsCallbackReq true "短信状态回调请求参数"
// @Success 200 {object} bus_models.SmsCallbackResp
// @Router /api/v1/sohan/notice [post]
func (e SmsApi) Callback(c *gin.Context) {
fmt.Printf("enter Callback")
// 读取原始请求体
bodyBytes, err := io.ReadAll(c.Request.Body)
if err != nil {
e.Logger.Error("读取回调请求体失败:", err)
fmt.Printf("读取回调请求体失败: %+v", err)
app.OK(c, bus_models.SmsCallbackResp{StatusReturn: false}, "读取请求失败")
return
}
// 重新设置 Body以便后续 Bind 使用
c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
// 打印原始请求体
fmt.Printf("收到短信回调原始请求体: %s", string(bodyBytes))
var req bus_models.SmsCallbackReq
err = e.MakeContext(c).
Bind(&req, binding.JSON).
Errors
if err != nil {
e.Logger.Error("回调参数绑定失败:", err)
app.OK(c, bus_models.SmsCallbackResp{
StatusReturn: false,
}, "参数绑定失败")
return
}
fmt.Printf("response: %+v", req)
// 打印回调内容
e.Logger.Infof("收到短信回调: phone=%s, outOrderId=%s, status=%d, receiveTime=%s, message=%v",
req.PhoneNumber, req.OutOrderID, req.SendStatus, req.ReceiveTime, req.Message)
// 返回成功
app.OK(c, bus_models.SmsCallbackResp{
StatusReturn: true,
}, "回调处理成功")
}