第一版完成
This commit is contained in:
286
internal/service/contact.go
Normal file
286
internal/service/contact.go
Normal file
@@ -0,0 +1,286 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"cms-api/internal/dao"
|
||||
"cms-api/internal/model"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
type sContact struct{}
|
||||
|
||||
func Contact() *sContact {
|
||||
return &sContact{}
|
||||
}
|
||||
|
||||
// GetById 根据ID获取联系信息
|
||||
func (s *sContact) GetById(ctx context.Context, id int) (*model.Contact, error) {
|
||||
return dao.Contact.GetById(ctx, id)
|
||||
}
|
||||
|
||||
// List 获取联系信息列表
|
||||
func (s *sContact) List(ctx context.Context, req *model.ContactListRequest) (*model.PageResponse, error) {
|
||||
var (
|
||||
page = req.Page
|
||||
pageSize = req.PageSize
|
||||
)
|
||||
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize <= 0 {
|
||||
pageSize = 20
|
||||
}
|
||||
|
||||
// 设置分页参数
|
||||
req.Page = page
|
||||
req.PageSize = pageSize
|
||||
|
||||
// 获取列表
|
||||
contacts, total, err := dao.Contact.List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &model.PageResponse{
|
||||
List: contacts,
|
||||
Total: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
TotalPages: (total + pageSize - 1) / pageSize,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Create 创建联系信息(前台提交表单)
|
||||
func (s *sContact) Create(ctx context.Context, req *model.CreateContactRequest) error {
|
||||
// 获取客户端信息
|
||||
request := g.RequestFromCtx(ctx)
|
||||
ip := request.GetClientIp()
|
||||
userAgent := request.Header.Get("User-Agent")
|
||||
|
||||
// 创建联系信息
|
||||
contact := &model.Contact{
|
||||
Name: req.Name,
|
||||
Email: req.Email,
|
||||
Phone: req.Phone,
|
||||
Company: req.Company,
|
||||
Subject: req.Subject,
|
||||
Message: req.Message,
|
||||
Ip: ip,
|
||||
UserAgent: userAgent,
|
||||
Status: 0, // 未处理
|
||||
CreatedAt: gtime.Now(),
|
||||
UpdatedAt: gtime.Now(),
|
||||
}
|
||||
|
||||
_, err := dao.Contact.Create(ctx, contact)
|
||||
return err
|
||||
}
|
||||
|
||||
// Reply 回复联系信息
|
||||
func (s *sContact) Reply(ctx context.Context, id int, req *model.ReplyContactRequest) error {
|
||||
// 检查联系信息是否存在
|
||||
contact, err := s.GetById(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if contact == nil {
|
||||
return gerror.New("联系信息不存在")
|
||||
}
|
||||
|
||||
// 获取回复人ID
|
||||
repliedBy := gconv.Int(g.RequestFromCtx(ctx).GetCtxVar("admin_id"))
|
||||
if repliedBy == 0 {
|
||||
return gerror.New("未获取到管理员信息")
|
||||
}
|
||||
|
||||
// 更新回复信息
|
||||
updateData := g.Map{
|
||||
"reply": req.Reply,
|
||||
"status": 2, // 已回复
|
||||
"replied_at": gtime.Now(),
|
||||
"replied_by": repliedBy,
|
||||
"updated_at": gtime.Now(),
|
||||
}
|
||||
|
||||
return dao.Contact.Update(ctx, id, updateData)
|
||||
}
|
||||
|
||||
// UpdateStatus 更新处理状态
|
||||
func (s *sContact) UpdateStatus(ctx context.Context, id int, status int) error {
|
||||
// 检查联系信息是否存在
|
||||
contact, err := s.GetById(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if contact == nil {
|
||||
return gerror.New("联系信息不存在")
|
||||
}
|
||||
|
||||
updateData := g.Map{
|
||||
"status": status,
|
||||
"updated_at": gtime.Now(),
|
||||
}
|
||||
|
||||
// 如果状态改为已处理但没有回复,只更新状态
|
||||
if status == 1 && contact.Status == 0 {
|
||||
// 已处理状态
|
||||
}
|
||||
|
||||
return dao.Contact.Update(ctx, id, updateData)
|
||||
}
|
||||
|
||||
// Delete 删除联系信息
|
||||
func (s *sContact) Delete(ctx context.Context, id int) error {
|
||||
// 检查联系信息是否存在
|
||||
contact, err := s.GetById(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if contact == nil {
|
||||
return gerror.New("联系信息不存在")
|
||||
}
|
||||
|
||||
return dao.Contact.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// GetStats 获取联系信息统计
|
||||
func (s *sContact) GetStats(ctx context.Context) (map[string]interface{}, error) {
|
||||
// 获取总联系信息数
|
||||
totalCount, err := dao.Contact.GetCount(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取各状态联系信息数
|
||||
unprocessedCount, err := dao.Contact.GetCountByStatus(ctx, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
processedCount, err := dao.Contact.GetCountByStatus(ctx, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repliedCount, err := dao.Contact.GetCountByStatus(ctx, 2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取今日新增联系信息数
|
||||
todayCount, err := dao.Contact.GetTodayCount(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取本周新增联系信息数
|
||||
weekCount, err := dao.Contact.GetWeekCount(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取本月新增联系信息数
|
||||
monthCount, err := dao.Contact.GetMonthCount(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"total_count": totalCount,
|
||||
"unprocessed_count": unprocessedCount,
|
||||
"processed_count": processedCount,
|
||||
"replied_count": repliedCount,
|
||||
"today_count": todayCount,
|
||||
"week_count": weekCount,
|
||||
"month_count": monthCount,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetLatest 获取最新联系信息
|
||||
func (s *sContact) GetLatest(ctx context.Context, limit int) ([]*model.Contact, error) {
|
||||
if limit <= 0 {
|
||||
limit = 10
|
||||
}
|
||||
return dao.Contact.GetLatest(ctx, limit)
|
||||
}
|
||||
|
||||
// GetUnprocessed 获取未处理的联系信息
|
||||
func (s *sContact) GetUnprocessed(ctx context.Context, limit int) ([]*model.Contact, error) {
|
||||
if limit <= 0 {
|
||||
limit = 20
|
||||
}
|
||||
return dao.Contact.GetUnprocessed(ctx, limit)
|
||||
}
|
||||
|
||||
// BatchUpdateStatus 批量更新状态
|
||||
func (s *sContact) BatchUpdateStatus(ctx context.Context, ids []int, status int) error {
|
||||
for _, id := range ids {
|
||||
if err := s.UpdateStatus(ctx, id, status); err != nil {
|
||||
g.Log().Error(ctx, "批量更新联系信息状态失败, ID:", id, "错误:", err)
|
||||
// 继续更新其他记录,不中断整个过程
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除联系信息
|
||||
func (s *sContact) BatchDelete(ctx context.Context, ids []int) error {
|
||||
for _, id := range ids {
|
||||
if err := s.Delete(ctx, id); err != nil {
|
||||
g.Log().Error(ctx, "批量删除联系信息失败, ID:", id, "错误:", err)
|
||||
// 继续删除其他记录,不中断整个过程
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Search 搜索联系信息
|
||||
func (s *sContact) Search(ctx context.Context, keyword string, page, pageSize int) (*model.PageResponse, error) {
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize <= 0 {
|
||||
pageSize = 20
|
||||
}
|
||||
|
||||
contacts, total, err := dao.Contact.Search(ctx, keyword, page, pageSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &model.PageResponse{
|
||||
List: contacts,
|
||||
Total: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
TotalPages: (total + pageSize - 1) / pageSize,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Export 导出联系信息
|
||||
func (s *sContact) Export(ctx context.Context, req *model.ContactListRequest) ([]*model.Contact, error) {
|
||||
// 设置大的页面大小来获取所有数据
|
||||
req.Page = 1
|
||||
req.PageSize = 10000
|
||||
|
||||
contacts, _, err := dao.Contact.List(ctx, req)
|
||||
return contacts, err
|
||||
}
|
||||
|
||||
// GetContactTrends 获取联系信息趋势数据
|
||||
func (s *sContact) GetContactTrends(ctx context.Context, days int) ([]map[string]interface{}, error) {
|
||||
if days <= 0 {
|
||||
days = 7 // 默认7天
|
||||
}
|
||||
return dao.Contact.GetTrends(ctx, days)
|
||||
}
|
||||
|
||||
// GetTrends 获取联系信息趋势数据(兼容性方法)
|
||||
func (s *sContact) GetTrends(ctx context.Context, days int) ([]map[string]interface{}, error) {
|
||||
return s.GetContactTrends(ctx, days)
|
||||
}
|
||||
Reference in New Issue
Block a user