diff --git a/server/bin/marketing-data-server b/server/bin/marketing-data-server index 4dd5e47..9492a8c 100755 Binary files a/server/bin/marketing-data-server and b/server/bin/marketing-data-server differ diff --git a/server/go.mod b/server/go.mod index 78258c8..1119ce4 100644 --- a/server/go.mod +++ b/server/go.mod @@ -12,6 +12,7 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/msoleps v1.0.3 // indirect + github.com/tjfoc/gmsm v1.4.1 // indirect github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect golang.org/x/crypto v0.19.0 // indirect diff --git a/server/go.sum b/server/go.sum index 05b5545..c5ef95c 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1,11 +1,35 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= @@ -13,21 +37,68 @@ github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= +github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 h1:Chd9DkqERQQuHpXjR/HSV1jLZA6uaoiwwH3vSuF3IW0= github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= github.com/xuri/excelize/v2 v2.8.1 h1:pZLMEwK8ep+CLIUWpWmvW8IWE/yxqG0I1xcN6cVMGuQ= github.com/xuri/excelize/v2 v2.8.1/go.mod h1:oli1E4C3Pa5RXg1TBXn4ENCXDV5JUMlBluUhG7c+CEE= github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 h1:qhbILQo1K3mphbwKh1vNm4oGezE1eF9fQWmNiIpSfI4= github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/server/internal/api/exports.go b/server/internal/api/exports.go index 11c27bd..2fe186c 100644 --- a/server/internal/api/exports.go +++ b/server/internal/api/exports.go @@ -7,7 +7,8 @@ import ( "fmt" "io" "log" - "marketing-system-data-tool/server/internal/exporter" + "marketing-system-data-tool/server/internal/exporter" + "marketing-system-data-tool/server/internal/ymtcrypto" "math/big" "net/http" "os" @@ -161,6 +162,17 @@ func (a *ExportsAPI) create(w http.ResponseWriter, r *http.Request) { } func (a *ExportsAPI) runJob(id uint64, db *sql.DB, q string, args []interface{}, fields []string, cols []string, fmt string) { + // load datasource once for transform decisions + var jobTplID uint64 + var jobDS string + { + row := a.meta.QueryRow("SELECT template_id FROM export_jobs WHERE id=?", id) + _ = row.Scan(&jobTplID) + if jobTplID > 0 { + tr := a.meta.QueryRow("SELECT datasource FROM export_templates WHERE id=?", jobTplID) + _ = tr.Scan(&jobDS) + } + } log.Printf("job_id=%d sql=%s args=%v", id, "UPDATE export_jobs SET status=?, started_at=? WHERE id= ?", []interface{}{"running", time.Now(), id}) a.meta.Exec("UPDATE export_jobs SET status=?, started_at=?, updated_at=? WHERE id= ?", "running", time.Now(), time.Now(), id) if fmt == "csv" { @@ -238,8 +250,8 @@ func (a *ExportsAPI) runJob(id uint64, db *sql.DB, q string, args []interface{}, vals[i] = toString(out[i]) } } - vals = transformRow(fs, vals) - w.WriteRow(vals) + vals = transformRow(jobDS, fs, vals) + w.WriteRow(vals) count++ partCount++ tick++ @@ -325,7 +337,8 @@ func (a *ExportsAPI) runJob(id uint64, db *sql.DB, q string, args []interface{}, vals[i] = toString(out[i]) } } - w.WriteRow(vals) + vals = transformRow(jobDS, fields, vals) + w.WriteRow(vals) count++ partCount++ tick++ @@ -408,7 +421,8 @@ func (a *ExportsAPI) runJob(id uint64, db *sql.DB, q string, args []interface{}, vals[i] = toString(out[i]) } } - w.WriteRow(vals) + vals = transformRow(jobDS, fields, vals) + w.WriteRow(vals) count++ partCount++ tick++ @@ -569,8 +583,8 @@ func (a *ExportsAPI) runJob(id uint64, db *sql.DB, q string, args []interface{}, vals[i] = toString(out[i]) } } - vals = transformRow(fs, vals) - x.WriteRow(vals) + vals = transformRow(jobDS, fs, vals) + x.WriteRow(vals) count++ partCount++ tick++ @@ -622,7 +636,8 @@ func (a *ExportsAPI) runJob(id uint64, db *sql.DB, q string, args []interface{}, vals[i] = toString(out2[i]) } } - x.WriteRow(vals) + vals = transformRow(jobDS, fs, vals) + x.WriteRow(vals) count++ tick2++ if tick2%50 == 0 { @@ -684,7 +699,8 @@ func (a *ExportsAPI) runJob(id uint64, db *sql.DB, q string, args []interface{}, vals[i] = toString(out[i]) } } - x.WriteRow(vals) + vals = transformRow(jobDS, fields, vals) + x.WriteRow(vals) count++ tick++ if tick%50 == 0 { @@ -847,17 +863,25 @@ func (a *ExportsAPI) download(w http.ResponseWriter, r *http.Request, id string) http.ServeFile(w, r, uri) } -func transformRow(fields []string, vals []string) []string { - for i := range fields { - if i >= len(vals) { - break - } - f := fields[i] - if f == "order.key" { - vals[i] = decodeOrderKey(vals[i]) - } - } - return vals +func transformRow(ds string, fields []string, vals []string) []string { + for i := range fields { + if i >= len(vals) { + break + } + f := fields[i] + if f == "order.key" { + if ds == "ymt" { + key := os.Getenv("YMT_KEY_DECRYPT_KEY_B64") + if key == "" { key = "z9DoIVLuDYEN/qsgweRA4A==" } + if dec, err := ymtcrypto.SM4Decrypt(vals[i], key); err == nil && dec != "" { + vals[i] = dec + } + } else { + vals[i] = decodeOrderKey(vals[i]) + } + } + } + return vals } func decodeOrderKey(s string) string { diff --git a/server/internal/exporter/sqlbuilder.go b/server/internal/exporter/sqlbuilder.go index b908cd7..8744c42 100644 --- a/server/internal/exporter/sqlbuilder.go +++ b/server/internal/exporter/sqlbuilder.go @@ -56,6 +56,32 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{ continue } } + if req.Datasource == "ymt" && t == "order" { + if f == "type" { + cols = append(cols, "CASE `"+mt+"`.type WHEN 1 THEN '现金红包' WHEN 2 THEN '直充' WHEN 3 THEN '立减金' ELSE '' END AS type") + continue + } + if f == "status" { + cols = append(cols, "CASE `"+mt+"`.status WHEN 1 THEN '待充值' WHEN 2 THEN '充值中' WHEN 3 THEN '充值成功' WHEN 4 THEN '充值失败' WHEN 5 THEN '已过期' WHEN 6 THEN '已作废' WHEN 7 THEN '已核销' WHEN 8 THEN '核销失败' WHEN 9 THEN '订单重置' WHEN 10 THEN '卡单' ELSE '' END AS status") + continue + } + if f == "pay_status" { + cols = append(cols, "CASE `"+mt+"`.pay_status WHEN 1 THEN '待支付' WHEN 2 THEN '支付中' WHEN 3 THEN '已支付' WHEN 4 THEN '取消支付' WHEN 5 THEN '退款中' WHEN 6 THEN '退款成功' ELSE '' END AS pay_status") + continue + } + } + if req.Datasource == "ymt" && t == "activity" { + if f == "settlement_type" { + cols = append(cols, "CASE `"+mt+"`.settlement_type WHEN 1 THEN '发放结算' WHEN 2 THEN '打开结算' WHEN 3 THEN '领用结算' WHEN 4 THEN '核销结算' ELSE '' END AS settlement_type") + continue + } + } + if req.Datasource == "ymt" && t == "order_digit" { + if f == "order_type" { + cols = append(cols, "CASE `"+mt+"`.order_type WHEN 1 THEN '直充' WHEN 2 THEN '卡密' ELSE '' END AS order_type") + continue + } + } if t == "order_cash" && f == "receive_status" { cols = append(cols, "CASE `order_cash`.receive_status WHEN 0 THEN '待领取' WHEN 1 THEN '领取中' WHEN 2 THEN '领取成功' WHEN 3 THEN '领取失败' ELSE '' END AS receive_status") continue @@ -65,7 +91,11 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{ continue } if t == "order_voucher" && f == "channel" { - cols = append(cols, "CASE `order_voucher`.channel WHEN 1 THEN '支付宝' WHEN 2 THEN '微信' ELSE '' END AS channel") + cols = append(cols, "CASE `order_voucher`.channel WHEN 1 THEN '支付宝' WHEN 2 THEN '微信' WHEN 3 THEN '云闪付' ELSE '' END AS channel") + continue + } + if req.Datasource == "ymt" && t == "order_voucher" && f == "status" { + cols = append(cols, "CASE `order_voucher`.status WHEN 1 THEN '待发放' WHEN 2 THEN '发放中' WHEN 3 THEN '发放失败' WHEN 4 THEN '待核销' WHEN 5 THEN '已核销' WHEN 6 THEN '已过期' WHEN 7 THEN '已退款' ELSE '' END AS status") continue } if t == "order_voucher" && f == "status" { diff --git a/server/internal/schema/ymt.go b/server/internal/schema/ymt.go index 789f417..cef6cf9 100644 --- a/server/internal/schema/ymt.go +++ b/server/internal/schema/ymt.go @@ -28,6 +28,8 @@ func (s ymtSchema) MapField(t, f string) (string, bool) { if t == "order_voucher" { switch f { case "channel_activity_id": return "channel_batch_no", true + case "overdue_time": return "expire_time", true + case "account_no": return "account", true default: return f, true } diff --git a/server/internal/ymtcrypto/crypto.go b/server/internal/ymtcrypto/crypto.go new file mode 100644 index 0000000..5a43d20 --- /dev/null +++ b/server/internal/ymtcrypto/crypto.go @@ -0,0 +1,48 @@ +package ymtcrypto + +import ( + "crypto/cipher" + "encoding/base64" + "errors" + sm4 "github.com/tjfoc/gmsm/sm4" +) + +func SM4Decrypt(encrypted, encryptKey string) (string, error) { + if encrypted == "" { + return "", nil + } + d, err := base64.StdEncoding.DecodeString(encryptKey) + if err != nil { + return "", err + } + if len(d) != 16 { + return "", errors.New("invalid sm4 key length") + } + cipherBlock, err := sm4.NewCipher(d) + if err != nil { + return "", err + } + blockSize := cipherBlock.BlockSize() + iv := make([]byte, blockSize) + for i := 0; i < blockSize; i++ { iv[i] = 0 } + cipherText, err := base64.StdEncoding.DecodeString(encrypted) + if err != nil { + return "", err + } + if len(cipherText)%blockSize != 0 { + return "", errors.New("invalid sm4 ciphertext size") + } + plainText := make([]byte, len(cipherText)) + blockMode := cipher.NewCBCDecrypter(cipherBlock, iv) + blockMode.CryptBlocks(plainText, cipherText) + if len(plainText) == 0 { + return "", nil + } + padding := int(plainText[len(plainText)-1]) + if padding <= 0 || padding > len(plainText) { + return "", errors.New("invalid padding") + } + buff := plainText[:len(plainText)-padding] + return string(buff), nil +} + diff --git a/server/storage/export/job_57_1764308505.zip b/server/storage/export/job_57_1764308505.zip new file mode 100644 index 0000000..1e596b2 Binary files /dev/null and b/server/storage/export/job_57_1764308505.zip differ diff --git a/server/storage/export/job_58_1764308582.zip b/server/storage/export/job_58_1764308582.zip new file mode 100644 index 0000000..a9cf772 Binary files /dev/null and b/server/storage/export/job_58_1764308582.zip differ diff --git a/server/storage/export/job_59_1764308833.zip b/server/storage/export/job_59_1764308833.zip new file mode 100644 index 0000000..b61961b Binary files /dev/null and b/server/storage/export/job_59_1764308833.zip differ diff --git a/server/storage/export/job_60_1764308932.zip b/server/storage/export/job_60_1764308932.zip new file mode 100644 index 0000000..e7f23de Binary files /dev/null and b/server/storage/export/job_60_1764308932.zip differ diff --git a/server/storage/export/job_61_1764308939.zip b/server/storage/export/job_61_1764308939.zip new file mode 100644 index 0000000..25512cb Binary files /dev/null and b/server/storage/export/job_61_1764308939.zip differ diff --git a/server/storage/export/job_62_1764309063.zip b/server/storage/export/job_62_1764309063.zip new file mode 100644 index 0000000..ae28d70 Binary files /dev/null and b/server/storage/export/job_62_1764309063.zip differ diff --git a/server/storage/export/job_63_1764309115.zip b/server/storage/export/job_63_1764309115.zip new file mode 100644 index 0000000..36325eb Binary files /dev/null and b/server/storage/export/job_63_1764309115.zip differ diff --git a/server/storage/export/job_64_1764309204.zip b/server/storage/export/job_64_1764309204.zip new file mode 100644 index 0000000..035a87f Binary files /dev/null and b/server/storage/export/job_64_1764309204.zip differ diff --git a/server/storage/export/job_65_1764310402.zip b/server/storage/export/job_65_1764310402.zip new file mode 100644 index 0000000..f386aeb Binary files /dev/null and b/server/storage/export/job_65_1764310402.zip differ diff --git a/server/storage/export/job_66_1764310446.zip b/server/storage/export/job_66_1764310446.zip new file mode 100644 index 0000000..cebb0e3 Binary files /dev/null and b/server/storage/export/job_66_1764310446.zip differ diff --git a/server/storage/export/job_67_1764310572.zip b/server/storage/export/job_67_1764310572.zip new file mode 100644 index 0000000..272d892 Binary files /dev/null and b/server/storage/export/job_67_1764310572.zip differ diff --git a/server/storage/export/job_68_1764310587.zip b/server/storage/export/job_68_1764310587.zip new file mode 100644 index 0000000..603015b Binary files /dev/null and b/server/storage/export/job_68_1764310587.zip differ diff --git a/server/storage/export_20251128134143.xlsx b/server/storage/export_20251128134143.xlsx new file mode 100755 index 0000000..2484559 Binary files /dev/null and b/server/storage/export_20251128134143.xlsx differ diff --git a/server/storage/export_20251128134257.xlsx b/server/storage/export_20251128134257.xlsx new file mode 100755 index 0000000..17187a7 Binary files /dev/null and b/server/storage/export_20251128134257.xlsx differ diff --git a/server/storage/export_20251128134710.xlsx b/server/storage/export_20251128134710.xlsx new file mode 100755 index 0000000..2484559 Binary files /dev/null and b/server/storage/export_20251128134710.xlsx differ diff --git a/server/storage/export_20251128134849.xlsx b/server/storage/export_20251128134849.xlsx new file mode 100755 index 0000000..2484559 Binary files /dev/null and b/server/storage/export_20251128134849.xlsx differ diff --git a/server/storage/export_20251128134856.xlsx b/server/storage/export_20251128134856.xlsx new file mode 100755 index 0000000..2484559 Binary files /dev/null and b/server/storage/export_20251128134856.xlsx differ diff --git a/server/storage/export_20251128135100.xlsx b/server/storage/export_20251128135100.xlsx new file mode 100755 index 0000000..2484559 Binary files /dev/null and b/server/storage/export_20251128135100.xlsx differ diff --git a/server/storage/export_20251128135153.xlsx b/server/storage/export_20251128135153.xlsx new file mode 100755 index 0000000..2484559 Binary files /dev/null and b/server/storage/export_20251128135153.xlsx differ diff --git a/server/storage/export_20251128135322.xlsx b/server/storage/export_20251128135322.xlsx new file mode 100755 index 0000000..6935f92 Binary files /dev/null and b/server/storage/export_20251128135322.xlsx differ diff --git a/server/storage/export_20251128141320.xlsx b/server/storage/export_20251128141320.xlsx new file mode 100755 index 0000000..2484559 Binary files /dev/null and b/server/storage/export_20251128141320.xlsx differ diff --git a/server/storage/export_20251128141404.xlsx b/server/storage/export_20251128141404.xlsx new file mode 100755 index 0000000..d72c148 Binary files /dev/null and b/server/storage/export_20251128141404.xlsx differ diff --git a/server/storage/export_20251128141610.xlsx b/server/storage/export_20251128141610.xlsx new file mode 100755 index 0000000..2484559 Binary files /dev/null and b/server/storage/export_20251128141610.xlsx differ diff --git a/server/storage/export_20251128141624.xlsx b/server/storage/export_20251128141624.xlsx new file mode 100755 index 0000000..ce5e29b Binary files /dev/null and b/server/storage/export_20251128141624.xlsx differ diff --git a/web/index.html b/web/index.html index 5ad4ab8..1338d53 100644 --- a/web/index.html +++ b/web/index.html @@ -23,7 +23,7 @@ @@ -235,21 +235,21 @@ - + - + - + diff --git a/web/main.js b/web/main.js index 15f508d..f1efc79 100644 --- a/web/main.js +++ b/web/main.js @@ -840,7 +840,9 @@ const { createApp, reactive } = Vue; } const loadYmtCreators = async ()=>{ try{ - const res = await fetch(API_BASE + '/api/ymt/users?limit=2000') + const uid = getUserId() + const url = API_BASE + '/api/ymt/users?limit=2000' + (uid?('&q='+encodeURIComponent(uid)):'') + const res = await fetch(url) const data = await res.json() const arr = Array.isArray(data?.data) ? data.data : (Array.isArray(data) ? data : []) ymtCreatorOptions.value = arr.map(it=>({ label: it.name || String(it.id), value: Number(it.id) })) @@ -1067,6 +1069,8 @@ const { createApp, reactive } = Vue; await loadYmtCreators() await loadYmtMerchants() await loadYmtActivities() + const uid = getUserId() + if(uid){ state.exportForm.ymtCreatorId = Number(uid) } } if(!Array.isArray(state.exportForm.dateRange) || state.exportForm.dateRange.length!==2){ state.exportForm.dateRange = yearRange() } state.exportVisible = true @@ -1080,7 +1084,7 @@ const { createApp, reactive } = Vue; state.exportTpl = tpl }catch(e){ msg('加载模板详情异常','error'); state.exportTpl = { id: null, filters: {}, main_table: '', fields: [], datasource: '', file_format: '' } } } - const submitExport = async ()=>{ + const submitExport = async ()=>{ const formRef = exportFormRef.value const ok = formRef ? await formRef.validate().catch(()=>false) : true if(!ok){ msg('请完善必填项','error'); return }