419 lines
13 KiB
Go
419 lines
13 KiB
Go
package repository
|
||
|
||
import (
|
||
"context"
|
||
"electricity_bill_calc/global"
|
||
"electricity_bill_calc/logger"
|
||
"electricity_bill_calc/model"
|
||
"electricity_bill_calc/tools"
|
||
"electricity_bill_calc/tools/serial"
|
||
"electricity_bill_calc/types"
|
||
"github.com/doug-martin/goqu/v9"
|
||
_ "github.com/doug-martin/goqu/v9/dialect/postgres"
|
||
"github.com/georgysavva/scany/v2/pgxscan"
|
||
"github.com/jackc/pgx/v5"
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
type _ParkRepository struct {
|
||
log *zap.Logger
|
||
ds goqu.DialectWrapper
|
||
}
|
||
|
||
var ParkRepository = _ParkRepository{
|
||
log: logger.Named("Repository", "Park"),
|
||
ds: goqu.Dialect("postgres"),
|
||
}
|
||
|
||
// 列出指定用户下的所有园区
|
||
func (pr _ParkRepository) ListAllParks(uid string) ([]*model.Park, error) {
|
||
pr.log.Info("列出指定用户下的所有园区", zap.String("uid", uid))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
var parks = make([]*model.Park, 0)
|
||
parkQuerySql, parkParams, _ := pr.ds.
|
||
From("park").
|
||
Select(
|
||
"id", "user_id", "name", "area", "tenement_quantity", "capacity", "category",
|
||
"meter_04kv_type", "region", "address", "contact", "phone", "enabled", "price_policy", "tax_rate",
|
||
"basic_pooled", "adjust_pooled", "loss_pooled", "public_pooled", "created_at", "last_modified_at",
|
||
"deleted_at",
|
||
).
|
||
Where(
|
||
goqu.I("user_id").Eq(uid),
|
||
goqu.I("deleted_at").IsNull(),
|
||
).
|
||
Order(goqu.I("created_at").Asc()).
|
||
Prepared(true).ToSQL()
|
||
if err := pgxscan.Select(ctx, global.DB, &parks, parkQuerySql, parkParams...); err != nil {
|
||
pr.log.Error("列出指定用户下的所有园区失败!", zap.Error(err))
|
||
return make([]*model.Park, 0), err
|
||
}
|
||
return parks, nil
|
||
}
|
||
|
||
// 检查并确定指定园区的归属情况
|
||
func (pr _ParkRepository) IsParkBelongs(pid, uid string) (bool, error) {
|
||
pr.log.Info("检查并确定指定园区的归属情况", zap.String("pid", pid), zap.String("uid", uid))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
var count int64
|
||
parkQuerySql, parkParams, _ := pr.ds.
|
||
From("park").
|
||
Select(goqu.COUNT("*")).
|
||
Where(
|
||
goqu.I("id").Eq(pid),
|
||
goqu.I("user_id").Eq(uid),
|
||
).
|
||
Prepared(true).ToSQL()
|
||
if err := pgxscan.Get(ctx, global.DB, &count, parkQuerySql, parkParams...); err != nil {
|
||
pr.log.Error("检查并确定指定园区的归属情况失败!", zap.Error(err))
|
||
return false, err
|
||
}
|
||
return count > 0, nil
|
||
}
|
||
|
||
// 创建一个属于指定用户的新园区。该创建功能不会对园区的名称进行检查。
|
||
func (pr _ParkRepository) CreatePark(ownerId string, park *model.Park) (bool, error) {
|
||
pr.log.Info("创建一个属于指定用户的新园区", zap.String("ownerId", ownerId))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
timeNow := types.Now()
|
||
serial.StringSerialRequestChan <- 1
|
||
code := serial.Prefix("P", <-serial.StringSerialResponseChan)
|
||
createSql, createArgs, _ := pr.ds.
|
||
Insert("park").
|
||
Cols(
|
||
"id", "user_id", "name", "abbr", "area", "tenement_quantity", "capacity", "category",
|
||
"meter_04kv_type", "region", "address", "contact", "phone", "enabled", "price_policy", "tax_rate",
|
||
"basic_pooled", "adjust_pooled", "loss_pooled", "public_pooled", "created_at", "last_modified_at",
|
||
).
|
||
Vals(goqu.Vals{
|
||
code,
|
||
ownerId, park.Name, tools.PinyinAbbr(park.Name),
|
||
park.Area, park.TenementQuantity, park.Capacity, park.Category,
|
||
park.MeterType, park.Region, park.Address, park.Contact, park.Phone, park.Enabled, park.PricePolicy, park.TaxRate,
|
||
park.BasicPooled, park.AdjustPooled, park.LossPooled, park.PublicPooled, timeNow, timeNow,
|
||
}).
|
||
Prepared(true).ToSQL()
|
||
rs, err := global.DB.Exec(ctx, createSql, createArgs...)
|
||
if err != nil {
|
||
pr.log.Error("创建一个属于指定用户的新园区失败!", zap.Error(err))
|
||
return false, err
|
||
}
|
||
return rs.RowsAffected() > 0, nil
|
||
}
|
||
|
||
// 获取指定园区的详细信息
|
||
func (pr _ParkRepository) RetrieveParkDetail(pid string) (*model.Park, error) {
|
||
pr.log.Info("获取指定园区的详细信息", zap.String("pid", pid))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
var park model.Park
|
||
parkSql, parkArgs, _ := pr.ds.
|
||
From("park").
|
||
Select(
|
||
"id", "user_id", "name", "area", "tenement_quantity", "capacity", "category",
|
||
"meter_04kv_type", "region", "address", "contact", "phone", "enabled", "price_policy", "tax_rate",
|
||
"basic_pooled", "adjust_pooled", "loss_pooled", "public_pooled", "created_at", "last_modified_at",
|
||
"deleted_at",
|
||
).
|
||
Where(goqu.I("id").Eq(pid)).
|
||
Prepared(true).ToSQL()
|
||
if err := pgxscan.Get(ctx, global.DB, &park, parkSql, parkArgs...); err != nil {
|
||
pr.log.Error("获取指定园区的详细信息失败!", zap.Error(err))
|
||
return nil, err
|
||
}
|
||
return &park, nil
|
||
}
|
||
|
||
// 获取园区对应的用户ID
|
||
func (pr _ParkRepository) RetrieveParkBelongs(pid string) (string, error) {
|
||
pr.log.Info("获取园区对应的用户ID", zap.String("pid", pid))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
var uid string
|
||
parkSql, parkArgs, _ := pr.ds.
|
||
From("park").
|
||
Select(goqu.I("user_id")).
|
||
Where(goqu.I("id").Eq(pid)).
|
||
Prepared(true).ToSQL()
|
||
if err := pgxscan.Get(ctx, global.DB, &uid, parkSql, parkArgs...); err != nil {
|
||
pr.log.Error("获取园区对应的用户ID失败!", zap.Error(err))
|
||
return "", err
|
||
}
|
||
return uid, nil
|
||
}
|
||
|
||
// 更新指定园区的信息
|
||
func (pr _ParkRepository) UpdatePark(pid string, park *model.Park) (bool, error) {
|
||
pr.log.Info("更新指定园区的信息", zap.String("pid", pid))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
timeNow := types.Now()
|
||
updateSql, updateArgs, _ := pr.ds.
|
||
Update("park").
|
||
Set(goqu.Record{
|
||
"name": park.Name,
|
||
"abbr": tools.PinyinAbbr(park.Name),
|
||
"area": park.Area,
|
||
"tenement_quantity": park.TenementQuantity,
|
||
"capacity": park.Capacity,
|
||
"category": park.Category,
|
||
"meter_04kv_type": park.MeterType,
|
||
"region": park.Region,
|
||
"address": park.Address,
|
||
"contact": park.Contact,
|
||
"phone": park.Phone,
|
||
"price_policy": park.PricePolicy,
|
||
"tax_rate": park.TaxRate,
|
||
"basic_pooled": park.BasicPooled,
|
||
"adjust_pooled": park.AdjustPooled,
|
||
"loss_pooled": park.LossPooled,
|
||
"public_pooled": park.PublicPooled,
|
||
"last_modified_at": timeNow,
|
||
}).
|
||
Where(goqu.I("id").Eq(pid)).
|
||
Prepared(true).ToSQL()
|
||
|
||
ok, err := global.DB.Exec(ctx, updateSql, updateArgs...)
|
||
if err != nil {
|
||
pr.log.Error("更新指定园区的信息失败!", zap.Error(err))
|
||
return false, err
|
||
}
|
||
return ok.RowsAffected() > 0, nil
|
||
}
|
||
|
||
// 设定园区的可用状态
|
||
func (pr _ParkRepository) EnablingPark(pid string, enabled bool) (bool, error) {
|
||
pr.log.Info("设定园区的可用状态", zap.String("pid", pid), zap.Bool("enabled", enabled))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
timeNow := types.Now()
|
||
updateSql, updateArgs, _ := pr.ds.
|
||
Update("park").
|
||
Set(goqu.Record{
|
||
"enabled": enabled,
|
||
"last_modified_at": timeNow,
|
||
}).
|
||
Where(goqu.I("id").Eq(pid)).
|
||
Prepared(true).ToSQL()
|
||
|
||
ok, err := global.DB.Exec(ctx, updateSql, updateArgs...)
|
||
if err != nil {
|
||
pr.log.Error("设定园区的可用状态失败!", zap.Error(err))
|
||
return false, err
|
||
}
|
||
return ok.RowsAffected() > 0, nil
|
||
}
|
||
|
||
// 删除指定园区(软删除)
|
||
func (pr _ParkRepository) DeletePark(pid string) (bool, error) {
|
||
pr.log.Info("删除指定园区(软删除)", zap.String("pid", pid))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
timeNow := types.Now()
|
||
updateSql, updateArgs, _ := pr.ds.
|
||
Update("park").
|
||
Set(goqu.Record{
|
||
"deleted_at": timeNow,
|
||
"last_modified_at": timeNow,
|
||
}).
|
||
Where(goqu.I("id").Eq(pid)).
|
||
Prepared(true).ToSQL()
|
||
|
||
ok, err := global.DB.Exec(ctx, updateSql, updateArgs...)
|
||
if err != nil {
|
||
pr.log.Error("删除指定园区(软删除)失败!", zap.Error(err))
|
||
return false, err
|
||
}
|
||
return ok.RowsAffected() > 0, nil
|
||
}
|
||
|
||
// 检索给定的园区详细信息列表
|
||
func (pr _ParkRepository) RetrieveParks(pids []string) ([]*model.Park, error) {
|
||
pr.log.Info("检索给定的园区详细信息列表", zap.Strings("pids", pids))
|
||
if len(pids) == 0 {
|
||
pr.log.Info("给定要检索的园区ID列表为空,执行快速返回。")
|
||
return make([]*model.Park, 0), nil
|
||
}
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
var parks []*model.Park
|
||
parkSql, parkArgs, _ := pr.ds.
|
||
From("park").
|
||
Where(goqu.I("id").In(pids)).
|
||
Prepared(true).ToSQL()
|
||
if err := pgxscan.Select(ctx, global.DB, &parks, parkSql, parkArgs...); err != nil {
|
||
pr.log.Error("检索给定的园区详细信息列表失败!", zap.Error(err))
|
||
return nil, err
|
||
}
|
||
return parks, nil
|
||
}
|
||
|
||
// 获取指定园区中的建筑
|
||
func (pr _ParkRepository) RetrieveParkBuildings(pid string) ([]*model.ParkBuilding, error) {
|
||
pr.log.Info("获取指定园区中的建筑", zap.String("pid", pid))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
var buildings []*model.ParkBuilding
|
||
buildingSql, buildingArgs, _ := pr.ds.
|
||
From("park_building").
|
||
Where(
|
||
goqu.I("park_id").Eq(pid),
|
||
goqu.I("deleted_at").IsNull(),
|
||
).
|
||
Order(goqu.I("created_at").Asc()).
|
||
Prepared(true).ToSQL()
|
||
|
||
if err := pgxscan.Select(ctx, global.DB, &buildings, buildingSql, buildingArgs...); err != nil {
|
||
pr.log.Error("获取指定园区中的建筑失败!", zap.Error(err))
|
||
return nil, err
|
||
}
|
||
return buildings, nil
|
||
}
|
||
|
||
// 在指定园区中创建一个新建筑
|
||
func (pr _ParkRepository) CreateParkBuilding(pid, name string, floor *string) (bool, error) {
|
||
pr.log.Info("在指定园区中创建一个新建筑", zap.String("pid", pid), zap.String("name", name), zap.Stringp("floor", floor))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
timeNow := types.Now()
|
||
serial.StringSerialRequestChan <- 1
|
||
code := serial.Prefix("B", <-serial.StringSerialResponseChan)
|
||
createSql, createArgs, _ := pr.ds.
|
||
Insert("park_building").
|
||
Cols(
|
||
"id", "park_id", "name", "floors", "enabled", "created_at", "last_modified_at",
|
||
).
|
||
Vals(goqu.Vals{
|
||
code,
|
||
pid, name, floor, true, timeNow, timeNow,
|
||
}).
|
||
Prepared(true).ToSQL()
|
||
|
||
rs, err := global.DB.Exec(ctx, createSql, createArgs...)
|
||
if err != nil {
|
||
pr.log.Error("在指定园区中创建一个新建筑失败!", zap.Error(err))
|
||
return false, err
|
||
}
|
||
return rs.RowsAffected() > 0, nil
|
||
}
|
||
|
||
// 在指定园区中创建一个建筑,这个方法会使用事务
|
||
func (pr _ParkRepository) CreateParkBuildingWithTransaction(tx pgx.Tx, ctx context.Context, pid, name string, floor *string) (bool, error) {
|
||
timeNow := types.Now()
|
||
serial.StringSerialRequestChan <- 1
|
||
code := serial.Prefix("B", <-serial.StringSerialResponseChan)
|
||
createSql, createArgs, _ := pr.ds.
|
||
Insert("park_building").
|
||
Cols(
|
||
"id", "park_id", "name", "floors", "enabled", "created_at", "last_modified_at",
|
||
).
|
||
Vals(goqu.Vals{
|
||
code,
|
||
pid, name, floor, true, timeNow, timeNow,
|
||
}).
|
||
Prepared(true).ToSQL()
|
||
|
||
rs, err := tx.Exec(ctx, createSql, createArgs...)
|
||
if err != nil {
|
||
pr.log.Error("在指定园区中创建一个新建筑失败!", zap.Error(err))
|
||
return false, err
|
||
}
|
||
return rs.RowsAffected() > 0, nil
|
||
}
|
||
|
||
// 修改指定园区中指定建筑的信息
|
||
func (pr _ParkRepository) ModifyParkBuilding(id, pid, name string, floor *string) (bool, error) {
|
||
pr.log.Info("修改指定园区中指定建筑的信息", zap.String("id", id), zap.String("pid", pid), zap.String("name", name), zap.Stringp("floor", floor))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
timeNow := types.Now()
|
||
updateSql, updateArgs, _ := pr.ds.
|
||
Update("park_building").
|
||
Set(goqu.Record{
|
||
"name": name,
|
||
"floors": floor,
|
||
"last_modified_at": timeNow,
|
||
}).
|
||
Where(
|
||
goqu.I("id").Eq(id),
|
||
goqu.I("park_id").Eq(pid),
|
||
).
|
||
Prepared(true).ToSQL()
|
||
|
||
rs, err := global.DB.Exec(ctx, updateSql, updateArgs...)
|
||
if err != nil {
|
||
pr.log.Error("修改指定园区中指定建筑的信息失败!", zap.Error(err))
|
||
return false, err
|
||
}
|
||
return rs.RowsAffected() > 0, nil
|
||
}
|
||
|
||
// 修改指定建筑的可以状态
|
||
func (pr _ParkRepository) EnablingParkBuilding(id, pid string, enabled bool) (bool, error) {
|
||
pr.log.Info("修改指定建筑的可以状态", zap.String("id", id), zap.String("pid", pid), zap.Bool("enabled", enabled))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
timeNow := types.Now()
|
||
updateSql, updateArgs, _ := pr.ds.
|
||
Update("park_building").
|
||
Set(goqu.Record{
|
||
"enabled": enabled,
|
||
"last_modified_at": timeNow,
|
||
}).
|
||
Where(
|
||
goqu.I("id").Eq(id),
|
||
goqu.I("park_id").Eq(pid),
|
||
).
|
||
Prepared(true).ToSQL()
|
||
|
||
rs, err := global.DB.Exec(ctx, updateSql, updateArgs...)
|
||
if err != nil {
|
||
pr.log.Error("修改指定建筑的可以状态失败!", zap.Error(err))
|
||
return false, err
|
||
}
|
||
return rs.RowsAffected() > 0, nil
|
||
}
|
||
|
||
// 删除指定建筑(软删除)
|
||
func (pr _ParkRepository) DeleteParkBuilding(id, pid string) (bool, error) {
|
||
pr.log.Info("删除指定建筑(软删除)", zap.String("id", id), zap.String("pid", pid))
|
||
ctx, cancel := global.TimeoutContext()
|
||
defer cancel()
|
||
|
||
timeNow := types.Now()
|
||
updateSql, updateArgs, _ := pr.ds.
|
||
Update("park_building").
|
||
Set(goqu.Record{
|
||
"deleted_at": timeNow,
|
||
"last_modified_at": timeNow,
|
||
}).
|
||
Where(
|
||
goqu.I("id").Eq(id),
|
||
goqu.I("park_id").Eq(pid),
|
||
).
|
||
Prepared(true).ToSQL()
|
||
|
||
rs, err := global.DB.Exec(ctx, updateSql, updateArgs...)
|
||
if err != nil {
|
||
pr.log.Error("删除指定建筑(软删除)失败!", zap.Error(err))
|
||
return false, err
|
||
}
|
||
return rs.RowsAffected() > 0, nil
|
||
}
|