168 lines
4.1 KiB
Go
Executable File
168 lines
4.1 KiB
Go
Executable File
package store
|
|
|
|
import (
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"git.zhouxhere.com/zhouxhere/maptile/model"
|
|
"github.com/google/uuid"
|
|
"github.com/pkg/errors"
|
|
"github.com/twpayne/go-geom"
|
|
"github.com/twpayne/go-geom/encoding/geojson"
|
|
)
|
|
|
|
// ListFeature 获取要素列表
|
|
func (s *Store) ListFeature(query *model.FeatureList) ([]model.Feature, int, error) {
|
|
queryStr := `
|
|
SELECT id, name, ST_AsGeoJSON(geometry) AS geometry, status, created_at, updated_at
|
|
FROM feature WHERE 1 = 1
|
|
`
|
|
if query.Status != "" {
|
|
queryStr += " AND status = :status"
|
|
}
|
|
if query.Name != "" {
|
|
queryStr += " AND name LIKE :name"
|
|
}
|
|
queryStr += " ORDER BY status, created_at DESC"
|
|
queryStr += " LIMIT :limit OFFSET :offset"
|
|
|
|
namedParams := map[string]interface{}{
|
|
"status": query.Status,
|
|
"name": "'%" + query.Name + "%'",
|
|
"limit": query.Size,
|
|
"offset": (query.Page - 1) * query.Size,
|
|
}
|
|
|
|
queryStr, args, err := s.DB.BindNamed(queryStr, namedParams)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// 执行查询
|
|
features := []model.Feature{}
|
|
|
|
if err := s.DB.Select(&features, queryStr, args...); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
countQuery := `
|
|
SELECT COUNT(*) FROM feature WHERE 1 = 1
|
|
`
|
|
if query.Status != "" {
|
|
countQuery += " AND status = :status"
|
|
}
|
|
if query.Name != "" {
|
|
countQuery += " AND name LIKE :name"
|
|
}
|
|
|
|
countQuery, countArgs, err := s.DB.BindNamed(countQuery, namedParams)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
var count int
|
|
if err := s.DB.Get(&count, countQuery, countArgs...); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return features, count, nil
|
|
}
|
|
|
|
// GetFeatureByID 获取要素
|
|
func (s *Store) GetFeatureByID(id uuid.UUID) (*model.Feature, error) {
|
|
query := `
|
|
SELECT id, name, ST_AsGeoJSON(geometry) AS geometry, status, created_at, updated_at
|
|
FROM feature
|
|
WHERE id = :id
|
|
`
|
|
f := &model.Feature{}
|
|
if err := s.DB.Get(f, query, id); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return f, nil
|
|
}
|
|
|
|
// CreateFeature 创建要素
|
|
func (s *Store) CreateFeature(feature *model.FeatureCreate) (*model.Feature, error) {
|
|
// 将传入的 JSON 格式的 geometry 转换为 geom.T 类型
|
|
geometryBytes, err := json.Marshal(feature.Geometry)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var geomT geom.T
|
|
if err := geojson.Unmarshal(geometryBytes, &geomT); err != nil {
|
|
return nil, errors.New("invalid GeoJSON format")
|
|
}
|
|
query := `
|
|
INSERT INTO feature (id, name, geometry, status, created_at, updated_at)
|
|
VALUES (:id, :name, ST_GeomFromGeoJSON(:geometry), :status, :created_at, :updated_at)
|
|
`
|
|
|
|
f := &model.Feature{
|
|
ID: uuid.New(),
|
|
Name: feature.Name,
|
|
Geometry: geometryBytes,
|
|
Status: model.StatusNormal,
|
|
CreatedAt: time.Now().Unix(),
|
|
UpdatedAt: time.Now().Unix(),
|
|
}
|
|
_, err = s.DB.NamedExec(query, f)
|
|
return f, err
|
|
}
|
|
|
|
// UpdateFeature 更新要素
|
|
func (s *Store) UpdateFeature(feature *model.FeatureUpdate) (*model.Feature, error) {
|
|
// 将传入的 JSON 格式的 geometry 转换为 geom.T 类型
|
|
geometryBytes, err := json.Marshal(feature.Geometry)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var geomT geom.T
|
|
if err := geojson.Unmarshal(geometryBytes, &geomT); err != nil {
|
|
return nil, errors.New("invalid GeoJSON format")
|
|
}
|
|
|
|
query := `
|
|
UPDATE feature
|
|
SET name = :name, geometry = ST_GeomFromGeoJSON(:geometry), updated_at = :updated_at
|
|
WHERE id = :id
|
|
`
|
|
f := &model.Feature{
|
|
ID: feature.ID,
|
|
Name: feature.Name,
|
|
Geometry: geometryBytes,
|
|
UpdatedAt: time.Now().Unix(),
|
|
}
|
|
_, err = s.DB.NamedExec(query, f)
|
|
return f, err
|
|
}
|
|
|
|
// DeleteFeature 删除要素
|
|
func (s *Store) DeleteFeature(feature *model.FeatureDeleteOrBanned) error {
|
|
query := `
|
|
UPDATE feature SET status = :status, updated_at = :updated_at WHERE id = :id
|
|
`
|
|
f := &model.Feature{
|
|
ID: feature.ID,
|
|
Status: model.StatusDeleted,
|
|
UpdatedAt: time.Now().Unix(),
|
|
}
|
|
_, err := s.DB.NamedExec(query, f)
|
|
return err
|
|
}
|
|
|
|
// BannedFeature 禁用要素
|
|
func (s *Store) BannedFeature(feature *model.FeatureDeleteOrBanned) error {
|
|
query := `
|
|
UPDATE feature SET status = :status, updated_at = :updated_at WHERE id = :id
|
|
`
|
|
f := &model.Feature{
|
|
ID: feature.ID,
|
|
Status: model.StatusBanned,
|
|
UpdatedAt: time.Now().Unix(),
|
|
}
|
|
_, err := s.DB.NamedExec(query, f)
|
|
return err
|
|
}
|