Browse Source

新增公众号相关

Roc 1 week ago
parent
commit
5dab943ada

+ 222 - 0
controllers/rag/wechat_platform_controller.go

@@ -0,0 +1,222 @@
+package rag
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/rag"
+	"eta/eta_api/models/rag/request"
+	"eta/eta_api/models/rag/response"
+	"eta/eta_api/services/llm"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strings"
+	"time"
+)
+
+// WechatPlatformController
+// @Description: 微信公众号管理
+type WechatPlatformController struct {
+	controllers.BaseAuthController
+}
+
+// TagList
+// @Title 获取ppt列表
+// @Description 获取ppt列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Success 200 {object} models.TagListResp
+// @router /tag/list [get]
+func (c *WechatPlatformController) TagList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		return
+	}
+	pageSize, _ := c.GetInt("PageSize")
+	currentIndex, _ := c.GetInt("CurrentIndex")
+	keyWord := c.GetString("KeyWord")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	var condition string
+	var pars []interface{}
+
+	if keyWord != "" {
+		condition = fmt.Sprintf(` AND %s = ?`, rag.WechatPlatformColumns.Nickname)
+		pars = append(pars, `%`+keyWord+`%`)
+	}
+
+	obj := new(rag.Tag)
+	total, list, err := obj.GetPageListByCondition(condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(response.TagListResp)
+	resp.Paging = page
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// Add
+// @Title 新增公众号
+// @Description 新增公众号
+// @Param	request	body request.AddWechatPlatformReq true "type json string"
+// @Success 200 Ret=200 新增成功
+// @router /wechat_platform/add [post]
+func (c *WechatPlatformController) Add() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req request.AddWechatPlatformReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	req.Name = strings.TrimSpace(req.Name)
+	if req.Name == "" {
+		br.Msg = "请输入公众号名称"
+		br.IsSendEmail = false
+		return
+	}
+	req.Link = strings.TrimSpace(req.Link)
+	if req.Link == "" {
+		br.Msg = "请输入文章链接"
+		br.IsSendEmail = false
+		return
+	}
+
+	var condition string
+	var pars []interface{}
+	condition = fmt.Sprintf(` AND %s = ?`, rag.WechatPlatformColumns.Nickname)
+	pars = append(pars, req.Name)
+	obj := new(rag.WechatPlatform)
+	item, err := obj.GetByCondition(condition, pars)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "公众号信息获取失败"
+		br.ErrMsg = "公众号信息获取失败,Err:" + err.Error()
+		return
+	}
+
+	if item.WechatPlatformId > 0 {
+		br.Msg = "公众号名称重复"
+		br.IsSendEmail = false
+		return
+	}
+
+	item = &rag.WechatPlatform{
+		WechatPlatformId: 0,
+		FakeId:           "",
+		Nickname:         req.Name,
+		Alias:            "",
+		RoundHeadImg:     "",
+		ServiceType:      0,
+		Signature:        "",
+		Verified:         0,
+		ArticleLink:      req.Link,
+		Enabled:          0,
+		SysUserId:        c.SysUser.AdminId,
+		ModifyTime:       time.Now(),
+		CreateTime:       time.Now(),
+	}
+	err = item.Add(req.TagIdList)
+	if err != nil {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加失败,Err:" + err.Error()
+		return
+	}
+
+	// 异步新增公众号
+	go llm.AddWechatPlatform(item)
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = `添加成功`
+}
+
+// List
+// @Title 获取ppt列表
+// @Description 获取ppt列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Success 200 {object} models.WechatPlatformListResp
+// @router /wechat_platform/list [get]
+func (c *WechatPlatformController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		return
+	}
+	pageSize, _ := c.GetInt("PageSize")
+	currentIndex, _ := c.GetInt("CurrentIndex")
+	keyWord := c.GetString("KeyWord")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	var condition string
+	var pars []interface{}
+
+	if keyWord != "" {
+		condition = fmt.Sprintf(` AND %s = ?`, rag.WechatPlatformColumns.Nickname)
+		pars = append(pars, `%`+keyWord+`%`)
+	}
+
+	obj := new(rag.WechatPlatform)
+	total, list, err := obj.GetPageListByCondition(condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(response.WechatPlatformListResp)
+	resp.Paging = page
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 7 - 0
models/rag/request/wechat_platform.go

@@ -0,0 +1,7 @@
+package request
+
+type AddWechatPlatformReq struct {
+	Name      string `description:"公众号名称"`
+	Link      string `description:"公众号文章链接"`
+	TagIdList []int  `description:"标签列表"`
+}

+ 16 - 0
models/rag/response/wechat_platform.go

@@ -0,0 +1,16 @@
+package response
+
+import (
+	"eta/eta_api/models/rag"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type WechatPlatformListResp struct {
+	List   []*rag.WechatPlatform
+	Paging *paging.PagingItem `description:"分页数据"`
+}
+
+type TagListResp struct {
+	List   []*rag.Tag
+	Paging *paging.PagingItem `description:"分页数据"`
+}

+ 83 - 0
models/rag/tag.go

@@ -0,0 +1,83 @@
+package rag
+
+import (
+	"database/sql"
+	"eta/eta_api/global"
+	"eta/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+// Tag 品种标签
+type Tag struct {
+	TagId      int       `gorm:"column:tag_id;type:int(9) UNSIGNED;primaryKey;not null;" description:"tag_id"`
+	TagName    string    `gorm:"column:tag_name;type:varchar(255);comment:标签名称;" description:"tag_name"`                // 标签名称
+	Sort       int       `gorm:"column:sort;type:int(9);comment:排序字段;default:0;" description:"sort"`                    // 排序字段
+	ModifyTime time.Time `gorm:"column:modify_time;type:datetime;comment:修改时间;default:NULL;" description:"modify_time"` // 修改时间
+	CreateTime time.Time `gorm:"column:create_time;type:datetime;comment:添加时间;default:NULL;" description:"create_time"` // 添加时间
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *Tag) TableName() string {
+	return "tag"
+}
+
+// TagColumns get sql column name.获取数据库列名
+var TagColumns = struct {
+	TagID      string
+	TagName    string
+	Sort       string
+	ModifyTime string
+	CreateTime string
+}{
+	TagID:      "tag_id",
+	TagName:    "tag_name",
+	Sort:       "sort",
+	ModifyTime: "modify_time",
+	CreateTime: "create_time",
+}
+
+func (m *Tag) GetByID(TagId int) (item *Tag, err error) {
+	err = global.DbMap[utils.DbNameAI].Where(fmt.Sprintf("%s = ?", TagColumns.TagID), TagId).First(&item).Error
+
+	return
+}
+
+func (m *Tag) GetByCondition(condition string, pars []interface{}) (item *Tag, err error) {
+	sqlStr := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).First(&item).Error
+
+	return
+}
+
+func (m *Tag) GetListByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*Tag, err error) {
+	sqlStr := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s LIMIT ?,?`, m.TableName(), condition)
+	pars = append(pars, startSize, pageSize)
+	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).Find(&items).Error
+
+	return
+}
+
+func (m *Tag) GetCountByCondition(condition string, pars []interface{}) (total int, err error) {
+	var intNull sql.NullInt64
+	sqlStr := fmt.Sprintf(`SELECT COUNT(1) total FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).Scan(&intNull).Error
+	if err == nil && intNull.Valid {
+		total = int(intNull.Int64)
+	}
+
+	return
+}
+
+func (m *Tag) GetPageListByCondition(condition string, pars []interface{}, startSize, pageSize int) (total int, items []*Tag, err error) {
+
+	total, err = m.GetCountByCondition(condition, pars)
+	if err != nil {
+		return
+	}
+	if total > 0 {
+		items, err = m.GetListByCondition(condition, pars, startSize, pageSize)
+	}
+
+	return
+}

+ 77 - 0
models/rag/wechat_article.go

@@ -0,0 +1,77 @@
+package rag
+
+import (
+	"eta/eta_api/global"
+	"eta/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+type WechatArticle struct {
+	WechatArticleId   int       `gorm:"column:wechat_article_id;type:int(10) UNSIGNED;primaryKey;not null;" description:""`
+	WechatPlatformId  int       `gorm:"column:wechat_platform_id;type:int(11);comment:归属公众号id;default:0;" description:"归属公众号id"`
+	FakeId            string    `gorm:"column:fake_id;type:varchar(255);comment:公众号唯一id;" description:"公众号唯一id"`
+	Title             string    `gorm:"column:title;type:varchar(255);comment:标题;" description:"标题"`
+	Link              string    `gorm:"column:link;type:varchar(255);comment:链接;" description:"链接"`
+	CoverUrl          string    `gorm:"column:cover_url;type:varchar(255);comment:公众号封面;" description:"公众号封面"`
+	Desc              string    `gorm:"column:desc;type:varchar(255);comment:描述;" description:"描述"`
+	Content           string    `gorm:"column:content;type:longtext;comment:报告详情;" description:"报告详情"`
+	TextContent       string    `gorm:"column:text_content;type:text;comment:文本内容;" description:"文本内容"`
+	Abstract          string    `gorm:"column:abstract;type:text;comment:摘要;" description:"摘要"`
+	ArticleCreateTime time.Time `gorm:"column:article_create_time;type:datetime;comment:报告创建时间;default:NULL;" description:"报告创建时间"`
+	ModifyTime        time.Time `gorm:"column:modify_time;type:datetime;comment:修改时间;default:NULL;" description:"修改时间"`
+	CreateTime        time.Time `gorm:"column:create_time;type:datetime;comment:入库时间;default:NULL;" description:"入库时间"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *WechatArticle) TableName() string {
+	return "wechat_article"
+}
+
+// WechatArticleColumns get sql column name.获取数据库列名
+var WechatArticleColumns = struct {
+	WechatArticleID   string
+	WechatPlatformID  string
+	FakeID            string
+	Title             string
+	Link              string
+	CoverURL          string
+	Desc              string
+	Content           string
+	TextContent       string
+	Abstract          string
+	ArticleCreateTime string
+	ModifyTime        string
+	CreateTime        string
+}{
+	WechatArticleID:   "wechat_article_id",
+	WechatPlatformID:  "wechat_platform_id",
+	FakeID:            "fake_id",
+	Title:             "title",
+	Link:              "link",
+	CoverURL:          "cover_url",
+	Desc:              "desc",
+	Content:           "content",
+	TextContent:       "text_content",
+	Abstract:          "abstract",
+	ArticleCreateTime: "article_create_time",
+	ModifyTime:        "modify_time",
+	CreateTime:        "create_time",
+}
+
+func (m *WechatArticle) Create() (err error) {
+	err = global.DbMap[utils.DbNameAI].Create(&m).Error
+
+	return
+}
+
+func (m *WechatArticle) Update(updateCols []string) (err error) {
+	err = global.DbMap[utils.DbNameAI].Select(updateCols).Updates(&m).Error
+
+	return
+}
+func (m *WechatArticle) GetByLink(link string) (item *WechatArticle, err error) {
+	err = global.DbMap[utils.DbNameAI].Where(fmt.Sprintf("%s = ?", WechatArticleColumns.Link), link).First(&item).Error
+
+	return
+}

+ 184 - 0
models/rag/wechat_platform.go

@@ -0,0 +1,184 @@
+package rag
+
+import (
+	"database/sql"
+	"eta/eta_api/global"
+	"eta/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+type WechatPlatform struct {
+	WechatPlatformId int       `gorm:"column:wechat_platform_id;type:int(10) UNSIGNED;primaryKey;not null;" description:"wechat_platform_id"`
+	FakeId           string    `gorm:"column:fake_id;type:varchar(255);comment:公众号唯一id;" description:"fake_id"`                             // 公众号唯一id
+	Nickname         string    `gorm:"column:nickname;type:varchar(255);comment:公众号名称;" description:"nickname"`                             // 公众号名称
+	Alias            string    `gorm:"column:alias;type:varchar(255);comment:别名;" description:"alias"`                                      // 别名
+	RoundHeadImg     string    `gorm:"column:round_head_img;type:varchar(255);comment:头像;" description:"round_head_img"`                    // 头像
+	ServiceType      int       `gorm:"column:service_type;type:int(11);comment:类型;default:0;" description:"service_type"`                   // 类型
+	Signature        string    `gorm:"column:signature;type:varchar(255);comment:签名;" description:"signature"`                              // 签名
+	Verified         int       `gorm:"column:verified;type:int(11);comment:是否认证,0:未认证,1:已认证;这个我不确定,再核实下;default:0;" description:"verified"` // 是否认证,0:未认证,1:已认证;这个我不确定,再核实下
+	ArticleLink      string    `gorm:"column:article_link;type:varchar(255);comment:添加公众时的文章链接;" description:"article_link"`                // 添加公众时的文章链接
+	Enabled          int       `gorm:"column:enabled;type:tinyint(9);comment:是否启用,0:禁用,1:启用;default:1;" description:"enabled"`              // 是否启用,0:禁用,1:启用
+	SysUserId        int       `gorm:"column:sys_user_id;type:int(9) UNSIGNED;comment:用户id;default:0;" description:"sys_user_id"`           // 用户id
+	ModifyTime       time.Time `gorm:"column:modify_time;type:datetime;comment:最后一次修改时间;default:NULL;" description:"modify_time"`           // 最后一次修改时间
+	CreateTime       time.Time `gorm:"column:create_time;type:datetime;comment:添加时间;default:NULL;" description:"create_time"`               // 添加时间
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *WechatPlatform) TableName() string {
+	return "wechat_platform"
+}
+
+// WechatPlatformColumns get sql column name.获取数据库列名
+var WechatPlatformColumns = struct {
+	WechatPlatformID string
+	FakeID           string
+	Nickname         string
+	Alias            string
+	RoundHeadImg     string
+	ServiceType      string
+	Signature        string
+	Verified         string
+	ArticleLink      string
+	Enabled          string
+	SysUserID        string
+	ModifyTime       string
+	CreateTime       string
+}{
+	WechatPlatformID: "wechat_platform_id",
+	FakeID:           "fake_id",
+	Nickname:         "nickname",
+	Alias:            "alias",
+	RoundHeadImg:     "round_head_img",
+	ServiceType:      "service_type",
+	Signature:        "signature",
+	Verified:         "verified",
+	ArticleLink:      "article_link",
+	Enabled:          "enabled",
+	SysUserID:        "sys_user_id",
+	ModifyTime:       "modify_time",
+	CreateTime:       "create_time",
+}
+
+func (m *WechatPlatform) Create() (err error) {
+	err = global.DbMap[utils.DbNameAI].Create(&m).Error
+
+	return
+}
+
+func (m *WechatPlatform) Update(updateCols []string) (err error) {
+	err = global.DbMap[utils.DbNameAI].Select(updateCols).Updates(&m).Error
+
+	return
+}
+
+func (m *WechatPlatform) Del() (err error) {
+	err = global.DbMap[utils.DbNameAI].Delete(&m).Error
+
+	return
+}
+
+func (m *WechatPlatform) GetByID(wechatPlatformId int) (item *WechatPlatform, err error) {
+	err = global.DbMap[utils.DbNameAI].Where(fmt.Sprintf("%s = ?", WechatPlatformColumns.WechatPlatformID), wechatPlatformId).First(&item).Error
+
+	return
+}
+
+func (m *WechatPlatform) GetByCondition(condition string, pars []interface{}) (item *WechatPlatform, err error) {
+	sqlStr := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).First(&item).Error
+
+	return
+}
+
+func (m *WechatPlatform) GetListByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*WechatPlatform, err error) {
+	sqlStr := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s LIMIT ?,?`, m.TableName(), condition)
+	pars = append(pars, startSize, pageSize)
+	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).Find(&items).Error
+
+	return
+}
+
+func (m *WechatPlatform) GetCountByCondition(condition string, pars []interface{}) (total int, err error) {
+	var intNull sql.NullInt64
+	sqlStr := fmt.Sprintf(`SELECT COUNT(1) total FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).Scan(&intNull).Error
+	if err == nil && intNull.Valid {
+		total = int(intNull.Int64)
+	}
+
+	return
+}
+
+func (m *WechatPlatform) GetPageListByCondition(condition string, pars []interface{}, startSize, pageSize int) (total int, items []*WechatPlatform, err error) {
+
+	total, err = m.GetCountByCondition(condition, pars)
+	if err != nil {
+		return
+	}
+	if total > 0 {
+		items, err = m.GetListByCondition(condition, pars, startSize, pageSize)
+	}
+
+	return
+}
+
+func (m *WechatPlatform) GetByFakeID(fakeId string) (item *WechatPlatform, err error) {
+	err = global.DbMap[utils.DbNameAI].Where(fmt.Sprintf("%s = ?", WechatPlatformColumns.FakeID), fakeId).First(&item).Error
+
+	return
+}
+
+// Add
+// @Description: 添加一个新的公众号
+// @author: Roc
+// @receiver m
+// @datetime 2025-03-04 17:48:30
+// @param tagIdList []int
+// @return err error
+func (m *WechatPlatform) Add(tagIdList []int) (err error) {
+	tx := global.DbMap[utils.DbNameAI].Begin()
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+		} else {
+			_ = tx.Commit()
+		}
+	}()
+
+	err = tx.Create(&m).Error
+	if err != nil {
+		return
+	}
+
+	// 标签与公众号关系
+	if len(tagIdList) > 0 {
+		addTagMappingList := make([]*WechatPlatformTagMapping, 0)
+
+		for _, tagId := range tagIdList {
+			addTagMappingList = append(addTagMappingList, &WechatPlatformTagMapping{
+				WechatPlatformTagMappingId: 0,
+				WechatPlatformId:           m.WechatPlatformId,
+				TagId:                      tagId,
+				ModifyTime:                 time.Now(),
+				CreateTime:                 time.Now(),
+			})
+		}
+		err = tx.CreateInBatches(addTagMappingList, utils.MultiAddNum).Error
+		if err != nil {
+			return
+		}
+	}
+
+	// 用户与公众号关系
+	userMapping := &WechatPlatformUserMapping{
+		WechatPlatformUserMappingId: 0,
+		WechatPlatformId:            m.WechatPlatformId,
+		SysUserId:                   m.SysUserId,
+		ModifyTime:                  time.Now(),
+		CreateTime:                  time.Now(),
+	}
+	err = tx.Create(userMapping).Error
+
+	return
+}

+ 82 - 0
models/rag/wechat_platform_tag_mapping.go

@@ -0,0 +1,82 @@
+package rag
+
+import (
+	"database/sql"
+	"eta/eta_api/global"
+	"eta/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+type WechatPlatformTagMapping struct {
+	WechatPlatformTagMappingId int       `gorm:"column:wechat_platform_tag_mapping_id;type:int(9) UNSIGNED;primaryKey;not null;" description:"wechat_platform_tag_mapping_id"`
+	WechatPlatformId           int       `gorm:"column:wechat_platform_id;type:int(9) UNSIGNED;comment:微信公众号id;default:0;" description:"wechat_platform_id"` // 微信公众号id
+	TagId                      int       `gorm:"column:tag_id;type:int(9) UNSIGNED;comment:品种id;default:0;" description:"tag_id"`                            // 品种id
+	ModifyTime                 time.Time `gorm:"column:modify_time;type:datetime;default:NULL;" description:"modify_time"`
+	CreateTime                 time.Time `gorm:"column:create_time;type:datetime;default:NULL;" description:"create_time"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *WechatPlatformTagMapping) TableName() string {
+	return "wechat_platform_tag_mapping"
+}
+
+// WechatPlatformTagMappingColumns get sql column name.获取数据库列名
+var WechatPlatformTagMappingColumns = struct {
+	WechatPlatformTagMappingID string
+	WechatPlatformID           string
+	TagID                      string
+	ModifyTime                 string
+	CreateTime                 string
+}{
+	WechatPlatformTagMappingID: "wechat_platform_tag_mapping_id",
+	WechatPlatformID:           "wechat_platform_id",
+	TagID:                      "tag_id",
+	ModifyTime:                 "modify_time",
+	CreateTime:                 "create_time",
+}
+
+func (m *WechatPlatformTagMapping) GetByID(WechatPlatformTagMappingColumnsId int) (item *WechatPlatformTagMapping, err error) {
+	err = global.DbMap[utils.DbNameAI].Where(fmt.Sprintf("%s = ?", WechatPlatformTagMappingColumns.WechatPlatformTagMappingID), WechatPlatformTagMappingColumnsId).First(&item).Error
+
+	return
+}
+
+func (m *WechatPlatformTagMapping) GetByCondition(condition string, pars []interface{}) (item *WechatPlatformTagMapping, err error) {
+	sqlStr := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).Where(condition, pars).First(&item).Error
+
+	return
+}
+
+func (m *WechatPlatformTagMapping) GetListByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*WechatPlatformTagMapping, err error) {
+	sqlStr := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s LIMIT ?,?`, m.TableName(), condition)
+	pars = append(pars, startSize, pageSize)
+	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).Find(&items).Error
+
+	return
+}
+
+func (m *WechatPlatformTagMapping) GetCountByCondition(condition string, pars []interface{}) (total int, err error) {
+	var intNull sql.NullInt64
+	sqlStr := fmt.Sprintf(`SELECT COUNT(1) total FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).Scan(&intNull).Error
+	if err == nil && intNull.Valid {
+		total = int(intNull.Int64)
+	}
+
+	return
+}
+
+func (m *WechatPlatformTagMapping) GetPageListByCondition(condition string, pars []interface{}, startSize, pageSize int) (total int, items []*WechatPlatformTagMapping, err error) {
+
+	total, err = m.GetCountByCondition(condition, pars)
+	if err != nil {
+		return
+	}
+	if total > 0 {
+		items, err = m.GetListByCondition(condition, pars, startSize, pageSize)
+	}
+
+	return
+}

+ 31 - 0
models/rag/wechat_platform_user_mapping.go

@@ -0,0 +1,31 @@
+package rag
+
+import "time"
+
+type WechatPlatformUserMapping struct {
+	WechatPlatformUserMappingId int       `gorm:"column:wechat_platform_user_mapping_id;type:int(9) UNSIGNED;primaryKey;not null;" description:"wechat_platform_user_mapping_id"`
+	WechatPlatformId            int       `gorm:"column:wechat_platform_id;type:int(9) UNSIGNED;comment:微信公众号id;default:0;" description:"wechat_platform_id"` // 微信公众号id
+	SysUserId                   int       `gorm:"column:sys_user_id;type:int(9) UNSIGNED;comment:用户id;default:0;" description:"sys_user_id"`                  // 用户id
+	ModifyTime                  time.Time `gorm:"column:modify_time;type:datetime;default:NULL;" description:"modify_time"`
+	CreateTime                  time.Time `gorm:"column:create_time;type:datetime;default:NULL;" description:"create_time"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *WechatPlatformUserMapping) TableName() string {
+	return "wechat_platform_user_mapping"
+}
+
+// WechatPlatformUserMappingColumns get sql column name.获取数据库列名
+var WechatPlatformUserMappingColumns = struct {
+	WechatPlatformUserMappingID string
+	WechatPlatformID            string
+	SysUserID                   string
+	ModifyTime                  string
+	CreateTime                  string
+}{
+	WechatPlatformUserMappingID: "wechat_platform_user_mapping_id",
+	WechatPlatformID:            "wechat_platform_id",
+	SysUserID:                   "sys_user_id",
+	ModifyTime:                  "modify_time",
+	CreateTime:                  "create_time",
+}

+ 27 - 0
routers/commentsRouter.go

@@ -8530,6 +8530,33 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/rag:WechatPlatformController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:WechatPlatformController"],
+        beego.ControllerComments{
+            Method: "TagList",
+            Router: `/tag/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/rag:WechatPlatformController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:WechatPlatformController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/wechat_platform/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/rag:WechatPlatformController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:WechatPlatformController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/wechat_platform/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/report_approve:ReportApproveController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/report_approve:ReportApproveController"],
         beego.ControllerComments{
             Method: "Approve",

+ 2 - 1
routers/router.go

@@ -54,7 +54,7 @@ func init() {
 		ExposeHeaders:    []string{"Content-Length", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Content-Type"},
 		AllowCredentials: true,
 	}))
-	web.InsertFilter("/adminapi/llm/chat/connect", web.BeforeRouter,services.WsAuthenticate())
+	web.InsertFilter("/adminapi/llm/chat/connect", web.BeforeRouter, services.WsAuthenticate())
 	ns := web.NewNamespace("/adminapi",
 		web.NSNamespace("/sysuser",
 			web.NSInclude(
@@ -72,6 +72,7 @@ func init() {
 		web.NSNamespace("/llm",
 			web.NSInclude(
 				&rag.ChatController{},
+				&rag.WechatPlatformController{},
 			),
 		),
 		web.NSNamespace("/banner",

+ 212 - 0
services/llm/base_wechat_lib.go

@@ -0,0 +1,212 @@
+package llm
+
+import (
+	"encoding/json"
+	"eta/eta_api/utils"
+	"fmt"
+	"io"
+	"net/http"
+	"strings"
+)
+
+type BaseResp struct {
+	Code int    `json:"code"`
+	Msg  string `json:"msg"`
+}
+
+type WechatPlatformListResp struct {
+	BaseResp
+	Data []WechatPlatformResp `json:"data"`
+}
+
+type WechatPlatformResp struct {
+	Fakeid       string `json:"fakeid"`
+	Nickname     string `json:"nickname"`
+	Alias        string `json:"alias"`
+	RoundHeadImg string `json:"round_head_img"`
+	ServiceType  int    `json:"service_type"`
+	Signature    string `json:"signature"`
+	Verified     bool   `json:"verified"`
+}
+
+// SearchByWechat
+// @Description: 公众号列表
+// @author: Roc
+// @datetime 2025-03-04 18:09:01
+// @param name string
+// @return resp WechatPlatformResp
+// @return err error
+func SearchByWechat(name string) (items []WechatPlatformResp, err error) {
+	if utils.ETA_WX_CRAWLER_URL == "" {
+		err = fmt.Errorf("ETA微信爬虫服务地址为空")
+		return
+	}
+	getUrl := utils.ETA_WX_CRAWLER_URL + `/api/wechat_platform/search_by_wechat?name=` + name
+	result, err := HttpGet(getUrl)
+	if err != nil {
+		err = fmt.Errorf("调用ETA微信爬虫服务接口失败 error:%s", err.Error())
+		return
+	}
+
+	var resp WechatPlatformListResp
+	err = json.Unmarshal(result, &resp)
+	if err != nil {
+		return
+	}
+
+	items = resp.Data
+
+	return
+}
+
+type WechatArticleResp struct {
+	BaseResp
+	Data WechatArticleDataResp `json:"data"`
+}
+
+type WechatArticleDataResp struct {
+	HtmlContent      string `json:"HtmlContent"`
+	TextContent      string `json:"TextContent"`
+	RoundHeadImg     string `json:"RoundHeadImg"`
+	ProfileSignature string `json:"ProfileSignature"`
+	Appuin           string `json:"Appuin"`
+	Nickname         string `json:"Nickname"`
+	UserName         string `json:"UserName"`
+	Title            string `json:"Title"`
+	Desc             string `json:"Desc"`
+	CoverUrl         string `json:"CoverUrl"`
+	CreateAt         string `json:"CreateAt"`
+	CountryName      string `json:"CountryName"`
+	ProvinceName     string `json:"ProvinceName"`
+	CityName         string `json:"CityName"`
+}
+
+// SearchByWechatArticle
+// @Description: 获取报告详情
+// @author: Roc
+// @datetime 2025-03-04 18:08:45
+// @param link string
+// @return resp WechatArticleResp
+// @return err error
+func SearchByWechatArticle(link string) (wechatArticle WechatArticleDataResp, err error) {
+	if utils.ETA_WX_CRAWLER_URL == "" {
+		err = fmt.Errorf("ETA微信爬虫服务地址为空")
+		return
+	}
+	getUrl := utils.ETA_WX_CRAWLER_URL + `/api/wechat_platform/article/info/search_by_wechat?link=` + link
+	result, err := HttpGet(getUrl)
+	if err != nil {
+		err = fmt.Errorf("调用ETA微信爬虫服务接口失败 error:%s", err.Error())
+		return
+	}
+
+	var resp WechatArticleResp
+	err = json.Unmarshal(result, &resp)
+	if err != nil {
+		return
+	}
+
+	wechatArticle = resp.Data
+
+	return
+}
+
+type WechatArticleListResp struct {
+	BaseResp
+	Data WechatArticleMenuPage `json:"data"`
+}
+
+type WechatArticleMenuPage struct {
+	List  []ArticleMenu `json:"List"`
+	Total int           `json:"Total"`
+}
+
+type ArticleMenu struct {
+	Aid        string `json:"Aid"`
+	Title      string `json:"Title"`
+	Link       string `json:"Link"`
+	Cover      string `json:"Cover"`
+	Digest     string `json:"Digest"`
+	UpdateTime int    `json:"UpdateTime"`
+	CreateTime int    `json:"CreateTime"`
+	AppMsgId   int64  `json:"AppMsgId"`
+	AuthorName string `json:"AuthorName"`
+	Content    string `json:"Content"`
+}
+
+func SearchByWechatArticleList(fakeId string, num int) (items WechatArticleMenuPage, err error) {
+	if utils.ETA_WX_CRAWLER_URL == "" {
+		err = fmt.Errorf("ETA微信爬虫服务地址为空")
+		return
+	}
+	getUrl := fmt.Sprintf(`%s/api/wechat_platform/article/list/search_by_wechat?fakeid=%s&num=%d`, utils.ETA_WX_CRAWLER_URL, fakeId, num)
+	result, err := HttpGet(getUrl)
+	if err != nil {
+		err = fmt.Errorf("调用ETA微信爬虫服务接口失败 error:%s", err.Error())
+		return
+	}
+
+	var resp WechatArticleListResp
+	err = json.Unmarshal(result, &resp)
+	if err != nil {
+		return
+	}
+
+	items = resp.Data
+
+	return
+}
+
+func HttpGet(url string) ([]byte, error) {
+	client := &http.Client{}
+	req, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set("authorization", utils.MD5(utils.ETA_FORUM_HUB_NAME_EN+utils.ETA_FORUM_HUB_MD5_KEY))
+	resp, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	result, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return nil, err
+	}
+	utils.FileLog.Debug("HttpPost:" + string(result))
+
+	var baseResp BaseResp
+	err = json.Unmarshal(result, &baseResp)
+	if err != nil {
+		return nil, err
+	}
+	if baseResp.Code != 200 {
+		return nil, fmt.Errorf("code:%d,msg:%s", baseResp.Code, baseResp.Msg)
+	}
+
+	return result, err
+}
+
+func HttpPost(url, postData, lang string, params ...string) ([]byte, error) {
+	body := io.NopCloser(strings.NewReader(postData))
+	client := &http.Client{}
+	req, err := http.NewRequest("POST", url, body)
+	if err != nil {
+		return nil, err
+	}
+	contentType := "application/x-www-form-urlencoded;charset=utf-8"
+	if len(params) > 0 && params[0] != "" {
+		contentType = params[0]
+	}
+	req.Header.Set("Content-Type", contentType)
+	req.Header.Set("Lang", lang)
+	req.Header.Set("authorization", utils.MD5(utils.APP_EDB_LIB_NAME_EN+utils.EDB_LIB_Md5_KEY))
+	resp, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	b, err := io.ReadAll(resp.Body)
+	utils.FileLog.Debug("HttpPost:" + string(b))
+	return b, err
+}

+ 185 - 0
services/llm/wechat_platform.go

@@ -0,0 +1,185 @@
+package llm
+
+import (
+	"eta/eta_api/models/rag"
+	"eta/eta_api/utils"
+	"fmt"
+	"html"
+	"strconv"
+	"time"
+)
+
+func AddWechatPlatform(item *rag.WechatPlatform) {
+	var err error
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("公众号入库后查找最新记录失败,err:%v", err)
+		}
+	}()
+	if item.FakeId != `` {
+		return
+	}
+
+	if item.ArticleLink == `` {
+		return
+	}
+
+	articleLink := item.ArticleLink
+
+	articleDetail, err := SearchByWechatArticle(item.ArticleLink)
+	if err != nil {
+		return
+	}
+
+	if articleDetail.Appuin == `` {
+		err = fmt.Errorf("文章内未匹配到公众号唯一标识")
+		return
+	}
+
+	wechatPlatform := new(rag.WechatPlatform)
+	// 查找是否存在这个公众号id的
+	wechatPlatformInfo, tmpErr := wechatPlatform.GetByFakeID(articleDetail.Appuin)
+	if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+		err = tmpErr
+		return
+	}
+	if tmpErr == nil {
+		// 如果找到了,那么需要将当前的给移除掉
+		err = item.Del()
+		if err != nil {
+			return
+		}
+
+		// 并将查出来的微信公众号摘出来的数据重新赋值
+		item = wechatPlatformInfo
+
+	} else if utils.IsErrNoRow(tmpErr) {
+		// 如果没找到,那么就变更当前的信息
+		item.FakeId = articleDetail.Appuin
+		item.Nickname = articleDetail.Nickname
+		//item.Alias = req.Alias
+		item.RoundHeadImg = articleDetail.RoundHeadImg
+		//item.ServiceType = req.ServiceType
+		item.Signature = articleDetail.ProfileSignature
+		//item.Verified = verified
+		item.ModifyTime = time.Now()
+
+		err = item.Update([]string{rag.WechatPlatformColumns.FakeID, rag.WechatPlatformColumns.Nickname, rag.WechatPlatformColumns.RoundHeadImg, rag.WechatPlatformColumns.Signature, rag.WechatPlatformColumns.ModifyTime})
+		if err != nil {
+			return
+		}
+	}
+
+	// 把刚搜索的文章加入到指标库
+	AddWechatArticle(item, articleLink, articleDetail, nil)
+
+	return
+}
+
+// AddWechatArticle
+// @Description: 添加公众号文章入库
+// @author: Roc
+// @datetime 2025-03-05 13:24:14
+// @param item *rag.WechatPlatform
+// @param link string
+// @param articleDetail WechatArticleDataResp
+func AddWechatArticle(item *rag.WechatPlatform, articleLink string, articleDetail WechatArticleDataResp, articleMenu *ArticleMenu) {
+	var err error
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("公众号文章入库失败,文章链接:%s ,err:%v", articleLink, err)
+		}
+	}()
+	obj := new(rag.WechatArticle)
+
+	_, err = obj.GetByLink(articleLink)
+	if err == nil {
+		// 文章已经入库了,不需要重复入库
+		return
+	}
+
+	// 如果不是 ErrNoRow 的时候,那么就是查询数据库出问题了,需要直接返回
+	if !utils.IsErrNoRow(err) {
+		return
+	}
+
+	// 这个时候,说明数据库中没有这个文章,那么需要文章入库
+	err = nil
+
+	var publishAt time.Time
+	if articleDetail.CreateAt != `` {
+		createAtInt, tmpErr := strconv.Atoi(articleDetail.CreateAt)
+		if tmpErr == nil {
+			publishAt = time.Unix(int64(createAtInt), 1000)
+		}
+	} else if articleMenu != nil {
+		publishAt = time.Unix(int64(articleMenu.UpdateTime), 1000)
+	}
+
+	obj = &rag.WechatArticle{
+		WechatArticleId:  0,
+		WechatPlatformId: item.WechatPlatformId,
+		FakeId:           item.FakeId,
+		Title:            articleDetail.Title,
+		Link:             articleLink,
+		CoverUrl:         articleDetail.CoverUrl,
+		Desc:             articleDetail.Desc,
+		Content:          html.EscapeString(articleDetail.HtmlContent),
+		TextContent:      articleDetail.TextContent,
+		//Abstract:          "",
+		//ArticleCreateTime: createAt,
+		ModifyTime: time.Now(),
+		CreateTime: time.Now(),
+	}
+	if !publishAt.IsZero() {
+		obj.ArticleCreateTime = publishAt
+	}
+
+	if articleMenu != nil {
+		obj.Title = articleMenu.Title
+		//obj.Link = articleMenu.Link
+		obj.CoverUrl = articleMenu.Cover
+		obj.Abstract = articleMenu.Digest
+	}
+	err = obj.Create()
+}
+
+// BeachAddWechatPlatform
+// @Description: 批量添加公众号文章
+// @author: Roc
+// @datetime 2025-03-05 15:05:07
+// @param item *rag.WechatPlatform
+// @return err error
+func BeachAddWechatPlatform(item *rag.WechatPlatform) (err error) {
+	defer func() {
+		fmt.Println("公众号文章批量入库完成")
+		if err != nil {
+			utils.FileLog.Error("公众号文章批量入库失败,err:%v", err)
+			fmt.Println("公众号文章批量入库失败,err:", err)
+		}
+	}()
+	if item.FakeId == `` {
+		return
+	}
+
+	num := 10
+
+	// 获取公众号的文章列表
+	articleListResp, err := SearchByWechatArticleList(item.FakeId, num)
+	if err != nil {
+		return
+	}
+	for _, articleMenu := range articleListResp.List {
+		articleDetail, tmpErr := SearchByWechatArticle(articleMenu.Link)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		// 把刚搜索的文章加入到指标库
+		AddWechatArticle(item, articleMenu.Link, articleDetail, &articleMenu)
+
+		time.Sleep(10 * time.Second)
+	}
+	return
+}

+ 10 - 0
utils/config.go

@@ -213,6 +213,10 @@ var (
 	ETA_FORUM_HUB_MD5_KEY string
 )
 
+var (
+	ETA_WX_CRAWLER_URL string
+)
+
 // BusinessCode 商家编码
 var BusinessCode string
 
@@ -581,6 +585,12 @@ func init() {
 		ETA_FORUM_HUB_NAME_EN = config["eta_forum_hub_name_en"]
 		ETA_FORUM_HUB_MD5_KEY = config["eta_forum_hub_md5_key"]
 	}
+
+	// 微信爬虫服务
+	{
+		ETA_WX_CRAWLER_URL = config["eta_wx_crawler_url"]
+	}
+
 	// 商家编码
 	BusinessCode = config["business_code"]
 	// eta_mini_bridge 小程序桥接服务地址