正在显示
88 个修改的文件
包含
3741 行增加
和
165 行删除
| 1 | FROM golang:latest | 1 | FROM golang:latest |
| 2 | +#FROM 192.168.0.243:5000/mmm/character-library-metadata-bastion:base | ||
| 2 | ENV APP_DIR $GOPATH/src/character-library-metadata-bastion | 3 | ENV APP_DIR $GOPATH/src/character-library-metadata-bastion |
| 3 | RUN mkdir -p $APP_DIR | 4 | RUN mkdir -p $APP_DIR |
| 4 | WORKDIR $APP_DIR/ | 5 | WORKDIR $APP_DIR/ |
| @@ -8,7 +9,7 @@ COPY ./go.mod go.mod | @@ -8,7 +9,7 @@ COPY ./go.mod go.mod | ||
| 8 | COPY ./main.go main.go | 9 | COPY ./main.go main.go |
| 9 | RUN ["ln","-sf","/usr/share/zoneinfo/Asia/Shanghai","/etc/localtime"] | 10 | RUN ["ln","-sf","/usr/share/zoneinfo/Asia/Shanghai","/etc/localtime"] |
| 10 | ENV GO111MODULE on | 11 | ENV GO111MODULE on |
| 11 | -ENV GOPROXY https://goproxy.io | 12 | +ENV GOPROXY https://goproxy.cn |
| 12 | RUN ["go","mod","tidy"] | 13 | RUN ["go","mod","tidy"] |
| 13 | RUN ["ls"] | 14 | RUN ["ls"] |
| 14 | RUN ["go","build"] | 15 | RUN ["go","build"] |
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | ## 源文件管理 | 3 | ## 源文件管理 |
| 4 | 4 | ||
| 5 | - 文件列表 - list | 5 | - 文件列表 - list |
| 6 | -- 上传 - 上传oss / 创建file | 6 | +- 上传 - 上传 oss / 创建 file |
| 7 | - 加载 - loadDataTable | 7 | - 加载 - loadDataTable |
| 8 | - 编辑 - editDataTable | 8 | - 编辑 - editDataTable |
| 9 | - 持久化 - flushDataTable | 9 | - 持久化 - flushDataTable |
| @@ -11,7 +11,6 @@ | @@ -11,7 +11,6 @@ | ||
| 11 | - 删除 - delete | 11 | - 删除 - delete |
| 12 | - 操作日志 - log | 12 | - 操作日志 - log |
| 13 | 13 | ||
| 14 | - | ||
| 15 | - editDataTable params 列表 | 14 | - editDataTable params 列表 |
| 16 | 15 | ||
| 17 | ### 加载表格数据 loadDataTable - 查询 | 16 | ### 加载表格数据 loadDataTable - 查询 |
| @@ -25,9 +24,9 @@ | @@ -25,9 +24,9 @@ | ||
| 25 | "index": 1, | 24 | "index": 1, |
| 26 | "name": "产品名称" | 25 | "name": "产品名称" |
| 27 | }, | 26 | }, |
| 28 | - "in": ["a","b"], | ||
| 29 | - "ex": ["c","d"], | ||
| 30 | - "sort": ["a","asc"] | 27 | + "in": ["a", "b"], |
| 28 | + "ex": ["c", "d"], | ||
| 29 | + "sort": ["a", "asc"] | ||
| 31 | } | 30 | } |
| 32 | ] | 31 | ] |
| 33 | } | 32 | } |
| @@ -42,17 +41,19 @@ | @@ -42,17 +41,19 @@ | ||
| 42 | "name": "产品名称" | 41 | "name": "产品名称" |
| 43 | }, | 42 | }, |
| 44 | "operation": { | 43 | "operation": { |
| 45 | - "desc": ["拆分","按字符数"], | 44 | + "desc": ["拆分", "按字符数"], |
| 46 | "code": "split_by_char_number" | 45 | "code": "split_by_char_number" |
| 47 | }, | 46 | }, |
| 48 | "params": [] | 47 | "params": [] |
| 49 | } | 48 | } |
| 50 | ``` | 49 | ``` |
| 50 | + | ||
| 51 | 精简 | 51 | 精简 |
| 52 | + | ||
| 52 | ```json | 53 | ```json |
| 53 | { | 54 | { |
| 54 | "field": "产品名称", | 55 | "field": "产品名称", |
| 55 | - "desc": ["拆分","按字符数"], | 56 | + "desc": ["拆分", "按字符数"], |
| 56 | "operationCode": "split_by_char_number", | 57 | "operationCode": "split_by_char_number", |
| 57 | "params": [] | 58 | "params": [] |
| 58 | } | 59 | } |
| @@ -60,7 +61,6 @@ | @@ -60,7 +61,6 @@ | ||
| 60 | 61 | ||
| 61 | `params 列表` | 62 | `params 列表` |
| 62 | 63 | ||
| 63 | - | ||
| 64 | ### 数据展示 | 64 | ### 数据展示 |
| 65 | 65 | ||
| 66 | ```json | 66 | ```json |
| @@ -80,22 +80,10 @@ | @@ -80,22 +80,10 @@ | ||
| 80 | } | 80 | } |
| 81 | ], | 81 | ], |
| 82 | "dataRows": [ | 82 | "dataRows": [ |
| 83 | - [ | ||
| 84 | - "素面", | ||
| 85 | - 200 | ||
| 86 | - ], | ||
| 87 | - [ | ||
| 88 | - "冻豆腐", | ||
| 89 | - 400 | ||
| 90 | - ], | ||
| 91 | - [ | ||
| 92 | - "冻豆腐1", | ||
| 93 | - 300 | ||
| 94 | - ], | ||
| 95 | - [ | ||
| 96 | - "冻豆2", | ||
| 97 | - "A" | ||
| 98 | - ] | 83 | + ["素面", 200], |
| 84 | + ["冻豆腐", 400], | ||
| 85 | + ["冻豆腐1", 300], | ||
| 86 | + ["冻豆2", "A"] | ||
| 99 | ], | 87 | ], |
| 100 | "total": 100, | 88 | "total": 100, |
| 101 | "pageNumber": 1, | 89 | "pageNumber": 1, |
| @@ -111,7 +99,6 @@ | @@ -111,7 +99,6 @@ | ||
| 111 | } | 99 | } |
| 112 | ``` | 100 | ``` |
| 113 | 101 | ||
| 114 | - | ||
| 115 | ## 表关联关系 | 102 | ## 表关联关系 |
| 116 | 103 | ||
| 117 | - [x] 可追加数据的表列表 /tables/search-appended-list | 104 | - [x] 可追加数据的表列表 /tables/search-appended-list |
| @@ -135,6 +122,7 @@ | @@ -135,6 +122,7 @@ | ||
| 135 | - [x] 校验步骤日志 /log/verified-step-Log | 122 | - [x] 校验步骤日志 /log/verified-step-Log |
| 136 | 123 | ||
| 137 | ## 数据预览 | 124 | ## 数据预览 |
| 125 | + | ||
| 138 | - [x] 表数据预览(格式) /table/preview | 126 | - [x] 表数据预览(格式) /table/preview |
| 139 | - [x] 表数据自定义查询 /table/preview where conditions 升序、降序 包含、不包含 | 127 | - [x] 表数据自定义查询 /table/preview where conditions 升序、降序 包含、不包含 |
| 140 | - [x] 表数据字段可选值搜索 /table/field-optional 文本匹配 | 128 | - [x] 表数据字段可选值搜索 /table/field-optional 文本匹配 |
| @@ -147,27 +135,424 @@ | @@ -147,27 +135,424 @@ | ||
| 147 | 135 | ||
| 148 | ## 底层字库接口 | 136 | ## 底层字库接口 |
| 149 | 137 | ||
| 150 | -```json | ||
| 151 | -{ | ||
| 152 | - "file": {}, | ||
| 153 | - "fields": [], | ||
| 154 | - "action":"filed_rename", | ||
| 155 | - "params": ["产品名2"] | ||
| 156 | -} | ||
| 157 | -``` | ||
| 158 | -- [ ] 数据预览 1 | ||
| 159 | -- [ ] 表格编辑 1 | ||
| 160 | -- [ ] 保存校验文件 (文件地址) 1 | ||
| 161 | -- [ ] 生成主表 1 | ||
| 162 | -- [ ] 表复制 (副表) | ||
| 163 | -- [ ] 追加数据 (主表、副表) | 138 | +- [x] 数据预览 1 |
| 139 | +- [x] 表格编辑 1 | ||
| 140 | +- [x] 保存校验文件 (文件地址) 1 | ||
| 141 | +- [x] 生成主表 1 | ||
| 142 | +- [x] 表复制 (副表)1 | ||
| 143 | +- [x] 追加数据 (主表、副表) | ||
| 164 | - [ ] 表删除 (主表、副表)~~、分表~~ | 144 | - [ ] 表删除 (主表、副表)~~、分表~~ |
| 165 | -- [x] ~~表拆分~~ | ||
| 166 | -- [x] ~~更新表结构(分表)~~ | ||
| 167 | -- [ ] 编辑、添加、删除表数据(副表) 1 | 145 | +- [x] 表拆分 1 |
| 146 | +- [x] 更新表结构(分表)1 | ||
| 147 | +- [x] 编辑、添加、删除表数据(副表) 1 | ||
| 168 | - [ ] 取消校验 | 148 | - [ ] 取消校验 |
| 169 | 149 | ||
| 170 | ## 定时作业 | 150 | ## 定时作业 |
| 171 | 151 | ||
| 172 | - [x] 隔天清理校验中的文件 | 152 | - [x] 隔天清理校验中的文件 |
| 173 | -- [x] 隔天清理public临时文件 | ||
| 153 | +- [x] 隔天清理 public 临时文件 | ||
| 154 | + | ||
| 155 | +## 表数据导出 | ||
| 156 | + | ||
| 157 | +- [ ] 加锁,只允许当前用户同时只能发起一次导出命令 ,3min 过期 | ||
| 158 | +- [ ] 单次拉取数量 MR | ||
| 159 | + - [ ] 100W .. | ||
| 160 | + - [ ] 50W 120s 读取数据库:30s 保存文件:10s 下载:30M/500K=60S;RAR 压缩 24M/500k=50S | ||
| 161 | + - [ ] 20W .. | ||
| 162 | + - [ ] 10W .. | ||
| 163 | +- [ ] 保存单个文件、压缩 | 保存多个文件、压缩 | ||
| 164 | + | ||
| 165 | +## 表达式解析 | ||
| 166 | + | ||
| 167 | +### 表达式类型说明 | ||
| 168 | +- ValueExprAST: 值表达式(数值,字符串) e.g. 1 、 2011-1-1 、字符串 | ||
| 169 | +```json | ||
| 170 | +{ | ||
| 171 | + "exprType":"ValueExprAST", | ||
| 172 | + "val":"", | ||
| 173 | + "str":"业绩2" | ||
| 174 | +} | ||
| 175 | +``` | ||
| 176 | +- FieldExprAST: 字段表达式(处理的字段) e.g. 生产明细.业绩 | ||
| 177 | +```json | ||
| 178 | +{ | ||
| 179 | + "exprType":"FieldExprAST", | ||
| 180 | + "str":"业绩1", | ||
| 181 | + "field":{ | ||
| 182 | + "tableId":1, | ||
| 183 | + "tableName":"测试ABC", | ||
| 184 | + "tableSqlName":"table_abc_test", | ||
| 185 | + "fieldName":"业绩", | ||
| 186 | + "fieldSqlName":"ye_ji_1", | ||
| 187 | + "fieldSqlType":"Float" | ||
| 188 | + } | ||
| 189 | +} | ||
| 190 | +``` | ||
| 191 | +- BinaryExprAST: 二元表达式 e.g. 1 + 2 、 100 * 生产明细.业绩 | ||
| 192 | +```json | ||
| 193 | +{ | ||
| 194 | + "exprType":"BinaryExprAST", | ||
| 195 | + "op":"/", | ||
| 196 | + "lhs":{}, | ||
| 197 | + "rhs":{} | ||
| 198 | +} | ||
| 199 | +``` | ||
| 200 | + | ||
| 201 | +- FunCallerExprAST:函数表达式 e.g. sum(arg1,arg2,arg3) | ||
| 202 | +```json | ||
| 203 | +{ | ||
| 204 | + "arrayFlag": false, | ||
| 205 | + "exprType": "FunCallerExprAST", | ||
| 206 | + "name": "sum", | ||
| 207 | + "args": [] | ||
| 208 | +} | ||
| 209 | +``` | ||
| 210 | + | ||
| 211 | +### 用例 | ||
| 212 | +- 输入表达式 `SUM(1/COUNTIFS(【业绩】,【业绩】))` | ||
| 213 | +```json | ||
| 214 | +{ | ||
| 215 | + "arrayFlag":false, | ||
| 216 | + "exprType":"FunCallerExprAST", | ||
| 217 | + "name":"sum", | ||
| 218 | + "args":[ | ||
| 219 | + { | ||
| 220 | + "exprType":"BinaryExprAST", | ||
| 221 | + "op":"/", | ||
| 222 | + "lhs":{ | ||
| 223 | + "exprType":"ValueExprAST", | ||
| 224 | + "val":"", | ||
| 225 | + "str":"1" | ||
| 226 | + }, | ||
| 227 | + "rhs":{ | ||
| 228 | + "arrayFlag":false, | ||
| 229 | + "exprType":"FunCallerExprAST", | ||
| 230 | + "name":"countifs", | ||
| 231 | + "args":[ | ||
| 232 | + { | ||
| 233 | + "exprType":"FieldExprAST", | ||
| 234 | + "str":"业绩1", | ||
| 235 | + "field":{ | ||
| 236 | + "tableId":1, | ||
| 237 | + "tableName":"测试ABC", | ||
| 238 | + "tableSqlName":"table_abc_test", | ||
| 239 | + "fieldName":"业绩", | ||
| 240 | + "fieldSqlName":"ye_ji_1", | ||
| 241 | + "fieldSqlType":"Float" | ||
| 242 | + } | ||
| 243 | + }, | ||
| 244 | + { | ||
| 245 | + "exprType":"ValueExprAST", | ||
| 246 | + "val":"", | ||
| 247 | + "str":"业绩2" | ||
| 248 | + } | ||
| 249 | + ] | ||
| 250 | + } | ||
| 251 | + } | ||
| 252 | + ] | ||
| 253 | +} | ||
| 254 | +``` | ||
| 255 | + | ||
| 256 | +## 讨论事项 | ||
| 257 | + | ||
| 258 | +- [ ] 校验动作,参数模型讨论 | ||
| 259 | +- [ ] 校验日志错误(标红) | ||
| 260 | +- [ ] 校验完毕应答实体,类型修改即使错误,也要返回修改完毕的表 | ||
| 261 | + | ||
| 262 | +## 参数说明 | ||
| 263 | + | ||
| 264 | +### 通用格式 | ||
| 265 | + | ||
| 266 | +```json | ||
| 267 | +{ | ||
| 268 | + "objectId": 1, | ||
| 269 | + "processFields": [], | ||
| 270 | + "action": "xx", | ||
| 271 | + "params": {} | ||
| 272 | +} | ||
| 273 | +``` | ||
| 274 | + | ||
| 275 | +processFields:操作字段 | ||
| 276 | + | ||
| 277 | +### 常规 | ||
| 278 | + | ||
| 279 | +1. 删除列 | ||
| 280 | + | ||
| 281 | +```json | ||
| 282 | +{ | ||
| 283 | + "action": "remove-column", | ||
| 284 | + "params": {} | ||
| 285 | +} | ||
| 286 | +``` | ||
| 287 | + | ||
| 288 | +2. 复制列 | ||
| 289 | + | ||
| 290 | +```json | ||
| 291 | +{ | ||
| 292 | + "action": "copy-column", | ||
| 293 | + "params": {} | ||
| 294 | +} | ||
| 295 | +``` | ||
| 296 | + | ||
| 297 | +3. 重命名 | ||
| 298 | + | ||
| 299 | +```json | ||
| 300 | +{ | ||
| 301 | + "action": "rename-column", | ||
| 302 | + "params": { | ||
| 303 | + "newColumnName": "新的列名称" | ||
| 304 | + } | ||
| 305 | +} | ||
| 306 | +``` | ||
| 307 | + | ||
| 308 | +4. 替换值 | ||
| 309 | + | ||
| 310 | +```json | ||
| 311 | +{ | ||
| 312 | + "action": "replace-column", | ||
| 313 | + "params": { | ||
| 314 | + "replaceMethod": "replace", | ||
| 315 | + "searchValue": "搜索值", | ||
| 316 | + "replaceValue": "替换值" | ||
| 317 | + } | ||
| 318 | +} | ||
| 319 | +``` | ||
| 320 | + | ||
| 321 | +参数说明 | ||
| 322 | + | ||
| 323 | +``` | ||
| 324 | +replaceMethod: 替换方法(1.replace:替换值 2.add-prefix:添加前缀 3.add-postfix:添加后缀 4.remove-prefix:去除前缀 5.remove-postfix:去除后缀 6.remove-chars:去除固定字符 7.clean:清除) | ||
| 325 | +searchValue: 搜索值-replace,remove-prefix,remove-postfix,remove-chars参数 | ||
| 326 | +replaceValue: 替换值-replace,add-prefix,add-postfix参数 | ||
| 327 | +``` | ||
| 328 | + | ||
| 329 | +### 格式 formatMethod | ||
| 330 | + | ||
| 331 | +1. 大写 | ||
| 332 | + | ||
| 333 | +```json | ||
| 334 | +{ | ||
| 335 | + "action": "format-column", | ||
| 336 | + "params": { | ||
| 337 | + "formatMethod": "upper" | ||
| 338 | + } | ||
| 339 | +} | ||
| 340 | +``` | ||
| 341 | + | ||
| 342 | +参数说明 | ||
| 343 | + | ||
| 344 | +``` | ||
| 345 | +formatMethod: 格式化方法(1.upper:大写2.lower:小写3.capitalize:首字母大写4.strip:修整) | ||
| 346 | +``` | ||
| 347 | + | ||
| 348 | +2. 小写 | ||
| 349 | + | ||
| 350 | +```json | ||
| 351 | +{ | ||
| 352 | + "action": "format-column", | ||
| 353 | + "params": { | ||
| 354 | + "formatMethod": "lower" | ||
| 355 | + } | ||
| 356 | +} | ||
| 357 | +``` | ||
| 358 | + | ||
| 359 | +3. 首字母大写 | ||
| 360 | + | ||
| 361 | +```json | ||
| 362 | +{ | ||
| 363 | + "action": "format-column", | ||
| 364 | + "params": { | ||
| 365 | + "formatMethod": "capitalize" | ||
| 366 | + } | ||
| 367 | +} | ||
| 368 | +``` | ||
| 369 | + | ||
| 370 | +4. 清除 | ||
| 371 | + | ||
| 372 | +```json | ||
| 373 | +{ | ||
| 374 | + "action": "replace-column", | ||
| 375 | + "params": { | ||
| 376 | + "replaceMethod": "clean" | ||
| 377 | + } | ||
| 378 | +} | ||
| 379 | +``` | ||
| 380 | + | ||
| 381 | +5. 修整 | ||
| 382 | + | ||
| 383 | +```json | ||
| 384 | +{ | ||
| 385 | + "action": "format-column", | ||
| 386 | + "params": { | ||
| 387 | + "formatMethod": "strip" | ||
| 388 | + } | ||
| 389 | +} | ||
| 390 | +``` | ||
| 391 | + | ||
| 392 | +6. 添加前缀 | ||
| 393 | + | ||
| 394 | +```json | ||
| 395 | +{ | ||
| 396 | + "action": "replace-column", | ||
| 397 | + "params": { | ||
| 398 | + "replaceMethod": "add-prefix", | ||
| 399 | + "replaceValue": "前缀值" | ||
| 400 | + } | ||
| 401 | +} | ||
| 402 | +``` | ||
| 403 | + | ||
| 404 | +7. 添加后缀 | ||
| 405 | + | ||
| 406 | +```json | ||
| 407 | +{ | ||
| 408 | + "action": "replace-column", | ||
| 409 | + "params": { | ||
| 410 | + "replaceMethod": "add-postfix", | ||
| 411 | + "replaceValue": "后缀值" | ||
| 412 | + } | ||
| 413 | +} | ||
| 414 | +``` | ||
| 415 | + | ||
| 416 | +8. 去除前缀 | ||
| 417 | + | ||
| 418 | +```json | ||
| 419 | +{ | ||
| 420 | + "action": "replace-column", | ||
| 421 | + "params": { | ||
| 422 | + "replaceMethod": "remove-prefix", | ||
| 423 | + "searchValue": "前缀值" | ||
| 424 | + } | ||
| 425 | +} | ||
| 426 | +``` | ||
| 427 | + | ||
| 428 | +9. 去除后最 | ||
| 429 | + | ||
| 430 | +```json | ||
| 431 | +{ | ||
| 432 | + "action": "replace-column", | ||
| 433 | + "params": { | ||
| 434 | + "replaceMethod": "remove-postfix", | ||
| 435 | + "searchValue": "后缀值" | ||
| 436 | + } | ||
| 437 | +} | ||
| 438 | +``` | ||
| 439 | + | ||
| 440 | +10. 去除固定字符 | ||
| 441 | + | ||
| 442 | +```json | ||
| 443 | +{ | ||
| 444 | + "action": "replace-column", | ||
| 445 | + "params": { | ||
| 446 | + "replaceMethod": "remove-chars", | ||
| 447 | + "searchValue": "字符" | ||
| 448 | + } | ||
| 449 | +} | ||
| 450 | +``` | ||
| 451 | + | ||
| 452 | +### 拆分 split-column | ||
| 453 | + | ||
| 454 | +1. 按分隔符 | ||
| 455 | + | ||
| 456 | +```json | ||
| 457 | +{ | ||
| 458 | + "action": "split-column", | ||
| 459 | + "params": { | ||
| 460 | + "splitMethod": "separator", | ||
| 461 | + "separator": "|", | ||
| 462 | + "splitDirection": "left", | ||
| 463 | + "splitCount": "1" | ||
| 464 | + } | ||
| 465 | +} | ||
| 466 | +``` | ||
| 467 | + | ||
| 468 | +参数说明 | ||
| 469 | + | ||
| 470 | +``` | ||
| 471 | +separator: 分割符号 ‘|’ | ||
| 472 | +splitDirection: 拆分方向(1.left:从左边 2.right:从右边) | ||
| 473 | +splitCount: 拆分次数 | ||
| 474 | +``` | ||
| 475 | + | ||
| 476 | +2. 按字符数 | ||
| 477 | + | ||
| 478 | +```json | ||
| 479 | +{ | ||
| 480 | + "action": "split-column", | ||
| 481 | + "params": { | ||
| 482 | + "splitMethod": "char-length", | ||
| 483 | + "splitDirection": "left", | ||
| 484 | + "charLength": "10", | ||
| 485 | + "splitCount": "1" | ||
| 486 | + } | ||
| 487 | +} | ||
| 488 | +``` | ||
| 489 | + | ||
| 490 | +参数说明 | ||
| 491 | + | ||
| 492 | +``` | ||
| 493 | +charLength: 字符长度-char-length专属参数 | ||
| 494 | +splitDirection: 拆分方向(1.left:从左边 2.right:从右边) | ||
| 495 | +splitCount: 拆分次数 (拆分策略是重复时:值0或者非1整数) | ||
| 496 | +``` | ||
| 497 | + | ||
| 498 | +### 提取 extract-column | ||
| 499 | + | ||
| 500 | +1. 按日期 | ||
| 501 | + | ||
| 502 | +```json | ||
| 503 | +{ | ||
| 504 | + "action": "extract-column", | ||
| 505 | + "params": { | ||
| 506 | + "extractMethod": "by-date" | ||
| 507 | + } | ||
| 508 | +} | ||
| 509 | +``` | ||
| 510 | + | ||
| 511 | +参数说明 | ||
| 512 | + | ||
| 513 | +``` | ||
| 514 | +extractMethod: 提取方法(1.by-date:按日期 2.by-number:按数值) | ||
| 515 | +``` | ||
| 516 | + | ||
| 517 | +2. 按数值 action | ||
| 518 | + | ||
| 519 | +```json | ||
| 520 | +{ | ||
| 521 | + "action": "extract-column", | ||
| 522 | + "params": { | ||
| 523 | + "extractMethod": "by-number" | ||
| 524 | + } | ||
| 525 | +} | ||
| 526 | +``` | ||
| 527 | + | ||
| 528 | +### 修改字段类型 | ||
| 529 | + | ||
| 530 | +```json | ||
| 531 | +{ | ||
| 532 | + "action": "convert-column-type", | ||
| 533 | + "params": { | ||
| 534 | + "convertType": "STRING" | ||
| 535 | + } | ||
| 536 | +} | ||
| 537 | +``` | ||
| 538 | + | ||
| 539 | +参数说明 | ||
| 540 | + | ||
| 541 | +``` | ||
| 542 | +convertType:转换类型 STRING 数值: INT 小数: FLOAT 日期: DATE 时间: DATETIME | ||
| 543 | +``` | ||
| 544 | + | ||
| 545 | +## 优化点 | ||
| 546 | +- [] 0.测试服务、数据库的上限(QPS,TPS)查询瓶颈的接口 | ||
| 547 | + | ||
| 548 | +- [] 1.模型详情缓存(tables、query_set) | ||
| 549 | + | ||
| 550 | +- [] 2.列表搜索缓存 (tables、query_set),减轻数据库压力 | ||
| 551 | + | ||
| 552 | +``` | ||
| 553 | +更新、删除、重命名 | ||
| 554 | +get list:queryset:cxxx:* | ||
| 555 | +删除所有匹配的缓存 | ||
| 556 | + | ||
| 557 | +消息队列更新事件、确保缓存一定移除成功、缓存时间控制 | ||
| 558 | +``` |
| 1 | -POSTGRESQL_DB_NAME = allied_creation_dev | 1 | +POSTGRESQL_DB_NAME = allied_creation_test |
| 2 | POSTGRESQL_HOST = 114.55.200.59 | 2 | POSTGRESQL_HOST = 114.55.200.59 |
| 3 | POSTGRESQL_PORT = 31543 | 3 | POSTGRESQL_PORT = 31543 |
| 4 | POSTGRESQL_USER = postgres | 4 | POSTGRESQL_USER = postgres |
| @@ -9,3 +9,19 @@ HTTP_PORT = 8081 | @@ -9,3 +9,19 @@ HTTP_PORT = 8081 | ||
| 9 | ENABLE_KAFKA_LOG11 = true | 9 | ENABLE_KAFKA_LOG11 = true |
| 10 | HTTPS_PORT = 8143 | 10 | HTTPS_PORT = 8143 |
| 11 | ALLIED_CREATION_USER_HOST = http://allied-creation-user-dev.fjmaimaimai.com | 11 | ALLIED_CREATION_USER_HOST = http://allied-creation-user-dev.fjmaimaimai.com |
| 12 | +# AUTH_SERVER_HOST = http://127.0.0.1:8081 | ||
| 13 | +BYTE_CORE_HOST = http://47.97.5.102:8303 | ||
| 14 | +METADATA_BASTION_HOST = http://106.75.231.90:9999 | ||
| 15 | + | ||
| 16 | +KAFKA_HOST =47.97.5.102:9092 | ||
| 17 | +#192.168.100.35:9092 | ||
| 18 | + | ||
| 19 | +STARROCKS_DB_NAME = character_library | ||
| 20 | +STARROCKS_USER = root | ||
| 21 | +STARROCKS_PASSWORD = eagle1010 | ||
| 22 | +STARROCKS_HOST = 220.250.41.79 | ||
| 23 | +STARROCKS_PORT = 9030 | ||
| 24 | + | ||
| 25 | +BLACK_LIST_USER = 0 | ||
| 26 | +BLACK_LIST_COMPANY = 1612991734952759296 | ||
| 27 | +WHITE_LIST_USERS = 22,23 |
deploy/db/db_query_script.sql
0 → 100644
| 1 | +/* | ||
| 2 | + 1. 查询依赖的查询集 | ||
| 3 | +*/ | ||
| 4 | +select * from metadata.query_sets where query_set_info->>'BindTableId' in ( | ||
| 5 | + select distinct table_id::text from ( /*element_id,table_info,table_type*/ | ||
| 6 | + select json_array_elements(to_json(table_info->'dependencyTables'))::text::int element_id,table_info,table_id,table_type | ||
| 7 | + from metadata.tables where table_info->'dependencyTables'::text <>'null' and table_type in ('SubProcess','CalculateTable') | ||
| 8 | + ) a where a.element_id in (select table_id from metadata.tables where table_type in ('MainTable','SubTable','SideTable')) | ||
| 9 | + order by table_id asc | ||
| 10 | +) and context->>'operatorId' = '22' |
| @@ -19,3 +19,6 @@ CREATE INDEX IF NOT EXISTS idx_logs_company_id_created_at ON metadata.logs USING | @@ -19,3 +19,6 @@ CREATE INDEX IF NOT EXISTS idx_logs_company_id_created_at ON metadata.logs USING | ||
| 19 | 19 | ||
| 20 | /*mapping_rules*/ | 20 | /*mapping_rules*/ |
| 21 | CREATE INDEX IF NOT EXISTS idx_mapping_rules_company_id_table_id_file_id ON metadata.mapping_rules USING btree((context->>'companyId'),table_id,file_id); | 21 | CREATE INDEX IF NOT EXISTS idx_mapping_rules_company_id_table_id_file_id ON metadata.mapping_rules USING btree((context->>'companyId'),table_id,file_id); |
| 22 | + | ||
| 23 | +/*query_sets*/ | ||
| 24 | +CREATE INDEX IF NOT EXISTS idx_query_sets_company_id_type_deleted_at ON metadata.query_sets USING btree((context->>'companyId'),type,deleted_at); |
deploy/db/db_script_v1.4.0.sql
0 → 100644
| 1 | +ALTER TABLE files ADD file_from TEXT; | ||
| 2 | +ALTER TABLE files ADD app_key TEXT; | ||
| 3 | +Update files set file_from = 'ByteBankWebClient'; | ||
| 4 | + | ||
| 5 | +CREATE INDEX IF NOT EXISTS idx_files_app_key ON metadata.files USING btree(app_key); | ||
| 6 | + | ||
| 7 | + | ||
| 8 | +alter table metadata.tables add column apply_at timestamptz; | ||
| 9 | +update metadata.tables set apply_at = null where table_type in ('MainTable','SubTable','SideTable') and apply_at is null; |
| @@ -102,9 +102,9 @@ spec: | @@ -102,9 +102,9 @@ spec: | ||
| 102 | - name: METADATA_BASTION_HOST | 102 | - name: METADATA_BASTION_HOST |
| 103 | value: "http://character-library-metadata-bastion-dev.fjmaimaimai.com" | 103 | value: "http://character-library-metadata-bastion-dev.fjmaimaimai.com" |
| 104 | - name: BYTE_CORE_HOST | 104 | - name: BYTE_CORE_HOST |
| 105 | - value: "http://192.168.100.34:8303" | 105 | + value: "http://47.97.5.102:8303" |
| 106 | - name: STARROCKS_HOST | 106 | - name: STARROCKS_HOST |
| 107 | - value: "118.178.239.45" | 107 | + value: "220.250.41.79" |
| 108 | - name: STARROCKS_PORT | 108 | - name: STARROCKS_PORT |
| 109 | value: "9030" | 109 | value: "9030" |
| 110 | - name: STARROCKS_DB_NAME | 110 | - name: STARROCKS_DB_NAME |
deploy/k8s/test/.gitkeep
0 → 100644
| 1 | +apiVersion: v1 | ||
| 2 | +kind: Service | ||
| 3 | +metadata: | ||
| 4 | + name: character-library-metadata-bastion | ||
| 5 | + namespace: mmm-suplus-test | ||
| 6 | + labels: | ||
| 7 | + k8s-app: character-library-metadata-bastion | ||
| 8 | +spec: | ||
| 9 | + ports: | ||
| 10 | + - name: "http" | ||
| 11 | + port: 80 | ||
| 12 | + targetPort: 8082 | ||
| 13 | + selector: | ||
| 14 | + k8s-app: character-library-metadata-bastion | ||
| 15 | +--- | ||
| 16 | +apiVersion: extensions/v1beta1 | ||
| 17 | +kind: Deployment | ||
| 18 | +metadata: | ||
| 19 | + name: character-library-metadata-bastion | ||
| 20 | + namespace: mmm-suplus-test | ||
| 21 | + labels: | ||
| 22 | + k8s-app: character-library-metadata-bastion | ||
| 23 | +spec: | ||
| 24 | + replicas: 1 | ||
| 25 | + template: | ||
| 26 | + metadata: | ||
| 27 | + labels: | ||
| 28 | + k8s-app: character-library-metadata-bastion | ||
| 29 | + spec: | ||
| 30 | + affinity: | ||
| 31 | + nodeAffinity: | ||
| 32 | + preferredDuringSchedulingIgnoredDuringExecution: | ||
| 33 | + - preference: {} | ||
| 34 | + weight: 100 | ||
| 35 | + requiredDuringSchedulingIgnoredDuringExecution: | ||
| 36 | + nodeSelectorTerms: | ||
| 37 | + - matchExpressions: | ||
| 38 | + - key: kubernetes.io/hostname | ||
| 39 | + operator: In | ||
| 40 | + values: | ||
| 41 | + - cn-hangzhou.i-bp1djh1xn7taumbue1ze | ||
| 42 | + | ||
| 43 | + containers: | ||
| 44 | + - name: character-library-metadata-bastion | ||
| 45 | + image: 192.168.0.243:5000/mmm/character-library-metadata-bastion:dev | ||
| 46 | + imagePullPolicy: Always | ||
| 47 | + ports: | ||
| 48 | + - containerPort: 8082 | ||
| 49 | + volumeMounts: | ||
| 50 | + - mountPath: /opt/logs | ||
| 51 | + name: accesslogs | ||
| 52 | + env: | ||
| 53 | + - name: POSTGRESQL_DB_NAME | ||
| 54 | + valueFrom: | ||
| 55 | + configMapKeyRef: | ||
| 56 | + name: suplus-config | ||
| 57 | + key: postgresqlalliedcreation.dbname | ||
| 58 | + - name: POSTGRESQL_USER | ||
| 59 | + valueFrom: | ||
| 60 | + configMapKeyRef: | ||
| 61 | + name: suplus-config | ||
| 62 | + key: postgresql.user | ||
| 63 | + - name: POSTGRESQL_PASSWORD | ||
| 64 | + valueFrom: | ||
| 65 | + configMapKeyRef: | ||
| 66 | + name: suplus-config | ||
| 67 | + key: postgresql.password | ||
| 68 | + - name: POSTGRESQL_HOST | ||
| 69 | + valueFrom: | ||
| 70 | + configMapKeyRef: | ||
| 71 | + name: suplus-config | ||
| 72 | + key: postgresql.host | ||
| 73 | + - name: POSTGRESQL_PORT | ||
| 74 | + valueFrom: | ||
| 75 | + configMapKeyRef: | ||
| 76 | + name: suplus-config | ||
| 77 | + key: postgresql.port | ||
| 78 | + - name: REDIS_HOST | ||
| 79 | + valueFrom: | ||
| 80 | + configMapKeyRef: | ||
| 81 | + name: suplus-config | ||
| 82 | + key: redis.ip | ||
| 83 | + - name: REDIS_PORT | ||
| 84 | + valueFrom: | ||
| 85 | + configMapKeyRef: | ||
| 86 | + name: suplus-config | ||
| 87 | + key: redis.port | ||
| 88 | + - name: REDIS_AUTH | ||
| 89 | + value: "" | ||
| 90 | + - name: LOG_LEVEL | ||
| 91 | + value: "debug" | ||
| 92 | + - name: ERROR_BASE_CODE | ||
| 93 | + value: "1" | ||
| 94 | + - name: ERROR_BASE_CODE_MULTIPLE | ||
| 95 | + value: "2000" | ||
| 96 | + - name: KAFKA_HOST | ||
| 97 | + value: "47.97.5.102:9092" | ||
| 98 | + - name: HTTP_PORT | ||
| 99 | + value: "8082" | ||
| 100 | + - name: SERVICE_ENV | ||
| 101 | + value: "test" | ||
| 102 | + - name: METADATA_BASTION_HOST | ||
| 103 | + value: "https://character-library-metadata-bastion-test.fjmaimaimai.com" | ||
| 104 | + - name: BYTE_CORE_HOST | ||
| 105 | + value: "http://47.97.5.102:8303" | ||
| 106 | + - name: STARROCKS_HOST | ||
| 107 | + value: "220.250.41.79" | ||
| 108 | + - name: STARROCKS_PORT | ||
| 109 | + value: "9030" | ||
| 110 | + - name: STARROCKS_DB_NAME | ||
| 111 | + value: "character_library" | ||
| 112 | + - name: STARROCKS_USER | ||
| 113 | + value: "root" | ||
| 114 | + - name: STARROCKS_PASSWORD | ||
| 115 | + value: "eagle1010" | ||
| 116 | + - name: BLACK_LIST_USER | ||
| 117 | + value: "1" | ||
| 118 | + - name: BLACK_LIST_COMPANY | ||
| 119 | + value: "1646025721363042304" | ||
| 120 | + - name: WHITE_LIST_USERS | ||
| 121 | + value: "0" | ||
| 122 | + volumes: | ||
| 123 | + - name: accesslogs | ||
| 124 | + emptyDir: {} |
deploy/k8s/test/install.sh
0 → 100644
| 1 | +#!/bin/bash | ||
| 2 | +export PATH=/root/local/bin:$PATH | ||
| 3 | +kubectl -n mmm-suplus-test get pods | grep -q character-library-metadata-bastion | ||
| 4 | +if [ "$?" == "1" ];then | ||
| 5 | + kubectl create -f /tmp/test/character-library-metadata-bastion/character-library-metadata-bastion.yaml --record | ||
| 6 | + kubectl -n mmm-suplus-test get svc | grep -q character-library-metadata-bastion | ||
| 7 | + if [ "$?" == "0" ];then | ||
| 8 | + echo "character-library-metadata-bastion service install success!" | ||
| 9 | + else | ||
| 10 | + echo "character-library-metadata-bastion service install fail!" | ||
| 11 | + fi | ||
| 12 | + kubectl -n mmm-suplus-test get pods | grep -q character-library-metadata-bastion | ||
| 13 | + if [ "$?" == "0" ];then | ||
| 14 | + echo "character-library-metadata-bastion deployment install success!" | ||
| 15 | + else | ||
| 16 | + echo "character-library-metadata-bastion deployment install fail!" | ||
| 17 | + fi | ||
| 18 | +else | ||
| 19 | + kubectl delete -f /tmp/test/character-library-metadata-bastion/character-library-metadata-bastion.yaml | ||
| 20 | + kubectl -n mmm-suplus-test get svc | grep -q character-library-metadata-bastion | ||
| 21 | + while [ "$?" == "0" ] | ||
| 22 | + do | ||
| 23 | + kubectl -n mmm-suplus-test get svc | grep -q character-library-metadata-bastion | ||
| 24 | + done | ||
| 25 | + kubectl -n mmm-suplus-test get pods | grep -q character-library-metadata-bastion | ||
| 26 | + while [ "$?" == "0" ] | ||
| 27 | + do | ||
| 28 | + kubectl -n mmm-suplus-test get pods | grep -q character-library-metadata-bastion | ||
| 29 | + done | ||
| 30 | + kubectl create -f /tmp/test/character-library-metadata-bastion/character-library-metadata-bastion.yaml --record | ||
| 31 | + kubectl -n mmm-suplus-test get svc | grep -q character-library-metadata-bastion | ||
| 32 | + if [ "$?" == "0" ];then | ||
| 33 | + echo "character-library-metadata-bastion service update success!" | ||
| 34 | + else | ||
| 35 | + echo "character-library-metadata-bastion service update fail!" | ||
| 36 | + fi | ||
| 37 | + kubectl -n mmm-suplus-test get pods | grep -q character-library-metadata-bastion | ||
| 38 | + if [ "$?" == "0" ];then | ||
| 39 | + echo "character-library-metadata-bastion deployment update success!" | ||
| 40 | + else | ||
| 41 | + echo "character-library-metadata-bastion deployment update fail!" | ||
| 42 | + fi | ||
| 43 | +fi |
| 1 | +version: v1 | ||
| 2 | +kind: HttpApi | ||
| 3 | +metadata: | ||
| 4 | + service: querySet | ||
| 5 | + path: /query-sets | ||
| 6 | + endpoints: | ||
| 7 | + - method: createQuerySet | ||
| 8 | + route: | ||
| 9 | + post: / | ||
| 10 | + - method: updateQuerySet | ||
| 11 | + route: | ||
| 12 | + put: /{Id} | ||
| 13 | + - method: getQuerySet | ||
| 14 | + route: | ||
| 15 | + get: /{Id} | ||
| 16 | + - method: removeQuerySet | ||
| 17 | + route: | ||
| 18 | + delete: /{Id} | ||
| 19 | + - method: listQuerySet | ||
| 20 | + route: | ||
| 21 | + get: / | ||
| 22 | + params: | ||
| 23 | + - name: offset | ||
| 24 | + - name: limit | ||
| 25 | + - method: changeStatus | ||
| 26 | + route: | ||
| 27 | + post: /change-status | ||
| 28 | + - method: copy | ||
| 29 | + route: | ||
| 30 | + post: /copy | ||
| 31 | + - method: dependencyGraph | ||
| 32 | + route: | ||
| 33 | + post: /dependency-ggraph | ||
| 34 | + - method: move | ||
| 35 | + route: | ||
| 36 | + post: /move | ||
| 37 | + - method: rename | ||
| 38 | + route: | ||
| 39 | + post: /rename | ||
| 40 | + - method: searchQuerySet | ||
| 41 | + route: | ||
| 42 | + post: /search |
| 1 | +version: v1 | ||
| 2 | +kind: Schema | ||
| 3 | +metadata: | ||
| 4 | + name: querySet | ||
| 5 | + description: 查询集合 | ||
| 6 | + attributes: | ||
| 7 | + - ref: querySetId | ||
| 8 | + required: true | ||
| 9 | + - ref: type | ||
| 10 | + required: true | ||
| 11 | + - ref: flag | ||
| 12 | + required: true | ||
| 13 | + - ref: name | ||
| 14 | + required: true | ||
| 15 | + - ref: pinName | ||
| 16 | + required: true | ||
| 17 | + - ref: parentId | ||
| 18 | + required: true | ||
| 19 | + - ref: status | ||
| 20 | + required: true | ||
| 21 | + - ref: querySetInfo | ||
| 22 | + required: true | ||
| 23 | + - ref: queryComponents | ||
| 24 | + required: true | ||
| 25 | + - ref: sort | ||
| 26 | + required: true | ||
| 27 | + - ref: createdAt | ||
| 28 | + required: true | ||
| 29 | + - ref: updatedAt | ||
| 30 | + required: true | ||
| 31 | + - ref: deletedAt | ||
| 32 | + required: true | ||
| 33 | + - ref: context | ||
| 34 | + required: true |
| 1 | +version: v1 | ||
| 2 | +kind: Method | ||
| 3 | +metadata: | ||
| 4 | + name: copy | ||
| 5 | + type: command | ||
| 6 | + description: 移动 | ||
| 7 | + payload: | ||
| 8 | + - ref: flag | ||
| 9 | + required: true | ||
| 10 | + - ref: parentId | ||
| 11 | + required: true | ||
| 12 | + - ref: name | ||
| 13 | + required: true | ||
| 14 | + - ref: querySetId | ||
| 15 | + required: true | ||
| 16 | + result: | ||
| 17 | + - name: querySet | ||
| 18 | + type: | ||
| 19 | + schema: querySet | ||
| 20 | + required: true |
| 1 | +version: v1 | ||
| 2 | +kind: Method | ||
| 3 | +metadata: | ||
| 4 | + name: createQuerySet | ||
| 5 | + type: command | ||
| 6 | + description: 创建查询集合服务 | ||
| 7 | + payload: | ||
| 8 | + - ref: type | ||
| 9 | + required: true | ||
| 10 | + - ref: flag | ||
| 11 | + required: true | ||
| 12 | + - ref: name | ||
| 13 | + required: true | ||
| 14 | + - ref: parentId | ||
| 15 | + required: false | ||
| 16 | + result: | ||
| 17 | + - name: querySet | ||
| 18 | + type: | ||
| 19 | + schema: querySet | ||
| 20 | + required: true |
| 1 | +version: v1 | ||
| 2 | +kind: Method | ||
| 3 | +metadata: | ||
| 4 | + name: listQuerySet | ||
| 5 | + type: query | ||
| 6 | + description: 返回查询集合服务列表 | ||
| 7 | + payload: | ||
| 8 | + - ref: offset | ||
| 9 | + required: true | ||
| 10 | + - ref: limit | ||
| 11 | + required: true | ||
| 12 | + result: | ||
| 13 | + - ref: count | ||
| 14 | + required: true | ||
| 15 | + - name: querySets | ||
| 16 | + type: | ||
| 17 | + array: querySet | ||
| 18 | + required: true |
| 1 | +version: v1 | ||
| 2 | +kind: Method | ||
| 3 | +metadata: | ||
| 4 | + name: searchQuerySet | ||
| 5 | + type: query | ||
| 6 | + description: 返回查询集合服务列表 | ||
| 7 | + payload: | ||
| 8 | + - ref: offset | ||
| 9 | + required: true | ||
| 10 | + - ref: limit | ||
| 11 | + required: true | ||
| 12 | + result: | ||
| 13 | + - ref: count | ||
| 14 | + required: true | ||
| 15 | + - name: querySets | ||
| 16 | + type: | ||
| 17 | + array: querySet | ||
| 18 | + required: true |
| @@ -3,51 +3,57 @@ module gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion | @@ -3,51 +3,57 @@ module gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion | ||
| 3 | go 1.16 | 3 | go 1.16 |
| 4 | 4 | ||
| 5 | require ( | 5 | require ( |
| 6 | - github.com/Shopify/sarama v1.30.0 // indirect | ||
| 7 | - github.com/ajg/form v1.5.1 // indirect | 6 | + github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible |
| 8 | github.com/beego/beego/v2 v2.0.1 | 7 | github.com/beego/beego/v2 v2.0.1 |
| 9 | github.com/bwmarrin/snowflake v0.3.0 | 8 | github.com/bwmarrin/snowflake v0.3.0 |
| 9 | + github.com/dgrijalva/jwt-go v3.2.0+incompatible | ||
| 10 | github.com/extrame/xls v0.0.1 | 10 | github.com/extrame/xls v0.0.1 |
| 11 | - github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect | ||
| 12 | - github.com/fatih/structs v1.1.0 // indirect | ||
| 13 | github.com/gavv/httpexpect v2.0.0+incompatible | 11 | github.com/gavv/httpexpect v2.0.0+incompatible |
| 12 | + github.com/go-gota/gota v0.12.0 | ||
| 14 | github.com/go-pg/pg/v10 v10.10.6 | 13 | github.com/go-pg/pg/v10 v10.10.6 |
| 15 | github.com/go-redis/redis v6.15.9+incompatible | 14 | github.com/go-redis/redis v6.15.9+incompatible |
| 16 | - github.com/google/go-cmp v0.5.7 // indirect | ||
| 17 | - github.com/google/go-querystring v1.1.0 // indirect | 15 | + github.com/google/gofuzz v1.2.0 |
| 18 | github.com/google/uuid v1.3.0 | 16 | github.com/google/uuid v1.3.0 |
| 19 | - github.com/imkira/go-interpol v1.1.0 // indirect | 17 | + github.com/gookit/event v1.0.6 |
| 20 | github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 | 18 | github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 |
| 21 | - github.com/mattn/go-colorable v0.1.9 // indirect | ||
| 22 | - github.com/mattn/go-isatty v0.0.14 // indirect | ||
| 23 | - github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect | ||
| 24 | - github.com/moul/http2curl v1.0.0 // indirect | ||
| 25 | github.com/onsi/ginkgo v1.16.5 | 19 | github.com/onsi/ginkgo v1.16.5 |
| 26 | github.com/onsi/gomega v1.18.1 | 20 | github.com/onsi/gomega v1.18.1 |
| 27 | - github.com/prometheus/client_golang v1.12.2 // indirect | ||
| 28 | - github.com/sergi/go-diff v1.2.0 // indirect | 21 | + github.com/patrickmn/go-cache v2.1.0+incompatible |
| 29 | github.com/shopspring/decimal v1.3.1 | 22 | github.com/shopspring/decimal v1.3.1 |
| 30 | - github.com/smartystreets/goconvey v1.7.2 // indirect | ||
| 31 | github.com/stretchr/testify v1.7.1 | 23 | github.com/stretchr/testify v1.7.1 |
| 24 | + github.com/xuri/excelize/v2 v2.6.0 | ||
| 25 | + github.com/zeromicro/go-zero v1.3.4 | ||
| 26 | + golang.org/x/text v0.3.7 | ||
| 27 | + gorm.io/driver/mysql v1.3.6 | ||
| 28 | + gorm.io/driver/postgres v1.3.9 | ||
| 29 | + gorm.io/gorm v1.23.8 | ||
| 30 | +) | ||
| 31 | + | ||
| 32 | +require ( | ||
| 33 | + github.com/ajg/form v1.5.1 // indirect | ||
| 34 | + github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect | ||
| 35 | + github.com/fatih/structs v1.1.0 // indirect | ||
| 36 | + github.com/go-sql-driver/mysql v1.7.0 // indirect | ||
| 37 | + github.com/google/go-querystring v1.1.0 // indirect | ||
| 38 | + github.com/imkira/go-interpol v1.1.0 // indirect | ||
| 39 | + github.com/moul/http2curl v1.0.0 // indirect | ||
| 40 | + github.com/sergi/go-diff v1.2.0 // indirect | ||
| 41 | + github.com/sirupsen/logrus v1.9.0 // indirect | ||
| 42 | + github.com/smartystreets/goconvey v1.7.2 // indirect | ||
| 32 | github.com/valyala/fasthttp v1.38.0 // indirect | 43 | github.com/valyala/fasthttp v1.38.0 // indirect |
| 33 | github.com/xeipuuv/gojsonschema v1.2.0 // indirect | 44 | github.com/xeipuuv/gojsonschema v1.2.0 // indirect |
| 34 | - github.com/xuri/excelize/v2 v2.6.0 | 45 | + github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect |
| 35 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect | 46 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect |
| 36 | github.com/yudai/gojsondiff v1.0.0 // indirect | 47 | github.com/yudai/gojsondiff v1.0.0 // indirect |
| 37 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect | 48 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect |
| 38 | github.com/yudai/pp v2.0.1+incompatible // indirect | 49 | github.com/yudai/pp v2.0.1+incompatible // indirect |
| 39 | - go.uber.org/automaxprocs v1.5.1 // indirect | ||
| 40 | - golang.org/x/net v0.0.0-20220421235706-1d1ef9303861 // indirect | ||
| 41 | - golang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32 // indirect | ||
| 42 | - golang.org/x/text v0.3.7 | ||
| 43 | - golang.org/x/tools v0.1.5 // indirect | ||
| 44 | - google.golang.org/protobuf v1.28.0 // indirect | ||
| 45 | - gorm.io/driver/mysql v1.3.6 | ||
| 46 | - gorm.io/driver/postgres v1.3.9 | ||
| 47 | - gorm.io/gorm v1.23.8 | 50 | + github.com/zeromicro/go-queue v1.1.6 |
| 51 | + golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect | ||
| 48 | ) | 52 | ) |
| 49 | 53 | ||
| 50 | replace ( | 54 | replace ( |
| 51 | github.com/extrame/xls v0.0.1 => github.com/tiptok/xls v1.0.1 | 55 | github.com/extrame/xls v0.0.1 => github.com/tiptok/xls v1.0.1 |
| 52 | - github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 => github.com/tiptok/egglib-go v0.0.0-20220421085958-9682d0ac42c1 | 56 | + github.com/go-sql-driver/mysql v1.7.0 => github.com/StarRocks/go-mysql-driver v1.7.0 |
| 57 | + //github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 => github.com/tiptok/egglib-go v0.0.0-20220421085958-9682d0ac42c1 | ||
| 58 | + github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 => github.com/tiptok/egglib-go v1.0.2 | ||
| 53 | ) | 59 | ) |
| @@ -5,19 +5,18 @@ import ( | @@ -5,19 +5,18 @@ import ( | ||
| 5 | "github.com/beego/beego/v2/server/web" | 5 | "github.com/beego/beego/v2/server/web" |
| 6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/crontab" | 6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/crontab" |
| 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" | 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" |
| 8 | + _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" | ||
| 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg" | 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg" |
| 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" | 10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" |
| 11 | + _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" | ||
| 10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" | 12 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" |
| 11 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" | 13 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" |
| 12 | - "time" | ||
| 13 | - | ||
| 14 | - _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" | ||
| 15 | - _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" | ||
| 16 | _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" | 14 | _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" |
| 17 | _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/beego" | 15 | _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/beego" |
| 16 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/event" | ||
| 18 | ) | 17 | ) |
| 19 | 18 | ||
| 20 | -const Version = "v1.0.1" | 19 | +const Version = "v1.4.0" |
| 21 | 20 | ||
| 22 | func main() { | 21 | func main() { |
| 23 | defer func() { | 22 | defer func() { |
| @@ -28,6 +27,7 @@ func main() { | @@ -28,6 +27,7 @@ func main() { | ||
| 28 | 27 | ||
| 29 | log.InitLogHook(constant.ENABLE_KAFKA_LOG, true) | 28 | log.InitLogHook(constant.ENABLE_KAFKA_LOG, true) |
| 30 | redis.InitRedis() | 29 | redis.InitRedis() |
| 30 | + redis.InitZeroCoreRedis() | ||
| 31 | pg.Init() | 31 | pg.Init() |
| 32 | if err := starrocks.Init(); err != nil { | 32 | if err := starrocks.Init(); err != nil { |
| 33 | log.Logger.Error(err.Error()) | 33 | log.Logger.Error(err.Error()) |
| @@ -35,8 +35,7 @@ func main() { | @@ -35,8 +35,7 @@ func main() { | ||
| 35 | cron := crontab.NewCrontabService(nil) | 35 | cron := crontab.NewCrontabService(nil) |
| 36 | cron.StartCrontabTask() | 36 | cron.StartCrontabTask() |
| 37 | defer cron.StopCrontabTask() | 37 | defer cron.StopCrontabTask() |
| 38 | - | ||
| 39 | - time.Sleep(time.Second) | 38 | + event.Start() |
| 40 | log.Logger.Info("Service:" + constant.SERVICE_NAME) | 39 | log.Logger.Info("Service:" + constant.SERVICE_NAME) |
| 41 | log.Logger.Info("Version:" + Version) | 40 | log.Logger.Info("Version:" + Version) |
| 42 | log.Logger.Info("server start!") | 41 | log.Logger.Info("server start!") |
| @@ -4,9 +4,12 @@ import ( | @@ -4,9 +4,12 @@ import ( | ||
| 4 | "context" | 4 | "context" |
| 5 | "fmt" | 5 | "fmt" |
| 6 | "github.com/beego/beego/v2/task" | 6 | "github.com/beego/beego/v2/task" |
| 7 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 7 | "github.com/linmadan/egglib-go/utils/xtime" | 8 | "github.com/linmadan/egglib-go/utils/xtime" |
| 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" |
| 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
| 11 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/dao" | ||
| 12 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" | ||
| 10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" | 13 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" |
| 11 | "io/fs" | 14 | "io/fs" |
| 12 | "os" | 15 | "os" |
| @@ -28,6 +31,9 @@ func (crontabService *CrontabService) initTask() { | @@ -28,6 +31,9 @@ func (crontabService *CrontabService) initTask() { | ||
| 28 | 31 | ||
| 29 | autoRemovePublicDownloadFile := task.NewTask("定时清理缓存文件", "0 20 */1 * * *", AutoRemovePublicDownloadFile) | 32 | autoRemovePublicDownloadFile := task.NewTask("定时清理缓存文件", "0 20 */1 * * *", AutoRemovePublicDownloadFile) |
| 30 | task.AddTask("autoRemovePublicDownloadFile", autoRemovePublicDownloadFile) | 33 | task.AddTask("autoRemovePublicDownloadFile", autoRemovePublicDownloadFile) |
| 34 | + | ||
| 35 | + autoRemoveTemporaryTable := task.NewTask("定时清理临时表", "0 57 */1 * * *", AutoRemoveTemporaryTable) | ||
| 36 | + task.AddTask("autoRemoveTemporaryTable", autoRemoveTemporaryTable) | ||
| 31 | } | 37 | } |
| 32 | 38 | ||
| 33 | func (crontabService *CrontabService) StartCrontabTask() { | 39 | func (crontabService *CrontabService) StartCrontabTask() { |
| @@ -115,3 +121,49 @@ func AutoRemovePublicDownloadFile(ctx context.Context) error { | @@ -115,3 +121,49 @@ func AutoRemovePublicDownloadFile(ctx context.Context) error { | ||
| 115 | } | 121 | } |
| 116 | return nil | 122 | return nil |
| 117 | } | 123 | } |
| 124 | + | ||
| 125 | +func AutoRemoveTemporaryTable(ctx context.Context) error { | ||
| 126 | + defer func() { | ||
| 127 | + if r := recover(); r != nil { | ||
| 128 | + log.Logger.Error(fmt.Sprintf("%v", r), map[string]interface{}{"task": "定时清理过期临时文件记录"}) | ||
| 129 | + } | ||
| 130 | + }() | ||
| 131 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 132 | + if err != nil { | ||
| 133 | + return err | ||
| 134 | + } | ||
| 135 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 136 | + return err | ||
| 137 | + } | ||
| 138 | + defer func() { | ||
| 139 | + if err != nil { | ||
| 140 | + log.Logger.Error("【定时清理临时表】 失败:" + err.Error()) | ||
| 141 | + } | ||
| 142 | + transactionContext.RollbackTransaction() | ||
| 143 | + }() | ||
| 144 | + | ||
| 145 | + log.Logger.Debug("【定时清理临时表】 启动") | ||
| 146 | + end := xtime.New(time.Now()).BeginningOfDay().Add(-time.Hour * 12) | ||
| 147 | + begin := end.AddDate(0, 0, -7) | ||
| 148 | + | ||
| 149 | + tableRepository, _, _ := factory.FastPgTable(transactionContext, 0) | ||
| 150 | + _, tables, err := tableRepository.Find(map[string]interface{}{"beginTime": begin, "endTime": end, "tableTypes": []string{domain.TemporaryTable.ToString()}}) | ||
| 151 | + if err != nil { | ||
| 152 | + return nil | ||
| 153 | + } | ||
| 154 | + for i, t := range tables { | ||
| 155 | + if err = dao.TableDelete(transactionContext.(*pgTransaction.TransactionContext), t.TableId, domain.TemporaryTable); err != nil { | ||
| 156 | + log.Logger.Error(err.Error()) | ||
| 157 | + return nil | ||
| 158 | + } | ||
| 159 | + log.Logger.Info(fmt.Sprintf("序号:%d 清理临时表 %v", i, t.SQLName)) | ||
| 160 | + if err = starrocks.DropView(starrocks.DB, t.SQLName); err != nil { | ||
| 161 | + log.Logger.Error(err.Error()) | ||
| 162 | + return nil | ||
| 163 | + } | ||
| 164 | + } | ||
| 165 | + if err = transactionContext.CommitTransaction(); err != nil { | ||
| 166 | + return err | ||
| 167 | + } | ||
| 168 | + return nil | ||
| 169 | +} |
| 1 | +package service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/linmadan/egglib-go/core/application" | ||
| 6 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 7 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/event/command" | ||
| 8 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | ||
| 9 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" | ||
| 10 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 11 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/api/digitalLib" | ||
| 12 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/broker" | ||
| 13 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" | ||
| 14 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" | ||
| 15 | + "math" | ||
| 16 | + "time" | ||
| 17 | +) | ||
| 18 | + | ||
| 19 | +func (tableEventService *TableEventService) DigitalPlatformEventSubscribe(ctx *domain.Context, cmd *command.TableEventCommand) (interface{}, error) { | ||
| 20 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 21 | + if err != nil { | ||
| 22 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 23 | + } | ||
| 24 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 25 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 26 | + } | ||
| 27 | + defer func() { | ||
| 28 | + transactionContext.RollbackTransaction() | ||
| 29 | + }() | ||
| 30 | + | ||
| 31 | + var ( | ||
| 32 | + dataChanged = true | ||
| 33 | + structChanged = true | ||
| 34 | + ok bool | ||
| 35 | + tableId int | ||
| 36 | + ) | ||
| 37 | + event := cmd.EventTable | ||
| 38 | + if tableId = resolveTableId(event); tableId == 0 { | ||
| 39 | + return nil, nil | ||
| 40 | + } | ||
| 41 | + if event.Type == domain.TableApplyOnEvent { | ||
| 42 | + dataChanged = false | ||
| 43 | + } | ||
| 44 | + var notifyData = &NotifyData{ | ||
| 45 | + DataChanged: dataChanged, | ||
| 46 | + StructChanged: structChanged, | ||
| 47 | + TableId: tableId, | ||
| 48 | + Event: event.Type.ToString(), | ||
| 49 | + Metadata: event.Metadata, | ||
| 50 | + } | ||
| 51 | + // 表类型 | ||
| 52 | + tableRepository, table, _ := factory.FastPgTable(transactionContext, tableId) | ||
| 53 | + if table == nil && event.Table != nil { | ||
| 54 | + table = event.Table | ||
| 55 | + notifyData.CompanyId = table.Context.CompanyId | ||
| 56 | + } | ||
| 57 | + notifyData.SetType(event, table) | ||
| 58 | + | ||
| 59 | + // 依赖的表 \ 依赖的查询集合 | ||
| 60 | + _, tables, err := tableRepository.Find(map[string]interface{}{"context": event.Context, "tableTypesNotIn": []string{domain.TemporaryTable.ToString(), domain.ExcelTable.ToString()}}) | ||
| 61 | + if err != nil { | ||
| 62 | + return nil, err | ||
| 63 | + } | ||
| 64 | + tableDependencyService, _ := domainService.NewTableDependencyService(transactionContext.(*pgTransaction.TransactionContext)) | ||
| 65 | + tableDependTree := tableDependencyService.TableDependTree(tables, tableId) | ||
| 66 | + tree := tableDependTree.Tree | ||
| 67 | + querySetRepository, _, _ := factory.FastPgQuerySet(transactionContext, 0) | ||
| 68 | + var mapTableQuerySet = make(map[int]*domain.QuerySet) | ||
| 69 | + if len(tree) > 0 { | ||
| 70 | + _, querySets, _ := querySetRepository.Find(map[string]interface{}{ | ||
| 71 | + "types": []string{domain.SchemaTable.ToString(), domain.CalculateItem.ToString(), domain.CalculateSet.ToString()}, | ||
| 72 | + "bindTableIds": tree, | ||
| 73 | + "status": domain.StatusOn, | ||
| 74 | + }) | ||
| 75 | + for _, q := range querySets { | ||
| 76 | + mapTableQuerySet[q.QuerySetInfo.BindTableId] = q | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + // 过滤出需要推送的表 | ||
| 81 | + for i := range tree { | ||
| 82 | + table, ok = tableDependencyService.TableMap[tree[i]] | ||
| 83 | + if !ok { | ||
| 84 | + continue | ||
| 85 | + } | ||
| 86 | + if notifyData.CompanyId == 0 { | ||
| 87 | + notifyData.CompanyId = table.Context.CompanyId | ||
| 88 | + } | ||
| 89 | + switch table.TableType { | ||
| 90 | + case domain.MainTable.ToString(), domain.SubTable.ToString(), domain.SideTable.ToString(): | ||
| 91 | + if table.TableInfo != nil { | ||
| 92 | + applyOn := domain.ModuleDigitalCenter | domain.ModuleChartTemplate | ||
| 93 | + if table.TableInfo.ApplyOnModule&applyOn == 0 { | ||
| 94 | + continue | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + break | ||
| 98 | + case domain.SubProcessTable.ToString(), domain.CalculateTable.ToString(): | ||
| 99 | + continue | ||
| 100 | + case domain.SchemaTable.ToString(), domain.CalculateSet.ToString(), domain.CalculateItem.ToString(): | ||
| 101 | + var querySet *domain.QuerySet | ||
| 102 | + if querySet, ok = mapTableQuerySet[tree[i]]; !ok { | ||
| 103 | + continue | ||
| 104 | + } | ||
| 105 | + // 不是当前的查询集。且状态为关闭的都补推送 | ||
| 106 | + if querySet.Status != domain.StatusOn && querySet.QuerySetInfo.BindTableId != 0 && querySet.QuerySetInfo.BindTableId != tableId { | ||
| 107 | + continue | ||
| 108 | + } | ||
| 109 | + } | ||
| 110 | + notifyData.TableAffectedList = append(notifyData.TableAffectedList, tree[i]) | ||
| 111 | + } | ||
| 112 | + // 包含自己 | ||
| 113 | + if !exist(notifyData.TableAffectedList, tableId) { | ||
| 114 | + notifyData.TableAffectedList = append(notifyData.TableAffectedList, tableId) | ||
| 115 | + } | ||
| 116 | + // 通过消息队列发送 | ||
| 117 | + if err = tableEventService.send(notifyData, tableEventService.sendBroker); err != nil { | ||
| 118 | + return nil, err | ||
| 119 | + } | ||
| 120 | + if err = transactionContext.CommitTransaction(); err != nil { | ||
| 121 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 122 | + } | ||
| 123 | + return nil, nil | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +func (tableEventService *TableEventService) send(notifyData *NotifyData, sendFunc func(*NotifyData) error) error { | ||
| 127 | + var err error | ||
| 128 | + if err = sendFunc(notifyData); err != nil { | ||
| 129 | + log.Logger.Error(fmt.Sprintf("通知数控失败:%s", err.Error())) | ||
| 130 | + if t, ok := notifyData.Retry(); ok { | ||
| 131 | + tableEventService.TimingWheel.SetTimer(notifyData.Key(), ¬ifyData, t) | ||
| 132 | + log.Logger.Debug(fmt.Sprintf("通知数控重试 key:%s wait:%vs", notifyData.Key(), t.Seconds())) | ||
| 133 | + } | ||
| 134 | + } | ||
| 135 | + return err | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +func (tableEventService *TableEventService) sendHttp(notifyData *NotifyData) error { | ||
| 139 | + var err error | ||
| 140 | + lib := digitalLib.NewDigitalLib(constant.DIGITAL_SERVER_HOST) | ||
| 141 | + if _, err = lib.SyncNotice(digitalLib.RequestSyncNotice{Body: notifyData}); err != nil { | ||
| 142 | + return err | ||
| 143 | + } | ||
| 144 | + return nil | ||
| 145 | +} | ||
| 146 | + | ||
| 147 | +func (tableEventService *TableEventService) sendBroker(notifyData *NotifyData) error { | ||
| 148 | + var err error | ||
| 149 | + if err = broker.Push(constant.KAFKA_HOST, constant.TOPIC_TABLE_DATA_SYNC, notifyData); err != nil { | ||
| 150 | + return err | ||
| 151 | + } | ||
| 152 | + return nil | ||
| 153 | +} | ||
| 154 | + | ||
| 155 | +func resolveTableId(event *domain.EventTable) (tableId int) { | ||
| 156 | + switch event.Type { | ||
| 157 | + case domain.TableDataImportEvent, domain.TableDataEditEvent, domain.TableDeleteEvent, domain.TableStructEditEvent: | ||
| 158 | + tableId = event.Table.TableId | ||
| 159 | + case domain.QuerySetUpdateEvent, domain.QuerySetUpdateRenameEvent: | ||
| 160 | + if event.QuerySet.Status != domain.StatusOn { | ||
| 161 | + return | ||
| 162 | + } | ||
| 163 | + if !domain.AssertTableType(event.QuerySet.Type, domain.SchemaTable, domain.CalculateItem, domain.CalculateSet) { | ||
| 164 | + return | ||
| 165 | + } | ||
| 166 | + tableId = event.QuerySet.QuerySetInfo.BindTableId | ||
| 167 | + case domain.QuerySetUpdateStatusEvent: | ||
| 168 | + if !domain.AssertTableType(event.QuerySet.Type, domain.SchemaTable, domain.CalculateItem, domain.CalculateSet) { | ||
| 169 | + return | ||
| 170 | + } | ||
| 171 | + tableId = event.QuerySet.QuerySetInfo.BindTableId | ||
| 172 | + case domain.TableApplyOnEvent: | ||
| 173 | + tableId = event.Table.TableId | ||
| 174 | + case domain.QuerySetDeleteEvent: | ||
| 175 | + tableId = event.Table.TableId | ||
| 176 | + } | ||
| 177 | + return tableId | ||
| 178 | +} | ||
| 179 | + | ||
| 180 | +func exist(idList []int, target int) bool { | ||
| 181 | + found := false | ||
| 182 | + for _, id := range idList { | ||
| 183 | + if id == target { | ||
| 184 | + found = true | ||
| 185 | + } | ||
| 186 | + } | ||
| 187 | + return found | ||
| 188 | +} | ||
| 189 | + | ||
| 190 | +type NotifyData struct { | ||
| 191 | + DataChanged bool `json:"dataChanged"` // 数据有变化 | ||
| 192 | + StructChanged bool `json:"structChanged"` // 结构有变化 | ||
| 193 | + TableId int `json:"tableId"` // 表ID | ||
| 194 | + TableType string `json:"tableType"` // 表类型:导入模块(主表,副表,分表) 拆解模块(方案、子过程、计算表) 计算模块(计算项,计算集) | ||
| 195 | + ObjectType string `json:"objectType"` // 导入模块、拆解模块、计算模块 | ||
| 196 | + CompanyId int `json:"companyId"` // 公司 | ||
| 197 | + Event string `json:"event"` // 事件名称 | ||
| 198 | + TableAffectedList []int `json:"tableAffectedList"` // 级联影响到的表 | ||
| 199 | + Metadata map[string]interface{} `json:"metadata"` // 元数据 | ||
| 200 | + sendRetry int | ||
| 201 | +} | ||
| 202 | + | ||
| 203 | +func (n *NotifyData) SetType(event *domain.EventTable, table *domain.Table) { | ||
| 204 | + var tableType string | ||
| 205 | + // 表类型 | ||
| 206 | + if tableType == "" && table != nil { | ||
| 207 | + tableType = table.TableType | ||
| 208 | + } | ||
| 209 | + if tableType == "" && event.QuerySet != nil { | ||
| 210 | + tableType = event.QuerySet.Type | ||
| 211 | + } | ||
| 212 | + n.TableType = domain.EnumsDescription(domain.ObjectTypeMap, tableType) | ||
| 213 | + if table != nil { | ||
| 214 | + switch domain.TableType(tableType) { | ||
| 215 | + case domain.MainTable, domain.SubTable, domain.SideTable: | ||
| 216 | + n.ObjectType = "导入模块" | ||
| 217 | + case domain.SchemaTable, domain.SubProcessTable, domain.CalculateTable: | ||
| 218 | + n.ObjectType = "拆解模块" | ||
| 219 | + case domain.CalculateItem, domain.CalculateSet: | ||
| 220 | + n.ObjectType = "计算模块" | ||
| 221 | + } | ||
| 222 | + } | ||
| 223 | +} | ||
| 224 | + | ||
| 225 | +func (n *NotifyData) Key() string { | ||
| 226 | + return fmt.Sprintf("delay:notify:table:%d", n.TableId) | ||
| 227 | +} | ||
| 228 | + | ||
| 229 | +func (n *NotifyData) Retry() (time.Duration, bool) { | ||
| 230 | + n.sendRetry++ | ||
| 231 | + if n.sendRetry > 3 { | ||
| 232 | + return n.Delay(), false | ||
| 233 | + } | ||
| 234 | + if n.sendRetry == 1 { | ||
| 235 | + return n.Delay(), true | ||
| 236 | + } | ||
| 237 | + return n.Delay() * time.Duration(int(math.Pow(float64(2), float64(n.sendRetry)))), true | ||
| 238 | +} | ||
| 239 | + | ||
| 240 | +func (n *NotifyData) Delay() time.Duration { | ||
| 241 | + return time.Second * 10 | ||
| 242 | +} | ||
| 243 | + | ||
| 244 | +func (n *NotifyData) RetryTime() int { | ||
| 245 | + return n.sendRetry | ||
| 246 | +} |
pkg/application/event/service/event.go
0 → 100644
| 1 | +package service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/linmadan/egglib-go/core/application" | ||
| 6 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 7 | + "github.com/zeromicro/go-zero/core/collection" | ||
| 8 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/event/command" | ||
| 9 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | ||
| 10 | + tablecommand "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command" | ||
| 11 | + tableservice "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/service" | ||
| 12 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 13 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/api/digitalLib" | ||
| 14 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/cache" | ||
| 15 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" | ||
| 16 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" | ||
| 17 | + "time" | ||
| 18 | +) | ||
| 19 | + | ||
| 20 | +type TableEventService struct { | ||
| 21 | + TimingWheel *collection.TimingWheel | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +func (tableEventService *TableEventService) Handler(ctx *domain.Context, cmd *command.TableEventCommand) (interface{}, error) { | ||
| 25 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 26 | + if err != nil { | ||
| 27 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 28 | + } | ||
| 29 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 30 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 31 | + } | ||
| 32 | + defer func() { | ||
| 33 | + transactionContext.RollbackTransaction() | ||
| 34 | + }() | ||
| 35 | + | ||
| 36 | + data := cmd.EventTable | ||
| 37 | + tableId := 0 | ||
| 38 | + switch data.Type { | ||
| 39 | + case domain.TableDataImportEvent, domain.TableDataEditEvent, domain.TableDeleteEvent, domain.TableStructEditEvent: | ||
| 40 | + tableId = data.Table.TableId | ||
| 41 | + case domain.QuerySetUpdateEvent: | ||
| 42 | + tableId = data.QuerySet.QuerySetInfo.BindTableId | ||
| 43 | + default: | ||
| 44 | + return nil, err | ||
| 45 | + } | ||
| 46 | + if tableId == 0 { | ||
| 47 | + return nil, nil | ||
| 48 | + } | ||
| 49 | + // tableId 相关联的 | ||
| 50 | + tableRepository, _, _ := factory.FastPgTable(transactionContext, 0) | ||
| 51 | + _, tables, err := tableRepository.Find(map[string]interface{}{"context": data.Context, "tableTypesNotIn": []string{domain.TemporaryTable.ToString(), domain.ExcelTable.ToString()}}) | ||
| 52 | + if err != nil { | ||
| 53 | + return nil, err | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + tableDependencyService, _ := domainService.NewTableDependencyService(transactionContext.(*pgTransaction.TransactionContext)) | ||
| 57 | + tableDependTree := tableDependencyService.TableDependTree(tables, tableId) | ||
| 58 | + tree := tableDependTree.Tree | ||
| 59 | + | ||
| 60 | + tableService := tableservice.NewTableService(nil) | ||
| 61 | + for i := range tree { | ||
| 62 | + cache.DefaultDataTableCacheService.DeleteDataTable(tree[i]) | ||
| 63 | + // fresh cache | ||
| 64 | + tableService.TablePreview(data.Context, &tablecommand.TablePreviewCommand{ | ||
| 65 | + TableId: tree[i], | ||
| 66 | + ObjectType: domain.ObjectMetaTable, | ||
| 67 | + PageSize: 10000, | ||
| 68 | + PageNumber: 0, | ||
| 69 | + UseCache: true, | ||
| 70 | + }) | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 74 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 75 | + } | ||
| 76 | + return nil, nil | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +func NewTableEventService(options map[string]interface{}) *TableEventService { | ||
| 80 | + svr := &TableEventService{} | ||
| 81 | + delayNotifyTimingWheel, _ := collection.NewTimingWheel(time.Second, 10, svr.TimingWheelFunc) | ||
| 82 | + svr.TimingWheel = delayNotifyTimingWheel | ||
| 83 | + return svr | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +func (tableEventService *TableEventService) TimingWheelFunc(key, value interface{}) { | ||
| 87 | + v, ok := value.(*NotifyData) | ||
| 88 | + if !ok { | ||
| 89 | + return | ||
| 90 | + } | ||
| 91 | + lib := digitalLib.NewDigitalLib("") | ||
| 92 | + if _, err := lib.SyncNotice(digitalLib.RequestSyncNotice{Body: v}); err != nil { | ||
| 93 | + log.Logger.Error(fmt.Sprintf("通知数控失败:%s", err.Error())) | ||
| 94 | + if t, ok := v.Retry(); ok { | ||
| 95 | + if err = tableEventService.TimingWheel.SetTimer(v.Key(), v, t); err == nil { | ||
| 96 | + log.Logger.Debug(fmt.Sprintf("通知数控重试(%d) key:%s wait:%vs", v.RetryTime(), v.Key(), t.Seconds())) | ||
| 97 | + return | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + } | ||
| 101 | + tableEventService.TimingWheel.RemoveTimer(v.Key()) | ||
| 102 | +} |
| 1 | +package service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "errors" | ||
| 5 | + "fmt" | ||
| 6 | + "github.com/linmadan/egglib-go/core/application" | ||
| 7 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/event/command" | ||
| 8 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | ||
| 9 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 10 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" | ||
| 11 | + "reflect" | ||
| 12 | + "sort" | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +func (tableEventService *TableEventService) HandlerTableAffectedMarkToConflictStatus(ctx *domain.Context, cmd *command.TableEventCommand) (interface{}, error) { | ||
| 16 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 17 | + if err != nil { | ||
| 18 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 19 | + } | ||
| 20 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 21 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 22 | + } | ||
| 23 | + defer func() { | ||
| 24 | + transactionContext.RollbackTransaction() | ||
| 25 | + }() | ||
| 26 | + | ||
| 27 | + data := cmd.EventTable | ||
| 28 | + tableId := 0 | ||
| 29 | + switch data.Type { | ||
| 30 | + case domain.TableStructEditEvent, domain.TableDeleteEvent: | ||
| 31 | + tableId = data.Table.TableId | ||
| 32 | + case domain.QuerySetUpdateEvent: | ||
| 33 | + // 结构变更才报冲突 | ||
| 34 | + if !checkStructChange(cmd) { | ||
| 35 | + return nil, err | ||
| 36 | + } | ||
| 37 | + tableId = data.QuerySet.QuerySetInfo.BindTableId | ||
| 38 | + case domain.QuerySetUpdateRenameEvent: | ||
| 39 | + tableId = data.QuerySet.QuerySetInfo.BindTableId | ||
| 40 | + default: | ||
| 41 | + return nil, err | ||
| 42 | + } | ||
| 43 | + if tableId == 0 { | ||
| 44 | + return nil, nil | ||
| 45 | + } | ||
| 46 | + // tableId 相关联的 | ||
| 47 | + tableRepository, _, _ := factory.FastPgTable(transactionContext, 0) | ||
| 48 | + | ||
| 49 | + _, tables, err := tableRepository.Find(map[string]interface{}{"context": ctx, "dependencyTable": tableId, "tableTypesNotIn": []string{domain.TemporaryTable.ToString()}}) | ||
| 50 | + if errors.Is(err, domain.ErrorNotFound) { | ||
| 51 | + return nil, nil | ||
| 52 | + } | ||
| 53 | + tableIds := make([]int, 0) | ||
| 54 | + for _, table := range tables { | ||
| 55 | + tableIds = append(tableIds, table.TableId) | ||
| 56 | + } | ||
| 57 | + if len(tableIds) == 0 { | ||
| 58 | + return nil, nil | ||
| 59 | + } | ||
| 60 | + querySetRepository, _, _ := factory.FastPgQuerySet(transactionContext, 0) | ||
| 61 | + _, querySets, _ := querySetRepository.Find(map[string]interface{}{"context": ctx, "bindTableIds": tableIds}) | ||
| 62 | + for _, querySet := range querySets { | ||
| 63 | + log.Logger.Debug(fmt.Sprintf("【集合状态更新】 id:%v name:%v ReadyStatus:1", querySet.QuerySetId, querySet.Name)) | ||
| 64 | + querySet.QuerySetInfo.WithConflictStatus() | ||
| 65 | + _, err = querySetRepository.Save(querySet) | ||
| 66 | + if err != nil { | ||
| 67 | + return nil, err | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + //tableDependencyService, _ := domainService.NewTableDependencyService(transactionContext.(*pgTransaction.TransactionContext)) | ||
| 72 | + //tableDependTree := tableDependencyService.TableDependTree(tables, tableId) | ||
| 73 | + //tree := tableDependTree.Tree | ||
| 74 | + // | ||
| 75 | + //querySetRepository, _, _ := factory.FastPgQuerySet(transactionContext, 0) | ||
| 76 | + //if len(tree) > 0 { | ||
| 77 | + // _, querySets, _ := querySetRepository.Find(map[string]interface{}{ | ||
| 78 | + // "types": []string{domain.SchemaTable.ToString(), domain.SubProcessTable.ToString(), domain.CalculateTable.ToString()}, | ||
| 79 | + // "bindTableIds": tree, | ||
| 80 | + // }) | ||
| 81 | + // for _, querySet := range querySets { | ||
| 82 | + // log.Logger.Debug(fmt.Sprintf("【集合状态更新】 id:%v name:%v 标记冲突", querySet.QuerySetId, querySet.Name)) | ||
| 83 | + // querySet.QuerySetInfo.WithConflictStatus() | ||
| 84 | + // _, err = querySetRepository.Save(querySet) | ||
| 85 | + // if err != nil { | ||
| 86 | + // return nil, err | ||
| 87 | + // } | ||
| 88 | + // } | ||
| 89 | + //} | ||
| 90 | + | ||
| 91 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 92 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 93 | + } | ||
| 94 | + return nil, nil | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +func checkStructChange(cmd *command.TableEventCommand) bool { | ||
| 98 | + var ( | ||
| 99 | + newSet = cmd.EventTable.QuerySet | ||
| 100 | + oldSet = cmd.EventTable.OldQuerySet | ||
| 101 | + newTable = cmd.EventTable.Table | ||
| 102 | + oldTable = cmd.EventTable.OldTable | ||
| 103 | + ) | ||
| 104 | + if newSet == nil || oldSet == nil { | ||
| 105 | + return false | ||
| 106 | + } | ||
| 107 | + var ( | ||
| 108 | + t string = newSet.Type | ||
| 109 | + ) | ||
| 110 | + | ||
| 111 | + switch t { | ||
| 112 | + case domain.SchemaTable.ToString(), domain.SubProcessTable.ToString(): | ||
| 113 | + // 第一步表有变更 | ||
| 114 | + newSetDepTables := newSet.GetDependencyTables(newSet.QueryComponents) | ||
| 115 | + oldSetDepTables := newSet.GetDependencyTables(oldSet.QueryComponents) | ||
| 116 | + sort.SliceStable(newSetDepTables, func(i, j int) bool { | ||
| 117 | + return newSetDepTables[i] < newSetDepTables[j] | ||
| 118 | + }) | ||
| 119 | + sort.SliceStable(oldSetDepTables, func(i, j int) bool { | ||
| 120 | + return oldSetDepTables[i] < oldSetDepTables[j] | ||
| 121 | + }) | ||
| 122 | + if !reflect.DeepEqual(newSetDepTables, oldSetDepTables) { | ||
| 123 | + log.Logger.Debug(fmt.Sprintf("方案/过程:%v 依赖变更 %v -> %v", t, oldSetDepTables, newSetDepTables)) | ||
| 124 | + return true | ||
| 125 | + } | ||
| 126 | + case domain.CalculateTable.ToString(): | ||
| 127 | + | ||
| 128 | + case domain.CalculateItem.ToString(), domain.CalculateSet.ToString(): | ||
| 129 | + return false | ||
| 130 | + } | ||
| 131 | + if newTable == nil || oldTable == nil { | ||
| 132 | + return false | ||
| 133 | + } | ||
| 134 | + // 第二步判断字段是否有变更 | ||
| 135 | + newTableFields := tableFields(newTable) | ||
| 136 | + oldTableFields := tableFields(oldTable) | ||
| 137 | + sort.Strings(newTableFields) | ||
| 138 | + sort.Strings(oldTableFields) | ||
| 139 | + if !reflect.DeepEqual(newTableFields, oldTableFields) { | ||
| 140 | + log.Logger.Debug(fmt.Sprintf("计算表:%v 结构变更 %v -> %v", t, oldTableFields, newTableFields)) | ||
| 141 | + return true | ||
| 142 | + } | ||
| 143 | + return false | ||
| 144 | +} | ||
| 145 | + | ||
| 146 | +func tableFields(t *domain.Table) []string { | ||
| 147 | + var result = make([]string, 0) | ||
| 148 | + for _, f := range t.Fields(false) { | ||
| 149 | + result = append(result, f.Name) | ||
| 150 | + } | ||
| 151 | + return result | ||
| 152 | +} |
| @@ -4,7 +4,6 @@ import ( | @@ -4,7 +4,6 @@ import ( | ||
| 4 | "github.com/linmadan/egglib-go/core/application" | 4 | "github.com/linmadan/egglib-go/core/application" |
| 5 | "github.com/linmadan/egglib-go/transaction/pg" | 5 | "github.com/linmadan/egglib-go/transaction/pg" |
| 6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
| 7 | - "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain/bytecore" | ||
| 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" | 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" |
| 9 | ) | 8 | ) |
| 10 | 9 | ||
| @@ -58,6 +57,6 @@ func CreateTableEditDataService(transactionContext application.TransactionContex | @@ -58,6 +57,6 @@ func CreateTableEditDataService(transactionContext application.TransactionContex | ||
| 58 | } | 57 | } |
| 59 | 58 | ||
| 60 | // 字库核心 | 59 | // 字库核心 |
| 61 | -func CreateByteCoreService(transactionContext application.TransactionContext) (bytecore.ByteLibService, error) { | 60 | +func CreateByteCoreService(transactionContext application.TransactionContext) (domain.ByteLibService, error) { |
| 62 | return domainService.ByteCore, nil | 61 | return domainService.ByteCore, nil |
| 63 | } | 62 | } |
| @@ -2,7 +2,9 @@ package factory | @@ -2,7 +2,9 @@ package factory | ||
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "github.com/linmadan/egglib-go/core/application" | 4 | "github.com/linmadan/egglib-go/core/application" |
| 5 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 5 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
| 7 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" | ||
| 6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" | 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" |
| 7 | ) | 9 | ) |
| 8 | 10 | ||
| @@ -10,6 +12,18 @@ func FastError(err error) error { | @@ -10,6 +12,18 @@ func FastError(err error) error { | ||
| 10 | return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 12 | return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 11 | } | 13 | } |
| 12 | 14 | ||
| 15 | +func FastErrorResponse(err error, args ...interface{}) interface{} { | ||
| 16 | + var response = make(map[string]interface{}) | ||
| 17 | + response["internalErr"] = err.Error() | ||
| 18 | + for i := 0; i < len(args); i += 2 { | ||
| 19 | + if i+1 >= len(args) { | ||
| 20 | + break | ||
| 21 | + } | ||
| 22 | + response[args[i].(string)] = args[i+1] | ||
| 23 | + } | ||
| 24 | + return response | ||
| 25 | +} | ||
| 26 | + | ||
| 13 | func FastDataTable(options starrocks.QueryOptions) (*domain.DataTable, error) { | 27 | func FastDataTable(options starrocks.QueryOptions) (*domain.DataTable, error) { |
| 14 | var err error | 28 | var err error |
| 15 | // 待优化分批下载,压缩 | 29 | // 待优化分批下载,压缩 |
| @@ -25,3 +39,7 @@ func FastDataTable(options starrocks.QueryOptions) (*domain.DataTable, error) { | @@ -25,3 +39,7 @@ func FastDataTable(options starrocks.QueryOptions) (*domain.DataTable, error) { | ||
| 25 | } | 39 | } |
| 26 | return dataTable, nil | 40 | return dataTable, nil |
| 27 | } | 41 | } |
| 42 | + | ||
| 43 | +func FastQuerySetServices(transactionContext application.TransactionContext) (*domainService.QuerySetService, error) { | ||
| 44 | + return domainService.NewQuerySetService(transactionContext.(*pgTransaction.TransactionContext)) | ||
| 45 | +} |
| @@ -23,9 +23,9 @@ func FastPgFile(transactionContext application.TransactionContext, id int) (doma | @@ -23,9 +23,9 @@ func FastPgFile(transactionContext application.TransactionContext, id int) (doma | ||
| 23 | if id > 0 { | 23 | if id > 0 { |
| 24 | if mod, err = rep.FindOne(map[string]interface{}{"fileId": id}); err != nil { | 24 | if mod, err = rep.FindOne(map[string]interface{}{"fileId": id}); err != nil { |
| 25 | if err == domain.ErrorNotFound { | 25 | if err == domain.ErrorNotFound { |
| 26 | - return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该文件不存在") | 26 | + return rep, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该文件不存在") |
| 27 | } | 27 | } |
| 28 | - return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 28 | + return rep, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| 29 | } | 29 | } |
| 30 | } | 30 | } |
| 31 | //if err = fastPgDataAuth(transactionContext, mod, options...); err != nil { | 31 | //if err = fastPgDataAuth(transactionContext, mod, options...); err != nil { |
| @@ -52,9 +52,9 @@ func FastPgTable(transactionContext application.TransactionContext, id int) (dom | @@ -52,9 +52,9 @@ func FastPgTable(transactionContext application.TransactionContext, id int) (dom | ||
| 52 | if id > 0 { | 52 | if id > 0 { |
| 53 | if mod, err = rep.FindOne(map[string]interface{}{"tableId": id}); err != nil { | 53 | if mod, err = rep.FindOne(map[string]interface{}{"tableId": id}); err != nil { |
| 54 | if err == domain.ErrorNotFound { | 54 | if err == domain.ErrorNotFound { |
| 55 | - return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该表格不存在") | 55 | + return rep, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该表格不存在") |
| 56 | } | 56 | } |
| 57 | - return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 57 | + return rep, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| 58 | } | 58 | } |
| 59 | } | 59 | } |
| 60 | return rep, mod, err | 60 | return rep, mod, err |
| @@ -78,9 +78,9 @@ func FastPgLog(transactionContext application.TransactionContext, id int) (domai | @@ -78,9 +78,9 @@ func FastPgLog(transactionContext application.TransactionContext, id int) (domai | ||
| 78 | if id > 0 { | 78 | if id > 0 { |
| 79 | if mod, err = rep.FindOne(map[string]interface{}{"logId": id}); err != nil { | 79 | if mod, err = rep.FindOne(map[string]interface{}{"logId": id}); err != nil { |
| 80 | if err == domain.ErrorNotFound { | 80 | if err == domain.ErrorNotFound { |
| 81 | - return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该日志不存在") | 81 | + return rep, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该日志不存在") |
| 82 | } | 82 | } |
| 83 | - return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 83 | + return rep, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| 84 | } | 84 | } |
| 85 | } | 85 | } |
| 86 | return rep, mod, err | 86 | return rep, mod, err |
| @@ -104,9 +104,35 @@ func FastPgMappingRule(transactionContext application.TransactionContext, id int | @@ -104,9 +104,35 @@ func FastPgMappingRule(transactionContext application.TransactionContext, id int | ||
| 104 | if id > 0 { | 104 | if id > 0 { |
| 105 | if mod, err = rep.FindOne(map[string]interface{}{"mappingRuleId": id}); err != nil { | 105 | if mod, err = rep.FindOne(map[string]interface{}{"mappingRuleId": id}); err != nil { |
| 106 | if err == domain.ErrorNotFound { | 106 | if err == domain.ErrorNotFound { |
| 107 | - return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该匹配规则不存在") | 107 | + return rep, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该匹配规则不存在") |
| 108 | } | 108 | } |
| 109 | - return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 109 | + return rep, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| 110 | + } | ||
| 111 | + } | ||
| 112 | + return rep, mod, err | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +// FastPgQuerySet 快速返回查询集合 | ||
| 116 | +// | ||
| 117 | +// transactionContext 事务 | ||
| 118 | +// id 对象唯一标识 | ||
| 119 | +func FastPgQuerySet(transactionContext application.TransactionContext, id int) (domain.QuerySetRepository, *domain.QuerySet, error) { | ||
| 120 | + var rep domain.QuerySetRepository | ||
| 121 | + var mod *domain.QuerySet | ||
| 122 | + var err error | ||
| 123 | + if value, err := CreateQuerySetRepository(map[string]interface{}{ | ||
| 124 | + "transactionContext": transactionContext, | ||
| 125 | + }); err != nil { | ||
| 126 | + return nil, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 127 | + } else { | ||
| 128 | + rep = value | ||
| 129 | + } | ||
| 130 | + if id > 0 { | ||
| 131 | + if mod, err = rep.FindOne(map[string]interface{}{"querySetId": id}); err != nil { | ||
| 132 | + if err == domain.ErrorNotFound { | ||
| 133 | + return rep, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该查询集合不存在") | ||
| 134 | + } | ||
| 135 | + return rep, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 110 | } | 136 | } |
| 111 | } | 137 | } |
| 112 | return rep, mod, err | 138 | return rep, mod, err |
| @@ -37,3 +37,11 @@ func CreateMappingRuleRepository(options map[string]interface{}) (domain.Mapping | @@ -37,3 +37,11 @@ func CreateMappingRuleRepository(options map[string]interface{}) (domain.Mapping | ||
| 37 | } | 37 | } |
| 38 | return repository.NewMappingRuleRepository(transactionContext) | 38 | return repository.NewMappingRuleRepository(transactionContext) |
| 39 | } | 39 | } |
| 40 | + | ||
| 41 | +func CreateQuerySetRepository(options map[string]interface{}) (domain.QuerySetRepository, error) { | ||
| 42 | + var transactionContext *pg.TransactionContext | ||
| 43 | + if value, ok := options["transactionContext"]; ok { | ||
| 44 | + transactionContext = value.(*pg.TransactionContext) | ||
| 45 | + } | ||
| 46 | + return repository.NewQuerySetRepository(transactionContext) | ||
| 47 | +} |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 4 | + | ||
| 5 | +type AppTableFileAppendDataCommand struct { | ||
| 6 | + Name string `json:"name"` | ||
| 7 | + // name 字段中文名 | ||
| 8 | + Fields []*domain.Field `json:"fields"` | ||
| 9 | + // 数据列表 key:name(字段中文名) value:值(字符串类型) | ||
| 10 | + Data []map[string]string `json:"data"` | ||
| 11 | + | ||
| 12 | + AppKey string `json:"appKey"` | ||
| 13 | + | ||
| 14 | + // 追加表数据标识 true:往应用表里面追加数据 false:跳过 | ||
| 15 | + AppendTableDataFlag bool `json:"appendTableDataFlag"` | ||
| 16 | +} |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 4 | + | ||
| 5 | +type CreateAppTableFileCommand struct { | ||
| 6 | + Name string `json:"name"` | ||
| 7 | + // name 字段中文名 | ||
| 8 | + Fields []*domain.Field `json:"fields"` | ||
| 9 | + // 数据列表 key:name(字段中文名) value:值(字符串类型) | ||
| 10 | + Data []map[string]string `json:"data"` | ||
| 11 | + // 生成表标识 true:实例化一个表 false:跳过 | ||
| 12 | + GenerateTableFlag bool `json:"generateTableFlag"` | ||
| 13 | +} |
| @@ -19,7 +19,14 @@ type AppendDataToTableCommand struct { | @@ -19,7 +19,14 @@ type AppendDataToTableCommand struct { | ||
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | func (cmd *AppendDataToTableCommand) Valid(validation *validation.Validation) { | 21 | func (cmd *AppendDataToTableCommand) Valid(validation *validation.Validation) { |
| 22 | - | 22 | + newMappingFields := make([]*domain.MappingField, 0) |
| 23 | + for i := range cmd.MappingFields { | ||
| 24 | + if len(cmd.MappingFields[i].VerifiedFileFieldName) == 0 { | ||
| 25 | + continue | ||
| 26 | + } | ||
| 27 | + newMappingFields = append(newMappingFields, cmd.MappingFields[i]) | ||
| 28 | + } | ||
| 29 | + cmd.MappingFields = newMappingFields | ||
| 23 | } | 30 | } |
| 24 | 31 | ||
| 25 | func (cmd *AppendDataToTableCommand) ValidateCommand() error { | 32 | func (cmd *AppendDataToTableCommand) ValidateCommand() error { |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "reflect" | ||
| 6 | + "strings" | ||
| 7 | + | ||
| 8 | + "github.com/beego/beego/v2/core/validation" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type CheckFileVerifyStatusCommand struct { | ||
| 12 | + // 文件ID | ||
| 13 | + FileId int `cname:"文件ID" json:"objectId" valid:"Required"` | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +func (cmd *CheckFileVerifyStatusCommand) Valid(validation *validation.Validation) { | ||
| 17 | + | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +func (cmd *CheckFileVerifyStatusCommand) ValidateCommand() error { | ||
| 21 | + valid := validation.Validation{} | ||
| 22 | + b, err := valid.Valid(cmd) | ||
| 23 | + if err != nil { | ||
| 24 | + return err | ||
| 25 | + } | ||
| 26 | + if !b { | ||
| 27 | + elem := reflect.TypeOf(cmd).Elem() | ||
| 28 | + for _, validErr := range valid.Errors { | ||
| 29 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 30 | + if isExist { | ||
| 31 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 32 | + } else { | ||
| 33 | + return fmt.Errorf(validErr.Message) | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + } | ||
| 37 | + return nil | ||
| 38 | +} |
| @@ -17,14 +17,37 @@ type CreateFileCommand struct { | @@ -17,14 +17,37 @@ type CreateFileCommand struct { | ||
| 17 | Url string `cname:"文件地址" json:"url" valid:"Required"` | 17 | Url string `cname:"文件地址" json:"url" valid:"Required"` |
| 18 | // 文件大小 单位KB | 18 | // 文件大小 单位KB |
| 19 | FileSize int `cname:"文件大小" json:"fileSize" valid:"Required"` | 19 | FileSize int `cname:"文件大小" json:"fileSize" valid:"Required"` |
| 20 | + // 文件来源 | ||
| 21 | + FileFrom string `json:"-"` | ||
| 22 | + // AppKey | ||
| 23 | + AppKey string `json:"-"` | ||
| 24 | + | ||
| 25 | + // 生成表标识 true:实例化一个表 false:跳过 | ||
| 26 | + GenerateTableFlag bool `json:"-"` | ||
| 27 | + // name 字段中文名 | ||
| 28 | + Fields []*domain.Field `json:"-"` | ||
| 20 | } | 29 | } |
| 21 | 30 | ||
| 31 | +var MaxFileSize = 50 * 1024 * 1024 | ||
| 32 | + | ||
| 22 | func (createFileCommand *CreateFileCommand) Valid(validation *validation.Validation) { | 33 | func (createFileCommand *CreateFileCommand) Valid(validation *validation.Validation) { |
| 23 | ext := filepath.Ext(createFileCommand.Name) | 34 | ext := filepath.Ext(createFileCommand.Name) |
| 24 | if !(ext == domain.XLS || ext == domain.XLSX) { | 35 | if !(ext == domain.XLS || ext == domain.XLSX) { |
| 25 | - validation.Error(fmt.Sprintf("仅支持文件格式 xls 、 xlsx")) | 36 | + validation.Error("仅支持文件格式 xls 、 xlsx") |
| 37 | + return | ||
| 38 | + } | ||
| 39 | + if createFileCommand.FileSize > 0 && createFileCommand.FileSize > MaxFileSize { | ||
| 40 | + validation.Error("文件大小超过50M") | ||
| 26 | return | 41 | return |
| 27 | } | 42 | } |
| 43 | + if createFileCommand.GenerateTableFlag { | ||
| 44 | + for _, f := range createFileCommand.Fields { | ||
| 45 | + if err := f.Valid(); err != nil { | ||
| 46 | + validation.Error(err.Error()) | ||
| 47 | + return | ||
| 48 | + } | ||
| 49 | + } | ||
| 50 | + } | ||
| 28 | } | 51 | } |
| 29 | 52 | ||
| 30 | func (createFileCommand *CreateFileCommand) ValidateCommand() error { | 53 | func (createFileCommand *CreateFileCommand) ValidateCommand() error { |
| @@ -15,10 +15,11 @@ type EditDataTableCommand struct { | @@ -15,10 +15,11 @@ type EditDataTableCommand struct { | ||
| 15 | // | 15 | // |
| 16 | //Fields []*domain.Field | 16 | //Fields []*domain.Field |
| 17 | domain.EditTableRequest | 17 | domain.EditTableRequest |
| 18 | + HeaderRow int `json:"headerRow"` // 行号 默认:0 | ||
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | func (editDataTableCommand *EditDataTableCommand) Valid(validation *validation.Validation) { | 21 | func (editDataTableCommand *EditDataTableCommand) Valid(validation *validation.Validation) { |
| 21 | - if len(editDataTableCommand.ProcessFields) == 0 { | 22 | + if len(editDataTableCommand.ProcessFieldNames) == 0 { |
| 22 | validation.Error("未选择操作列") | 23 | validation.Error("未选择操作列") |
| 23 | return | 24 | return |
| 24 | } | 25 | } |
| @@ -30,6 +31,7 @@ func (editDataTableCommand *EditDataTableCommand) Valid(validation *validation.V | @@ -30,6 +31,7 @@ func (editDataTableCommand *EditDataTableCommand) Valid(validation *validation.V | ||
| 30 | validation.Error("文件ID不能为空") | 31 | validation.Error("文件ID不能为空") |
| 31 | return | 32 | return |
| 32 | } | 33 | } |
| 34 | + editDataTableCommand.Where.HeaderRow = domain.SetHeaderRow(editDataTableCommand.HeaderRow) | ||
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | func (editDataTableCommand *EditDataTableCommand) ValidateCommand() error { | 37 | func (editDataTableCommand *EditDataTableCommand) ValidateCommand() error { |
pkg/application/file/command/export_file.go
0 → 100644
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "reflect" | ||
| 6 | + "strings" | ||
| 7 | + | ||
| 8 | + "github.com/beego/beego/v2/core/validation" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type ExportFileCommand struct { | ||
| 12 | + // 文件ID | ||
| 13 | + FileId int `cname:"文件ID" json:"fileId" valid:"Required"` | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +func (cmd *ExportFileCommand) Valid(validation *validation.Validation) { | ||
| 17 | + | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +func (cmd *ExportFileCommand) ValidateCommand() error { | ||
| 21 | + valid := validation.Validation{} | ||
| 22 | + b, err := valid.Valid(cmd) | ||
| 23 | + if err != nil { | ||
| 24 | + return err | ||
| 25 | + } | ||
| 26 | + if !b { | ||
| 27 | + elem := reflect.TypeOf(cmd).Elem() | ||
| 28 | + for _, validErr := range valid.Errors { | ||
| 29 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 30 | + if isExist { | ||
| 31 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 32 | + } else { | ||
| 33 | + return fmt.Errorf(validErr.Message) | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + } | ||
| 37 | + return nil | ||
| 38 | +} |
| @@ -2,7 +2,6 @@ package command | @@ -2,7 +2,6 @@ package command | ||
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "fmt" | 4 | "fmt" |
| 5 | - "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 6 | "reflect" | 5 | "reflect" |
| 7 | "strings" | 6 | "strings" |
| 8 | 7 | ||
| @@ -11,11 +10,11 @@ import ( | @@ -11,11 +10,11 @@ import ( | ||
| 11 | 10 | ||
| 12 | type FlushDataTableCommand struct { | 11 | type FlushDataTableCommand struct { |
| 13 | // 文件ID | 12 | // 文件ID |
| 14 | - FileId int `cname:"文件ID" json:"objectId" valid:"Required"` | 13 | + ObjectId int `cname:"文件ID" json:"objectId" valid:"Required"` |
| 15 | // 记录数 | 14 | // 记录数 |
| 16 | - RowCount int `cname:"记录数" json:"rowCount" valid:"Required"` | 15 | + //RowCount int `cname:"记录数" json:"rowCount" valid:"Required"` |
| 17 | // 数据列 | 16 | // 数据列 |
| 18 | - DataFields []*domain.Field `cname:"数据列" json:"fields" valid:"Required"` | 17 | + //DataFields []*domain.Field `cname:"数据列" json:"fields" valid:"Required"` |
| 19 | } | 18 | } |
| 20 | 19 | ||
| 21 | func (flushDataTableCommand *FlushDataTableCommand) Valid(validation *validation.Validation) { | 20 | func (flushDataTableCommand *FlushDataTableCommand) Valid(validation *validation.Validation) { |
| @@ -23,6 +23,7 @@ func (loadDataTableCommand *LoadDataTableCommand) Valid(validation *validation.V | @@ -23,6 +23,7 @@ func (loadDataTableCommand *LoadDataTableCommand) Valid(validation *validation.V | ||
| 23 | if loadDataTableCommand.PageSize == 0 { | 23 | if loadDataTableCommand.PageSize == 0 { |
| 24 | loadDataTableCommand.PageSize = 20 | 24 | loadDataTableCommand.PageSize = 20 |
| 25 | } | 25 | } |
| 26 | + loadDataTableCommand.HeaderRow = domain.SetHeaderRow(loadDataTableCommand.HeaderRow) | ||
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | func (loadDataTableCommand *LoadDataTableCommand) ValidateCommand() error { | 29 | func (loadDataTableCommand *LoadDataTableCommand) ValidateCommand() error { |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "reflect" | ||
| 6 | + "strings" | ||
| 7 | + | ||
| 8 | + "github.com/beego/beego/v2/core/validation" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type PrepareTemporaryFileCommand struct { | ||
| 12 | + // 文件ID | ||
| 13 | + FileId int `cname:"文件ID" json:"fileId" valid:"Required"` | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +func (cmd *PrepareTemporaryFileCommand) Valid(validation *validation.Validation) { | ||
| 17 | + | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +func (cmd *PrepareTemporaryFileCommand) ValidateCommand() error { | ||
| 21 | + valid := validation.Validation{} | ||
| 22 | + b, err := valid.Valid(cmd) | ||
| 23 | + if err != nil { | ||
| 24 | + return err | ||
| 25 | + } | ||
| 26 | + if !b { | ||
| 27 | + elem := reflect.TypeOf(cmd).Elem() | ||
| 28 | + for _, validErr := range valid.Errors { | ||
| 29 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 30 | + if isExist { | ||
| 31 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 32 | + } else { | ||
| 33 | + return fmt.Errorf(validErr.Message) | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + } | ||
| 37 | + return nil | ||
| 38 | +} |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 6 | + "reflect" | ||
| 7 | + "strings" | ||
| 8 | + | ||
| 9 | + "github.com/beego/beego/v2/core/validation" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +type ResetTableHeaderCommand struct { | ||
| 13 | + // 文件ID | ||
| 14 | + FileId int `cname:"文件ID" json:"objectId" valid:"Required"` | ||
| 15 | + domain.Where | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +func (loadDataTableCommand *ResetTableHeaderCommand) Valid(validation *validation.Validation) { | ||
| 19 | + loadDataTableCommand.HeaderRow = domain.SetHeaderRow(loadDataTableCommand.HeaderRow) | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +func (loadDataTableCommand *ResetTableHeaderCommand) ValidateCommand() error { | ||
| 23 | + valid := validation.Validation{} | ||
| 24 | + b, err := valid.Valid(loadDataTableCommand) | ||
| 25 | + if err != nil { | ||
| 26 | + return err | ||
| 27 | + } | ||
| 28 | + if !b { | ||
| 29 | + elem := reflect.TypeOf(loadDataTableCommand).Elem() | ||
| 30 | + for _, validErr := range valid.Errors { | ||
| 31 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 32 | + if isExist { | ||
| 33 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 34 | + } else { | ||
| 35 | + return fmt.Errorf(validErr.Message) | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + return nil | ||
| 40 | +} |
| 1 | +package dto | ||
| 2 | + | ||
| 3 | +import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 4 | + | ||
| 5 | +type EditDataTableDto struct { | ||
| 6 | + Code int `json:"errNo,omitempty"` | ||
| 7 | + Error string `json:"errMsg,omitempty"` | ||
| 8 | + InValidCells []domain.InValidCell `json:"inValidCells,omitempty"` | ||
| 9 | +} | ||
| 10 | + | ||
| 11 | +func (d *EditDataTableDto) Load(m *domain.DataEditDataTable) *EditDataTableDto { | ||
| 12 | + d.Error = "" | ||
| 13 | + if len(m.InValidCells) > 0 { | ||
| 14 | + d.Error = "类型转换错误" | ||
| 15 | + d.Code = 1001 // 1001:类型转换错误 | ||
| 16 | + } | ||
| 17 | + //d.InValidCells = m.InValidCells | ||
| 18 | + return d | ||
| 19 | +} |
| @@ -14,14 +14,77 @@ type FileDto struct { | @@ -14,14 +14,77 @@ type FileDto struct { | ||
| 14 | Url string `json:"url"` | 14 | Url string `json:"url"` |
| 15 | // 文件类型 | 15 | // 文件类型 |
| 16 | FileType string `json:"fileType"` | 16 | FileType string `json:"fileType"` |
| 17 | + // 后缀扩展 | ||
| 18 | + Ext string `json:"ext"` | ||
| 17 | // 创建时间 | 19 | // 创建时间 |
| 18 | Time string `json:"time"` | 20 | Time string `json:"time"` |
| 21 | + // 行号 | ||
| 22 | + HeaderRow int `json:"headerRow"` | ||
| 23 | + // 所属应用 | ||
| 24 | + AppKey string `json:"appKey"` | ||
| 25 | + // 表ID | ||
| 26 | + TableId int `json:"tableId"` | ||
| 27 | + // 允许表生成标识 1:允许生成分表 0:不允许 | ||
| 28 | + AllowTableGenerateFlag int `json:"-"` | ||
| 29 | + // 允许表处理标识 1:允许 0:不允许 | ||
| 30 | + AllowTableProcessFlag int `json:"-"` | ||
| 31 | + // 允许表导出标识 1:允许 0:不允许 | ||
| 32 | + AllowTableExportFlag int `json:"-"` | ||
| 33 | + // 标志位 1:可校验 2:可分表生成 4:导出 | ||
| 34 | + Flag int `json:"-"` | ||
| 35 | + // 标志位 1:可校验 2:可分表生成 4:导出 | ||
| 36 | + Flags []int `json:"flags"` | ||
| 19 | } | 37 | } |
| 20 | 38 | ||
| 21 | -func (d *FileDto) Load(f *domain.File) { | 39 | +func (d *FileDto) Load(f *domain.File) *FileDto { |
| 40 | + if f == nil { | ||
| 41 | + return nil | ||
| 42 | + } | ||
| 22 | d.FileId = f.FileId | 43 | d.FileId = f.FileId |
| 23 | d.Name = f.FileInfo.Name | 44 | d.Name = f.FileInfo.Name |
| 24 | d.Url = f.FileInfo.Url | 45 | d.Url = f.FileInfo.Url |
| 25 | d.FileType = f.FileType | 46 | d.FileType = f.FileType |
| 26 | - d.Time = xtime.New(f.CreatedAt).Local().Format("2006-01-02 15:04:05") | 47 | + d.Ext = f.FileInfo.Ext |
| 48 | + d.Time = xtime.New(f.UpdatedAt).Local().Format("2006-01-02 15:04:05") | ||
| 49 | + d.HeaderRow = domain.GetHeaderRow(f.FileInfo.HeaderRow) | ||
| 50 | + d.AppKey = f.AppKey | ||
| 51 | + //d.AllowTableProcessFlag = 1 | ||
| 52 | + //d.AllowTableExportFlag = 1 | ||
| 53 | + d.AddFlag(5) // 默认可以 校验、导出 | ||
| 54 | + if len(f.AppKey) > 0 && f.FileInfo.TableId > 0 { | ||
| 55 | + d.TableId = f.FileInfo.TableId | ||
| 56 | + //d.AllowTableGenerateFlag = 1 | ||
| 57 | + d.AddFlag(2) // 可分表生成 | ||
| 58 | + d.RemoveFlag(1) // 不可校验 | ||
| 59 | + //d.RemoveFlag(4) // 不可校验 | ||
| 60 | + //d.AllowTableProcessFlag = 0 | ||
| 61 | + //d.AllowTableExportFlag = 0 | ||
| 62 | + } | ||
| 63 | + for i := 1; i <= 4; i = i << 1 { | ||
| 64 | + if i&d.Flag == i { | ||
| 65 | + d.Flags = append(d.Flags, i) | ||
| 66 | + } | ||
| 67 | + } | ||
| 68 | + return d | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +func (d *FileDto) AddFlag(flag int) { | ||
| 72 | + if d.Flag&flag == flag { | ||
| 73 | + return | ||
| 74 | + } | ||
| 75 | + d.Flag |= flag | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | +func (d *FileDto) RemoveFlag(flag int) { | ||
| 79 | + if d.Flag&flag != flag { | ||
| 80 | + return | ||
| 81 | + } | ||
| 82 | + d.Flag ^= flag | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +type AppDto struct { | ||
| 86 | + AppId int64 `json:"appId"` | ||
| 87 | + AppKey string `json:"appKey"` | ||
| 88 | + AppName string `json:"appName"` | ||
| 89 | + Files []*FileDto `json:"files"` | ||
| 27 | } | 90 | } |
| @@ -10,11 +10,15 @@ import ( | @@ -10,11 +10,15 @@ import ( | ||
| 10 | 10 | ||
| 11 | type GetFileQuery struct { | 11 | type GetFileQuery struct { |
| 12 | // 文件ID | 12 | // 文件ID |
| 13 | - FileId int `cname:"文件ID" json:"fileId" valid:"Required"` | 13 | + FileId int `cname:"文件ID" json:"fileId"` |
| 14 | + | ||
| 15 | + FileName string `json:"name"` | ||
| 16 | + | ||
| 17 | + FileType string `json:"type"` | ||
| 14 | } | 18 | } |
| 15 | 19 | ||
| 16 | func (getFileQuery *GetFileQuery) Valid(validation *validation.Validation) { | 20 | func (getFileQuery *GetFileQuery) Valid(validation *validation.Validation) { |
| 17 | - validation.SetError("CustomValid", "未实现的自定义认证") | 21 | + |
| 18 | } | 22 | } |
| 19 | 23 | ||
| 20 | func (getFileQuery *GetFileQuery) ValidateQuery() error { | 24 | func (getFileQuery *GetFileQuery) ValidateQuery() error { |
| @@ -21,6 +21,7 @@ type SearchFileQuery struct { | @@ -21,6 +21,7 @@ type SearchFileQuery struct { | ||
| 21 | PageSize int `cname:"页数" json:"pageSize,omitempty"` | 21 | PageSize int `cname:"页数" json:"pageSize,omitempty"` |
| 22 | LastId int `cname:"最后一条记录ID" json:"lastId"` | 22 | LastId int `cname:"最后一条记录ID" json:"lastId"` |
| 23 | FileType domain.FileType `cname:"文件类型" json:"fileType" valid:"Required"` | 23 | FileType domain.FileType `cname:"文件类型" json:"fileType" valid:"Required"` |
| 24 | + InAppKeys []string `json:"inAppKeys"` | ||
| 24 | Context *domain.Context | 25 | Context *domain.Context |
| 25 | } | 26 | } |
| 26 | 27 |
| 1 | +package service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "bytes" | ||
| 5 | + "errors" | ||
| 6 | + "fmt" | ||
| 7 | + "github.com/beego/beego/v2/client/httplib" | ||
| 8 | + "github.com/linmadan/egglib-go/core/application" | ||
| 9 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 10 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | ||
| 11 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/command" | ||
| 12 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/query" | ||
| 13 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" | ||
| 14 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 15 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/api/apilib" | ||
| 16 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" | ||
| 17 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/excel" | ||
| 18 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" | ||
| 19 | + "os" | ||
| 20 | + "strings" | ||
| 21 | + "time" | ||
| 22 | +) | ||
| 23 | + | ||
| 24 | +func (fileService *FileService) CreateAppTableFile(ctx *domain.Context, cmd *command.CreateAppTableFileCommand) (*command.CreateFileCommand, error) { | ||
| 25 | + response := &command.CreateFileCommand{} | ||
| 26 | + var ( | ||
| 27 | + titles = make([]string, 0) | ||
| 28 | + dataList = make([][]string, 0) | ||
| 29 | + ) | ||
| 30 | + for _, filed := range cmd.Fields { | ||
| 31 | + titles = append(titles, filed.Name) | ||
| 32 | + } | ||
| 33 | + for i := range cmd.Data { | ||
| 34 | + row := make([]string, 0) | ||
| 35 | + for _, filed := range titles { | ||
| 36 | + if v, ok := cmd.Data[i][filed]; ok { | ||
| 37 | + row = append(row, v) | ||
| 38 | + } else { | ||
| 39 | + row = append(row, "") | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | + dataList = append(dataList, row) | ||
| 43 | + } | ||
| 44 | + fileUpload, err := saveFile(cmd.Name, titles, dataList, nil) | ||
| 45 | + if err != nil { | ||
| 46 | + return nil, factory.FastError(err) | ||
| 47 | + } | ||
| 48 | + response.Name = cmd.Name | ||
| 49 | + if !strings.HasSuffix(response.Name, domain.XLSX) { | ||
| 50 | + response.Name = response.Name + domain.XLSX | ||
| 51 | + } | ||
| 52 | + response.Url = fileUpload.Url | ||
| 53 | + response.FileSize = int(fileUpload.FileSize) | ||
| 54 | + response.FileFrom = domain.FileFromDigitalAppClient | ||
| 55 | + return response, nil | ||
| 56 | +} | ||
| 57 | + | ||
| 58 | +func saveFile(name string, title []string, dataList [][]string, toInterfaces func([]string) []interface{}) (FileUpload, error) { | ||
| 59 | + var ( | ||
| 60 | + response = FileUpload{} | ||
| 61 | + err error | ||
| 62 | + ) | ||
| 63 | + var writerTo = excel.NewXLXSWriterTo(title, dataList) | ||
| 64 | + if toInterfaces != nil { | ||
| 65 | + writerTo.ToInterfaces = toInterfaces | ||
| 66 | + } | ||
| 67 | + filename := fmt.Sprintf("%v_%v.xlsx", name, time.Now().Format("060102150405")) | ||
| 68 | + path := fmt.Sprintf("public/%v", filename) | ||
| 69 | + if err = writerTo.Save(path); err != nil { | ||
| 70 | + return response, factory.FastError(err) | ||
| 71 | + } | ||
| 72 | + api := apilib.NewApiAuthLib(constant.OPEN_API_HOST) | ||
| 73 | + uploadResponse, err := api.Upload(apilib.RequestUpload{ | ||
| 74 | + UploadFileMap: map[string]string{"file": path}, | ||
| 75 | + }) | ||
| 76 | + if err != nil { | ||
| 77 | + return response, err | ||
| 78 | + } | ||
| 79 | + if stat, err := os.Stat(path); err == nil { | ||
| 80 | + response.FileSize = stat.Size() | ||
| 81 | + } | ||
| 82 | + response.Url = domain.ConvertInternalFileUrlToPublic(uploadResponse.Path) | ||
| 83 | + response.FileName = name | ||
| 84 | + response.Ext = domain.XLSX | ||
| 85 | + | ||
| 86 | + return response, nil | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +func saveCsvFile(name string, title []string, dataList [][]string, toInterfaces func([]string) []interface{}) (FileUpload, error) { | ||
| 90 | + var ( | ||
| 91 | + response = FileUpload{} | ||
| 92 | + err error | ||
| 93 | + ) | ||
| 94 | + var writerTo = excel.NewCSVWriterTo(title, dataList) | ||
| 95 | + filename := fmt.Sprintf("%v_%v.csv", name, time.Now().Format("060102150405")) | ||
| 96 | + path := fmt.Sprintf("public/%v", filename) | ||
| 97 | + if err = writerTo.Save(path); err != nil { | ||
| 98 | + return response, factory.FastError(err) | ||
| 99 | + } | ||
| 100 | + api := apilib.NewApiAuthLib(constant.OPEN_API_HOST) | ||
| 101 | + uploadResponse, err := api.Upload(apilib.RequestUpload{ | ||
| 102 | + UploadFileMap: map[string]string{"file": path}, | ||
| 103 | + }) | ||
| 104 | + if err != nil { | ||
| 105 | + return response, err | ||
| 106 | + } | ||
| 107 | + if stat, err := os.Stat(path); err == nil { | ||
| 108 | + response.FileSize = stat.Size() | ||
| 109 | + } | ||
| 110 | + response.Url = domain.ConvertInternalFileUrlToPublic(uploadResponse.Path) | ||
| 111 | + response.FileName = name | ||
| 112 | + response.Ext = domain.CSV | ||
| 113 | + | ||
| 114 | + return response, nil | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +type FileUpload struct { | ||
| 118 | + Url string `json:"url"` | ||
| 119 | + Ext string `json:"ext"` | ||
| 120 | + FileName string `json:"fileName"` | ||
| 121 | + FileSize int64 `json:"fileSize"` | ||
| 122 | +} | ||
| 123 | + | ||
| 124 | +func (fileService *FileService) DeleteAppTableFile(ctx *domain.Context, cmd *command.DeleteAppTableFileCommand) (interface{}, error) { | ||
| 125 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 126 | + if err != nil { | ||
| 127 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 128 | + } | ||
| 129 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 130 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 131 | + } | ||
| 132 | + defer func() { | ||
| 133 | + transactionContext.RollbackTransaction() | ||
| 134 | + }() | ||
| 135 | + | ||
| 136 | + fileRepository, file, _ := factory.FastPgFile(transactionContext, 0) | ||
| 137 | + file, err = fileRepository.FindOne(map[string]interface{}{"appKey": cmd.AppKey, "fileName": cmd.Name, "fileType": domain.SourceFile}) | ||
| 138 | + if err == domain.ErrorNotFound { | ||
| 139 | + return nil, factory.FastError(errors.New("文件不存在")) | ||
| 140 | + } | ||
| 141 | + if err != nil { | ||
| 142 | + return nil, factory.FastError(err) | ||
| 143 | + } | ||
| 144 | + if _, err := fileRepository.Remove(file); err != nil { | ||
| 145 | + return nil, factory.FastError(err) | ||
| 146 | + } | ||
| 147 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 148 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 149 | + } | ||
| 150 | + return struct{}{}, nil | ||
| 151 | +} | ||
| 152 | + | ||
| 153 | +func (fileService *FileService) AppTableFileAppendData(ctx *domain.Context, cmd *command.AppTableFileAppendDataCommand) (interface{}, error) { | ||
| 154 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 155 | + if err != nil { | ||
| 156 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 157 | + } | ||
| 158 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 159 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 160 | + } | ||
| 161 | + defer func() { | ||
| 162 | + transactionContext.RollbackTransaction() | ||
| 163 | + }() | ||
| 164 | + | ||
| 165 | + fileRepository, file, _ := factory.FastPgFile(transactionContext, 0) | ||
| 166 | + file, err = fileRepository.FindOne(map[string]interface{}{"appKey": cmd.AppKey, "fileName": cmd.Name, "fileType": domain.SourceFile}) | ||
| 167 | + if err == domain.ErrorNotFound { | ||
| 168 | + return nil, factory.FastError(errors.New("文件不存在")) | ||
| 169 | + } | ||
| 170 | + if err != nil { | ||
| 171 | + return nil, factory.FastError(err) | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + // 下载文件 | ||
| 175 | + f, err := httplib.Get(domain.ConvertFileUrlToInternal(file.FileInfo.Url)).Bytes() | ||
| 176 | + if err != nil { | ||
| 177 | + return nil, factory.FastError(err) | ||
| 178 | + } | ||
| 179 | + reader := bytes.NewReader(f) | ||
| 180 | + var ( | ||
| 181 | + importer *excel.Importer = excel.NewExcelImportByFile(file.FileInfo.Ext) | ||
| 182 | + appendTableDataList = make([][]string, 0) | ||
| 183 | + ) | ||
| 184 | + data, err := importer.OpenExcelFromIoReader(reader) | ||
| 185 | + if err != nil { | ||
| 186 | + return nil, factory.FastError(err) | ||
| 187 | + } | ||
| 188 | + titles := importer.Reader().Header().Columns | ||
| 189 | + for _, f := range cmd.Fields { | ||
| 190 | + found := false | ||
| 191 | + for _, column := range titles { | ||
| 192 | + if column == f.Name { | ||
| 193 | + found = true | ||
| 194 | + break | ||
| 195 | + } | ||
| 196 | + } | ||
| 197 | + if !found { | ||
| 198 | + titles = append(titles, f.Name) | ||
| 199 | + } | ||
| 200 | + } | ||
| 201 | + // 填充旧数据 | ||
| 202 | + // 追加文件 | ||
| 203 | + for i := range data { | ||
| 204 | + if len(data[i]) < len(titles) { | ||
| 205 | + for j := 0; j < (len(titles) - len(data[i])); j++ { | ||
| 206 | + data[i] = append(data[i], "") | ||
| 207 | + } | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | + for i := range cmd.Data { | ||
| 211 | + row := make([]string, 0) | ||
| 212 | + for _, filed := range titles { | ||
| 213 | + if v, ok := cmd.Data[i][filed]; ok { | ||
| 214 | + row = append(row, v) | ||
| 215 | + } else { | ||
| 216 | + row = append(row, "") | ||
| 217 | + } | ||
| 218 | + } | ||
| 219 | + data = append(data, row) | ||
| 220 | + if cmd.AppendTableDataFlag { | ||
| 221 | + appendTableDataList = append(appendTableDataList, row) | ||
| 222 | + } | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + //if !cmd.AppendTableDataFlag { | ||
| 226 | + // 上传文件 | ||
| 227 | + fileUpload, err := saveFile(cmd.Name, titles, data, nil) | ||
| 228 | + if err != nil { | ||
| 229 | + return nil, factory.FastError(err) | ||
| 230 | + } | ||
| 231 | + // 更新文件 | ||
| 232 | + file.FileInfo.Url = fileUpload.Url | ||
| 233 | + file.FileInfo.FileSize = int(fileUpload.FileSize) | ||
| 234 | + file.FileInfo.RowCount = len(data) | ||
| 235 | + _, err = fileRepository.Save(file) | ||
| 236 | + if err != nil { | ||
| 237 | + return nil, factory.FastError(err) | ||
| 238 | + } | ||
| 239 | + //} | ||
| 240 | + //else if cmd.AppendTableDataFlag && file.FileInfo.TableId != 0 { // 追加数据到应用表 | ||
| 241 | + //var table *domain.Table | ||
| 242 | + //if _, table, err = factory.FastPgTable(transactionContext, file.FileInfo.TableId); err != nil { | ||
| 243 | + // return nil, factory.FastError(err) | ||
| 244 | + //} | ||
| 245 | + //// 上传文件 | ||
| 246 | + //fileUpload, err := saveCsvFile(cmd.Name, titles, appendTableDataList, nil) | ||
| 247 | + //if err != nil { | ||
| 248 | + // return nil, factory.FastError(err) | ||
| 249 | + //} | ||
| 250 | + //appendDataToTableService, _ := domainService.NewAppendDataToTableService(transactionContext.(*pgTransaction.TransactionContext)) | ||
| 251 | + //var mappingFields = make([]*domain.MappingField, 0) | ||
| 252 | + //for _, f := range cmd.Fields { | ||
| 253 | + // mappingFields = append(mappingFields, &domain.MappingField{ | ||
| 254 | + // MainTableField: &domain.Field{Name: f.Name}, | ||
| 255 | + // VerifiedFileFieldName: f.Name, | ||
| 256 | + // }) | ||
| 257 | + //} | ||
| 258 | + //if _, err = appendDataToTableService.AppendDataDirectly(ctx, fileUpload.Url, table, mappingFields); err != nil { | ||
| 259 | + // return nil, factory.FastError(err) | ||
| 260 | + //} | ||
| 261 | + //} | ||
| 262 | + | ||
| 263 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 264 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 265 | + } | ||
| 266 | + return struct{}{}, nil | ||
| 267 | +} | ||
| 268 | + | ||
| 269 | +func (fileService *FileService) AppTableAppendData(ctx *domain.Context, cmd *command.AppTableFileAppendDataCommand) (interface{}, error) { | ||
| 270 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 271 | + if err != nil { | ||
| 272 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 273 | + } | ||
| 274 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 275 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 276 | + } | ||
| 277 | + defer func() { | ||
| 278 | + transactionContext.RollbackTransaction() | ||
| 279 | + }() | ||
| 280 | + | ||
| 281 | + fileRepository, file, _ := factory.FastPgFile(transactionContext, 0) | ||
| 282 | + file, err = fileRepository.FindOne(map[string]interface{}{"appKey": cmd.AppKey, "fileName": cmd.Name, "fileType": domain.SourceFile}) | ||
| 283 | + if err == domain.ErrorNotFound { | ||
| 284 | + return nil, factory.FastError(errors.New("文件不存在")) | ||
| 285 | + } | ||
| 286 | + if err != nil { | ||
| 287 | + return nil, factory.FastError(err) | ||
| 288 | + } | ||
| 289 | + if file.FileInfo.TableId == 0 { | ||
| 290 | + return nil, factory.FastError(errors.New("表不存在")) | ||
| 291 | + } | ||
| 292 | + var ( | ||
| 293 | + appendTableDataList = make([][]string, 0) | ||
| 294 | + titles = make([]string, 0) | ||
| 295 | + table *domain.Table | ||
| 296 | + ) | ||
| 297 | + _, table, err = factory.FastPgTable(transactionContext, file.FileInfo.TableId) | ||
| 298 | + if err != nil { | ||
| 299 | + return nil, factory.FastError(err) | ||
| 300 | + } | ||
| 301 | + for _, f := range table.Fields(false) { | ||
| 302 | + titles = append(titles, f.Name) | ||
| 303 | + } | ||
| 304 | + for _, f := range cmd.Fields { | ||
| 305 | + found := false | ||
| 306 | + for _, column := range titles { | ||
| 307 | + if column == f.Name { | ||
| 308 | + found = true | ||
| 309 | + break | ||
| 310 | + } | ||
| 311 | + } | ||
| 312 | + if !found { | ||
| 313 | + titles = append(titles, f.Name) | ||
| 314 | + } | ||
| 315 | + } | ||
| 316 | + for i := range cmd.Data { | ||
| 317 | + row := make([]string, 0) | ||
| 318 | + for _, filed := range titles { | ||
| 319 | + if v, ok := cmd.Data[i][filed]; ok { | ||
| 320 | + row = append(row, v) | ||
| 321 | + } else { | ||
| 322 | + row = append(row, "") | ||
| 323 | + } | ||
| 324 | + } | ||
| 325 | + appendTableDataList = append(appendTableDataList, row) | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + // 上传文件 | ||
| 329 | + fileUpload, err := saveCsvFile(cmd.Name, titles, appendTableDataList, nil) | ||
| 330 | + if err != nil { | ||
| 331 | + return nil, factory.FastError(err) | ||
| 332 | + } | ||
| 333 | + appendDataToTableService, _ := domainService.NewAppendDataToTableService(transactionContext.(*pgTransaction.TransactionContext)) | ||
| 334 | + var mappingFields = make([]*domain.MappingField, 0) | ||
| 335 | + for _, f := range cmd.Fields { | ||
| 336 | + mappingFields = append(mappingFields, &domain.MappingField{ | ||
| 337 | + MainTableField: &domain.Field{Name: f.Name}, | ||
| 338 | + VerifiedFileFieldName: f.Name, | ||
| 339 | + }) | ||
| 340 | + } | ||
| 341 | + if _, err = appendDataToTableService.AppendDataDirectly(ctx, fileUpload.Url, table, mappingFields); err != nil { | ||
| 342 | + return nil, factory.FastError(err) | ||
| 343 | + } | ||
| 344 | + | ||
| 345 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 346 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 347 | + } | ||
| 348 | + return struct{}{}, nil | ||
| 349 | +} | ||
| 350 | + | ||
| 351 | +func (fileService *FileService) AppTableAppendDataDirect(ctx *domain.Context, cmd *command.AppTableFileAppendDataCommand) (interface{}, error) { | ||
| 352 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 353 | + if err != nil { | ||
| 354 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 355 | + } | ||
| 356 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 357 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 358 | + } | ||
| 359 | + defer func() { | ||
| 360 | + transactionContext.RollbackTransaction() | ||
| 361 | + }() | ||
| 362 | + | ||
| 363 | + fileRepository, file, _ := factory.FastPgFile(transactionContext, 0) | ||
| 364 | + file, err = fileRepository.FindOne(map[string]interface{}{"appKey": cmd.AppKey, "fileName": cmd.Name, "fileType": domain.SourceFile}) | ||
| 365 | + if err == domain.ErrorNotFound { | ||
| 366 | + return nil, factory.FastError(errors.New("文件不存在")) | ||
| 367 | + } | ||
| 368 | + if err != nil { | ||
| 369 | + return nil, factory.FastError(err) | ||
| 370 | + } | ||
| 371 | + if file.FileInfo.TableId == 0 { | ||
| 372 | + return nil, factory.FastError(errors.New("表不存在")) | ||
| 373 | + } | ||
| 374 | + var ( | ||
| 375 | + titles = make([]string, 0) | ||
| 376 | + table *domain.Table | ||
| 377 | + ) | ||
| 378 | + _, table, err = factory.FastPgTable(transactionContext, file.FileInfo.TableId) | ||
| 379 | + if err != nil { | ||
| 380 | + return nil, factory.FastError(err) | ||
| 381 | + } | ||
| 382 | + for _, f := range table.Fields(false) { | ||
| 383 | + titles = append(titles, f.Name) | ||
| 384 | + } | ||
| 385 | + mapNameField := domain.Fields(table.Fields(false)).ToMap() | ||
| 386 | + for _, f := range cmd.Fields { | ||
| 387 | + found := false | ||
| 388 | + for _, column := range titles { | ||
| 389 | + if column == f.Name { | ||
| 390 | + found = true | ||
| 391 | + break | ||
| 392 | + } | ||
| 393 | + } | ||
| 394 | + if !found { | ||
| 395 | + titles = append(titles, f.Name) | ||
| 396 | + } | ||
| 397 | + } | ||
| 398 | + var mapData = make([]map[string]string, 0) | ||
| 399 | + for i := range cmd.Data { | ||
| 400 | + mapItem := make(map[string]string) | ||
| 401 | + for k, v := range cmd.Data[i] { | ||
| 402 | + if f, ok := mapNameField[k]; ok { | ||
| 403 | + mapItem[f.SQLName] = v | ||
| 404 | + } | ||
| 405 | + } | ||
| 406 | + mapData = append(mapData, mapItem) | ||
| 407 | + } | ||
| 408 | + editDataService, _ := factory.CreateTableEditDataService(transactionContext) | ||
| 409 | + _, err = editDataService.BatchAdd(ctx, domain.EditDataRequest{ | ||
| 410 | + TableId: table.TableId, | ||
| 411 | + Table: table, | ||
| 412 | + Where: domain.Where{}, | ||
| 413 | + UpdateList: nil, | ||
| 414 | + AddList: domainService.MapArrayToFieldValues(mapData, table, nil, false), | ||
| 415 | + RemoveList: nil, | ||
| 416 | + IgnoreTableType: true, | ||
| 417 | + }) | ||
| 418 | + if err != nil { | ||
| 419 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 420 | + } | ||
| 421 | + | ||
| 422 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 423 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 424 | + } | ||
| 425 | + return struct{}{}, nil | ||
| 426 | +} | ||
| 427 | + | ||
| 428 | +func (fileService *FileService) AppTableFileList(ctx *domain.Context, cmd *query.ListAppTableFileCommand) (interface{}, error) { | ||
| 429 | + return fileService.GetAppFile(ctx, cmd.AppKey, cmd.Name) | ||
| 430 | +} | ||
| 431 | + | ||
| 432 | +func (fileService *FileService) UpdateAppTableFile(ctx *domain.Context, cmd *command.UpdateAppTableFileCommand) (interface{}, error) { | ||
| 433 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 434 | + if err != nil { | ||
| 435 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 436 | + } | ||
| 437 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 438 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 439 | + } | ||
| 440 | + defer func() { | ||
| 441 | + transactionContext.RollbackTransaction() | ||
| 442 | + }() | ||
| 443 | + | ||
| 444 | + fileRepository, file, _ := factory.FastPgFile(transactionContext, 0) | ||
| 445 | + file, err = fileRepository.FindOne(map[string]interface{}{"appKey": cmd.AppKey, "fileName": cmd.Name, "fileType": domain.SourceFile}) | ||
| 446 | + if err == domain.ErrorNotFound { | ||
| 447 | + return nil, factory.FastError(errors.New("文件不存在")) | ||
| 448 | + } | ||
| 449 | + if err != nil { | ||
| 450 | + return nil, factory.FastError(err) | ||
| 451 | + } | ||
| 452 | + if len(cmd.AddFields) == 0 { | ||
| 453 | + return nil, nil | ||
| 454 | + } | ||
| 455 | + tableRepository, table, _ := factory.FastPgTable(transactionContext, file.FileInfo.TableId) | ||
| 456 | + if err == domain.ErrorNotFound { | ||
| 457 | + return nil, factory.FastError(errors.New("文件表不存在")) | ||
| 458 | + } | ||
| 459 | + builder := domainService.NewDataFieldsBuilder() | ||
| 460 | + for i, _ := range cmd.AddFields { | ||
| 461 | + if _, ok := table.MatchField(cmd.AddFields[i]); ok { | ||
| 462 | + return nil, factory.FastError(errors.New("字段已存在")) | ||
| 463 | + } | ||
| 464 | + } | ||
| 465 | + for _, f := range cmd.AddFields { | ||
| 466 | + dataField := builder.NewDataField(f.Name, f.SQLType, domain.MainTableField) | ||
| 467 | + table.DataFields = append(table.DataFields, dataField) | ||
| 468 | + if err = starrocks.AddTableColumn(starrocks.DB, table.SQLName, dataField); err != nil { | ||
| 469 | + return nil, factory.FastError(err) | ||
| 470 | + } | ||
| 471 | + } | ||
| 472 | + | ||
| 473 | + if table, err = tableRepository.Save(table); err != nil { | ||
| 474 | + return nil, factory.FastError(err) | ||
| 475 | + } | ||
| 476 | + | ||
| 477 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 478 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 479 | + } | ||
| 480 | + return struct{}{}, nil | ||
| 481 | +} |
| 1 | package service | 1 | package service |
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | + "bytes" | ||
| 5 | + "fmt" | ||
| 6 | + "github.com/beego/beego/v2/client/httplib" | ||
| 4 | "github.com/linmadan/egglib-go/core/application" | 7 | "github.com/linmadan/egglib-go/core/application" |
| 8 | + "github.com/linmadan/egglib-go/transaction/pg" | ||
| 5 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" |
| 6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/command" | 10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/command" |
| 11 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/dto" | ||
| 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 12 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
| 13 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" | ||
| 14 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/excel" | ||
| 15 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" | ||
| 8 | ) | 16 | ) |
| 9 | 17 | ||
| 10 | // FilePreview 加载表格数据 | 18 | // FilePreview 加载表格数据 |
| @@ -33,10 +41,88 @@ func (fileService *FileService) FilePreview(ctx *domain.Context, loadDataTableCo | @@ -33,10 +41,88 @@ func (fileService *FileService) FilePreview(ctx *domain.Context, loadDataTableCo | ||
| 33 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 41 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| 34 | } | 42 | } |
| 35 | 43 | ||
| 36 | - //return dto.NewDataTableDtoDemo(loadDataTableService.GetFileId()), nil | ||
| 37 | return data, nil | 44 | return data, nil |
| 38 | } | 45 | } |
| 39 | 46 | ||
| 47 | +func (fileService *FileService) ResetHeaderRow(ctx *domain.Context, loadDataTableCommand *command.ResetTableHeaderCommand) (interface{}, error) { | ||
| 48 | + if err := loadDataTableCommand.ValidateCommand(); err != nil { | ||
| 49 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 50 | + } | ||
| 51 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 52 | + if err != nil { | ||
| 53 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 54 | + } | ||
| 55 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 56 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 57 | + } | ||
| 58 | + defer func() { | ||
| 59 | + transactionContext.RollbackTransaction() | ||
| 60 | + }() | ||
| 61 | + cache := redis.NewFileCacheService() | ||
| 62 | + temporaryFile, err := cache.Get(redis.KeyTemporaryFileInfo(loadDataTableCommand.FileId)) | ||
| 63 | + if err != nil { | ||
| 64 | + return nil, factory.FastError(err) | ||
| 65 | + } | ||
| 66 | + loadDataTableService, _ := factory.CreateLoadDataTableService(transactionContext) | ||
| 67 | + data, err := loadDataTableService.RePreview(ctx, loadDataTableCommand.FileId, temporaryFile.Fields, loadDataTableCommand.Where) | ||
| 68 | + // 处理错误 | ||
| 69 | + level := domain.LevelInfo | ||
| 70 | + errMsg := "" | ||
| 71 | + if err != nil { | ||
| 72 | + level = domain.LevelError | ||
| 73 | + errMsg = err.Error() | ||
| 74 | + } | ||
| 75 | + if logErr := domainService.FastLog(transactionContext.(*pg.TransactionContext), | ||
| 76 | + domain.VerifiedStepLog, temporaryFile.FileId, &domainService.ExcelTableResetHeaderLog{ | ||
| 77 | + LogEntry: domain.NewLogEntry(temporaryFile.FileName, domain.VerifiedFile.ToString(), domain.FileVerify, | ||
| 78 | + ctx.WithValue(domain.ContextWithLogLevel, level). | ||
| 79 | + WithValue(domain.ContextWithLogMsg, errMsg)), | ||
| 80 | + HeaderRow: domain.GetHeaderRow(loadDataTableCommand.HeaderRow), | ||
| 81 | + }); logErr != nil { | ||
| 82 | + return nil, logErr | ||
| 83 | + } | ||
| 84 | + if err != nil { | ||
| 85 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 89 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + return data, nil | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +// PrepareTemporaryFile 准备临时文件 | ||
| 96 | +func (fileService *FileService) PrepareTemporaryFile(ctx *domain.Context, cmd *command.PrepareTemporaryFileCommand) (interface{}, error) { | ||
| 97 | + if err := cmd.ValidateCommand(); err != nil { | ||
| 98 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 99 | + } | ||
| 100 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 101 | + if err != nil { | ||
| 102 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 103 | + } | ||
| 104 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 105 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 106 | + } | ||
| 107 | + defer func() { | ||
| 108 | + transactionContext.RollbackTransaction() | ||
| 109 | + }() | ||
| 110 | + | ||
| 111 | + loadDataTableService, _ := factory.CreateLoadDataTableService(transactionContext) | ||
| 112 | + data, err := loadDataTableService.CreateTemporaryFile(ctx, cmd.FileId) | ||
| 113 | + if err != nil { | ||
| 114 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 118 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + fileDto := &dto.FileDto{} | ||
| 122 | + fileDto.Load(data) | ||
| 123 | + return fileDto, nil | ||
| 124 | +} | ||
| 125 | + | ||
| 40 | // EditDataTable 编辑表格数据 | 126 | // EditDataTable 编辑表格数据 |
| 41 | func (fileService *FileService) EditDataTable(ctx *domain.Context, editDataTableCommand *command.EditDataTableCommand) (interface{}, error) { | 127 | func (fileService *FileService) EditDataTable(ctx *domain.Context, editDataTableCommand *command.EditDataTableCommand) (interface{}, error) { |
| 42 | if err := editDataTableCommand.ValidateCommand(); err != nil { | 128 | if err := editDataTableCommand.ValidateCommand(); err != nil { |
| @@ -53,15 +139,47 @@ func (fileService *FileService) EditDataTable(ctx *domain.Context, editDataTable | @@ -53,15 +139,47 @@ func (fileService *FileService) EditDataTable(ctx *domain.Context, editDataTable | ||
| 53 | transactionContext.RollbackTransaction() | 139 | transactionContext.RollbackTransaction() |
| 54 | }() | 140 | }() |
| 55 | 141 | ||
| 142 | + cache := redis.NewFileCacheService() | ||
| 143 | + temporaryFile, err := cache.Get(redis.KeyTemporaryFileInfo(editDataTableCommand.FileId)) | ||
| 144 | + if err != nil { | ||
| 145 | + return nil, factory.FastError(err) | ||
| 146 | + } | ||
| 147 | + editDataTableCommand.Fields = temporaryFile.Fields | ||
| 148 | + editDataTableCommand.ProcessFields = temporaryFile.MatchFields(editDataTableCommand.ProcessFieldNames) | ||
| 149 | + if len(editDataTableCommand.ProcessFields) == 0 { | ||
| 150 | + return nil, factory.FastError(fmt.Errorf("请至少选择一个数据列")) | ||
| 151 | + } | ||
| 152 | + if editDataTableCommand.Action == "remove-column" && len(temporaryFile.Fields) == len(editDataTableCommand.ProcessFields) { | ||
| 153 | + return nil, factory.FastError(fmt.Errorf("请至少保留一个数据列")) | ||
| 154 | + } | ||
| 155 | + if editDataTableCommand.Action == "rename-column" { | ||
| 156 | + targetColumn := editDataTableCommand.ProcessFieldNames[0] | ||
| 157 | + newColumnName := editDataTableCommand.Params["newColumnName"].(string) | ||
| 158 | + if len(temporaryFile.MatchFields([]string{newColumnName})) > 0 && newColumnName != targetColumn { | ||
| 159 | + return nil, factory.FastError(fmt.Errorf("已存在相同名称,修改无效")) | ||
| 160 | + } | ||
| 161 | + } | ||
| 162 | + // allowAction := func(fields []*domain.Field, action string) error { | ||
| 163 | + // for _, f := range fields { | ||
| 164 | + // if f.SQLType != string(domain.String) && | ||
| 165 | + // !(action == domain.RemoveColumn || action == domain.CopyColumn || action == domain.RenameColumn || action == domain.ConvertColumnType) { | ||
| 166 | + // return fmt.Errorf("列【%v】必须先转字符串类型",f.Name) | ||
| 167 | + // } | ||
| 168 | + // } | ||
| 169 | + // return nil | ||
| 170 | + // } | ||
| 171 | + // if err = allowAction(editDataTableCommand.ProcessFields, editDataTableCommand.Action); err != nil { | ||
| 172 | + // return nil, factory.FastError(err) | ||
| 173 | + // } | ||
| 56 | editDataTableService, _ := factory.CreateEditDataTableService(transactionContext) | 174 | editDataTableService, _ := factory.CreateEditDataTableService(transactionContext) |
| 57 | - _, err = editDataTableService.Edit(ctx, editDataTableCommand.EditTableRequest) | 175 | + response, err := editDataTableService.Edit(ctx, editDataTableCommand.EditTableRequest) |
| 58 | if err != nil { | 176 | if err != nil { |
| 59 | return nil, factory.FastError(err) | 177 | return nil, factory.FastError(err) |
| 60 | } | 178 | } |
| 61 | if err := transactionContext.CommitTransaction(); err != nil { | 179 | if err := transactionContext.CommitTransaction(); err != nil { |
| 62 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 180 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| 63 | } | 181 | } |
| 64 | - return struct{}{}, nil | 182 | + return (&dto.EditDataTableDto{}).Load(response), nil |
| 65 | } | 183 | } |
| 66 | 184 | ||
| 67 | // FlushDataTable 持久化表格数据 | 185 | // FlushDataTable 持久化表格数据 |
| @@ -80,16 +198,19 @@ func (fileService *FileService) FlushDataTable(ctx *domain.Context, flushDataTab | @@ -80,16 +198,19 @@ func (fileService *FileService) FlushDataTable(ctx *domain.Context, flushDataTab | ||
| 80 | transactionContext.RollbackTransaction() | 198 | transactionContext.RollbackTransaction() |
| 81 | }() | 199 | }() |
| 82 | flushDataTableService, _ := factory.CreateFlushDataTableService(transactionContext) | 200 | flushDataTableService, _ := factory.CreateFlushDataTableService(transactionContext) |
| 83 | - fields := make([]*domain.Field, 0) | ||
| 84 | - for _, f := range flushDataTableCommand.DataFields { | ||
| 85 | - fields = append(fields, &domain.Field{ | ||
| 86 | - Name: f.Name, | ||
| 87 | - SQLType: f.SQLType, | ||
| 88 | - }) | ||
| 89 | - } | ||
| 90 | - if _, err := flushDataTableService.Flush(ctx, flushDataTableCommand.FileId, &domain.Table{ | ||
| 91 | - DataFields: fields, | ||
| 92 | - RowCount: flushDataTableCommand.RowCount, | 201 | + cache := redis.NewFileCacheService() |
| 202 | + temporaryFile, err := cache.Get(redis.KeyTemporaryFileInfo(flushDataTableCommand.ObjectId)) | ||
| 203 | + if err != nil { | ||
| 204 | + return nil, factory.FastError(err) | ||
| 205 | + } | ||
| 206 | + if err = temporaryFile.Valid(); err != nil { | ||
| 207 | + return nil, factory.FastError(err) | ||
| 208 | + } | ||
| 209 | + | ||
| 210 | + if _, err := flushDataTableService.Flush(ctx, flushDataTableCommand.ObjectId, &domain.Table{ | ||
| 211 | + DataFields: temporaryFile.Fields, | ||
| 212 | + RowCount: temporaryFile.Total, | ||
| 213 | + HeaderRow: temporaryFile.HeaderRow, | ||
| 93 | }); err != nil { | 214 | }); err != nil { |
| 94 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 215 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 95 | } | 216 | } |
| @@ -131,6 +252,9 @@ func (fileService *FileService) AppendDataToTable(ctx *domain.Context, cmd *comm | @@ -131,6 +252,9 @@ func (fileService *FileService) AppendDataToTable(ctx *domain.Context, cmd *comm | ||
| 131 | if err := cmd.ValidateCommand(); err != nil { | 252 | if err := cmd.ValidateCommand(); err != nil { |
| 132 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 253 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| 133 | } | 254 | } |
| 255 | + if len(cmd.MappingFields) == 0 { | ||
| 256 | + return nil, factory.FastError(fmt.Errorf("请选择对应字段")) | ||
| 257 | + } | ||
| 134 | transactionContext, err := factory.CreateTransactionContext(nil) | 258 | transactionContext, err := factory.CreateTransactionContext(nil) |
| 135 | if err != nil { | 259 | if err != nil { |
| 136 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 260 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| @@ -152,3 +276,85 @@ func (fileService *FileService) AppendDataToTable(ctx *domain.Context, cmd *comm | @@ -152,3 +276,85 @@ func (fileService *FileService) AppendDataToTable(ctx *domain.Context, cmd *comm | ||
| 152 | } | 276 | } |
| 153 | return result, nil | 277 | return result, nil |
| 154 | } | 278 | } |
| 279 | + | ||
| 280 | +// AppendDataToTablePreflightCheck 追加数据预查 | ||
| 281 | +func (fileService *FileService) AppendDataToTablePreflightCheck(ctx *domain.Context, cmd *command.AppendDataToTableCommand) (interface{}, error) { | ||
| 282 | + if err := cmd.ValidateCommand(); err != nil { | ||
| 283 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 284 | + } | ||
| 285 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 286 | + if err != nil { | ||
| 287 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 288 | + } | ||
| 289 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 290 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 291 | + } | ||
| 292 | + defer func() { | ||
| 293 | + transactionContext.RollbackTransaction() | ||
| 294 | + }() | ||
| 295 | + | ||
| 296 | + generateMainTableService, _ := factory.CreateAppendDataToTableService(transactionContext) | ||
| 297 | + result, err := generateMainTableService.PreflightCheck(ctx, cmd.FileId, cmd.TableId, cmd.MappingFields) | ||
| 298 | + if err != nil { | ||
| 299 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 300 | + } | ||
| 301 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 302 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 303 | + } | ||
| 304 | + return result, nil | ||
| 305 | +} | ||
| 306 | + | ||
| 307 | +// ExportFile 文件下载 | ||
| 308 | +func (fileService *FileService) ExportFile(ctx *domain.Context, cmd *command.ExportFileCommand) (interface{}, error) { | ||
| 309 | + if err := cmd.ValidateCommand(); err != nil { | ||
| 310 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 311 | + } | ||
| 312 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 313 | + if err != nil { | ||
| 314 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 315 | + } | ||
| 316 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 317 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 318 | + } | ||
| 319 | + defer func() { | ||
| 320 | + transactionContext.RollbackTransaction() | ||
| 321 | + }() | ||
| 322 | + | ||
| 323 | + _, file, err := factory.FastPgFile(transactionContext, cmd.FileId) | ||
| 324 | + if err != nil { | ||
| 325 | + return nil, factory.FastError(err) | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + var response = FileUpload{} | ||
| 329 | + if file.FileType == domain.SourceFile.ToString() { | ||
| 330 | + response.Url = file.FileInfo.Url | ||
| 331 | + response.Ext = domain.XLSX | ||
| 332 | + response.FileName = file.FileInfo.Name | ||
| 333 | + return response, nil | ||
| 334 | + } | ||
| 335 | + _, table, err := factory.FastPgTable(transactionContext, file.FileInfo.TableId) | ||
| 336 | + if err != nil { | ||
| 337 | + return nil, factory.FastError(err) | ||
| 338 | + } | ||
| 339 | + | ||
| 340 | + f, err := httplib.Get(domain.ConvertFileUrlToInternal(file.FileInfo.Url)).Bytes() | ||
| 341 | + if err != nil { | ||
| 342 | + return nil, factory.FastError(err) | ||
| 343 | + } | ||
| 344 | + reader := bytes.NewReader(f) | ||
| 345 | + var importer *excel.Importer = excel.NewExcelImportByFile(file.FileInfo.Ext) | ||
| 346 | + data, err := importer.OpenExcelFromIoReader(reader) | ||
| 347 | + if err != nil { | ||
| 348 | + return nil, factory.FastError(err) | ||
| 349 | + } | ||
| 350 | + | ||
| 351 | + response, err = saveFile(file.FileInfo.Name, importer.Reader().Header().Columns, data, domain.MakeToInterfaces(table.DataFields)) | ||
| 352 | + if err != nil { | ||
| 353 | + return nil, factory.FastError(err) | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 357 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 358 | + } | ||
| 359 | + return response, nil | ||
| 360 | +} |
| @@ -2,6 +2,14 @@ package service | @@ -2,6 +2,14 @@ package service | ||
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "fmt" | 4 | "fmt" |
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" | ||
| 6 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/api/authlib" | ||
| 7 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/api/bytelib" | ||
| 8 | + "path/filepath" | ||
| 9 | + "sort" | ||
| 10 | + "strings" | ||
| 11 | + "time" | ||
| 12 | + | ||
| 5 | "github.com/linmadan/egglib-go/core/application" | 13 | "github.com/linmadan/egglib-go/core/application" |
| 6 | "github.com/linmadan/egglib-go/utils/tool_funs" | 14 | "github.com/linmadan/egglib-go/utils/tool_funs" |
| 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | 15 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" |
| @@ -9,19 +17,16 @@ import ( | @@ -9,19 +17,16 @@ import ( | ||
| 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/dto" | 17 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/dto" |
| 10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/query" | 18 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/query" |
| 11 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 19 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
| 12 | - "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain/bytecore" | ||
| 13 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" | 20 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" |
| 14 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" | 21 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" |
| 15 | - "path/filepath" | ||
| 16 | - "time" | ||
| 17 | ) | 22 | ) |
| 18 | 23 | ||
| 19 | -// 文件服务 | 24 | +// FileService 文件服务 |
| 20 | type FileService struct { | 25 | type FileService struct { |
| 21 | } | 26 | } |
| 22 | 27 | ||
| 23 | -// 创建文件服务 | ||
| 24 | -func (fileService *FileService) CreateFile(ctx *domain.Context, createFileCommand *command.CreateFileCommand) (interface{}, error) { | 28 | +// CreateFile 创建文件服务 |
| 29 | +func (fileService *FileService) CreateFile(ctx *domain.Context, createFileCommand *command.CreateFileCommand) (*domain.File, error) { | ||
| 25 | if err := createFileCommand.ValidateCommand(); err != nil { | 30 | if err := createFileCommand.ValidateCommand(); err != nil { |
| 26 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 31 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| 27 | } | 32 | } |
| @@ -35,25 +40,81 @@ func (fileService *FileService) CreateFile(ctx *domain.Context, createFileComman | @@ -35,25 +40,81 @@ func (fileService *FileService) CreateFile(ctx *domain.Context, createFileComman | ||
| 35 | defer func() { | 40 | defer func() { |
| 36 | transactionContext.RollbackTransaction() | 41 | transactionContext.RollbackTransaction() |
| 37 | }() | 42 | }() |
| 38 | - newFile := &domain.File{ | ||
| 39 | - FileType: domain.SourceFile.ToString(), | ||
| 40 | - FileInfo: &domain.FileInfo{ | 43 | + fileInfo := &domain.FileInfo{ |
| 41 | Name: domain.FileName(createFileCommand.Name), | 44 | Name: domain.FileName(createFileCommand.Name), |
| 42 | Url: createFileCommand.Url, | 45 | Url: createFileCommand.Url, |
| 43 | FileSize: createFileCommand.FileSize, | 46 | FileSize: createFileCommand.FileSize, |
| 44 | Ext: filepath.Ext(createFileCommand.Name), | 47 | Ext: filepath.Ext(createFileCommand.Name), |
| 45 | - }, | 48 | + } |
| 49 | + newFile := &domain.File{ | ||
| 50 | + FileType: domain.SourceFile.ToString(), | ||
| 51 | + FileInfo: fileInfo, | ||
| 46 | SourceFileId: 0, | 52 | SourceFileId: 0, |
| 47 | //Operator: "", | 53 | //Operator: "", |
| 48 | CreatedAt: time.Now(), | 54 | CreatedAt: time.Now(), |
| 49 | UpdatedAt: time.Now(), | 55 | UpdatedAt: time.Now(), |
| 50 | Context: ctx, | 56 | Context: ctx, |
| 57 | + FileFrom: createFileCommand.FileFrom, | ||
| 58 | + AppKey: createFileCommand.AppKey, | ||
| 51 | } | 59 | } |
| 52 | fileRepository, _, _ := factory.FastPgFile(transactionContext, 0) | 60 | fileRepository, _, _ := factory.FastPgFile(transactionContext, 0) |
| 61 | + | ||
| 62 | + // 文件名相同,进行替换 | ||
| 63 | + if oldFile, findOldFileErr := fileRepository.FindOne(map[string]interface{}{ | ||
| 64 | + "context": ctx, | ||
| 65 | + "fileName": fileInfo.Name, | ||
| 66 | + "fileType": domain.SourceFile.ToString(), | ||
| 67 | + }); oldFile != nil && findOldFileErr == nil { | ||
| 68 | + oldFile.FileInfo = fileInfo | ||
| 69 | + oldFile.UpdatedAt = time.Now() | ||
| 70 | + newFile = oldFile | ||
| 71 | + | ||
| 72 | + if err = factory.FastLog(transactionContext, domain.CommonLog, oldFile.FileId, &domainService.FileReplaceLog{ | ||
| 73 | + LogEntry: domain.NewLogEntry(oldFile.FileInfo.Name, domain.SourceFile.ToString(), domain.FileUpload, ctx), | ||
| 74 | + }); err != nil { | ||
| 75 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | + | ||
| 53 | file, err := fileRepository.Save(newFile) | 79 | file, err := fileRepository.Save(newFile) |
| 54 | if err != nil { | 80 | if err != nil { |
| 55 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 81 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 56 | } | 82 | } |
| 83 | + // 同时生成主表 | ||
| 84 | + // 前置需要进行预览、保持文件,才能生成主表 | ||
| 85 | + if createFileCommand.GenerateTableFlag { | ||
| 86 | + table := domainService.NewTable(domain.MainTable, fileInfo.Name, createFileCommand.Fields, 0). | ||
| 87 | + WithPrefix(domain.MainTable.ToString()).WithContext(&domain.Context{}) | ||
| 88 | + tableRepository, _, _ := factory.FastPgTable(transactionContext, 0) | ||
| 89 | + if table, err = tableRepository.Save(table); err != nil { | ||
| 90 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 91 | + } | ||
| 92 | + domainService.ByteCore.LoadDataTable(domain.ReqLoadDataTable{ | ||
| 93 | + FileId: file.FileId, | ||
| 94 | + FileName: file.FileInfo.Name, | ||
| 95 | + Url: file.FileInfo.Url, | ||
| 96 | + Ext: file.FileInfo.Ext, | ||
| 97 | + //Where: where, | ||
| 98 | + OriginalTableId: fmt.Sprintf("%v", file.FileId), | ||
| 99 | + IsFromOriginalTable: true, | ||
| 100 | + TableFileUrl: file.FileInfo.Url, | ||
| 101 | + ColumnSchemas: bytelib.DomainFieldsToColumnSchemas(table.Fields(false)), | ||
| 102 | + SortParameters: make(map[string]interface{}), | ||
| 103 | + }) | ||
| 104 | + response, err := domainService.ByteCore.SaveTable(domain.ReqSaveTable{FileId: file.FileId, Table: table}) | ||
| 105 | + if err != nil { | ||
| 106 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 107 | + } | ||
| 108 | + if _, err = domainService.ByteCore.GenerateTable(ctx, domain.ReqGenerateTable{ | ||
| 109 | + file.FileId, response.Url, table, | ||
| 110 | + }); err != nil { | ||
| 111 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 112 | + } | ||
| 113 | + file.FileInfo.TableId = table.TableId | ||
| 114 | + if file, err = fileRepository.Save(file); err != nil { | ||
| 115 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 116 | + } | ||
| 117 | + } | ||
| 57 | if err = factory.FastLog(transactionContext, domain.CommonLog, file.FileId, &domainService.FileUploadSuccessLog{ | 118 | if err = factory.FastLog(transactionContext, domain.CommonLog, file.FileId, &domainService.FileUploadSuccessLog{ |
| 58 | LogEntry: domain.NewLogEntry(file.FileInfo.Name, domain.SourceFile.ToString(), domain.FileUpload, ctx), | 119 | LogEntry: domain.NewLogEntry(file.FileInfo.Name, domain.SourceFile.ToString(), domain.FileUpload, ctx), |
| 59 | }); err != nil { | 120 | }); err != nil { |
| @@ -62,11 +123,11 @@ func (fileService *FileService) CreateFile(ctx *domain.Context, createFileComman | @@ -62,11 +123,11 @@ func (fileService *FileService) CreateFile(ctx *domain.Context, createFileComman | ||
| 62 | if err := transactionContext.CommitTransaction(); err != nil { | 123 | if err := transactionContext.CommitTransaction(); err != nil { |
| 63 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 124 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| 64 | } | 125 | } |
| 65 | - return struct{}{}, nil | 126 | + return file, nil |
| 66 | } | 127 | } |
| 67 | 128 | ||
| 68 | -// 返回文件服务 | ||
| 69 | -func (fileService *FileService) GetFile(getFileQuery *query.GetFileQuery) (interface{}, error) { | 129 | +// GetFile 返回文件服务 |
| 130 | +func (fileService *FileService) GetFile(ctx *domain.Context, getFileQuery *query.GetFileQuery) (interface{}, error) { | ||
| 70 | if err := getFileQuery.ValidateQuery(); err != nil { | 131 | if err := getFileQuery.ValidateQuery(); err != nil { |
| 71 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 132 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| 72 | } | 133 | } |
| @@ -88,21 +149,35 @@ func (fileService *FileService) GetFile(getFileQuery *query.GetFileQuery) (inter | @@ -88,21 +149,35 @@ func (fileService *FileService) GetFile(getFileQuery *query.GetFileQuery) (inter | ||
| 88 | } else { | 149 | } else { |
| 89 | fileRepository = value | 150 | fileRepository = value |
| 90 | } | 151 | } |
| 91 | - file, err := fileRepository.FindOne(map[string]interface{}{"fileId": getFileQuery.FileId}) | ||
| 92 | - if err != nil { | ||
| 93 | - return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 152 | + response := map[string]interface{}{ |
| 153 | + "file": nil, | ||
| 94 | } | 154 | } |
| 95 | - if file == nil { | ||
| 96 | - return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(getFileQuery.FileId))) | ||
| 97 | - } else { | 155 | + options := map[string]interface{}{"context": ctx} |
| 156 | + if getFileQuery.FileId > 0 { | ||
| 157 | + options["fileId"] = getFileQuery.FileId | ||
| 158 | + } | ||
| 159 | + if len(getFileQuery.FileName) > 0 { | ||
| 160 | + options["fileName"] = domain.FileName(getFileQuery.FileName) | ||
| 161 | + } | ||
| 162 | + if len(getFileQuery.FileType) > 0 { | ||
| 163 | + options["fileType"] = getFileQuery.FileType | ||
| 164 | + } | ||
| 165 | + // 未传递参数 | ||
| 166 | + if len(options) == 1 { | ||
| 167 | + return response, nil | ||
| 168 | + } | ||
| 169 | + file, _ := fileRepository.FindOne(options) | ||
| 170 | + //if err != nil { | ||
| 171 | + // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 172 | + //} | ||
| 98 | if err := transactionContext.CommitTransaction(); err != nil { | 173 | if err := transactionContext.CommitTransaction(); err != nil { |
| 99 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 174 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| 100 | } | 175 | } |
| 101 | - return file, nil | ||
| 102 | - } | 176 | + response["file"] = (&dto.FileDto{}).Load(file) |
| 177 | + return response, nil | ||
| 103 | } | 178 | } |
| 104 | 179 | ||
| 105 | -// 返回文件服务列表 | 180 | +// ListFile 返回文件服务列表 |
| 106 | func (fileService *FileService) ListFile(listFileQuery *query.ListFileQuery) (interface{}, error) { | 181 | func (fileService *FileService) ListFile(listFileQuery *query.ListFileQuery) (interface{}, error) { |
| 107 | if err := listFileQuery.ValidateQuery(); err != nil { | 182 | if err := listFileQuery.ValidateQuery(); err != nil { |
| 108 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 183 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -180,8 +255,131 @@ func (fileService *FileService) SearchFile(listFileQuery *query.SearchFileQuery) | @@ -180,8 +255,131 @@ func (fileService *FileService) SearchFile(listFileQuery *query.SearchFileQuery) | ||
| 180 | }, nil | 255 | }, nil |
| 181 | } | 256 | } |
| 182 | 257 | ||
| 183 | -// 移除文件服务 | ||
| 184 | -func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFileCommand) (interface{}, error) { | 258 | +// SearchAppFile 返回文件服务列表 |
| 259 | +func (fileService *FileService) SearchAppFile(ctx *domain.Context, listFileQuery *query.SearchFileQuery) (interface{}, error) { | ||
| 260 | + if err := listFileQuery.ValidateQuery(); err != nil { | ||
| 261 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 262 | + } | ||
| 263 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 264 | + if err != nil { | ||
| 265 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 266 | + } | ||
| 267 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 268 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 269 | + } | ||
| 270 | + defer func() { | ||
| 271 | + transactionContext.RollbackTransaction() | ||
| 272 | + }() | ||
| 273 | + var fileRepository, _, _ = factory.FastPgFile(transactionContext, 0) | ||
| 274 | + | ||
| 275 | + apiAuthLib := authlib.NewApiAuthLib(constant.AUTH_SERVER_HOST).WithToken(ctx.AccessToken) | ||
| 276 | + response, err := apiAuthLib.MeAppInfo(authlib.RequestUserMeQuery{UserId: ctx.TenantId}) | ||
| 277 | + if err != nil { | ||
| 278 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 279 | + } | ||
| 280 | + inAppKeys := make([]string, 0) | ||
| 281 | + for _, app := range response.Apps { | ||
| 282 | + inAppKeys = append(inAppKeys, app.AppKey) | ||
| 283 | + } | ||
| 284 | + var ( | ||
| 285 | + fileDtos = make([]*dto.FileDto, 0) | ||
| 286 | + total int64 | ||
| 287 | + ) | ||
| 288 | + if len(inAppKeys) > 0 { | ||
| 289 | + queryOptions := utils.ObjectToMap(listFileQuery) | ||
| 290 | + queryOptions["inAppKeys"] = inAppKeys | ||
| 291 | + queryOptions["limit"] = 1000 | ||
| 292 | + queryOptions["fileName"] = listFileQuery.FileName | ||
| 293 | + count, files, err := fileRepository.Find(queryOptions) | ||
| 294 | + if err != nil { | ||
| 295 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 296 | + } | ||
| 297 | + for _, file := range files { | ||
| 298 | + var item = &dto.FileDto{} | ||
| 299 | + item.Load(file) | ||
| 300 | + fileDtos = append(fileDtos, item) | ||
| 301 | + } | ||
| 302 | + total = count | ||
| 303 | + } | ||
| 304 | + var apps = make([]*dto.AppDto, 0) | ||
| 305 | + for _, app := range response.Apps { | ||
| 306 | + if len(listFileQuery.FileName) > 0 && !strings.Contains(app.AppName, listFileQuery.FileName) { | ||
| 307 | + continue | ||
| 308 | + } | ||
| 309 | + files := make([]*dto.FileDto, 0) | ||
| 310 | + for _, file := range fileDtos { | ||
| 311 | + if file.AppKey == app.AppKey { | ||
| 312 | + files = append(files, file) | ||
| 313 | + } | ||
| 314 | + } | ||
| 315 | + sort.SliceStable(files, func(i, j int) bool { | ||
| 316 | + return files[i].Name < files[j].Name | ||
| 317 | + }) | ||
| 318 | + apps = append(apps, &dto.AppDto{ | ||
| 319 | + AppId: app.AppId, | ||
| 320 | + AppKey: app.AppKey, | ||
| 321 | + AppName: app.AppName, | ||
| 322 | + Files: files, | ||
| 323 | + }) | ||
| 324 | + } | ||
| 325 | + | ||
| 326 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 327 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 328 | + } | ||
| 329 | + return map[string]interface{}{ | ||
| 330 | + "apps": apps, | ||
| 331 | + "count": total, | ||
| 332 | + }, nil | ||
| 333 | +} | ||
| 334 | + | ||
| 335 | +// GetAppFile 返回应用对应的文件服务列表 | ||
| 336 | +func (fileService *FileService) GetAppFile(ctx *domain.Context, appKey string, fileName string) (interface{}, error) { | ||
| 337 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 338 | + if err != nil { | ||
| 339 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 340 | + } | ||
| 341 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 342 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 343 | + } | ||
| 344 | + defer func() { | ||
| 345 | + transactionContext.RollbackTransaction() | ||
| 346 | + }() | ||
| 347 | + var fileRepository, _, _ = factory.FastPgFile(transactionContext, 0) | ||
| 348 | + | ||
| 349 | + var ( | ||
| 350 | + fileDtos = make([]*dto.FileDto, 0) | ||
| 351 | + total int64 | ||
| 352 | + ) | ||
| 353 | + | ||
| 354 | + queryOptions := make(map[string]interface{}) | ||
| 355 | + queryOptions["fileType"] = domain.SourceFile | ||
| 356 | + queryOptions["inAppKeys"] = []string{appKey} | ||
| 357 | + queryOptions["limit"] = 100 | ||
| 358 | + count, files, err := fileRepository.Find(queryOptions) | ||
| 359 | + if err != nil { | ||
| 360 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 361 | + } | ||
| 362 | + for _, file := range files { | ||
| 363 | + var item = &dto.FileDto{} | ||
| 364 | + if fileName != "" && file.FileInfo.Name != fileName { | ||
| 365 | + continue | ||
| 366 | + } | ||
| 367 | + item.Load(file) | ||
| 368 | + fileDtos = append(fileDtos, item) | ||
| 369 | + } | ||
| 370 | + total = count | ||
| 371 | + | ||
| 372 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 373 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 374 | + } | ||
| 375 | + return map[string]interface{}{ | ||
| 376 | + "count": total, | ||
| 377 | + "files": fileDtos, | ||
| 378 | + }, nil | ||
| 379 | +} | ||
| 380 | + | ||
| 381 | +// RemoveFile 移除文件服务 | ||
| 382 | +func (fileService *FileService) RemoveFile(ctx *domain.Context, removeFileCommand *command.RemoveFileCommand) (interface{}, error) { | ||
| 185 | if err := removeFileCommand.ValidateCommand(); err != nil { | 383 | if err := removeFileCommand.ValidateCommand(); err != nil { |
| 186 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 384 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| 187 | } | 385 | } |
| @@ -208,10 +406,10 @@ func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFile | @@ -208,10 +406,10 @@ func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFile | ||
| 208 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 406 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 209 | } | 407 | } |
| 210 | if file == nil { | 408 | if file == nil { |
| 211 | - return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeFileCommand.FileId))) | 409 | + return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%d", removeFileCommand.FileId)) |
| 212 | } | 410 | } |
| 213 | deleteFileService, _ := factory.CreateDeleteFileService(transactionContext) | 411 | deleteFileService, _ := factory.CreateDeleteFileService(transactionContext) |
| 214 | - err = deleteFileService.DeleteFiles(nil, file) | 412 | + err = deleteFileService.DeleteFiles(ctx, file) |
| 215 | if err != nil { | 413 | if err != nil { |
| 216 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 414 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 217 | } | 415 | } |
| @@ -221,7 +419,7 @@ func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFile | @@ -221,7 +419,7 @@ func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFile | ||
| 221 | return struct{}{}, nil | 419 | return struct{}{}, nil |
| 222 | } | 420 | } |
| 223 | 421 | ||
| 224 | -// 更新文件服务 | 422 | +// UpdateFile 更新文件服务 |
| 225 | func (fileService *FileService) UpdateFile(updateFileCommand *command.UpdateFileCommand) (interface{}, error) { | 423 | func (fileService *FileService) UpdateFile(updateFileCommand *command.UpdateFileCommand) (interface{}, error) { |
| 226 | if err := updateFileCommand.ValidateCommand(); err != nil { | 424 | if err := updateFileCommand.ValidateCommand(); err != nil { |
| 227 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 425 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -249,7 +447,7 @@ func (fileService *FileService) UpdateFile(updateFileCommand *command.UpdateFile | @@ -249,7 +447,7 @@ func (fileService *FileService) UpdateFile(updateFileCommand *command.UpdateFile | ||
| 249 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 447 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 250 | } | 448 | } |
| 251 | if file == nil { | 449 | if file == nil { |
| 252 | - return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(updateFileCommand.FileId))) | 450 | + return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%d", updateFileCommand.FileId)) |
| 253 | } | 451 | } |
| 254 | if err := file.Update(tool_funs.SimpleStructToMap(updateFileCommand)); err != nil { | 452 | if err := file.Update(tool_funs.SimpleStructToMap(updateFileCommand)); err != nil { |
| 255 | return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error()) | 453 | return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error()) |
| @@ -264,7 +462,7 @@ func (fileService *FileService) UpdateFile(updateFileCommand *command.UpdateFile | @@ -264,7 +462,7 @@ func (fileService *FileService) UpdateFile(updateFileCommand *command.UpdateFile | ||
| 264 | } | 462 | } |
| 265 | } | 463 | } |
| 266 | 464 | ||
| 267 | -// 取消校验中的文件 | 465 | +// CancelVerifyingFile 取消校验中的文件 |
| 268 | func (fileService *FileService) CancelVerifyingFile(ctx *domain.Context, cmd *command.CancelVerifyingFileCommand) (interface{}, error) { | 466 | func (fileService *FileService) CancelVerifyingFile(ctx *domain.Context, cmd *command.CancelVerifyingFileCommand) (interface{}, error) { |
| 269 | if err := cmd.ValidateCommand(); err != nil { | 467 | if err := cmd.ValidateCommand(); err != nil { |
| 270 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 468 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -295,7 +493,7 @@ func (fileService *FileService) CancelVerifyingFile(ctx *domain.Context, cmd *co | @@ -295,7 +493,7 @@ func (fileService *FileService) CancelVerifyingFile(ctx *domain.Context, cmd *co | ||
| 295 | } | 493 | } |
| 296 | 494 | ||
| 297 | byteCore, _ := factory.CreateByteCoreService(transactionContext) | 495 | byteCore, _ := factory.CreateByteCoreService(transactionContext) |
| 298 | - _, err = byteCore.CancelFile(bytecore.ReqCancelFile{}) | 496 | + _, err = byteCore.CancelFile(domain.ReqCancelFile{}) |
| 299 | if err != nil { | 497 | if err != nil { |
| 300 | return nil, factory.FastError(err) | 498 | return nil, factory.FastError(err) |
| 301 | } | 499 | } |
| @@ -306,6 +504,40 @@ func (fileService *FileService) CancelVerifyingFile(ctx *domain.Context, cmd *co | @@ -306,6 +504,40 @@ func (fileService *FileService) CancelVerifyingFile(ctx *domain.Context, cmd *co | ||
| 306 | return struct{}{}, nil | 504 | return struct{}{}, nil |
| 307 | } | 505 | } |
| 308 | 506 | ||
| 507 | +// CheckFileVerifyStatus 检查文件校验状态 | ||
| 508 | +func (fileService *FileService) CheckFileVerifyStatus(ctx *domain.Context, cmd *command.CheckFileVerifyStatusCommand) (interface{}, error) { | ||
| 509 | + if err := cmd.ValidateCommand(); err != nil { | ||
| 510 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 511 | + } | ||
| 512 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 513 | + if err != nil { | ||
| 514 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 515 | + } | ||
| 516 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 517 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 518 | + } | ||
| 519 | + defer func() { | ||
| 520 | + transactionContext.RollbackTransaction() | ||
| 521 | + }() | ||
| 522 | + | ||
| 523 | + fileRepository, file, err := factory.FastPgFile(transactionContext, cmd.FileId) | ||
| 524 | + if err != nil { | ||
| 525 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 526 | + } | ||
| 527 | + var res = struct { | ||
| 528 | + ExistVerifyFile bool `json:"existVerifyFile"` | ||
| 529 | + }{} | ||
| 530 | + _, verifyFiles, findErr := fileRepository.Find(map[string]interface{}{"context": ctx, "fileType": domain.VerifiedFile.ToString(), "sourceFileId": file.SourceFileId}) | ||
| 531 | + if findErr == nil && len(verifyFiles) > 0 { | ||
| 532 | + res.ExistVerifyFile = true | ||
| 533 | + } | ||
| 534 | + | ||
| 535 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 536 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 537 | + } | ||
| 538 | + return res, nil | ||
| 539 | +} | ||
| 540 | + | ||
| 309 | func NewFileService(options map[string]interface{}) *FileService { | 541 | func NewFileService(options map[string]interface{}) *FileService { |
| 310 | newFileService := &FileService{} | 542 | newFileService := &FileService{} |
| 311 | return newFileService | 543 | return newFileService |
| @@ -2,11 +2,12 @@ package command | @@ -2,11 +2,12 @@ package command | ||
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "fmt" | 4 | "fmt" |
| 5 | - "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 6 | "reflect" | 5 | "reflect" |
| 7 | "strings" | 6 | "strings" |
| 8 | "time" | 7 | "time" |
| 9 | 8 | ||
| 9 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 10 | + | ||
| 10 | "github.com/beego/beego/v2/core/validation" | 11 | "github.com/beego/beego/v2/core/validation" |
| 11 | ) | 12 | ) |
| 12 | 13 | ||
| @@ -23,6 +24,8 @@ type SearchLogCommand struct { | @@ -23,6 +24,8 @@ type SearchLogCommand struct { | ||
| 23 | PageNumber int `cname:"页码" json:"pageNumber,omitempty"` | 24 | PageNumber int `cname:"页码" json:"pageNumber,omitempty"` |
| 24 | // 页数 | 25 | // 页数 |
| 25 | PageSize int `cname:"页数" json:"pageSize,omitempty"` | 26 | PageSize int `cname:"页数" json:"pageSize,omitempty"` |
| 27 | + // 对象名称 | ||
| 28 | + ObjectName string `cname:"页数" json:"objectName,omitempty"` | ||
| 26 | 29 | ||
| 27 | Year int `cname:"年" json:"year,omitempty"` | 30 | Year int `cname:"年" json:"year,omitempty"` |
| 28 | Month int `cname:"月" json:"month,omitempty"` | 31 | Month int `cname:"月" json:"month,omitempty"` |
| @@ -31,7 +34,8 @@ type SearchLogCommand struct { | @@ -31,7 +34,8 @@ type SearchLogCommand struct { | ||
| 31 | BeginTime time.Time `cname:"开始时间" json:"beginTime"` | 34 | BeginTime time.Time `cname:"开始时间" json:"beginTime"` |
| 32 | // 结束时间 | 35 | // 结束时间 |
| 33 | EndTime time.Time `cname:"结束时间" json:"endTime"` | 36 | EndTime time.Time `cname:"结束时间" json:"endTime"` |
| 34 | - | 37 | + // 按log_id 排序 |
| 38 | + SortByLogId string `json:"sortByLogId"` | ||
| 35 | Context *domain.Context | 39 | Context *domain.Context |
| 36 | } | 40 | } |
| 37 | 41 | ||
| @@ -46,7 +50,10 @@ func (cmd *SearchLogCommand) Valid(validation *validation.Validation) { | @@ -46,7 +50,10 @@ func (cmd *SearchLogCommand) Valid(validation *validation.Validation) { | ||
| 46 | } | 50 | } |
| 47 | if cmd.Year > 0 && cmd.Month > 0 && cmd.Day > 0 { | 51 | if cmd.Year > 0 && cmd.Month > 0 && cmd.Day > 0 { |
| 48 | cmd.BeginTime = time.Date(cmd.Year, time.Month(cmd.Month), cmd.Day, 0, 0, 0, 0, time.Local) | 52 | cmd.BeginTime = time.Date(cmd.Year, time.Month(cmd.Month), cmd.Day, 0, 0, 0, 0, time.Local) |
| 49 | - cmd.EndTime = cmd.BeginTime.AddDate(0, 0, cmd.Day) | 53 | + cmd.EndTime = cmd.BeginTime.AddDate(0, 0, 1) |
| 54 | + } | ||
| 55 | + if cmd.PageNumber == 0 { | ||
| 56 | + cmd.PageNumber = 1 | ||
| 50 | } | 57 | } |
| 51 | } | 58 | } |
| 52 | 59 |
| @@ -21,6 +21,10 @@ type VerifiedStepLogDto struct { | @@ -21,6 +21,10 @@ type VerifiedStepLogDto struct { | ||
| 21 | //OperatorName string `json:"operatorName"` | 21 | //OperatorName string `json:"operatorName"` |
| 22 | // 创建时间 | 22 | // 创建时间 |
| 23 | CreatedAt string `json:"createdAt"` | 23 | CreatedAt string `json:"createdAt"` |
| 24 | + // 错误级别 | ||
| 25 | + Level string `json:"level"` | ||
| 26 | + // 错误信息 | ||
| 27 | + Error string `json:"error"` | ||
| 24 | } | 28 | } |
| 25 | 29 | ||
| 26 | func (d *VerifiedStepLogDto) Load(m *domain.Log) { | 30 | func (d *VerifiedStepLogDto) Load(m *domain.Log) { |
| @@ -32,4 +36,9 @@ func (d *VerifiedStepLogDto) Load(m *domain.Log) { | @@ -32,4 +36,9 @@ func (d *VerifiedStepLogDto) Load(m *domain.Log) { | ||
| 32 | d.Content = m.Content | 36 | d.Content = m.Content |
| 33 | //d.OperatorName = m.OperatorName | 37 | //d.OperatorName = m.OperatorName |
| 34 | d.CreatedAt = m.CreatedAt.Local().Format("2006-01-02 15:04:05") | 38 | d.CreatedAt = m.CreatedAt.Local().Format("2006-01-02 15:04:05") |
| 39 | + d.Level = m.Entry.Level | ||
| 40 | + d.Error = m.Entry.Error | ||
| 41 | + if len(d.Level) == 0 { | ||
| 42 | + d.Level = domain.LevelInfo.ToString() | ||
| 43 | + } | ||
| 35 | } | 44 | } |
| @@ -12,11 +12,9 @@ import ( | @@ -12,11 +12,9 @@ import ( | ||
| 12 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" | 12 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" |
| 13 | ) | 13 | ) |
| 14 | 14 | ||
| 15 | -// 日志服务 | ||
| 16 | type LogService struct { | 15 | type LogService struct { |
| 17 | } | 16 | } |
| 18 | 17 | ||
| 19 | -// 创建日志服务 | ||
| 20 | func (logService *LogService) CreateLog(createLogCommand *command.CreateLogCommand) (interface{}, error) { | 18 | func (logService *LogService) CreateLog(createLogCommand *command.CreateLogCommand) (interface{}, error) { |
| 21 | if err := createLogCommand.ValidateCommand(); err != nil { | 19 | if err := createLogCommand.ValidateCommand(); err != nil { |
| 22 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 20 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -56,7 +54,6 @@ func (logService *LogService) CreateLog(createLogCommand *command.CreateLogComma | @@ -56,7 +54,6 @@ func (logService *LogService) CreateLog(createLogCommand *command.CreateLogComma | ||
| 56 | } | 54 | } |
| 57 | } | 55 | } |
| 58 | 56 | ||
| 59 | -// 返回日志服务 | ||
| 60 | func (logService *LogService) GetLog(getLogQuery *query.GetLogQuery) (interface{}, error) { | 57 | func (logService *LogService) GetLog(getLogQuery *query.GetLogQuery) (interface{}, error) { |
| 61 | if err := getLogQuery.ValidateQuery(); err != nil { | 58 | if err := getLogQuery.ValidateQuery(); err != nil { |
| 62 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 59 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -93,7 +90,6 @@ func (logService *LogService) GetLog(getLogQuery *query.GetLogQuery) (interface{ | @@ -93,7 +90,6 @@ func (logService *LogService) GetLog(getLogQuery *query.GetLogQuery) (interface{ | ||
| 93 | } | 90 | } |
| 94 | } | 91 | } |
| 95 | 92 | ||
| 96 | -// 返回日志服务列表 | ||
| 97 | func (logService *LogService) ListLog(listLogQuery *query.ListLogQuery) (interface{}, error) { | 93 | func (logService *LogService) ListLog(listLogQuery *query.ListLogQuery) (interface{}, error) { |
| 98 | if err := listLogQuery.ValidateQuery(); err != nil { | 94 | if err := listLogQuery.ValidateQuery(); err != nil { |
| 99 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 95 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -129,7 +125,6 @@ func (logService *LogService) ListLog(listLogQuery *query.ListLogQuery) (interfa | @@ -129,7 +125,6 @@ func (logService *LogService) ListLog(listLogQuery *query.ListLogQuery) (interfa | ||
| 129 | } | 125 | } |
| 130 | } | 126 | } |
| 131 | 127 | ||
| 132 | -// 移除日志服务 | ||
| 133 | func (logService *LogService) RemoveLog(removeLogCommand *command.RemoveLogCommand) (interface{}, error) { | 128 | func (logService *LogService) RemoveLog(removeLogCommand *command.RemoveLogCommand) (interface{}, error) { |
| 134 | if err := removeLogCommand.ValidateCommand(); err != nil { | 129 | if err := removeLogCommand.ValidateCommand(); err != nil { |
| 135 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 130 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -169,7 +164,6 @@ func (logService *LogService) RemoveLog(removeLogCommand *command.RemoveLogComma | @@ -169,7 +164,6 @@ func (logService *LogService) RemoveLog(removeLogCommand *command.RemoveLogComma | ||
| 169 | } | 164 | } |
| 170 | } | 165 | } |
| 171 | 166 | ||
| 172 | -// 搜索日志 | ||
| 173 | func (logService *LogService) SearchLog(searchLogCommand *command.SearchLogCommand) (int64, interface{}, error) { | 167 | func (logService *LogService) SearchLog(searchLogCommand *command.SearchLogCommand) (int64, interface{}, error) { |
| 174 | if err := searchLogCommand.ValidateCommand(); err != nil { | 168 | if err := searchLogCommand.ValidateCommand(); err != nil { |
| 175 | return 0, nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 169 | return 0, nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -204,7 +198,6 @@ func (logService *LogService) SearchLog(searchLogCommand *command.SearchLogComma | @@ -204,7 +198,6 @@ func (logService *LogService) SearchLog(searchLogCommand *command.SearchLogComma | ||
| 204 | return count, result, nil | 198 | return count, result, nil |
| 205 | } | 199 | } |
| 206 | 200 | ||
| 207 | -// 搜索日志 | ||
| 208 | func (logService *LogService) VerifiedStepLog(searchLogCommand *command.SearchLogCommand) (int64, interface{}, error) { | 201 | func (logService *LogService) VerifiedStepLog(searchLogCommand *command.SearchLogCommand) (int64, interface{}, error) { |
| 209 | if err := searchLogCommand.ValidateCommand(); err != nil { | 202 | if err := searchLogCommand.ValidateCommand(); err != nil { |
| 210 | return 0, nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 203 | return 0, nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -252,7 +245,6 @@ func (logService *LogService) VerifiedStepLog(searchLogCommand *command.SearchLo | @@ -252,7 +245,6 @@ func (logService *LogService) VerifiedStepLog(searchLogCommand *command.SearchLo | ||
| 252 | }, nil | 245 | }, nil |
| 253 | } | 246 | } |
| 254 | 247 | ||
| 255 | -// 更新日志服务 | ||
| 256 | func (logService *LogService) UpdateLog(updateLogCommand *command.UpdateLogCommand) (interface{}, error) { | 248 | func (logService *LogService) UpdateLog(updateLogCommand *command.UpdateLogCommand) (interface{}, error) { |
| 257 | if err := updateLogCommand.ValidateCommand(); err != nil { | 249 | if err := updateLogCommand.ValidateCommand(); err != nil { |
| 258 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 250 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -13,7 +13,7 @@ type UpdateMappingRuleCommand struct { | @@ -13,7 +13,7 @@ type UpdateMappingRuleCommand struct { | ||
| 13 | // 匹配规则ID | 13 | // 匹配规则ID |
| 14 | MappingRuleId int `cname:"匹配规则ID" json:"mappingRuleId" valid:"Required"` | 14 | MappingRuleId int `cname:"匹配规则ID" json:"mappingRuleId" valid:"Required"` |
| 15 | // 名称 | 15 | // 名称 |
| 16 | - Name string `cname:"名称" json:"name" valid:"Required"` | 16 | + Name string `cname:"名称" json:"name"` |
| 17 | // 校验文件列 | 17 | // 校验文件列 |
| 18 | MappingFields []*domain.MappingField `cname:"匹配规则列表" json:"mappingFields" valid:"Required"` | 18 | MappingFields []*domain.MappingField `cname:"匹配规则列表" json:"mappingFields" valid:"Required"` |
| 19 | } | 19 | } |
| @@ -13,11 +13,11 @@ import ( | @@ -13,11 +13,11 @@ import ( | ||
| 13 | "time" | 13 | "time" |
| 14 | ) | 14 | ) |
| 15 | 15 | ||
| 16 | -// 匹配规则服务 | 16 | +// MappingRuleService 匹配规则服务 |
| 17 | type MappingRuleService struct { | 17 | type MappingRuleService struct { |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | -// 创建匹配规则服务 | 20 | +// CreateMappingRule 创建匹配规则服务 |
| 21 | func (mappingRuleService *MappingRuleService) CreateMappingRule(ctx *domain.Context, cmd *command.CreateMappingRuleCommand) (interface{}, error) { | 21 | func (mappingRuleService *MappingRuleService) CreateMappingRule(ctx *domain.Context, cmd *command.CreateMappingRuleCommand) (interface{}, error) { |
| 22 | if err := cmd.ValidateCommand(); err != nil { | 22 | if err := cmd.ValidateCommand(); err != nil { |
| 23 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 23 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -47,7 +47,7 @@ func (mappingRuleService *MappingRuleService) CreateMappingRule(ctx *domain.Cont | @@ -47,7 +47,7 @@ func (mappingRuleService *MappingRuleService) CreateMappingRule(ctx *domain.Cont | ||
| 47 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 47 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | - if duplicateRule, e := mappingRuleRepository.FindOne(map[string]interface{}{"context": ctx, "name": cmd.Name}); e == nil && duplicateRule != nil { | 50 | + if duplicateRule, e := mappingRuleRepository.FindOne(map[string]interface{}{"context": ctx, "name": cmd.Name, "tableId": cmd.TableId}); e == nil && duplicateRule != nil { |
| 51 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "方案名称重复") | 51 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "方案名称重复") |
| 52 | } | 52 | } |
| 53 | 53 | ||
| @@ -81,7 +81,7 @@ func (mappingRuleService *MappingRuleService) CreateMappingRule(ctx *domain.Cont | @@ -81,7 +81,7 @@ func (mappingRuleService *MappingRuleService) CreateMappingRule(ctx *domain.Cont | ||
| 81 | return result, nil | 81 | return result, nil |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | -// 返回匹配规则服务 | 84 | +// GetMappingRule 返回匹配规则服务 |
| 85 | func (mappingRuleService *MappingRuleService) GetMappingRule(getMappingRuleQuery *query.GetMappingRuleQuery) (interface{}, error) { | 85 | func (mappingRuleService *MappingRuleService) GetMappingRule(getMappingRuleQuery *query.GetMappingRuleQuery) (interface{}, error) { |
| 86 | if err := getMappingRuleQuery.ValidateQuery(); err != nil { | 86 | if err := getMappingRuleQuery.ValidateQuery(); err != nil { |
| 87 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 87 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -109,7 +109,7 @@ func (mappingRuleService *MappingRuleService) GetMappingRule(getMappingRuleQuery | @@ -109,7 +109,7 @@ func (mappingRuleService *MappingRuleService) GetMappingRule(getMappingRuleQuery | ||
| 109 | return result, nil | 109 | return result, nil |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | -// 返回匹配规则服务列表 | 112 | +// ListMappingRule 返回匹配规则服务列表 |
| 113 | func (mappingRuleService *MappingRuleService) ListMappingRule(listMappingRuleQuery *query.ListMappingRuleQuery) (interface{}, error) { | 113 | func (mappingRuleService *MappingRuleService) ListMappingRule(listMappingRuleQuery *query.ListMappingRuleQuery) (interface{}, error) { |
| 114 | if err := listMappingRuleQuery.ValidateQuery(); err != nil { | 114 | if err := listMappingRuleQuery.ValidateQuery(); err != nil { |
| 115 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 115 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -145,7 +145,7 @@ func (mappingRuleService *MappingRuleService) ListMappingRule(listMappingRuleQue | @@ -145,7 +145,7 @@ func (mappingRuleService *MappingRuleService) ListMappingRule(listMappingRuleQue | ||
| 145 | } | 145 | } |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | -// 匹配规则预准备(新建规则) | 148 | +// Prepare 匹配规则预准备(新建规则) |
| 149 | func (mappingRuleService *MappingRuleService) Prepare(prepareCommand *command.PrepareCommand) (interface{}, error) { | 149 | func (mappingRuleService *MappingRuleService) Prepare(prepareCommand *command.PrepareCommand) (interface{}, error) { |
| 150 | if err := prepareCommand.ValidateCommand(); err != nil { | 150 | if err := prepareCommand.ValidateCommand(); err != nil { |
| 151 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 151 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -182,7 +182,7 @@ func (mappingRuleService *MappingRuleService) Prepare(prepareCommand *command.Pr | @@ -182,7 +182,7 @@ func (mappingRuleService *MappingRuleService) Prepare(prepareCommand *command.Pr | ||
| 182 | return ruleDto, nil | 182 | return ruleDto, nil |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | -// 移除匹配规则服务 | 185 | +// RemoveMappingRule 移除匹配规则服务 |
| 186 | func (mappingRuleService *MappingRuleService) RemoveMappingRule(removeMappingRuleCommand *command.RemoveMappingRuleCommand) (interface{}, error) { | 186 | func (mappingRuleService *MappingRuleService) RemoveMappingRule(removeMappingRuleCommand *command.RemoveMappingRuleCommand) (interface{}, error) { |
| 187 | if err := removeMappingRuleCommand.ValidateCommand(); err != nil { | 187 | if err := removeMappingRuleCommand.ValidateCommand(); err != nil { |
| 188 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 188 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -222,7 +222,7 @@ func (mappingRuleService *MappingRuleService) RemoveMappingRule(removeMappingRul | @@ -222,7 +222,7 @@ func (mappingRuleService *MappingRuleService) RemoveMappingRule(removeMappingRul | ||
| 222 | }{}, nil | 222 | }{}, nil |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | -// 搜索规则 | 225 | +// Search 搜索规则 |
| 226 | func (mappingRuleService *MappingRuleService) Search(searchCommand *command.SearchCommand) (interface{}, error) { | 226 | func (mappingRuleService *MappingRuleService) Search(searchCommand *command.SearchCommand) (interface{}, error) { |
| 227 | if err := searchCommand.ValidateCommand(); err != nil { | 227 | if err := searchCommand.ValidateCommand(); err != nil { |
| 228 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 228 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -259,7 +259,7 @@ func (mappingRuleService *MappingRuleService) Search(searchCommand *command.Sear | @@ -259,7 +259,7 @@ func (mappingRuleService *MappingRuleService) Search(searchCommand *command.Sear | ||
| 259 | }, nil | 259 | }, nil |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | -// 更新匹配规则服务 | 262 | +// UpdateMappingRule 更新匹配规则服务 |
| 263 | func (mappingRuleService *MappingRuleService) UpdateMappingRule(ctx *domain.Context, cmd *command.UpdateMappingRuleCommand) (interface{}, error) { | 263 | func (mappingRuleService *MappingRuleService) UpdateMappingRule(ctx *domain.Context, cmd *command.UpdateMappingRuleCommand) (interface{}, error) { |
| 264 | if err := cmd.ValidateCommand(); err != nil { | 264 | if err := cmd.ValidateCommand(); err != nil { |
| 265 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 265 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| @@ -288,11 +288,14 @@ func (mappingRuleService *MappingRuleService) UpdateMappingRule(ctx *domain.Cont | @@ -288,11 +288,14 @@ func (mappingRuleService *MappingRuleService) UpdateMappingRule(ctx *domain.Cont | ||
| 288 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 288 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | + if len(cmd.Name) != 0 { | ||
| 291 | if duplicateRule, e := mappingRuleRepository.FindOne(map[string]interface{}{"context": ctx, "name": cmd.Name}); e == nil && duplicateRule != nil && duplicateRule.MappingRuleId != cmd.MappingRuleId { | 292 | if duplicateRule, e := mappingRuleRepository.FindOne(map[string]interface{}{"context": ctx, "name": cmd.Name}); e == nil && duplicateRule != nil && duplicateRule.MappingRuleId != cmd.MappingRuleId { |
| 292 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "方案名称重复") | 293 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "方案名称重复") |
| 293 | } | 294 | } |
| 294 | - | 295 | + } |
| 296 | + if len(cmd.Name) > 0 { | ||
| 295 | mappingRule.Name = cmd.Name | 297 | mappingRule.Name = cmd.Name |
| 298 | + } | ||
| 296 | mappingRule.MappingFields = cmd.MappingFields | 299 | mappingRule.MappingFields = cmd.MappingFields |
| 297 | mappingRule.VerifiedFileFields = fileTable.Fields(false) | 300 | mappingRule.VerifiedFileFields = fileTable.Fields(false) |
| 298 | mappingRule.UpdatedAt = time.Now() | 301 | mappingRule.UpdatedAt = time.Now() |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 6 | + "reflect" | ||
| 7 | + "strings" | ||
| 8 | + | ||
| 9 | + "github.com/beego/beego/v2/core/validation" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +type ChangeStatusCommand struct { | ||
| 13 | + // 查询集合ID | ||
| 14 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
| 15 | + // 状态 1:启用 2:关闭 (子过程默认启用) | ||
| 16 | + Status int `cname:"状态 1:启用 2:关闭 (子过程默认启用)" json:"status" valid:"Required"` | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +func (changeStatusCommand *ChangeStatusCommand) Valid(validation *validation.Validation) { | ||
| 20 | + if !(changeStatusCommand.Status == domain.StatusOn || changeStatusCommand.Status == domain.StatusOff) { | ||
| 21 | + validation.Error("状态值有误") | ||
| 22 | + } | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +func (changeStatusCommand *ChangeStatusCommand) ValidateCommand() error { | ||
| 26 | + valid := validation.Validation{} | ||
| 27 | + b, err := valid.Valid(changeStatusCommand) | ||
| 28 | + if err != nil { | ||
| 29 | + return err | ||
| 30 | + } | ||
| 31 | + if !b { | ||
| 32 | + elem := reflect.TypeOf(changeStatusCommand).Elem() | ||
| 33 | + for _, validErr := range valid.Errors { | ||
| 34 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 35 | + if isExist { | ||
| 36 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 37 | + } else { | ||
| 38 | + return fmt.Errorf(validErr.Message) | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | + return nil | ||
| 43 | +} |
pkg/application/querySet/command/copy.go
0 → 100644
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 6 | + "reflect" | ||
| 7 | + "strings" | ||
| 8 | + | ||
| 9 | + "github.com/beego/beego/v2/core/validation" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +type CopyCommand struct { | ||
| 13 | + // Schema:方案 SubProcess:子过程 | ||
| 14 | + Type string `cname:"类型" json:"type" valid:"Required"` | ||
| 15 | + // 父级ID | ||
| 16 | + ParentId int `cname:"父级ID" json:"parentId" valid:"Required"` | ||
| 17 | + // 名称 | ||
| 18 | + Name string `cname:"名称" json:"name" valid:"Required"` | ||
| 19 | + // 查询集合ID | ||
| 20 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +func (cmd *CopyCommand) Valid(validation *validation.Validation) { | ||
| 24 | + if err := domain.ValidQuerySetType(cmd.Type); err != nil { | ||
| 25 | + validation.Error(err.Error()) | ||
| 26 | + return | ||
| 27 | + } | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +func (cmd *CopyCommand) ValidateCommand() error { | ||
| 31 | + valid := validation.Validation{} | ||
| 32 | + b, err := valid.Valid(cmd) | ||
| 33 | + if err != nil { | ||
| 34 | + return err | ||
| 35 | + } | ||
| 36 | + if !b { | ||
| 37 | + elem := reflect.TypeOf(cmd).Elem() | ||
| 38 | + for _, validErr := range valid.Errors { | ||
| 39 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 40 | + if isExist { | ||
| 41 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 42 | + } else { | ||
| 43 | + return fmt.Errorf(validErr.Message) | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | + } | ||
| 47 | + return nil | ||
| 48 | +} |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 6 | + "reflect" | ||
| 7 | + "strings" | ||
| 8 | + | ||
| 9 | + "github.com/beego/beego/v2/core/validation" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +type CreateQuerySetCommand struct { | ||
| 13 | + // Schema:方案 SubProcess:子过程 | ||
| 14 | + Type string `cname:"类型" json:"type" valid:"Required"` | ||
| 15 | + // 标识 | ||
| 16 | + Flag string `cname:"标识" json:"flag" valid:"Required"` | ||
| 17 | + // 名称 | ||
| 18 | + Name string `cname:"名称" json:"name"` | ||
| 19 | + // 父级ID | ||
| 20 | + ParentId int `cname:"父级ID" json:"parentId,omitempty"` | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +func (cmd *CreateQuerySetCommand) Valid(validation *validation.Validation) { | ||
| 24 | + if err := domain.ValidQuerySetType(cmd.Type); err != nil { | ||
| 25 | + validation.Error(err.Error()) | ||
| 26 | + return | ||
| 27 | + } | ||
| 28 | + if err := domain.ValidQuerySetFlag(cmd.Flag); err != nil { | ||
| 29 | + validation.Error(err.Error()) | ||
| 30 | + return | ||
| 31 | + } | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +func (cmd *CreateQuerySetCommand) ValidateCommand() error { | ||
| 35 | + valid := validation.Validation{} | ||
| 36 | + b, err := valid.Valid(cmd) | ||
| 37 | + if err != nil { | ||
| 38 | + return err | ||
| 39 | + } | ||
| 40 | + if !b { | ||
| 41 | + elem := reflect.TypeOf(cmd).Elem() | ||
| 42 | + for _, validErr := range valid.Errors { | ||
| 43 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 44 | + if isExist { | ||
| 45 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 46 | + } else { | ||
| 47 | + return fmt.Errorf(validErr.Message) | ||
| 48 | + } | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + return nil | ||
| 52 | +} |
pkg/application/querySet/command/move.go
0 → 100644
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "reflect" | ||
| 6 | + "strings" | ||
| 7 | + | ||
| 8 | + "github.com/beego/beego/v2/core/validation" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type MoveCommand struct { | ||
| 12 | + // 查询集合ID | ||
| 13 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
| 14 | + // 父级ID | ||
| 15 | + ParentId int `cname:"父级ID" json:"parentId" valid:"Required"` | ||
| 16 | + // 排序 | ||
| 17 | + Index int `cname:"序号" json:"index" valid:"Required"` | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +func (moveCommand *MoveCommand) Valid(validation *validation.Validation) { | ||
| 21 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +func (moveCommand *MoveCommand) ValidateCommand() error { | ||
| 25 | + valid := validation.Validation{} | ||
| 26 | + b, err := valid.Valid(moveCommand) | ||
| 27 | + if err != nil { | ||
| 28 | + return err | ||
| 29 | + } | ||
| 30 | + if !b { | ||
| 31 | + elem := reflect.TypeOf(moveCommand).Elem() | ||
| 32 | + for _, validErr := range valid.Errors { | ||
| 33 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 34 | + if isExist { | ||
| 35 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 36 | + } else { | ||
| 37 | + return fmt.Errorf(validErr.Message) | ||
| 38 | + } | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + return nil | ||
| 42 | +} |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "reflect" | ||
| 6 | + "strings" | ||
| 7 | + | ||
| 8 | + "github.com/beego/beego/v2/core/validation" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type RefreshQuerySetCommand struct { | ||
| 12 | + // 查询集合ID | ||
| 13 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +func (updateQuerySetCommand *RefreshQuerySetCommand) Valid(validation *validation.Validation) { | ||
| 17 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +func (updateQuerySetCommand *RefreshQuerySetCommand) ValidateCommand() error { | ||
| 21 | + valid := validation.Validation{} | ||
| 22 | + b, err := valid.Valid(updateQuerySetCommand) | ||
| 23 | + if err != nil { | ||
| 24 | + return err | ||
| 25 | + } | ||
| 26 | + if !b { | ||
| 27 | + elem := reflect.TypeOf(updateQuerySetCommand).Elem() | ||
| 28 | + for _, validErr := range valid.Errors { | ||
| 29 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 30 | + if isExist { | ||
| 31 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 32 | + } else { | ||
| 33 | + return fmt.Errorf(validErr.Message) | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + } | ||
| 37 | + return nil | ||
| 38 | +} |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "reflect" | ||
| 6 | + "strings" | ||
| 7 | + | ||
| 8 | + "github.com/beego/beego/v2/core/validation" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type RemoveQuerySetCommand struct { | ||
| 12 | + // 查询集合ID | ||
| 13 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +func (removeQuerySetCommand *RemoveQuerySetCommand) Valid(validation *validation.Validation) { | ||
| 17 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +func (removeQuerySetCommand *RemoveQuerySetCommand) ValidateCommand() error { | ||
| 21 | + valid := validation.Validation{} | ||
| 22 | + b, err := valid.Valid(removeQuerySetCommand) | ||
| 23 | + if err != nil { | ||
| 24 | + return err | ||
| 25 | + } | ||
| 26 | + if !b { | ||
| 27 | + elem := reflect.TypeOf(removeQuerySetCommand).Elem() | ||
| 28 | + for _, validErr := range valid.Errors { | ||
| 29 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 30 | + if isExist { | ||
| 31 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 32 | + } else { | ||
| 33 | + return fmt.Errorf(validErr.Message) | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + } | ||
| 37 | + return nil | ||
| 38 | +} |
pkg/application/querySet/command/rename.go
0 → 100644
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "reflect" | ||
| 6 | + "strings" | ||
| 7 | + | ||
| 8 | + "github.com/beego/beego/v2/core/validation" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type RenameCommand struct { | ||
| 12 | + // 查询集合ID | ||
| 13 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
| 14 | + // 名称 | ||
| 15 | + Name string `cname:"名称" json:"name" valid:"Required"` | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +func (renameCommand *RenameCommand) Valid(validation *validation.Validation) { | ||
| 19 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +func (renameCommand *RenameCommand) ValidateCommand() error { | ||
| 23 | + valid := validation.Validation{} | ||
| 24 | + b, err := valid.Valid(renameCommand) | ||
| 25 | + if err != nil { | ||
| 26 | + return err | ||
| 27 | + } | ||
| 28 | + if !b { | ||
| 29 | + elem := reflect.TypeOf(renameCommand).Elem() | ||
| 30 | + for _, validErr := range valid.Errors { | ||
| 31 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 32 | + if isExist { | ||
| 33 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 34 | + } else { | ||
| 35 | + return fmt.Errorf(validErr.Message) | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + return nil | ||
| 40 | +} |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 6 | + "reflect" | ||
| 7 | + "strings" | ||
| 8 | + | ||
| 9 | + "github.com/beego/beego/v2/core/validation" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +type UpdateQuerySetCommand struct { | ||
| 13 | + // 查询集合ID | ||
| 14 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
| 15 | + QueryComponents []*domain.QueryComponent `cname:"查询组件" json:"queryComponents" valid:"Required"` | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +func (updateQuerySetCommand *UpdateQuerySetCommand) Valid(validation *validation.Validation) { | ||
| 19 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +func (updateQuerySetCommand *UpdateQuerySetCommand) ValidateCommand() error { | ||
| 23 | + valid := validation.Validation{} | ||
| 24 | + b, err := valid.Valid(updateQuerySetCommand) | ||
| 25 | + if err != nil { | ||
| 26 | + return err | ||
| 27 | + } | ||
| 28 | + if !b { | ||
| 29 | + elem := reflect.TypeOf(updateQuerySetCommand).Elem() | ||
| 30 | + for _, validErr := range valid.Errors { | ||
| 31 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 32 | + if isExist { | ||
| 33 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 34 | + } else { | ||
| 35 | + return fmt.Errorf(validErr.Message) | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + return nil | ||
| 40 | +} |
| 1 | +package dto | ||
| 2 | + | ||
| 3 | +import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 4 | + | ||
| 5 | +type QuerySetDetailDto struct { | ||
| 6 | + // 查询集合ID | ||
| 7 | + QuerySetId int `json:"querySetId"` | ||
| 8 | + // Schema:方案 SubProcess:子过程 | ||
| 9 | + Type string `json:"type"` | ||
| 10 | + // 标识 分组:Group 子过程/方案:Set | ||
| 11 | + Flag string `json:"flag"` | ||
| 12 | + // 名称 | ||
| 13 | + Name string `json:"name"` | ||
| 14 | + // 查询组件 | ||
| 15 | + QueryComponents []*domain.QueryComponent `json:"queryComponents"` | ||
| 16 | + // 查询集绑定的表 | ||
| 17 | + TableId int `json:"tableId"` | ||
| 18 | + // 在冲突状态 true:冲突异常 false:正常 | ||
| 19 | + InConflict bool `json:"inConflict"` | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +func (d *QuerySetDetailDto) Load(m *domain.QuerySet, mapTables map[int]*domain.Table) *QuerySetDetailDto { | ||
| 23 | + d.QuerySetId = m.QuerySetId | ||
| 24 | + d.Type = m.Type | ||
| 25 | + d.Flag = m.Flag | ||
| 26 | + d.Name = m.Name | ||
| 27 | + d.QueryComponents = m.QueryComponents | ||
| 28 | + if m.QuerySetInfo != nil { | ||
| 29 | + d.TableId = m.QuerySetInfo.BindTableId | ||
| 30 | + } | ||
| 31 | + hasUpdateTable := false | ||
| 32 | + for i, q := range d.QueryComponents { | ||
| 33 | + if q.MasterTable != nil && q.MasterTable.TableId != 0 { | ||
| 34 | + if t, ok := mapTables[q.MasterTable.TableId]; ok { | ||
| 35 | + d.QueryComponents[i].MasterTable = domain.NewQueryComponentTable(t) | ||
| 36 | + d.QueryComponents[i].UpdateTables(t) | ||
| 37 | + hasUpdateTable = true | ||
| 38 | + } | ||
| 39 | + } | ||
| 40 | + if d.QueryComponents[i].Aggregation != nil { | ||
| 41 | + d.QueryComponents[i].Aggregation.Aggregation.AllFields = d.QueryComponents[i].Aggregation.AggregationFields() | ||
| 42 | + } | ||
| 43 | + if !hasUpdateTable && len(mapTables) == 1 { | ||
| 44 | + for _, t := range mapTables { | ||
| 45 | + d.QueryComponents[i].UpdateTables(t) | ||
| 46 | + hasUpdateTable = true | ||
| 47 | + break | ||
| 48 | + } | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + d.InConflict = false | ||
| 52 | + if m.QuerySetInfo != nil { | ||
| 53 | + if m.QuerySetInfo.ReadyStatus == 1 { | ||
| 54 | + d.InConflict = true | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + return d | ||
| 58 | +} |
| 1 | +package dto | ||
| 2 | + | ||
| 3 | +import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 4 | + | ||
| 5 | +type QuerySetDto struct { | ||
| 6 | + // 查询集合ID | ||
| 7 | + QuerySetId int `json:"querySetId"` | ||
| 8 | + // Schema:方案 SubProcess:子过程 | ||
| 9 | + Type string `json:"type"` | ||
| 10 | + // 标识 分组:Group 子过程/方案:Set | ||
| 11 | + Flag string `json:"flag"` | ||
| 12 | + // 名称 | ||
| 13 | + Name string `json:"name"` | ||
| 14 | + // 父级ID | ||
| 15 | + ParentId int `json:"parentId"` | ||
| 16 | + // 状态 1:启用 2:关闭 (子过程默认启用) | ||
| 17 | + Status int `json:"status"` | ||
| 18 | + // 排序 | ||
| 19 | + Sort int `json:"sort"` | ||
| 20 | + // 时间 | ||
| 21 | + Time string `json:"time"` | ||
| 22 | + // 绑定的表ID | ||
| 23 | + BindTableId int `json:"tableId"` | ||
| 24 | + // 在冲突状态 true:冲突异常 false:正常 | ||
| 25 | + InConflict bool `json:"inConflict"` | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +func (d *QuerySetDto) Load(m *domain.QuerySet) *QuerySetDto { | ||
| 29 | + d.QuerySetId = m.QuerySetId | ||
| 30 | + d.Type = m.Type | ||
| 31 | + d.Flag = m.Flag | ||
| 32 | + d.Name = m.Name | ||
| 33 | + d.ParentId = m.ParentId | ||
| 34 | + d.Status = m.Status | ||
| 35 | + d.Sort = m.Sort | ||
| 36 | + d.Time = m.CreatedAt.Local().Format("2006-01-02 15:04:05") | ||
| 37 | + d.BindTableId = m.QuerySetInfo.BindTableId | ||
| 38 | + d.InConflict = m.QuerySetInfo.ReadyStatus == 1 | ||
| 39 | + return d | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +func NewQuerySetDtoList(querySets []*domain.QuerySet) []*QuerySetDto { | ||
| 43 | + var result = make([]*QuerySetDto, 0) | ||
| 44 | + for _, set := range querySets { | ||
| 45 | + var item = &QuerySetDto{} | ||
| 46 | + item.Load(set) | ||
| 47 | + result = append(result, item) | ||
| 48 | + } | ||
| 49 | + return result | ||
| 50 | +} |
| 1 | +package query | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 6 | + "reflect" | ||
| 7 | + "strings" | ||
| 8 | + | ||
| 9 | + "github.com/beego/beego/v2/core/validation" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +type CalculateItemPreviewQuery struct { | ||
| 13 | + // 查询集合ID | ||
| 14 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
| 15 | + // 公式 | ||
| 16 | + Formula *domain.FieldExpr `json:"formula" valid:"Required"` | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +func (dependencyGraphQuery *CalculateItemPreviewQuery) Valid(validation *validation.Validation) { | ||
| 20 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +func (dependencyGraphQuery *CalculateItemPreviewQuery) ValidateQuery() error { | ||
| 24 | + valid := validation.Validation{} | ||
| 25 | + b, err := valid.Valid(dependencyGraphQuery) | ||
| 26 | + if err != nil { | ||
| 27 | + return err | ||
| 28 | + } | ||
| 29 | + if !b { | ||
| 30 | + elem := reflect.TypeOf(dependencyGraphQuery).Elem() | ||
| 31 | + for _, validErr := range valid.Errors { | ||
| 32 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 33 | + if isExist { | ||
| 34 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 35 | + } else { | ||
| 36 | + return fmt.Errorf(validErr.Message) | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + } | ||
| 40 | + return nil | ||
| 41 | +} |
| 1 | +package query | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "reflect" | ||
| 6 | + "strings" | ||
| 7 | + | ||
| 8 | + "github.com/beego/beego/v2/core/validation" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type DependencyGraphQuery struct { | ||
| 12 | + // 查询集合ID | ||
| 13 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +func (dependencyGraphQuery *DependencyGraphQuery) Valid(validation *validation.Validation) { | ||
| 17 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +func (dependencyGraphQuery *DependencyGraphQuery) ValidateQuery() error { | ||
| 21 | + valid := validation.Validation{} | ||
| 22 | + b, err := valid.Valid(dependencyGraphQuery) | ||
| 23 | + if err != nil { | ||
| 24 | + return err | ||
| 25 | + } | ||
| 26 | + if !b { | ||
| 27 | + elem := reflect.TypeOf(dependencyGraphQuery).Elem() | ||
| 28 | + for _, validErr := range valid.Errors { | ||
| 29 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 30 | + if isExist { | ||
| 31 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 32 | + } else { | ||
| 33 | + return fmt.Errorf(validErr.Message) | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + } | ||
| 37 | + return nil | ||
| 38 | +} |
| 1 | +package query | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "reflect" | ||
| 6 | + "strings" | ||
| 7 | + | ||
| 8 | + "github.com/beego/beego/v2/core/validation" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type GetQuerySetQuery struct { | ||
| 12 | + // 查询集合ID | ||
| 13 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +func (getQuerySetQuery *GetQuerySetQuery) Valid(validation *validation.Validation) { | ||
| 17 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +func (getQuerySetQuery *GetQuerySetQuery) ValidateQuery() error { | ||
| 21 | + valid := validation.Validation{} | ||
| 22 | + b, err := valid.Valid(getQuerySetQuery) | ||
| 23 | + if err != nil { | ||
| 24 | + return err | ||
| 25 | + } | ||
| 26 | + if !b { | ||
| 27 | + elem := reflect.TypeOf(getQuerySetQuery).Elem() | ||
| 28 | + for _, validErr := range valid.Errors { | ||
| 29 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 30 | + if isExist { | ||
| 31 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 32 | + } else { | ||
| 33 | + return fmt.Errorf(validErr.Message) | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + } | ||
| 37 | + return nil | ||
| 38 | +} |
| 1 | +package query | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "reflect" | ||
| 6 | + "strings" | ||
| 7 | + | ||
| 8 | + "github.com/beego/beego/v2/core/validation" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type ListQuerySetQuery struct { | ||
| 12 | + // 查询偏离量 | ||
| 13 | + Offset int `cname:"查询偏离量" json:"offset" valid:"Required"` | ||
| 14 | + // 查询限制 | ||
| 15 | + Limit int `cname:"查询限制" json:"limit" valid:"Required"` | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +func (listQuerySetQuery *ListQuerySetQuery) Valid(validation *validation.Validation) { | ||
| 19 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +func (listQuerySetQuery *ListQuerySetQuery) ValidateQuery() error { | ||
| 23 | + valid := validation.Validation{} | ||
| 24 | + b, err := valid.Valid(listQuerySetQuery) | ||
| 25 | + if err != nil { | ||
| 26 | + return err | ||
| 27 | + } | ||
| 28 | + if !b { | ||
| 29 | + elem := reflect.TypeOf(listQuerySetQuery).Elem() | ||
| 30 | + for _, validErr := range valid.Errors { | ||
| 31 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 32 | + if isExist { | ||
| 33 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 34 | + } else { | ||
| 35 | + return fmt.Errorf(validErr.Message) | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + return nil | ||
| 40 | +} |
| 1 | +package query | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/beego/beego/v2/core/validation" | ||
| 6 | + "reflect" | ||
| 7 | + "strings" | ||
| 8 | +) | ||
| 9 | + | ||
| 10 | +type StatisticsQuery struct { | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +func (q *StatisticsQuery) Valid(validation *validation.Validation) { | ||
| 14 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +func (q *StatisticsQuery) ValidateQuery() error { | ||
| 18 | + valid := validation.Validation{} | ||
| 19 | + b, err := valid.Valid(q) | ||
| 20 | + if err != nil { | ||
| 21 | + return err | ||
| 22 | + } | ||
| 23 | + if !b { | ||
| 24 | + elem := reflect.TypeOf(q).Elem() | ||
| 25 | + for _, validErr := range valid.Errors { | ||
| 26 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 27 | + if isExist { | ||
| 28 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 29 | + } else { | ||
| 30 | + return fmt.Errorf(validErr.Message) | ||
| 31 | + } | ||
| 32 | + } | ||
| 33 | + } | ||
| 34 | + return nil | ||
| 35 | +} |
| 1 | +package query | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/beego/beego/v2/adapter/utils" | ||
| 6 | + "reflect" | ||
| 7 | + "strings" | ||
| 8 | + | ||
| 9 | + "github.com/beego/beego/v2/core/validation" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +type SearchQuerySetQuery struct { | ||
| 13 | + Type string `cname:"类型" json:"type"` | ||
| 14 | + Types []string `cname:"类型" json:"types"` | ||
| 15 | + Flag string `cname:"标识" json:"flag"` | ||
| 16 | + Status int `cname:"状态 1:启用 2:关闭" json:"status"` | ||
| 17 | + MatchName string `cname:"匹配名称" json:"matchName"` | ||
| 18 | + SortByName string `json:"sortByName"` | ||
| 19 | + SortByTime string `json:"sortByTime"` | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +func (searchQuerySetQuery *SearchQuerySetQuery) Valid(validation *validation.Validation) { | ||
| 23 | + optionsValues := []string{"asc", "desc"} | ||
| 24 | + if searchQuerySetQuery.SortByName != "" && !utils.InSlice(strings.ToLower(searchQuerySetQuery.SortByName), optionsValues) { | ||
| 25 | + validation.Error("排序值有误 ASC|DESC") | ||
| 26 | + } | ||
| 27 | + if searchQuerySetQuery.SortByTime != "" && !utils.InSlice(strings.ToLower(searchQuerySetQuery.SortByTime), optionsValues) { | ||
| 28 | + validation.Error("排序值有误 ASC|DESC") | ||
| 29 | + } | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +func (searchQuerySetQuery *SearchQuerySetQuery) ValidateQuery() error { | ||
| 33 | + valid := validation.Validation{} | ||
| 34 | + b, err := valid.Valid(searchQuerySetQuery) | ||
| 35 | + if err != nil { | ||
| 36 | + return err | ||
| 37 | + } | ||
| 38 | + if !b { | ||
| 39 | + elem := reflect.TypeOf(searchQuerySetQuery).Elem() | ||
| 40 | + for _, validErr := range valid.Errors { | ||
| 41 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 42 | + if isExist { | ||
| 43 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 44 | + } else { | ||
| 45 | + return fmt.Errorf(validErr.Message) | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | + } | ||
| 49 | + return nil | ||
| 50 | +} |
| 1 | +package service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/linmadan/egglib-go/core/application" | ||
| 6 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | ||
| 7 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/querySet/command" | ||
| 8 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/dto" | ||
| 9 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 10 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/excel" | ||
| 11 | + "time" | ||
| 12 | +) | ||
| 13 | + | ||
| 14 | +// CalculateSetPreview 计算集预览 | ||
| 15 | +func (querySetService *QuerySetService) CalculateSetPreview(ctx *domain.Context, updateQuerySetCommand *command.UpdateQuerySetCommand) (interface{}, error) { | ||
| 16 | + if err := updateQuerySetCommand.ValidateCommand(); err != nil { | ||
| 17 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 18 | + } | ||
| 19 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 20 | + if err != nil { | ||
| 21 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 22 | + } | ||
| 23 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 24 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 25 | + } | ||
| 26 | + defer func() { | ||
| 27 | + transactionContext.RollbackTransaction() | ||
| 28 | + }() | ||
| 29 | + | ||
| 30 | + var querySet *domain.QuerySet | ||
| 31 | + _, querySet, err = factory.FastPgQuerySet(transactionContext, updateQuerySetCommand.QuerySetId) | ||
| 32 | + if err != nil { | ||
| 33 | + return nil, factory.FastError(err) | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + svr, _ := factory.FastQuerySetServices(transactionContext) | ||
| 37 | + var dataTable *domain.DataTable | ||
| 38 | + dataTable, err = svr.LoadCalculateSetData(ctx, querySet, updateQuerySetCommand.QueryComponents) | ||
| 39 | + if err != nil { | ||
| 40 | + return nil, factory.FastError(err) | ||
| 41 | + } | ||
| 42 | + response := (&dto.TablePreviewDto{}) | ||
| 43 | + response.ObjectType = querySet.Type | ||
| 44 | + response.Name = querySet.Name | ||
| 45 | + response.Fields = dataTable.Fields | ||
| 46 | + response.Data = domain.GripData(domain.ToFieldData(dataTable.Fields, dataTable.Data, false, true), int64(len(dataTable.Data))) | ||
| 47 | + | ||
| 48 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 49 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 50 | + } | ||
| 51 | + return response, nil | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +// CalculateSetExport 计算集导出 | ||
| 55 | +func (querySetService *QuerySetService) CalculateSetExport(ctx *domain.Context, updateQuerySetCommand *command.UpdateQuerySetCommand) (interface{}, error) { | ||
| 56 | + if err := updateQuerySetCommand.ValidateCommand(); err != nil { | ||
| 57 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 58 | + } | ||
| 59 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 60 | + if err != nil { | ||
| 61 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 62 | + } | ||
| 63 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 64 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 65 | + } | ||
| 66 | + defer func() { | ||
| 67 | + transactionContext.RollbackTransaction() | ||
| 68 | + }() | ||
| 69 | + | ||
| 70 | + var querySet *domain.QuerySet | ||
| 71 | + _, querySet, err = factory.FastPgQuerySet(transactionContext, updateQuerySetCommand.QuerySetId) | ||
| 72 | + if err != nil { | ||
| 73 | + return nil, factory.FastError(err) | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + svr, _ := factory.FastQuerySetServices(transactionContext) | ||
| 77 | + var dataTable *domain.DataTable | ||
| 78 | + dataTable, err = svr.LoadCalculateSetData(ctx, querySet, updateQuerySetCommand.QueryComponents) | ||
| 79 | + if err != nil { | ||
| 80 | + return nil, factory.FastError(err) | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + var fields []string | ||
| 84 | + filename := fmt.Sprintf("%v_%v.xlsx", querySet.Name, time.Now().Format("060102150405")) | ||
| 85 | + path := fmt.Sprintf("public/%v", filename) | ||
| 86 | + for _, f := range dataTable.Fields { | ||
| 87 | + fields = append(fields, f.Name) | ||
| 88 | + } | ||
| 89 | + excelWriter := excel.NewXLXSWriterTo(fields, dataTable.Data) | ||
| 90 | + excelWriter.IgnoreTitle = false | ||
| 91 | + if err = excelWriter.Save(path); err != nil { | ||
| 92 | + return nil, factory.FastError(err) | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 96 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 97 | + } | ||
| 98 | + return map[string]interface{}{ | ||
| 99 | + "url": domain.DownloadUrl(filename), | ||
| 100 | + }, err | ||
| 101 | +} |
-
请 注册 或 登录 后发表评论