2025-04-11 12:15:45 +00:00
|
|
|
|
package bus_service
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
2025-04-23 10:00:14 +00:00
|
|
|
|
"encoding/csv"
|
2025-04-18 10:08:14 +00:00
|
|
|
|
"errors"
|
2025-04-11 12:15:45 +00:00
|
|
|
|
"fmt"
|
2025-05-19 07:39:05 +00:00
|
|
|
|
"github.com/gin-gonic/gin"
|
2025-04-18 10:08:14 +00:00
|
|
|
|
"github.com/go-admin-team/go-admin-core/logger"
|
2025-04-11 12:15:45 +00:00
|
|
|
|
"github.com/go-admin-team/go-admin-core/sdk/service"
|
|
|
|
|
"github.com/xuri/excelize/v2"
|
2025-05-19 07:39:05 +00:00
|
|
|
|
"go-admin/app/admin/models"
|
2025-04-11 12:15:45 +00:00
|
|
|
|
"go-admin/app/admin/models/bus_models"
|
|
|
|
|
"go-admin/common/redisx"
|
2025-05-19 07:39:05 +00:00
|
|
|
|
"go-admin/tools"
|
2025-04-11 12:15:45 +00:00
|
|
|
|
"golang.org/x/net/context"
|
|
|
|
|
"gorm.io/gorm"
|
2025-04-23 10:00:14 +00:00
|
|
|
|
"io"
|
2025-04-11 12:15:45 +00:00
|
|
|
|
"math/rand"
|
2025-04-23 10:00:14 +00:00
|
|
|
|
"os"
|
|
|
|
|
"regexp"
|
|
|
|
|
"sort"
|
2025-04-11 12:15:45 +00:00
|
|
|
|
"strconv"
|
2025-04-18 10:08:14 +00:00
|
|
|
|
"strings"
|
2025-04-11 12:15:45 +00:00
|
|
|
|
"time"
|
2025-04-18 10:08:14 +00:00
|
|
|
|
"unicode/utf8"
|
2025-04-11 12:15:45 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
maxPhonesPerShard = 10000
|
|
|
|
|
cacheExpire = time.Hour
|
2025-04-18 10:08:14 +00:00
|
|
|
|
|
|
|
|
|
TimeFormat = "2006-01-02T15:04:05+08:00"
|
|
|
|
|
|
|
|
|
|
ExportFile = "/www/server/images/export/"
|
|
|
|
|
MiGuExportUrl = "https://telecom.deovo.com/load/export/"
|
2025-04-11 12:15:45 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type SmsService struct {
|
|
|
|
|
service.Service
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadExcelFile 读取 Excel 文件并提取第一列的手机号
|
|
|
|
|
func (s *SmsService) ReadExcelFile(file []byte) ([]string, error) {
|
|
|
|
|
// 使用 excelize.OpenReader 直接从文件流读取内容
|
|
|
|
|
f, err := excelize.OpenReader(bytes.NewReader(file))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("无法打开 Excel 文件: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var phones []string
|
|
|
|
|
// 获取所有工作表列表
|
|
|
|
|
sheetList := f.GetSheetList()
|
|
|
|
|
|
|
|
|
|
if len(sheetList) == 0 {
|
|
|
|
|
return nil, fmt.Errorf("excel 文件中没有工作表")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 选择第一个工作表
|
|
|
|
|
sheet := sheetList[0]
|
|
|
|
|
rows, err := f.GetRows(sheet)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("读取 Excel 行失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 假设第一列是手机号
|
|
|
|
|
for _, row := range rows {
|
|
|
|
|
if len(row) > 0 {
|
|
|
|
|
phone := row[0]
|
|
|
|
|
phones = append(phones, phone)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return phones, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) CachePhonesByShard(importSerial string, phones []string) error {
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
|
|
total := 0
|
|
|
|
|
for i := 0; i < len(phones); i += maxPhonesPerShard {
|
|
|
|
|
end := i + maxPhonesPerShard
|
|
|
|
|
if end > len(phones) {
|
|
|
|
|
end = len(phones)
|
|
|
|
|
}
|
|
|
|
|
shard := phones[i:end]
|
|
|
|
|
total++
|
|
|
|
|
key := fmt.Sprintf("sms:import:%s:%d", importSerial, total)
|
|
|
|
|
if err := redisx.Client.RPush(ctx, key, shard).Err(); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
redisx.Client.Expire(ctx, key, cacheExpire)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存总分片数量
|
|
|
|
|
totalKey := fmt.Sprintf("sms:import:%s:total", importSerial)
|
|
|
|
|
err := redisx.Client.Set(ctx, totalKey, total, cacheExpire).Err()
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) AppendPhonesToRedis(serial string, phones []string) error {
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
|
|
// 拿当前最大分片号
|
|
|
|
|
totalKey := fmt.Sprintf("sms:import:%s:total", serial)
|
|
|
|
|
totalStr, err := redisx.Client.Get(ctx, totalKey).Result()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("无法读取缓存分片: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
total, _ := strconv.Atoi(totalStr)
|
|
|
|
|
if total == 0 {
|
|
|
|
|
return fmt.Errorf("缓存分片不存在")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 直接往最后一片中添加(你也可以按量分片再扩展)
|
|
|
|
|
lastKey := fmt.Sprintf("sms:import:%s:%d", serial, total)
|
|
|
|
|
values := make([]interface{}, len(phones))
|
|
|
|
|
for i, p := range phones {
|
|
|
|
|
values[i] = p
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = redisx.Client.RPush(ctx, lastKey, values...).Err()
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 10:08:14 +00:00
|
|
|
|
func (s *SmsService) SubmitSmsTaskFromRedis(ctx context.Context,
|
|
|
|
|
serial, content, sendTime, coopNum, coopName string) error {
|
2025-04-11 12:15:45 +00:00
|
|
|
|
// 读取分片数量
|
|
|
|
|
totalKey := fmt.Sprintf("sms:import:%s:total", serial)
|
|
|
|
|
totalStr, err := redisx.Client.Get(ctx, totalKey).Result()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("获取缓存分片数失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
total, _ := strconv.Atoi(totalStr)
|
|
|
|
|
if total == 0 {
|
|
|
|
|
return fmt.Errorf("分片数为 0,无法创建任务")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 统计总手机号数量
|
|
|
|
|
var totalPhones int
|
|
|
|
|
phoneCounts := make([]int, total)
|
|
|
|
|
for i := 1; i <= total; i++ {
|
|
|
|
|
redisKey := fmt.Sprintf("sms:import:%s:%d", serial, i)
|
|
|
|
|
count, err := redisx.Client.LLen(ctx, redisKey).Result()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("读取缓存分片 %d 失败: %v", i, err)
|
|
|
|
|
}
|
|
|
|
|
totalPhones += int(count)
|
|
|
|
|
phoneCounts[i-1] = int(count)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if totalPhones == 0 {
|
|
|
|
|
return fmt.Errorf("手机号为空,不能创建任务")
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 10:08:14 +00:00
|
|
|
|
var planTime time.Time
|
|
|
|
|
// 判断是否设置了定时发送
|
|
|
|
|
if sendTime != "" {
|
|
|
|
|
loc, _ := time.LoadLocation("Asia/Shanghai")
|
|
|
|
|
planTime, err = time.ParseInLocation(TimeFormat, sendTime, loc)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("解析时间出错:%s", err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-11 12:15:45 +00:00
|
|
|
|
// 计算短信条数(按70字分割)
|
|
|
|
|
// 短信条数计算:70字以内算1条,超过则每67字拆1条(长短信按67字分段)
|
|
|
|
|
contentCost := (len([]rune(content)) + 66) / 67
|
|
|
|
|
totalSmsCount := totalPhones * contentCost
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if coopNum != "admin" {
|
|
|
|
|
// 查询合作商余额
|
|
|
|
|
var coop bus_models.BusCooperative
|
|
|
|
|
if err := s.Orm.WithContext(ctx).Model(&bus_models.BusCooperative{}).
|
|
|
|
|
Where("cooperative_number = ?", coopNum).
|
|
|
|
|
First(&coop).Error; err != nil {
|
|
|
|
|
return fmt.Errorf("查询合作商信息失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询合作商产品价格
|
|
|
|
|
var coopProduct []bus_models.BusCooperativeProduct
|
|
|
|
|
if err := s.Orm.WithContext(ctx).Where("cooperative_id = ?", coopNum).
|
|
|
|
|
Find(&coopProduct).Error; err != nil {
|
|
|
|
|
return fmt.Errorf("查询合作商产品失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
productFlag := false
|
|
|
|
|
var productPrice float64
|
|
|
|
|
for _, item := range coopProduct {
|
|
|
|
|
var product bus_models.BusProduct
|
|
|
|
|
if err := s.Orm.WithContext(ctx).Where("id = ?", item.ProductID).First(&product).Error; err != nil {
|
|
|
|
|
return fmt.Errorf("查询产品失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if product.ProductType == 1 { // 只处理短信产品
|
|
|
|
|
productPrice = product.Price * product.Discount
|
|
|
|
|
productFlag = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !productFlag {
|
|
|
|
|
return fmt.Errorf("未配置短信产品")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算总金额
|
|
|
|
|
totalAmount := float64(totalSmsCount) * productPrice
|
|
|
|
|
|
|
|
|
|
// 检查余额是否足够
|
|
|
|
|
if coop.Balance+coop.Free < totalAmount {
|
|
|
|
|
return fmt.Errorf("账户余额不足,当前余额:%.2f 元,赠送余额:%.2f 元,需扣除:%.2f 元", coop.Balance,
|
|
|
|
|
coop.Free, totalAmount)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-11 12:15:45 +00:00
|
|
|
|
// 使用数据库事务
|
|
|
|
|
return s.Orm.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
2025-04-18 10:08:14 +00:00
|
|
|
|
|
2025-04-11 12:15:45 +00:00
|
|
|
|
// 生成批次ID
|
|
|
|
|
batchID, _ := GenerateBatchID(s.Orm)
|
|
|
|
|
|
|
|
|
|
// 插入任务
|
|
|
|
|
task := &bus_models.SmsTask{
|
2025-04-18 10:08:14 +00:00
|
|
|
|
CooperativeNumber: coopNum, // 可根据需要填充
|
|
|
|
|
CooperativeName: coopName,
|
2025-04-11 12:15:45 +00:00
|
|
|
|
BatchID: batchID,
|
|
|
|
|
ImportID: serial,
|
|
|
|
|
SmsContent: content,
|
|
|
|
|
SmsContentCost: contentCost,
|
|
|
|
|
TotalPhoneCount: totalPhones,
|
|
|
|
|
TotalSmsCount: totalSmsCount,
|
|
|
|
|
Status: 0,
|
|
|
|
|
InterceptFailCount: 0,
|
|
|
|
|
ChannelFailCount: 0,
|
2025-04-18 10:08:14 +00:00
|
|
|
|
ScheduleTime: &planTime,
|
2025-04-11 12:15:45 +00:00
|
|
|
|
}
|
|
|
|
|
if err := tx.Create(task).Error; err != nil {
|
|
|
|
|
return fmt.Errorf("创建短信任务失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 插入批次记录
|
|
|
|
|
for i := 1; i <= total; i++ {
|
|
|
|
|
batch := &bus_models.SmsTaskBatch{
|
2025-04-18 10:08:14 +00:00
|
|
|
|
CooperativeNumber: coopNum, // 可根据需要填充
|
|
|
|
|
CooperativeName: coopName,
|
|
|
|
|
TaskID: task.ID,
|
|
|
|
|
BatchID: batchID,
|
|
|
|
|
ImportID: serial,
|
|
|
|
|
Num: i,
|
|
|
|
|
PhoneCount: phoneCounts[i-1],
|
|
|
|
|
SmsCount: phoneCounts[i-1] * contentCost,
|
|
|
|
|
SmsContent: content,
|
|
|
|
|
Status: 0,
|
|
|
|
|
ScheduleTime: &planTime,
|
2025-04-11 12:15:45 +00:00
|
|
|
|
}
|
|
|
|
|
if err := tx.Create(batch).Error; err != nil {
|
|
|
|
|
return fmt.Errorf("创建批次失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ✅ 提示:不在这里生成 SmsSendRecord,后续通过消费者从 Redis 中读取批次生成
|
|
|
|
|
// 否则数据量大时会影响事务和响应速度
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GenerateBatchID 生成唯一的批次ID:日期(YYYYMMDD)+ 8位随机数(共16位)
|
|
|
|
|
func GenerateBatchID(db *gorm.DB) (string, error) {
|
|
|
|
|
// 获取当前日期(年月日)
|
|
|
|
|
dateStr := time.Now().Format("20060102") // 例如:20250411
|
|
|
|
|
|
|
|
|
|
// 生成一个8位随机数(范围:00000000 ~ 99999999)
|
|
|
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
|
randomNum := rand.Int63n(100000000) // 8位最大是1亿,即10^8
|
|
|
|
|
|
|
|
|
|
// 格式化为8位字符串(左侧补0)
|
|
|
|
|
randomNumStr := fmt.Sprintf("%08d", randomNum)
|
|
|
|
|
|
|
|
|
|
// 拼接成 batch_id
|
|
|
|
|
batchID := fmt.Sprintf("%s%s", dateStr, randomNumStr)
|
|
|
|
|
|
|
|
|
|
// 检查 sms_task 表中是否已存在该 batch_id
|
|
|
|
|
var count int64
|
|
|
|
|
err := db.Table("sms_task").Where("batch_id = ?", batchID).Count(&count).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果已存在,则递归重试
|
|
|
|
|
if count > 0 {
|
|
|
|
|
return GenerateBatchID(db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return batchID, nil
|
|
|
|
|
}
|
2025-04-18 10:08:14 +00:00
|
|
|
|
|
|
|
|
|
func (s *SmsService) ExportPhoneListToExcel(importSerial string, directPhones []string) (string, error) {
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
var allPhones []string
|
|
|
|
|
|
|
|
|
|
// 从 Redis 获取导入的号码
|
|
|
|
|
if importSerial != "" {
|
|
|
|
|
totalKey := fmt.Sprintf("sms:import:%s:total", importSerial)
|
|
|
|
|
totalStr, err := redisx.Client.Get(ctx, totalKey).Result()
|
|
|
|
|
if err == nil {
|
|
|
|
|
total, _ := strconv.Atoi(totalStr)
|
|
|
|
|
for i := 1; i <= total; i++ {
|
|
|
|
|
key := fmt.Sprintf("sms:import:%s:%d", importSerial, i)
|
|
|
|
|
shardPhones, err := redisx.Client.LRange(ctx, key, 0, -1).Result()
|
|
|
|
|
if err == nil {
|
|
|
|
|
allPhones = append(allPhones, shardPhones...)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 追加直接输入的号码
|
|
|
|
|
if len(directPhones) > 0 {
|
|
|
|
|
allPhones = append(allPhones, directPhones...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(allPhones) == 0 {
|
|
|
|
|
return "", fmt.Errorf("没有可导出的号码")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建 Excel 文件
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
sheet := "Sheet1"
|
|
|
|
|
|
|
|
|
|
for i, phone := range allPhones {
|
|
|
|
|
cell := fmt.Sprintf("A%d", i+1)
|
|
|
|
|
file.SetCellValue(sheet, cell, phone)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置样式
|
|
|
|
|
style, _ := file.NewStyle(&excelize.Style{
|
|
|
|
|
Alignment: &excelize.Alignment{
|
|
|
|
|
Horizontal: "center",
|
|
|
|
|
Vertical: "center",
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
_ = file.SetCellStyle(sheet, "A1", fmt.Sprintf("A%d", len(allPhones)), style)
|
|
|
|
|
file.SetColWidth(sheet, "A", "A", 20)
|
|
|
|
|
|
|
|
|
|
// 保存文件
|
|
|
|
|
fileName := time.Now().Format("20060102150405") + "_号码导出.xlsx"
|
|
|
|
|
url := MiGuExportUrl + fileName
|
|
|
|
|
|
|
|
|
|
if err := file.SaveAs(ExportFile + fileName); err != nil {
|
|
|
|
|
logger.Errorf("导出Excel失败: %v", err)
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return url, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CheckSensitiveWords 检查短信内容是否包含敏感词
|
|
|
|
|
func (s *SmsService) CheckSensitiveWords(content string) ([]string, error) {
|
|
|
|
|
var sensitiveWords []bus_models.SensitiveWord
|
|
|
|
|
|
|
|
|
|
err := s.Orm.Table("sensitive_words").Where("is_enabled = ?", 1).
|
|
|
|
|
Find(&sensitiveWords).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var hits []string
|
|
|
|
|
for _, sw := range sensitiveWords {
|
|
|
|
|
if strings.Contains(content, sw.Word) {
|
|
|
|
|
hits = append(hits, sw.Word)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return hits, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// QuerySmsTaskList 查询短信下行记录
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) QuerySmsTaskList(c *gin.Context, req bus_models.SmsTaskQueryRequest,
|
|
|
|
|
db *gorm.DB) (*bus_models.SmsTaskQueryResponse, error) {
|
|
|
|
|
|
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return nil, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 10:08:14 +00:00
|
|
|
|
var tasks []bus_models.SmsTask
|
|
|
|
|
var total int64
|
|
|
|
|
|
|
|
|
|
query := db.Model(&bus_models.SmsTask{}).Where("status = 2")
|
|
|
|
|
|
|
|
|
|
if req.BatchID != "" {
|
|
|
|
|
query = query.Where("batch_id = ?", req.BatchID)
|
|
|
|
|
}
|
|
|
|
|
if req.MinTotalSms > 0 {
|
|
|
|
|
query = query.Where("total_sms_count >= ?", req.MinTotalSms)
|
|
|
|
|
}
|
|
|
|
|
if req.MinPhoneCount > 0 {
|
|
|
|
|
query = query.Where("total_phone_count >= ?", req.MinPhoneCount)
|
|
|
|
|
}
|
|
|
|
|
if req.Status != nil {
|
|
|
|
|
query = query.Where("status = ?", *req.Status)
|
|
|
|
|
}
|
|
|
|
|
if req.StartTime != "" && req.EndTime != "" {
|
|
|
|
|
query = query.Where("created_at BETWEEN ? AND ?", req.StartTime, req.EndTime)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-18 10:08:14 +00:00
|
|
|
|
|
|
|
|
|
// 统计总数
|
|
|
|
|
if err := query.Count(&total).Error; err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分页处理
|
|
|
|
|
page := req.Page
|
|
|
|
|
if page < 1 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
pageSize := req.PageSize
|
|
|
|
|
if pageSize <= 0 {
|
|
|
|
|
pageSize = 10
|
|
|
|
|
}
|
|
|
|
|
offset := (page - 1) * pageSize
|
|
|
|
|
|
|
|
|
|
// 查询分页数据
|
|
|
|
|
if err := query.
|
|
|
|
|
Order("created_at DESC").
|
|
|
|
|
Limit(pageSize).
|
|
|
|
|
Offset(offset).
|
|
|
|
|
Find(&tasks).Error; err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalPage := int((total + int64(pageSize) - 1) / int64(pageSize))
|
|
|
|
|
if totalPage < 1 {
|
|
|
|
|
totalPage = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &bus_models.SmsTaskQueryResponse{
|
|
|
|
|
List: tasks,
|
|
|
|
|
Total: total,
|
|
|
|
|
Page: page,
|
|
|
|
|
PageSize: pageSize,
|
|
|
|
|
TotalPage: totalPage,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) QuerySmsSendRecords(c *gin.Context, req bus_models.SmsSendRecordQueryReq) (
|
|
|
|
|
bus_models.SmsSendRecordQueryResp, error) {
|
2025-04-18 10:08:14 +00:00
|
|
|
|
var resp bus_models.SmsSendRecordQueryResp
|
2025-05-19 07:39:05 +00:00
|
|
|
|
|
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return resp, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return resp, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 10:08:14 +00:00
|
|
|
|
db := s.Orm.Model(&bus_models.SmsSendRecord{})
|
|
|
|
|
|
|
|
|
|
if req.BatchID != "" {
|
|
|
|
|
db = db.Where("batch_id = ?", req.BatchID)
|
|
|
|
|
}
|
|
|
|
|
if req.Phone != "" {
|
|
|
|
|
db = db.Where("phone = ?", req.Phone)
|
|
|
|
|
}
|
|
|
|
|
if req.SmsCode != "" {
|
|
|
|
|
db = db.Where("sms_code = ?", req.SmsCode)
|
|
|
|
|
}
|
|
|
|
|
if req.StartTime != "" {
|
|
|
|
|
db = db.Where("receive_time >= ?", req.StartTime)
|
|
|
|
|
}
|
|
|
|
|
if req.EndTime != "" {
|
|
|
|
|
db = db.Where("receive_time <= ?", req.EndTime)
|
|
|
|
|
}
|
|
|
|
|
if req.MinSegments > 0 {
|
|
|
|
|
// 计算短信计费条数的粗略估算:每67字1条,注意实际可以存字段
|
|
|
|
|
db = db.Where("(length(sms_content) / 67) + 1 >= ?", req.MinSegments)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
db = db.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-18 10:08:14 +00:00
|
|
|
|
|
|
|
|
|
err := db.Count(&resp.Total).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分页处理
|
|
|
|
|
page := req.Page
|
|
|
|
|
if page < 1 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
pageSize := req.PageSize
|
|
|
|
|
if pageSize <= 0 {
|
|
|
|
|
pageSize = 10
|
|
|
|
|
}
|
|
|
|
|
offset := (page - 1) * pageSize
|
|
|
|
|
|
|
|
|
|
// 查询分页数据
|
|
|
|
|
if err = db.
|
|
|
|
|
Order("created_at DESC").
|
|
|
|
|
Limit(pageSize).
|
|
|
|
|
Offset(offset).
|
|
|
|
|
Find(&resp.List).Error; err != nil {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalPage := int((resp.Total + int64(pageSize) - 1) / int64(pageSize))
|
|
|
|
|
if totalPage < 1 {
|
|
|
|
|
totalPage = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp.Page = page
|
|
|
|
|
resp.PageSize = pageSize
|
|
|
|
|
resp.TotalPage = totalPage
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPhonesFromCache 获取导入手机号前 limit 条
|
|
|
|
|
func (s *SmsService) GetPhonesFromCache(importSerial string, limit int) ([]string, error) {
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
totalKey := fmt.Sprintf("sms:import:%s:total", importSerial)
|
|
|
|
|
totalStr, err := redisx.Client.Get(ctx, totalKey).Result()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalShards, err := strconv.Atoi(totalStr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result := make([]string, 0, limit)
|
|
|
|
|
for i := 1; i <= totalShards; i++ {
|
|
|
|
|
key := fmt.Sprintf("sms:import:%s:%d", importSerial, i)
|
|
|
|
|
phones, err := redisx.Client.LRange(ctx, key, 0, -1).Result()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
result = append(result, phones...)
|
|
|
|
|
if len(result) >= limit {
|
|
|
|
|
return result[:limit], nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetSentPhonesByBatchID 从数据库查询已发送的手机号,最多返回 limit 条
|
|
|
|
|
func (s *SmsService) GetSentPhonesByBatchID(db *gorm.DB, batchID string, limit int) ([]string, error) {
|
|
|
|
|
var records []bus_models.SmsSendRecord
|
|
|
|
|
err := db.
|
|
|
|
|
Where("batch_id = ?", batchID).
|
|
|
|
|
Order("id DESC").
|
|
|
|
|
Limit(limit).
|
|
|
|
|
Find(&records).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var phones []string
|
|
|
|
|
for _, record := range records {
|
|
|
|
|
phones = append(phones, record.Phone)
|
|
|
|
|
}
|
|
|
|
|
return phones, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// QueryScheduledSmsTaskList 查询定时短信任务
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) QueryScheduledSmsTaskList(c *gin.Context, req bus_models.SmsTaskScheduledQueryRequest,
|
|
|
|
|
db *gorm.DB) (*bus_models.SmsTaskQueryResponse, error) {
|
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return nil, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 10:08:14 +00:00
|
|
|
|
var tasks []bus_models.SmsTask
|
|
|
|
|
var total int64
|
|
|
|
|
|
|
|
|
|
query := db.Model(&bus_models.SmsTask{}).
|
|
|
|
|
Where("schedule_time IS NOT NULL").
|
|
|
|
|
Where("status = ?", 0)
|
|
|
|
|
|
|
|
|
|
if req.StartTime != "" && req.EndTime != "" {
|
|
|
|
|
query = query.Where("schedule_time BETWEEN ? AND ?", req.StartTime, req.EndTime)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-18 10:08:14 +00:00
|
|
|
|
|
|
|
|
|
// 统计总数
|
|
|
|
|
if err := query.Count(&total).Error; err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分页处理
|
|
|
|
|
page := req.Page
|
|
|
|
|
if page < 1 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
pageSize := req.PageSize
|
|
|
|
|
if pageSize <= 0 {
|
|
|
|
|
pageSize = 10
|
|
|
|
|
}
|
|
|
|
|
offset := (page - 1) * pageSize
|
|
|
|
|
|
|
|
|
|
if err := query.
|
|
|
|
|
Order("schedule_time ASC").
|
|
|
|
|
Limit(pageSize).
|
|
|
|
|
Offset(offset).
|
|
|
|
|
Find(&tasks).Error; err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalPage := int((total + int64(pageSize) - 1) / int64(pageSize))
|
|
|
|
|
if totalPage < 1 {
|
|
|
|
|
totalPage = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &bus_models.SmsTaskQueryResponse{
|
|
|
|
|
List: tasks,
|
|
|
|
|
Total: total,
|
|
|
|
|
Page: page,
|
|
|
|
|
PageSize: pageSize,
|
|
|
|
|
TotalPage: totalPage,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) QuerySmsUplinkList(c *gin.Context, req bus_models.SmsUplinkQueryRequest,
|
|
|
|
|
db *gorm.DB) (bus_models.SmsUplinkQueryResponse, error) {
|
2025-04-18 10:08:14 +00:00
|
|
|
|
var resp bus_models.SmsUplinkQueryResponse
|
|
|
|
|
var total int64
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return resp, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return resp, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 10:08:14 +00:00
|
|
|
|
query := db.Table("sms_uplink_log AS uplink").
|
|
|
|
|
Select(`
|
|
|
|
|
uplink.id AS uplink_id,
|
|
|
|
|
uplink.phone_number,
|
|
|
|
|
sr.id AS send_id,
|
|
|
|
|
sr.sms_content,
|
|
|
|
|
uplink.reply_content,
|
|
|
|
|
uplink.created_at AS receive_time,
|
|
|
|
|
sr.created_at AS send_time
|
|
|
|
|
`).
|
|
|
|
|
Joins("LEFT JOIN sms_send_record sr ON uplink.batch_id = sr.batch_id AND uplink.phone_number = sr.phone")
|
|
|
|
|
|
|
|
|
|
// 条件拼接
|
|
|
|
|
if req.PhoneNumber != "" {
|
|
|
|
|
query = query.Where("uplink.phone_number LIKE ?", "%"+req.PhoneNumber+"%")
|
|
|
|
|
}
|
|
|
|
|
if req.SendID > 0 {
|
|
|
|
|
query = query.Where("sr.id = ?", req.SendID)
|
|
|
|
|
}
|
|
|
|
|
if req.UplinkID > 0 {
|
|
|
|
|
query = query.Where("uplink.id = ?", req.UplinkID)
|
|
|
|
|
}
|
|
|
|
|
if req.ReplyContent != "" {
|
|
|
|
|
query = query.Where("uplink.reply_content LIKE ?", "%"+req.ReplyContent+"%")
|
|
|
|
|
}
|
|
|
|
|
if req.StartTime != "" && req.EndTime != "" {
|
|
|
|
|
query = query.Where("uplink.created_at BETWEEN ? AND ?", req.StartTime, req.EndTime)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("sr.cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-18 10:08:14 +00:00
|
|
|
|
|
|
|
|
|
// 统计总数
|
|
|
|
|
if err := query.Count(&total).Error; err != nil {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分页处理
|
|
|
|
|
page := req.Page
|
|
|
|
|
if page <= 0 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
pageSize := req.PageSize
|
|
|
|
|
if pageSize <= 0 {
|
|
|
|
|
pageSize = 10
|
|
|
|
|
}
|
|
|
|
|
offset := (page - 1) * pageSize
|
|
|
|
|
|
|
|
|
|
var results []bus_models.SmsUplinkRecordResponse
|
|
|
|
|
// 查询数据
|
|
|
|
|
err := query.Order("uplink.created_at DESC").Limit(pageSize).Offset(offset).Scan(&results).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp.List = results
|
|
|
|
|
resp.Total = total
|
|
|
|
|
resp.Page = page
|
|
|
|
|
resp.PageSize = pageSize
|
|
|
|
|
resp.TotalPage = (total + int64(page) - 1) / int64(pageSize)
|
|
|
|
|
if resp.TotalPage < 1 {
|
|
|
|
|
resp.TotalPage = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// BatchUpdateSmsContent 修改短信内容
|
|
|
|
|
func (s *SmsService) BatchUpdateSmsContent(req bus_models.BatchUpdateSmsContentRequest, db *gorm.DB) error {
|
|
|
|
|
// 计算短信内容消耗(每70字符1条,超出部分算1条)
|
|
|
|
|
runeCount := utf8.RuneCountInString(req.SmsContent)
|
|
|
|
|
smsCost := runeCount / 70
|
|
|
|
|
if runeCount%70 != 0 {
|
|
|
|
|
smsCost++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 批量更新 SmsTask
|
|
|
|
|
if err := db.Model(&bus_models.SmsTask{}).
|
|
|
|
|
Where("id IN ?", req.TaskIDs).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"sms_content": req.SmsContent,
|
|
|
|
|
"sms_content_cost": smsCost,
|
|
|
|
|
}).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 同步更新 SmsTaskBatch 中相应内容
|
|
|
|
|
if err := db.Model(&bus_models.SmsTaskBatch{}).
|
|
|
|
|
Where("task_id IN ?", req.TaskIDs).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"sms_content": req.SmsContent,
|
|
|
|
|
}).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) BatchCancelSmsTasks(req bus_models.BatchUpdateRequest, db *gorm.DB) error {
|
|
|
|
|
if len(req.TaskIDs) == 0 {
|
|
|
|
|
return errors.New("任务ID列表不能为空")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 取消任务状态为 4(取消)
|
|
|
|
|
if err := db.Model(&bus_models.SmsTask{}).
|
|
|
|
|
Where("id IN ?", req.TaskIDs).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"status": 4,
|
|
|
|
|
}).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 同步取消子任务
|
|
|
|
|
if err := db.Model(&bus_models.SmsTaskBatch{}).
|
|
|
|
|
Where("task_id IN ?", req.TaskIDs).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"status": 4,
|
|
|
|
|
}).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// BatchResetScheduleTime 批量重置定时时间
|
|
|
|
|
func (s *SmsService) BatchResetScheduleTime(req bus_models.BatchResetScheduleTimeRequest, db *gorm.DB) error {
|
|
|
|
|
if len(req.TaskIDs) == 0 || req.ScheduleTime == "" {
|
|
|
|
|
return errors.New("任务ID和定时时间不能为空")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var planTime time.Time
|
|
|
|
|
var err error
|
|
|
|
|
// 判断是否设置了定时发送
|
|
|
|
|
if req.ScheduleTime != "" {
|
|
|
|
|
loc, _ := time.LoadLocation("Asia/Shanghai")
|
|
|
|
|
planTime, err = time.ParseInLocation(TimeFormat, req.ScheduleTime, loc)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("解析时间出错:%s", err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新 SmsTask
|
|
|
|
|
if err := db.Model(&bus_models.SmsTask{}).
|
|
|
|
|
Where("id IN ?", req.TaskIDs).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"schedule_time": planTime,
|
|
|
|
|
}).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 同步更新 SmsTaskBatch
|
|
|
|
|
if err := db.Model(&bus_models.SmsTaskBatch{}).
|
|
|
|
|
Where("task_id IN ?", req.TaskIDs).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"schedule_time": planTime,
|
|
|
|
|
}).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CreateSignatureRealname 创建签名实名制记录
|
|
|
|
|
func (s *SmsService) CreateSignatureRealname(data *bus_models.SmsSignatureRealname, db *gorm.DB) error {
|
|
|
|
|
return db.Create(data).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdateSignatureRealname 编辑签名实名制记录
|
|
|
|
|
func (s *SmsService) UpdateSignatureRealname(data *bus_models.SmsSignatureRealname, db *gorm.DB) error {
|
|
|
|
|
if data.ID == 0 {
|
|
|
|
|
return errors.New("ID不能为空")
|
|
|
|
|
}
|
|
|
|
|
return db.Model(&bus_models.SmsSignatureRealname{}).
|
|
|
|
|
Where("id = ?", data.ID).
|
|
|
|
|
Updates(data).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// BatchDeleteSignatureRealname 删除签名实名制记录
|
|
|
|
|
func (s *SmsService) BatchDeleteSignatureRealname(ids []uint, db *gorm.DB) error {
|
|
|
|
|
if len(ids) == 0 {
|
|
|
|
|
return errors.New("删除ID列表不能为空")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return db.Where("id IN ?", ids).Delete(&bus_models.SmsSignatureRealname{}).Error
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) ListSignatureRealname(c *gin.Context, req bus_models.SignatureRealnameQuery,
|
|
|
|
|
db *gorm.DB) (bus_models.SignatureRealnameQueryResp, error) {
|
2025-04-18 10:08:14 +00:00
|
|
|
|
var resp bus_models.SignatureRealnameQueryResp
|
|
|
|
|
var list []bus_models.SmsSignatureRealname
|
|
|
|
|
var total int64
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return resp, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return resp, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 10:08:14 +00:00
|
|
|
|
query := db.Model(&bus_models.SmsSignatureRealname{})
|
|
|
|
|
|
|
|
|
|
if req.Signature != "" {
|
|
|
|
|
query = query.Where("signature LIKE ?", "%"+req.Signature+"%")
|
|
|
|
|
}
|
|
|
|
|
if req.CooperativeName != "" {
|
|
|
|
|
query = query.Where("cooperative_name LIKE ?", "%"+req.CooperativeName+"%")
|
|
|
|
|
}
|
|
|
|
|
if req.CompanyName != "" {
|
|
|
|
|
query = query.Where("company_name LIKE ?", "%"+req.CompanyName+"%")
|
|
|
|
|
}
|
|
|
|
|
if req.CompanyCreditCode != "" {
|
|
|
|
|
query = query.Where("company_credit_code LIKE ?", "%"+req.CompanyCreditCode+"%")
|
|
|
|
|
}
|
|
|
|
|
if req.ResponsibleName != "" {
|
|
|
|
|
query = query.Where("responsible_name LIKE ?", "%"+req.ResponsibleName+"%")
|
|
|
|
|
}
|
|
|
|
|
if req.UsageCategory != 0 {
|
|
|
|
|
query = query.Where("usage_category = ?", req.UsageCategory)
|
|
|
|
|
}
|
|
|
|
|
if req.IsActive != 0 {
|
|
|
|
|
query = query.Where("is_active = ?", req.IsActive)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-18 10:08:14 +00:00
|
|
|
|
|
|
|
|
|
// 获取总条数
|
|
|
|
|
err := query.Count(&total).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分页处理
|
|
|
|
|
page := req.Page
|
|
|
|
|
if page <= 0 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
pageSize := req.PageSize
|
|
|
|
|
if pageSize <= 0 {
|
|
|
|
|
pageSize = 10
|
|
|
|
|
}
|
|
|
|
|
offset := (page - 1) * pageSize
|
|
|
|
|
|
|
|
|
|
// 分页查询
|
|
|
|
|
err = query.Order("id desc").
|
|
|
|
|
Offset(offset).
|
|
|
|
|
Limit(pageSize).
|
|
|
|
|
Find(&list).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建分页响应
|
|
|
|
|
totalPage := (total + int64(pageSize) - 1) / int64(pageSize)
|
|
|
|
|
if totalPage < 1 {
|
|
|
|
|
totalPage = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp = bus_models.SignatureRealnameQueryResp{
|
|
|
|
|
List: list,
|
|
|
|
|
Total: total,
|
|
|
|
|
Page: page,
|
|
|
|
|
PageSize: pageSize,
|
|
|
|
|
TotalPage: totalPage,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) ListContacts(c *gin.Context, req bus_models.ContactQuery,
|
|
|
|
|
db *gorm.DB) (bus_models.ContactQueryResp, error) {
|
2025-04-18 10:08:14 +00:00
|
|
|
|
var resp bus_models.ContactQueryResp
|
|
|
|
|
var list []bus_models.SmsContact
|
|
|
|
|
var total int64
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return resp, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return resp, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 10:08:14 +00:00
|
|
|
|
query := db.Model(&bus_models.SmsContact{})
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
if len(req.CategoryID) != 0 {
|
|
|
|
|
query = query.Where("category_id IN ?", req.CategoryID)
|
|
|
|
|
}
|
2025-04-18 10:08:14 +00:00
|
|
|
|
if req.Name != "" {
|
|
|
|
|
query = query.Where("name LIKE ?", "%"+req.Name+"%")
|
|
|
|
|
}
|
|
|
|
|
if req.PhoneNumber != "" {
|
|
|
|
|
query = query.Where("phone_number LIKE ?", "%"+req.PhoneNumber+"%")
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-18 10:08:14 +00:00
|
|
|
|
|
|
|
|
|
err := query.Count(&total).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
page := req.Page
|
|
|
|
|
if page <= 0 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
pageSize := req.PageSize
|
|
|
|
|
if pageSize <= 0 {
|
|
|
|
|
pageSize = 10
|
|
|
|
|
}
|
|
|
|
|
offset := (page - 1) * pageSize
|
|
|
|
|
|
|
|
|
|
err = query.Order("id desc").
|
|
|
|
|
Offset(offset).
|
|
|
|
|
Limit(pageSize).
|
|
|
|
|
Find(&list).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalPage := (total + int64(pageSize) - 1) / int64(pageSize)
|
|
|
|
|
if totalPage < 1 {
|
|
|
|
|
totalPage = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp = bus_models.ContactQueryResp{
|
|
|
|
|
List: list,
|
|
|
|
|
Total: total,
|
|
|
|
|
Page: page,
|
|
|
|
|
PageSize: pageSize,
|
|
|
|
|
TotalPage: totalPage,
|
|
|
|
|
}
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddContact 添加联系人
|
|
|
|
|
func (s *SmsService) AddContact(contact bus_models.SmsContact, db *gorm.DB) error {
|
|
|
|
|
return db.Create(&contact).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// EditContact 编辑联系人
|
2025-04-23 10:00:14 +00:00
|
|
|
|
func (s *SmsService) EditContact(id uint64, contact bus_models.SmsContact, db *gorm.DB) error {
|
2025-04-18 10:08:14 +00:00
|
|
|
|
var existingContact bus_models.SmsContact
|
|
|
|
|
if err := db.Where("id = ?", id).First(&existingContact).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新联系人字段
|
|
|
|
|
existingContact.Name = contact.Name
|
|
|
|
|
existingContact.PhoneNumber = contact.PhoneNumber
|
|
|
|
|
existingContact.Gender = contact.Gender
|
|
|
|
|
existingContact.Birthday = contact.Birthday
|
|
|
|
|
existingContact.Company = contact.Company
|
|
|
|
|
existingContact.Address = contact.Address
|
|
|
|
|
existingContact.Remark = contact.Remark
|
|
|
|
|
existingContact.CooperativeName = contact.CooperativeName
|
|
|
|
|
existingContact.CooperativeNumber = contact.CooperativeNumber
|
|
|
|
|
|
|
|
|
|
return db.Save(&existingContact).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// BulkDeleteContacts 批量删除联系人
|
|
|
|
|
func (s *SmsService) BulkDeleteContacts(req bus_models.ContactDeleteRequest, db *gorm.DB) error {
|
|
|
|
|
return db.Where("id IN (?)", req.ContactIDs).Delete(&bus_models.SmsContact{}).Error
|
|
|
|
|
}
|
2025-04-23 10:00:14 +00:00
|
|
|
|
|
|
|
|
|
// ImportContactsFromExcel 从Excel导入联系人(含格式校验)
|
|
|
|
|
func (s *SmsService) ImportContactsFromExcel(r io.Reader, db *gorm.DB, coopNum, coopName string, categoryId uint64) error {
|
|
|
|
|
excelFile, err := excelize.OpenReader(r)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return errors.New("解析Excel失败")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rows, err := excelFile.GetRows("Sheet1")
|
|
|
|
|
if err != nil || len(rows) < 2 {
|
|
|
|
|
return errors.New("excel格式错误或无有效数据")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var contacts []bus_models.SmsContact
|
|
|
|
|
for i, row := range rows {
|
|
|
|
|
if i == 0 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(row) < 7 {
|
|
|
|
|
// 如果一行少于7个字段,补充缺失字段为空字符串或默认值
|
|
|
|
|
for len(row) < 7 {
|
|
|
|
|
row = append(row, "")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
phone := strings.TrimSpace(row[3])
|
|
|
|
|
if !isValidPhoneNumber(phone) {
|
|
|
|
|
return fmt.Errorf("第 %d 行手机号码格式不正确: %s", i+1, phone)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
birthday, err := parseExcelDate(row[4])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("第 %d 行生日格式不正确,应为YYYY-MM-DD: %s", i+1, row[4])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
contacts = append(contacts, bus_models.SmsContact{
|
|
|
|
|
CategoryID: categoryId,
|
|
|
|
|
CooperativeNumber: coopNum,
|
|
|
|
|
CooperativeName: coopName,
|
|
|
|
|
Name: strings.TrimSpace(row[0]),
|
|
|
|
|
Company: strings.TrimSpace(row[1]),
|
|
|
|
|
Gender: strings.TrimSpace(row[2]),
|
|
|
|
|
PhoneNumber: phone,
|
|
|
|
|
Birthday: birthday,
|
|
|
|
|
Address: strings.TrimSpace(row[5]),
|
|
|
|
|
Remark: strings.TrimSpace(row[6]),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(contacts) == 0 {
|
|
|
|
|
return errors.New("无有效联系人记录")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = db.Create(&contacts).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return errors.New("导入失败:" + err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func isValidPhoneNumber(phone string) bool {
|
|
|
|
|
match, _ := regexp.MatchString(`^1\d{10}$`, phone)
|
|
|
|
|
return match
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseExcelDate(dateStr string) (*time.Time, error) {
|
|
|
|
|
if dateStr == "" {
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
layouts := []string{"2006-01-02", "2006/01/02"}
|
|
|
|
|
for _, layout := range layouts {
|
|
|
|
|
if t, err := time.Parse(layout, dateStr); err == nil {
|
|
|
|
|
return &t, nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("日期格式不正确")
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) ExportContactsToExcel(c *gin.Context, db *gorm.DB,
|
|
|
|
|
req bus_models.ExportContactsRequest) (string, error) {
|
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return "", errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
var contacts []bus_models.SmsContact
|
|
|
|
|
query := db.Order("id desc")
|
|
|
|
|
|
|
|
|
|
if !req.All {
|
|
|
|
|
if len(req.IDs) == 0 {
|
|
|
|
|
return "", fmt.Errorf("未传入ID且未选择导出全部")
|
|
|
|
|
}
|
|
|
|
|
query = query.Where("id IN ?", req.IDs)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-23 10:00:14 +00:00
|
|
|
|
|
|
|
|
|
if err := query.Find(&contacts).Error; err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(contacts) == 0 {
|
|
|
|
|
return "", fmt.Errorf("没有可导出的联系人")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
sheet := "Sheet1"
|
|
|
|
|
headers := []string{"姓名", "公司", "性别", "手机号码", "生日", "地址", "备注"}
|
|
|
|
|
|
|
|
|
|
// 表头
|
|
|
|
|
for i, h := range headers {
|
|
|
|
|
col := string('A' + i)
|
|
|
|
|
file.SetCellValue(sheet, col+"1", h)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 内容
|
|
|
|
|
for i, c := range contacts {
|
|
|
|
|
row := i + 2
|
|
|
|
|
file.SetCellValue(sheet, "A"+strconv.Itoa(row), c.Name)
|
|
|
|
|
file.SetCellValue(sheet, "B"+strconv.Itoa(row), c.Company)
|
|
|
|
|
file.SetCellValue(sheet, "C"+strconv.Itoa(row), c.Gender)
|
|
|
|
|
file.SetCellValue(sheet, "D"+strconv.Itoa(row), c.PhoneNumber)
|
|
|
|
|
if c.Birthday != nil {
|
|
|
|
|
file.SetCellValue(sheet, "E"+strconv.Itoa(row), c.Birthday.Format("2006-01-02"))
|
|
|
|
|
}
|
|
|
|
|
file.SetCellValue(sheet, "F"+strconv.Itoa(row), c.Address)
|
|
|
|
|
file.SetCellValue(sheet, "G"+strconv.Itoa(row), c.Remark)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
style, _ := file.NewStyle(&excelize.Style{
|
|
|
|
|
Alignment: &excelize.Alignment{
|
|
|
|
|
Horizontal: "center",
|
|
|
|
|
Vertical: "center",
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
file.SetColWidth(sheet, "A", "G", 20)
|
|
|
|
|
file.SetCellStyle(sheet, "A1", fmt.Sprintf("G%d", len(contacts)+1), style)
|
|
|
|
|
|
|
|
|
|
// 保存文件
|
|
|
|
|
fileName := time.Now().Format("20060102150405") + "_导出通讯录.xlsx"
|
|
|
|
|
filePath := ExportFile + fileName
|
|
|
|
|
fileUrl := MiGuExportUrl + fileName
|
|
|
|
|
|
|
|
|
|
if err := file.SaveAs(filePath); err != nil {
|
|
|
|
|
logger.Errorf("导出通讯录失败: %v", err)
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fileUrl, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) AddPhraseCategory(req bus_models.AddPhraseCategoryReq, db *gorm.DB) error {
|
|
|
|
|
return db.Create(&bus_models.SmsPhraseCategory{
|
2025-05-19 07:39:05 +00:00
|
|
|
|
Name: req.Name,
|
|
|
|
|
ParentID: uint64(req.ParentID),
|
|
|
|
|
CooperativeNumber: req.CooperativeNumber,
|
|
|
|
|
CooperativeName: req.CooperativeName,
|
2025-04-23 10:00:14 +00:00
|
|
|
|
}).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) EditPhraseCategory(req bus_models.EditPhraseCategoryReq, db *gorm.DB) error {
|
|
|
|
|
return db.Model(&bus_models.SmsPhraseCategory{}).
|
|
|
|
|
Where("id = ?", req.ID).
|
2025-05-19 07:39:05 +00:00
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"name": req.Name,
|
|
|
|
|
"cooperative_number": req.CooperativeNumber,
|
|
|
|
|
"cooperative_name": req.CooperativeName,
|
|
|
|
|
}).Error
|
2025-04-23 10:00:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) DeletePhraseCategories(ids []uint, db *gorm.DB) error {
|
|
|
|
|
if len(ids) == 0 {
|
|
|
|
|
return errors.New("未指定需要删除的分类")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var total int64
|
|
|
|
|
if err := db.Model(&bus_models.SmsPhraseCategory{}).Count(&total).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 递归找出所有要删除的 ID(含子分类)
|
|
|
|
|
var allIDs []uint
|
|
|
|
|
var walk func(uint)
|
|
|
|
|
walk = func(parentID uint) {
|
|
|
|
|
var children []bus_models.SmsPhraseCategory
|
|
|
|
|
db.Where("parent_id = ?", parentID).Find(&children)
|
|
|
|
|
for _, child := range children {
|
|
|
|
|
allIDs = append(allIDs, uint(child.ID))
|
|
|
|
|
walk(uint(child.ID))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, id := range ids {
|
|
|
|
|
allIDs = append(allIDs, id)
|
|
|
|
|
walk(id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保证删除后至少保留一个分类节点
|
|
|
|
|
if len(allIDs) >= int(total) {
|
|
|
|
|
return errors.New("无法删除所有分类节点,至少保留一个")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除短语
|
|
|
|
|
if err := db.Where("category_id IN ?", allIDs).Delete(&bus_models.SmsPhrase{}).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除分类
|
|
|
|
|
return db.Where("id IN ?", allIDs).Delete(&bus_models.SmsPhraseCategory{}).Error
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) ListPhrases(c *gin.Context, req bus_models.SmsPhraseQuery, db *gorm.DB) (
|
|
|
|
|
bus_models.SmsPhraseListResp, error) {
|
2025-04-23 10:00:14 +00:00
|
|
|
|
var list []bus_models.SmsPhrase
|
|
|
|
|
var total int64
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.SmsPhraseListResp{}, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return bus_models.SmsPhraseListResp{}, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
query := db.Model(&bus_models.SmsPhrase{})
|
|
|
|
|
|
|
|
|
|
if req.Content != "" {
|
|
|
|
|
query = query.Where("content LIKE ?", "%"+req.Content+"%")
|
|
|
|
|
}
|
|
|
|
|
if req.CategoryID != 0 {
|
|
|
|
|
query = query.Where("category_id = ?", req.CategoryID)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-23 10:00:14 +00:00
|
|
|
|
|
|
|
|
|
err := query.Count(&total).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.SmsPhraseListResp{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理分页
|
|
|
|
|
page := req.Page
|
|
|
|
|
if page < 1 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
pageSize := req.PageSize
|
|
|
|
|
if pageSize <= 0 {
|
|
|
|
|
pageSize = 10
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = query.Order("id desc").
|
|
|
|
|
Offset((page - 1) * pageSize).
|
|
|
|
|
Limit(pageSize).
|
|
|
|
|
Find(&list).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.SmsPhraseListResp{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bus_models.SmsPhraseListResp{
|
|
|
|
|
List: list,
|
|
|
|
|
Total: total,
|
|
|
|
|
Page: page,
|
|
|
|
|
PageSize: pageSize,
|
|
|
|
|
TotalPage: (total + int64(pageSize) - 1) / int64(pageSize),
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddPhrase 新增
|
|
|
|
|
func (s *SmsService) AddPhrase(req bus_models.SmsPhraseAddOrEdit, db *gorm.DB) error {
|
|
|
|
|
phrase := bus_models.SmsPhrase{
|
2025-05-19 07:39:05 +00:00
|
|
|
|
Content: req.Content,
|
|
|
|
|
CategoryID: req.CategoryID,
|
|
|
|
|
CooperativeNumber: req.CooperativeNumber,
|
|
|
|
|
CooperativeName: req.CooperativeName,
|
2025-04-23 10:00:14 +00:00
|
|
|
|
}
|
|
|
|
|
return db.Create(&phrase).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// EditPhrase 编辑
|
|
|
|
|
func (s *SmsService) EditPhrase(req bus_models.SmsPhraseAddOrEdit, db *gorm.DB) error {
|
|
|
|
|
return db.Model(&bus_models.SmsPhrase{}).
|
|
|
|
|
Where("id = ?", req.ID).
|
|
|
|
|
Updates(map[string]interface{}{
|
2025-05-19 07:39:05 +00:00
|
|
|
|
"content": req.Content,
|
|
|
|
|
"category_id": req.CategoryID,
|
|
|
|
|
"cooperative_number": req.CooperativeNumber,
|
|
|
|
|
"cooperative_name": req.CooperativeName,
|
2025-04-23 10:00:14 +00:00
|
|
|
|
}).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeletePhrases 批量删除
|
|
|
|
|
func (s *SmsService) DeletePhrases(ids []uint, db *gorm.DB) error {
|
|
|
|
|
return db.Where("id IN (?)", ids).Delete(&bus_models.SmsPhrase{}).Error
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) GetPhraseCategoryTree(c *gin.Context, db *gorm.DB, parentID uint64) (
|
|
|
|
|
[]bus_models.SmsPhraseCategoryTree, error) {
|
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return []bus_models.SmsPhraseCategoryTree{}, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return []bus_models.SmsPhraseCategoryTree{}, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query := db.Table("sms_phrase_category")
|
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
var categories []bus_models.SmsPhraseCategory
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if err := query.Find(&categories).Error; err != nil {
|
2025-04-23 10:00:14 +00:00
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建 map[id]category
|
|
|
|
|
idMap := make(map[uint64]*bus_models.SmsPhraseCategoryTree)
|
|
|
|
|
for _, cat := range categories {
|
|
|
|
|
node := &bus_models.SmsPhraseCategoryTree{
|
|
|
|
|
ID: cat.ID,
|
|
|
|
|
Name: cat.Name,
|
|
|
|
|
ParentID: cat.ParentID,
|
|
|
|
|
}
|
|
|
|
|
idMap[cat.ID] = node
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建树结构
|
|
|
|
|
for _, node := range idMap {
|
|
|
|
|
if parent, ok := idMap[node.ParentID]; ok {
|
|
|
|
|
parent.Children = append(parent.Children, *node)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回指定节点下的树
|
|
|
|
|
if parentID != 0 {
|
|
|
|
|
if root, ok := idMap[parentID]; ok {
|
|
|
|
|
return []bus_models.SmsPhraseCategoryTree{*root}, nil
|
|
|
|
|
}
|
|
|
|
|
return []bus_models.SmsPhraseCategoryTree{}, nil // 指定节点不存在
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 否则返回整棵树
|
|
|
|
|
var roots []bus_models.SmsPhraseCategoryTree
|
|
|
|
|
for _, node := range idMap {
|
|
|
|
|
if node.ParentID == 0 {
|
|
|
|
|
roots = append(roots, *node)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return roots, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) AddContactsCategory(req bus_models.AddContactCategoryReq, db *gorm.DB) error {
|
|
|
|
|
return db.Create(&bus_models.SmsContactCategory{
|
2025-05-19 07:39:05 +00:00
|
|
|
|
Name: req.Name,
|
|
|
|
|
ParentID: uint64(req.ParentID),
|
|
|
|
|
CooperativeNumber: req.CooperativeNumber,
|
|
|
|
|
CooperativeName: req.CooperativeName,
|
2025-04-23 10:00:14 +00:00
|
|
|
|
}).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) EditContactsCategory(req bus_models.EditContactCategoryReq, db *gorm.DB) error {
|
|
|
|
|
return db.Model(&bus_models.SmsContactCategory{}).
|
|
|
|
|
Where("id = ?", req.ID).
|
2025-05-19 07:39:05 +00:00
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"name": req.Name,
|
|
|
|
|
"cooperative_number": req.CooperativeNumber,
|
|
|
|
|
"cooperative_name": req.CooperativeName,
|
|
|
|
|
}).Error
|
2025-04-23 10:00:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) DeleteContactsCategories(ids []uint, db *gorm.DB) error {
|
|
|
|
|
if len(ids) == 0 {
|
|
|
|
|
return errors.New("未指定需要删除的分类")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var total int64
|
|
|
|
|
if err := db.Model(&bus_models.SmsContactCategory{}).Count(&total).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 递归找出所有要删除的 ID(含子分类)
|
|
|
|
|
var allIDs []uint
|
|
|
|
|
var walk func(uint)
|
|
|
|
|
walk = func(parentID uint) {
|
|
|
|
|
var children []bus_models.SmsContactCategory
|
|
|
|
|
db.Where("parent_id = ?", parentID).Find(&children)
|
|
|
|
|
for _, child := range children {
|
|
|
|
|
allIDs = append(allIDs, uint(child.ID))
|
|
|
|
|
walk(uint(child.ID))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, id := range ids {
|
|
|
|
|
allIDs = append(allIDs, id)
|
|
|
|
|
walk(id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保证删除后至少保留一个分类节点
|
|
|
|
|
if len(allIDs) >= int(total) {
|
|
|
|
|
return errors.New("无法删除所有分类节点,至少保留一个")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除短语
|
|
|
|
|
if err := db.Where("category_id IN ?", allIDs).Delete(&bus_models.SmsContact{}).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除分类
|
|
|
|
|
return db.Where("id IN ?", allIDs).Delete(&bus_models.SmsContactCategory{}).Error
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) GetContactsCategoryTree(c *gin.Context, db *gorm.DB, parentID uint64) (
|
|
|
|
|
[]bus_models.SmsContactCategoryTree, error) {
|
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return []bus_models.SmsContactCategoryTree{}, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return []bus_models.SmsContactCategoryTree{}, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
var categories []bus_models.SmsContactCategory
|
2025-05-19 07:39:05 +00:00
|
|
|
|
query := db.Table("sms_contact_category")
|
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
|
|
|
|
if err := query.Find(&categories).Error; err != nil {
|
2025-04-23 10:00:14 +00:00
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建 map[id]category
|
|
|
|
|
idMap := make(map[uint64]*bus_models.SmsContactCategoryTree)
|
|
|
|
|
for _, cat := range categories {
|
|
|
|
|
node := &bus_models.SmsContactCategoryTree{
|
|
|
|
|
ID: cat.ID,
|
|
|
|
|
Name: cat.Name,
|
|
|
|
|
ParentID: cat.ParentID,
|
|
|
|
|
}
|
|
|
|
|
idMap[cat.ID] = node
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建树结构
|
|
|
|
|
for _, node := range idMap {
|
|
|
|
|
if parent, ok := idMap[node.ParentID]; ok {
|
|
|
|
|
parent.Children = append(parent.Children, *node)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
// 递归对 Children 排序
|
|
|
|
|
var sortChildren func(nodes []bus_models.SmsContactCategoryTree)
|
|
|
|
|
sortChildren = func(nodes []bus_models.SmsContactCategoryTree) {
|
|
|
|
|
sort.Slice(nodes, func(i, j int) bool {
|
|
|
|
|
return nodes[i].ID < nodes[j].ID
|
|
|
|
|
})
|
|
|
|
|
for i := range nodes {
|
|
|
|
|
sortChildren(nodes[i].Children)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
// 返回指定节点下的树
|
|
|
|
|
if parentID != 0 {
|
|
|
|
|
if root, ok := idMap[parentID]; ok {
|
|
|
|
|
return []bus_models.SmsContactCategoryTree{*root}, nil
|
|
|
|
|
}
|
|
|
|
|
return []bus_models.SmsContactCategoryTree{}, nil // 指定节点不存在
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 否则返回整棵树
|
|
|
|
|
var roots []bus_models.SmsContactCategoryTree
|
|
|
|
|
for _, node := range idMap {
|
|
|
|
|
if node.ParentID == 0 {
|
|
|
|
|
roots = append(roots, *node)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return roots, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) ListCommonNumbers(c *gin.Context, req bus_models.SmsCommonNumberQuery,
|
|
|
|
|
db *gorm.DB) (bus_models.SmsCommonNumberListResp, error) {
|
2025-04-23 10:00:14 +00:00
|
|
|
|
var dbList []bus_models.SmsCommonNumber
|
|
|
|
|
var total int64
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.SmsCommonNumberListResp{}, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return bus_models.SmsCommonNumberListResp{}, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
query := db.Model(&bus_models.SmsCommonNumber{})
|
|
|
|
|
if req.Name != "" {
|
|
|
|
|
query = query.Where("name LIKE ?", "%"+req.Name+"%")
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-23 10:00:14 +00:00
|
|
|
|
err := query.Count(&total).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.SmsCommonNumberListResp{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理分页
|
|
|
|
|
page := req.Page
|
|
|
|
|
if page < 1 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
pageSize := req.PageSize
|
|
|
|
|
if pageSize <= 0 {
|
|
|
|
|
pageSize = 10
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = query.Order("id desc").
|
|
|
|
|
Offset((page - 1) * pageSize).
|
|
|
|
|
Limit(pageSize).
|
|
|
|
|
Find(&dbList).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.SmsCommonNumberListResp{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 转换为返回结构体
|
|
|
|
|
var respList []bus_models.SmsCommonNumber
|
|
|
|
|
for _, item := range dbList {
|
2025-05-19 07:39:05 +00:00
|
|
|
|
var test bus_models.SmsCommonNumber
|
|
|
|
|
test.ID = item.ID
|
|
|
|
|
test.CreatedAt = item.CreatedAt
|
|
|
|
|
test.UpdatedAt = item.UpdatedAt
|
|
|
|
|
test.Name = item.Name
|
|
|
|
|
test.PhoneNumbers = item.PhoneNumbers
|
|
|
|
|
test.PhoneCount = len(strings.Split(item.PhoneNumbers, ","))
|
|
|
|
|
|
|
|
|
|
respList = append(respList, test)
|
2025-04-23 10:00:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalPage := (total + int64(page) - 1) / int64(pageSize)
|
|
|
|
|
if totalPage < 1 {
|
|
|
|
|
totalPage = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bus_models.SmsCommonNumberListResp{
|
|
|
|
|
List: respList,
|
|
|
|
|
Total: total,
|
|
|
|
|
Page: page,
|
|
|
|
|
PageSize: pageSize,
|
|
|
|
|
TotalPage: totalPage,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) AddCommonNumber(req bus_models.SmsCommonNumberAddReq, db *gorm.DB) error {
|
|
|
|
|
if req.Name == "" {
|
|
|
|
|
return errors.New("名称不能为空")
|
|
|
|
|
}
|
|
|
|
|
return db.Create(&bus_models.SmsCommonNumber{
|
2025-05-19 07:39:05 +00:00
|
|
|
|
Name: req.Name,
|
|
|
|
|
PhoneNumbers: strings.Join(req.PhoneList, ","),
|
|
|
|
|
CooperativeNumber: req.CooperativeNumber,
|
|
|
|
|
CooperativeName: req.CooperativeName,
|
2025-04-23 10:00:14 +00:00
|
|
|
|
}).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AppendCommonNumber 向已有常用号码记录中追加号码(自动去重)
|
|
|
|
|
// 逻辑:获取原始号码列表 + 新号码列表 => 合并去重 => 更新保存
|
|
|
|
|
func (s *SmsService) AppendCommonNumber(req bus_models.SmsCommonNumberAppendReq, db *gorm.DB) error {
|
|
|
|
|
var record bus_models.SmsCommonNumber
|
|
|
|
|
err := db.Where("id = ?", req.ID).First(&record).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 拆分原始号码
|
|
|
|
|
originalNumbers := strings.Split(record.PhoneNumbers, ",")
|
|
|
|
|
numberSet := make(map[string]struct{})
|
|
|
|
|
|
|
|
|
|
// 原号码去重填入 map
|
|
|
|
|
for _, num := range originalNumbers {
|
|
|
|
|
num = strings.TrimSpace(num)
|
|
|
|
|
if num != "" {
|
|
|
|
|
numberSet[num] = struct{}{}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 新号码去重合并
|
|
|
|
|
for _, num := range req.PhoneList {
|
|
|
|
|
num = strings.TrimSpace(num)
|
|
|
|
|
if num != "" {
|
|
|
|
|
numberSet[num] = struct{}{}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var deduplicated []string
|
|
|
|
|
for num := range numberSet {
|
|
|
|
|
deduplicated = append(deduplicated, num)
|
|
|
|
|
}
|
|
|
|
|
sort.Strings(deduplicated) // 方便前端对比、稳定输出顺序
|
|
|
|
|
|
|
|
|
|
record.PhoneNumbers = strings.Join(deduplicated, ",")
|
|
|
|
|
return db.Save(&record).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) GetCommonNumberDetail(id int64, db *gorm.DB) (bus_models.SmsCommonNumber, error) {
|
|
|
|
|
var record bus_models.SmsCommonNumber
|
|
|
|
|
err := db.First(&record, id).Error
|
|
|
|
|
return record, err
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) DeleteCommonNumbers(ids []uint64, phoneNumber string, db *gorm.DB) error {
|
|
|
|
|
if phoneNumber != "" && len(ids) > 0 {
|
|
|
|
|
var record bus_models.SmsCommonNumber
|
|
|
|
|
if err := db.First(&record, ids[0]).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分割手机号列表
|
|
|
|
|
phones := strings.Split(record.PhoneNumbers, ",")
|
|
|
|
|
newPhones := make([]string, 0, len(phones))
|
|
|
|
|
for _, p := range phones {
|
|
|
|
|
if strings.TrimSpace(p) != phoneNumber {
|
|
|
|
|
newPhones = append(newPhones, p)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新手机号列表
|
|
|
|
|
record.PhoneNumbers = strings.Join(newPhones, ",")
|
|
|
|
|
return db.Model(&bus_models.SmsCommonNumber{}).
|
|
|
|
|
Where("id = ?", record.ID).
|
|
|
|
|
Update("phone_numbers", record.PhoneNumbers).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// phoneNumber 为空,按原逻辑删除多条记录
|
2025-04-23 10:00:14 +00:00
|
|
|
|
return db.Where("id IN (?)", ids).Delete(&bus_models.SmsCommonNumber{}).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ExportCommonNumbers 导出多个常用号码名称下的所有号码到一个文件
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) ExportCommonNumbers(c *gin.Context, req bus_models.SmsCommonNumberExportReq,
|
|
|
|
|
db *gorm.DB) (string, error) {
|
2025-04-23 10:00:14 +00:00
|
|
|
|
var records []bus_models.SmsCommonNumber
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return "", errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
query := db.Model(&bus_models.SmsCommonNumber{}).Order("id desc")
|
|
|
|
|
if !req.All {
|
|
|
|
|
if len(req.Ids) == 0 {
|
|
|
|
|
return "", fmt.Errorf("未传入号码且未选择导出全部")
|
|
|
|
|
}
|
|
|
|
|
query = query.Where("id IN ?", req.Ids)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-23 10:00:14 +00:00
|
|
|
|
|
|
|
|
|
err := query.Find(&records).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(records) == 0 {
|
|
|
|
|
return "", errors.New("未找到对应的常用号码数据")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建文件
|
|
|
|
|
fileName := time.Now().Format("20060102150405") + "_常用号码.xlsx"
|
|
|
|
|
filePath := ExportFile + fileName
|
|
|
|
|
fileUrl := MiGuExportUrl + fileName
|
|
|
|
|
|
|
|
|
|
file, err := os.Create(filePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
|
|
writer := csv.NewWriter(file)
|
|
|
|
|
defer writer.Flush()
|
|
|
|
|
|
|
|
|
|
// 写数据
|
|
|
|
|
for _, record := range records {
|
|
|
|
|
numbers := strings.Split(record.PhoneNumbers, ",")
|
|
|
|
|
for _, number := range numbers {
|
|
|
|
|
trimmed := strings.TrimSpace(number)
|
|
|
|
|
if trimmed != "" {
|
|
|
|
|
writer.Write([]string{trimmed})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fileUrl, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SmsService) AddBlacklistNumber(req bus_models.BlacklistAddReq, db *gorm.DB) error {
|
|
|
|
|
if len(req.PhoneList) == 0 {
|
|
|
|
|
return fmt.Errorf("手机号列表不能为空")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var records []bus_models.SmsBlackList
|
|
|
|
|
for _, phone := range req.PhoneList {
|
|
|
|
|
records = append(records, bus_models.SmsBlackList{
|
2025-05-19 07:39:05 +00:00
|
|
|
|
PhoneNumber: phone,
|
|
|
|
|
Remark: req.Remark,
|
|
|
|
|
CooperativeNumber: req.CooperativeNumber,
|
|
|
|
|
CooperativeName: req.CooperativeName,
|
2025-04-23 10:00:14 +00:00
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return db.Create(&records).Error
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) ListBlacklist(c *gin.Context, req bus_models.BlacklistQuery,
|
|
|
|
|
db *gorm.DB) (bus_models.BlacklistListResp, error) {
|
2025-04-23 10:00:14 +00:00
|
|
|
|
var list []bus_models.SmsBlackList
|
|
|
|
|
var total int64
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.BlacklistListResp{}, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return bus_models.BlacklistListResp{}, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
query := db.Model(&bus_models.SmsBlackList{})
|
|
|
|
|
if req.PhoneNumber != "" {
|
|
|
|
|
query = query.Where("phone_number LIKE ?", "%"+req.PhoneNumber+"%")
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-23 10:00:14 +00:00
|
|
|
|
|
|
|
|
|
err := query.Count(&total).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.BlacklistListResp{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
page := req.Page
|
|
|
|
|
if page < 1 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
pageSize := req.PageSize
|
|
|
|
|
if pageSize <= 0 {
|
|
|
|
|
pageSize = 10
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = query.Order("id desc").
|
|
|
|
|
Offset((page - 1) * pageSize).
|
|
|
|
|
Limit(pageSize).
|
|
|
|
|
Find(&list).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.BlacklistListResp{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalPage := (total + int64(pageSize) - 1) / int64(pageSize)
|
|
|
|
|
if totalPage < 1 {
|
|
|
|
|
totalPage = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bus_models.BlacklistListResp{
|
|
|
|
|
List: list,
|
|
|
|
|
Total: total,
|
|
|
|
|
Page: page,
|
|
|
|
|
PageSize: pageSize,
|
|
|
|
|
TotalPage: totalPage,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) ExportBlacklistToExcel(c *gin.Context, db *gorm.DB,
|
|
|
|
|
req bus_models.ExportBlacklistRequest) (string, error) {
|
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return "", errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
var blacklists []bus_models.SmsBlackList
|
|
|
|
|
query := db.Model(&bus_models.SmsBlackList{}).Order("id desc")
|
|
|
|
|
|
|
|
|
|
if !req.All {
|
|
|
|
|
if len(req.Ids) == 0 {
|
|
|
|
|
return "", fmt.Errorf("未传入号码且未选择导出全部")
|
|
|
|
|
}
|
|
|
|
|
query = query.Where("id IN ?", req.Ids)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-23 10:00:14 +00:00
|
|
|
|
|
|
|
|
|
if err := query.Find(&blacklists).Error; err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(blacklists) == 0 {
|
|
|
|
|
return "", fmt.Errorf("没有可导出的黑名单记录")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
sheet := "Sheet1"
|
|
|
|
|
headers := []string{"手机号", "备注", "创建时间"}
|
|
|
|
|
|
|
|
|
|
for i, h := range headers {
|
|
|
|
|
col := string('A' + i)
|
|
|
|
|
file.SetCellValue(sheet, col+"1", h)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i, b := range blacklists {
|
|
|
|
|
row := strconv.Itoa(i + 2)
|
|
|
|
|
file.SetCellValue(sheet, "A"+row, b.PhoneNumber)
|
|
|
|
|
file.SetCellValue(sheet, "B"+row, b.Remark)
|
|
|
|
|
file.SetCellValue(sheet, "C"+row, b.CreatedAt.Format("2006-01-02 15:04:05"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
style, _ := file.NewStyle(&excelize.Style{
|
|
|
|
|
Alignment: &excelize.Alignment{
|
|
|
|
|
Horizontal: "center",
|
|
|
|
|
Vertical: "center",
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
file.SetColWidth(sheet, "A", "C", 20)
|
|
|
|
|
file.SetCellStyle(sheet, "A1", fmt.Sprintf("C%d", len(blacklists)+1), style)
|
|
|
|
|
|
|
|
|
|
fileName := time.Now().Format("20060102150405") + "_导出黑名单.xlsx"
|
|
|
|
|
filePath := ExportFile + fileName
|
|
|
|
|
fileUrl := MiGuExportUrl + fileName
|
|
|
|
|
|
|
|
|
|
if err := file.SaveAs(filePath); err != nil {
|
|
|
|
|
logger.Errorf("导出黑名单失败: %v", err)
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fileUrl, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteBlacklist 批量删除黑名单记录
|
|
|
|
|
func (s *SmsService) DeleteBlacklist(ids []uint, db *gorm.DB) error {
|
|
|
|
|
return db.Where("id IN ?", ids).Delete(&bus_models.SmsBlackList{}).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CreateSmsTemplate 创建短信模版
|
|
|
|
|
func (s *SmsService) CreateSmsTemplate(data *bus_models.SmsTemplate, db *gorm.DB) error {
|
|
|
|
|
return db.Create(data).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteSmsTemplates 批量删除短信模版
|
|
|
|
|
func (s *SmsService) DeleteSmsTemplates(ids []uint, db *gorm.DB) error {
|
|
|
|
|
return db.Delete(&bus_models.SmsTemplate{}, ids).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdateSmsTemplate 更新短信模版
|
|
|
|
|
func (s *SmsService) UpdateSmsTemplate(req *bus_models.SmsTemplateUpdateRequest, db *gorm.DB) error {
|
|
|
|
|
var tmpl bus_models.SmsTemplate
|
|
|
|
|
|
|
|
|
|
// 查找原始数据
|
|
|
|
|
if err := db.First(&tmpl, req.ID).Error; err != nil {
|
|
|
|
|
return fmt.Errorf("未找到指定的短信模版")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新模版内容
|
|
|
|
|
tmpl.Content = req.Content
|
2025-05-19 07:39:05 +00:00
|
|
|
|
tmpl.Remark = req.Remark
|
2025-04-23 10:00:14 +00:00
|
|
|
|
|
|
|
|
|
// 更新到期时间(如果传入了新的时间)
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if req.ExpireAt != nil {
|
|
|
|
|
if !req.ExpireAt.IsZero() {
|
|
|
|
|
tmpl.ExpireAt = req.ExpireAt
|
|
|
|
|
}
|
2025-04-23 10:00:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新更新时间
|
|
|
|
|
tmpl.UpdatedAt = time.Now()
|
|
|
|
|
|
|
|
|
|
// 保存更新后的模版
|
|
|
|
|
return db.Save(&tmpl).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ApproveSmsTemplate 审核短信模版
|
|
|
|
|
func (s *SmsService) ApproveSmsTemplate(id uint, status int, db *gorm.DB) error {
|
|
|
|
|
return db.Model(&bus_models.SmsTemplate{}).
|
|
|
|
|
Where("id = ?", id).
|
|
|
|
|
Update("status", status).Error
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) ListSmsTemplates(c *gin.Context, req bus_models.SmsTemplateQuery,
|
|
|
|
|
db *gorm.DB) (bus_models.SmsTemplateListResp, error) {
|
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己门店的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.SmsTemplateListResp{}, errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return bus_models.SmsTemplateListResp{}, errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
var list []bus_models.SmsTemplate
|
|
|
|
|
var total int64
|
|
|
|
|
|
|
|
|
|
query := db.Model(&bus_models.SmsTemplate{})
|
|
|
|
|
|
|
|
|
|
if req.Content != "" {
|
|
|
|
|
query = query.Where("content LIKE ?", "%"+req.Content+"%")
|
|
|
|
|
}
|
|
|
|
|
if req.Status != 0 {
|
|
|
|
|
query = query.Where("status = ?", req.Status)
|
|
|
|
|
}
|
|
|
|
|
if !req.CreateStart.IsZero() && !req.CreateEnd.IsZero() {
|
|
|
|
|
query = query.Where("created_at BETWEEN ? AND ?", req.CreateStart, req.CreateEnd)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-23 10:00:14 +00:00
|
|
|
|
|
|
|
|
|
err := query.Count(&total).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.SmsTemplateListResp{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
page := req.Page
|
|
|
|
|
if page < 1 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
pageSize := req.PageSize
|
|
|
|
|
if pageSize <= 0 {
|
|
|
|
|
pageSize = 10
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = query.Order("id desc").
|
|
|
|
|
Offset((page - 1) * pageSize).
|
|
|
|
|
Limit(pageSize).
|
|
|
|
|
Find(&list).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return bus_models.SmsTemplateListResp{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalPage := (total + int64(pageSize) - 1) / int64(pageSize)
|
|
|
|
|
if totalPage < 1 {
|
|
|
|
|
totalPage = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bus_models.SmsTemplateListResp{
|
|
|
|
|
List: list,
|
|
|
|
|
Total: total,
|
|
|
|
|
Page: page,
|
|
|
|
|
PageSize: pageSize,
|
|
|
|
|
TotalPage: totalPage,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
func (s *SmsService) ExportSmsTemplates(c *gin.Context, req bus_models.SmsTemplateExportReq,
|
|
|
|
|
db *gorm.DB) (string, error) {
|
2025-04-23 10:00:14 +00:00
|
|
|
|
var templates []bus_models.SmsTemplate
|
|
|
|
|
|
2025-05-19 07:39:05 +00:00
|
|
|
|
var cooperative bus_models.BusCooperative
|
|
|
|
|
// 用户权限校验:非管理员仅能查看自己的数据
|
|
|
|
|
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
|
|
|
|
|
sysUser, err := models.GetSysUserByCtx(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", errors.New("操作失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("sysUser:", sysUser)
|
|
|
|
|
|
|
|
|
|
// 查询合作商信息(根据 userId 关联)
|
|
|
|
|
err = s.Orm.Where("user_id = ?", sysUser.UserId).First(&cooperative).Error
|
|
|
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
return "", errors.New("获取合作商信息失败: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 10:00:14 +00:00
|
|
|
|
query := db.Model(&bus_models.SmsTemplate{}).Order("id desc")
|
|
|
|
|
if !req.All {
|
|
|
|
|
if len(req.Ids) == 0 {
|
|
|
|
|
return "", fmt.Errorf("未传入模版且未选择导出全部")
|
|
|
|
|
}
|
|
|
|
|
query = query.Where("id IN ?", req.Ids)
|
|
|
|
|
}
|
2025-05-19 07:39:05 +00:00
|
|
|
|
if cooperative.CooperativeNumber != "" {
|
|
|
|
|
query = query.Where("cooperative_number = ?", cooperative.CooperativeNumber)
|
|
|
|
|
}
|
2025-04-23 10:00:14 +00:00
|
|
|
|
|
|
|
|
|
err := query.Find(&templates).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(templates) == 0 {
|
|
|
|
|
return "", errors.New("未找到对应的短信模版数据")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成文件
|
|
|
|
|
fileName := time.Now().Format("20060102150405") + "_短信模版导出.csv"
|
|
|
|
|
filePath := ExportFile + fileName
|
|
|
|
|
fileUrl := MiGuExportUrl + fileName
|
|
|
|
|
|
|
|
|
|
file, err := os.Create(filePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
|
|
writer := csv.NewWriter(file)
|
|
|
|
|
defer writer.Flush()
|
|
|
|
|
|
|
|
|
|
// 写表头
|
|
|
|
|
writer.Write([]string{"模版ID", "模版内容", "备注", "状态", "创建时间"})
|
|
|
|
|
|
|
|
|
|
// 写内容
|
|
|
|
|
for _, tmpl := range templates {
|
|
|
|
|
status := map[int]string{
|
|
|
|
|
0: "待审核",
|
|
|
|
|
1: "正常",
|
|
|
|
|
2: "审核拒绝",
|
|
|
|
|
3: "已过期",
|
|
|
|
|
}[tmpl.Status]
|
|
|
|
|
|
|
|
|
|
writer.Write([]string{
|
|
|
|
|
strconv.Itoa(int(tmpl.ID)),
|
|
|
|
|
tmpl.Content,
|
|
|
|
|
tmpl.Remark,
|
|
|
|
|
status,
|
|
|
|
|
tmpl.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fileUrl, nil
|
|
|
|
|
}
|