forked from free-lancers/electricity_bill_calc_service
		
	Merge pull request 'enhance(calculate): 完善计算部分' (#3) from Deka_123/electricity_bill_calc_service:newBranch into 0.2
Reviewed-on: free-lancers/electricity_bill_calc_service#3
This commit is contained in:
		
							
								
								
									
										9
									
								
								.idea/0.2.iml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.idea/0.2.iml
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <module type="WEB_MODULE" version="4"> | ||||
|   <component name="Go" enabled="true" /> | ||||
|   <component name="NewModuleRootManager"> | ||||
|     <content url="file://$MODULE_DIR$" /> | ||||
|     <orderEntry type="inheritedJdk" /> | ||||
|     <orderEntry type="sourceFolder" forTests="false" /> | ||||
|   </component> | ||||
| </module> | ||||
							
								
								
									
										2
									
								
								.idea/modules.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/modules.xml
									
									
									
										generated
									
									
									
								
							| @@ -2,7 +2,7 @@ | ||||
| <project version="4"> | ||||
|   <component name="ProjectModuleManager"> | ||||
|     <modules> | ||||
|       <module fileurl="file://$PROJECT_DIR$/.idea/electricity_bill_calc_service.iml" filepath="$PROJECT_DIR$/.idea/electricity_bill_calc_service.iml" /> | ||||
|       <module fileurl="file://$PROJECT_DIR$/.idea/0.2.iml" filepath="$PROJECT_DIR$/.idea/0.2.iml" /> | ||||
|     </modules> | ||||
|   </component> | ||||
| </project> | ||||
							
								
								
									
										2
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project version="4"> | ||||
|   <component name="VcsDirectoryMappings"> | ||||
|     <mapping directory="$PROJECT_DIR$" vcs="Git" /> | ||||
|     <mapping directory="" vcs="Git" /> | ||||
|   </component> | ||||
| </project> | ||||
							
								
								
									
										183
									
								
								_1.gitignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								_1.gitignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | ||||
| # If you prefer the allow list template instead of the deny list, see community template: | ||||
| # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore | ||||
| # | ||||
| # Binaries for programs and plugins | ||||
| *.exe | ||||
| *.exe~ | ||||
| *.dll | ||||
| *.so | ||||
| *.dylib | ||||
|  | ||||
| # Test binary, built with `go test -c` | ||||
| *.test | ||||
|  | ||||
| # Output of the go coverage tool, specifically when used with LiteIDE | ||||
| *.out | ||||
|  | ||||
| # Dependency directories (remove the comment below to include it) | ||||
| # vendor/ | ||||
|  | ||||
| # Go workspace file | ||||
| go.work | ||||
|  | ||||
| # Windows thumbnail cache files | ||||
| Thumbs.db | ||||
| Thumbs.db:encryptable | ||||
| ehthumbs.db | ||||
| ehthumbs_vista.db | ||||
|  | ||||
| # Dump file | ||||
| *.stackdump | ||||
|  | ||||
| # Folder config file | ||||
| [Dd]esktop.ini | ||||
|  | ||||
| # Recycle Bin used on file shares | ||||
| $RECYCLE.BIN/ | ||||
|  | ||||
| # Windows Installer files | ||||
| *.cab | ||||
| *.msi | ||||
| *.msix | ||||
| *.msm | ||||
| *.msp | ||||
|  | ||||
| # Windows shortcuts | ||||
| *.lnk | ||||
|  | ||||
| # General | ||||
| .DS_Store | ||||
| .AppleDouble | ||||
| .LSOverride | ||||
|  | ||||
| # Icon must end with two \r | ||||
| Icon | ||||
|  | ||||
| # Thumbnails | ||||
| ._* | ||||
|  | ||||
| # Files that might appear in the root of a volume | ||||
| .DocumentRevisions-V100 | ||||
| .fseventsd | ||||
| .Spotlight-V100 | ||||
| .TemporaryItems | ||||
| .Trashes | ||||
| .VolumeIcon.icns | ||||
| .com.apple.timemachine.donotpresent | ||||
|  | ||||
| # Directories potentially created on remote AFP share | ||||
| .AppleDB | ||||
| .AppleDesktop | ||||
| Network Trash Folder | ||||
| Temporary Items | ||||
| .apdisk | ||||
|  | ||||
| *~ | ||||
|  | ||||
| # temporary files which can be created if a process still has a handle open of a deleted file | ||||
| .fuse_hidden* | ||||
|  | ||||
| # KDE directory preferences | ||||
| .directory | ||||
|  | ||||
| # Linux trash folder which might appear on any partition or disk | ||||
| .Trash-* | ||||
|  | ||||
| # .nfs files are created when an open file is removed but is still being accessed | ||||
| .nfs* | ||||
|  | ||||
| .vscode/* | ||||
| !.vscode/settings.json | ||||
| !.vscode/tasks.json | ||||
| !.vscode/launch.json | ||||
| !.vscode/extensions.json | ||||
| !.vscode/*.code-snippets | ||||
|  | ||||
| # Local History for Visual Studio Code | ||||
| .history/ | ||||
|  | ||||
| # Built Visual Studio Code Extensions | ||||
| *.vsix | ||||
|  | ||||
| # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider | ||||
| # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||||
|  | ||||
| # User-specific stuff | ||||
| .idea/**/workspace.xml | ||||
| .idea/**/tasks.xml | ||||
| .idea/**/usage.statistics.xml | ||||
| .idea/**/dictionaries | ||||
| .idea/**/shelf | ||||
|  | ||||
| # AWS User-specific | ||||
| .idea/**/aws.xml | ||||
|  | ||||
| # Generated files | ||||
| .idea/**/contentModel.xml | ||||
|  | ||||
| # Sensitive or high-churn files | ||||
| .idea/**/dataSources/ | ||||
| .idea/**/dataSources.ids | ||||
| .idea/**/dataSources.local.xml | ||||
| .idea/**/sqlDataSources.xml | ||||
| .idea/**/dynamic.xml | ||||
| .idea/**/uiDesigner.xml | ||||
| .idea/**/dbnavigator.xml | ||||
|  | ||||
| # Gradle | ||||
| .idea/**/gradle.xml | ||||
| .idea/**/libraries | ||||
|  | ||||
| # Gradle and Maven with auto-import | ||||
| # When using Gradle or Maven with auto-import, you should exclude module files, | ||||
| # since they will be recreated, and may cause churn.  Uncomment if using | ||||
| # auto-import. | ||||
| # .idea/artifacts | ||||
| # .idea/compiler.xml | ||||
| # .idea/jarRepositories.xml | ||||
| # .idea/modules.xml | ||||
| # .idea/*.iml | ||||
| # .idea/modules | ||||
| # *.iml | ||||
| # *.ipr | ||||
|  | ||||
| # CMake | ||||
| cmake-build-*/ | ||||
|  | ||||
| # Mongo Explorer plugin | ||||
| .idea/**/mongoSettings.xml | ||||
|  | ||||
| # File-based project format | ||||
| *.iws | ||||
|  | ||||
| # IntelliJ | ||||
| out/ | ||||
|  | ||||
| # mpeltonen/sbt-idea plugin | ||||
| .idea_modules/ | ||||
|  | ||||
| # JIRA plugin | ||||
| atlassian-ide-plugin.xml | ||||
|  | ||||
| # Cursive Clojure plugin | ||||
| .idea/replstate.xml | ||||
|  | ||||
| # SonarLint plugin | ||||
| .idea/sonarlint/ | ||||
|  | ||||
| # Crashlytics plugin (for Android Studio and IntelliJ) | ||||
| com_crashlytics_export_strings.xml | ||||
| crashlytics.properties | ||||
| crashlytics-build.properties | ||||
| fabric.properties | ||||
|  | ||||
| # Editor-based Rest Client | ||||
| .idea/httpRequests | ||||
|  | ||||
| # Android studio 3.1+ serialized cache file | ||||
| .idea/caches/build_file_checksums.ser | ||||
|  | ||||
| # Block sensitive configuration files | ||||
| settings.local.yaml | ||||
| log/ | ||||
| __debug_bin | ||||
| @@ -36,7 +36,7 @@ type ServiceSetting struct { | ||||
| 	HostSerial     int64 | ||||
| } | ||||
|  | ||||
| //读取基准线损率 | ||||
| // 读取基准线损率 | ||||
| type BaseLossSetting struct { | ||||
| 	Base string | ||||
| } | ||||
|   | ||||
| @@ -23,6 +23,7 @@ func InitializeReportHandlers(router *fiber.App) { | ||||
| 	router.Get("/reports", security.MustAuthenticated, reportComprehensiveSearch) | ||||
| 	router.Post("/report", security.EnterpriseAuthorize, initNewReportCalculateTask) | ||||
| 	router.Get("/report/draft", security.EnterpriseAuthorize, listDraftReportIndicies) | ||||
| 	router.Post("/report/calcualte", security.EnterpriseAuthorize, testCalculateReportSummary) | ||||
| 	//TODO: 2023-07-20将calcualte错误请求改为正确的calculate请求 | ||||
| 	router.Post("/report/calculate", security.EnterpriseAuthorize, testCalculateReportSummary) | ||||
| 	router.Get("/report/calculate/status", security.EnterpriseAuthorize, listCalculateTaskStatus) | ||||
|   | ||||
							
								
								
									
										121
									
								
								controller/sync.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								controller/sync.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| package controller | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/logger" | ||||
| 	"electricity_bill_calc/model" | ||||
| 	"electricity_bill_calc/repository" | ||||
| 	"electricity_bill_calc/response" | ||||
| 	"electricity_bill_calc/security" | ||||
| 	"electricity_bill_calc/service" | ||||
| 	"electricity_bill_calc/tools" | ||||
| 	"electricity_bill_calc/vo" | ||||
| 	"fmt" | ||||
| 	"github.com/gofiber/fiber/v2" | ||||
| 	"go.uber.org/zap" | ||||
| ) | ||||
|  | ||||
| var synchronizeLog = logger.Named("Handler", "Synchronize") | ||||
|  | ||||
| func InitializeSynchronizeHandlers(router *fiber.App) { | ||||
| 	router.Get("/synchronize/task", security.EnterpriseAuthorize, searchSynchronizeSchedules) | ||||
| 	router.Get("/synchronize/configuration", security.EnterpriseAuthorize, getSynchronizeConfiguration) | ||||
| 	router.Post("/synchronize/configuration", security.EnterpriseAuthorize, recordsynchronizeConfiguration) | ||||
| } | ||||
|  | ||||
| // 查询当前平台中符合查询条件的同步任务,企业用户无论传入什么用户ID条件,都仅能看到自己的同步任务 | ||||
| func searchSynchronizeSchedules(c *fiber.Ctx) error { | ||||
| 	result := response.NewResult(c) | ||||
| 	session, err := _retreiveSession(c) | ||||
| 	if err != nil { | ||||
| 		synchronizeLog.Error("查询同步任务失败,未能获取当前用户会话信息", zap.Error(err)) | ||||
| 		return result.Unauthorized("未能获取当前用户会话信息。") | ||||
| 	} | ||||
| 	parkId := tools.EmptyToNil(c.Params("park")) | ||||
| 	if parkId != nil && len(*parkId) > 0 { | ||||
| 		if pass, err := checkParkBelongs(*parkId, reportLog, c, &result); !pass { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	userId := tools.EmptyToNil(c.Params("user")) | ||||
| 	keyword := tools.EmptyToNil(c.Query("keyword")) | ||||
| 	page := c.QueryInt("page", 1) | ||||
| 	synchronizeLog.Info("查询当前平台中符合查询条件的同步任务。", zap.String("Ent", session.Uid), zap.Stringp("Park", parkId)) | ||||
| 	schedules, total, err := repository.SynchronizeRepository.SearchSynchronizeSchedules(userId, parkId, uint(page), keyword) | ||||
| 	if err != nil { | ||||
| 		reportLog.Error("无法获取同步任务", zap.Error(err)) | ||||
| 		return result.Error(fiber.StatusInternalServerError, "无法获取同步任务") | ||||
| 	} | ||||
| 	return result.Success( | ||||
| 		" ", | ||||
| 		response.NewPagedResponse(page, total).ToMap(), | ||||
| 		fiber.Map{"tasks": schedules}, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| // 获取指定的同步任务配置 | ||||
| func getSynchronizeConfiguration(c *fiber.Ctx) error { | ||||
| 	result := response.NewResult(c) | ||||
| 	parkId := c.Query("park") | ||||
| 	userId := c.Query("user") | ||||
| 	session, err := _retreiveSession(c) | ||||
| 	if err != nil { | ||||
| 		reportLog.Error("无法获取当前用户的会话信息", zap.Error(err)) | ||||
| 		return result.Unauthorized("无法获取当前用户的会话信息。") | ||||
| 	} | ||||
| 	var user_id string | ||||
| 	if session.Type == model.USER_TYPE_ENT { | ||||
| 		user_id = session.Uid | ||||
| 	} else { | ||||
| 		if userId != "" { | ||||
| 			user_id = userId | ||||
| 		} else { | ||||
| 			return result.NotAccept(fmt.Sprintf("必须指定要记录同步任务的用户,%s", err.Error())) | ||||
| 		} | ||||
| 	} | ||||
| 	fmt.Println("pppppppppppppppppppppppppppp", parkId, len(parkId)) | ||||
| 	if parkId == "" { | ||||
| 		return result.NotAccept("必须指定要获取同步任务的园区。") | ||||
| 	} | ||||
|  | ||||
| 	fmt.Printf(user_id) | ||||
| 	configurations, err := repository.SynchronizeRepository.RetrieveSynchronizeConfiguration(user_id, parkId) | ||||
| 	if err != nil { | ||||
| 		reportLog.Error("无法获取同步任务", zap.Error(err)) | ||||
| 		return result.Error(fiber.StatusInternalServerError, "无法获取同步任务") | ||||
| 	} | ||||
| 	return result.Success( | ||||
| 		" 123", | ||||
| 		fiber.Map{"setup": configurations}, | ||||
| 	) | ||||
| } | ||||
| func recordsynchronizeConfiguration(c *fiber.Ctx) error { | ||||
| 	userId := c.Query("user") | ||||
| 	synchronizeLog.Info("记录一个新的同步任务配置", zap.String("user id", userId)) | ||||
| 	session, err := _retreiveSession(c) | ||||
| 	result := response.NewResult(c) | ||||
| 	if err != nil { | ||||
| 		reportLog.Error("无法获取当前用户的会话信息", zap.Error(err)) | ||||
| 		return result.Unauthorized("无法获取当前用户的会话信息。") | ||||
| 	} | ||||
| 	var Form vo.SynchronizeConfigurationCreateForm | ||||
| 	if err := c.BodyParser(&Form); err != nil { | ||||
| 		meterLog.Error("无法更新同步配置,无法解析表计更新表单", zap.Error(err)) | ||||
| 		return result.NotAccept(err.Error()) | ||||
| 	} | ||||
| 	var user_id string | ||||
| 	if session.Type == model.USER_TYPE_ENT { | ||||
| 		user_id = session.Uid | ||||
| 	} else { | ||||
| 		if userId != "" { | ||||
| 			user_id = userId | ||||
| 		} else { | ||||
| 			return result.NotAccept(fmt.Sprintf("必须指定更新同步任务的用户,%s", err.Error())) | ||||
| 		} | ||||
| 	} | ||||
| 	//configurations, err := repository.SynchronizeRepository.CreateSynchronizeConfiguration | ||||
| 	if err := service.SynchronizeService.CreateSynchronizeConfiguration(user_id, &Form); err != nil { | ||||
| 		synchronizeLog.Error("无法更新同步配置", zap.Error(err)) | ||||
| 		return result.NotAccept(err.Error()) | ||||
| 	} | ||||
| 	return result.Success("更新完成。") | ||||
| } | ||||
| @@ -25,6 +25,9 @@ func InitializeTenementHandler(router *fiber.App) { | ||||
| 	router.Put("/tenement/:pid/:tid", security.EnterpriseAuthorize, updateTenement) | ||||
| 	router.Get("/tenement/:pid/:tid", security.EnterpriseAuthorize, getTenementDetail) | ||||
| 	router.Get("/tenement/:pid/:tid/meter", security.EnterpriseAuthorize, listMeters) | ||||
| 	router.Post("/tenement/:pid/:tid/move/out", security.EnterpriseAuthorize, moveOutTenement) | ||||
| 	router.Post("/tenement/:pid", security.EnterpriseAuthorize, addTenement) | ||||
| 	router.Post("/tenement/:pid/:tid/binding", security.EnterpriseAuthorize, bindMeterToTenement) | ||||
| 	//TODO: 2023-07-19再apiFox上该请求是个PUT请求,后端接收是个POST请求,不知道是否有误或是缺少对应请求(apiFox测试请求返回值为405) | ||||
| 	router.Post("/tenement/:pid/:tid/move/out", security.EnterpriseAuthorize, moveOutTenement) | ||||
| 	router.Post("/tenement/:pid", security.EnterpriseAuthorize, addTenement) | ||||
|   | ||||
| @@ -18,8 +18,6 @@ import ( | ||||
| 	"go.uber.org/zap" | ||||
| ) | ||||
|  | ||||
| var userLog = logger.Named("Handler", "User") | ||||
|  | ||||
| func InitializeUserHandlers(router *fiber.App) { | ||||
| 	router.Delete("/login", security.MustAuthenticated, doLogout) | ||||
| 	router.Post("/login", doLogin) | ||||
| @@ -35,6 +33,8 @@ func InitializeUserHandlers(router *fiber.App) { | ||||
| 	router.Delete("/password/:uid", security.OPSAuthorize, invalidUserPassword) | ||||
| } | ||||
|  | ||||
| var userLog = logger.Named("Handler", "User") | ||||
|  | ||||
| type _LoginForm struct { | ||||
| 	Username string `json:"uname"` | ||||
| 	Password string `json:"upass"` | ||||
| @@ -42,37 +42,35 @@ type _LoginForm struct { | ||||
| } | ||||
|  | ||||
| func doLogin(c *fiber.Ctx) error { | ||||
| 	result := response.NewResult(c)                 //创建一个相应结果对象 | ||||
| 	loginData := new(_LoginForm)                    //创建一个解析登录表单数据的实体 | ||||
| 	if err := c.BodyParser(loginData); err != nil { //解析请求体中的Json数据到loginData里,如果解析出错就返回错误 | ||||
| 	result := response.NewResult(c) | ||||
| 	loginData := new(_LoginForm) | ||||
| 	if err := c.BodyParser(loginData); err != nil { | ||||
| 		userLog.Error("表单解析失败!", zap.Error(err)) | ||||
| 		return result.Error(http.StatusInternalServerError, "表单解析失败。") //返回一个内部服务器错误的相应结果 | ||||
| 		return result.Error(http.StatusInternalServerError, "表单解析失败。") | ||||
| 	} | ||||
| 	var ( | ||||
| 		session *model.Session | ||||
| 		err     error | ||||
| 	) | ||||
| 	userLog.Info("有用户请求登录。", zap.String("username", loginData.Username), zap.Int16("type", loginData.Type)) //记录日志相关信息 | ||||
| 	if loginData.Type == model.USER_TYPE_ENT {                                                              //根据登录类型选择不同的处理方法 | ||||
| 		session, err = service.UserService.ProcessEnterpriseUserLogin(loginData.Username, loginData.Password) //企业用户 | ||||
| 	userLog.Info("有用户请求登录。", zap.String("username", loginData.Username), zap.Int16("type", loginData.Type)) | ||||
| 	if loginData.Type == model.USER_TYPE_ENT { | ||||
| 		session, err = service.UserService.ProcessEnterpriseUserLogin(loginData.Username, loginData.Password) | ||||
| 	} else { | ||||
| 		userLog.Info("该用户是管理用户") | ||||
| 		session, err = service.UserService.ProcessManagementUserLogin(loginData.Username, loginData.Password) //管理用户 | ||||
| 		session, err = service.UserService.ProcessManagementUserLogin(loginData.Username, loginData.Password) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		if authError, ok := err.(*exceptions.AuthenticationError); ok { //检查错误是否为身份验证错误 | ||||
| 			if authError.NeedReset { //如果需要重置密码则返回对应结果 | ||||
| 		if authError, ok := err.(*exceptions.AuthenticationError); ok { | ||||
| 			if authError.NeedReset { | ||||
| 				return result.LoginNeedReset() | ||||
| 			} | ||||
| 			return result.Error(int(authError.Code), authError.Message) //返回身份验证错误相应 | ||||
| 			return result.Error(int(authError.Code), authError.Message) | ||||
| 		} else { | ||||
| 			userLog.Error("用户登录请求处理失败!", zap.Error(err)) | ||||
| 			return result.Error(http.StatusInternalServerError, err.Error()) //返回内部服务器错误 | ||||
| 			return result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 		} | ||||
| 	} | ||||
| 	return result.LoginSuccess(session) //返回登录成功相应结果,包含会话信息 | ||||
| 	return result.LoginSuccess(session) | ||||
| } | ||||
|  | ||||
| func doLogout(c *fiber.Ctx) error { | ||||
| 	result := response.NewResult(c) | ||||
| 	session, err := _retreiveSession(c) | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package controller | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/logger" | ||||
|  | ||||
| 	"electricity_bill_calc/repository" | ||||
| 	"electricity_bill_calc/response" | ||||
| 	"electricity_bill_calc/security" | ||||
| @@ -19,7 +20,7 @@ func InitializeWithdrawHandlers(router *fiber.App) { | ||||
| 	router.Delete("/withdraw/:rid", security.EnterpriseAuthorize, recallReport) | ||||
| } | ||||
|  | ||||
| //用于分页检索用户的核算报表 | ||||
| // 用于分页检索用户的核算报表 | ||||
| func withdraw(c *fiber.Ctx) error { | ||||
| 	//记录日志 | ||||
| 	withdrawLog.Info("带分页的待审核的核算撤回申请列表") | ||||
| @@ -43,7 +44,7 @@ func withdraw(c *fiber.Ctx) error { | ||||
| 	) | ||||
| } | ||||
|  | ||||
| //用于审核撤回报表 | ||||
| // 用于审核撤回报表 | ||||
| func reviewRequestWithdraw(c *fiber.Ctx) error { | ||||
| 	Rid := c.Params("rid", "") | ||||
| 	Data := new(vo.ReviewWithdraw) | ||||
| @@ -84,7 +85,7 @@ func reviewRequestWithdraw(c *fiber.Ctx) error { | ||||
|  | ||||
| } | ||||
|  | ||||
| //用于撤回电费核算 | ||||
| // 用于撤回电费核算 | ||||
| func recallReport(c *fiber.Ctx) error { | ||||
| 	//	获取用户会话信息和参数 | ||||
| 	rid := c.Params("rid", "") | ||||
|   | ||||
							
								
								
									
										22
									
								
								excel/tenement.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								excel/tenement.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| package excel | ||||
|  | ||||
| var tenementRecognizers = []*ColumnRecognizer{ | ||||
| 	{Pattern: [][]string{{"商户全称"}}, Tag: "fullName", MatchIndex: -1}, | ||||
| 	{Pattern: [][]string{{"联系地址"}}, Tag: "address", MatchIndex: -1}, | ||||
| 	{Pattern: [][]string{{"入驻时间"}}, Tag: "movedInAt", MatchIndex: -1}, | ||||
| 	{Pattern: [][]string{{"商铺名称"}}, Tag: "shortName", MatchIndex: -1}, | ||||
| 	{Pattern: [][]string{{"联系人"}}, Tag: "contactName", MatchIndex: -1}, | ||||
| 	{Pattern: [][]string{{"电话"}}, Tag: "contactPhone", MatchIndex: -1}, | ||||
| 	{Pattern: [][]string{{"USCI"}}, Tag: "usci", MatchIndex: -1}, | ||||
| 	{Pattern: [][]string{{"开票地址"}}, Tag: "invoiceAddress", MatchIndex: -1}, | ||||
| 	{Pattern: [][]string{{"账号"}}, Tag: "account", MatchIndex: -1}, | ||||
| 	{Pattern: [][]string{{"开户行"}}, Tag: "bank", MatchIndex: -1}, | ||||
| } | ||||
|  | ||||
| //func NewTenementExcelAnalyzer(file io.Reader) (*ExcelAnalyzer[model.TenementImportRow], error) { | ||||
| //	return NewExcelAnalyzer[model.TenementImportRow](file, tenementRecognizers) | ||||
| //} | ||||
|  | ||||
| //func NewMeterArchiveExcelAnalyzer(file io.Reader) (*ExcelAnalyzer[model.MeterImportRow], error) { | ||||
| //	return NewExcelAnalyzer[model.MeterImportRow](file, meterArchiveRecognizers) | ||||
| //} | ||||
| @@ -53,9 +53,7 @@ func (ql QueryLogger) TraceQueryStart(ctx context.Context, conn *pgx.Conn, data | ||||
| 	ql.logger.Info("查询参数", lo.Map(data.Args, func(elem any, index int) zap.Field { | ||||
| 		return zap.Any(fmt.Sprintf("[Arg %d]: ", index), elem) | ||||
| 	})...) | ||||
| 	//	for index, arg := range data.Args { | ||||
| 	//		ql.logger.Info(fmt.Sprintf("[Arg %d]: %v", index, arg)) | ||||
| 	//	} | ||||
|  | ||||
| 	return ctx | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -18,10 +18,9 @@ func SetupRedisConnection() error { | ||||
| 	a := fmt.Sprintf("%s:%d", config.RedisSettings.Host, config.RedisSettings.Port) | ||||
| 	fmt.Println(a) | ||||
| 	Rd, err = rueidis.NewClient(rueidis.ClientOption{ | ||||
| 		InitAddress: []string{"127.0.0.1:6379"}, | ||||
| 		Password:    "", | ||||
| 		InitAddress: []string{fmt.Sprintf("%s:%d", config.RedisSettings.Host, config.RedisSettings.Port)}, | ||||
| 		Password:    config.RedisSettings.Password, | ||||
| 		SelectDB:    config.RedisSettings.DB, | ||||
| 		DisableCache:true, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|   | ||||
							
								
								
									
										14
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								go.mod
									
									
									
									
									
								
							| @@ -3,7 +3,6 @@ module electricity_bill_calc | ||||
| go 1.19 | ||||
|  | ||||
| require ( | ||||
| 	github.com/deckarep/golang-set/v2 v2.1.0 | ||||
| 	github.com/fufuok/utils v0.10.2 | ||||
| 	github.com/georgysavva/scany/v2 v2.0.0 | ||||
| 	github.com/gofiber/fiber/v2 v2.46.0 | ||||
| @@ -27,26 +26,18 @@ require ( | ||||
| 	github.com/jackc/pgpassfile v1.0.0 // indirect | ||||
| 	github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect | ||||
| 	github.com/jackc/puddle/v2 v2.2.0 // indirect | ||||
| 	github.com/jinzhu/inflection v1.0.0 // indirect | ||||
| 	github.com/jmoiron/sqlx v1.3.5 // indirect | ||||
| 	github.com/klauspost/compress v1.16.6 // indirect | ||||
| 	github.com/mattn/go-colorable v0.1.13 // indirect | ||||
| 	github.com/mattn/go-isatty v0.0.19 // indirect | ||||
| 	github.com/mattn/go-runewidth v0.0.14 // indirect | ||||
| 	github.com/philhofer/fwd v1.1.2 // indirect | ||||
| 	github.com/rivo/uniseg v0.4.4 // indirect | ||||
| 	github.com/rogpeppe/go-internal v1.9.0 // indirect | ||||
| 	github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect | ||||
| 	github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect | ||||
| 	github.com/tinylib/msgp v1.1.8 // indirect | ||||
| 	github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect | ||||
| 	github.com/valyala/bytebufferpool v1.0.0 // indirect | ||||
| 	github.com/valyala/tcplisten v1.0.0 // indirect | ||||
| 	github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect | ||||
| 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect | ||||
| 	golang.org/x/sync v0.2.0 // indirect | ||||
| 	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect | ||||
| 	mellium.im/sasl v0.3.0 // indirect | ||||
| ) | ||||
|  | ||||
| require ( | ||||
| @@ -59,7 +50,6 @@ require ( | ||||
| 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||||
| 	github.com/modern-go/reflect2 v1.0.2 // indirect | ||||
| 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect | ||||
| 	github.com/pelletier/go-toml v1.9.5 // indirect | ||||
| 	github.com/pelletier/go-toml/v2 v2.0.8 // indirect | ||||
| 	github.com/richardlehane/mscfb v1.0.4 // indirect | ||||
| 	github.com/richardlehane/msoleps v1.0.3 // indirect | ||||
| @@ -68,9 +58,6 @@ require ( | ||||
| 	github.com/spf13/jwalterweatherman v1.1.0 // indirect | ||||
| 	github.com/spf13/pflag v1.0.5 // indirect | ||||
| 	github.com/subosito/gotenv v1.4.2 // indirect | ||||
| 	github.com/uptrace/bun v1.1.8 | ||||
| 	github.com/uptrace/bun/dialect/pgdialect v1.1.8 | ||||
| 	github.com/uptrace/bun/driver/pgdriver v1.1.8 | ||||
| 	github.com/xuri/efp v0.0.0-20230422071738-01f4e37c47e9 // indirect | ||||
| 	github.com/xuri/nfp v0.0.0-20230503010013-3f38cdbb0b83 // indirect | ||||
| 	go.uber.org/atomic v1.11.0 // indirect | ||||
| @@ -81,6 +68,5 @@ require ( | ||||
| 	golang.org/x/sys v0.9.0 // indirect | ||||
| 	golang.org/x/text v0.10.0 // indirect | ||||
| 	gopkg.in/ini.v1 v1.67.0 // indirect | ||||
| 	gopkg.in/yaml.v2 v2.4.0 // indirect | ||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||
| ) | ||||
|   | ||||
							
								
								
									
										133
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								go.sum
									
									
									
									
									
								
							| @@ -36,12 +36,10 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX | ||||
| cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= | ||||
| cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= | ||||
| dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= | ||||
| github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= | ||||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||
| github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= | ||||
| github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= | ||||
| github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= | ||||
| github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= | ||||
| github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= | ||||
| github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= | ||||
| github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= | ||||
| github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= | ||||
| @@ -53,11 +51,10 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk | ||||
| github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= | ||||
| github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= | ||||
| github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= | ||||
| github.com/cockroachdb/cockroach-go/v2 v2.2.0 h1:/5znzg5n373N/3ESjHF5SMLxiW4RKB05Ql//KWfeTFs= | ||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= | ||||
| github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= | ||||
| github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= | ||||
| github.com/doug-martin/goqu/v9 v9.18.0 h1:/6bcuEtAe6nsSMVK/M+fOiXUNfyFF3yYtE07DBPFMYY= | ||||
| github.com/doug-martin/goqu/v9 v9.18.0/go.mod h1:nf0Wc2/hV3gYK9LiyqIrzBEVGlI8qW3GuDCEobC4wBQ= | ||||
| @@ -67,14 +64,9 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m | ||||
| github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= | ||||
| github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= | ||||
| github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= | ||||
| github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= | ||||
| github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= | ||||
| github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= | ||||
| github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= | ||||
| github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= | ||||
| github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= | ||||
| github.com/fufuok/utils v0.7.13 h1:FGx8Mnfg0ZB8HdVz1X60JJ2kFu1rtcsFDYUxUTzNKkU= | ||||
| github.com/fufuok/utils v0.7.13/go.mod h1:ztIaorPqZGdbvmW3YlwQp80K8rKJmEy6xa1KwpJSsmk= | ||||
| github.com/fufuok/utils v0.10.2 h1:jXgE7yBSUW9z+sJs/VQq3o4MH+jN30PzIILVXFw73lE= | ||||
| github.com/fufuok/utils v0.10.2/go.mod h1:87MJq0gAZDYBgUOpxSGoLkdv8VCuRNOL9vK02F7JC3s= | ||||
| github.com/georgysavva/scany/v2 v2.0.0 h1:RGXqxDv4row7/FYoK8MRXAZXqoWF/NM+NP0q50k3DKU= | ||||
| @@ -83,10 +75,9 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 | ||||
| github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= | ||||
| github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= | ||||
| github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= | ||||
| github.com/gofiber/fiber/v2 v2.38.1 h1:GEQ/Yt3Wsf2a30iTqtLXlBYJZso0JXPovt/tmj5H9jU= | ||||
| github.com/gofiber/fiber/v2 v2.38.1/go.mod h1:t0NlbaXzuGH7I+7M4paE848fNWInZ7mfxI/Er1fTth8= | ||||
| github.com/gofiber/fiber/v2 v2.46.0 h1:wkkWotblsGVlLjXj2dpgKQAYHtXumsK/HyFugQM68Ns= | ||||
| github.com/gofiber/fiber/v2 v2.46.0/go.mod h1:DNl0/c37WLe0g92U6lx1VMQuxGUQY5V7EIaVoEsUffc= | ||||
| github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= | ||||
| github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= | ||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||||
| github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||||
| @@ -124,7 +115,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ | ||||
| github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= | ||||
| github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= | ||||
| github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= | ||||
| @@ -162,36 +153,24 @@ github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk | ||||
| github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= | ||||
| github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= | ||||
| github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= | ||||
| github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= | ||||
| github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= | ||||
| github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= | ||||
| github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= | ||||
| github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | ||||
| github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | ||||
| github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | ||||
| github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= | ||||
| github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= | ||||
| github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | ||||
| github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= | ||||
| github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= | ||||
| github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= | ||||
| github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= | ||||
| github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk= | ||||
| github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= | ||||
| github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= | ||||
| github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||||
| github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||||
| github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= | ||||
| github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | ||||
| github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||||
| github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||||
| github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||||
| github.com/liamylian/jsontime/v2 v2.0.0 h1:3if2kDW/boymUdO+4Qj/m4uaXMBSF6np9KEgg90cwH0= | ||||
| github.com/liamylian/jsontime/v2 v2.0.0/go.mod h1:UHp1oAPqCBfspokvGmaGe0IAl2IgOpgOgDaKPcvcGGY= | ||||
| github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||||
| github.com/lib/pq v1.10.1 h1:6VXZrLU0jHBYyAqrSPa+MgPfnSvTPuMgK+k0o5kVFWo= | ||||
| github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= | ||||
| github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= | ||||
| github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= | ||||
| github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= | ||||
| github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= | ||||
| github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= | ||||
| @@ -201,7 +180,6 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP | ||||
| github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= | ||||
| github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= | ||||
| github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= | ||||
| github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= | ||||
| github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= | ||||
| github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= | ||||
| github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | ||||
| @@ -214,20 +192,14 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G | ||||
| github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= | ||||
| github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= | ||||
| github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= | ||||
| github.com/mozillazg/go-pinyin v0.19.0 h1:p+J8/kjJ558KPvVGYLvqBhxf8jbZA2exSLCs2uUVN8c= | ||||
| github.com/mozillazg/go-pinyin v0.19.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc= | ||||
| github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ= | ||||
| github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc= | ||||
| github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= | ||||
| github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= | ||||
| github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= | ||||
| github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= | ||||
| github.com/onsi/gomega v1.27.5 h1:T/X6I0RNFw/kTqgfkZPcQ5KU6vCnWNBGdtrIx2dpGeQ= | ||||
| github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= | ||||
| github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= | ||||
| github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= | ||||
| github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= | ||||
| github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= | ||||
| github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= | ||||
| github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | ||||
| github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||
| github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= | ||||
| @@ -243,16 +215,9 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ | ||||
| github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= | ||||
| github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= | ||||
| github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= | ||||
| github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= | ||||
| github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= | ||||
| github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= | ||||
| github.com/rueian/rueidis v0.0.73 h1:+r0Z6C6HMnkquPgY3zaHVpTqmCyJL56Z36GSlyBrufk= | ||||
| github.com/rueian/rueidis v0.0.73/go.mod h1:FwnfDILF2GETrvXcYFlhIiru/7NmSIm1f+7C5kutO0I= | ||||
| github.com/rueian/rueidis v0.0.100 h1:22yp/+8YHuWc/vcrp8bkjeE7baD3vygoh2gZ2+xu1KQ= | ||||
| github.com/rueian/rueidis v0.0.100/go.mod h1:ivvsRYRtAUcf9OnheuKc5Gpa8IebrkLT1P45Lr2jlXE= | ||||
| github.com/samber/lo v1.27.0 h1:GOyDWxsblvqYobqsmUuMddPa2/mMzkKyojlXol4+LaQ= | ||||
| github.com/samber/lo v1.27.0/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg= | ||||
| github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= | ||||
| github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= | ||||
| github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4= | ||||
| @@ -262,75 +227,45 @@ github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1Avp | ||||
| github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g= | ||||
| github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= | ||||
| github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= | ||||
| github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= | ||||
| github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= | ||||
| github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= | ||||
| github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= | ||||
| github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= | ||||
| github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= | ||||
| github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= | ||||
| github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= | ||||
| github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= | ||||
| github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= | ||||
| github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | ||||
| github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||||
| github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= | ||||
| github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= | ||||
| github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= | ||||
| github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||||
| github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= | ||||
| github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | ||||
| github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||
| github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | ||||
| github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
| github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
| github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
| github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= | ||||
| github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= | ||||
| github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||||
| github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= | ||||
| github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= | ||||
| github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | ||||
| github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= | ||||
| github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= | ||||
| github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= | ||||
| github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= | ||||
| github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= | ||||
| github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= | ||||
| github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= | ||||
| github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= | ||||
| github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= | ||||
| github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= | ||||
| github.com/uptrace/bun v1.1.8 h1:slxuaP4LYWFbPRUmTtQhfJN+6eX/6ar2HDKYTcI50SA= | ||||
| github.com/uptrace/bun v1.1.8/go.mod h1:iT89ESdV3uMupD9ixt6Khidht+BK0STabK/LeZE+B84= | ||||
| github.com/uptrace/bun/dialect/pgdialect v1.1.8 h1:wayJhjYDPGv8tgOBLolbBtSFQ0TihFoo8E1T129UdA8= | ||||
| github.com/uptrace/bun/dialect/pgdialect v1.1.8/go.mod h1:nNbU8PHTjTUM+CRtGmqyBb9zcuRAB8I680/qoFSmBUk= | ||||
| github.com/uptrace/bun/driver/pgdriver v1.1.8 h1:gyL22axRQfjJS2Umq0erzJnp0bLOdUE8/USKZHPQB8o= | ||||
| github.com/uptrace/bun/driver/pgdriver v1.1.8/go.mod h1:4tHK0h7a/UoldBoe9J3GU4tEYjr3mkd62U3Kq3PVk3E= | ||||
| github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= | ||||
| github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= | ||||
| github.com/valyala/fasthttp v1.40.0 h1:CRq/00MfruPGFLTQKY8b+8SfdK60TxNztjRMnH0t1Yc= | ||||
| github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= | ||||
| github.com/valyala/fasthttp v1.47.0 h1:y7moDoxYzMooFpT5aHgNgVOQDrS3qlkfiP9mDtGGK9c= | ||||
| github.com/valyala/fasthttp v1.47.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= | ||||
| github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= | ||||
| github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= | ||||
| github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= | ||||
| github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= | ||||
| github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= | ||||
| github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= | ||||
| github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c= | ||||
| github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= | ||||
| github.com/xuri/efp v0.0.0-20230422071738-01f4e37c47e9 h1:ge5g8vsTQclA5lXDi+PuiAFw5GMIlMHOB/5e1hsf96E= | ||||
| github.com/xuri/efp v0.0.0-20230422071738-01f4e37c47e9/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= | ||||
| github.com/xuri/excelize/v2 v2.6.1 h1:ICBdtw803rmhLN3zfvyEGH3cwSmZv+kde7LhTDT659k= | ||||
| github.com/xuri/excelize/v2 v2.6.1/go.mod h1:tL+0m6DNwSXj/sILHbQTYsLi9IF4TW59H2EF3Yrx1AU= | ||||
| github.com/xuri/excelize/v2 v2.7.1 h1:gm8q0UCAyaTt3MEF5wWMjVdmthm2EHAWesGSKS9tdVI= | ||||
| github.com/xuri/excelize/v2 v2.7.1/go.mod h1:qc0+2j4TvAUrBw36ATtcTeC1VCM0fFdAXZOmcF4nTpY= | ||||
| github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M= | ||||
| github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= | ||||
| github.com/xuri/nfp v0.0.0-20230503010013-3f38cdbb0b83 h1:xVwnvkzzi+OiwhIkWOXvh1skFI6bagk8OvGuazM80Rw= | ||||
| github.com/xuri/nfp v0.0.0-20230503010013-3f38cdbb0b83/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= | ||||
| @@ -345,19 +280,11 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | ||||
| go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | ||||
| go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | ||||
| go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= | ||||
| go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= | ||||
| go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= | ||||
| go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= | ||||
| go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= | ||||
| go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= | ||||
| go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= | ||||
| go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= | ||||
| go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= | ||||
| go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= | ||||
| go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= | ||||
| go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= | ||||
| go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= | ||||
| go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= | ||||
| go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= | ||||
| go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| @@ -368,18 +295,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U | ||||
| golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= | ||||
| golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||||
| golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||||
| golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||||
| golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||||
| golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||||
| golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo= | ||||
| golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||||
| golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= | ||||
| golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||||
| golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= | ||||
| golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= | ||||
| golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= | ||||
| golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= | ||||
| golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= | ||||
| golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= | ||||
| golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= | ||||
| @@ -393,14 +309,10 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 | ||||
| golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= | ||||
| golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= | ||||
| golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= | ||||
| golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= | ||||
| golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= | ||||
| golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= | ||||
| golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= | ||||
| golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= | ||||
| golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= | ||||
| golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE= | ||||
| golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= | ||||
| golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI= | ||||
| golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= | ||||
| golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||
| @@ -459,15 +371,9 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v | ||||
| golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||
| golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||
| golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= | ||||
| golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= | ||||
| golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= | ||||
| golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= | ||||
| golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= | ||||
| golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= | ||||
| golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | ||||
| golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= | ||||
| golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= | ||||
| golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= | ||||
| golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= | ||||
| golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= | ||||
| @@ -491,7 +397,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ | ||||
| golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= | ||||
| golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= | ||||
| golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| @@ -530,23 +435,14 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U= | ||||
| golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= | ||||
| golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= | ||||
| golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= | ||||
| golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| @@ -561,13 +457,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= | ||||
| golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | ||||
| golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | ||||
| golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= | ||||
| golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | ||||
| golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= | ||||
| golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= | ||||
| golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= | ||||
| golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= | ||||
| golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= | ||||
| @@ -720,22 +612,13 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | ||||
| gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= | ||||
| gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4= | ||||
| gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= | ||||
| gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= | ||||
| gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= | ||||
| gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= | ||||
| gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= | ||||
| gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= | ||||
| gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= | ||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | ||||
| gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= | ||||
| gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||||
| gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| @@ -745,8 +628,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh | ||||
| honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= | ||||
| honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= | ||||
| honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= | ||||
| mellium.im/sasl v0.3.0 h1:0qoaTCTo5Py7u/g0cBIQZcMOgG/5LM71nshbXwznBh8= | ||||
| mellium.im/sasl v0.3.0/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= | ||||
| rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= | ||||
| rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= | ||||
| rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= | ||||
|   | ||||
| @@ -60,6 +60,7 @@ type TenementCharge struct { | ||||
| 	LossPooled   decimal.Decimal | ||||
| 	PublicPooled decimal.Decimal | ||||
| 	FinalCharges decimal.Decimal | ||||
| 	Loss         decimal.Decimal | ||||
| 	Submeters    []*Meter | ||||
| 	Poolings     []*Meter | ||||
| } | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package model | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/types" | ||||
|  | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/shopspring/decimal" | ||||
| @@ -39,7 +40,7 @@ type Parks struct { | ||||
| } | ||||
|  | ||||
| type ParkPeriodStatistics struct { | ||||
| 	Id string `json:"id"` | ||||
| 	Name string `json:"name"` | ||||
| 	Id     string `json:"id"` | ||||
| 	Name   string `json:"name"` | ||||
| 	Period *types.DateRange | ||||
| } | ||||
|   | ||||
							
								
								
									
										38
									
								
								model/synchronize.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								model/synchronize.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/types" | ||||
| 	_ "github.com/shopspring/decimal" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| type SynchronizeConfiguration struct { | ||||
| 	User                   string    `json:"user" db:"user_id"` | ||||
| 	Park                   string    `json:"park" db:"park_id"` | ||||
| 	MeterReadingType       int16     `json:"meter_reading_type"` | ||||
| 	ImrsType               string    `json:"imrs_type"` | ||||
| 	AuthorizationAccount   string    `json:"authorization_account" db:"imrs_authorization_account"` | ||||
| 	AuthorizationSecret    string    `json:"authorization_secret" db:"imrs_authorization_secret"` | ||||
| 	AuthorizationKey       []byte    `json:"authorization_key,omitempty" db:"imrs_authorization_key"` | ||||
| 	Interval               int16     `json:"interval"` | ||||
| 	CollectAt              time.Time `json:"collect_at" db:"-"` | ||||
| 	MaxRetries             int16     `json:"max_retries"` | ||||
| 	RetryInterval          int16     `json:"retry_interval"` | ||||
| 	RetryIntervalAlgorithm int16     `json:"retry_interval_algorithm"` | ||||
| } | ||||
|  | ||||
| type SynchronizeSchedule struct { | ||||
| 	User               string         `json:"userId" db:"user_id"` | ||||
| 	UserName           string         `json:"userName" db:"user_name"` | ||||
| 	Park               string         `json:"parkId" db:"park_id"` | ||||
| 	ParkName           string         `json:"parkName" db:"park_name"` | ||||
| 	TaskIdentity       string         `json:"taskIdentity" db:"task_identity"` | ||||
| 	TaskName           string         `json:"taskName" db:"task_name"` | ||||
| 	TaskDescription    string         `json:"taskDescription" db:"task_description"` | ||||
| 	CreatedAt          types.DateTime `json:"createdAt" db:"created_at"` | ||||
| 	LastModifiedAt     types.DateTime `json:"lastModifiedAt" db:"last_modified_at"` | ||||
| 	LastDispatchedAt   types.DateTime `json:"lastDispatchedAt" db:"last_dispatched_at"` | ||||
| 	LastDispatchStatus int16          `json:"lastDispatchStatus" db:"last_dispatch_status"` | ||||
| 	NextDispatchAt     types.DateTime `json:"nextDispatchAt" db:"next_dispatch_at"` | ||||
| 	CurrentRetries     int16          `json:"currentRetries" db:"current_retries"` | ||||
| } | ||||
| @@ -4,7 +4,16 @@ import ( | ||||
| 	"electricity_bill_calc/global" | ||||
| 	"electricity_bill_calc/logger" | ||||
| 	"electricity_bill_calc/model" | ||||
| 	"electricity_bill_calc/model/calculate" | ||||
| 	"electricity_bill_calc/types" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/jackc/pgx/v5" | ||||
| 	"github.com/shopspring/decimal" | ||||
| 	"golang.org/x/sync/errgroup" | ||||
| 	"log" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/doug-martin/goqu/v9" | ||||
| @@ -70,7 +79,7 @@ func (cr _CalculateRepository) UpdateReportTaskStatus(rid string, status int16, | ||||
| 	return res.RowsAffected() > 0, nil | ||||
| } | ||||
|  | ||||
| //获取当前园区中所有公摊表计与商户表计之间的关联关系,包括已经解除的 | ||||
| // 获取当前园区中所有公摊表计与商户表计之间的关联关系,包括已经解除的 | ||||
| func (cr _CalculateRepository) GetAllPoolingMeterRelations(pid string, revokedAfter time.Time) ([]model.MeterRelation, error) { | ||||
| 	cr.log.Info("获取当前园区中所有公摊表计与商户表计之间的关联关系,包括已经解除的", zap.String("pid", pid), zap.Time("revokedAfter", revokedAfter)) | ||||
|  | ||||
| @@ -94,7 +103,7 @@ func (cr _CalculateRepository) GetAllPoolingMeterRelations(pid string, revokedAf | ||||
| 	return meterRelation, nil | ||||
| } | ||||
|  | ||||
| //获取当前园区中所有的商户与表计的关联关系,包括已经解除的 | ||||
| // 获取当前园区中所有的商户与表计的关联关系,包括已经解除的 | ||||
| func (cr _CalculateRepository) GetAllTenementMeterRelations(pid string, associatedBefore time.Time, disassociatedAfter time.Time) ([]model.TenementMeter, error) { | ||||
| 	cr.log.Info("获取当前园区中所有的商户与表计的关联关系,包括已经解除的", zap.String("pid", pid), zap.Time("associatedBefore", associatedBefore), zap.Time("disassociatedAfter", disassociatedAfter)) | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| @@ -123,7 +132,7 @@ func (cr _CalculateRepository) GetAllTenementMeterRelations(pid string, associat | ||||
|  | ||||
| } | ||||
|  | ||||
| //获取指定报表中所有涉及到的指定类型表计在核算时间段内的所有读数数据 | ||||
| // 获取指定报表中所有涉及到的指定类型表计在核算时间段内的所有读数数据 | ||||
| func (cr _CalculateRepository) GetMeterReadings(rid string, meterType int16) ([]model.MeterReading, error) { | ||||
| 	cr.log.Info("获取指定报表中所有涉及到的指定类型表计在核算时间段内的所有读数数据", zap.String("rid", rid), zap.Int16("meterType", meterType)) | ||||
|  | ||||
| @@ -239,3 +248,264 @@ func (cr _CalculateRepository) GetAllTenements(rid string) ([]model.Tenement, er | ||||
| 	} | ||||
| 	return tenements, nil | ||||
| } | ||||
| func (cr _CalculateRepository) ClearReportContent(tx pgx.Tx, rid string) error { | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
| 	querysql, querarg, _ := cr.ds.Delete("report_summary"). | ||||
| 		Where(goqu.C("report_id").Eq(rid)).ToSQL() | ||||
| 	_, err := tx.Exec(ctx, querysql, querarg...) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	querysql, querarg, _ = cr.ds.Delete("report_public_consumption"). | ||||
| 		Where(goqu.C("report_id").Eq(rid)).ToSQL() | ||||
| 	_, err = tx.Exec(ctx, querysql, querarg...) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	querysql, querarg, _ = cr.ds.Delete("report_pooled_consumption"). | ||||
| 		Where(goqu.C("report_id").Eq(rid)).ToSQL() | ||||
| 	_, err = tx.Exec(ctx, querysql, querarg...) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	querysql, querarg, _ = cr.ds.Delete("report_tenement"). | ||||
| 		Where(goqu.C("report_id").Eq(rid)).ToSQL() | ||||
| 	_, err = tx.Exec(ctx, querysql, querarg...) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| func (cr _CalculateRepository) SaveReportPublics(tx pgx.Tx, rid string, meters []calculate.Meter) error { | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
| 	if len(meters) == 0 { | ||||
| 		// 如果没有公共表计则直接返回 | ||||
| 		return nil | ||||
| 	} | ||||
| 	// 准备插入表达式 | ||||
| 	insertExpr := cr.ds.Insert("report_public_consumption"). | ||||
| 		Cols( | ||||
| 			"report_id", "park_meter_id", "overall", "critical", "peak", "flat", "valley", | ||||
| 			"loss_adjust", "consumption_total", "loss_adjust_total", "final_total", | ||||
| 		).Prepared(true) | ||||
| 	// 添加值到插入表达式中 | ||||
| 	for _, meter := range meters { | ||||
| 		insertExpr = insertExpr.Vals([]interface{}{ | ||||
| 			rid, | ||||
| 			meter.Code, | ||||
| 			meter.Overall.Fee, | ||||
| 			meter.Critical.Fee, | ||||
| 			meter.Peak.Fee, | ||||
| 			meter.Flat.Fee, | ||||
| 			meter.Valley.Fee, | ||||
| 			meter.AdjustLoss.Fee, | ||||
| 			meter.Overall.Fee, | ||||
| 			meter.AdjustLoss.Fee, | ||||
| 			meter.Overall.Fee.Add(meter.AdjustLoss.Fee), | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	// 执行插入语句 | ||||
| 	inserSql, insertArgs, err := insertExpr.Prepared(true).ToSQL() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if _, err := tx.Exec(ctx, inserSql, insertArgs); err != nil { | ||||
| 		return fmt.Errorf("保存报表核算概要失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| func (cr _CalculateRepository) SaveReportSummary(tx pgx.Tx, summary calculate.Summary) error { | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
| 	// 构建插入表达式 | ||||
| 	insertsql, insertArgs, _ := cr.ds.Insert("report_summary"). | ||||
| 		Cols( | ||||
| 			"report_id", "overall", "critical", "peak", "flat", "valley", | ||||
| 			"loss", "loss_fee", "basic_fee", "basic_pooled_price_consumption", "basic_pooled_price_area", | ||||
| 			"adjust_fee", "adjust_pooled_price_consumption", "adjust_pooled_price_area", | ||||
| 			"loss_diluted_price", "loss_proportion", "final_diluted_overall", | ||||
| 			"consumption_fee", "authorize_loss", "overall_area", "total_consumption", | ||||
| 		). | ||||
| 		Vals(goqu.Vals{ | ||||
| 			summary.ReportId, summary.Overall, summary.Critical, summary.Peak, summary.Flat, | ||||
| 			summary.Valley, summary.Loss, summary.LossFee, summary.BasicFee, | ||||
| 			summary.BasicPooledPriceConsumption, summary.BasicPooledPriceArea, | ||||
| 			summary.AdjustFee, summary.AdjustPooledPriceConsumption, summary.AdjustPooledPriceArea, | ||||
| 			summary.LossDilutedPrice, summary.LossProportion, summary.FinalDilutedOverall, | ||||
| 			summary.ConsumptionFee, summary.AuthoizeLoss, summary.OverallArea, summary.TotalConsumption, | ||||
| 		}).Prepared(true).ToSQL() | ||||
|  | ||||
| 	// 执行插入语句 | ||||
|  | ||||
| 	if _, err := tx.Exec(ctx, insertsql, insertArgs...); err != nil { | ||||
| 		cr.log.Error("保存报表核算概要失败。") | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type NestedMeter struct { | ||||
| 	Overall     model.ConsumptionUnit | ||||
| 	Critical    model.ConsumptionUnit | ||||
| 	Peak        model.ConsumptionUnit | ||||
| 	Flat        model.ConsumptionUnit | ||||
| 	Valley      model.ConsumptionUnit | ||||
| 	CoveredArea decimal.Decimal | ||||
|  | ||||
| 	// Add other fields here as needed | ||||
| } | ||||
|  | ||||
| func (cr _CalculateRepository) SaveReportPoolings(tx pgx.Tx, | ||||
| 	rid string, | ||||
| 	meters []calculate.Meter, | ||||
| 	relations []model.MeterRelation, | ||||
| 	tenements []calculate.Meter) error { | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
| 	if len(meters) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	relationsSlaves := make(map[string]bool) | ||||
| 	for _, r := range relations { | ||||
| 		relationsSlaves[r.SlaveMeter] = true | ||||
| 	} | ||||
|  | ||||
| 	tenementCodes := make(map[string]bool) | ||||
| 	for _, t := range tenements { | ||||
| 		tenementCodes[t.Code] = true | ||||
| 	} | ||||
|  | ||||
| 	for _, r := range relations { | ||||
| 		if _, ok := tenementCodes[r.SlaveMeter]; !ok { | ||||
| 			return errors.New("unknown tenement meter in active meter relations") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var insertQueries []goqu.InsertDataset | ||||
| 	for _, meter := range meters { | ||||
| 		submeters := make([]NestedMeter, 0) | ||||
| 		for _, r := range relations { | ||||
| 			if r.MasterMeter == meter.Code { | ||||
| 				for _, t := range tenements { | ||||
| 					if t.Code == r.SlaveMeter { | ||||
| 						submeters = append(submeters, NestedMeter{ | ||||
| 							Overall:  t.Overall, | ||||
| 							Critical: t.Critical, | ||||
| 							Peak:     t.Peak, | ||||
| 							Flat:     t.Flat, | ||||
| 							Valley:   t.Valley, | ||||
| 						}) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		submetersJSON, err := json.Marshal(submeters) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		insertQuery := goqu.Insert("report_pooled_consumption"). | ||||
| 			Cols("report_id", "pooled_meter_id", "overall", "critical", "peak", "flat", "valley", "pooled_area", "diluted"). | ||||
| 			Vals(goqu.Vals{rid, meter.Code, meter.Overall, meter.Critical, meter.Peak, meter.Flat, meter.Valley, meter.CoveredArea, submetersJSON}) | ||||
|  | ||||
| 		insertQueries = append(insertQueries, *insertQuery) | ||||
| 	} | ||||
|  | ||||
| 	eg, _ := errgroup.WithContext(ctx) | ||||
| 	for _, insertQuery := range insertQueries { | ||||
| 		insertQuery := insertQuery // Capture loop variable | ||||
| 		eg.Go(func() error { | ||||
| 			sql, args, err := insertQuery.ToSQL() | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			_, err = tx.Exec(ctx, sql, args...) | ||||
| 			return err | ||||
| 		}) | ||||
| 	} | ||||
| 	return eg.Wait() | ||||
| } | ||||
| func (cr _CalculateRepository) SaveReportTenement(tx pgx.Tx, report model.ReportIndex, tenements []model.Tenement, tenementCharges []calculate.TenementCharge) error { | ||||
| 	if len(tenements) == 0 { | ||||
| 		// 如果没有商户则直接返回 | ||||
| 		return nil | ||||
| 	} | ||||
| 	cr.log.Info("保存商户报表。") | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
| 	insertQuery := cr.ds.Insert("report_tenement").Prepared(true) | ||||
| 	values := []goqu.Record{} | ||||
| 	for _, tenement := range tenements { | ||||
| 		charge := findTenementCharge(tenementCharges, tenement.Id) | ||||
| 		values = append(values, goqu.Record{ | ||||
| 			"report_id":         report.Id, | ||||
| 			"tenement_id":       tenement.Id, | ||||
| 			"tenement_detail":   toJSONString(tenement), | ||||
| 			"calc_period":       report.Period, | ||||
| 			"overall":           toJSONString(charge.Overall), | ||||
| 			"critical":          toJSONString(charge.Critical), | ||||
| 			"peak":              toJSONString(charge.Peak), | ||||
| 			"flat":              toJSONString(charge.Flat), | ||||
| 			"valley":            toJSONString(charge.Valley), | ||||
| 			"loss":              toJSONString(charge.Loss), | ||||
| 			"basic_fee_pooled":  charge.BasicFee, | ||||
| 			"adjust_fee_pooled": charge.AdjustFee, | ||||
| 			"loss_fee_pooled":   charge.LossPooled, | ||||
| 			"final_pooled":      charge.PublicPooled, | ||||
| 			"final_charge":      charge.FinalCharges, | ||||
| 			"meters":            toJSONString(convertToNestedMeters(charge.Submeters)), | ||||
| 			"pooled":            toJSONString(convertToNestedMeters(charge.Poolings)), | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	sql, params, err := insertQuery.Rows(values).Prepared(true).ToSQL() | ||||
| 	if err != nil { | ||||
| 		log.Println("sql出现问题................................") | ||||
| 		return err | ||||
| 	} | ||||
| 	tx.Exec(ctx, sql, params...) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // findTenementCharge 在 TenementCharges 切片中查找指定商户的核算内容 | ||||
| func findTenementCharge(charges []calculate.TenementCharge, tenementID string) calculate.TenementCharge { | ||||
| 	for _, charge := range charges { | ||||
| 		if charge.Tenement == tenementID { | ||||
| 			return charge | ||||
| 		} | ||||
| 	} | ||||
| 	return calculate.TenementCharge{} | ||||
| } | ||||
|  | ||||
| // convertToNestedMeters 将 Meter 切片转换为 NestedMeter 切片 | ||||
| func convertToNestedMeters(meters []*calculate.Meter) []NestedMeter { | ||||
| 	nestedMeters := []NestedMeter{} | ||||
| 	for _, meter := range meters { | ||||
| 		nestedMeters = append(nestedMeters, NestedMeter{ | ||||
| 			Overall:     meter.Overall, | ||||
| 			Critical:    meter.Critical, | ||||
| 			Peak:        meter.Peak, | ||||
| 			Flat:        meter.Flat, | ||||
| 			Valley:      meter.Valley, | ||||
| 			CoveredArea: meter.CoveredArea, | ||||
| 		}) | ||||
| 	} | ||||
| 	return nestedMeters | ||||
| } | ||||
|  | ||||
| // toJSONString 将对象转换为 JSON 字符串 | ||||
| func toJSONString(obj interface{}) string { | ||||
| 	return `"` + strings.ReplaceAll(fmt.Sprintf("%#v", obj), `"`, `\"`) + `"` | ||||
| } | ||||
|   | ||||
							
								
								
									
										19
									
								
								repository/god.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								repository/god.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| package repository | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/logger" | ||||
| 	"github.com/doug-martin/goqu/v9" | ||||
| 	"go.uber.org/zap" | ||||
| ) | ||||
|  | ||||
| type _GodModRepository struct { | ||||
| 	log *zap.Logger | ||||
| 	ds  goqu.DialectWrapper | ||||
| } | ||||
|  | ||||
| var GodModRepository = _GodModRepository{ | ||||
| 	log: logger.Named("Repository", "GodMod"), | ||||
| 	ds:  goqu.Dialect("postgres"), | ||||
| } | ||||
|  | ||||
| // 删除指定园区中的表计和商户的绑定关系 | ||||
							
								
								
									
										208
									
								
								repository/synchronize.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								repository/synchronize.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,208 @@ | ||||
| package repository | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"electricity_bill_calc/config" | ||||
| 	"electricity_bill_calc/global" | ||||
| 	"electricity_bill_calc/logger" | ||||
| 	"electricity_bill_calc/model" | ||||
| 	"electricity_bill_calc/tools" | ||||
| 	"electricity_bill_calc/vo" | ||||
| 	"fmt" | ||||
| 	"github.com/doug-martin/goqu/v9" | ||||
| 	"github.com/georgysavva/scany/v2/pgxscan" | ||||
| 	"github.com/jackc/pgx/v5" | ||||
| 	"go.uber.org/zap" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| type _SynchronizeRepository struct { | ||||
| 	log *zap.Logger | ||||
| 	ds  goqu.DialectWrapper | ||||
| } | ||||
|  | ||||
| var SynchronizeRepository = _SynchronizeRepository{ | ||||
| 	log: logger.Named("Repository", "Synchronize"), | ||||
| 	ds:  goqu.Dialect("postgres"), | ||||
| } | ||||
|  | ||||
| func (sr _SynchronizeRepository) SearchSynchronizeSchedules(userId *string, parkId *string, page uint, keyword *string) ([]*model.SynchronizeSchedule, int64, error) { | ||||
| 	sr.log.Info("检索符合指定条件的同步记录", zap.String("user id", tools.DefaultTo(userId, "")), | ||||
| 		zap.String("park id", tools.DefaultTo(parkId, "")), zap.Uint("page", page), | ||||
| 		zap.String("keyword", tools.DefaultTo(keyword, ""))) | ||||
| 	ctx, cancelFunc := global.TimeoutContext() | ||||
| 	defer cancelFunc() | ||||
| 	//scheduleQuery := "select ss.*, ud.name as user_name, p.name as park_name from synchronize_schedule as ss | ||||
| 	//join park as p on p.id=ss.park_id join user_detail as ud on ud.id=ss.user_id where 1=1" | ||||
| 	schedulequery := sr.ds.From(goqu.T("synchronize_schedule").As("ss")). | ||||
| 		Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("ss.park_id")))). | ||||
| 		Join(goqu.T("user_detail").As("ud"), goqu.On(goqu.I("ud.id").Eq(goqu.I("ss.user_id")))). | ||||
| 		Select("ss.*", goqu.I("ud.name").As("user_name"), goqu.I("p.name").As("park_name")) | ||||
| 	//countQuery := "select count(ss.*) from synchronize_schedule as ss | ||||
| 	//join park as p on p.id=ss.park_id join user_detail as ud on ud.id=ss.user_id where 1=1" | ||||
| 	countquery := sr.ds.From(goqu.T("synchronize_schedule").As("ss")). | ||||
| 		Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("ss.park_id")))). | ||||
| 		Join(goqu.T("user_detail").As("ud"), goqu.On(goqu.I("ud.id").Eq(goqu.I("ss.user_id")))). | ||||
| 		Select(goqu.COUNT(goqu.I("ss.*"))) | ||||
| 	if userId != nil && len(*userId) > 0 { | ||||
| 		schedulequery = schedulequery.Where(goqu.I("ss.user_id").Eq(*userId)) | ||||
| 		countquery = countquery.Where(goqu.I("ss.user_id").Eq(*userId)) | ||||
| 	} | ||||
| 	if parkId != nil && len(*parkId) > 0 { | ||||
| 		schedulequery = schedulequery.Where(goqu.I("ss.park_id").Eq(*parkId)) | ||||
| 		countquery = countquery.Where(goqu.I("ss.park_id").Eq(*parkId)) | ||||
| 	} | ||||
| 	if keyword != nil && len(*keyword) > 0 { | ||||
| 		pattern := fmt.Sprintf("%%%s%%", *keyword) | ||||
| 		schedulequery = schedulequery.Where(goqu.Or( | ||||
| 			goqu.I("p.name").ILike(pattern), | ||||
| 			goqu.I("p.abbr").ILike(pattern), | ||||
| 			goqu.I("p.address").ILike(pattern), | ||||
| 			goqu.I("p.contact").ILike(pattern), | ||||
| 			goqu.I("p.phone").ILike(pattern), | ||||
| 			goqu.I("ud.name").ILike(pattern), | ||||
| 			goqu.I("ud.abbr").ILike(pattern), | ||||
| 			goqu.I("ud.contact").ILike(pattern), | ||||
| 			goqu.I("ud.phone").ILike(pattern), | ||||
| 			goqu.I("ss.task_name").ILike(pattern), | ||||
| 			goqu.I("ss.task_description").ILike(pattern), | ||||
| 		)) | ||||
| 		countquery = countquery.Where(goqu.Or( | ||||
| 			goqu.I("p.name").ILike(pattern), | ||||
| 			goqu.I("p.abbr").ILike(pattern), | ||||
| 			goqu.I("p.address").ILike(pattern), | ||||
| 			goqu.I("p.contact").ILike(pattern), | ||||
| 			goqu.I("ud.name").ILike(pattern), | ||||
| 			goqu.I("ud.abbr").ILike(pattern), | ||||
| 			goqu.I("ud.contact").ILike(pattern), | ||||
| 			goqu.I("ud.phone").ILike(pattern), | ||||
| 			goqu.I("ss.task_name").ILike(pattern), | ||||
| 			goqu.I("ss.task_description").ILike(pattern), | ||||
| 		)) | ||||
| 	} | ||||
| 	startRow := (page - 1) * config.ServiceSettings.ItemsPageSize | ||||
| 	schedulequery = schedulequery. | ||||
| 		Order(goqu.I("ss.created_at").Desc()). | ||||
| 		Offset(startRow).Limit(config.ServiceSettings.ItemsPageSize) | ||||
| 	var ( | ||||
| 		schedule []*model.SynchronizeSchedule = make([]*model.SynchronizeSchedule, 0) | ||||
| 		count    int64 | ||||
| 	) | ||||
| 	querySql, queryArgs, _ := schedulequery.Prepared(true).ToSQL() | ||||
| 	countSql, countArgs, _ := countquery.Prepared(true).ToSQL() | ||||
| 	if err := pgxscan.Select(ctx, global.DB, &schedule, querySql, queryArgs...); err != nil { | ||||
| 		sr.log.Error("获取同步任务时出现错误", zap.Error(err)) | ||||
| 		return schedule, 0, err | ||||
| 	} | ||||
| 	if err := pgxscan.Get(ctx, global.DB, &count, countSql, countArgs...); err != nil { | ||||
| 		sr.log.Error("检索同步任务总数量时出现错误", zap.Error(err)) | ||||
| 		return schedule, 0, err | ||||
| 	} | ||||
| 	return schedule, count, nil | ||||
| } | ||||
|  | ||||
| // From("synchronize_schedule"). | ||||
| // | ||||
| //	Select( | ||||
| //		goqu.I("synchronize_schedule.*"), | ||||
| //		goqu.I("user_detail.name").As("user_name"), | ||||
| //		goqu.I("park.name").As("park_name"), | ||||
| //	). | ||||
| //	Join( | ||||
| //		goqu.T("park").On(goqu.I("park.id").Eq(goqu.I("synchronize_schedule.park_id"))), | ||||
| //		goqu.T("user_detail").On(goqu.I("user_detail.id").Eq(goqu.I("synchronize_schedule.user_id"))), | ||||
| //	). | ||||
| //	Where(goqu.C("1").Eq(1)) | ||||
| // | ||||
| // SELECT count(ss.*) | ||||
| // FROM synchronize_schedule AS ss | ||||
| // JOIN park AS p ON p.id = ss.park_id | ||||
| // JOIN user_detail AS ud ON ud.id = ss.user_id | ||||
| // WHERE true` | ||||
| // | ||||
| // var args []interface{} | ||||
| // | ||||
| //	if uid != nil { | ||||
| //	   scheduleQuery += " AND ss.user_id = $1" | ||||
| //	   countQuery += " AND ss.user_id = $1" | ||||
| //	   args = append(args, *uid) | ||||
| //	} | ||||
| // | ||||
| //	if pid != nil { | ||||
| //	   scheduleQuery += " AND ss.park_id = $2" | ||||
| //	   countQuery += " AND ss.park_id = $2" | ||||
| //	   args = append(args, *pid) | ||||
| //	} | ||||
| // | ||||
| //	if keyword != nil { | ||||
| //	   pattern := "%" + *keyword + "%" | ||||
| //	   scheduleQuery += ` AND (p.name LIKE $3 OR p.abbr LIKE $3 OR p.address LIKE $3 OR p.contact LIKE $3 OR | ||||
| // | ||||
| // p.phone LIKE $3 OR ud.name LIKE $3 OR ud.abbr LIKE $3 OR ud.contact LIKE $3 OR | ||||
| // ud.phone LIKE $3 OR ss.task_name LIKE $3 OR ss.task_description LIKE $3)` | ||||
| // | ||||
| //	   args = append(args, pattern) | ||||
| //	} | ||||
| func (sr _SynchronizeRepository) RetrieveSynchronizeConfiguration(uId, pId string) (vo.SynchronizeConfiguration, error) { | ||||
| 	sr.log.Info("检索符合指定条件的同步记录", zap.String("user id", uId), zap.String("park id", pId)) | ||||
| 	ctx, cancelFunc := global.TimeoutContext() | ||||
| 	defer cancelFunc() | ||||
| 	//select * from synchronize_config where user_id=$1 and park_id=$2 | ||||
| 	configSql, configArgs, _ := sr.ds. | ||||
| 		From(goqu.T("synchronize_config")). | ||||
| 		Where(goqu.I("user_id").Eq(uId)). | ||||
| 		Where(goqu.I("park_id").Eq(pId)). | ||||
| 		Prepared(true).Select("*").ToSQL() | ||||
| 	fmt.Println(configSql) | ||||
| 	var configs []model.SynchronizeConfiguration | ||||
| 	if err := pgxscan.Select(ctx, global.DB, &configs, configSql, configArgs...); err != nil { | ||||
| 		fmt.Println(err) | ||||
| 		sr.log.Error("获取同步任务时出现错误", zap.Error(err)) | ||||
| 		return vo.SynchronizeConfiguration{}, err | ||||
| 	} | ||||
| 	if len(configs) <= 0 { | ||||
| 		return vo.SynchronizeConfiguration{}, nil | ||||
| 	} | ||||
| 	maxr := strconv.Itoa(int(configs[0].MaxRetries)) | ||||
| 	retry := strconv.Itoa(int(configs[0].RetryInterval)) | ||||
| 	synconfig := vo.SynchronizeConfiguration{ | ||||
| 		CollectAt:      configs[0].CollectAt.Format("15:04:05"), | ||||
| 		EntID:          configs[0].User, | ||||
| 		Imrs:           configs[0].ImrsType, | ||||
| 		ImrsAccount:    configs[0].AuthorizationAccount, | ||||
| 		ImrsKey:        string(configs[0].AuthorizationKey), | ||||
| 		ImrsSecret:     configs[0].AuthorizationSecret, | ||||
| 		Interval:       float64(configs[0].Interval), | ||||
| 		MaxRetries:     maxr, | ||||
| 		ParkID:         configs[0].Park, | ||||
| 		ReadingType:    float64(configs[0].MeterReadingType), | ||||
| 		RetryAlgorithm: float64(configs[0].RetryIntervalAlgorithm), | ||||
| 		RetryInterval:  retry, | ||||
| 	} | ||||
| 	return synconfig, nil | ||||
| } | ||||
| func (sr _SynchronizeRepository) CreateSynchronizeConfiguration(tx pgx.Tx, ctx context.Context, uId string, form *vo.SynchronizeConfigurationCreateForm) (bool, error) { | ||||
| 	sr.log.Info("创建新的同步用户配置", zap.String("user Id", uId)) | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
| 	//insert into synchronize_config (user_id, park_id, meter_reading_type, imrs_type, imrs_authorization_account, | ||||
| 	//	imrs_authorization_secret, imrs_authorization_key, interval, collect_at, max_retries, retry_interval, retry_interval_algorithm) values | ||||
| 	configSql, configArgs, _ := sr.ds. | ||||
| 		Insert(goqu.T("synchronize_config")). | ||||
| 		Cols( | ||||
| 			"user_id", "park_id", "meter_reading_type", "imrs_type", "imrs_authorization_account", "imrs_authorization_secret", | ||||
| 			"imrs_authorization_key", "interval", "collect_at", "max_retries", | ||||
| 			"retry_interval", "retry_interval_algorithm"). | ||||
| 		Vals( | ||||
| 			goqu.Vals{uId, form.ParkID, form.ReadingType, form.Imrs, form.ImrsAccount, form.ImrsSecret, form.ImrsKey, form.Interval, | ||||
| 				form.CollectAt, form.MaxRetries, form.RetryInterval, form.RetryAlgorithm, | ||||
| 			}, | ||||
| 		). | ||||
| 		Prepared(true).ToSQL() | ||||
| 	ok, err := tx.Exec(ctx, configSql, configArgs...) | ||||
| 	if err != nil { | ||||
| 		sr.log.Error("创建同步配置信息失败", zap.Error(err)) | ||||
| 		return false, err | ||||
| 	} | ||||
| 	return ok.RowsAffected() > 0, nil | ||||
| } | ||||
| @@ -41,7 +41,7 @@ func App() *fiber.App { | ||||
| 	})) //恢复中间件 | ||||
| 	app.Use(logger.NewLogMiddleware(logger.LogMiddlewareConfig{ | ||||
| 		Logger: logger.Named("App"), | ||||
| 	}))                               //日志中间件 | ||||
| 	})) //日志中间件 | ||||
| 	app.Use(security.SessionRecovery) //会话恢复中间件 | ||||
|  | ||||
| 	controller.InitializeUserHandlers(app) | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| package calculate | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/model" | ||||
| 	"fmt" | ||||
| @@ -15,7 +16,7 @@ func CheckMeterArea(report *model.ReportIndex, meters []*model.MeterDetail) (boo | ||||
| 		var meterWithoutArea int32 | ||||
|  | ||||
| 		for _, m := range meters { | ||||
| 			if (m.MeterType ==  model.METER_INSTALLATION_TENEMENT || m.MeterType ==  model.METER_INSTALLATION_POOLING) && | ||||
| 			if (m.MeterType == model.METER_INSTALLATION_TENEMENT || m.MeterType == model.METER_INSTALLATION_POOLING) && | ||||
| 				m.Area == nil { | ||||
| 				atomic.AddInt32(&meterWithoutArea, 1) | ||||
| 			} | ||||
|   | ||||
							
								
								
									
										448
									
								
								service/calculate/meters.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										448
									
								
								service/calculate/meters.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,448 @@ | ||||
| package calculate | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/model" | ||||
| 	"electricity_bill_calc/model/calculate" | ||||
| 	"electricity_bill_calc/repository" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/shopspring/decimal" | ||||
| ) | ||||
|  | ||||
| func CollectMeters(tenements []calculate.PrimaryTenementStatistics, poolings []calculate.Meter, publics []calculate.Meter) (MeterMap, error) { | ||||
| 	meters := make(MeterMap) | ||||
| 	// Collect tenement meters | ||||
| 	for _, t := range tenements { | ||||
| 		for _, m := range t.Meters { | ||||
| 			key := Key{TenementID: t.Tenement.Id, Code: m.Code} | ||||
| 			meters[key] = m | ||||
| 		} | ||||
| 	} | ||||
| 	// Collect poolings | ||||
| 	for _, m := range poolings { | ||||
| 		key := Key{TenementID: "", Code: m.Code} | ||||
| 		meters[key] = m | ||||
| 	} | ||||
| 	// Collect publics | ||||
| 	for _, m := range publics { | ||||
| 		key := Key{TenementID: "", Code: m.Code} | ||||
| 		meters[key] = m | ||||
| 	} | ||||
| 	return meters, nil | ||||
| } | ||||
|  | ||||
| // / 计算基本电费摊薄 | ||||
| func CalculateBasicPooling(report *model.ReportIndex, summary *calculate.Summary, meters *MeterMap) error { | ||||
| 	switch report.BasisPooled { | ||||
| 	case model.POOLING_MODE_AREA: | ||||
| 		if summary.OverallArea.IsZero() { | ||||
| 			return fmt.Errorf("园区中表计覆盖总面积为零,无法按面积摊薄") | ||||
| 		} | ||||
| 		for _, meter := range *meters { | ||||
| 			meterFee := meter.Overall.Amount.InexactFloat64() * summary.BasicPooledPriceArea.InexactFloat64() | ||||
| 			meter.PooledBasic = model.ConsumptionUnit{ | ||||
| 				Amount:     meter.Overall.Amount, | ||||
| 				Fee:        decimal.NewFromFloat(meterFee), | ||||
| 				Price:      summary.BasicPooledPriceArea, | ||||
| 				Proportion: summary.BasicFee, | ||||
| 			} | ||||
| 		} | ||||
| 	case model.POOLING_MODE_CONSUMPTION: | ||||
| 		for _, meter := range *meters { | ||||
| 			meterFee := meter.Overall.Amount.InexactFloat64() * summary.BasicPooledPriceConsumption.InexactFloat64() | ||||
| 			meter.PooledBasic = model.ConsumptionUnit{ | ||||
| 				Amount:     meter.Overall.Amount, | ||||
| 				Fee:        decimal.NewFromFloat(meterFee), | ||||
| 				Price:      summary.BasicPooledPriceConsumption, | ||||
| 				Proportion: summary.BasicFee, | ||||
| 			} | ||||
| 		} | ||||
| 	default: | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| /// 计算调整电费摊薄 | ||||
|  | ||||
| func CalculateAdjustPooling(report model.ReportIndex, summary calculate.Summary, meters MeterMap) error { | ||||
| 	var p decimal.Decimal | ||||
| 	switch report.AdjustPooled { | ||||
| 	case model.POOLING_MODE_AREA: | ||||
| 		if summary.OverallArea.IsZero() { | ||||
| 			return fmt.Errorf("园区中表计覆盖总面积为零,无法按面积摊薄") | ||||
| 		} | ||||
|  | ||||
| 		for _, meter := range meters { | ||||
| 			meterFee := meter.Overall.Amount.Mul(summary.AdjustPooledPriceArea) | ||||
| 			if summary.AdjustFee.IsZero() { | ||||
| 				p = decimal.Zero | ||||
| 			} else { | ||||
| 				p = meterFee.Div(summary.AdjustFee) | ||||
| 			} | ||||
| 			meter.PooledAdjust = model.ConsumptionUnit{ | ||||
| 				Amount:     meter.Overall.Amount, | ||||
| 				Fee:        meterFee, | ||||
| 				Price:      summary.AdjustPooledPriceArea, | ||||
| 				Proportion: p, | ||||
| 			} | ||||
| 		} | ||||
| 	case model.POOLING_MODE_CONSUMPTION: | ||||
| 		for _, meter := range meters { | ||||
| 			meterFee := meter.Overall.Amount.Mul(summary.AdjustPooledPriceConsumption) | ||||
| 			if summary.AdjustFee.IsZero() { | ||||
| 				p = decimal.Zero | ||||
| 			} else { | ||||
| 				p = meterFee.Div(summary.AdjustFee) | ||||
| 			} | ||||
| 			meter.PooledAdjust = model.ConsumptionUnit{ | ||||
| 				Amount:     meter.Overall.Amount, | ||||
| 				Fee:        meterFee, | ||||
| 				Price:      summary.AdjustPooledPriceConsumption, | ||||
| 				Proportion: p, | ||||
| 			} | ||||
| 		} | ||||
| 	default: | ||||
|  | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // 除数问题 | ||||
| func CalculateLossPooling(report model.ReportIndex, summary calculate.Summary, meters MeterMap) error { | ||||
| 	switch report.LossPooled { | ||||
| 	case model.POOLING_MODE_AREA: | ||||
| 		if summary.OverallArea.IsZero() { | ||||
| 			return fmt.Errorf("园区中表计覆盖总面积为零,无法按面积摊薄") | ||||
| 		} | ||||
| 		for _, meter := range meters { | ||||
| 			pooledLossAmount1 := meter.Detail.Area.Decimal.Div(summary.OverallArea) | ||||
| 			pooledLossAmount := pooledLossAmount1.Mul(summary.AuthoizeLoss.Amount) | ||||
| 			meter.PooledLoss = model.ConsumptionUnit{ | ||||
| 				Amount:     pooledLossAmount, | ||||
| 				Fee:        pooledLossAmount.Mul(summary.LossDilutedPrice), | ||||
| 				Price:      summary.LossDilutedPrice, | ||||
| 				Proportion: meter.Detail.Area.Decimal.Div(summary.OverallArea), | ||||
| 			} | ||||
| 		} | ||||
| 	case model.POOLING_MODE_CONSUMPTION: | ||||
| 		for _, meter := range meters { | ||||
| 			pooledLossAmount1 := meter.Detail.Area.Decimal.Div(summary.OverallArea) | ||||
| 			pooledLossAmount := pooledLossAmount1.Mul(summary.AuthoizeLoss.Amount) | ||||
|  | ||||
| 			meter.PooledLoss = model.ConsumptionUnit{ | ||||
| 				Amount:     pooledLossAmount, | ||||
| 				Fee:        pooledLossAmount.Mul(summary.LossDilutedPrice), | ||||
| 				Price:      summary.LossDilutedPrice, | ||||
| 				Proportion: meter.Overall.Amount.Div(summary.Overall.Amount), | ||||
| 			} | ||||
| 		} | ||||
| 	default: | ||||
| 		// 其他情况下不做处理 | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| /// 计算所有商户类型表计的全周期电量。 | ||||
|  | ||||
| func CalculateTenementConsumptions(meters MeterMap) (map[string]decimal.Decimal, error) { | ||||
| 	consumptions := make(map[string]decimal.Decimal) | ||||
| 	for _, meter := range meters { | ||||
| 		if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT { | ||||
| 			amount, ok := consumptions[meter.Code] | ||||
| 			if !ok { | ||||
| 				amount = decimal.Decimal{} | ||||
| 			} | ||||
| 			amount.Add(meter.Overall.Amount).Add(amount) | ||||
| 			consumptions[meter.Code] = amount | ||||
| 		} | ||||
| 	} | ||||
| 	for _, meter := range meters { | ||||
| 		if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT { | ||||
| 			amount, ok := consumptions[meter.Code] | ||||
| 			if !ok { | ||||
| 				return nil, errors.New("meter code not found in consumptions") | ||||
| 			} | ||||
|  | ||||
| 			if amount.GreaterThan(decimal.Zero) { | ||||
| 				meter.SharedPoolingProportion = meter.Overall.Amount.Div(amount) | ||||
| 			} else if amount.IsZero() { | ||||
| 				meter.SharedPoolingProportion = decimal.NewFromFloat(1.0) | ||||
| 			} else { | ||||
| 				meter.SharedPoolingProportion = decimal.NewFromFloat(1.0) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return consumptions, nil | ||||
| } | ||||
|  | ||||
| /* | ||||
| /// 计算商户表计的公摊分摊 | ||||
|  | ||||
| func CalculateTenementPoolings(report model.ReportIndex, summary calculate.Summary, meters MeterMap, meterRelations []model.MeterRelation) error { | ||||
| 	for _, meter := range meters { | ||||
| 		if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT { | ||||
| 			switch report.PublicPooled { | ||||
| 			case model.POOLING_MODE_AREA: | ||||
| 				for _, relation := range meterRelations { | ||||
| 					if relation.SlaveMeter == meter.Code { | ||||
| 						key := Key{ | ||||
| 							Code: relation.MasterMeter, | ||||
| 						} | ||||
| 						parentMeter, ok := meters[key] | ||||
| 						if !ok { | ||||
| 							return errors.New("父级表记未找到") | ||||
| 						} | ||||
|  | ||||
| 						poolingAmount := meter.Detail.Area.Decimal.Div(parentMeter.CoveredArea). | ||||
| 							Mul(meter.SharedPoolingProportion). | ||||
| 							Mul(parentMeter.Overall.Amount).Mul(summary.Overall.Price) | ||||
|  | ||||
| 						pooling := calculate.Pooling{ | ||||
| 							Code: parentMeter.Code, | ||||
| 							Detail: model.ConsumptionUnit{ | ||||
| 								Amount: poolingAmount, | ||||
| 								Fee:    poolingAmount.Mul(summary.Overall.Price), | ||||
| 								Price:  summary.Overall.Price, | ||||
| 								//后续debug此处需要判断, | ||||
| 								Proportion: poolingAmount.Div(parentMeter.Overall.Amount), | ||||
| 							}, | ||||
| 						} | ||||
|  | ||||
| 						pooling := calculate.Pooling{ | ||||
| 							Code: parentMeter.Code, | ||||
| 							Detail: model.ConsumptionUnit{ | ||||
| 								Amount:     poolingAmount, | ||||
| 								Fee:        poolingAmount.Mul(summary.Overall.Price), | ||||
| 								Price:      summary.Overall.Price, | ||||
| 								Proportion: poolingAmount.Div(parentMeter.Overall.Amount), | ||||
| 							}, | ||||
| 						} | ||||
| 						meter.PooledPublic = &ConsumptionUnit{ | ||||
| 							Amount:     poolingAmount, | ||||
| 							Fee:        new(big.Rat).Mul(poolingAmount, summary.Overall.Price), | ||||
| 							Price:      summary.Overall.Price, | ||||
| 							Proportion: new(big.Rat).Quo(poolingAmount, parentAmount), | ||||
| 						} | ||||
|  | ||||
| 						meter.Poolings = append(meter.Poolings, pooling) | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 			case Consumption: | ||||
| 				for _, relation := range meterRelations { | ||||
| 					if relation.SlaveMeter == meter.Code { | ||||
| 						parentMeter, ok := meters[relation.MasterMeter] | ||||
| 						if !ok { | ||||
| 							return errors.New("parent meter not found") | ||||
| 						} | ||||
|  | ||||
| 						if parentMeter.Overall.Amount.Cmp(new(big.Rat)) == 0 { | ||||
| 							poolingAmount := new(big.Rat) | ||||
| 							parentAmount := new(big.Rat) | ||||
|  | ||||
| 							pooling := &Pooling{ | ||||
| 								Code: parentMeter.Code, | ||||
| 								Detail: &ConsumptionUnit{ | ||||
| 									Amount:     poolingAmount, | ||||
| 									Fee:        new(big.Rat), | ||||
| 									Price:      summary.Overall.Price, | ||||
| 									Proportion: new(big.Rat), | ||||
| 								}, | ||||
| 							} | ||||
|  | ||||
| 							meter.PooledPublic = &ConsumptionUnit{ | ||||
| 								Amount:     poolingAmount, | ||||
| 								Fee:        new(big.Rat), | ||||
| 								Price:      summary.Overall.Price, | ||||
| 								Proportion: new(big.Rat), | ||||
| 							} | ||||
|  | ||||
| 							meter.Poolings = append(meter.Poolings, pooling) | ||||
| 						} else { | ||||
| 							poolingAmount := new(big.Rat).Mul(meter.Overall.Amount, new(big.Rat).Quo(parentMeter.Overall.Amount, parentMeter.Overall.Amount)) | ||||
| 							parentAmount := parentMeter.Overall.Amount | ||||
|  | ||||
| 							pooling := &Pooling{ | ||||
| 								Code: parentMeter.Code, | ||||
| 								Detail: &ConsumptionUnit{ | ||||
| 									Amount:     poolingAmount, | ||||
| 									Fee:        new(big.Rat).Mul(poolingAmount, summary.Overall.Price), | ||||
| 									Price:      summary.Overall.Price, | ||||
| 									Proportion: new(big.Rat).Quo(poolingAmount, parentAmount), | ||||
| 								}, | ||||
| 							} | ||||
|  | ||||
| 							meter.PooledPublic = &ConsumptionUnit{ | ||||
| 								Amount:     poolingAmount, | ||||
| 								Fee:        new(big.Rat).Mul(poolingAmount, summary.Overall.Price), | ||||
| 								Price:      summary.Overall.Price, | ||||
| 								Proportion: new(big.Rat).Quo(poolingAmount, parentAmount), | ||||
| 							} | ||||
|  | ||||
| 							meter.Poolings = append(meter.Poolings, pooling) | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 			default: | ||||
| 				// handle other pooling modes... | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| */ | ||||
| // 计算商户表计的公摊分摊 | ||||
| func CalculateTenementPoolings(report model.ReportIndex, summary calculate.Summary, meters MeterMap, meterRelations []model.MeterRelation) error { | ||||
|  | ||||
| 	switch report.PublicPooled { | ||||
| 	case model.POOLING_MODE_AREA: | ||||
| 		for _, meter := range meters { | ||||
| 			if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT { | ||||
| 				var pooleds []struct { | ||||
| 					PooledAmount decimal.Decimal | ||||
| 					ParentAmount decimal.Decimal | ||||
| 					ParentCode   string | ||||
| 				} | ||||
| 				for _, relation := range meterRelations { | ||||
| 					if relation.SlaveMeter == meter.Code { | ||||
| 						key := Key{ | ||||
| 							Code: relation.MasterMeter, | ||||
| 						} | ||||
| 						parentMeter, ok := meters[key] | ||||
| 						if !ok { | ||||
| 							// 处理未找到父级表计的情况 | ||||
| 							continue | ||||
| 						} | ||||
| 						// 计算分摊电量和父级表电量 | ||||
|  | ||||
| 						pooledAmount := meter.Detail.Area.Decimal.Div(parentMeter.CoveredArea).Mul(parentMeter.Overall.Amount).Mul(meter.SharedPoolingProportion) | ||||
| 						pooleds = append(pooleds, struct { | ||||
| 							PooledAmount decimal.Decimal | ||||
| 							ParentAmount decimal.Decimal | ||||
| 							ParentCode   string | ||||
| 						}{ | ||||
| 							PooledAmount: pooledAmount, | ||||
| 							ParentAmount: parentMeter.Overall.Amount, | ||||
| 							ParentCode:   parentMeter.Code, | ||||
| 						}) | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				// 计算总分摊电量和总父级电量 | ||||
| 				var consumptions, total decimal.Decimal | ||||
| 				for _, p := range pooleds { | ||||
| 					consumptions = consumptions.Add(p.PooledAmount) | ||||
| 					total = total.Add(p.ParentAmount) | ||||
| 				} | ||||
|  | ||||
| 				// 计算并更新公摊分摊信息 | ||||
| 				for _, p := range pooleds { | ||||
| 					poolingAmount := p.PooledAmount | ||||
| 					proportion := p.PooledAmount.Div(p.ParentAmount) | ||||
| 					fee := poolingAmount.Mul(summary.Overall.Price) | ||||
|  | ||||
| 					// 更新父级表计的公摊分摊信息 | ||||
| 					key := Key{ | ||||
| 						Code: p.ParentCode, | ||||
| 					} | ||||
| 					parentMeter := meters[key] | ||||
| 					parentMeter.PooledPublic.Amount = consumptions | ||||
| 					parentMeter.PooledPublic.Fee = consumptions.Mul(summary.Overall.Price) | ||||
| 					parentMeter.PooledPublic.Proportion = consumptions.Div(total) | ||||
| 					meters[Key{Code: p.ParentCode}] = parentMeter | ||||
| 					// 创建并更新分摊信息 | ||||
| 					pooling := calculate.Pooling{ | ||||
| 						Code: p.ParentCode, | ||||
| 						Detail: model.ConsumptionUnit{ | ||||
| 							Amount:     poolingAmount, | ||||
| 							Fee:        fee, | ||||
| 							Price:      summary.Overall.Price, | ||||
| 							Proportion: proportion, | ||||
| 						}, | ||||
| 					} | ||||
| 					meter.Poolings = append(meter.Poolings, &pooling) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 	case model.POOLING_MODE_CONSUMPTION: | ||||
| 		for _, meter := range meters { | ||||
| 			if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT { | ||||
| 				var pooled []struct { | ||||
| 					PooledAmount decimal.Decimal | ||||
| 					ParentAmount decimal.Decimal | ||||
| 					ParentCode   string | ||||
| 				} | ||||
| 				for _, relation := range meterRelations { | ||||
| 					if relation.SlaveMeter == meter.Code { | ||||
| 						parentMeter, ok := meters[Key{Code: relation.MasterMeter}] | ||||
| 						if !ok { | ||||
| 							// 处理未找到父级表计的情况 | ||||
| 							continue | ||||
| 						} | ||||
| 						// 计算分摊电量和父级电量 | ||||
| 						var pooledAmount decimal.Decimal | ||||
| 						if parentMeter.Overall.Amount.IsZero() { | ||||
| 							relations, err := repository.MeterRepository.ListPooledMeterRelations(report.Park, meter.Code) | ||||
| 							if err != nil { | ||||
| 								return err | ||||
| 							} | ||||
| 							//此处rust版本有误,更新后的解决办法 | ||||
| 							pooledAmount = meter.Overall.Amount.Div(decimal.NewFromInt(int64(len(relations)))).Mul(parentMeter.Overall.Amount) | ||||
| 						} | ||||
| 						pooled = append(pooled, struct { | ||||
| 							PooledAmount decimal.Decimal | ||||
| 							ParentAmount decimal.Decimal | ||||
| 							ParentCode   string | ||||
| 						}{ | ||||
| 							PooledAmount: pooledAmount, | ||||
| 							ParentAmount: parentMeter.Overall.Amount, | ||||
| 							ParentCode:   parentMeter.Code, | ||||
| 						}) | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				// 计算总分摊电量和总父级表记电量 | ||||
| 				var consumptions, total decimal.Decimal | ||||
| 				for _, p := range pooled { | ||||
| 					consumptions = consumptions.Add(p.PooledAmount) | ||||
| 					total = total.Add(p.ParentAmount) | ||||
| 				} | ||||
|  | ||||
| 				// 计算并更新公摊分摊信息 | ||||
| 				for _, p := range pooled { | ||||
| 					poolingAmount := p.PooledAmount | ||||
| 					proportion := p.PooledAmount.Div(p.ParentAmount) | ||||
| 					fee := poolingAmount.Mul(summary.Overall.Price) | ||||
|  | ||||
| 					// 更新父级表计的公摊分摊信息 | ||||
| 					parentMeter := meters[Key{Code: p.ParentCode}] | ||||
| 					parentMeter.PooledPublic.Amount = consumptions | ||||
| 					parentMeter.PooledPublic.Fee = consumptions.Mul(summary.Overall.Price) | ||||
| 					parentMeter.PooledPublic.Proportion = consumptions.Div(total) | ||||
| 					meters[Key{Code: p.ParentCode}] = parentMeter | ||||
|  | ||||
| 					// 创建并更新分摊信息 | ||||
| 					pooling := calculate.Pooling{ | ||||
| 						Code: p.ParentCode, | ||||
| 						Detail: model.ConsumptionUnit{ | ||||
| 							Amount:     poolingAmount, | ||||
| 							Fee:        fee, | ||||
| 							Price:      summary.Overall.Price, | ||||
| 							Proportion: proportion, | ||||
| 						}, | ||||
| 					} | ||||
| 					meter.Poolings = append(meter.Poolings, &pooling) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 	default: | ||||
| 		// 处理其他分摊模式 | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										81
									
								
								service/calculate/persist.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								service/calculate/persist.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| package calculate | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/global" | ||||
| 	"electricity_bill_calc/model" | ||||
| 	"electricity_bill_calc/model/calculate" | ||||
| 	"electricity_bill_calc/repository" | ||||
| 	"github.com/jackc/pgx/v5" | ||||
| ) | ||||
|  | ||||
| // 向数据库保存核算概况结果 | ||||
| func SaveSummary(tx pgx.Tx, summary calculate.Summary) error { | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
|  | ||||
| 	// 保存核算概况结果到数据库 | ||||
| 	err := repository.CalculateRepository.SaveReportSummary(tx, summary) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	tx.Commit(ctx) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // type MeterMap map[string]map[string]calculate.Meter | ||||
| // 向数据库保存公共表计的计算结果 | ||||
| func SavePublics(tx pgx.Tx, report model.ReportIndex, meters MeterMap) error { | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
|  | ||||
| 	var filteredMeters []calculate.Meter | ||||
|  | ||||
| 	for _, m := range meters { | ||||
| 		if m.Detail.MeterType == model.METER_INSTALLATION_PARK { | ||||
| 			filteredMeters = append(filteredMeters, m) | ||||
| 		} | ||||
| 	} | ||||
| 	err := repository.CalculateRepository.SaveReportPublics(tx, report.Id, filteredMeters) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	tx.Commit(ctx) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func SavePoolings(tx pgx.Tx, report model.ReportIndex, meters MeterMap, relations []model.MeterRelation) error { | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
| 	var poolingMeters []calculate.Meter | ||||
| 	var tenementMeters []calculate.Meter | ||||
| 	// 根据条件筛选 Meter 并保存到对应的数组中 | ||||
| 	for _, m := range meters { | ||||
| 		if m.Detail.MeterType == model.METER_INSTALLATION_POOLING { | ||||
| 			poolingMeters = append(poolingMeters, m) | ||||
| 		} else if m.Detail.MeterType == model.METER_INSTALLATION_TENEMENT { | ||||
| 			tenementMeters = append(tenementMeters, m) | ||||
| 		} | ||||
| 	} | ||||
| 	err := repository.CalculateRepository.SaveReportPoolings(tx, report.Id, poolingMeters, relations, tenementMeters) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	tx.Commit(ctx) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| func SaveTenements(tx pgx.Tx, report model.ReportIndex, tenement []calculate.PrimaryTenementStatistics, tc []calculate.TenementCharge) error { | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
| 	var ts []model.Tenement | ||||
| 	for _, r := range tenement { | ||||
| 		ts = append(ts, r.Tenement) | ||||
| 	} | ||||
| 	err := repository.CalculateRepository.SaveReportTenement(tx, report, ts, tc) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	tx.Commit(ctx) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| @@ -4,13 +4,13 @@ import ( | ||||
| 	"electricity_bill_calc/model" | ||||
| 	"electricity_bill_calc/model/calculate" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/shopspring/decimal" | ||||
|  | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| // 计算已经启用的商铺面积和 | ||||
| func TotalConsumptionCalculate(tenements []calculate.PrimaryTenementStatistics, | ||||
| 	summary calculate.Summary) decimal.Decimal { | ||||
| func TotalConsumptionCalculate(tenements []calculate.PrimaryTenementStatistics, summary calculate.Summary) decimal.Decimal { | ||||
| 	var areaMaters []calculate.Meter | ||||
| 	for _, t := range tenements { | ||||
| 		areaMaters = append(areaMaters, t.Meters...) | ||||
| @@ -41,7 +41,7 @@ func removeDuplicates(meters []calculate.Meter) []calculate.Meter { | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| //计算线损以及调整线损 | ||||
| // 计算线损以及调整线损 | ||||
| func LossCalculate(report *model.ReportIndex, Public *[]calculate.Meter, | ||||
| 	publicTotal *decimal.Decimal, summary *calculate.Summary) error { | ||||
| 	summary.Loss = summary.Overall.Amount.Sub(summary.TotalConsumption) | ||||
| @@ -91,7 +91,7 @@ func LossCalculate(report *model.ReportIndex, Public *[]calculate.Meter, | ||||
|  | ||||
| // 计算已经启用的商铺面积和 | ||||
| func EnabledAreaCalculate(tenements *[]calculate.PrimaryTenementStatistics, | ||||
| 	summary *calculate.Summary) error { | ||||
| 	summary *calculate.Summary) (*decimal.Decimal, error) { | ||||
| 	var areaMeters []calculate.Meter | ||||
| 	for _, t := range *tenements { | ||||
| 		areaMeters = append(areaMeters, t.Meters...) | ||||
| @@ -108,13 +108,16 @@ func EnabledAreaCalculate(tenements *[]calculate.PrimaryTenementStatistics, | ||||
| 	if summary != nil { | ||||
| 		summary.OverallArea = areaTotal | ||||
| 	} else { | ||||
| 		return errors.New("summary is nil") | ||||
| 		return nil, errors.New("summary is nil") | ||||
| 	} | ||||
| 	return nil | ||||
| 	return &areaTotal, nil | ||||
| } | ||||
|  | ||||
| // 计算基本电费分摊、调整电费分摊以及电费摊薄单价。 | ||||
| func PricesCalculate(summary *calculate.Summary) error { | ||||
| // ================================================================================= | ||||
| // / 计算基本电费分摊、调整电费分摊以及电费摊薄单价。 | ||||
| // / | ||||
| // / - `summary`:核算报表的摘要信息 | ||||
| func CalculatePrices(summary *calculate.Summary) error { | ||||
| 	if summary.TotalConsumption.IsZero() { | ||||
| 		return nil | ||||
| 	} | ||||
| @@ -131,4 +134,5 @@ func PricesCalculate(summary *calculate.Summary) error { | ||||
| 		summary.AdjustPooledPriceArea = summary.AdjustFee.Div(summary.OverallArea) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -14,9 +14,9 @@ import ( | ||||
| ) | ||||
|  | ||||
| // 核算园区中的全部商户表计电量用电 | ||||
| func TenementMetersCalculate(report *model.ReportIndex, PeriodStart time.Time, | ||||
| 	PeriodEnd time.Time, meterDetails []*model.MeterDetail, | ||||
| 	summary calculate.Summary) ([]calculate.PrimaryTenementStatistics, error) { | ||||
| func TenementMetersCalculate(report *model.ReportIndex, | ||||
| 	PeriodStart time.Time, PeriodEnd time.Time, | ||||
| 	meterDetails []*model.MeterDetail, summary calculate.Summary) ([]calculate.PrimaryTenementStatistics, error) { | ||||
| 	tenements, err := repository.CalculateRepository.GetAllTenements(report.Id) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("tenement 0", err) | ||||
| @@ -72,7 +72,7 @@ func TenementMetersCalculate(report *model.ReportIndex, PeriodStart time.Time, | ||||
| 	return tenementReports, nil | ||||
| } | ||||
|  | ||||
| //TODO: 2023.08.02 此方法未完成此方法主要用于。确定指定商户在指定时间段内的所有表计读数(完成) | ||||
| // TODO: 2023.08.02 此方法未完成此方法主要用于。确定指定商户在指定时间段内的所有表计读数(完成) | ||||
| func determineTenementConsumptions(tenement model.Tenement, | ||||
| 	relatedMeters []model.TenementMeter, periodStart time.Time, | ||||
| 	periodEnd time.Time, currentTermReadings []model.MeterReading, lastPeriodReadings []model.MeterReading, | ||||
| @@ -183,7 +183,7 @@ func getMeterDetail(meterDetails []*model.MeterDetail, code string) (model.Meter | ||||
| 	return model.MeterDetail{}, errors.New(fmt.Sprintf("表计 %s 的详细信息不存在", code)) | ||||
| } | ||||
|  | ||||
| //确定指定表计的起始读数 | ||||
| // 确定指定表计的起始读数 | ||||
| func determineTenementMeterStartReading(meterId string, periodStart time.Time, tenementMovedInAt time.Time, | ||||
| 	meterRelation model.TenementMeter, currentTermReadings []model.MeterReading, | ||||
| 	lastPeriodReadings []model.MeterReading) (*model.MeterReading, error) { | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package calculate | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/global" | ||||
| 	"electricity_bill_calc/model/calculate" | ||||
| 	"electricity_bill_calc/repository" | ||||
| 	"fmt" | ||||
| @@ -73,23 +74,95 @@ func MainCalculateProcess(rid string) { | ||||
| 	} | ||||
|  | ||||
| 	// 计算所有已经启用的商铺面积总和,仅计算所有未迁出的商户的所有表计对应的商铺面积。 | ||||
| 	err = EnabledAreaCalculate(&tenementReports, &summary) | ||||
| 	_, err = EnabledAreaCalculate(&tenementReports, &summary) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("10", err) | ||||
| 		return | ||||
| 	} | ||||
| 	err = PricesCalculate(&summary) | ||||
| 	err = CalculatePrices(&summary) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("11", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	//为获取值初始化一个空的,合并分支时可忽略 | ||||
| 	var meters MeterMap | ||||
| 	//=========================================================================== | ||||
| 	// 计算基本电费分摊、调整电费分摊、电费摊薄单价。 | ||||
| 	err = CalculatePrices(&summary) | ||||
| 	// 收集目前所有已经处理的表计,统一对其进行摊薄计算。 | ||||
| 	meters, err := CollectMeters(tenementReports, poolingMetersReports, parkMetersReports) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("12", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// 计算商户的合计电费信息,并归总与商户相关联的表计记录 | ||||
| 	tenementCharges := TenementChargeCalculate(tenementReports, summary, meters) | ||||
|  | ||||
| 	fmt.Println(meterRelations, poolingMetersReports, tenementCharges) | ||||
| 	// 根据核算报表中设置的摊薄内容,逐个表计进行计算 | ||||
| 	err = CalculateBasicPooling(report, &summary, &meters) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("13", err) | ||||
| 		return | ||||
| 	} | ||||
| 	err = CalculateAdjustPooling(*report, summary, meters) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("14", err) | ||||
| 		return | ||||
| 	} | ||||
| 	err = CalculateLossPooling(*report, summary, meters) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("15", err) | ||||
| 		return | ||||
| 	} | ||||
| 	// 计算所有商户类型表计的全周期电量,并根据全周期电量计算共用过同一表计的商户的二次分摊比例。 | ||||
| 	_, err = CalculateTenementConsumptions(meters) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("16", err) | ||||
| 		return | ||||
| 	} | ||||
| 	err = CalculateTenementPoolings(*report, summary, meters, meterRelations) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("17", err) | ||||
| 		return | ||||
| 	} | ||||
| 	// 计算商户的合计电费信息,并归总与商户相关联的表计记录 | ||||
| 	tenementCharges = TenementChargeCalculate(tenementReports, summary, meters) | ||||
|  | ||||
| 	// 从此处开始向数据库保存全部计算结果。 | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
| 	tx, _ := global.DB.Begin(ctx) | ||||
| 	err = repository.CalculateRepository.ClearReportContent(tx, report.Id) | ||||
| 	if err != nil { | ||||
| 		tx.Rollback(ctx) | ||||
| 		fmt.Println("18", err) | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	err = SaveSummary(tx, summary) | ||||
| 	if err != nil { | ||||
| 		tx.Rollback(ctx) | ||||
| 		fmt.Println("19", err) | ||||
|  | ||||
| 	} | ||||
| 	err = SavePublics(tx, *report, meters) | ||||
| 	if err != nil { | ||||
| 		tx.Rollback(ctx) | ||||
| 		fmt.Println("20", err) | ||||
|  | ||||
| 	} | ||||
| 	err = SavePoolings(tx, *report, meters, meterRelations) | ||||
| 	if err != nil { | ||||
| 		tx.Rollback(ctx) | ||||
| 		fmt.Println("21", err) | ||||
|  | ||||
| 	} | ||||
| 	err = SaveTenements(tx, *report, tenementReports, tenementCharges) | ||||
| 	if err != nil { | ||||
| 		tx.Rollback(ctx) | ||||
| 		fmt.Println("22", err) | ||||
|  | ||||
| 	} | ||||
| 	tx.Commit(ctx) | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										51
									
								
								service/synchronize.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								service/synchronize.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| package service | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/global" | ||||
| 	"electricity_bill_calc/logger" | ||||
| 	"electricity_bill_calc/repository" | ||||
| 	"electricity_bill_calc/vo" | ||||
| 	"github.com/doug-martin/goqu/v9" | ||||
| 	"go.uber.org/zap" | ||||
| ) | ||||
|  | ||||
| type _SynchronizeService struct { | ||||
| 	log *zap.Logger | ||||
| 	ds  goqu.DialectWrapper | ||||
| } | ||||
|  | ||||
| var SynchronizeService = _SynchronizeService{ | ||||
| 	log: logger.Named("Service", "Synchronize"), | ||||
| 	ds:  goqu.Dialect("postgres"), | ||||
| } | ||||
|  | ||||
| func (ss _SynchronizeService) CreateSynchronizeConfiguration(userId string, form *vo.SynchronizeConfigurationCreateForm) error { | ||||
| 	ss.log.Info("创建一条新的同步配置", zap.String("user id", userId)) | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
| 	tx, err := global.DB.Begin(ctx) | ||||
| 	if err != nil { | ||||
| 		ss.log.Error("无法启动数据库事务。", zap.Error(err)) | ||||
| 		return err | ||||
| 	} | ||||
| 	ok, err := repository.SynchronizeRepository.CreateSynchronizeConfiguration(tx, ctx, userId, form) | ||||
| 	if err != nil { | ||||
| 		ss.log.Error("无法创建新的同步配置。", zap.Error(err)) | ||||
| 		tx.Rollback(ctx) | ||||
| 		return err | ||||
| 	} | ||||
| 	if !ok { | ||||
| 		ss.log.Error("数据库未能记录新的同步配置。") | ||||
| 		tx.Rollback(ctx) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	err = tx.Commit(ctx) | ||||
| 	if err != nil { | ||||
| 		ss.log.Error("未能成功提交数据库事务。", zap.Error(err)) | ||||
| 		tx.Rollback(ctx) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
|  | ||||
| } | ||||
| @@ -80,7 +80,9 @@ func (us _UserService) ProcessEnterpriseUserLogin(username, password string) (*m | ||||
| 		us.log.Error("处理企业用户登录失败。", zap.String("username", username), zap.Error(err)) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	token, _ := uuid.NewRandom() //生成uuid作为会话的token使用 | ||||
|  | ||||
| 	userSession := &model.Session{ | ||||
| 		Uid:       user.Id, | ||||
| 		Name:      user.Username, | ||||
|   | ||||
| @@ -12,14 +12,16 @@ Server: | ||||
|   ReadTimeout: 60 | ||||
|   WriteTimeout: 60 | ||||
| Redis: | ||||
|   Host: redis | ||||
|   Host: 192.168.88.129 | ||||
|   Port: 6379 | ||||
|   Password: TmFRS0w6BIrAPA1Raj | ||||
|   Password: 123456 | ||||
|   DB: 1 | ||||
| Service: | ||||
|   MaxSessionLife: 2h | ||||
|   ItemsPageSize: 20 | ||||
|   CacheLifeTime: 5m | ||||
|   HostSerial: 5 | ||||
|  | ||||
| BaselineLineLossRatio: | ||||
|   Base: 基准线损率 | ||||
|   Base: 基准线损率 | ||||
|  | ||||
|   | ||||
| @@ -147,7 +147,7 @@ func NullDecimalToString(d decimal.NullDecimal, precision ...int32) *string { | ||||
| 	return lo.ToPtr(d.Decimal.StringFixedBank(precision[0])) | ||||
| } | ||||
|  | ||||
| //将sql.NullTime转换为*string | ||||
| // 将sql.NullTime转换为*string | ||||
| func NullTime2PointerString(nullTime sql.NullTime) *string { | ||||
| 	var strPtr *string | ||||
| 	if nullTime.Valid { | ||||
| @@ -160,7 +160,7 @@ func NullTime2PointerString(nullTime sql.NullTime) *string { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| //该方法用于将时间解析为字符串指针 | ||||
| // 该方法用于将时间解析为字符串指针 | ||||
| func TimeToStringPtr(t *time.Time) *string { | ||||
| 	if t == nil { | ||||
| 		return nil | ||||
| @@ -169,4 +169,3 @@ func TimeToStringPtr(t *time.Time) *string { | ||||
| 	timeStr := t.Format("2006-01-02 15:04:05") | ||||
| 	return &timeStr | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										29
									
								
								vo/synchronize.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vo/synchronize.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| package vo | ||||
|  | ||||
| type SynchronizeConfiguration struct { | ||||
| 	CollectAt      string  `json:"collectAt"`      // 采集时间,格式:HH:mm | ||||
| 	EntID          string  `json:"entId"`          // 企业ID | ||||
| 	Imrs           string  `json:"imrs"`           // 采集系统型号 | ||||
| 	ImrsAccount    string  `json:"imrsAccount"`    // 同步登录账号 | ||||
| 	ImrsKey        string  `json:"imrsKey"`        // 同步登录私钥,Base64或者私钥文件内容 | ||||
| 	ImrsSecret     string  `json:"imrsSecret"`     // 同步登录密钥,加盐双向加密 | ||||
| 	Interval       float64 `json:"interval"`       // 采集周期,0:每小时,1:每日,2:每周,3:每月 | ||||
| 	MaxRetries     string  `json:"maxRetries"`     // 最大重试次数 | ||||
| 	ParkID         string  `json:"parkId"`         // 园区ID | ||||
| 	ReadingType    float64 `json:"readingType"`    // 采集方式,0:自动+人工,1:自动,2:人工 | ||||
| 	RetryAlgorithm float64 `json:"retryAlgorithm"` // 重试间隔算法,0:指数退避,1:2倍线性间隔,2:3倍线性间隔,3:固定间隔 | ||||
| 	RetryInterval  string  `json:"retryInterval"`  // 重试间隔,基础间隔时间,根据间隔算法不同会产生不同的间隔 | ||||
| } | ||||
| type SynchronizeConfigurationCreateForm struct { | ||||
| 	CollectAt      string  `json:"collectAt"`      // 采集时间,格式:HH:mm | ||||
| 	Imrs           string  `json:"imrs"`           // 采集系统型号,为空的时候表示不同步 | ||||
| 	ImrsAccount    string  `json:"imrsAccount"`    // 同步登录账号 | ||||
| 	ImrsKey        string  `json:"imrsKey"`        // 同步登录私钥,Base64或者私钥文件内容 | ||||
| 	ImrsSecret     string  `json:"imrsSecret"`     // 同步登录密钥,加盐双向加密 | ||||
| 	Interval       float64 `json:"interval"`       // 采集周期,0:每小时,1:每日,2:每周,3:每月 | ||||
| 	MaxRetries     string  `json:"maxRetries"`     // 最大重试次数 | ||||
| 	ParkID         string  `json:"parkId"`         // 园区ID | ||||
| 	ReadingType    float64 `json:"readingType"`    // 采集方式,0:自动+人工,1:自动,2:人工 | ||||
| 	RetryAlgorithm float64 `json:"retryAlgorithm"` // 重试间隔算法,0:指数退避,1:2倍线性间隔,2:3倍线性间隔,3:固定间隔 | ||||
| 	RetryInterval  string  `json:"retryInterval"`  // 重试间隔,基础间隔时间,根据间隔算法不同会产生不同的间隔 | ||||
| } | ||||
		Reference in New Issue
	
	Block a user