diff --git a/go.mod b/go.mod index 32d3a27..1881bb2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module ai_scheduler go 1.26.2 require ( - gitea.cdlsxd.cn/self-tools/l-dingtalk-stream-sdk-go v0.9.3 gitea.cdlsxd.cn/self-tools/l_request v1.0.8 github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.12 github.com/alibabacloud-go/dingtalk v1.6.96 @@ -12,10 +11,7 @@ require ( github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible github.com/bytedance/gopkg v0.1.4 github.com/cloudwego/eino v0.7.7 - github.com/cloudwego/eino-ext/components/model/ollama v0.1.6 github.com/cloudwego/eino-ext/components/model/openai v0.1.5 - github.com/coze-dev/coze-go v0.0.0-20251029161603-312b7fd62d20 - github.com/duke-git/lancet/v2 v2.3.8 github.com/emirpasic/gods v1.18.1 github.com/faabiosr/cachego v0.26.0 github.com/fastwego/dingding v1.0.0-beta.4 @@ -33,16 +29,11 @@ require ( github.com/redis/go-redis/v9 v9.16.0 github.com/robfig/cron/v3 v3.0.1 github.com/sashabaranov/go-openai v1.42.1 - github.com/shopspring/decimal v1.4.0 github.com/spf13/viper v1.17.0 - github.com/stretchr/testify v1.11.1 github.com/tmc/langchaingo v0.1.13 github.com/valyala/fasthttp v1.51.0 - github.com/volcengine/volcengine-go-sdk v1.2.9 - github.com/xuri/excelize/v2 v2.10.0 go.mongodb.org/mongo-driver v1.14.0 golang.org/x/crypto v0.43.0 - golang.org/x/sync v0.17.0 google.golang.org/grpc v1.64.0 gorm.io/driver/mysql v1.6.0 gorm.io/gorm v1.31.0 @@ -69,19 +60,16 @@ require ( github.com/clbanning/mxj/v2 v2.5.5 // indirect github.com/cloudwego/base64x v0.1.7 // indirect github.com/cloudwego/eino-ext/libs/acl/openai v0.1.2 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dlclark/regexp2 v1.11.4 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/eino-contrib/jsonschema v1.0.3 // indirect - github.com/eino-contrib/ollama v0.1.0 // indirect github.com/evanphx/json-patch v0.5.2 // indirect github.com/fasthttp/websocket v1.5.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/goph/emperror v0.17.2 // indirect - github.com/gorilla/websocket v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect @@ -103,9 +91,6 @@ require ( github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkoukk/tiktoken-go v0.1.6 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/richardlehane/mscfb v1.0.4 // indirect - github.com/richardlehane/msoleps v1.0.4 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -116,19 +101,16 @@ require ( github.com/spf13/afero v1.10.0 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/testify v1.11.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/tiendc/go-deepcopy v1.7.1 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect - github.com/volcengine/volc-sdk-golang v1.0.23 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect - github.com/xuri/efp v0.0.1 // indirect - github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 // indirect github.com/yargevad/filepathx v1.0.0 // indirect github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect go.uber.org/atomic v1.9.0 // indirect @@ -136,12 +118,12 @@ require ( golang.org/x/arch v0.31.0 // indirect golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect golang.org/x/net v0.46.0 // indirect + golang.org/x/sync v0.17.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.30.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index eb9516b..5532cd7 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,6 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -gitea.cdlsxd.cn/self-tools/l-dingtalk-stream-sdk-go v0.9.3 h1:qaSPxVz5kHCs2AWvShnOG8mUgrUP9Gc3uUB4ZX1BF5A= -gitea.cdlsxd.cn/self-tools/l-dingtalk-stream-sdk-go v0.9.3/go.mod h1:5mCPTjBxOk69LRJPHWJRNTkfxcffqlQSOBMD4M5JVnE= gitea.cdlsxd.cn/self-tools/l_request v1.0.8 h1:FaKRql9mCVcSoaGqPeBOAruZ52slzRngQ6VRTYKNSsA= gitea.cdlsxd.cn/self-tools/l_request v1.0.8/go.mod h1:Qf4hVXm2Eu5vOvwXk8D7U0q/aekMCkZ4Fg9wnRKlasQ= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= @@ -101,7 +99,6 @@ github.com/aliyun/credentials-go v1.4.6 h1:CG8rc/nxCNKfXbZWpWDzI9GjF4Tuu3Es14qT8 github.com/aliyun/credentials-go v1.4.6/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= @@ -115,18 +112,12 @@ github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMU github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bugsnag/bugsnag-go v1.4.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= -github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= github.com/bytedance/gopkg v0.1.4 h1:oZnQwnX82KAIWb7033bEwtxvTqXcYMxDBaQxo5JJHWM= github.com/bytedance/gopkg v0.1.4/go.mod h1:v1zWfPm21Fb+OsyXN2VAHdL6TBb2L88anLQgdyje6R4= github.com/bytedance/mockey v1.2.14 h1:KZaFgPdiUwW+jOWFieo3Lr7INM1P+6adO3hxZhDswY8= github.com/bytedance/mockey v1.2.14/go.mod h1:1BPHF9sol5R1ud/+0VEHGQq/+i2lN+GTsr3O2Q9IENY= -github.com/bytedance/sonic v1.14.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w= -github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc= github.com/bytedance/sonic v1.15.4 h1:FgtV/4aBHpla9AxuMpuuzVUpa/Cf3izufkxNmnEzdI8= github.com/bytedance/sonic v1.15.4/go.mod h1:8e51yTPdY8M6t+vvGL1c2Y1xL9i+frEeIAQAEl75NUc= -github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= -github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/bytedance/sonic/loader v0.5.2 h1:0QtP1gevc1OZ6/H8Lb9BRZiCXd1Ftjd3OKuj1T1lBIo= github.com/bytedance/sonic/loader v0.5.2/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -139,14 +130,10 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E= github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= -github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/cloudwego/base64x v0.1.7 h1:NppS+Fgzg5ovhn4NkUXaDT3x9jldgH5ToMCqzBSi2zI= github.com/cloudwego/base64x v0.1.7/go.mod h1:Cu1PV9zfrSf7ET2tIbWbbEy7jO7HHJ13q4X2SQ8aWYg= github.com/cloudwego/eino v0.7.7 h1:WhP0SMWWPgLdOH03HrKUxtP9/Q96NhziMZNEQl9lxpU= github.com/cloudwego/eino v0.7.7/go.mod h1:nA8Vacmuqv3pqKBQbTWENBLQ8MmGmPt/WqiyLeB8ohQ= -github.com/cloudwego/eino-ext/components/model/ollama v0.1.6 h1:ZbrhV91uE0hGIOYXhb2i3G6tQJ/rK2SLYtoYrmocZXM= -github.com/cloudwego/eino-ext/components/model/ollama v0.1.6/go.mod h1:GDXrvorGdRNV6g2mK5jdla2D8Xc/hh7XDrTeGDteLLo= github.com/cloudwego/eino-ext/components/model/openai v0.1.5 h1:+yvGbTPw93li9GSmdm6Rix88Yy8AXg5NNBcRbWx3CQU= github.com/cloudwego/eino-ext/components/model/openai v0.1.5/go.mod h1:IPVYMFoZcuHeVEsDTGN6SZjvue0xr1iZFhdpq1SBWdQ= github.com/cloudwego/eino-ext/libs/acl/openai v0.1.2 h1:r9Id2wzJ05PoHl+Km7jQgNMgciaZI93TVnUYso89esM= @@ -154,8 +141,6 @@ github.com/cloudwego/eino-ext/libs/acl/openai v0.1.2/go.mod h1:S4OkvglPY9hsm9tXe github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/coze-dev/coze-go v0.0.0-20251029161603-312b7fd62d20 h1:m6P88V9lLrxZsE7uj9otq7l7nqDuCSAJ86KhzRlWf0M= -github.com/coze-dev/coze-go v0.0.0-20251029161603-312b7fd62d20/go.mod h1:wdT5CFt/sFsWz9hna2Z7DWzUra9spx0SoX1PUZyoSB0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -164,14 +149,10 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/duke-git/lancet/v2 v2.3.8 h1:dlkqn6Nj2LRWFuObNxttkMHxrFeaV6T26JR8jbEVbPg= -github.com/duke-git/lancet/v2 v2.3.8/go.mod h1:zGa2R4xswg6EG9I6WnyubDbFO/+A/RROxIbXcwryTsc= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eino-contrib/jsonschema v1.0.3 h1:2Kfsm1xlMV0ssY2nuxshS4AwbLFuqmPmzIjLVJ1Fsp0= github.com/eino-contrib/jsonschema v1.0.3/go.mod h1:cpnX4SyKjWjGC7iN2EbhxaTdLqGjCi0e9DxpLYxddD4= -github.com/eino-contrib/ollama v0.1.0 h1:z1NaMdKW6X1ftP8g5xGGR5zDRPUtuTKFq35vBQgxsN4= -github.com/eino-contrib/ollama v0.1.0/go.mod h1:mYsQ7b3DeqY8bHPuD3MZJYTqkgyL6LoemxoP/B7ZNhA= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -248,7 +229,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -262,7 +242,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -280,10 +259,7 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.7.0 h1:JxUKI6+CVBgCO2WToKy/nQk0sS+amI9z9EjVmdaocj4= @@ -297,8 +273,6 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= -github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= -github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -311,8 +285,6 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -325,14 +297,11 @@ github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALr github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= -github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw= github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -395,11 +364,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/redis/go-redis/v9 v9.16.0 h1:OotgqgLSRCmzfqChbQyG1PHC3tLNR89DG4jdOERSEP4= github.com/redis/go-redis/v9 v9.16.0/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370= -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= -github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00= -github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= @@ -417,8 +381,6 @@ github.com/sashabaranov/go-openai v1.42.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adO github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk= github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= -github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= -github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -454,7 +416,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -462,8 +423,6 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tiendc/go-deepcopy v1.7.1 h1:LnubftI6nYaaMOcaz0LphzwraqN8jiWTwm416sitff4= -github.com/tiendc/go-deepcopy v1.7.1/go.mod h1:4bKjNC2r7boYOkD2IOuZpYjmlDdzjbpTRyCx+goBCJQ= github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= @@ -477,10 +436,6 @@ github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1S github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/volcengine/volc-sdk-golang v1.0.23 h1:anOslb2Qp6ywnsbyq9jqR0ljuO63kg9PY+4OehIk5R8= -github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU= -github.com/volcengine/volcengine-go-sdk v1.2.9 h1:du2gnImtyWXKkQFnJW/GXCs+UBibGGOXIbP1Ams2pB8= -github.com/volcengine/volcengine-go-sdk v1.2.9/go.mod h1:oxoVo+A17kvkwPkIeIHPVLjSw7EQAm+l/Vau1YGHN+A= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= @@ -491,12 +446,6 @@ github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/xuri/efp v0.0.1 h1:fws5Rv3myXyYni8uwj2qKjVaRP30PdjeYe2Y6FDsCL8= -github.com/xuri/efp v0.0.1/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= -github.com/xuri/excelize/v2 v2.10.0 h1:8aKsP7JD39iKLc6dH5Tw3dgV3sPRh8uRVXu/fMstfW4= -github.com/xuri/excelize/v2 v2.10.0/go.mod h1:SC5TzhQkaOsTWpANfm+7bJCldzcnU/jrhqkTi/iBHBU= -github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 h1:+C0TIdyyYmzadGaL/HBLbf3WdLgC29pgyhTjAT/0nuE= -github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= github.com/yargevad/filepathx v1.0.0 h1:SYcT+N3tYGi+NvazubCNlvgIPbzAk7i7y2dwg3I5FYc= github.com/yargevad/filepathx v1.0.0/go.mod h1:BprfX/gpYNJHJfc35GjRRpVcwWXS89gGulUIU5tK3tA= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= @@ -522,8 +471,6 @@ go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= -golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= -golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/arch v0.31.0 h1:22MlEb14/O/EPCYHFxsDdv5TuLD5dMjT5e2QeJw4ULk= golang.org/x/arch v0.31.0/go.mod h1:KcJSod3cqT2dKcjBxqTyGfbumNikqU9p5tHJinPJnuY= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -558,8 +505,6 @@ golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrC golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ= -golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs= 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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -583,8 +528,6 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -707,8 +650,6 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -792,8 +733,6 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -890,14 +829,11 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/biz/advice_customer_new.go b/internal/biz/advice_customer_new.go new file mode 100644 index 0000000..8af1c4b --- /dev/null +++ b/internal/biz/advice_customer_new.go @@ -0,0 +1,113 @@ +package biz + +import ( + "ai_scheduler/internal/data/impl" + "ai_scheduler/internal/data/model" + "ai_scheduler/internal/entitys" + "ai_scheduler/tmpl/dataTemp" + "context" + + "xorm.io/builder" +) + +type AdviceCustomerBiz struct { + impl *impl.AdviceCustomerImpl +} + +func NewAdviceCustomerBiz(impl *impl.AdviceCustomerImpl) *AdviceCustomerBiz { + return &AdviceCustomerBiz{impl: impl} +} + +// Add 新增单条好友 +func (a *AdviceCustomerBiz) Add(ctx context.Context, req *entitys.AdvicerCustomerAddReq) error { + record := a.toModel(req) + return a.impl.Add(ctx, &record) +} + +// List 分页查询好友列表 +func (a *AdviceCustomerBiz) List(ctx context.Context, req *entitys.AdvicerCustomerListReq) (list []model.AiAdviceCustomer, err error) { + list = make([]model.AiAdviceCustomer, 0) + cond := builder.NewCond() + if req.SelfWxid != "" { + cond = cond.And(builder.Eq{"self_wxid": req.SelfWxid}) + } + pageBo := &dataTemp.ReqPageBo{Page: req.Page, Limit: req.PageSize} + _, err = a.impl.GetListToStruct(ctx, &cond, pageBo, &list, "create_at desc") + return +} + +// Del 删除好友 +func (a *AdviceCustomerBiz) Del(ctx context.Context, req *entitys.AdvicerCustomerDelReq) error { + return a.impl.DelByPrimary(ctx, "customer_id", req.CustomerId) +} + +// Diff 查询差集:返回库中已有好友记录 + 库中不存在的 userName 差集 +func (a *AdviceCustomerBiz) Diff(ctx context.Context, req *entitys.AdvicerCustomerDiffReq) (*entitys.AdvicerCustomerDiffRes, error) { + res := &entitys.AdvicerCustomerDiffRes{ + List: make([]model.AiAdviceCustomer, 0), + Diff: make([]string, 0), + } + if req.SelfWxid == "" { + return res, nil + } + // 查询该 selfWxid 下已有的全部好友记录 + cond := builder.Eq{"self_wxid": req.SelfWxid} + condPtr := builder.Cond(cond) + err := a.impl.GetRangeToMapStruct(&condPtr, &res.List) + if err != nil { + return nil, err + } + if len(req.UserNames) == 0 { + return res, nil + } + // 构建已有集合 + existSet := make(map[string]struct{}, len(res.List)) + for _, e := range res.List { + existSet[e.UserName] = struct{}{} + } + // 取差集 + for _, name := range req.UserNames { + if _, ok := existSet[name]; !ok { + res.Diff = append(res.Diff, name) + } + } + return res, nil +} + +// BatchAdd 批量新增好友 +func (a *AdviceCustomerBiz) BatchAdd(ctx context.Context, req *entitys.AdvicerCustomerBatchAddReq) error { + if len(req.List) == 0 { + return nil + } + records := make([]model.AiAdviceCustomer, 0, len(req.List)) + for _, item := range req.List { + records = append(records, a.toModel(&item)) + } + return a.impl.BatchInsert(ctx, records) +} + +func (a *AdviceCustomerBiz) toModel(req *entitys.AdvicerCustomerAddReq) model.AiAdviceCustomer { + return model.AiAdviceCustomer{ + SelfWxid: req.SelfWxid, + UserName: req.UserName, + NickName: req.NickName, + PyInitial: req.PyInitial, + QuanPin: req.QuanPin, + Sex: req.Sex, + Remark: req.Remark, + RemarkPyInitial: req.RemarkPyInitial, + RemarkQuanPin: req.RemarkQuanPin, + Signature: req.Signature, + Alias: req.Alias, + SnsBgImg: req.SnsBgImg, + Country: req.Country, + BigHeadImgUrl: req.BigHeadImgUrl, + SmallHeadImgUrl: req.SmallHeadImgUrl, + Description: req.Description, + CardImgUrl: req.CardImgUrl, + LabelList: req.LabelList, + Province: req.Province, + City: req.City, + PhoneNumList: req.PhoneNumList, + } +} diff --git a/internal/biz/advice_wx.go b/internal/biz/advice_wx.go index 2f096e8..75d5ae6 100644 --- a/internal/biz/advice_wx.go +++ b/internal/biz/advice_wx.go @@ -27,11 +27,11 @@ type WsBroadcaster interface { // 上游(WTAPI)消息通过 login/setCallback 配置的回调地址推送到本服务, // 本模块负责容错解析回调报文、记录消息流水、更新客户互动时间。 type AdviceWxBiz struct { - cfg *config.Config - mongo *pkg.Mongo - wxMsgMongo *mongo_model.AdvicerWxMsgMongo - clientBiz *AdviceClientBiz - strategyBiz *AdviceStrategyBiz + cfg *config.Config + mongo *pkg.Mongo + wxMsgMongo *mongo_model.AdvicerWxMsgMongo + clientBiz *AdviceClientBiz + strategyBiz *AdviceStrategyBiz wsBroadcaster WsBroadcaster } @@ -138,6 +138,15 @@ func (a *AdviceWxBiz) handleOneEvent(ctx context.Context, body []byte) error { newMsgId := event.Data.NewMsgId.String() msgId := event.Data.MsgId.String() + // 过滤:公众号消息(gh_ 开头)不存储不展示 + if strings.HasPrefix(peerWxid, "gh_") { + return nil + } + // 过滤:msgType 为 other 的不存储不展示 + if wx.MsgTypeCategory(msgType) == "other" { + return nil + } + // 媒体消息存原始 XML(去前缀后的),供前端调用下载 API var mediaXml string if wx.IsMediaMsg(msgType) { @@ -150,14 +159,14 @@ func (a *AdviceWxBiz) handleOneEvent(ctx context.Context, body []byte) error { SelfWxid: event.Wxid, SenderWxid: senderWxid, Direction: direction, - MsgType: wx.MsgTypeCategory(msgType), - Content: content, - MediaXml: mediaXml, - MsgId: msgId, - NewMsgId: newMsgId, - Source: mongo_model.WxMsgSourceCallback, - Raw: string(body), - CreateAt: callbackCreateTime(event.Data.CreateTime), + MsgType: wx.MsgTypeCategory(msgType), + Content: content, + MediaXml: mediaXml, + MsgId: msgId, + NewMsgId: newMsgId, + Source: mongo_model.WxMsgSourceCallback, + Raw: string(body), + CreateAt: callbackCreateTime(event.Data.CreateTime), } // 消息去重:使用 AppId + NewMsgId(文档推荐去重键) @@ -381,7 +390,7 @@ func (a *AdviceWxBiz) ConversationList(ctx context.Context, param *entitys.Advic }}, }}, {"$sort": bson.M{"lastMsgTime": -1}}, - {"$skip": int64(page - 1) * int64(size)}, + {"$skip": int64(page-1) * int64(size)}, {"$limit": int64(size)}, } diff --git a/internal/biz/provider_set.go b/internal/biz/provider_set.go index 939bdc9..9ea1c73 100644 --- a/internal/biz/provider_set.go +++ b/internal/biz/provider_set.go @@ -24,4 +24,5 @@ var ProviderSetBiz = wire.NewSet( NewAdviceStrategyBiz, NewAdviceProactiveBiz, NewAdviceIterateBiz, + NewAdviceCustomerBiz, ) diff --git a/internal/data/impl/advice_customer_impl.go b/internal/data/impl/advice_customer_impl.go new file mode 100644 index 0000000..7f711e2 --- /dev/null +++ b/internal/data/impl/advice_customer_impl.go @@ -0,0 +1,26 @@ +package impl + +import ( + "ai_scheduler/internal/data/model" + "ai_scheduler/tmpl/dataTemp" + "ai_scheduler/utils" + "context" +) + +type AdviceCustomerImpl struct { + dataTemp.DataTemp +} + +func NewAdviceCustomerImpl(db *utils.Db) *AdviceCustomerImpl { + return &AdviceCustomerImpl{ + DataTemp: *dataTemp.NewDataTemp(db, new(model.AiAdviceCustomer)), + } +} + +// BatchInsert 批量插入好友记录 +func (a *AdviceCustomerImpl) BatchInsert(ctx context.Context, records []model.AiAdviceCustomer) error { + if len(records) == 0 { + return nil + } + return a.Db.WithContext(ctx).Create(&records).Error +} diff --git a/internal/data/impl/provider_set.go b/internal/data/impl/provider_set.go index 307e4d4..ce27605 100644 --- a/internal/data/impl/provider_set.go +++ b/internal/data/impl/provider_set.go @@ -15,4 +15,5 @@ var ProviderImpl = wire.NewSet( NewAiAdviceModelSupImpl, NewAdviceIndustryImplImpl, NewAdviceAdminImpl, + NewAdviceCustomerImpl, ) diff --git a/internal/data/model/ai_advice_customer.gen.go b/internal/data/model/ai_advice_customer.gen.go new file mode 100644 index 0000000..01a9a8d --- /dev/null +++ b/internal/data/model/ai_advice_customer.gen.go @@ -0,0 +1,38 @@ +package model + +import "time" + +const TableNameAiAdviceCustomer = "ai_advice_customer" + +// AiAdviceCustomer mapped from table +type AiAdviceCustomer struct { + CustomerID int32 `gorm:"column:customer_id;primaryKey;autoIncrement:true" json:"customer_id"` + SelfWxid string `gorm:"column:self_wxid;not null;comment:登录微信的 wxid" json:"self_wxid"` + UserName string `gorm:"column:user_name;not null;comment:微信用户名" json:"user_name"` + NickName string `gorm:"column:nick_name;not null;comment:昵称" json:"nick_name"` + PyInitial string `gorm:"column:py_initial;not null;comment:拼音首字母" json:"py_initial"` + QuanPin string `gorm:"column:quan_pin;not null;comment:全拼" json:"quan_pin"` + Sex int8 `gorm:"column:sex;not null;default:0;comment:性别:0未知 1男 2女" json:"sex"` + Remark string `gorm:"column:remark;not null;comment:备注名" json:"remark"` + RemarkPyInitial string `gorm:"column:remark_py_initial;not null;comment:备注拼音首字母" json:"remark_py_initial"` + RemarkQuanPin string `gorm:"column:remark_quan_pin;not null;comment:备注全拼" json:"remark_quan_pin"` + Signature string `gorm:"column:signature;not null;comment:个性签名" json:"signature"` + Alias string `gorm:"column:alias;not null;comment:微信号(alias)" json:"alias"` + SnsBgImg string `gorm:"column:sns_bg_img;not null;comment:朋友圈背景图" json:"sns_bg_img"` + Country string `gorm:"column:country;not null;comment:国家" json:"country"` + BigHeadImgUrl string `gorm:"column:big_head_img_url;not null;comment:大头像 URL" json:"big_head_img_url"` + SmallHeadImgUrl string `gorm:"column:small_head_img_url;not null;comment:小头像 URL" json:"small_head_img_url"` + Description string `gorm:"column:description;not null;comment:描述" json:"description"` + CardImgUrl string `gorm:"column:card_img_url;not null;comment:名片图 URL" json:"card_img_url"` + LabelList string `gorm:"column:label_list;not null;comment:标签列表" json:"label_list"` + Province string `gorm:"column:province;not null;comment:省份" json:"province"` + City string `gorm:"column:city;not null;comment:城市" json:"city"` + PhoneNumList string `gorm:"column:phone_num_list;not null;comment:手机号列表" json:"phone_num_list"` + CreateAt time.Time `gorm:"column:create_at;default:CURRENT_TIMESTAMP" json:"create_at"` + UpdateAt time.Time `gorm:"column:update_at;default:CURRENT_TIMESTAMP" json:"update_at"` +} + +// TableName AiAdviceCustomer's table name +func (*AiAdviceCustomer) TableName() string { + return TableNameAiAdviceCustomer +} diff --git a/internal/entitys/advicer_data.go b/internal/entitys/advicer_data.go index 765761f..b58d872 100644 --- a/internal/entitys/advicer_data.go +++ b/internal/entitys/advicer_data.go @@ -432,13 +432,13 @@ type AdvicerWxMarkAsReadReq struct { // AdvicerWxConversationItem 会话列表条目 type AdvicerWxConversationItem struct { - Wxid string `json:"wxid"` // 对话方 wxid - LastMsg string `json:"lastMsg"` // 最后一条消息内容(截断) - LastMsgType string `json:"lastMsgType"` // 最后一条消息类型 - LastMsgTime int64 `json:"lastMsgTime"` // 最后一条消息时间戳(Unix 秒) + Wxid string `json:"wxid"` // 对话方 wxid + LastMsg string `json:"lastMsg"` // 最后一条消息内容(截断) + LastMsgType string `json:"lastMsgType"` // 最后一条消息类型 + LastMsgTime int64 `json:"lastMsgTime"` // 最后一条消息时间戳(Unix 秒) LastDirection string `json:"lastDirection"` // 最后一条消息方向 - UnreadCount int `json:"unreadCount"` // 未读消息数(客户发来的未读) - IsGroup bool `json:"isGroup"` // 是否群聊 + UnreadCount int `json:"unreadCount"` // 未读消息数(客户发来的未读) + IsGroup bool `json:"isGroup"` // 是否群聊 } // AdvicerProactiveLogListReq 主动触达记录查询 @@ -449,3 +449,60 @@ type AdvicerProactiveLogListReq struct { Page int `json:"page"` PageSize int `json:"page_size"` } + +// ==================== 微信好友(ai_advice_customer) ==================== + +// AdvicerCustomerAddReq 新增微信好友 +type AdvicerCustomerAddReq struct { + SelfWxid string `json:"selfWxid"` + UserName string `json:"userName"` + NickName string `json:"nickName"` + PyInitial string `json:"pyInitial"` + QuanPin string `json:"quanPin"` + Sex int8 `json:"sex"` + Remark string `json:"remark"` + RemarkPyInitial string `json:"remarkPyInitial"` + RemarkQuanPin string `json:"remarkQuanPin"` + Signature string `json:"signature"` + Alias string `json:"alias"` + SnsBgImg string `json:"snsBgImg"` + Country string `json:"country"` + BigHeadImgUrl string `json:"bigHeadImgUrl"` + SmallHeadImgUrl string `json:"smallHeadImgUrl"` + Description string `json:"description"` + CardImgUrl string `json:"cardImgUrl"` + LabelList string `json:"labelList"` + Province string `json:"province"` + City string `json:"city"` + PhoneNumList string `json:"phoneNumList"` +} + +// AdvicerCustomerListReq 微信好友列表查询 +type AdvicerCustomerListReq struct { + SelfWxid string `json:"selfWxid"` + Page int `json:"page"` + PageSize int `json:"page_size"` +} + +// AdvicerCustomerDelReq 删除微信好友 +type AdvicerCustomerDelReq struct { + CustomerId int32 `json:"customerId"` + SelfWxid string `json:"selfWxid"` +} + +// AdvicerCustomerDiffReq 好友差集查询 +type AdvicerCustomerDiffReq struct { + SelfWxid string `json:"selfWxid"` // 销售本人 wxid + UserNames []string `json:"userNames"` // 前端获取的好友 userName 列表 +} + +// AdvicerCustomerDiffRes 好友差集响应 +type AdvicerCustomerDiffRes struct { + List []model.AiAdviceCustomer `json:"list"` // 库中已有的好友记录 + Diff []string `json:"diff"` // 库中不存在的好友 userName +} + +// AdvicerCustomerBatchAddReq 批量新增微信好友 +type AdvicerCustomerBatchAddReq struct { + List []AdvicerCustomerAddReq `json:"list"` +} diff --git a/internal/server/http.go b/internal/server/http.go index 4859f1d..8c2df23 100644 --- a/internal/server/http.go +++ b/internal/server/http.go @@ -29,6 +29,7 @@ func NewHTTPServer( smartService *advice.SmartService, wxProxy *advice.WxProxyService, wsHub *advice.WxWsHub, + adviceCustomer *advice.CustomerService, ) *fiber.App { //构建 server app := initRoute() @@ -36,7 +37,7 @@ func NewHTTPServer( // 上传文件静态托管:/upload/...(聊天记录等) app.Static("/upload", "./upload") app.Static("/", "./web") - router.SetupRoutes(cfg, app, adviceFile, adviceData, adviceChat, adviceProject, adviceTalkSkill, adviceClient, industry, admin, modelSup, activity, wxHook, smartService, wxProxy, wsHub) + router.SetupRoutes(cfg, app, adviceFile, adviceData, adviceChat, adviceProject, adviceTalkSkill, adviceClient, industry, admin, modelSup, activity, wxHook, smartService, wxProxy, wsHub, adviceCustomer) return app } diff --git a/internal/server/router/advicer.go b/internal/server/router/advicer.go index dcaa49d..39b9cdd 100644 --- a/internal/server/router/advicer.go +++ b/internal/server/router/advicer.go @@ -24,6 +24,7 @@ func AdvicerRouterRegist( wxHook *advice.WxHookService, smart *advice.SmartService, wxProxy *advice.WxProxyService, + adviceCustomer *advice.CustomerService, ) { advicer := r.Group("advice/admin") // 登录放行 @@ -80,9 +81,9 @@ func AdvicerRouterRegist( advicer.Post("activity/active", activity.ActiveList) //微信回调与消息流水 - advicer.Post("wx/callback/set", wxHook.SetCallback) // 设置上游消息回调地址 - advicer.Post("wx/callback/info", wxHook.CallbackInfo) // 获取建议的回调地址 - advicer.Post("wxmsg/list", wxHook.MsgList) // 消息流水查询 + advicer.Post("wx/callback/set", wxHook.SetCallback) // 设置上游消息回调地址 + advicer.Post("wx/callback/info", wxHook.CallbackInfo) // 获取建议的回调地址 + advicer.Post("wxmsg/list", wxHook.MsgList) // 消息流水查询 advicer.Post("wx/conversation/list", wxHook.ConversationList) // 会话列表(聚合最新消息) advicer.Post("wx/conversation/msgs", wxHook.ConversationMsgs) // 会话消息记录 advicer.Post("wx/conversation/read", wxHook.MarkAsRead) // 标记会话消息已读 @@ -116,4 +117,11 @@ func AdvicerRouterRegist( // 微信 API 代理(包装转发,标准响应格式) advicer.All("wx/*", wxProxy.Proxy) + + // 微信好友(ai_advice_customer) + advicer.Post("advicer/customer/add", adviceCustomer.Add) + advicer.Post("advicer/customer/list", adviceCustomer.List) + advicer.Post("advicer/customer/del", adviceCustomer.Del) + advicer.Post("advicer/customer/diff", adviceCustomer.Diff) + advicer.Post("advicer/customer/batch_add", adviceCustomer.BatchAdd) } diff --git a/internal/server/router/router.go b/internal/server/router/router.go index caa382d..c7bc747 100644 --- a/internal/server/router/router.go +++ b/internal/server/router/router.go @@ -24,6 +24,7 @@ func SetupRoutes(cfg *config.Config, app *fiber.App, adviceFile *advice.FileServ smart *advice.SmartService, wxProxy *advice.WxProxyService, wsHub *advice.WxWsHub, + adviceCustomer *advice.CustomerService, ) { app.Use(func(c *fiber.Ctx) error { // 设置 CORS 头 @@ -80,6 +81,7 @@ func SetupRoutes(cfg *config.Config, app *fiber.App, adviceFile *advice.FileServ wxHook, smart, wxProxy, + adviceCustomer, ) } diff --git a/internal/services/advice/customer_new.go b/internal/services/advice/customer_new.go new file mode 100644 index 0000000..163cab6 --- /dev/null +++ b/internal/services/advice/customer_new.go @@ -0,0 +1,68 @@ +package advice + +import ( + "ai_scheduler/internal/biz" + "ai_scheduler/internal/entitys" + "ai_scheduler/internal/pkg" + + "github.com/gofiber/fiber/v2" +) + +// CustomerService 微信好友数据服务 +type CustomerService struct { + customerBiz *biz.AdviceCustomerBiz +} + +func NewCustomerService(customerBiz *biz.AdviceCustomerBiz) *CustomerService { + return &CustomerService{customerBiz: customerBiz} +} + +// Add 新增单条好友 +func (s *CustomerService) Add(c *fiber.Ctx) error { + req := &entitys.AdvicerCustomerAddReq{} + if err := c.BodyParser(req); err != nil { + return err + } + err := s.customerBiz.Add(c.UserContext(), req) + return pkg.HandleResponse(c, nil, err) +} + +// List 好友列表查询 +func (s *CustomerService) List(c *fiber.Ctx) error { + req := &entitys.AdvicerCustomerListReq{} + if err := c.BodyParser(req); err != nil { + return err + } + list, err := s.customerBiz.List(c.UserContext(), req) + return pkg.HandleResponse(c, list, err) +} + +// Del 删除好友 +func (s *CustomerService) Del(c *fiber.Ctx) error { + req := &entitys.AdvicerCustomerDelReq{} + if err := c.BodyParser(req); err != nil { + return err + } + err := s.customerBiz.Del(c.UserContext(), req) + return pkg.HandleResponse(c, nil, err) +} + +// Diff 好友差集查询 +func (s *CustomerService) Diff(c *fiber.Ctx) error { + req := &entitys.AdvicerCustomerDiffReq{} + if err := c.BodyParser(req); err != nil { + return err + } + diff, err := s.customerBiz.Diff(c.UserContext(), req) + return pkg.HandleResponse(c, diff, err) +} + +// BatchAdd 批量新增好友 +func (s *CustomerService) BatchAdd(c *fiber.Ctx) error { + req := &entitys.AdvicerCustomerBatchAddReq{} + if err := c.BodyParser(req); err != nil { + return err + } + err := s.customerBiz.BatchAdd(c.UserContext(), req) + return pkg.HandleResponse(c, nil, err) +} diff --git a/internal/services/advice/provider_set.go b/internal/services/advice/provider_set.go index 6f899dc..dd36b9c 100644 --- a/internal/services/advice/provider_set.go +++ b/internal/services/advice/provider_set.go @@ -1,6 +1,8 @@ package advice import ( + "ai_scheduler/internal/biz" + "github.com/google/wire" ) @@ -18,6 +20,8 @@ var ProviderService = wire.NewSet( NewActivityService, NewWxHookService, NewWxWsHub, + wire.Bind(new(biz.WsBroadcaster), new(*WxWsHub)), NewSmartService, NewWxProxyService, + NewCustomerService, ) diff --git a/internal/services/advice/wx_ws_hub.go b/internal/services/advice/wx_ws_hub.go index c9a6e00..aaf35dd 100644 --- a/internal/services/advice/wx_ws_hub.go +++ b/internal/services/advice/wx_ws_hub.go @@ -2,6 +2,7 @@ package advice import ( "ai_scheduler/internal/biz" + "ai_scheduler/internal/config" "ai_scheduler/internal/pkg" "encoding/json" "sync" @@ -25,10 +26,10 @@ type wsClient struct { } // NewWxWsHub 创建 WebSocket Hub(实现 biz.WsBroadcaster 接口) -func NewWxWsHub(jwtSecret string) *WxWsHub { +func NewWxWsHub(cfg *config.Config) *WxWsHub { return &WxWsHub{ clients: make(map[*wsClient]struct{}), - jwtSecret: jwtSecret, + jwtSecret: cfg.JwtSecret, } } diff --git a/server.exe b/server.exe index b5e8ac3..be4a423 100755 Binary files a/server.exe and b/server.exe differ diff --git a/sql/04_ai_advice_customer.sql b/sql/04_ai_advice_customer.sql new file mode 100644 index 0000000..003fa6c --- /dev/null +++ b/sql/04_ai_advice_customer.sql @@ -0,0 +1,29 @@ +CREATE TABLE `ai_advice_customer` ( + `customer_id` int NOT NULL AUTO_INCREMENT COMMENT '自增主键', + `self_wxid` varchar(50) NOT NULL DEFAULT '' COMMENT '登录微信的 wxid(标识归属哪个微信号)', + `user_name` varchar(50) NOT NULL DEFAULT '' COMMENT '微信用户名(wxid_xxx 或自定义)', + `nick_name` varchar(30) NOT NULL DEFAULT '' COMMENT '昵称', + `py_initial` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '拼音首字母', + `quan_pin` varchar(30) NOT NULL DEFAULT '' COMMENT '全拼', + `sex` tinyint NOT NULL DEFAULT '0' COMMENT '性别:0未知 1男 2女', + `remark` varchar(200) NOT NULL DEFAULT '' COMMENT '备注名', + `remark_py_initial` varchar(2) NOT NULL DEFAULT '' COMMENT '备注拼音首字母', + `remark_quan_pin` varchar(200) NOT NULL DEFAULT '' COMMENT '备注全拼', + `signature` varchar(200) NOT NULL DEFAULT '' COMMENT '个性签名', + `alias` varchar(50) NOT NULL DEFAULT '' COMMENT '微信号(alias)', + `sns_bg_img` varchar(250) NOT NULL DEFAULT '' COMMENT '朋友圈背景图', + `country` varchar(20) NOT NULL DEFAULT '' COMMENT '国家', + `big_head_img_url` varchar(250) NOT NULL DEFAULT '' COMMENT '大头像 URL', + `small_head_img_url` varchar(250) NOT NULL DEFAULT '' COMMENT '小头像 URL', + `description` varchar(200) NOT NULL DEFAULT '' COMMENT '描述', + `card_img_url` varchar(200) NOT NULL DEFAULT '' COMMENT '名片图 URL', + `label_list` varchar(100) NOT NULL DEFAULT '' COMMENT '标签列表', + `province` varchar(20) NOT NULL DEFAULT '' COMMENT '省份', + `city` varchar(20) NOT NULL DEFAULT '' COMMENT '城市', + `phone_num_list` varchar(100) NOT NULL DEFAULT '' COMMENT '手机号列表', + `create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`customer_id`,`self_wxid`), + UNIQUE KEY `uk_wxid_user` (`self_wxid`,`user_name`), + KEY `idx_self_wxid` (`self_wxid`) +) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='微信好友信息'; diff --git a/web/assets/js/project_data.js b/web/assets/js/project_data.js index 777cac9..1e972b4 100644 --- a/web/assets/js/project_data.js +++ b/web/assets/js/project_data.js @@ -682,23 +682,8 @@ function openAdvicerWxWorkbench(advicerId, advicerName, wxDeviceId) { }; return; } - // 3. 两者都已配置,用销售的 wxDeviceId 强制检测在线状态 - Core.loading(true, '检测微信在线状态…'); - Core.wxApi('login/checkOnline', { appId: wxDeviceId }) - .then(function (online) { - Core.loading(false); - if (online) { - enterWxWorkbench(advicerId, advicerName); - } else { - Core.toast('微信已离线,进入工作台后需重新扫码登录', 'warn'); - enterWxWorkbench(advicerId, advicerName); - } - }) - .catch(function (e) { - Core.loading(false); - Core.toast('在线状态检测失败,进入工作台后将自动检测', 'warn'); - enterWxWorkbench(advicerId, advicerName); - }); + // 3. 两者都已配置,直接进入工作台(在线检测由工作台 mount 负责) + enterWxWorkbench(advicerId, advicerName); }; // 如果 state.detail 尚未加载,先加载项目信息 if (state.detail && state.detail.Base) { diff --git a/web/assets/js/wx.js b/web/assets/js/wx.js index 3882d0c..9e50dc5 100644 --- a/web/assets/js/wx.js +++ b/web/assets/js/wx.js @@ -96,35 +96,15 @@ renderContacts(); WxN.renderChat(); - // 确定用于检测在线状态的 appId: - // 优先使用 QR 登录后的 state.app.appId - var appId = (state.app && state.app.appId) ? state.app.appId : null; - - if (appId) { - // 已有登录态,直接检测在线 - console.log("[Wx.mount] checkOnline, appId=" + appId); + // 从 URL hash 获取 wx-advicer 值,调用 advicer/info 获取 wx_device_id(即 app_id),再检测在线状态 + var advicerId = parseHashAdvicerId(); + if (advicerId) { + console.log("[Wx.mount] hash wx-advicer=" + advicerId + ", fetching fresh device info"); WxN.renderLoginCard(); - WxN.checkOnline().then(function (online) { - console.log("[Wx.mount] checkOnline result: " + online); - if (online) { - WxN.checkOnlineLoop(); - loadProfile().then(function () { WxN.loadConversations(); }); - WxN.loadContacts(); - } else { - WxN.getQrCode(); - } - }); + fetchDeviceAndCheck(advicerId); } else { - // 无登录态,从 URL hash 读取 advicerId,通过 API 获取设备信息 - var advicerId = parseHashAdvicerId(); - if (advicerId) { - console.log("[Wx.mount] fetching device info for advicerId=" + advicerId); - WxN.renderLoginCard(); - fetchDeviceAndCheck(advicerId); - } else { - console.log("[Wx.mount] no app/hash, showing QR login"); - WxN.renderLoginCard(); - } + console.log("[Wx.mount] no wx-advicer in hash, showing QR login"); + WxN.renderLoginCard(); } return { unmount: unmount }; } @@ -261,43 +241,126 @@ ghs: (data && data.ghs) || [] }; renderContacts(); - loadBriefInfo(forceRefresh); + // 群聊仍需 getBriefInfo 拉取 + loadBriefInfoForChatrooms(); + // 好友信息统一由 diff 接口提供:库中已有的从 list 填充 brief,差集部分调 getBriefInfo 补充后入库 + syncCustomerDiff(); }) .catch(function (e) { Core.loading(false); Core.toast("拉取通讯录失败:" + e.message, "err"); }); } - function loadBriefInfo(forceRefresh) { - var wxids = state.contacts.friends.concat(state.contacts.chatrooms); - var missing = forceRefresh - ? wxids // 强制刷新:全部重新拉取 - : wxids.filter(function (w) { return !state.brief[w]; }); - if (!missing.length) { renderContacts(); return; } - state.briefLoading = true; - state.briefTotalCount = missing.length; - state.briefLoadedCount = 0; - renderContacts(); - // 每批 20 个(接口限制),拉一批渲染一批 + /** 仅拉取群聊的 brief info */ + function loadBriefInfoForChatrooms() { + var chatrooms = state.contacts.chatrooms; + if (!chatrooms.length) return; var batches = []; - for (var i = 0; i < missing.length; i += 20) batches.push(missing.slice(i, i + 20)); + for (var i = 0; i < chatrooms.length; i += 20) batches.push(chatrooms.slice(i, i + 20)); var chain = Promise.resolve(); batches.forEach(function (batch) { chain = chain.then(function () { - return Core.wxApi("contacts/getBriefInfo", { appId: state.app.appId, wxids: batch }) + return getBriefInfoWithRetry(batch) .then(function (list) { (list || []).forEach(function (info) { if (info && info.userName) state.brief[info.userName] = info; }); - state.briefLoadedCount += batch.length; - // 每批拉完立即渲染 + 持久化缓存 renderContacts(); - saveBriefCache(); }) - .catch(function () { state.briefLoadedCount += batch.length; }); + .catch(function () {}); }); }); - chain.then(function () { - state.briefLoading = false; - state.briefLoadedCount = state.briefTotalCount; - renderContacts(); - }); + } + + /** getBriefInfo 带重试(最多 3 次,间隔 2 秒) */ + function getBriefInfoWithRetry(wxids, retries) { + retries = retries || 3; + return Core.wxApi("contacts/getBriefInfo", { appId: state.app.appId, wxids: wxids }) + .catch(function (e) { + if (retries <= 1) throw e; + console.warn("[getBriefInfo] retrying, " + (retries - 1) + " attempts left"); + return new Promise(function (resolve) { setTimeout(resolve, 2000); }) + .then(function () { return getBriefInfoWithRetry(wxids, retries - 1); }); + }); + } + + /** 同步好友差集到 ai_advice_customer 表 */ + function syncCustomerDiff() { + var selfWxid = state.app && state.app.wxid; + if (!selfWxid || !state.contacts.friends.length) return; + Core.api("advicer/customer/diff", { selfWxid: selfWxid, userNames: state.contacts.friends }) + .then(function (res) { + if (!res) return; + // 将库中已有的好友记录写入 brief + (res.list || []).forEach(function (item) { + if (item.user_name && !state.brief[item.user_name]) { + state.brief[item.user_name] = { + userName: item.user_name, + nickName: item.nick_name, + remark: item.remark, + sex: item.sex, + bigHeadImgUrl: item.big_head_img_url, + smallHeadImgUrl: item.small_head_img_url, + alias: item.alias, + signature: item.signature, + province: item.province, + city: item.city + }; + } + }); + renderContacts(); + var diff = res.diff; + if (!diff || !diff.length) return; + console.log("[syncCustomerDiff] missing " + diff.length + " friends, fetching brief info"); + // 每批 20 个拉取 getBriefInfo(带重试) + var batches = []; + for (var i = 0; i < diff.length; i += 20) batches.push(diff.slice(i, i + 20)); + var allInfo = []; + var chain = Promise.resolve(); + batches.forEach(function (batch) { + chain = chain.then(function () { + return getBriefInfoWithRetry(batch) + .then(function (list) { + (list || []).forEach(function (info) { + if (info && info.userName) { + allInfo.push(info); + state.brief[info.userName] = info; + } + }); + }); + }); + }); + chain.then(function () { + if (!allInfo.length) return; + // 组装入库数据 + var records = allInfo.map(function (info) { + return { + selfWxid: selfWxid, + userName: info.userName || "", + nickName: info.nickName || "", + pyInitial: info.pyInitial || "", + quanPin: info.quanPin || "", + sex: info.sex || 0, + remark: info.remark || "", + remarkPyInitial: info.remarkPyInitial || "", + remarkQuanPin: info.remarkQuanPin || "", + signature: info.signature || "", + alias: info.alias || "", + snsBgImg: info.snsBgImg || "", + country: info.country || "", + bigHeadImgUrl: info.bigHeadImgUrl || "", + smallHeadImgUrl: info.smallHeadImgUrl || "", + description: info.description || "", + cardImgUrl: info.cardImgUrl || "", + labelList: info.labelList || "", + province: info.province || "", + city: info.city || "", + phoneNumList: info.phoneNumList || "" + }; + }); + Core.api("advicer/customer/batch_add", { list: records }) + .then(function () { console.log("[syncCustomerDiff] synced " + records.length + " friends"); }) + .catch(function (e) { console.warn("[syncCustomerDiff] batch_add failed:", e); }); + renderContacts(); + }); + }) + .catch(function (e) { console.warn("[syncCustomerDiff] diff failed:", e); }); } function contactDisplay(wxid) { diff --git a/web/assets/js/wx_login.js b/web/assets/js/wx_login.js index fb2503e..20d1468 100644 --- a/web/assets/js/wx_login.js +++ b/web/assets/js/wx_login.js @@ -158,6 +158,14 @@ Core.loading(false); if (!data || !data.uuid) { Core.toast("获取二维码失败", "err"); return; } state().qr = { uuid: data.uuid, img: data.qrImgBase64, status: 0, expired: false, appId: data.appId || "", regionId: regionId }; + // 将接口返回的 appId 更新到销售的 wx_device_id + var hashMatch = (location.hash || '').match(/wx-advicer=(\d+)/); + var advicerId = hashMatch ? Number(hashMatch[1]) : 0; + if (data.appId && advicerId) { + Core.api("advicer/wx_device/update", { advicerId: advicerId, wxDeviceId: data.appId }) + .then(function () { console.log("[getQrCode] wx_device_id updated: " + data.appId); }) + .catch(function (e) { console.warn("[getQrCode] update wx_device_id failed:", e); }); + } renderLoginCard(); startLoginPolling(); }) diff --git a/web/project.html b/web/project.html index a98e3c2..1de3c16 100644 --- a/web/project.html +++ b/web/project.html @@ -92,14 +92,14 @@ - - + + - +