123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- package service
- import (
- "context"
- "fmt"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/os/gctx"
- "github.com/gogf/gf/v2/util/gconv"
- "jybxseo/internal/consts"
- )
- var (
- JyBxSeoAreaRoot *AreaRoot = &AreaRoot{}
- AreaLocationShowNameMap = map[int]string{
- 1: "华北",
- 2: "华中",
- 3: "东北",
- 4: "华中",
- 5: "华南",
- 6: "西南",
- 7: "西北",
- }
- )
- type (
- AreaRoot struct {
- areaCodeMap map[string]*AreaNode //所有节点平铺 key:code (部分城市有重复,请根据省份+GetChildNode code获取 ⚠️suzhou yulin yichun fuzhou taizhou)
- areaNameMap map[string]*AreaNode //所有节点平铺 key:name
- rootList []*AreaNode //根节点
- Location []*AreaLocation //区位
- areaCodeConfigMap map[string]*AreaIndexConfig
- }
- AreaNode struct {
- Name string `json:"name" doc:"名称"`
- Code string `json:"code" doc:"代码"`
- Href string `json:"href" doc:"地址"`
- PNode *AreaNode `json:"pNode" doc:"父节点代码"`
- Location int `json:"location" doc:"区位"`
- Type int `json:"type" doc:"1省份 2城市 3直辖市"`
- Child []*AreaNode `json:"child" doc:"子栏目"`
- }
- AreaLocation struct {
- Name string `json:"name" doc:"华北、华中、东北、华东、华南、西南、西北"`
- AreaList []*AreaNode `json:"areaList" doc:"地区列表"`
- }
- AreaIndexConfig struct {
- Hots []*AreaNode `json:"node"`
- AdLink string `json:"adLink"`
- FLinks []struct {
- Name string `json:"name"`
- Href string `json:"href"`
- } `json:"fLinks"`
- }
- )
- func init() {
- //JyBxSeoAreaRoot.LoadAreasFromConfig(gctx.New())
- JyBxSeoAreaRoot.LoadAreasFromDB(gctx.New())
- }
- func (aRoot *AreaRoot) LoadAreasFromDB(ctx context.Context) {
- areaCodeMap, areaNameMap := map[string]*AreaNode{}, map[string]*AreaNode{}
- var rootArr []*AreaNode
- res, err := g.DB().Query(ctx, "SELECT * FROM seo_area_code where state=1 and pfcode!='' order by id asc")
- if err != nil {
- g.Log().Errorf(ctx, "加载地区异常%v", err)
- }
- for _, m := range res.List() {
- node := &AreaNode{
- Code: gconv.String(m["pfcode"]),
- Type: gconv.Int(m["class"]),
- }
- switch node.Type {
- case consts.AreaType, consts.CitySpecialType:
- node.Name = gconv.String(m["area"])
- node.Location = gconv.Int(m["location"])
- node.Href = fmt.Sprintf(consts.WebDomainFormat, node.Code)
- rootArr = append(rootArr, node)
- case consts.CityType:
- node.Name = gconv.String(m["city"])
- pNode := areaNameMap[gconv.String(m["area"])]
- node.PNode = pNode
- if pNode == nil {
- g.Log().Panic(ctx, "加载地区父级异常%s", node.Name)
- }
- node.Href = fmt.Sprintf("%s/%s/", pNode.Href, node.Code)
- pNode.Child = append(pNode.Child, node)
- }
- areaCodeMap[node.Code] = node
- areaNameMap[node.Name] = node
- }
- //加载区位
- for _, m := range g.Cfg("global").MustGet(context.Background(), "areaLocation").Maps() {
- tLocation := &AreaLocation{
- Name: gconv.String(m["name"]),
- AreaList: nil,
- }
- for _, areaCode := range gconv.Strings(m["values"]) {
- if node := areaCodeMap[areaCode]; node != nil {
- tLocation.AreaList = append(tLocation.AreaList, node)
- }
- }
- aRoot.Location = append(aRoot.Location, tLocation)
- }
- // 加载区位
- var location []*AreaLocation
- locationMap := map[int][]*AreaNode{}
- for _, node := range rootArr {
- locationMap[node.Location] = append(locationMap[node.Location], node)
- }
- for i := 1; i <= 7; i++ {
- location = append(location, &AreaLocation{
- Name: AreaLocationShowNameMap[i],
- AreaList: locationMap[i],
- })
- }
- // 加载首页配置
- nameCfgMap := map[string]*struct {
- Hots []string `json:"hots"`
- AdLink string `json:"adLink"`
- FLinks []struct {
- Name string `json:"name"`
- Href string `json:"href"`
- } `json:"fLinks"`
- }{}
- aRoot.areaCodeConfigMap = map[string]*AreaIndexConfig{}
- if err := g.Cfg("global").MustGet(context.Background(), "areaIndexConfig").Structs(&nameCfgMap); err == nil {
- for name, val := range nameCfgMap {
- if node := areaNameMap[name]; node != nil {
- cfg := &AreaIndexConfig{
- FLinks: val.FLinks,
- AdLink: val.AdLink,
- }
- for _, cityCode := range val.Hots {
- if city := node.GetChildNode(cityCode); city != nil {
- cfg.Hots = append(cfg.Hots, city)
- }
- }
- aRoot.areaCodeConfigMap[node.Code] = cfg
- }
- }
- }
- aRoot.areaCodeMap = areaCodeMap
- aRoot.areaNameMap = areaNameMap
- aRoot.rootList = rootArr
- aRoot.Location = location
- }
- // LoadAreasFrom 加载地区表示
- func (aRoot *AreaRoot) LoadAreasFromConfig(ctx context.Context) {
- areaCodeMap, areaNameMap := map[string]*AreaNode{}, map[string]*AreaNode{}
- var rootArr []*AreaNode
- for _, m := range g.Cfg("global").MustGet(context.Background(), "allAreaTree").Maps() {
- root := &AreaNode{
- Name: gconv.String(m["name"]),
- Code: gconv.String(m["code"]),
- }
- root.Href = fmt.Sprintf(consts.WebDomainFormat, root.Code)
- if gconv.Bool(m["special"]) {
- root.Type = consts.CitySpecialType
- } else {
- root.Type = consts.AreaType
- }
- for _, n := range gconv.Maps(m["child"]) {
- node := &AreaNode{
- Name: gconv.String(n["name"]),
- Code: gconv.String(n["code"]),
- Type: consts.CityType,
- PNode: root,
- }
- node.Href = fmt.Sprintf("%s/%s/", root.Href, node.Code)
- root.Child = append(root.Child, node)
- areaCodeMap[node.Code] = node
- areaNameMap[node.Name] = node
- }
- areaCodeMap[root.Code] = root
- areaNameMap[root.Name] = root
- rootArr = append(rootArr, root)
- }
- //加载区位
- for _, m := range g.Cfg("global").MustGet(context.Background(), "areaLocation").Maps() {
- tLocation := &AreaLocation{
- Name: gconv.String(m["name"]),
- AreaList: nil,
- }
- for _, areaCode := range gconv.Strings(m["values"]) {
- if node := areaCodeMap[areaCode]; node != nil {
- tLocation.AreaList = append(tLocation.AreaList, node)
- }
- }
- aRoot.Location = append(aRoot.Location, tLocation)
- }
- // 加载首页配置
- nameCfgMap := map[string]*struct {
- Hots []string `json:"hots"`
- AdLink string `json:"adLink"`
- FLinks []struct {
- Name string `json:"name"`
- Href string `json:"href"`
- } `json:"fLinks"`
- }{}
- aRoot.areaCodeConfigMap = map[string]*AreaIndexConfig{}
- if err := g.Cfg("global").MustGet(context.Background(), "areaIndexConfig").Structs(&nameCfgMap); err == nil {
- for name, val := range nameCfgMap {
- if node := areaNameMap[name]; node != nil {
- cfg := &AreaIndexConfig{
- FLinks: val.FLinks,
- AdLink: val.AdLink,
- }
- for _, cityCode := range val.Hots {
- if city := node.GetChildNode(cityCode); city != nil {
- cfg.Hots = append(cfg.Hots, city)
- }
- }
- aRoot.areaCodeConfigMap[node.Code] = cfg
- }
- }
- }
- aRoot.areaCodeMap = areaCodeMap
- aRoot.areaNameMap = areaNameMap
- aRoot.rootList = rootArr
- }
- // GetData 获取地区数据
- func (aRoot *AreaRoot) GetData(ctx context.Context, maxTotal int, query *SeoBiddingQuery) []map[string]interface{} {
- var sql string
- var values []interface{}
- if query.district != "" {
- sql += " AND b.district=? "
- values = append(values, query.district)
- } else if query.city != "" {
- sql += " AND b.city=? "
- values = append(values, query.city)
- } else if query.area != "" {
- sql += " AND b.area=? "
- values = append(values, query.area)
- }
- if query.topClass != "" {
- sql += " AND b.class1=? "
- values = append(values, query.topClass)
- }
- if query.status > 0 {
- sql += " AND b.status=? "
- values = append(values, query.status)
- }
- values = append(values, maxTotal)
- queryRes, err := g.DB().Query(ctx, fmt.Sprintf(`SELECT b.bid_id,b.seo_id
- FROM %s b
- WHERE 1=1 %s
- ORDER BY b.publish_time DESC,b.seo_id DESC
- LIMIT 0,?`, consts.TableName, sql), values...)
- if err != nil || queryRes.IsEmpty() {
- return nil
- }
- return FillingBiddingBaseFields(ctx, queryRes.List())
- }
- func (an *AreaNode) GetChildNode(code string) *AreaNode {
- if len(an.Child) == 0 {
- return nil
- }
- for _, node := range an.Child {
- if node.Code == code {
- return node
- }
- }
- return nil
- }
- // GetNodeByCode 根据code (部分城市有重复,请根据省份+GetChildNode code获取 ⚠️suzhou yulin yichun fuzhou taizhou)
- func (aRoot *AreaRoot) GetNodeByCode(code string) *AreaNode {
- return aRoot.areaCodeMap[code]
- }
- // GetNodeByName 根据省份名字获取node
- func (aRoot *AreaRoot) GetNodeByName(name string) *AreaNode {
- return aRoot.areaNameMap[name]
- }
- // GetAllRootNodes 获取全部根地区节点
- func (aRoot *AreaRoot) GetAllRootNodes() []*AreaNode {
- return aRoot.rootList
- }
- // GetAllLocation 获取所有区位
- func (aRoot *AreaRoot) GetAllLocation() []*AreaLocation {
- return aRoot.Location
- }
- // GetIndexConfigByCode 获取站点配置
- func (aRoot *AreaRoot) GetIndexConfigByCode(code string) *AreaIndexConfig {
- return aRoot.areaCodeConfigMap[code]
- }
- // GetSortLocation 获取关联区位信息
- // 规则:按现有的华东华中华南等分类,显示当前省份所在分类的其他省份,再显示下个地区分类的全部省份;以此类推循环;
- func (aRoot *AreaRoot) GetSortLocation(code string, num int) (rData []*AreaNode) {
- var isFind int = -1
- var findTimes int = 0
- findStart:
- for _, location := range aRoot.Location {
- if isFind < 0 {
- for _, node := range location.AreaList {
- if node.Code == code {
- isFind = 0
- break
- }
- }
- }
- if isFind >= 0 {
- for _, node := range location.AreaList {
- if node.Code != code {
- rData = append(rData, node)
- }
- }
- isFind++
- }
- if isFind >= 2 {
- return
- }
- }
- if findTimes < 2 {
- findTimes++
- goto findStart
- }
- return
- }
|