正在显示
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 | +} |
-
请 注册 或 登录 后发表评论