正在显示
29 个修改的文件
包含
1070 行增加
和
13 行删除
| @@ -18,13 +18,14 @@ require ( | @@ -18,13 +18,14 @@ require ( | ||
| 18 | github.com/onsi/gomega v1.11.0 | 18 | github.com/onsi/gomega v1.11.0 |
| 19 | github.com/sergi/go-diff v1.2.0 // indirect | 19 | github.com/sergi/go-diff v1.2.0 // indirect |
| 20 | github.com/smartystreets/goconvey v1.7.2 // indirect | 20 | github.com/smartystreets/goconvey v1.7.2 // indirect |
| 21 | - github.com/tal-tech/go-zero v1.0.27 | 21 | + github.com/stretchr/testify v1.7.0 |
| 22 | github.com/valyala/fasthttp v1.32.0 // indirect | 22 | github.com/valyala/fasthttp v1.32.0 // indirect |
| 23 | github.com/xeipuuv/gojsonschema v1.2.0 // indirect | 23 | github.com/xeipuuv/gojsonschema v1.2.0 // indirect |
| 24 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect | 24 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect |
| 25 | github.com/yudai/gojsondiff v1.0.0 // indirect | 25 | github.com/yudai/gojsondiff v1.0.0 // indirect |
| 26 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect | 26 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect |
| 27 | github.com/yudai/pp v2.0.1+incompatible // indirect | 27 | github.com/yudai/pp v2.0.1+incompatible // indirect |
| 28 | + golang.org/x/text v0.3.6 | ||
| 28 | ) | 29 | ) |
| 29 | 30 | ||
| 30 | -replace github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 => github.com/tiptok/egglib-go v0.0.0-20210608073225-c852ce95ae34 | 31 | +replace github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 => github.com/tiptok/egglib-go v0.0.0-20220120032512-24dfab2b4987 |
| @@ -305,6 +305,10 @@ github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFB | @@ -305,6 +305,10 @@ github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFB | ||
| 305 | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= | 305 | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= |
| 306 | github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= | 306 | github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= |
| 307 | github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= | 307 | github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= |
| 308 | +github.com/richardlehane/mscfb v1.0.3 h1:rD8TBkYWkObWO0oLDFCbwMeZ4KoalxQy+QgniCj3nKI= | ||
| 309 | +github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= | ||
| 310 | +github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o= | ||
| 311 | +github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= | ||
| 308 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= | 312 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= |
| 309 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= | 313 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= |
| 310 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | 314 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= |
| @@ -347,8 +351,8 @@ github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2K | @@ -347,8 +351,8 @@ github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2K | ||
| 347 | github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= | 351 | github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= |
| 348 | github.com/tal-tech/go-zero v1.0.27 h1:QMIbaTxibMc/OsO5RTAuKZ8ndbl2dGN6pITQEtp2x/A= | 352 | github.com/tal-tech/go-zero v1.0.27 h1:QMIbaTxibMc/OsO5RTAuKZ8ndbl2dGN6pITQEtp2x/A= |
| 349 | github.com/tal-tech/go-zero v1.0.27/go.mod h1:JtNXlsh/CgeIHyQnt5C5M2IcSevW7V0NAnqO93TQgm8= | 353 | github.com/tal-tech/go-zero v1.0.27/go.mod h1:JtNXlsh/CgeIHyQnt5C5M2IcSevW7V0NAnqO93TQgm8= |
| 350 | -github.com/tiptok/egglib-go v0.0.0-20210608073225-c852ce95ae34 h1:9iDNyYbfpv5KLWDLpDywD/aIODg+PNnwn+v9on7KGlE= | ||
| 351 | -github.com/tiptok/egglib-go v0.0.0-20210608073225-c852ce95ae34/go.mod h1:KT8WFA2LPo5zVKbomCR6HocO4prnIY9DUVGekA3Ifo4= | 354 | +github.com/tiptok/egglib-go v0.0.0-20220120032512-24dfab2b4987 h1:0e2hOSL+//5AL7e1r3xCGEugsOPsw2POAm82VZvWLe4= |
| 355 | +github.com/tiptok/egglib-go v0.0.0-20220120032512-24dfab2b4987/go.mod h1:xl9i83IKNUkwlobRF6XLKn1RRbZsT+7yhCicpTGWTKc= | ||
| 352 | github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | 356 | github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= |
| 353 | github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | 357 | github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= |
| 354 | github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= | 358 | github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= |
| @@ -381,6 +385,10 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 | @@ -381,6 +385,10 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 | ||
| 381 | github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= | 385 | github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= |
| 382 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= | 386 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= |
| 383 | github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= | 387 | github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= |
| 388 | +github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 h1:EpI0bqf/eX9SdZDwlMmahKM+CDBgNbsXMhsN28XrM8o= | ||
| 389 | +github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= | ||
| 390 | +github.com/xuri/excelize/v2 v2.4.1 h1:veeeFLAJwsNEBPBlDepzPIYS1eLyBVcXNZUW79exZ1E= | ||
| 391 | +github.com/xuri/excelize/v2 v2.4.1/go.mod h1:rSu0C3papjzxQA3sdK8cU544TebhrPUoTOaGPIh0Q1A= | ||
| 384 | github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY= | 392 | github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY= |
| 385 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= | 393 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= |
| 386 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= | 394 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= |
| @@ -427,9 +435,12 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U | @@ -427,9 +435,12 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U | ||
| 427 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | 435 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= |
| 428 | golang.org/x/crypto v0.0.0-20210218145215-b8e89b74b9df/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= | 436 | golang.org/x/crypto v0.0.0-20210218145215-b8e89b74b9df/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= |
| 429 | golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= | 437 | golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= |
| 430 | -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc= | ||
| 431 | golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= | 438 | golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= |
| 439 | +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= | ||
| 440 | +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||
| 432 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | 441 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= |
| 442 | +golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk= | ||
| 443 | +golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= | ||
| 433 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | 444 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= |
| 434 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= | 445 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= |
| 435 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | 446 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= |
| @@ -463,8 +474,9 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY | @@ -463,8 +474,9 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY | ||
| 463 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | 474 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= |
| 464 | golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | 475 | golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= |
| 465 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | 476 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= |
| 466 | -golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I= | ||
| 467 | golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | 477 | golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= |
| 478 | +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8= | ||
| 479 | +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||
| 468 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | 480 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= |
| 469 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | 481 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
| 470 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | 482 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
| @@ -504,8 +516,9 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w | @@ -504,8 +516,9 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w | ||
| 504 | golang.org/x/sys v0.0.0-20210218155724-8ebf48af031b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | 516 | golang.org/x/sys v0.0.0-20210218155724-8ebf48af031b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
| 505 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | 517 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
| 506 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | 518 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
| 507 | -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E= | ||
| 508 | golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | 519 | golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 520 | +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= | ||
| 521 | +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
| 509 | golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= | 522 | golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= |
| 510 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | 523 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= |
| 511 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | 524 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "encoding/json" | ||
| 5 | + "fmt" | ||
| 6 | + "github.com/beego/beego/v2/core/validation" | ||
| 7 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
| 8 | +) | ||
| 9 | + | ||
| 10 | +type ExportDataCommand struct { | ||
| 11 | + //操作人 | ||
| 12 | + Operator *domain.OperateInfo `json:"-"` | ||
| 13 | + // 业务编码 | ||
| 14 | + Ids []string `json:"ids"` | ||
| 15 | + Where json.RawMessage `json:"where"` | ||
| 16 | + // 业务编码 | ||
| 17 | + Code string `form:"code"` | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +func (exportDataCommand *ExportDataCommand) Valid(validation *validation.Validation) { | ||
| 21 | + | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +func (exportDataCommand *ExportDataCommand) ValidateCommand() error { | ||
| 25 | + valid := validation.Validation{} | ||
| 26 | + b, err := valid.Valid(exportDataCommand) | ||
| 27 | + if err != nil { | ||
| 28 | + return err | ||
| 29 | + } | ||
| 30 | + if !b { | ||
| 31 | + for _, validErr := range valid.Errors { | ||
| 32 | + return fmt.Errorf("%s %s", validErr.Key, validErr.Message) | ||
| 33 | + } | ||
| 34 | + } | ||
| 35 | + return nil | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +func (exportDataCommand *ExportDataCommand) UnmarshalQuery(query interface{}) error { | ||
| 39 | + return json.Unmarshal(exportDataCommand.Where, query) | ||
| 40 | +} |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/beego/beego/v2/core/validation" | ||
| 6 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
| 7 | + "io" | ||
| 8 | +) | ||
| 9 | + | ||
| 10 | +type ImportDataCommand struct { | ||
| 11 | + //操作人 | ||
| 12 | + Operator *domain.OperateInfo `json:"-"` | ||
| 13 | + Reader io.Reader `json:"-"` | ||
| 14 | + FileExt string `json:"-"` | ||
| 15 | + // 业务编码 | ||
| 16 | + Code string `form:"code"` | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +func (importDataCommand *ImportDataCommand) Valid(validation *validation.Validation) { | ||
| 20 | + | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +func (importDataCommand *ImportDataCommand) ValidateCommand() error { | ||
| 24 | + valid := validation.Validation{} | ||
| 25 | + b, err := valid.Valid(importDataCommand) | ||
| 26 | + if err != nil { | ||
| 27 | + return err | ||
| 28 | + } | ||
| 29 | + if !b { | ||
| 30 | + for _, validErr := range valid.Errors { | ||
| 31 | + return fmt.Errorf("%s %s", validErr.Key, validErr.Message) | ||
| 32 | + } | ||
| 33 | + } | ||
| 34 | + return nil | ||
| 35 | +} |
| 1 | +package query | ||
| 2 | + | ||
| 3 | +import () | ||
| 4 | + | ||
| 5 | +type CooperationUserListQuery struct { | ||
| 6 | + //操作人 | ||
| 7 | + //Operator domain.Operator `json:"-"` | ||
| 8 | + //用户名称 | ||
| 9 | + UserName string `json:"userName"` | ||
| 10 | + //共创公司 | ||
| 11 | + CooperationCompany string `json:"cooperationCompany"` | ||
| 12 | + SelectedField []string `json:"selectedField"` | ||
| 13 | +} |
pkg/application/ecelData/service/export.go
0 → 100644
| 1 | +package service | ||
| 2 | + | ||
| 3 | +// ExportCompanyUser 导出公司用户信息列表 | ||
| 4 | +//func (srv ExcelDataService) ExportCompanyUser(companyUserListQuery *query.CompanyUserListQuery) (ExportCompanyUserData, error) { | ||
| 5 | +// creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(companyUserListQuery.Operator) | ||
| 6 | +// result, err := creationUserGateway.UserSearch(allied_creation_user.ReqUserSearch{ | ||
| 7 | +// Limit: 10000, | ||
| 8 | +// CompanyId: companyUserListQuery.Operator.CompanyId, | ||
| 9 | +// OrganizationId: 0, | ||
| 10 | +// DepartmentId: 0, | ||
| 11 | +// UserName: companyUserListQuery.UserName, | ||
| 12 | +// DepName: companyUserListQuery.DepartmentName, | ||
| 13 | +// Phone: "", | ||
| 14 | +// UserType: domain.UserTypeEmployee, | ||
| 15 | +// InOrgIds: companyUserListQuery.Operator.OrgIds, | ||
| 16 | +// PullRealTime: true, | ||
| 17 | +// }) | ||
| 18 | +// if err != nil { | ||
| 19 | +// return ExportCompanyUserData{}, fmt.Errorf("获取企业用户数据失败:%w", err) | ||
| 20 | +// } | ||
| 21 | +// return ExportCompanyUserData{ | ||
| 22 | +// SourceData: result.Users, | ||
| 23 | +// SelectedField: companyUserListQuery.SelectedField, | ||
| 24 | +// }, nil | ||
| 25 | +//} | ||
| 26 | + | ||
| 27 | +// ExportCooperationUser 导出共创用户信息列表 | ||
| 28 | +//func (srv ExcelDataService) ExportCooperationUser(companyUserListQuery *query.CooperationUserListQuery) (ExportCooperationUserData, error) { | ||
| 29 | +// creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(companyUserListQuery.Operator) | ||
| 30 | +// result, err := creationUserGateway.UserSearch(allied_creation_user.ReqUserSearch{ | ||
| 31 | +// Limit: 10000, | ||
| 32 | +// CompanyId: companyUserListQuery.Operator.CompanyId, | ||
| 33 | +// OrganizationId: 0, | ||
| 34 | +// DepartmentId: 0, | ||
| 35 | +// UserName: companyUserListQuery.UserName, | ||
| 36 | +// CooperationCompany: companyUserListQuery.CooperationCompany, | ||
| 37 | +// Phone: "", | ||
| 38 | +// UserType: domain.UserTypeCooperation, | ||
| 39 | +// InOrgIds: companyUserListQuery.Operator.OrgIds, | ||
| 40 | +// }) | ||
| 41 | +// if err != nil { | ||
| 42 | +// return ExportCooperationUserData{}, fmt.Errorf("获取企业用户数据失败:%w", err) | ||
| 43 | +// } | ||
| 44 | +// return ExportCooperationUserData{SourceData: result.Users, SelectedField: companyUserListQuery.SelectedField}, nil | ||
| 45 | +//} |
pkg/application/ecelData/service/import.go
0 → 100644
| 1 | +package service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/linmadan/egglib-go/core/application" | ||
| 6 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/ecelData/command" | ||
| 7 | + "strings" | ||
| 8 | + | ||
| 9 | + "github.com/linmadan/egglib-go/utils/excel" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +type ExcelDataService struct { | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +func NewExcelDataService(param map[string]interface{}) *ExcelDataService { | ||
| 16 | + return &ExcelDataService{} | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +// 导入结果 | ||
| 20 | +func (srv ExcelDataService) importResultWithHeader(headers []excel.DataField, failRows []interface{}, totalRow int) interface{} { | ||
| 21 | + var result = map[string]interface{}{ | ||
| 22 | + "successCount": 0, | ||
| 23 | + "fail": struct{}{}, | ||
| 24 | + } | ||
| 25 | + if len(failRows) == 0 { | ||
| 26 | + result["successCount"] = totalRow | ||
| 27 | + } | ||
| 28 | + if len(failRows) > 0 { | ||
| 29 | + fail := map[string]interface{}{ | ||
| 30 | + "body": failRows, | ||
| 31 | + } | ||
| 32 | + var header = make(map[string]string) | ||
| 33 | + for i := 0; i < len(headers); i++ { | ||
| 34 | + item := headers[i] | ||
| 35 | + header[item.EnName] = item.CnName | ||
| 36 | + } | ||
| 37 | + fail["header"] = header | ||
| 38 | + result["fail"] = fail | ||
| 39 | + } | ||
| 40 | + return result | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +func (srv ExcelDataService) fieldValueAllEmpty(param map[string]string) bool { | ||
| 44 | + isAllEmpty := true | ||
| 45 | + for _, v := range param { | ||
| 46 | + value := strings.TrimSpace(v) | ||
| 47 | + if len(value) > 0 { | ||
| 48 | + isAllEmpty = false | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + return isAllEmpty | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +//// FileImportTemplate 导入模板 | ||
| 55 | +func (srv ExcelDataService) FileImportTemplate(importDataCommand *command.ImportDataCommand) (interface{}, error) { | ||
| 56 | + var mapTemplate = map[string]string{ | ||
| 57 | + //domain.ImportCompanyUser: "https://timeless-world.oss-cn-shenzhen.aliyuncs.com/open-api/dev_online/20210916/object/1631807485_EaxECeRz23WpzrMZmbwdEPRJ3Pdxpx5X.xlsx", | ||
| 58 | + //domain.ImportOrganization: "https://timeless-world.oss-cn-shenzhen.aliyuncs.com/open-api/dev_online/20210916/object/1631807490_r2XWhGmbWWmpbeePBkZ3EJQFKcZEMpEm.xlsx", | ||
| 59 | + //domain.ImportDividendsOrders: "https://timeless-world.oss-cn-shenzhen.aliyuncs.com/open-api/dev_online/20210927/object/1632743206_NPYTKw6RGhXn4TpYNEQhGGdCkXKXTnxM.xlsx", | ||
| 60 | + //domain.ImportCooperationUser: "https://timeless-world.oss-cn-shenzhen.aliyuncs.com/open-api/dev_online/20210926/object/1632635345_SbfzmkXjQHhCwPw4MB7zb5EBBtdp2MSE.xlsx", | ||
| 61 | + //domain.ImportDividendsReturnOrders: "https://timeless-world.oss-cn-shenzhen.aliyuncs.com/open-api/dev_online/20210927/object/1632743214_rNHm6ZBXZaC5xKTrsE7M4h45MY6n6Ff3.xlsx", | ||
| 62 | + } | ||
| 63 | + var url string | ||
| 64 | + var ok bool | ||
| 65 | + if url, ok = mapTemplate[importDataCommand.Code]; !ok { | ||
| 66 | + return nil, application.ThrowError(application.BUSINESS_ERROR, fmt.Sprintf("模板:%v 不存在", importDataCommand.Code)) | ||
| 67 | + } | ||
| 68 | + return map[string]string{ | ||
| 69 | + "url": url, | ||
| 70 | + }, nil | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | +func (srv ExcelDataService) GetExcelDataFields(code string) (interface{}, error) { | ||
| 74 | + dataFields := []DataFieldOptions{} | ||
| 75 | + //switch code { | ||
| 76 | + //case domain.ExportCompanyUser: | ||
| 77 | + // dataFileds = (ExportCompanyUserData{}).AllFields() | ||
| 78 | + //case domain.ExportCooperationUser: | ||
| 79 | + // dataFileds = (ExportCooperationUserData{}).AllFields() | ||
| 80 | + //} | ||
| 81 | + return dataFields, nil | ||
| 82 | +} |
| 1 | +package service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "github.com/linmadan/egglib-go/core/application" | ||
| 5 | + "github.com/linmadan/egglib-go/utils/excel" | ||
| 6 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/ecelData/command" | ||
| 7 | + productService "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/service" | ||
| 8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
| 9 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils/converter" | ||
| 10 | + "strings" | ||
| 11 | +) | ||
| 12 | + | ||
| 13 | +// ImportProduct 导入生产信息 | ||
| 14 | +func (srv ExcelDataService) ImportProduct(importDataCommand *command.ImportDataCommand) (interface{}, error) { | ||
| 15 | + excelImport := excel.NewExcelImport() | ||
| 16 | + excelImport.RowBegin = 3 //第二行开始读取 | ||
| 17 | + excelImport.DataFields = []excel.DataField{ | ||
| 18 | + {EnName: "productCode", CnName: "产品编号"}, | ||
| 19 | + {EnName: "productName", CnName: "*品名"}, | ||
| 20 | + {EnName: "unit", CnName: "*规格"}, | ||
| 21 | + {EnName: "productCategory", CnName: "*类别"}, | ||
| 22 | + {EnName: "unitWeight", CnName: "投入单份重量"}, | ||
| 23 | + } | ||
| 24 | + excelData, err := converter.OpenImportFileFromIoReader(excelImport, importDataCommand.Reader, importDataCommand.FileExt) //excelImport.OpenExcelFromIoReader(importDataCommand.Reader) | ||
| 25 | + if err != nil { | ||
| 26 | + return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error()) | ||
| 27 | + } | ||
| 28 | + items := make([]*domain.ImportProductItem, 0) | ||
| 29 | + for _, v := range excelData { | ||
| 30 | + item := &domain.ImportProductItem{ | ||
| 31 | + ProductCode: strings.TrimSpace(v["productCode"]), | ||
| 32 | + ProductName: strings.TrimSpace(v["productName"]), | ||
| 33 | + ProductCategory: strings.TrimSpace(v["productCategory"]), | ||
| 34 | + Unit: strings.TrimSpace(v["unit"]), | ||
| 35 | + UnitWeight: strings.TrimSpace(v["unitWeight"]), | ||
| 36 | + } | ||
| 37 | + items = append(items, item) | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + svr := productService.NewProductService(nil) | ||
| 41 | + failRows, err := svr.BatchAddProduct(importDataCommand.Operator, items) | ||
| 42 | + if err != nil { | ||
| 43 | + return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error()) | ||
| 44 | + } | ||
| 45 | + return srv.importResultWithHeader(excelImport.DataFields, failRows, len(items)), nil | ||
| 46 | +} |
pkg/application/ecelData/service/types.go
0 → 100644
| 1 | +package service | ||
| 2 | + | ||
| 3 | +type DataFieldOptions struct { | ||
| 4 | + EnName string `json:"enName"` | ||
| 5 | + CnName string `json:"cnName"` | ||
| 6 | + IsDefault bool `json:"isDefault"` | ||
| 7 | +} | ||
| 8 | + | ||
| 9 | +// | ||
| 10 | +//// ExportCompanyUserData 导出公司用户数据 | ||
| 11 | +//type ExportCompanyUserData struct { | ||
| 12 | +// SourceData []allied_creation_user.UserDetail | ||
| 13 | +// SelectedField []string | ||
| 14 | +//} | ||
| 15 | +// | ||
| 16 | +//var _ excel.ExcelMaker = (*ExportCompanyUserData)(nil) | ||
| 17 | +// | ||
| 18 | +//func (data ExportCompanyUserData) AllFields() []DataFieldOptions { | ||
| 19 | +// return []DataFieldOptions{ | ||
| 20 | +// {EnName: "UserCode", CnName: "用户编码"}, | ||
| 21 | +// {EnName: "UserName", CnName: "用户姓名"}, | ||
| 22 | +// {EnName: "Phone", CnName: "手机号"}, | ||
| 23 | +// {EnName: "DepartmentName", CnName: "所属部门"}, | ||
| 24 | +// {EnName: "EnableStatus", CnName: "状态"}, | ||
| 25 | +// {EnName: "OrgName", CnName: "组织机构"}, | ||
| 26 | +// } | ||
| 27 | +//} | ||
| 28 | +// | ||
| 29 | +//func (data ExportCompanyUserData) DataFieldList() []excel.DataField { | ||
| 30 | +// fields := []excel.DataField{} | ||
| 31 | +// allFields := data.AllFields() | ||
| 32 | +// for _, value2 := range allFields { | ||
| 33 | +// if len(data.SelectedField) == 0 || value2.IsDefault { | ||
| 34 | +// fields = append(fields, excel.DataField{EnName: value2.EnName, CnName: value2.CnName}) | ||
| 35 | +// continue | ||
| 36 | +// } | ||
| 37 | +// for _, value3 := range data.SelectedField { | ||
| 38 | +// if value2.EnName == value3 { | ||
| 39 | +// fields = append(fields, excel.DataField{EnName: value2.EnName, CnName: value2.CnName}) | ||
| 40 | +// } | ||
| 41 | +// } | ||
| 42 | +// } | ||
| 43 | +// return fields | ||
| 44 | +//} | ||
| 45 | +// | ||
| 46 | +//func (data ExportCompanyUserData) CellValue(index int, enName string) (value interface{}) { | ||
| 47 | +// if index > data.DataListLen() { | ||
| 48 | +// return "" | ||
| 49 | +// } | ||
| 50 | +// switch enName { | ||
| 51 | +// case "UserCode": | ||
| 52 | +// return data.SourceData[index].UserCode | ||
| 53 | +// case "UserName": | ||
| 54 | +// return data.SourceData[index].UserInfo.UserName | ||
| 55 | +// case "Phone": | ||
| 56 | +// return data.SourceData[index].UserInfo.Phone | ||
| 57 | +// case "DepartmentName": | ||
| 58 | +// if data.SourceData[index].Department != nil { | ||
| 59 | +// return data.SourceData[index].Department.DepartmentName | ||
| 60 | +// } else { | ||
| 61 | +// return "" | ||
| 62 | +// } | ||
| 63 | +// case "EnableStatus": | ||
| 64 | +// status := data.SourceData[index].EnableStatus | ||
| 65 | +// statusName := "" | ||
| 66 | +// // 状态(1:启用 2:禁用 3:注销) | ||
| 67 | +// switch status { | ||
| 68 | +// case 1: | ||
| 69 | +// statusName = "启用" | ||
| 70 | +// case 2: | ||
| 71 | +// statusName = "禁用" | ||
| 72 | +// case 3: | ||
| 73 | +// statusName = "注销" | ||
| 74 | +// } | ||
| 75 | +// return statusName | ||
| 76 | +// case "OrgName": | ||
| 77 | +// if data.SourceData[index].Org != nil { | ||
| 78 | +// return data.SourceData[index].Org.OrgName | ||
| 79 | +// } else { | ||
| 80 | +// return "" | ||
| 81 | +// } | ||
| 82 | +// } | ||
| 83 | +// return nil | ||
| 84 | +//} | ||
| 85 | +// | ||
| 86 | +//func (data ExportCompanyUserData) DataListLen() int { | ||
| 87 | +// return len(data.SourceData) | ||
| 88 | +//} | ||
| 89 | +// | ||
| 90 | +//func (data ExportCompanyUserData) TableTitle() []string { | ||
| 91 | +// return nil | ||
| 92 | +//} | ||
| 93 | +// | ||
| 94 | +////ExportCooperationUserData 导出共创用户数据 | ||
| 95 | +//type ExportCooperationUserData struct { | ||
| 96 | +// SourceData []allied_creation_user.UserDetail | ||
| 97 | +// SelectedField []string | ||
| 98 | +//} | ||
| 99 | +// | ||
| 100 | +//var _ excel.ExcelMaker = (*ExportCooperationUserData)(nil) | ||
| 101 | +// | ||
| 102 | +//func (data ExportCooperationUserData) AllFields() []DataFieldOptions { | ||
| 103 | +// return []DataFieldOptions{ | ||
| 104 | +// {EnName: "UserCode", CnName: "用户编码"}, | ||
| 105 | +// {EnName: "UserName", CnName: "用户姓名"}, | ||
| 106 | +// {EnName: "Phone", CnName: "手机号"}, | ||
| 107 | +// {EnName: "CooperationCompany", CnName: "共创公司"}, | ||
| 108 | +// {EnName: "CooperationDeadline", CnName: "共创到期"}, | ||
| 109 | +// {EnName: "EnableStatus", CnName: "状态"}, | ||
| 110 | +// } | ||
| 111 | +//} | ||
| 112 | +// | ||
| 113 | +//func (data ExportCooperationUserData) DataFieldList() []excel.DataField { | ||
| 114 | +// fields := []excel.DataField{} | ||
| 115 | +// allFields := data.AllFields() | ||
| 116 | +// for _, value2 := range allFields { | ||
| 117 | +// if len(data.SelectedField) == 0 || value2.IsDefault { | ||
| 118 | +// fields = append(fields, excel.DataField{EnName: value2.EnName, CnName: value2.CnName}) | ||
| 119 | +// continue | ||
| 120 | +// } | ||
| 121 | +// for _, value3 := range data.SelectedField { | ||
| 122 | +// if value2.EnName == value3 { | ||
| 123 | +// fields = append(fields, excel.DataField{EnName: value2.EnName, CnName: value2.CnName}) | ||
| 124 | +// } | ||
| 125 | +// } | ||
| 126 | +// } | ||
| 127 | +// return fields | ||
| 128 | +//} | ||
| 129 | +// | ||
| 130 | +//func (data ExportCooperationUserData) CellValue(index int, enName string) (value interface{}) { | ||
| 131 | +// if index > data.DataListLen() { | ||
| 132 | +// return "" | ||
| 133 | +// } | ||
| 134 | +// switch enName { | ||
| 135 | +// case "UserCode": | ||
| 136 | +// return data.SourceData[index].UserCode | ||
| 137 | +// case "UserName": | ||
| 138 | +// return data.SourceData[index].UserInfo.UserName | ||
| 139 | +// case "CooperationCompany": | ||
| 140 | +// return data.SourceData[index].CooperationInfo.CooperationCompany | ||
| 141 | +// case "CooperationDeadline": | ||
| 142 | +// if data.SourceData[index].CooperationInfo.CooperationDeadline.IsZero() || data.SourceData[index].CooperationInfo.CooperationDeadline.Unix() == 0 { | ||
| 143 | +// return "" | ||
| 144 | +// } | ||
| 145 | +// return data.SourceData[index].CooperationInfo.CooperationDeadline.Format("2006-01-02") | ||
| 146 | +// case "Phone": | ||
| 147 | +// return data.SourceData[index].UserInfo.Phone | ||
| 148 | +// case "Email": | ||
| 149 | +// return data.SourceData[index].UserInfo.Email | ||
| 150 | +// case "EnableStatus": | ||
| 151 | +// status := data.SourceData[index].EnableStatus | ||
| 152 | +// statusName := "" | ||
| 153 | +// // 状态(1:启用 2:禁用 3:注销) | ||
| 154 | +// switch status { | ||
| 155 | +// case 1: | ||
| 156 | +// statusName = "启用" | ||
| 157 | +// case 2: | ||
| 158 | +// statusName = "禁用" | ||
| 159 | +// case 3: | ||
| 160 | +// statusName = "注销" | ||
| 161 | +// } | ||
| 162 | +// return statusName | ||
| 163 | +// } | ||
| 164 | +// return nil | ||
| 165 | +//} | ||
| 166 | +// | ||
| 167 | +//func (data ExportCooperationUserData) DataListLen() int { | ||
| 168 | +// return len(data.SourceData) | ||
| 169 | +//} | ||
| 170 | +// | ||
| 171 | +//func (data ExportCooperationUserData) TableTitle() []string { | ||
| 172 | +// return nil | ||
| 173 | +//} |
| @@ -3,12 +3,14 @@ package service | @@ -3,12 +3,14 @@ package service | ||
| 3 | import ( | 3 | import ( |
| 4 | "fmt" | 4 | "fmt" |
| 5 | "github.com/linmadan/egglib-go/core/application" | 5 | "github.com/linmadan/egglib-go/core/application" |
| 6 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 6 | "github.com/linmadan/egglib-go/utils/tool_funs" | 7 | "github.com/linmadan/egglib-go/utils/tool_funs" |
| 7 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory" | 8 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory" |
| 8 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/command" | 9 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/command" |
| 9 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/dto" | 10 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/dto" |
| 10 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/query" | 11 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/query" |
| 11 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | 12 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" |
| 13 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService" | ||
| 12 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis" | 14 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis" |
| 13 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" | 15 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" |
| 14 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" | 16 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" |
| @@ -275,6 +277,33 @@ func (productService *ProductService) SearchProduct(operateInfo *domain.OperateI | @@ -275,6 +277,33 @@ func (productService *ProductService) SearchProduct(operateInfo *domain.OperateI | ||
| 275 | 277 | ||
| 276 | } | 278 | } |
| 277 | 279 | ||
| 280 | +// 创建产品服务 | ||
| 281 | +func (productService *ProductService) BatchAddProduct(opt *domain.OperateInfo, list []*domain.ImportProductItem) ([]interface{}, error) { | ||
| 282 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 283 | + if err != nil { | ||
| 284 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 285 | + } | ||
| 286 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 287 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 288 | + } | ||
| 289 | + defer func() { | ||
| 290 | + transactionContext.RollbackTransaction() | ||
| 291 | + }() | ||
| 292 | + | ||
| 293 | + batchAddProductService, _ := domainService.NewPGBatchAddProductService(transactionContext.(*pgTransaction.TransactionContext)) | ||
| 294 | + var failRows []interface{} | ||
| 295 | + if failRows, err = batchAddProductService.BatchAddProduct(opt, list); err != nil { | ||
| 296 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 297 | + } | ||
| 298 | + if len(failRows) != 0 { | ||
| 299 | + return failRows, nil //有错误行,回滚 | ||
| 300 | + } | ||
| 301 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 302 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 303 | + } | ||
| 304 | + return failRows, nil | ||
| 305 | +} | ||
| 306 | + | ||
| 278 | func NewProductService(options map[string]interface{}) *ProductService { | 307 | func NewProductService(options map[string]interface{}) *ProductService { |
| 279 | newProductService := &ProductService{} | 308 | newProductService := &ProductService{} |
| 280 | return newProductService | 309 | return newProductService |
| @@ -28,6 +28,8 @@ type SearchProductJobQuery struct { | @@ -28,6 +28,8 @@ type SearchProductJobQuery struct { | ||
| 28 | WorkshopName string `cname:"车间名称" json:"workshopName,omitempty"` | 28 | WorkshopName string `cname:"车间名称" json:"workshopName,omitempty"` |
| 29 | // 生产线名称 | 29 | // 生产线名称 |
| 30 | LineName string `cname:"生产线名称" json:"lineName,omitempty"` | 30 | LineName string `cname:"生产线名称" json:"lineName,omitempty"` |
| 31 | + // 工段名称 | ||
| 32 | + SectionName string `cname:"工段名称" json:"sectionName,omitempty"` | ||
| 31 | } | 33 | } |
| 32 | 34 | ||
| 33 | func (cmd *SearchProductJobQuery) Valid(validation *validation.Validation) { | 35 | func (cmd *SearchProductJobQuery) Valid(validation *validation.Validation) { |
| @@ -38,6 +38,7 @@ func (productSectionService *ProductSectionService) CreateProductSection(createP | @@ -38,6 +38,7 @@ func (productSectionService *ProductSectionService) CreateProductSection(createP | ||
| 38 | newProductSection := &domain.ProductSection{ | 38 | newProductSection := &domain.ProductSection{ |
| 39 | SectionId: uniqueId, | 39 | SectionId: uniqueId, |
| 40 | SectionName: createProductSectionCommand.SectionName, | 40 | SectionName: createProductSectionCommand.SectionName, |
| 41 | + Removed: domain.NotDeleted, | ||
| 41 | } | 42 | } |
| 42 | var workshopRepository domain.WorkshopRepository | 43 | var workshopRepository domain.WorkshopRepository |
| 43 | var workshop *domain.Workshop | 44 | var workshop *domain.Workshop |
| @@ -30,6 +30,6 @@ func (dto *WorkshopDto) LoadDto(m *domain.Workshop) *WorkshopDto { | @@ -30,6 +30,6 @@ func (dto *WorkshopDto) LoadDto(m *domain.Workshop) *WorkshopDto { | ||
| 30 | dto.WorkshopId = m.WorkshopId | 30 | dto.WorkshopId = m.WorkshopId |
| 31 | dto.WorkshopName = m.WorkshopName | 31 | dto.WorkshopName = m.WorkshopName |
| 32 | dto.Principal = m.Principal | 32 | dto.Principal = m.Principal |
| 33 | - dto.ProductLines = m.ProductLines | 33 | + dto.ProductLines = m.GetProductLines(domain.NotDeleted) |
| 34 | return dto | 34 | return dto |
| 35 | } | 35 | } |
| @@ -279,6 +279,49 @@ func (workshopService *WorkshopService) SearchWorkshop(operateInfo *domain.Opera | @@ -279,6 +279,49 @@ func (workshopService *WorkshopService) SearchWorkshop(operateInfo *domain.Opera | ||
| 279 | 279 | ||
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | +// 搜索车间服务列表 | ||
| 283 | +func (workshopService *WorkshopService) SelectorWorkshop(operateInfo *domain.OperateInfo, listWorkshopQuery *query.SearchWorkshopQuery) (interface{}, error) { | ||
| 284 | + if err := listWorkshopQuery.ValidateQuery(); err != nil { | ||
| 285 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 286 | + } | ||
| 287 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 288 | + if err != nil { | ||
| 289 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 290 | + } | ||
| 291 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 292 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 293 | + } | ||
| 294 | + defer func() { | ||
| 295 | + transactionContext.RollbackTransaction() | ||
| 296 | + }() | ||
| 297 | + workshopRepository, _, err := factory.FastPgWorkshop(transactionContext, 0) | ||
| 298 | + if err != nil { | ||
| 299 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 300 | + } | ||
| 301 | + var count int64 | ||
| 302 | + var workshops []*domain.Workshop | ||
| 303 | + options := utils.ObjectToMap(listWorkshopQuery) | ||
| 304 | + options["companyId"] = operateInfo.CompanyId | ||
| 305 | + options["orgId"] = operateInfo.OrgId | ||
| 306 | + if count, workshops, err = workshopRepository.Find(options); err != nil { | ||
| 307 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 308 | + } | ||
| 309 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 310 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 311 | + } | ||
| 312 | + | ||
| 313 | + var results = make([]*dto.WorkshopDto, 0) | ||
| 314 | + for i := range workshops { | ||
| 315 | + newItem := &dto.WorkshopDto{} | ||
| 316 | + results = append(results, newItem.LoadDto(workshops[i])) | ||
| 317 | + } | ||
| 318 | + return map[string]interface{}{ | ||
| 319 | + "count": count, | ||
| 320 | + "workshops": results, | ||
| 321 | + }, nil | ||
| 322 | + | ||
| 323 | +} | ||
| 324 | + | ||
| 282 | func NewWorkshopService(options map[string]interface{}) *WorkshopService { | 325 | func NewWorkshopService(options map[string]interface{}) *WorkshopService { |
| 283 | newWorkshopService := &WorkshopService{} | 326 | newWorkshopService := &WorkshopService{} |
| 284 | return newWorkshopService | 327 | return newWorkshopService |
| @@ -18,6 +18,12 @@ var ( | @@ -18,6 +18,12 @@ var ( | ||
| 18 | ErrorNotFound = fmt.Errorf("没有此资源") | 18 | ErrorNotFound = fmt.Errorf("没有此资源") |
| 19 | ) | 19 | ) |
| 20 | 20 | ||
| 21 | +// excel 编码 | ||
| 22 | +var ( | ||
| 23 | + ExcelImportProduct = "MANUFACTURE_EXCEL_IMPORT_PRODUCT" | ||
| 24 | + ExcelExportProduct = "MANUFACTURE_EXCEL_EXPORT_PRODUCT" | ||
| 25 | +) | ||
| 26 | + | ||
| 21 | /***** 1.数据权限 *****/ | 27 | /***** 1.数据权限 *****/ |
| 22 | // DataAuthor 数据验证器 | 28 | // DataAuthor 数据验证器 |
| 23 | type DataAuthor interface { | 29 | type DataAuthor interface { |
| 1 | package domain | 1 | package domain |
| 2 | 2 | ||
| 3 | -import "time" | 3 | +import ( |
| 4 | + "fmt" | ||
| 5 | + "strconv" | ||
| 6 | + "time" | ||
| 7 | +) | ||
| 4 | 8 | ||
| 5 | // 产品信息 | 9 | // 产品信息 |
| 6 | type Product struct { | 10 | type Product struct { |
| @@ -62,3 +66,38 @@ func (product *Product) Update(data map[string]interface{}) error { | @@ -62,3 +66,38 @@ func (product *Product) Update(data map[string]interface{}) error { | ||
| 62 | product.UpdatedAt = time.Now() | 66 | product.UpdatedAt = time.Now() |
| 63 | return nil | 67 | return nil |
| 64 | } | 68 | } |
| 69 | + | ||
| 70 | +// 导入数据体 | ||
| 71 | +type ImportProductItem struct { | ||
| 72 | + // 产品编号 编码规则为“CP”+2 位年+2 位月+2 位日+3 位流水码,如 CP211229001 | ||
| 73 | + ProductCode string `json:"productCode,omitempty"` | ||
| 74 | + // 产品名称 | ||
| 75 | + ProductName string `json:"productName,omitempty"` | ||
| 76 | + // 产品类别 | ||
| 77 | + ProductCategory string `json:"productCategory,omitempty"` | ||
| 78 | + // 单位 | ||
| 79 | + Unit string `json:"unit,omitempty"` | ||
| 80 | + // 单份重量(原材料) | ||
| 81 | + UnitWeight string `json:"unitWeight,omitempty"` | ||
| 82 | + // 失败理由 | ||
| 83 | + FailReason string `json:"failReason"` | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +func (item *ImportProductItem) Valid() error { | ||
| 87 | + if len(item.ProductName) == 0 { | ||
| 88 | + return fmt.Errorf("品名不能为空") | ||
| 89 | + } | ||
| 90 | + if len(item.Unit) == 0 { | ||
| 91 | + return fmt.Errorf("规格不能为空") | ||
| 92 | + } | ||
| 93 | + if len(item.ProductCategory) == 0 { | ||
| 94 | + return fmt.Errorf("类别不能为空") | ||
| 95 | + } | ||
| 96 | + if len(item.UnitWeight) == 0 { | ||
| 97 | + item.UnitWeight = "0" | ||
| 98 | + } | ||
| 99 | + if _, err := strconv.ParseFloat(item.UnitWeight, 64); err != nil { | ||
| 100 | + return fmt.Errorf("投入单份重量格式有误") | ||
| 101 | + } | ||
| 102 | + return nil | ||
| 103 | +} |
| @@ -8,6 +8,19 @@ type ProductLine struct { | @@ -8,6 +8,19 @@ type ProductLine struct { | ||
| 8 | LineName string `json:"lineName,omitempty"` | 8 | LineName string `json:"lineName,omitempty"` |
| 9 | // 工段列表 | 9 | // 工段列表 |
| 10 | ProductSections []*ProductSection `json:"productSections,omitempty"` | 10 | ProductSections []*ProductSection `json:"productSections,omitempty"` |
| 11 | - // 已删除标识 0:正常 1:已删除 | 11 | + // 已删除标识 1:正常 2:已删除 |
| 12 | Removed int `json:"removed,omitempty"` | 12 | Removed int `json:"removed,omitempty"` |
| 13 | } | 13 | } |
| 14 | + | ||
| 15 | +func (productLine *ProductLine) GetProductSections(removed int) []*ProductSection { | ||
| 16 | + var result = make([]*ProductSection, 0) | ||
| 17 | + for i := range productLine.ProductSections { | ||
| 18 | + if removed > 0 && productLine.ProductSections[i].Removed != removed { | ||
| 19 | + continue | ||
| 20 | + } | ||
| 21 | + item := productLine.ProductSections[i] | ||
| 22 | + item.Removed = 0 | ||
| 23 | + result = append(result, item) | ||
| 24 | + } | ||
| 25 | + return result | ||
| 26 | +} |
| @@ -6,6 +6,6 @@ type ProductSection struct { | @@ -6,6 +6,6 @@ type ProductSection struct { | ||
| 6 | SectionId int `json:"sectionId,omitempty"` | 6 | SectionId int `json:"sectionId,omitempty"` |
| 7 | // 工段名称 | 7 | // 工段名称 |
| 8 | SectionName string `json:"sectionName,omitempty"` | 8 | SectionName string `json:"sectionName,omitempty"` |
| 9 | - // 已删除标识 0:正常 1:已删除 | 9 | + // 已删除标识 1:正常 2:已删除 |
| 10 | Removed int `json:"removed,omitempty"` | 10 | Removed int `json:"removed,omitempty"` |
| 11 | } | 11 | } |
| @@ -7,9 +7,9 @@ import ( | @@ -7,9 +7,9 @@ import ( | ||
| 7 | 7 | ||
| 8 | const ( | 8 | const ( |
| 9 | // 未删除 | 9 | // 未删除 |
| 10 | - NotDeleted = 0 | 10 | + NotDeleted = 1 |
| 11 | // 已删除 | 11 | // 已删除 |
| 12 | - Deleted = 1 | 12 | + Deleted = 2 |
| 13 | ) | 13 | ) |
| 14 | 14 | ||
| 15 | // 车间 | 15 | // 车间 |
| @@ -203,3 +203,17 @@ func (workshop *Workshop) FindWorkStation(workshopId, lineId, sectionId int) (*W | @@ -203,3 +203,17 @@ func (workshop *Workshop) FindWorkStation(workshopId, lineId, sectionId int) (*W | ||
| 203 | } | 203 | } |
| 204 | return NewWorkStation(workshop, line, section), nil | 204 | return NewWorkStation(workshop, line, section), nil |
| 205 | } | 205 | } |
| 206 | + | ||
| 207 | +func (workshop *Workshop) GetProductLines(removed int) []*ProductLine { | ||
| 208 | + var result = make([]*ProductLine, 0) | ||
| 209 | + for i := range workshop.ProductLines { | ||
| 210 | + if removed > 0 && workshop.ProductLines[i].Removed != removed { | ||
| 211 | + continue | ||
| 212 | + } | ||
| 213 | + item := workshop.ProductLines[i] | ||
| 214 | + item.Removed = 0 // 隐藏 | ||
| 215 | + item.ProductSections = item.GetProductSections(removed) | ||
| 216 | + result = append(result, item) | ||
| 217 | + } | ||
| 218 | + return result | ||
| 219 | +} |
| 1 | +package domainService | ||
| 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/allied-creation-manufacture/pkg/domain" | ||
| 8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis" | ||
| 9 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository" | ||
| 10 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" | ||
| 11 | + "strconv" | ||
| 12 | + "time" | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +type PGBatchAddProductService struct { | ||
| 16 | + transactionContext *pgTransaction.TransactionContext | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +func (ptr *PGBatchAddProductService) BatchAddProduct(opt *domain.OperateInfo, list []*domain.ImportProductItem) ([]interface{}, error) { | ||
| 20 | + var failRows = make([]interface{}, 0) | ||
| 21 | + | ||
| 22 | + productRepository, _ := repository.NewProductRepository(ptr.transactionContext) | ||
| 23 | + _, products, _ := productRepository.Find(map[string]interface{}{"companyId": opt.CompanyId, "orgId": opt.OrgId}) | ||
| 24 | + var mapProduct = make(map[string]*domain.Product) | ||
| 25 | + for i := range products { | ||
| 26 | + mapProduct[products[i].ProductCode] = products[i] | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + var generator = redis.NewProductCodeCache(opt.CompanyId) | ||
| 30 | + for i := range list { | ||
| 31 | + item := list[i] | ||
| 32 | + if err := item.Valid(); err != nil { | ||
| 33 | + item.FailReason = err.Error() | ||
| 34 | + failRows = append(failRows, item) | ||
| 35 | + continue | ||
| 36 | + } | ||
| 37 | + unitWeight, _ := strconv.ParseFloat(item.UnitWeight, 64) | ||
| 38 | + newItem := &domain.Product{ | ||
| 39 | + CompanyId: opt.CompanyId, | ||
| 40 | + OrgId: opt.OrgId, | ||
| 41 | + ProductCode: item.ProductCode, | ||
| 42 | + ProductName: item.ProductName, | ||
| 43 | + ProductCategory: item.ProductCategory, | ||
| 44 | + ProductSpec: &domain.UnitQuantity{ | ||
| 45 | + Unit: item.Unit, | ||
| 46 | + UnitWeight: unitWeight, | ||
| 47 | + }, | ||
| 48 | + CreatedAt: time.Now(), | ||
| 49 | + UpdatedAt: time.Now(), | ||
| 50 | + } | ||
| 51 | + if len(newItem.ProductCode) == 0 { | ||
| 52 | + code, err := redis.GenCode(generator) | ||
| 53 | + if err != nil { | ||
| 54 | + log.Logger.Error(err.Error()) | ||
| 55 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "服务器异常") | ||
| 56 | + } | ||
| 57 | + newItem.ProductCode = code | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + if _, ok := mapProduct[newItem.ProductCode]; !ok { | ||
| 61 | + mapProduct[newItem.ProductCode] = newItem | ||
| 62 | + } else { | ||
| 63 | + item.FailReason = "导入的产品编号已存在" | ||
| 64 | + failRows = append(failRows, item) | ||
| 65 | + continue | ||
| 66 | + } | ||
| 67 | + if _, err := productRepository.Save(newItem); err != nil { | ||
| 68 | + log.Logger.Error(err.Error()) | ||
| 69 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "服务器异常") | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + return failRows, nil | ||
| 73 | +} | ||
| 74 | + | ||
| 75 | +func NewPGBatchAddProductService(transactionContext *pgTransaction.TransactionContext) (*PGBatchAddProductService, error) { | ||
| 76 | + if transactionContext == nil { | ||
| 77 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
| 78 | + } else { | ||
| 79 | + return &PGBatchAddProductService{ | ||
| 80 | + transactionContext: transactionContext, | ||
| 81 | + }, nil | ||
| 82 | + } | ||
| 83 | +} |
| 1 | +package converter | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "bytes" | ||
| 5 | + "encoding/csv" | ||
| 6 | + "fmt" | ||
| 7 | + "github.com/linmadan/egglib-go/utils/excel" | ||
| 8 | + "golang.org/x/text/encoding/simplifiedchinese" | ||
| 9 | + "golang.org/x/text/transform" | ||
| 10 | + "io" | ||
| 11 | + "strings" | ||
| 12 | + "unicode/utf8" | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +type ( | ||
| 16 | + CSVReader struct { | ||
| 17 | + Data *excel.ExcelImport | ||
| 18 | + } | ||
| 19 | +) | ||
| 20 | + | ||
| 21 | +func (cr *CSVReader) ToMap(reader io.Reader) ([]map[string]string, error) { | ||
| 22 | + var err error | ||
| 23 | + if reader, err = cr.PrepareCheck(reader); err != nil { | ||
| 24 | + return nil, err | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + r := csv.NewReader(reader) | ||
| 28 | + rows := make([]map[string]string, 0) | ||
| 29 | + var header = make([]string, 0) | ||
| 30 | + var headerMap = make(map[string]string) | ||
| 31 | + var index int = 0 | ||
| 32 | + for i := range cr.Data.DataFields { | ||
| 33 | + item := cr.Data.DataFields[i] | ||
| 34 | + headerMap[item.CnName] = item.EnName | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + for { | ||
| 38 | + index++ | ||
| 39 | + | ||
| 40 | + record, err := r.Read() | ||
| 41 | + if err == io.EOF { | ||
| 42 | + break | ||
| 43 | + } | ||
| 44 | + if err != nil { | ||
| 45 | + return nil, err | ||
| 46 | + } | ||
| 47 | + if index <= cr.Data.RowBegin-1 { | ||
| 48 | + continue | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + if len(header) == 0 { | ||
| 52 | + header = record | ||
| 53 | + } else { | ||
| 54 | + dict := map[string]string{} | ||
| 55 | + for i := range header { | ||
| 56 | + if column, ok := headerMap[header[i]]; ok { | ||
| 57 | + dict[column] = record[i] | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | + rows = append(rows, dict) | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + } | ||
| 64 | + return rows, nil | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +func (cr *CSVReader) PrepareCheck(reader io.Reader) (io.Reader, error) { | ||
| 68 | + return GBKToUtf8(reader) | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +func GBKToUtf8(readIn io.Reader) (io.Reader, error) { | ||
| 72 | + var ( | ||
| 73 | + err error | ||
| 74 | + fileByte []byte | ||
| 75 | + ) | ||
| 76 | + fileByte, err = io.ReadAll(readIn) | ||
| 77 | + if err != nil { | ||
| 78 | + return nil, err | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + if utf8.Valid(fileByte) { | ||
| 82 | + return bytes.NewReader(fileByte), nil | ||
| 83 | + } else { | ||
| 84 | + utf8Reader := transform.NewReader(bytes.NewReader(fileByte), simplifiedchinese.GBK.NewDecoder()) | ||
| 85 | + return utf8Reader, nil | ||
| 86 | + } | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +func OpenImportFileFromIoReader(ex *excel.ExcelImport, reader io.Reader, ext string) ([]map[string]string, error) { | ||
| 90 | + var tmp []map[string]string | ||
| 91 | + var err error | ||
| 92 | + if ext == "csv" || ext == ".csv" { | ||
| 93 | + csvReader := &CSVReader{ex} | ||
| 94 | + tmp, err = csvReader.ToMap(reader) | ||
| 95 | + } else { | ||
| 96 | + tmp, err = ex.OpenExcelFromIoReader(reader) | ||
| 97 | + } | ||
| 98 | + if err != nil { | ||
| 99 | + return nil, err | ||
| 100 | + } | ||
| 101 | + var response []map[string]string | ||
| 102 | + for i := range tmp { | ||
| 103 | + if fieldValueAllEmpty(tmp[i]) { | ||
| 104 | + continue | ||
| 105 | + } | ||
| 106 | + response = append(response, tmp[i]) | ||
| 107 | + } | ||
| 108 | + return response, nil | ||
| 109 | +} | ||
| 110 | + | ||
| 111 | +func fieldValueAllEmpty(param map[string]string) bool { | ||
| 112 | + isAllEmpty := true | ||
| 113 | + for _, v := range param { | ||
| 114 | + value := strings.TrimSpace(v) | ||
| 115 | + if len(value) > 0 { | ||
| 116 | + isAllEmpty = false | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + return isAllEmpty | ||
| 120 | +} | ||
| 121 | + | ||
| 122 | +// TODO: export csv | ||
| 123 | +func MakeToCsv(sourData excel.ExcelMaker, w io.Writer) error { | ||
| 124 | + _, err := w.Write([]byte("\xEF\xBB\xBF")) //写入UTF-8 BOM | ||
| 125 | + if err != nil { | ||
| 126 | + return err | ||
| 127 | + } | ||
| 128 | + csvWriter := csv.NewWriter(w) | ||
| 129 | + fields := sourData.DataFieldList() | ||
| 130 | + firstRow := []string{} | ||
| 131 | + for i := range fields { | ||
| 132 | + firstRow = append(firstRow, fields[i].CnName) | ||
| 133 | + } | ||
| 134 | + title := sourData.TableTitle() | ||
| 135 | + if len(title) > 0 { | ||
| 136 | + csvWriter.Write(title) | ||
| 137 | + } | ||
| 138 | + csvWriter.Write(firstRow) | ||
| 139 | + dataLenght := sourData.DataListLen() | ||
| 140 | + for i := 0; i < dataLenght; i++ { | ||
| 141 | + rowData := []string{} | ||
| 142 | + for ii := range fields { | ||
| 143 | + cellValue := sourData.CellValue(i, fields[ii].EnName) | ||
| 144 | + str := "" | ||
| 145 | + if cellValue != nil { | ||
| 146 | + str = fmt.Sprintf("%v", cellValue) | ||
| 147 | + } | ||
| 148 | + rowData = append(rowData, str) | ||
| 149 | + } | ||
| 150 | + csvWriter.Write(rowData) | ||
| 151 | + } | ||
| 152 | + csvWriter.Flush() | ||
| 153 | + return csvWriter.Error() | ||
| 154 | +} |
| @@ -262,3 +262,29 @@ func CopyObject(src, dst interface{}) { | @@ -262,3 +262,29 @@ func CopyObject(src, dst interface{}) { | ||
| 262 | } | 262 | } |
| 263 | } | 263 | } |
| 264 | } | 264 | } |
| 265 | + | ||
| 266 | +/* | ||
| 267 | + 时间计算 | ||
| 268 | +*/ | ||
| 269 | + | ||
| 270 | +func ValidWorkTime(t string) error { | ||
| 271 | + ts := strings.Split(t, ":") | ||
| 272 | + if len(ts) != 2 { | ||
| 273 | + return fmt.Errorf("时间格式有误") | ||
| 274 | + } | ||
| 275 | + ts1, err := strconv.Atoi(ts[0]) | ||
| 276 | + if err != nil { | ||
| 277 | + return fmt.Errorf("小时格式有误") | ||
| 278 | + } | ||
| 279 | + if !(ts1 < 24 && ts1 >= 0) { | ||
| 280 | + return fmt.Errorf("小时格式有误") | ||
| 281 | + } | ||
| 282 | + ts2, err := strconv.Atoi(ts[1]) | ||
| 283 | + if err != nil { | ||
| 284 | + return fmt.Errorf("分钟格式有误") | ||
| 285 | + } | ||
| 286 | + if !(ts2 < 60 && ts2 >= 0) { | ||
| 287 | + return fmt.Errorf("分钟格式有误") | ||
| 288 | + } | ||
| 289 | + return nil | ||
| 290 | +} |
pkg/infrastructure/utils/utils_test.go
0 → 100644
| 1 | +package utils | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "github.com/stretchr/testify/assert" | ||
| 5 | + "testing" | ||
| 6 | +) | ||
| 7 | + | ||
| 8 | +func TestTimeSpan(t *testing.T) { | ||
| 9 | + inputs := []struct { | ||
| 10 | + t string | ||
| 11 | + e bool | ||
| 12 | + }{ | ||
| 13 | + {"10:00", false}, | ||
| 14 | + {"10:11", false}, | ||
| 15 | + {"24:00", true}, | ||
| 16 | + {"-1:00", true}, | ||
| 17 | + {"10:60", true}, | ||
| 18 | + {"A:B", true}, | ||
| 19 | + } | ||
| 20 | + for i := range inputs { | ||
| 21 | + err := ValidWorkTime(inputs[i].t) | ||
| 22 | + if inputs[i].e { | ||
| 23 | + assert.NotNil(t, err) | ||
| 24 | + } else { | ||
| 25 | + assert.Nil(t, err) | ||
| 26 | + } | ||
| 27 | + } | ||
| 28 | +} |
| 1 | +package controllers | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/beego/beego/v2/server/web/context" | ||
| 6 | + "github.com/linmadan/egglib-go/utils/excel" | ||
| 7 | + "github.com/linmadan/egglib-go/web/beego" | ||
| 8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/ecelData/command" | ||
| 9 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/ecelData/service" | ||
| 10 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" | ||
| 11 | + "io" | ||
| 12 | + "path/filepath" | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +type ExcelDataController struct { | ||
| 16 | + beego.BaseController | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +func (controller *ExcelDataController) responseExcelByFile(ctx *context.Context, excelExport *excel.ExcelExport, fileName string) error { | ||
| 20 | + ctx.Output.Header("Content-Disposition", "attachment; filename="+fileName) | ||
| 21 | + ctx.Output.Header("Content-Description", "File Transfer") | ||
| 22 | + ctx.Output.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | ||
| 23 | + ctx.Output.Header("Content-Transfer-Encoding", "binary") | ||
| 24 | + ctx.Output.Header("Expires", "0") | ||
| 25 | + ctx.Output.Header("Cache-Control", "must-revalidate") | ||
| 26 | + ctx.Output.Header("Pragma", "public") | ||
| 27 | + //跳过保存文件,直接写入ctx.ResponseWriter | ||
| 28 | + excelExport.ExcelFile.Write(ctx.ResponseWriter) | ||
| 29 | + return nil | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +func (controller *ExcelDataController) FileImport() { | ||
| 33 | + var ( | ||
| 34 | + data interface{} | ||
| 35 | + err error | ||
| 36 | + r io.Reader | ||
| 37 | + ext string | ||
| 38 | + ) | ||
| 39 | + //excelService := service.NewExcelDataService(nil) | ||
| 40 | + r, ext, err = controller.GetFileWithExt() | ||
| 41 | + if err != nil { | ||
| 42 | + controller.Response(nil, err) | ||
| 43 | + return | ||
| 44 | + } | ||
| 45 | + cmd := &command.ImportDataCommand{} | ||
| 46 | + controller.ParseForm(cmd) | ||
| 47 | + cmd.Operator = ParseOperateInfo(controller.BaseController) | ||
| 48 | + cmd.Reader = r | ||
| 49 | + cmd.FileExt = ext | ||
| 50 | + switch cmd.Code { | ||
| 51 | + //case domain.ImportCompanyUser: | ||
| 52 | + // data, err = excelService.ImportCompanyUser(cmd) | ||
| 53 | + //case domain.ImportCooperationUser: | ||
| 54 | + // data, err = excelService.ImportCooperationUser(cmd) | ||
| 55 | + //case domain.ImportOrganization: | ||
| 56 | + // data, err = excelService.ImportOrganization(cmd) | ||
| 57 | + default: | ||
| 58 | + err = fmt.Errorf("导入不存在 Code:%v", cmd.Code) | ||
| 59 | + } | ||
| 60 | + controller.Response(data, err) | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +// FileExport 文件导出 | ||
| 64 | +func (controller *ExcelDataController) FileExport() { | ||
| 65 | + // 1.读取command | ||
| 66 | + exportDataCommand := &command.ExportDataCommand{} | ||
| 67 | + err := controller.Unmarshal(exportDataCommand) | ||
| 68 | + if err != nil { | ||
| 69 | + log.Logger.Debug("json err:" + err.Error()) | ||
| 70 | + controller.Response(nil, err) | ||
| 71 | + return | ||
| 72 | + } | ||
| 73 | + exportDataCommand.Operator = ParseOperateInfo(controller.BaseController) | ||
| 74 | + | ||
| 75 | + // 2.读取data | ||
| 76 | + var data excel.ExcelMaker | ||
| 77 | + var filename string | ||
| 78 | + //var excelService = service.NewExcelDataService(nil) | ||
| 79 | + switch exportDataCommand.Code { | ||
| 80 | + //case domain.ExportCompanyUser: | ||
| 81 | + // companyUserListQuery := &query.CompanyUserListQuery{} | ||
| 82 | + // exportDataCommand.UnmarshalQuery(companyUserListQuery) | ||
| 83 | + // companyUserListQuery.Operator = exportDataCommand.Operator | ||
| 84 | + // data, err = excelService.ExportCompanyUser(companyUserListQuery) | ||
| 85 | + // filename = "导出公司用户" | ||
| 86 | + //case domain.ExportCooperationUser: | ||
| 87 | + // companyUserListQuery := &query.CooperationUserListQuery{} | ||
| 88 | + // exportDataCommand.UnmarshalQuery(companyUserListQuery) | ||
| 89 | + // companyUserListQuery.Operator = exportDataCommand.Operator | ||
| 90 | + // data, err = excelService.ExportCooperationUser(companyUserListQuery) | ||
| 91 | + // filename = "导出共创用户" | ||
| 92 | + default: | ||
| 93 | + err = fmt.Errorf("export type :%v not exists", exportDataCommand.Code) | ||
| 94 | + } | ||
| 95 | + if err != nil { | ||
| 96 | + log.Logger.Debug("excelService.Export err:" + err.Error()) | ||
| 97 | + controller.Response(nil, err) | ||
| 98 | + return | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + // 3.返回文件 | ||
| 102 | + excelTool := excel.NewExcelExport() | ||
| 103 | + err = excelTool.ExportData(data, "") | ||
| 104 | + if err != nil { | ||
| 105 | + log.Logger.Debug("excelTool.ExportData err:" + err.Error()) | ||
| 106 | + controller.Response(nil, err) | ||
| 107 | + return | ||
| 108 | + } | ||
| 109 | + controller.responseExcelByFile(controller.Ctx, excelTool, filename) | ||
| 110 | +} | ||
| 111 | + | ||
| 112 | +//GetExcelDataFields 获取导出excel数据的可选字段 | ||
| 113 | +func (controller *ExcelDataController) GetExcelDataFields() { | ||
| 114 | + | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +func (controller *ExcelDataController) GetFileWithExt() (io.Reader, string, error) { | ||
| 118 | + excelFile, fileHeader, err := controller.GetFile("file") | ||
| 119 | + if err != nil { | ||
| 120 | + log.Logger.Error(err.Error()) | ||
| 121 | + return nil, "", fmt.Errorf("上传文件不存在") | ||
| 122 | + } | ||
| 123 | + ext := filepath.Ext(fileHeader.Filename) | ||
| 124 | + if !(ext == ".xlsx" || ext == ".xls" || ext == ".csv") { | ||
| 125 | + return nil, "", fmt.Errorf("仅支持上传文件格式 xls/xlsx/csv") | ||
| 126 | + } | ||
| 127 | + return excelFile, ext, nil | ||
| 128 | +} | ||
| 129 | + | ||
| 130 | +func (controller *ExcelDataController) FileImportTemplate() { | ||
| 131 | + excelService := service.NewExcelDataService(nil) | ||
| 132 | + cmd := &command.ImportDataCommand{} | ||
| 133 | + code := controller.GetString(":code") | ||
| 134 | + cmd.Code = code | ||
| 135 | + var data interface{} | ||
| 136 | + data, err := excelService.FileImportTemplate(cmd) | ||
| 137 | + controller.Response(data, err) | ||
| 138 | +} |
| @@ -5,6 +5,7 @@ import ( | @@ -5,6 +5,7 @@ import ( | ||
| 5 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/command" | 5 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/command" |
| 6 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/query" | 6 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/query" |
| 7 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/service" | 7 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/service" |
| 8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
| 8 | ) | 9 | ) |
| 9 | 10 | ||
| 10 | type ProductController struct { | 11 | type ProductController struct { |
| @@ -69,3 +70,13 @@ func (controller *ProductController) SearchProduct() { | @@ -69,3 +70,13 @@ func (controller *ProductController) SearchProduct() { | ||
| 69 | total, data, err := productService.SearchProduct(ParseOperateInfo(controller.BaseController), listProductQuery) | 70 | total, data, err := productService.SearchProduct(ParseOperateInfo(controller.BaseController), listProductQuery) |
| 70 | ResponseGrid(controller.BaseController, total, data, err) | 71 | ResponseGrid(controller.BaseController, total, data, err) |
| 71 | } | 72 | } |
| 73 | + | ||
| 74 | +func (controller *ProductController) BatchAddProduct() { | ||
| 75 | + productService := service.NewProductService(nil) | ||
| 76 | + cmd := &struct { | ||
| 77 | + List []*domain.ImportProductItem `json:"list"` | ||
| 78 | + }{} | ||
| 79 | + controller.Unmarshal(cmd) | ||
| 80 | + data, err := productService.BatchAddProduct(ParseOperateInfo(controller.BaseController), cmd.List) | ||
| 81 | + controller.Response(data, err) | ||
| 82 | +} |
| @@ -66,3 +66,11 @@ func (controller *WorkshopController) SearchWorkshop() { | @@ -66,3 +66,11 @@ func (controller *WorkshopController) SearchWorkshop() { | ||
| 66 | data, err := workshopService.SearchWorkshop(ParseOperateInfo(controller.BaseController), listWorkshopQuery) | 66 | data, err := workshopService.SearchWorkshop(ParseOperateInfo(controller.BaseController), listWorkshopQuery) |
| 67 | controller.Response(data, err) | 67 | controller.Response(data, err) |
| 68 | } | 68 | } |
| 69 | + | ||
| 70 | +func (controller *WorkshopController) SelectorWorkshop() { | ||
| 71 | + workshopService := service.NewWorkshopService(nil) | ||
| 72 | + listWorkshopQuery := &query.SearchWorkshopQuery{} | ||
| 73 | + controller.Unmarshal(listWorkshopQuery) | ||
| 74 | + data, err := workshopService.SearchWorkshop(ParseOperateInfo(controller.BaseController), listWorkshopQuery) | ||
| 75 | + controller.Response(data, err) | ||
| 76 | +} |
pkg/port/beego/routers/excel_router.go
0 → 100644
| 1 | +package routers | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "github.com/beego/beego/v2/server/web" | ||
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/port/beego/controllers" | ||
| 6 | +) | ||
| 7 | + | ||
| 8 | +func init() { | ||
| 9 | + web.Router("/file-import", &controllers.ExcelDataController{}, "Post:FileImport") | ||
| 10 | + web.Router("/file-export", &controllers.ExcelDataController{}, "Post:FileExport") | ||
| 11 | + web.Router("/file-import-template/:code", &controllers.ExcelDataController{}, "Get:FileImportTemplate") | ||
| 12 | +} |
| @@ -12,4 +12,5 @@ func init() { | @@ -12,4 +12,5 @@ func init() { | ||
| 12 | web.Router("/products/:productId", &controllers.ProductController{}, "Delete:RemoveProduct") | 12 | web.Router("/products/:productId", &controllers.ProductController{}, "Delete:RemoveProduct") |
| 13 | web.Router("/products/", &controllers.ProductController{}, "Get:ListProduct") | 13 | web.Router("/products/", &controllers.ProductController{}, "Get:ListProduct") |
| 14 | web.Router("/products/search", &controllers.ProductController{}, "Post:SearchProduct") | 14 | web.Router("/products/search", &controllers.ProductController{}, "Post:SearchProduct") |
| 15 | + web.Router("/products/batch-add", &controllers.ProductController{}, "Post:BatchAddProduct") | ||
| 15 | } | 16 | } |
| @@ -12,4 +12,5 @@ func init() { | @@ -12,4 +12,5 @@ func init() { | ||
| 12 | web.Router("/workshops/:workshopId", &controllers.WorkshopController{}, "Delete:RemoveWorkshop") | 12 | web.Router("/workshops/:workshopId", &controllers.WorkshopController{}, "Delete:RemoveWorkshop") |
| 13 | web.Router("/workshops/", &controllers.WorkshopController{}, "Get:ListWorkshop") | 13 | web.Router("/workshops/", &controllers.WorkshopController{}, "Get:ListWorkshop") |
| 14 | web.Router("/workshops/search", &controllers.WorkshopController{}, "Post:SearchWorkshop") | 14 | web.Router("/workshops/search", &controllers.WorkshopController{}, "Post:SearchWorkshop") |
| 15 | + web.Router("/workshops/selector", &controllers.WorkshopController{}, "Post:SelectorWorkshop") | ||
| 15 | } | 16 | } |
-
请 注册 或 登录 后发表评论