Browse Source

Merge branch 'feature/eta_1.4.7'

hsun 1 year ago
parent
commit
64df382c1f
10 changed files with 1164 additions and 25 deletions
  1. 12 5
      go.mod
  2. 62 9
      go.sum
  3. 60 0
      models/base_from_fenwei.go
  4. 3 1
      services/base.go
  5. 903 0
      services/base_from_fenwei.go
  6. 67 0
      services/fenwei_watch.go
  7. 11 4
      services/task.go
  8. 21 0
      utils/common.go
  9. 16 0
      utils/config.go
  10. 9 6
      utils/constants.go

+ 12 - 5
go.mod

@@ -7,12 +7,13 @@ require (
 	github.com/beego/beego/v2 v2.1.4
 	github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b
 	github.com/mozillazg/go-pinyin v0.20.0
-	github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
 	github.com/patrickmn/go-cache v2.1.0+incompatible
 	github.com/rdlucklib/rdluck_tools v1.0.3
 	github.com/robfig/cron/v3 v3.0.1
+	github.com/shakinm/xlsReader v0.9.12
 	github.com/shopspring/decimal v1.3.1
 	github.com/tealeg/xlsx v1.0.5
+	github.com/xuri/excelize/v2 v2.8.0
 )
 
 require (
@@ -28,17 +29,23 @@ require (
 	github.com/hashicorp/golang-lru v0.5.4 // indirect
 	github.com/kr/text v0.2.0 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
+	github.com/metakeule/fmtdate v1.1.2 // indirect
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
+	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/prometheus/client_golang v1.16.0 // indirect
 	github.com/prometheus/client_model v0.3.0 // indirect
 	github.com/prometheus/common v0.42.0 // indirect
 	github.com/prometheus/procfs v0.10.1 // indirect
+	github.com/richardlehane/mscfb v1.0.4 // indirect
+	github.com/richardlehane/msoleps v1.0.3 // indirect
 	github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
-	golang.org/x/crypto v0.10.0 // indirect
-	golang.org/x/net v0.10.0 // indirect
-	golang.org/x/sys v0.9.0 // indirect
-	golang.org/x/text v0.10.0 // indirect
+	github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca // indirect
+	github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a // indirect
+	golang.org/x/crypto v0.12.0 // indirect
+	golang.org/x/net v0.14.0 // indirect
+	golang.org/x/sys v0.11.0 // indirect
+	golang.org/x/text v0.12.0 // indirect
 	google.golang.org/protobuf v1.30.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )

+ 62 - 9
go.sum

@@ -104,12 +104,16 @@ github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
 github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/metakeule/fmtdate v1.1.2 h1:n9M7H9HfAqp+6OA98wXGMdcAr6omshSNVct65Bks1lQ=
+github.com/metakeule/fmtdate v1.1.2/go.mod h1:2JyMFlKxeoGy1qS6obQukT0AL0Y4iNANQL8scbSdT4E=
 github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+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/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ=
 github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -117,8 +121,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
-github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
 github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
 github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@@ -151,9 +153,16 @@ github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+Pymzi
 github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
 github.com/rdlucklib/rdluck_tools v1.0.3 h1:iOtK2QPlPQ6CL6c1htCk5VnFCHzyG6DCfJtunrMswK0=
 github.com/rdlucklib/rdluck_tools v1.0.3/go.mod h1:9Onw9o4w19C8KE5lxb8GyxgRBbZweRVkQSc79v38EaA=
+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.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
+github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
 github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
 github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
 github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
+github.com/shakinm/xlsReader v0.9.12 h1:F6GWYtCzfzQqdIuqZJ0MU3YJ7uwH1ofJtmTKyWmANQk=
+github.com/shakinm/xlsReader v0.9.12/go.mod h1:ME9pqIGf+547L4aE4YTZzwmhsij+5K9dR+k84OO6WSs=
 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
 github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 h1:DAYUYH5869yV94zvCES9F51oYtN5oGlwjxJJz7ZCnik=
 github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
@@ -167,9 +176,12 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
 github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+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 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
 github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
 github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
@@ -177,24 +189,43 @@ github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
 github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
 github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
 github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
+github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca h1:uvPMDVyP7PXMMioYdyPH+0O+Ta/UO1WFfNYMO3Wz0eg=
+github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
+github.com/xuri/excelize/v2 v2.8.0 h1:Vd4Qy809fupgp1v7X+nCS/MioeQmYVVzi495UCTqB7U=
+github.com/xuri/excelize/v2 v2.8.0/go.mod h1:6iA2edBTKxKbZAa7X5bDhcCg51xdOn1Ar5sfoXRGrQg=
+github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a h1:Mw2VNrNNNjDtw68VsEj2+st+oCSn4Uz7vZw6TbhcV1o=
+github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
 github.com/ylywyn/jpush-api-go-client v0.0.0-20190906031852-8c4466c6e369/go.mod h1:Nv7wKD2/bCdKUFNKcJRa99a+1+aSLlCRJFriFYdjz/I=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
-golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
+golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
+golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
+golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
+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/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
+golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
 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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -204,11 +235,32 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
+golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+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/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 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=
@@ -235,5 +287,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 60 - 0
models/base_from_fenwei.go

@@ -0,0 +1,60 @@
+package models
+
+import "time"
+
+// FenweiExcelIndex 汾渭Excel指标数据
+type FenweiExcelIndex struct {
+	//ClassifyName string `description:"指标目录"`
+	//ClassifySort int    `description:"指标目录排序号"`
+	IndexName    string `description:"指标名称"`
+	IndexCode    string `description:"指标编码"`
+	Unit         string `description:"单位"`
+	Sort         int    `description:"排序号"`
+	Frequency    string `description:"频度"`
+	TerminalCode string `description:"编码"`
+	ClassifyId   int    `description:"分类ID"`
+	ExcelDataMap map[string]string
+}
+
+// BaseFromFenweiClassifyItem 汾渭数据分类信息
+type BaseFromFenweiClassifyItem struct {
+	ClassifyId   int                           `description:"分类ID"`
+	ClassifyName string                        `description:"分类名称"`
+	ParentId     int                           `description:"父级id"`
+	Level        int                           `description:"层级"`
+	Sort         int                           `description:"排序字段"`
+	CreateTime   string                        `description:"创建时间"`
+	ModifyTime   string                        `description:"修改时间"`
+	Child        []*BaseFromFenweiClassifyItem `description:"子分类"`
+}
+
+type EdbLibFenweiClassifyResponse struct {
+	Ret     int
+	Msg     string
+	ErrMsg  string
+	ErrCode string
+	Data    []BaseFromFenweiClassifyItem
+}
+
+type BaseFromFenweiIndex struct {
+	FenweiIndexId int64 `orm:"column(fenwei_index_id);pk"`
+	IndexCode     string
+	IndexName     string
+	Frequency     string
+	Unit          string
+	ClassifyId    int
+	StartDate     string
+	EndDate       string
+	Sort          int
+	TerminalCode  string
+	CreateTime    time.Time
+	ModifyTime    time.Time
+}
+
+type EdbLibFenweiIndexListResponse struct {
+	Ret     int
+	Msg     string
+	ErrMsg  string
+	ErrCode string
+	Data    []BaseFromFenweiIndex
+}

+ 3 - 1
services/base.go

@@ -44,6 +44,8 @@ func HttpPost(url, postData string, params ...string) ([]byte, error) {
 	}
 	defer resp.Body.Close()
 	b, err := ioutil.ReadAll(resp.Body)
-	fmt.Println("HttpPost:" + string(b))
+	if err != nil {
+		fmt.Println("HttpPost:" + string(b))
+	}
 	return b, err
 }

+ 903 - 0
services/base_from_fenwei.go

@@ -0,0 +1,903 @@
+package services
+
+import (
+	"encoding/json"
+	"eta/eta_data_analysis/models"
+	"eta/eta_data_analysis/utils"
+	"fmt"
+	"github.com/shakinm/xlsReader/xls"
+	"github.com/tealeg/xlsx"
+	"github.com/xuri/excelize/v2"
+	"path"
+	"strings"
+	"time"
+)
+
+const (
+	FenweiIndexNamePrefix = "fwsj" // 指标名称前缀
+
+	FenweiExcelNameA    = "动力煤产销存-66家"
+	FenweiExcelNameB    = "动力煤产销存-100家"
+	FenweiExcelNameC    = "焦煤产销存-53家"
+	FenweiNewExcelNameC = "炼焦煤产销存分省-53家"
+	FenweiExcelNameD    = "焦煤产销存-88家"
+	FenweiNewExcelNameD = "炼焦煤产销存分省-88家"
+	FenweiExcelNameE    = "样本焦化厂焦煤"
+
+	FenweiYangBenIndexNamePre    = "样本焦企炼焦煤库存可用天数"
+	FenweiYangBenIndexClassifyId = 5 // 样本焦企炼焦分类ID
+)
+
+var FenweiProvinces = []string{
+	"内蒙古", "山西", "陕西", "三省合计", "临汾市", "临汾", "吕梁市", "吕梁", "长治市", "长治", "山西其他", "河北", "合计", "山东", "其他",
+}
+
+// FenweiProvinceClassifyMapping 指标名称省份->分类省份
+var FenweiProvinceClassifyMapping = map[string]string{
+	"内蒙古":  "内蒙古",
+	"山西":   "山西",
+	"陕西":   "陕西",
+	"三省合计": "三省合计",
+	"临汾市":  "临汾市",
+	"吕梁市":  "吕梁市",
+	"长治市":  "长治市",
+	"临汾":   "临汾市",
+	"吕梁":   "吕梁市",
+	"长治":   "长治市",
+	"山西其他": "山西其他",
+	"河北":   "河北",
+	"山东":   "山东",
+	"合计":   "合计",
+	"其他":   "其他",
+}
+
+// FenweiFirstClassifyMap excel表名->一级分类ID
+var FenweiFirstClassifyMap = map[string]int{
+	FenweiExcelNameA: 1,
+	FenweiExcelNameB: 2,
+	FenweiExcelNameC: 3,
+	FenweiExcelNameD: 4,
+	FenweiExcelNameE: 5,
+}
+
+// FenweiNewDlm66DiffIndexNameReplaceMapping 动力煤66家-指标名称不同的进行替换
+var FenweiNewDlm66DiffIndexNameReplaceMapping = map[string]string{
+	"价格平均上涨幅度(元/吨)": "煤矿价格平均上涨幅度",
+	"库存库存量(万吨)":     "煤矿库存",
+	"盈亏情况盈利煤矿数量":    "盈利煤矿数量",
+	"盈亏情况平均利润(元/吨)": "煤矿平均利润",
+	"盈亏情况亏损煤矿数量":    "亏损煤矿数量",
+	"盈亏情况平均亏损(元/吨)": "煤矿平均亏损",
+	"周度产量产量(万吨)":    "煤矿周度产量",
+	"销售好":           "销售好煤矿数量",
+	"销售一般":          "销售一般煤矿数量",
+	"销售不好":          "销售不好煤矿数量",
+	"销售关闭":          "关闭煤矿数量",
+	"产能利用率产能利用率":    "煤矿产能利用率",
+	"开工率开工率":        "煤矿算术平均开工率(含停产)",
+	"价格平均下跌幅度":      "煤矿价格平均下跌幅度",
+}
+
+// FenweiNewDlm66IgnoreIndexNameMapping 动力煤66家-需要忽略的指标名称
+var FenweiNewDlm66IgnoreIndexNameMapping = []string{
+	"库存环比", "发运至港口平均利润", "周度产量环比", "开工率算数平均(不含停产矿)", "变化", "产能利用率变化", "开工率变化",
+}
+
+// FenweiNewDlm100DiffIndexNameReplaceMapping 动力煤100家-指标名称不同的进行替换
+var FenweiNewDlm100DiffIndexNameReplaceMapping = map[string]string{
+	"价格平均上涨幅度(元/吨)": "煤矿价格平均上涨幅度",
+	"价格平均下跌幅度":      "煤矿价格平均下跌幅度",
+	"库存库存量(万吨)":     "煤矿库存",
+	"库存环比":          "煤矿库存环比",
+	"盈亏情况盈利煤矿数量":    "盈利煤矿数量",
+	"盈亏情况平均利润(元/吨)": "煤矿平均利润",
+	"盈亏情况亏损煤矿数量":    "亏损煤矿数量",
+	"盈亏情况平均亏损(元/吨)": "煤矿平均亏损",
+	"发运至港口平均利润":     "煤炭发运至港口平均利润",
+	"周度产量产量(万吨)":    "煤矿周度产量",
+	"周度产量环比":        "煤矿周度产量环比",
+	"产能利用率产能利用率":    "煤矿产能利用率",
+	"产能利用率变化":       "煤矿产能利用率环比",
+	"开工率开工率":        "煤矿平均开工率",
+	"开工率变化":         "煤矿平均开工率环比",
+	"销售好":           "销售好煤矿数量",
+	"销售一般":          "销售一般煤矿数量",
+	"销售不好":          "销售不好煤矿数量",
+	"销售关闭":          "关闭煤矿数量",
+}
+
+// FenweiNewDlm100IgnoreIndexNameMapping 动力煤100家-需要忽略的指标名称
+var FenweiNewDlm100IgnoreIndexNameMapping = make([]string, 0)
+
+// FenweiNewJm53DiffIndexNameReplaceMapping 焦煤53家-指标名称不同的进行替换
+var FenweiNewJm53DiffIndexNameReplaceMapping = map[string]string{
+	"价格情况煤矿数量":       "煤矿数量",
+	"价格情况上涨煤矿数量":     "上涨煤矿数量",
+	"价格情况平均上涨(元/吨)":  "煤矿平均上涨幅度",
+	"价格情况下跌煤矿数量":     "下跌煤矿数量",
+	"价格情况平均下跌(元/吨)":  "煤矿平均下跌幅度",
+	"价格情况持平煤矿数量":     "持平煤矿数量",
+	"原煤库存情况库存总量(万吨)": "原煤库存",
+	"精煤库存情况库存总量(万吨)": "精煤库存",
+	"开工情况权重平均开工率":    "煤矿加权开工率",
+	"开工情况算数平均开工率":    "煤矿算术平均开工率",
+	"开工情况停产煤矿数量":     "停产煤矿数量",
+	"开工情况本周原煤产量(万吨)": "本周原煤产量",
+	"销售良好":     "销售好煤矿数量",
+	"销售正常":     "销售一般煤矿数量",
+	"销售不好":     "销售不好煤矿数量",
+	"成本盈利煤矿数量": "盈利煤矿数量",
+	"成本平均利润":   "煤矿平均利润",
+	"成本亏损煤矿数量": "亏损煤矿数量",
+	"成本平均亏损":   "煤矿平均亏损",
+}
+
+// FenweiNewJm53IgnoreIndexNameMapping 焦煤53家-需要忽略的指标名称
+var FenweiNewJm53IgnoreIndexNameMapping = []string{
+	"原煤库存情况环比(万吨)", "精煤库存情况环比(万吨)", "开工情况开工率变化", "开工情况停产煤矿数量变化", "开工情况环比产量变化",
+}
+
+// FenweiNewJm88DiffIndexNameReplaceMapping 焦煤88家-指标名称不同的进行替换
+var FenweiNewJm88DiffIndexNameReplaceMapping = map[string]string{
+	"价格情况煤企数量":       "煤企数量",
+	"价格情况上涨煤企数量":     "上涨煤企数量",
+	"价格情况平均上涨(元/吨)":  "煤企平均上涨幅度",
+	"价格情况下跌煤矿数量":     "下跌煤企数量",
+	"价格情况平均下跌(元/吨)":  "煤企平均下跌幅度",
+	"价格情况持平煤企数量":     "持平煤企数量",
+	"原煤库存情况库存总量(万吨)": "原煤库存",
+	"原煤库存情况环比(万吨)":   "原煤库存环比",
+	"精煤库存情况库存总量(万吨)": "精煤库存",
+	"精煤库存情况环比(万吨)":   "精煤库存环比",
+	"开工情况产能利用率":      "煤企产能利用率",
+	"开工情况产能利用率变化":    "煤企产能利用率环比",
+	"开工情况开工率":        "煤企开工率",
+	"开工情况开工率变化":      "煤企开工率环比",
+	"开工情况停产煤矿数量":     "停产煤矿数量",
+	"开工情况停产煤矿数量变化":   "停产煤矿数量变化",
+	"开工情况本周原煤产量(万吨)": "本周原煤产量",
+	"开工情况环比产量变化":     "本周原煤产量变化",
+	"本周精煤产量(万吨)":     "本周精煤产量",
+	"环比产量变化":         "本周精煤产量变化",
+	"良好":             "销售好煤企数量",
+	"正常":             "销售一般煤企数量",
+	"不好":             "销售不好煤企数量",
+	"盈利煤企数量":         "盈利煤企数量",
+	"商品煤平均利润":        "煤企平均利润",
+	"亏损煤企数量":         "亏损煤企数量",
+	"商品煤平均亏损":        "煤企平均亏损",
+}
+
+// FenweiNewJm88IgnoreIndexNameMapping 焦煤88家-需要忽略的指标名称
+var FenweiNewJm88IgnoreIndexNameMapping = make([]string, 0)
+
+var FenweiNewDiffIndexNameReplaceMapping = map[string]map[string]string{
+	FenweiExcelNameA: FenweiNewDlm66DiffIndexNameReplaceMapping,
+	FenweiExcelNameB: FenweiNewDlm100DiffIndexNameReplaceMapping,
+	FenweiExcelNameC: FenweiNewJm53DiffIndexNameReplaceMapping,
+	FenweiExcelNameD: FenweiNewJm88DiffIndexNameReplaceMapping,
+}
+
+var FenweiNewIgnoreIndexNameMapping = map[string][]string{
+	FenweiExcelNameA: FenweiNewDlm66IgnoreIndexNameMapping,
+	FenweiExcelNameB: FenweiNewDlm100IgnoreIndexNameMapping,
+	FenweiExcelNameC: FenweiNewJm53IgnoreIndexNameMapping,
+	FenweiExcelNameD: FenweiNewJm88IgnoreIndexNameMapping,
+}
+
+var FenweiNewIndexNameSuffixMapping = map[string]string{
+	FenweiExcelNameA: "/动力煤/66家样本",
+	FenweiExcelNameB: "/动力煤/100家样本",
+	FenweiExcelNameC: "/焦煤/53家样本",
+	FenweiExcelNameD: "/焦煤/88家样本",
+}
+
+var FenweiNewExcelProvinceMapping = map[string]string{
+	"内蒙古":    "内蒙古",
+	"山西":     "山西",
+	"陕西":     "陕西",
+	"三省合计":   "三省合计",
+	"山西-临汾市": "临汾",
+	"山西-吕梁市": "吕梁",
+	"山西-长治市": "长治",
+	"山西-其他":  "山西其他",
+	"山东":     "山东",
+	"其他":     "其他",
+	"合计":     "合计",
+	"河北":     "河北",
+}
+
+// AnalysisFenweiHistoryExcel 解析汾渭历史Excel数据
+func AnalysisFenweiHistoryExcel(filePath string) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Printf("AnalysisFenweiExcel ErrMsg: %s\n", err.Error())
+			utils.FileLog.Info(fmt.Sprintf("AnalysisFenweiExcel ErrMsg: %s", err.Error()))
+		}
+	}()
+
+	fileName := path.Base(filePath)
+	var indexes []*models.FenweiExcelIndex
+	var e error
+	if strings.Contains(fileName, FenweiExcelNameA) {
+		indexes, e = AnalysisFenweiHistoryExcelNormal(filePath, FenweiExcelNameA)
+	} else if strings.Contains(fileName, FenweiExcelNameB) {
+		indexes, e = AnalysisFenweiHistoryExcelNormal(filePath, FenweiExcelNameB)
+	} else if strings.Contains(fileName, FenweiExcelNameC) {
+		indexes, e = AnalysisFenweiHistoryExcelNormal(filePath, FenweiExcelNameC)
+	} else if strings.Contains(fileName, FenweiExcelNameD) {
+		indexes, e = AnalysisFenweiHistoryExcelNormal(filePath, FenweiExcelNameD)
+	} else if strings.Contains(fileName, FenweiExcelNameE) {
+		indexes, e = AnalysisFenweiExcelYangBen(filePath)
+	} else {
+		utils.FileLog.Info(fmt.Sprintf("文件名有误, FileName: %s", fileName))
+		return
+	}
+	if e != nil {
+		utils.FileLog.Info(fmt.Sprintf("获取excel数据失败, FileName: %s, Err: %s", fileName, e))
+		return
+	}
+	if len(indexes) == 0 {
+		utils.FileLog.Info(fmt.Sprintf("fileName: %s, index empty", fileName))
+		return
+	}
+
+	// 写入数据
+	params := make(map[string]interface{})
+	params["List"] = indexes
+	params["TerminalCode"] = utils.TerminalCode
+	result, e := PostEdbLib(params, utils.LIB_ROUTE_FENWEI_HANDLE)
+	if e != nil {
+		b, _ := json.Marshal(params)
+		utils.FileLog.Info(fmt.Sprintf("fileName: %s, PostEdbLib err: %s, params: %s", fileName, e.Error(), string(b)))
+		return
+	}
+	resp := new(models.BaseEdbLibResponse)
+	if e := json.Unmarshal(result, &resp); e != nil {
+		utils.FileLog.Info(fmt.Sprintf("fileName: %s, json.Unmarshal err: %s", fileName, e.Error()))
+		return
+	}
+	if resp.Ret != 200 {
+		utils.FileLog.Info(fmt.Sprintf("fileName: %s, Msg: %s, ErrMsg: %s", fileName, resp.Msg, resp.ErrMsg))
+		return
+	}
+	return
+}
+
+// AnalysisFenweiHistoryExcelNormal 历史数据-动力煤产销存/焦煤产销存
+func AnalysisFenweiHistoryExcelNormal(filePath, excelName string) (indexes []*models.FenweiExcelIndex, err error) {
+	defer func() {
+		if err != nil {
+			fmt.Printf("AnalysisFenweiHistoryExcelNormal ErrMsg: %s\n", err.Error())
+			utils.FileLog.Info(fmt.Sprintf("AnalysisFenweiHistoryExcelNormal ErrMsg: %s", err.Error()))
+		}
+	}()
+
+	f, e := excelize.OpenFile(filePath)
+	if e != nil {
+		err = fmt.Errorf("open file err: %s", e.Error())
+		return
+	}
+	defer func() {
+		if e = f.Close(); e != nil {
+			err = fmt.Errorf("f close err: %s", e.Error())
+		}
+	}()
+	sheetName := f.GetSheetName(0)
+	rows, e := f.GetRows(sheetName)
+	if e != nil {
+		err = fmt.Errorf("f GetRows err: %s", e.Error())
+		return
+	}
+
+	// 获取指标分类
+	firstId := FenweiFirstClassifyMap[excelName]
+	if firstId <= 0 {
+		err = fmt.Errorf("excel名称有误, 分类不匹配, excelName: %s", excelName)
+		return
+	}
+	classifies, e := GetFenweiClassify()
+	if e != nil {
+		err = fmt.Errorf("获取指标分类失败, Err: %s", e.Error())
+		return
+	}
+	secondClassifyMap := make(map[string]int)
+	for _, v := range classifies {
+		if v.ClassifyId != firstId {
+			continue
+		}
+		for _, c := range v.Child {
+			secondClassifyMap[c.ClassifyName] = c.ClassifyId
+		}
+	}
+
+	indexes = make([]*models.FenweiExcelIndex, 0)
+	indexColIndex := make(map[int]*models.FenweiExcelIndex) // 列对应的指标(B列-?列)
+	maxCol := 0
+	sortArr := make([]string, 0) // 排序用的
+	for i, row := range rows {
+		// 首行为标题, 忽略
+		if i == 0 {
+			continue
+		}
+
+		// 第二行-指标名称
+		if i == 1 {
+			for k, cell := range row {
+				if k == 0 {
+					maxCol += 1
+					continue
+				}
+				name := strings.TrimSpace(cell)
+				name = strings.ReplaceAll(name, " ", "")
+				if name == "" {
+					break
+				}
+				maxCol += 1
+				if indexColIndex[k] == nil {
+					indexColIndex[k] = new(models.FenweiExcelIndex)
+					indexColIndex[k].ExcelDataMap = make(map[string]string)
+					indexColIndex[k].TerminalCode = utils.TerminalCode
+					indexColIndex[k].IndexName = name
+				}
+			}
+			continue
+		}
+
+		// 第三行-指标ID、指标分类
+		if i == 2 {
+			for k := 0; k < maxCol; k++ {
+				if k == 0 {
+					continue
+				}
+				if indexColIndex[k] == nil {
+					utils.FileLog.Info(fmt.Sprintf("第%d列无指标ID", k))
+					break
+				}
+				// 例:内蒙古煤矿数量/动力煤/66家样本->fwsjneimenggumksldlm66jyb
+				name := strings.ReplaceAll(indexColIndex[k].IndexName, "/", "")
+				var middle, suffix, province string
+				for _, p := range FenweiProvinces {
+					// 此处山西其他可能会被错误的给鉴别为山西, 所以优先鉴别一下山西其他
+					if strings.Contains(name, "山西其他") {
+						province = "山西其他"
+						middle = utils.GetFullPingYin("山西其他")
+						name = strings.ReplaceAll(name, p, "")
+						break
+					}
+					if strings.Contains(name, p) {
+						province = p
+						middle = utils.GetFullPingYin(p)
+						name = strings.ReplaceAll(name, p, "")
+						break
+					}
+				}
+				if middle == "" {
+					utils.FileLog.Info(fmt.Sprintf("指标名称转换编码有误, IndexName: %s", indexColIndex[k].IndexName))
+					continue
+				}
+				classifyProvince := FenweiProvinceClassifyMapping[province]
+				classifyId := secondClassifyMap[classifyProvince]
+				if classifyId <= 0 {
+					utils.FileLog.Info(fmt.Sprintf("指标名称分类不匹配, IndexName: %s", indexColIndex[k].IndexName))
+					continue
+				}
+
+				suffix = utils.GetFirstPingYin(name)
+				indexColIndex[k].IndexCode = fmt.Sprint(FenweiIndexNamePrefix, middle, suffix)
+				indexColIndex[k].ClassifyId = classifyId
+				sortArr = append(sortArr, indexColIndex[k].IndexCode)
+			}
+			continue
+		}
+
+		// 第四行-频度
+		if i == 3 {
+			for k, cell := range row {
+				if k == 0 {
+					continue
+				}
+				if indexColIndex[k] == nil {
+					utils.FileLog.Info(fmt.Sprintf("第%d列无指标名称", k))
+					break
+				}
+				frequency := strings.TrimSpace(cell)
+				indexColIndex[k].Frequency = frequency
+			}
+			continue
+		}
+
+		// 第五行-单位
+		if i == 4 {
+			for k, cell := range row {
+				if k == 0 {
+					continue
+				}
+				if indexColIndex[k] == nil {
+					utils.FileLog.Info(fmt.Sprintf("第%d列无指标单位", k))
+					break
+				}
+				unit := strings.TrimSpace(cell)
+				indexColIndex[k].Unit = unit
+			}
+			continue
+		}
+
+		// 数据行
+		if i > 4 {
+			var date string
+			for k, cell := range row {
+				if k == 0 {
+					// 日期
+					date = strings.TrimSpace(cell)
+					_, e := time.Parse(utils.FormatDate, date)
+					if e != nil {
+						// 如果第一列不是日期那么结束本行的读取
+						break
+					}
+					continue
+				}
+				// 日期数据
+				if date == "" {
+					utils.FileLog.Info(fmt.Sprintf("第%d行无数据日期", i))
+					break
+				}
+				if indexColIndex[k] == nil {
+					utils.FileLog.Info(fmt.Sprintf("第%d列无指标名称", k))
+					break
+				}
+				val := strings.TrimSpace(cell)
+				if val == "" {
+					// 单元格数据为空, 则当前日期无数据
+					continue
+				}
+				indexColIndex[k].ExcelDataMap[date] = val
+			}
+			continue
+		}
+	}
+
+	codeIndexes := make(map[string]*models.FenweiExcelIndex)
+	for _, v := range indexColIndex {
+		if v.IndexCode == "" {
+			continue
+		}
+		codeIndexes[v.IndexCode] = v
+	}
+	for _, v := range sortArr {
+		if codeIndexes[v] != nil {
+			indexes = append(indexes, codeIndexes[v])
+		}
+	}
+	return
+}
+
+// AnalysisFenweiExcelYangBen 样本焦化厂
+func AnalysisFenweiExcelYangBen(filePath string) (indexes []*models.FenweiExcelIndex, err error) {
+	defer func() {
+		if err != nil {
+			fmt.Printf("AnalysisFenweiExcelYangBen ErrMsg: %s\n", err.Error())
+			utils.FileLog.Info(fmt.Sprintf("AnalysisFenweiExcelYangBen ErrMsg: %s", err.Error()))
+		}
+	}()
+
+	indexColIndex := make(map[int]*models.FenweiExcelIndex) // 列对应的指标(B列-E列)
+	provinces := []string{"地区", "全国", "山西", "河北", "山东"}
+	for k, v := range provinces {
+		if k == 0 {
+			continue
+		}
+		if indexColIndex[k] == nil {
+			indexColIndex[k] = new(models.FenweiExcelIndex)
+			indexColIndex[k].ExcelDataMap = make(map[string]string)
+			indexColIndex[k].TerminalCode = utils.TerminalCode
+			indexColIndex[k].ClassifyId = FenweiYangBenIndexClassifyId
+			indexColIndex[k].Frequency = "周度"
+			indexColIndex[k].Unit = "天"
+			indexColIndex[k].IndexName = fmt.Sprintf("%s/%s", FenweiYangBenIndexNamePre, v)
+
+			// 指标编码, 例:样本焦企炼焦煤库存可用天数/全国->fwsjybjqljmkckytsquanguo
+			name := strings.ReplaceAll(indexColIndex[k].IndexName, "/", "")
+			var middle, suffix string
+			for _, p := range provinces {
+				if strings.Contains(name, p) {
+					suffix = utils.GetFullPingYin(p)
+					name = strings.ReplaceAll(name, p, "")
+					break
+				}
+			}
+			if suffix == "" {
+				utils.FileLog.Info(fmt.Sprintf("指标名称转换编码有误, IndexName: %s", indexColIndex[k].IndexName))
+				continue
+			}
+			middle = utils.GetFirstPingYin(name)
+			indexColIndex[k].IndexCode = fmt.Sprint(FenweiIndexNamePrefix, middle, suffix)
+		}
+	}
+
+	maxCols := 5      // 每行只读取前5列即可
+	startDateRow := 0 // 数据日期起始行(第一行), 后面依次加4行读取
+	startDataRow := 2 // 数据值起始行(第三行), 后面依次加4行读取
+	sumDateRow := 0   // 数据日期累加的行, 每加4次重置0
+	sumDataRow := 0   // 数据值累加的行, 每加4次重置0
+	currDate := ""    // 最近的一次日期
+	stop := false     // 结束读取excel
+
+	xlsFile, e := xls.OpenFile(filePath)
+	if e != nil {
+		err = fmt.Errorf("open xls file err: %s", e.Error())
+		return
+	}
+	sheet, e := xlsFile.GetSheet(0)
+	if e != nil {
+		err = fmt.Errorf("GetSheet err: %s", e.Error())
+		return
+	}
+	rows := sheet.GetRows()
+	for i, row := range rows {
+		sumDateRow += 1
+		sumDataRow += 1
+
+		// 第一个日期行/后续每4行取一次日期
+		if i == startDateRow || sumDateRow == 4 {
+			if stop {
+				break
+			}
+			sumDateRow = 0
+
+			for k, cell := range row.GetCols() {
+				// 日期只取第一个单元格中的
+				if k > 0 {
+					break
+				}
+				strDates := strings.TrimSpace(cell.GetString())
+				strDates = strings.ReplaceAll(strDates, "样本焦企炼焦煤库存", "")
+				strDates = strings.ReplaceAll(strDates, "\x00", "")
+				strDates = strings.ReplaceAll(strDates, "本焦企炼焦煤库存", "")
+				strDateArr := strings.Split(strDates, "-")
+				// 正常情况下, 长度不为2说明读取到了最后一行了
+				if len(strDateArr) != 2 {
+					utils.FileLog.Info(fmt.Sprintf("第%d行数据日期长度有误, 结束读取", i+1))
+					stop = true
+					break
+				}
+				t, e := time.Parse("2006.1.2", strDateArr[1])
+				if e != nil {
+					utils.FileLog.Info(fmt.Sprintf("第%d行数据日期有误, err: %s", i+1, e.Error()))
+					break
+				}
+				currDate = t.Format(utils.FormatDate)
+			}
+		}
+
+		// 第一个数据行/后续每4行取一次数据
+		if i == startDataRow || sumDataRow == 4 {
+			if currDate == "" {
+				utils.FileLog.Info(fmt.Sprintf("第%d行数据对应日期有误", i+1))
+				continue
+			}
+			sumDataRow = 0
+
+			for k, cell := range row.GetCols() {
+				if k >= maxCols {
+					break
+				}
+				if k == 0 {
+					continue
+				}
+				val := cell.GetFloat64()
+				// 保留4位小数
+				indexColIndex[k].ExcelDataMap[currDate] = fmt.Sprintf("%.4f", val)
+			}
+			// 重置日期
+			currDate = ""
+		}
+	}
+
+	indexes = make([]*models.FenweiExcelIndex, 0)
+	for _, v := range indexColIndex {
+		if v.IndexCode == "" {
+			continue
+		}
+		indexes = append(indexes, v)
+	}
+	return
+}
+
+// GetFenweiClassify 获取汾渭数据分类
+func GetFenweiClassify() (classifies []models.BaseFromFenweiClassifyItem, err error) {
+	params := make(map[string]interface{})
+	result, e := PostEdbLib(params, utils.LIB_ROUTE_FENWEI_CLASSIFY)
+	if e != nil {
+		b, _ := json.Marshal(params)
+		err = fmt.Errorf("GetFenweiClassify, PostEdbLib err: %s, params: %s", e.Error(), string(b))
+		return
+	}
+	resp := new(models.EdbLibFenweiClassifyResponse)
+	if e = json.Unmarshal(result, &resp); e != nil {
+		err = fmt.Errorf(fmt.Sprintf("GetFenweiClassify, json.Unmarshal err: %s", e.Error()))
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf(fmt.Sprintf("GetFenweiClassify, Msg: %s, ErrMsg: %s", resp.Msg, resp.ErrMsg))
+		return
+	}
+	classifies = resp.Data
+	return
+}
+
+// GetFenweiIndexList 获取汾渭指标列表
+func GetFenweiIndexList() (list []models.BaseFromFenweiIndex, err error) {
+	params := make(map[string]interface{})
+	result, e := PostEdbLib(params, utils.LIB_ROUTE_FENWEI_INDEX_LIST)
+	if e != nil {
+		b, _ := json.Marshal(params)
+		err = fmt.Errorf("GetFenweiIndexList, PostEdbLib err: %s, params: %s", e.Error(), string(b))
+		return
+	}
+	resp := new(models.EdbLibFenweiIndexListResponse)
+	if e = json.Unmarshal(result, &resp); e != nil {
+		err = fmt.Errorf(fmt.Sprintf("GetFenweiIndexList, json.Unmarshal err: %s", e.Error()))
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf(fmt.Sprintf("GetFenweiIndexList, Msg: %s, ErrMsg: %s", resp.Msg, resp.ErrMsg))
+		return
+	}
+	list = resp.Data
+	return
+}
+
+// AnalysisFenweiNewExcel 解析汾渭增量Excel数据
+func AnalysisFenweiNewExcel(filePath string) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Printf("AnalysisFenweiNewExcel ErrMsg: %s\n", err.Error())
+			utils.FileLog.Info(fmt.Sprintf("AnalysisFenweiNewExcel ErrMsg: %s", err.Error()))
+		}
+	}()
+
+	fileName := path.Base(filePath)
+	var indexes []*models.FenweiExcelIndex
+	var e error
+	if strings.Contains(fileName, FenweiExcelNameA) {
+		indexes, e = AnalysisFenweiNewExcelNormal(filePath, FenweiExcelNameA)
+	} else if strings.Contains(fileName, FenweiExcelNameB) {
+		indexes, e = AnalysisFenweiNewExcelNormal(filePath, FenweiExcelNameB)
+	} else if strings.Contains(fileName, FenweiNewExcelNameC) {
+		indexes, e = AnalysisFenweiNewExcelNormal(filePath, FenweiExcelNameC)
+	} else if strings.Contains(fileName, FenweiNewExcelNameD) {
+		indexes, e = AnalysisFenweiNewExcelNormal(filePath, FenweiExcelNameD)
+	} else if strings.Contains(fileName, FenweiExcelNameE) {
+		indexes, e = AnalysisFenweiExcelYangBen(filePath) // 样本焦化厂-增量数据和历史数据excel格式相同
+	} else {
+		utils.FileLog.Info(fmt.Sprintf("文件名有误, FileName: %s", fileName))
+		return
+	}
+	if e != nil {
+		utils.FileLog.Info(fmt.Sprintf("获取excel数据失败, FileName: %s, Err: %s", fileName, e))
+		return
+	}
+	if len(indexes) == 0 {
+		utils.FileLog.Info(fmt.Sprintf("fileName: %s, index empty", fileName))
+		return
+	}
+
+	// 写入数据
+	params := make(map[string]interface{})
+	params["List"] = indexes
+	params["TerminalCode"] = utils.TerminalCode
+	result, e := PostEdbLib(params, utils.LIB_ROUTE_FENWEI_HANDLE)
+	if e != nil {
+		b, _ := json.Marshal(params)
+		utils.FileLog.Info(fmt.Sprintf("fileName: %s, PostEdbLib err: %s, params: %s", fileName, e.Error(), string(b)))
+		return
+	}
+	resp := new(models.BaseEdbLibResponse)
+	if e := json.Unmarshal(result, &resp); e != nil {
+		utils.FileLog.Info(fmt.Sprintf("fileName: %s, json.Unmarshal err: %s", fileName, e.Error()))
+		return
+	}
+	if resp.Ret != 200 {
+		utils.FileLog.Info(fmt.Sprintf("fileName: %s, Msg: %s, ErrMsg: %s", fileName, resp.Msg, resp.ErrMsg))
+		return
+	}
+	return
+}
+
+// AnalysisFenweiNewExcelNormal 增量数据-动力煤/焦煤
+func AnalysisFenweiNewExcelNormal(filePath, excelName string) (indexes []*models.FenweiExcelIndex, err error) {
+	defer func() {
+		if err != nil {
+			fmt.Printf("AnalysisFenweiNewExcelNormal ErrMsg: %s\n", err.Error())
+			utils.FileLog.Info(fmt.Sprintf("AnalysisFenweiNewExcelNormal ErrMsg: %s", err.Error()))
+		}
+	}()
+
+	xlsFile, e := xlsx.OpenFile(filePath)
+	if e != nil {
+		err = fmt.Errorf("OpenFile Err: %s", e.Error())
+		return
+	}
+
+	// 获取存量指标, 增量数据只新增存量指标的数据
+	originIndexes, e := GetFenweiIndexList()
+	if e != nil {
+		err = fmt.Errorf("GetFenweiIndexList err: %s", e.Error())
+		return
+	}
+	indexMapping := make(map[string]models.BaseFromFenweiIndex)
+	for _, v := range originIndexes {
+		indexMapping[v.IndexCode] = v
+	}
+
+	diffNameReplace := FenweiNewDiffIndexNameReplaceMapping[excelName]
+	ignoreIndexName := FenweiNewIgnoreIndexNameMapping[excelName]
+	indexNameSuffix := FenweiNewIndexNameSuffixMapping[excelName]
+	var dataRowMin, dataRowMax int // 数据起始行数
+	if excelName == FenweiExcelNameA || excelName == FenweiExcelNameB {
+		dataRowMin = 3
+		dataRowMax = 6
+	}
+	if excelName == FenweiExcelNameC {
+		dataRowMin = 3
+		dataRowMax = 10
+	}
+	if excelName == FenweiExcelNameD {
+		dataRowMin = 3
+		dataRowMax = 13
+	}
+
+	var dataDate string
+	secondRowNames := make(map[int]string) // 第二行-指标名称的上半部分
+	thirdRowNames := make(map[int]string)  // 第三行-指标名称的另一部分
+	indexes = make([]*models.FenweiExcelIndex, 0)
+	indexColIndex := make(map[string]*models.FenweiExcelIndex) // 行-列对应的指标
+	rowProvince := make(map[int]string)                        // 行对应的省份名
+	for _, sheet := range xlsFile.Sheet {
+		maxRow := sheet.MaxRow
+		for i := 0; i < maxRow; i++ {
+			cells := sheet.Row(i).Cells
+
+			// 首行为数据日期
+			if i == 0 {
+				for _, cell := range cells {
+					str := strings.TrimSpace(cell.String())
+					if str == "" {
+						continue
+					}
+					dateArr := strings.Split(str, "-")
+					if len(dateArr) != 2 {
+						err = fmt.Errorf("数据日期有误, len(dateArr): %d", len(dateArr))
+						return
+					}
+					t, e := time.ParseInLocation("2006.1.2", dateArr[1], time.Local)
+					if e != nil {
+						t, e = time.ParseInLocation("2006.01.02", dateArr[1], time.Local)
+						if e != nil {
+							err = fmt.Errorf("数据日期有误, date: %s", dateArr[1])
+							return
+						}
+					}
+					dataDate = t.Format(utils.FormatDate)
+					break
+				}
+			}
+
+			// 第二行-指标名称上半部分
+			if i == 1 {
+				for k, cell := range cells {
+					text := strings.TrimSpace(cell.String())
+					if k > 0 && text != "" {
+						// 纵向合并
+						if cell.VMerge > 0 {
+							thirdRowNames[k] = text
+							continue
+						}
+						secondRowNames[k] = text
+						// 横向合并
+						if cell.HMerge > 0 {
+							for j := 1; j <= cell.HMerge; j++ {
+								if secondRowNames[k+j] != "" {
+									continue
+								}
+								secondRowNames[k+j] = text
+							}
+						}
+					}
+				}
+			}
+
+			// 第三行-指标名称下半部分, 指标名称, 指标编码在这一步生成
+			if i == 2 {
+				for k, cell := range cells {
+					text := strings.TrimSpace(cell.String())
+					if k > 0 && text != "" {
+						thirdRowNames[k] = text
+					}
+				}
+			}
+
+			// 数据行
+			if i >= dataRowMin && i <= dataRowMax {
+				for k, cell := range cells {
+					text := strings.TrimSpace(cell.String())
+					if text == "" {
+						continue
+					}
+					// 第一个单元格为地区
+					if k == 0 {
+						if text == "合计" && (excelName == FenweiExcelNameA || excelName == FenweiExcelNameB) {
+							text = "三省合计"
+						}
+						rowProvince[i] = FenweiNewExcelProvinceMapping[text]
+						continue
+					}
+					rowsName := strings.TrimSpace(fmt.Sprint(secondRowNames[k], thirdRowNames[k]))
+					rowsName = strings.ReplaceAll(rowsName, "\n", "")
+					namePrefix := diffNameReplace[rowsName]
+					if namePrefix == "" {
+						namePrefix = rowsName
+					}
+					// 忽略部分名称
+					if utils.InArrayByStr(ignoreIndexName, namePrefix) {
+						continue
+					}
+					indexName := fmt.Sprintf("%s%s%s", rowProvince[i], namePrefix, indexNameSuffix)
+					//fmt.Printf("k: %d, %s\n", k, indexName)
+					name := strings.ReplaceAll(indexName, "/", "")
+					var middle, suffix string
+					for _, p := range FenweiProvinces {
+						// 此处山西其他可能会被错误的给鉴别为山西, 所以优先鉴别一下山西其他
+						if strings.Contains(name, "山西其他") {
+							middle = utils.GetFullPingYin("山西其他")
+							name = strings.ReplaceAll(name, p, "")
+							break
+						}
+						if strings.Contains(name, p) {
+							middle = utils.GetFullPingYin(p)
+							name = strings.ReplaceAll(name, p, "")
+							break
+						}
+					}
+					if middle == "" {
+						utils.FileLog.Info(fmt.Sprintf("指标名称转换编码有误, IndexName: %s", indexName))
+						continue
+					}
+					suffix = utils.GetFirstPingYin(name)
+					indexCode := fmt.Sprint(FenweiIndexNamePrefix, middle, suffix)
+
+					// 根据转换的编码, 匹配存量指标, 无则忽略
+					originIndex := indexMapping[indexCode]
+					if originIndex.FenweiIndexId <= 0 {
+						utils.FileLog.Info(fmt.Sprintf("无对应存量指标, IndexName: %s, IndexCode: %s", indexName, indexCode))
+						continue
+					}
+					indexKey := fmt.Sprintf("%d-%d", i, k)
+					if indexColIndex[indexKey] == nil {
+						indexColIndex[indexKey] = new(models.FenweiExcelIndex)
+						indexColIndex[indexKey].TerminalCode = utils.TerminalCode
+						indexColIndex[indexKey].ClassifyId = originIndex.ClassifyId
+						indexColIndex[indexKey].Frequency = originIndex.Frequency
+						indexColIndex[indexKey].Unit = originIndex.Unit
+						indexColIndex[indexKey].IndexName = indexName
+						indexColIndex[indexKey].IndexCode = indexCode
+						indexColIndex[indexKey].ExcelDataMap = make(map[string]string)
+						indexColIndex[indexKey].ExcelDataMap[dataDate] = text
+					}
+				}
+			}
+		}
+
+		// 只读取第一个sheet
+		break
+	}
+
+	for _, v := range indexColIndex {
+		if v.IndexCode == "" {
+			continue
+		}
+		indexes = append(indexes, v)
+	}
+	return
+}

+ 67 - 0
services/fenwei_watch.go

@@ -0,0 +1,67 @@
+package services
+
+import (
+	"context"
+	"eta/eta_data_analysis/utils"
+	"fmt"
+	"io/fs"
+	"os"
+	"path/filepath"
+	"sync"
+)
+
+// HandleExcelFilePathMutex 创建一个互斥锁
+var HandleExcelFilePathMutex sync.Mutex
+
+func FenweiReadWatchIndexFile(context.Context) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("FenweiReadWatchIndexFile Err:" + err.Error())
+			utils.FileLog.Info(fmt.Sprintf("FenweiReadWatchIndexFile Err: %s", err.Error()))
+		}
+	}()
+	if utils.FenweiFileDir == "" {
+		utils.FileLog.Info("文件目录未配置")
+		return
+	}
+
+	// 上一个监听未结束时不执行
+	HandleExcelFilePathMutex.Lock()
+	defer HandleExcelFilePathMutex.Unlock()
+	//fmt.Println("FenweiFileDir: ", utils.FenweiFileDir)
+
+	err = filepath.Walk(utils.FenweiFileDir, func(path string, info fs.FileInfo, e error) error {
+		if e != nil {
+			err = fmt.Errorf("walk err: %s", e.Error())
+			return err
+		}
+		if info.IsDir() {
+			return nil
+		}
+		if path == "" {
+			return nil
+		}
+
+		//fmt.Println("path", path)
+		e = AnalysisFenweiNewExcel(path)
+		if e != nil {
+			err = fmt.Errorf("AnalysisFenweiNewExcel err: %s", e.Error())
+			return err
+		}
+
+		// 移动文件至已处理目录
+		e = utils.CreateDirIfNotExists(utils.FenweiOldFileDir)
+		if e != nil {
+			err = fmt.Errorf("CreateDirIfNotExists err: %s", e.Error())
+			return err
+		}
+		destPath := filepath.Join(utils.FenweiOldFileDir, info.Name())
+		e = os.Rename(path, destPath)
+		if e != nil {
+			err = fmt.Errorf("file move err: %s", e.Error())
+			return err
+		}
+		return nil
+	})
+	return
+}

+ 11 - 4
services/task.go

@@ -30,7 +30,6 @@ func Task() {
 
 		yongyiDownloadWeekly := task.NewTask("YongyiDownloadWeekly", "0 0 17,23 * * *", YongyiDownloadWeeyly)
 		task.AddTask("涌益咨询周度指标下载", yongyiDownloadWeekly)
-		task.StartTask()
 	}
 
 	if utils.CoalMineOpen == "1" {
@@ -44,10 +43,18 @@ func Task() {
 		c.Start()
 	}
 
+	// 汾渭数据
+	if utils.FenweiOpen == "1" {
+		// 每5分钟检测一次目录是否有新文件
+		fenWeiReadWatchIndexFile := task.NewTask("fenWeiReadWatchIndexFile", "0 */5 * * * *", FenweiReadWatchIndexFile)
+		task.AddTask("汾渭数据指标文件检测", fenWeiReadWatchIndexFile)
+	}
+
+	task.StartTask()
+
 	fmt.Println("task end")
 }
 
-
 func ReadWatchIndexFile() {
 	fmt.Println("ReadWatchIndexFile start")
 	var err error
@@ -86,7 +93,7 @@ func ReadWatchIndexFile() {
 						err = JsmHistory(path)
 					} else if strings.Contains(path, "CⅢ-8-16 25省市库存和日耗情况") {
 						err = CoastalHistory(path)
-						time.Sleep(time.Second*10)
+						time.Sleep(time.Second * 10)
 						err = InlandHistory(path)
 					}
 				}
@@ -101,7 +108,7 @@ func ReadWatchIndexFile() {
 					err = JsmHistory(path)
 				} else if strings.Contains(path, "CⅢ-8-16 25省市库存和日耗情况") {
 					err = CoastalHistory(path)
-					time.Sleep(time.Second*10)
+					time.Sleep(time.Second * 10)
 					err = InlandHistory(path)
 				}
 			}

+ 21 - 0
utils/common.go

@@ -1237,3 +1237,24 @@ func SecondToTime(sec int64) time.Time {
 	return time.Unix(sec, 0)
 }
 
+// CreateDirIfNotExists 目录是否存在
+func CreateDirIfNotExists(directoryPath string) error {
+	// 检查目录是否存在
+	_, err := os.Stat(directoryPath)
+	if os.IsNotExist(err) {
+		// 目录不存在,创建目录
+		err := os.MkdirAll(directoryPath, 0755)
+		if err != nil {
+			return fmt.Errorf("failed to create directory: %v", err)
+		}
+		fmt.Printf("Directory '%s' created successfully.\n", directoryPath)
+	} else if err != nil {
+		// 发生其他错误
+		return fmt.Errorf("failed to check directory: %v", err)
+	} else {
+		// 目录已存在
+		//fmt.Printf("Directory '%s' already exists.\n", directoryPath)
+	}
+
+	return nil
+}

+ 16 - 0
utils/config.go

@@ -48,6 +48,13 @@ var (
 	CoalMineOpen     string //是否配置涌益生猪数据源,1已配置
 )
 
+// 汾渭煤炭
+var (
+	FenweiFileDir    string // excel文件目录
+	FenweiOldFileDir string // 已读取过的excel文件目录
+	FenweiOpen       string // 是否配置汾渭数据源
+)
+
 var TerminalCode string
 
 func init() {
@@ -92,11 +99,20 @@ func init() {
 		YongyiFilePath = config["yongyi_file_path"]
 		YongyiOpen = config["yongyi_open"]
 	}
+
 	//中国煤炭网文件夹配置
 	{
 		CoalMineFilePath = config["coal_mine_file_path"]
 		CoalMineOpen = config["coal_mine_open"]
 	}
+
+	// 汾渭配置
+	{
+		FenweiOpen = config["fenwei_open"]
+		FenweiFileDir = config["fenwei_file_dir"]
+		FenweiOldFileDir = config["fenwei_old_file_dir"]
+	}
+
 	TerminalCode = config["terminal_code"]
 }
 

+ 9 - 6
utils/constants.go

@@ -230,11 +230,14 @@ var FrequencyDaysMap = map[string]int{
 
 // edb_index_lib 的接口名称
 const (
-	LIB_ROUTE_YONGYI_HANDLE = "yongyi/handle/excel_data" //涌益咨询处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_JSM_HISTORY = "/coal_mine/jsm/history" //jsm三省煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_YONGYI_HANDLE             = "yongyi/handle/excel_data"   //涌益咨询处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_JSM_HISTORY     = "/coal_mine/jsm/history"     //jsm三省煤炭网历史数据处理excel数据并入库 数据地址
 	LIB_ROUTE_COAL_MINE_COASTAL_HISTORY = "/coal_mine/coastal/history" //沿海煤炭网历史数据处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_INLAND_HISTORY = "/coal_mine/inland/history" //内陆三省煤炭网历史数据处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_JSM = "/coal_mine/jsm" //jsm三省煤炭网历史数据处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_COASTAL = "/coal_mine/coastal" //沿海煤炭网历史数据处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_INLAND = "/coal_mine/inland" //内陆三省煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_INLAND_HISTORY  = "/coal_mine/inland/history"  //内陆三省煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_JSM             = "/coal_mine/jsm"             //jsm三省煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_COASTAL         = "/coal_mine/coastal"         //沿海煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_INLAND          = "/coal_mine/inland"          //内陆三省煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_FENWEI_HANDLE             = "fenwei/handle/excel_data"   // 汾渭煤炭excel数据入库接口地址
+	LIB_ROUTE_FENWEI_CLASSIFY           = "fenwei/classify_tree"       // 汾渭煤炭分类接口地址
+	LIB_ROUTE_FENWEI_INDEX_LIST         = "fenwei/base_index_list"     // 汾渭煤炭指标列表接口地址
 )