123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- package main
- import (
- "flag"
- "github.com/gin-gonic/gin"
- "io"
- "io/ioutil"
- "log"
- "os"
- "os/signal"
- "syscall"
- "time"
- "github.com/RoaringBitmap/roaring"
- "github.com/cespare/xxhash/v2"
- )
- var (
- dbfile = flag.String("dbfile", "./db", "数据库文件")
- addr = flag.String("p", ":8088", "监听地址")
- cache = roaring.NewBitmap()
- cacheModify = false //控制10秒 定时写入文件
- )
- type ProjectData struct {
- ProjectName string `json:"project_name"`
- ProjectCode string `json:"project_code"`
- Buyer string `json:"buyer"`
- ProjectDate string `json:"project_date"`
- Packages string `json:"packages"`
- }
- // init 初始化
- func init() {
- flag.Parse()
- _, err := os.Stat(*dbfile)
- if !os.IsNotExist(err) {
- bs, err := ioutil.ReadFile(*dbfile)
- if err != nil {
- log.Fatal(err)
- }
- if len(bs) > 0 {
- cache.FromBuffer(bs)
- }
- }
- //监听,写入文件保存
- go func() {
- for {
- time.Sleep(10 * time.Second)
- if cacheModify {
- saveDb()
- cacheModify = false
- }
- }
- }()
- }
- func main() {
- // 设置 Gin 模式为发布模式,关闭每次路由请求打印
- gin.SetMode(gin.ReleaseMode)
- gin.DefaultWriter = io.Discard
- router := gin.Default()
- router.POST("/rename", getRename)
- log.Println("程序监听端口", *addr)
- go func() {
- err := router.Run(*addr)
- if err != nil {
- log.Fatal(err)
- }
- }()
- //监听异常退出信号;及时保存数据
- signalChan := make(chan os.Signal, 1)
- signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
- <-signalChan
- log.Println("程序退出")
- saveDb()
- }
- // saveDb 文件写入
- func saveDb() {
- fo, err := os.OpenFile(*dbfile, os.O_CREATE|os.O_RDWR|os.O_SYNC|os.O_TRUNC, 0777)
- if err != nil {
- log.Fatal(err)
- }
- defer fo.Close()
- cache.WriteTo(fo)
- }
- // hash 计算hash
- func hash(src string) uint64 {
- return xxhash.Sum64String(src)
- }
- // RenameProjectName 获取新的不重复的项目名称
- func RenameProjectName(projectName, projectCode, packages, projectDate, buyer string) string {
- //TODO 1.判断项目名称是否重复
- var id uint64
- defer func() {
- cache.Add(uint32(id))
- cacheModify = true
- }()
- //1.项目名称
- if projectName != "" {
- id = hash(projectName)
- if !cache.Contains(uint32(id)) {
- return projectName
- }
- }
- //TODO 2.1 项目名称+项目编码
- if projectCode != "" {
- newName := projectName + "_" + projectCode
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 2.2 项目名称+分包信息
- if packages != "" {
- newName := projectName + "_" + packages
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 2.3 项目名称+项目时间
- if projectDate != "" {
- newName := projectName + "_" + projectDate
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 2.4 项目名称+采购单位名称
- if buyer != "" {
- newName := projectName + "_" + buyer
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 3.1 项目名称+项目编码+分包信息
- if projectCode != "" && packages != "" {
- newName := projectName + "_" + projectCode + "_" + packages
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 3.2 项目名称+项目编码+项目时间
- if projectCode != "" && projectDate != "" {
- newName := projectName + "_" + projectCode + "_" + projectDate
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 3.3 项目名称+项目编码+采购单位
- if projectCode != "" && buyer != "" {
- newName := projectName + "_" + projectCode + "_" + buyer
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 3.4 项目名称+分包+项目时间
- if packages != "" && projectDate != "" {
- newName := projectName + "_" + packages + "_" + projectDate
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 3.5 项目名称+分包+采购单位
- if packages != "" && buyer != "" {
- newName := projectName + "_" + packages + "_" + buyer
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 3.6 项目名称+项目时间+采购单位
- if projectDate != "" && buyer != "" {
- newName := projectName + "_" + projectDate + "_" + buyer
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 4.1 项目名称+项目编码+分包信息+项目时间
- if projectCode != "" && packages != "" && projectDate != "" {
- newName := projectName + "_" + projectCode + "_" + packages + "_" + projectDate
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 4.2 项目名称+项目编码+分包信息+采购单位
- if projectCode != "" && packages != "" && buyer != "" {
- newName := projectName + "_" + projectCode + "_" + packages + "_" + buyer
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- //TODO 5 项目名称+项目编码+分包信息+项目时间+采购单位
- if projectCode != "" && packages != "" && projectDate != "" && buyer != "" {
- newName := projectName + "_" + projectCode + "_" + packages + "_" + projectDate + "_" + buyer
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- }
- now := time.Now().Format("2006-01-02")
- newName := projectName + "_" + projectCode + "_" + packages + "_" + projectDate + "_" + buyer + "_" + now
- id = hash(newName)
- if !cache.Contains(uint32(id)) {
- return newName
- }
- return ""
- }
- // getRename 获取新的不重复名称
- func getRename(c *gin.Context) {
- var data = ProjectData{}
- err := c.ShouldBindJSON(&data)
- if err != nil {
- log.Println("ShouldBindJSON", err)
- c.JSON(200, map[string]interface{}{
- "code": 0,
- "msg": "参数识别错误,请检查参数",
- "data": nil,
- })
- return
- }
- newName := RenameProjectName(data.ProjectName, data.ProjectCode, data.Packages, data.ProjectDate, data.Buyer)
- if newName != "" {
- c.JSON(200, map[string]interface{}{
- "code": 0,
- "msg": "请求成功",
- "data": newName,
- })
- } else {
- c.JSON(200, map[string]interface{}{
- "code": -1,
- "msg": "提供参数,无法获取到唯一不重复项目名称",
- "data": newName,
- })
- }
- }
|