electricity_bill_calc_service/repository/park.go

419 lines
13 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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","norm_authorized_loss_rate",
).
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
}