main.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. package main
  2. import (
  3. "flag"
  4. "github.com/gin-gonic/gin"
  5. "io"
  6. "io/ioutil"
  7. "log"
  8. "os"
  9. "os/signal"
  10. "syscall"
  11. "time"
  12. "github.com/RoaringBitmap/roaring"
  13. "github.com/cespare/xxhash/v2"
  14. )
  15. var (
  16. dbfile = flag.String("dbfile", "./db", "数据库文件")
  17. addr = flag.String("p", ":8088", "监听地址")
  18. cache = roaring.NewBitmap()
  19. cacheModify = false //控制10秒 定时写入文件
  20. )
  21. type ProjectData struct {
  22. ProjectName string `json:"project_name"`
  23. ProjectCode string `json:"project_code"`
  24. Buyer string `json:"buyer"`
  25. ProjectDate string `json:"project_date"`
  26. Packages string `json:"packages"`
  27. }
  28. // init 初始化
  29. func init() {
  30. flag.Parse()
  31. _, err := os.Stat(*dbfile)
  32. if !os.IsNotExist(err) {
  33. bs, err := ioutil.ReadFile(*dbfile)
  34. if err != nil {
  35. log.Fatal(err)
  36. }
  37. if len(bs) > 0 {
  38. cache.FromBuffer(bs)
  39. }
  40. }
  41. //监听,写入文件保存
  42. go func() {
  43. for {
  44. time.Sleep(10 * time.Second)
  45. if cacheModify {
  46. saveDb()
  47. cacheModify = false
  48. }
  49. }
  50. }()
  51. }
  52. func main() {
  53. // 设置 Gin 模式为发布模式,关闭每次路由请求打印
  54. gin.SetMode(gin.ReleaseMode)
  55. gin.DefaultWriter = io.Discard
  56. router := gin.Default()
  57. router.POST("/rename", getRename)
  58. log.Println("程序监听端口", *addr)
  59. go func() {
  60. err := router.Run(*addr)
  61. if err != nil {
  62. log.Fatal(err)
  63. }
  64. }()
  65. //监听异常退出信号;及时保存数据
  66. signalChan := make(chan os.Signal, 1)
  67. signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
  68. <-signalChan
  69. log.Println("程序退出")
  70. saveDb()
  71. }
  72. // saveDb 文件写入
  73. func saveDb() {
  74. fo, err := os.OpenFile(*dbfile, os.O_CREATE|os.O_RDWR|os.O_SYNC|os.O_TRUNC, 0777)
  75. if err != nil {
  76. log.Fatal(err)
  77. }
  78. defer fo.Close()
  79. cache.WriteTo(fo)
  80. }
  81. // hash 计算hash
  82. func hash(src string) uint64 {
  83. return xxhash.Sum64String(src)
  84. }
  85. // RenameProjectName 获取新的不重复的项目名称
  86. func RenameProjectName(projectName, projectCode, packages, projectDate, buyer string) string {
  87. //TODO 1.判断项目名称是否重复
  88. var id uint64
  89. defer func() {
  90. cache.Add(uint32(id))
  91. cacheModify = true
  92. }()
  93. //1.项目名称
  94. if projectName != "" {
  95. id = hash(projectName)
  96. if !cache.Contains(uint32(id)) {
  97. return projectName
  98. }
  99. }
  100. //TODO 2.1 项目名称+项目编码
  101. if projectCode != "" {
  102. newName := projectName + "_" + projectCode
  103. id = hash(newName)
  104. if !cache.Contains(uint32(id)) {
  105. return newName
  106. }
  107. }
  108. //TODO 2.2 项目名称+分包信息
  109. if packages != "" {
  110. newName := projectName + "_" + packages
  111. id = hash(newName)
  112. if !cache.Contains(uint32(id)) {
  113. return newName
  114. }
  115. }
  116. //TODO 2.3 项目名称+项目时间
  117. if projectDate != "" {
  118. newName := projectName + "_" + projectDate
  119. id = hash(newName)
  120. if !cache.Contains(uint32(id)) {
  121. return newName
  122. }
  123. }
  124. //TODO 2.4 项目名称+采购单位名称
  125. if buyer != "" {
  126. newName := projectName + "_" + buyer
  127. id = hash(newName)
  128. if !cache.Contains(uint32(id)) {
  129. return newName
  130. }
  131. }
  132. //TODO 3.1 项目名称+项目编码+分包信息
  133. if projectCode != "" && packages != "" {
  134. newName := projectName + "_" + projectCode + "_" + packages
  135. id = hash(newName)
  136. if !cache.Contains(uint32(id)) {
  137. return newName
  138. }
  139. }
  140. //TODO 3.2 项目名称+项目编码+项目时间
  141. if projectCode != "" && projectDate != "" {
  142. newName := projectName + "_" + projectCode + "_" + projectDate
  143. id = hash(newName)
  144. if !cache.Contains(uint32(id)) {
  145. return newName
  146. }
  147. }
  148. //TODO 3.3 项目名称+项目编码+采购单位
  149. if projectCode != "" && buyer != "" {
  150. newName := projectName + "_" + projectCode + "_" + buyer
  151. id = hash(newName)
  152. if !cache.Contains(uint32(id)) {
  153. return newName
  154. }
  155. }
  156. //TODO 3.4 项目名称+分包+项目时间
  157. if packages != "" && projectDate != "" {
  158. newName := projectName + "_" + packages + "_" + projectDate
  159. id = hash(newName)
  160. if !cache.Contains(uint32(id)) {
  161. return newName
  162. }
  163. }
  164. //TODO 3.5 项目名称+分包+采购单位
  165. if packages != "" && buyer != "" {
  166. newName := projectName + "_" + packages + "_" + buyer
  167. id = hash(newName)
  168. if !cache.Contains(uint32(id)) {
  169. return newName
  170. }
  171. }
  172. //TODO 3.6 项目名称+项目时间+采购单位
  173. if projectDate != "" && buyer != "" {
  174. newName := projectName + "_" + projectDate + "_" + buyer
  175. id = hash(newName)
  176. if !cache.Contains(uint32(id)) {
  177. return newName
  178. }
  179. }
  180. //TODO 4.1 项目名称+项目编码+分包信息+项目时间
  181. if projectCode != "" && packages != "" && projectDate != "" {
  182. newName := projectName + "_" + projectCode + "_" + packages + "_" + projectDate
  183. id = hash(newName)
  184. if !cache.Contains(uint32(id)) {
  185. return newName
  186. }
  187. }
  188. //TODO 4.2 项目名称+项目编码+分包信息+采购单位
  189. if projectCode != "" && packages != "" && buyer != "" {
  190. newName := projectName + "_" + projectCode + "_" + packages + "_" + buyer
  191. id = hash(newName)
  192. if !cache.Contains(uint32(id)) {
  193. return newName
  194. }
  195. }
  196. //TODO 5 项目名称+项目编码+分包信息+项目时间+采购单位
  197. if projectCode != "" && packages != "" && projectDate != "" && buyer != "" {
  198. newName := projectName + "_" + projectCode + "_" + packages + "_" + projectDate + "_" + buyer
  199. id = hash(newName)
  200. if !cache.Contains(uint32(id)) {
  201. return newName
  202. }
  203. }
  204. now := time.Now().Format("2006-01-02")
  205. newName := projectName + "_" + projectCode + "_" + packages + "_" + projectDate + "_" + buyer + "_" + now
  206. id = hash(newName)
  207. if !cache.Contains(uint32(id)) {
  208. return newName
  209. }
  210. return ""
  211. }
  212. // getRename 获取新的不重复名称
  213. func getRename(c *gin.Context) {
  214. var data = ProjectData{}
  215. err := c.ShouldBindJSON(&data)
  216. if err != nil {
  217. log.Println("ShouldBindJSON", err)
  218. c.JSON(200, map[string]interface{}{
  219. "code": 0,
  220. "msg": "参数识别错误,请检查参数",
  221. "data": nil,
  222. })
  223. return
  224. }
  225. newName := RenameProjectName(data.ProjectName, data.ProjectCode, data.Packages, data.ProjectDate, data.Buyer)
  226. if newName != "" {
  227. c.JSON(200, map[string]interface{}{
  228. "code": 0,
  229. "msg": "请求成功",
  230. "data": newName,
  231. })
  232. } else {
  233. c.JSON(200, map[string]interface{}{
  234. "code": -1,
  235. "msg": "提供参数,无法获取到唯一不重复项目名称",
  236. "data": newName,
  237. })
  238. }
  239. }