450 lines
13 KiB
Go
450 lines
13 KiB
Go
|
/*
|
|||
|
Package dao venue
|
|||
|
场馆(venue)=>场地(place)=>区域(area)的三级层次,均为一对多
|
|||
|
venue表冗余place_num表示场地数,
|
|||
|
place表通过ID对应place_polygon,存有area的地理位置信息
|
|||
|
*/
|
|||
|
|
|||
|
package dao
|
|||
|
|
|||
|
import (
|
|||
|
"context"
|
|||
|
"encoding/json"
|
|||
|
"fmt"
|
|||
|
|
|||
|
"go-common/app/service/openplatform/ticket-item/model"
|
|||
|
"go-common/library/cache/redis"
|
|||
|
"go-common/library/database/elastic"
|
|||
|
"go-common/library/ecode"
|
|||
|
"go-common/library/log"
|
|||
|
|
|||
|
"github.com/jinzhu/gorm"
|
|||
|
)
|
|||
|
|
|||
|
// RawVenues 批量获取场馆
|
|||
|
func (d *Dao) RawVenues(c context.Context, ids []int64) (vl map[int64]*model.Venue, err error) {
|
|||
|
vrows, err := d.db.Model(&model.Venue{}).Where("id in (?)", ids).Rows()
|
|||
|
vl = make(map[int64]*model.Venue)
|
|||
|
if err != nil {
|
|||
|
log.Error("RawVenues(%v) error(%v)", ids, err)
|
|||
|
return
|
|||
|
}
|
|||
|
defer vrows.Close()
|
|||
|
for vrows.Next() {
|
|||
|
var v model.Venue
|
|||
|
err = d.db.ScanRows(vrows, &v)
|
|||
|
vl[v.ID] = &v
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// CacheVenues 缓存批量获取场馆
|
|||
|
func (d *Dao) CacheVenues(c context.Context, ids []int64) (vl map[int64]*model.Venue, err error) {
|
|||
|
var keys []interface{}
|
|||
|
keyVidMap := make(map[string]int64, len(ids))
|
|||
|
for _, id := range ids {
|
|||
|
key := keyVenue(id)
|
|||
|
if _, ok := keyVidMap[key]; !ok {
|
|||
|
// duplicate pid
|
|||
|
keyVidMap[key] = id
|
|||
|
keys = append(keys, key)
|
|||
|
}
|
|||
|
}
|
|||
|
conn := d.redis.Get(c)
|
|||
|
defer conn.Close()
|
|||
|
var data [][]byte
|
|||
|
log.Info("MGET %v", model.JSONEncode(keys))
|
|||
|
if data, err = redis.ByteSlices((conn.Do("MGET", keys))); err != nil {
|
|||
|
log.Error("VenueList MGET %v ERR: %v", model.JSONEncode(keys), err)
|
|||
|
return
|
|||
|
}
|
|||
|
vl = make(map[int64]*model.Venue)
|
|||
|
for _, d := range data {
|
|||
|
if d != nil {
|
|||
|
var v *model.Venue
|
|||
|
vl[v.ID] = v
|
|||
|
json.Unmarshal(d, &v)
|
|||
|
}
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// AddCacheVenues 缓存场馆信息
|
|||
|
func (d *Dao) AddCacheVenues(c context.Context, vl map[int64]*model.Venue) (err error) {
|
|||
|
conn := d.redis.Get(c)
|
|||
|
defer func() {
|
|||
|
conn.Flush()
|
|||
|
conn.Close()
|
|||
|
}()
|
|||
|
var data []interface{}
|
|||
|
var keys []string
|
|||
|
for k, v := range vl {
|
|||
|
b, _ := json.Marshal(v)
|
|||
|
key := keyVenue(k)
|
|||
|
keys = append(keys, key)
|
|||
|
data = append(data, key, b)
|
|||
|
}
|
|||
|
log.Info("MSET %v", keys)
|
|||
|
if err = conn.Send("MSET", data...); err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
for i := 0; i < len(data); i += 2 {
|
|||
|
conn.Send("EXPIRE", data[i], CacheTimeout)
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// VenueSearch 场馆搜索
|
|||
|
func (d *Dao) VenueSearch(c context.Context, req *model.VenueSearchParam) (venues *model.VenueSearchList, err error) {
|
|||
|
r := d.es.NewRequest("ticket_venue").Index("ticket_venue")
|
|||
|
if req.ID > 0 {
|
|||
|
r.WhereEq("id", req.ID)
|
|||
|
} else if req.Name != "" {
|
|||
|
r.WhereLike([]string{"name"}, []string{req.Name}, false, elastic.LikeLevelLow)
|
|||
|
}
|
|||
|
if req.ProvinceID > 0 {
|
|||
|
r.WhereEq("province", req.ProvinceID)
|
|||
|
}
|
|||
|
if req.CityID > 0 {
|
|||
|
r.WhereEq("city", req.CityID)
|
|||
|
}
|
|||
|
r.Order("ctime", elastic.OrderDesc).Ps(req.Ps).Pn(req.Pn)
|
|||
|
log.Info(fmt.Sprintf("%s/x/admin/search/query?%s", d.c.URL.ElasticHost, r.Params()))
|
|||
|
|
|||
|
venues = new(model.VenueSearchList)
|
|||
|
if err = r.Scan(c, venues); err != nil {
|
|||
|
log.Error("VenueSearch(%v) r.Query(%s) error(%s)", req, r.Params(), err)
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// AddVenue 添加场馆信息
|
|||
|
func (d *Dao) AddVenue(c context.Context, venue *model.Venue) (err error) {
|
|||
|
if err = d.db.Create(venue).Error; err != nil {
|
|||
|
log.Error("添加场馆信息失败:%s", err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// UpdateVenue 编辑场馆信息
|
|||
|
func (d *Dao) UpdateVenue(c context.Context, venue *model.Venue) (err error) {
|
|||
|
// update venue with new info (using map can update the column with empty string)
|
|||
|
if err = d.db.Table("venue").Where("id = ?", venue.ID).Updates(
|
|||
|
map[string]interface{}{
|
|||
|
"name": venue.Name,
|
|||
|
"city": venue.City,
|
|||
|
"province": venue.Province,
|
|||
|
"district": venue.District,
|
|||
|
"address_detail": venue.AddressDetail,
|
|||
|
"status": venue.Status,
|
|||
|
"traffic": venue.Traffic,
|
|||
|
}).Error; err != nil {
|
|||
|
log.Error("更新场馆信息失败:%s", err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxIncPlaceNum 增加场馆的场地数(事务)
|
|||
|
func (d *Dao) TxIncPlaceNum(c context.Context, tx *gorm.DB, venueID int64) (err error) {
|
|||
|
var oriVenue model.Venue
|
|||
|
if err = tx.First(&oriVenue, venueID).Error; err != nil {
|
|||
|
log.Error("查找对应的场馆信息(ID:%d)失败:%s", venueID, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
if err = tx.Model(&oriVenue).Updates(
|
|||
|
map[string]interface{}{
|
|||
|
"place_num": oriVenue.PlaceNum + 1,
|
|||
|
}).Error; err != nil {
|
|||
|
log.Error("更新场馆信息(ID:%d)失败:%s", venueID, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxDecPlaceNum 减少场馆的场地数(事务)
|
|||
|
func (d *Dao) TxDecPlaceNum(c context.Context, tx *gorm.DB, venueID int64) (err error) {
|
|||
|
var oriVenue model.Venue
|
|||
|
if err = tx.First(&oriVenue, venueID).Error; err != nil {
|
|||
|
log.Error("查找对应的场馆信息(ID:%d)失败:%s", venueID, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
if oriVenue.PlaceNum < 1 {
|
|||
|
log.Error("更新场馆信息(ID:%d)失败:场地数小于1", venueID)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
if err = tx.Model(&oriVenue).Updates(
|
|||
|
map[string]interface{}{
|
|||
|
"place_num": oriVenue.PlaceNum - 1,
|
|||
|
}).Error; err != nil {
|
|||
|
log.Error("更新场馆信息(ID:%d)失败:%s", venueID, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// RawPlace 获取场地
|
|||
|
func (d *Dao) RawPlace(c context.Context, id int64) (place *model.Place, err error) {
|
|||
|
place = new(model.Place)
|
|||
|
err = d.db.Model(&model.Place{}).First(&place, id).Scan(&place).Error
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Error("RawPlace(%v) error(%v)", id, err)
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// RawPlacePolygon 获取场地坐标
|
|||
|
func (d *Dao) RawPlacePolygon(c context.Context, id int64) (placePolygon *model.PlacePolygon, err error) {
|
|||
|
placePolygon = new(model.PlacePolygon)
|
|||
|
err = d.db.Model(&model.PlacePolygon{}).First(&placePolygon, id).Scan(&placePolygon).Error
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Error("RawPlacePolygon(%v) error(%v)", id, err)
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxRawPlace 获取场地(事务)
|
|||
|
func (d *Dao) TxRawPlace(c context.Context, tx *gorm.DB, id int64) (place *model.Place, err error) {
|
|||
|
place = new(model.Place)
|
|||
|
err = tx.Model(&model.Place{}).First(&place, id).Scan(&place).Error
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Error("TxRawPlace(%v) error(%v)", id, err)
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// CachePlace 缓存获取场地
|
|||
|
func (d *Dao) CachePlace(c context.Context, id int64) (place *model.Place, err error) {
|
|||
|
var data []byte
|
|||
|
key := keyPlace(id)
|
|||
|
conn := d.redis.Get(c)
|
|||
|
defer conn.Close()
|
|||
|
log.Info("GET %v", key)
|
|||
|
if data, err = redis.Bytes((conn.Do("GET", key))); err != nil {
|
|||
|
if err == redis.ErrNil {
|
|||
|
err = nil
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
json.Unmarshal(data, &place)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// AddCachePlace 缓存场地信息
|
|||
|
func (d *Dao) AddCachePlace(c context.Context, id int64, place *model.Place) (err error) {
|
|||
|
conn := d.redis.Get(c)
|
|||
|
defer func() {
|
|||
|
conn.Flush()
|
|||
|
conn.Close()
|
|||
|
}()
|
|||
|
var data []interface{}
|
|||
|
key := keyPlace(id)
|
|||
|
data = append(data, key, place)
|
|||
|
log.Info("SET %v", key)
|
|||
|
if err = conn.Send("SET", data...); err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
conn.Send("EXPIRE", data[0], CacheTimeout)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxAddPlace 添加场地信息(事务)
|
|||
|
func (d *Dao) TxAddPlace(c context.Context, tx *gorm.DB, place *model.Place) (err error) {
|
|||
|
if err = tx.Create(place).Error; err != nil {
|
|||
|
log.Error("添加场地信息失败:%s", err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxUpdatePlace 编辑场地信息(事务)
|
|||
|
func (d *Dao) TxUpdatePlace(c context.Context, tx *gorm.DB, place *model.Place) (err error) {
|
|||
|
// find original place with id
|
|||
|
if err = tx.Table("place").Where("id = ?", place.ID).Update(
|
|||
|
map[string]interface{}{
|
|||
|
"name": place.Name,
|
|||
|
"base_pic": place.BasePic,
|
|||
|
"status": place.Status,
|
|||
|
"venue": place.Venue,
|
|||
|
"d_width": place.DWidth,
|
|||
|
"d_height": place.DHeight,
|
|||
|
}).Error; err != nil {
|
|||
|
log.Error("更新场地信息(ID:%d)失败:%s", place.ID, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxAddOrUpdateAreaPolygon 添加或更新区域的场地坐标信息(事务)
|
|||
|
func (d *Dao) TxAddOrUpdateAreaPolygon(c context.Context, tx *gorm.DB, place int64, area int64, coordinate *string) (err error) {
|
|||
|
var (
|
|||
|
oriPlacePolygon model.PlacePolygon
|
|||
|
coordinates map[int64]string
|
|||
|
found bool
|
|||
|
)
|
|||
|
if res := tx.First(&oriPlacePolygon, place); res.Error != nil {
|
|||
|
if !res.RecordNotFound() {
|
|||
|
log.Error("查找对应的场地坐标信息(ID:%d)失败:%s", place, res.Error)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
coordinates = make(map[int64]string)
|
|||
|
oriPlacePolygon.ID = place
|
|||
|
found = false
|
|||
|
} else {
|
|||
|
// 反序列化出coordinate字段
|
|||
|
if err = json.Unmarshal([]byte(oriPlacePolygon.Coordinate), &coordinates); err != nil {
|
|||
|
log.Error("数据库中的场地坐标信息(ID:%d)反序列化失败:%s", place, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
found = true
|
|||
|
}
|
|||
|
// 添加新的coordinate并序列化
|
|||
|
coordinates[area] = *coordinate
|
|||
|
b, _ := json.Marshal(coordinates)
|
|||
|
oriPlacePolygon.Coordinate = string(b)
|
|||
|
if found {
|
|||
|
if err = tx.Model(&oriPlacePolygon).Updates(
|
|||
|
map[string]interface{}{
|
|||
|
"coordinate": oriPlacePolygon.Coordinate,
|
|||
|
}).Error; err != nil {
|
|||
|
log.Error("更新场地坐标信息(ID:%d)失败:%s", place, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
} else {
|
|||
|
if err = tx.Create(oriPlacePolygon).Error; err != nil {
|
|||
|
log.Error("创建场地坐标信息(ID:%d)失败:%s", place, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
}
|
|||
|
*coordinate = oriPlacePolygon.Coordinate
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxDelAreaPolygon 删除区域的场地坐标信息(事务)
|
|||
|
func (d *Dao) TxDelAreaPolygon(c context.Context, tx *gorm.DB, place int64, area int64) (err error) {
|
|||
|
var (
|
|||
|
oriPlacePolygon model.PlacePolygon
|
|||
|
coordinates map[int64]string
|
|||
|
)
|
|||
|
if err = tx.First(&oriPlacePolygon, place).Error; err != nil {
|
|||
|
log.Error("查找对应的场地坐标信息(ID:%d)失败:%s", place, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
if oriPlacePolygon.Coordinate != "" {
|
|||
|
if err = json.Unmarshal([]byte(oriPlacePolygon.Coordinate), &coordinates); err != nil {
|
|||
|
log.Error("数据库中的场地坐标信息(ID:%d)反序列化失败:%s", place, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
} else {
|
|||
|
coordinates = make(map[int64]string)
|
|||
|
}
|
|||
|
|
|||
|
// 添加新的coordinate并序列化
|
|||
|
if _, ok := coordinates[area]; !ok {
|
|||
|
log.Error("数据库中的场地坐标信息(ID:%d)并未包含该区域(ID:%d),删除失败", place, area)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
delete(coordinates, area)
|
|||
|
b, _ := json.Marshal(coordinates)
|
|||
|
oriPlacePolygon.Coordinate = string(b)
|
|||
|
if err = tx.Model(&oriPlacePolygon).Updates(
|
|||
|
map[string]interface{}{
|
|||
|
"coordinate": oriPlacePolygon.Coordinate,
|
|||
|
}).Error; err != nil {
|
|||
|
log.Error("创建场地坐标信息(ID:%d)失败:%s", place, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// RawArea 获取区域
|
|||
|
func (d *Dao) RawArea(c context.Context, id int64) (area *model.Area, err error) {
|
|||
|
area = new(model.Area)
|
|||
|
if err = d.db.Where("deleted_status = 0").First(&area, id).Error; err != nil {
|
|||
|
log.Error("RawArea(%v) error(%v)", id, err)
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxRawArea 获取区域
|
|||
|
func (d *Dao) TxRawArea(c context.Context, tx *gorm.DB, id int64) (area *model.Area, err error) {
|
|||
|
area = new(model.Area)
|
|||
|
if err = tx.Where("deleted_status = 0").First(&area, id).Error; err != nil {
|
|||
|
log.Error("TxRawArea(%v) error(%v)", id, err)
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxRawDeletedAreaByAID 通过场地ID和自定义区域编号获取已删除的区域
|
|||
|
func (d *Dao) TxRawDeletedAreaByAID(c context.Context, tx *gorm.DB, aid string, place int64) (area *model.Area, err error) {
|
|||
|
area = new(model.Area)
|
|||
|
if res := tx.Where("deleted_status = 1").Where("a_id = ? AND place = ?", aid, place).First(&area); res.Error != nil {
|
|||
|
if res.RecordNotFound() {
|
|||
|
return nil, nil
|
|||
|
}
|
|||
|
err = res.Error
|
|||
|
log.Error("TxRawAreaByAID(%v, %v) error(%v)", aid, place, err)
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxAddArea 添加区域信息(事务)
|
|||
|
func (d *Dao) TxAddArea(c context.Context, tx *gorm.DB, area *model.Area) (err error) {
|
|||
|
if res := tx.Create(area); res.Error != nil {
|
|||
|
log.Error("添加区域信息失败:%s", res.Error)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxUpdateArea 编辑区域信息(事务)
|
|||
|
func (d *Dao) TxUpdateArea(c context.Context, tx *gorm.DB, area *model.Area) (err error) {
|
|||
|
if err = tx.Table("area").Where("id = ?", area.ID).Updates(
|
|||
|
map[string]interface{}{
|
|||
|
"a_id": area.AID,
|
|||
|
"name": area.Name,
|
|||
|
"place": area.Place,
|
|||
|
"deleted_status": area.DeletedStatus,
|
|||
|
}).Error; err != nil {
|
|||
|
log.Error("更新区域信息(ID:%d)失败:%s", area.ID, err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// TxDelArea 软删除区域(事务)
|
|||
|
func (d *Dao) TxDelArea(c context.Context, tx *gorm.DB, id int64) (err error) {
|
|||
|
if err = tx.Table("area").Where("id = ?", id).Updates(
|
|||
|
map[string]interface{}{
|
|||
|
"deleted_status": 1,
|
|||
|
}).Error; err != nil {
|
|||
|
log.Error("删除区域信息失败:%s", err)
|
|||
|
err = ecode.NotModified
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|