2 Komitmen d89ccb351d ... 947c0084bd

Pembuat SHA1 Pesan Tanggal
  xq 947c0084bd del wisemodel 1 tahun lalu
  xq b79e2e236b up 1 tahun lalu
14 mengubah file dengan 954 tambahan dan 1 penghapusan
  1. 39 1
      README.md
  2. 17 0
      conf.ini
  3. 39 0
      go.mod
  4. 101 0
      go.sum
  5. 339 0
      main.go
  6. TEMPAT SAMPAH
      static/Uploader.swf
  7. 4 0
      static/bootstrap.min.css
  8. 8 0
      static/fs.go
  9. 1 0
      static/jquery-3.1.1.min.js
  10. 191 0
      static/md5.js
  11. 187 0
      static/upload.html
  12. 28 0
      static/webuploader.css
  13. 0 0
      static/webuploader.html5only.min.js
  14. 0 0
      static/webuploader.min.js

+ 39 - 1
README.md

@@ -1,3 +1,41 @@
 # webuploader
 
-webuploader
+
+
+
+  - Help
+
+  ```sh
+NAME:
+   webuploader - 文件服务
+
+USAGE:
+   webuploader [global options] command [command options] [arguments...]
+
+COMMANDS:
+   help, h  Shows a list of commands or help for one command
+
+GLOBAL OPTIONS:
+   --port value, -p value  port (default: "8888")
+   --help, -h              show help
+
+  ```
+
+  
+
+- 最好保留6066端口 做为监控pprof
+- 编译
+
+```shell
+GOOS=linux GOARCH=amd64 go build -o webup-linux-amd64 -a -ldflags '-w -s -extldflags "-static"' main.go
+GOOS=linux GOARCH=arm64 go build -o webup-linux-arm64 -a -ldflags '-w -s -extldflags "-static"' main.go
+
+GOOS=darwin GOARCH=amd64 go build -o webup-darwin-amd64 -a -ldflags '-w -s -extldflags "-static"' main.go
+GOOS=darwin GOARCH=arm64 go build -o webup-darwin-arm64 -a -ldflags '-w -s -extldflags "-static"' main.go
+
+GOOS=windows GOARCH=arm64 go build -o webup-windows-arm64.exe -a -ldflags '-w -s -extldflags "-static"' main.go
+GOOS=windows GOARCH=amd64 go build -o webup-windows-amd64.exe -a -ldflags '-w -s -extldflags "-static"' main.go
+
+```
+
+

+ 17 - 0
conf.ini

@@ -0,0 +1,17 @@
+;区列表,与下面每小结名字对应
+ap = yun001,yun002
+
+;成功率阈值
+success_ratio = 0.9
+
+[yun001]
+endpoint = cwp.yun001.com
+region = ap-beijing
+secret_id = XXXXX
+secret_key = CCCCC
+
+[yun002]
+endpoint = cwp.yun002.com
+region = ap-beijing
+secret_id = XXXXXX
+secret_key = CCCCCCCC

+ 39 - 0
go.mod

@@ -0,0 +1,39 @@
+module webuploader
+
+go 1.20
+
+require (
+	github.com/gin-gonic/gin v1.9.0
+	github.com/quillaja/logrus-systemd-formatter/systemdfmt v0.0.5
+	github.com/sirupsen/logrus v1.9.0
+	github.com/urfave/cli/v2 v2.25.0
+)
+
+require (
+	github.com/bytedance/sonic v1.8.0 // indirect
+	github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
+	github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
+	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
+	github.com/go-playground/validator/v10 v10.11.2 // indirect
+	github.com/goccy/go-json v0.10.0 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/klauspost/cpuid/v2 v2.0.9 // indirect
+	github.com/leodido/go-urn v1.2.1 // indirect
+	github.com/mattn/go-isatty v0.0.17 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
+	github.com/russross/blackfriday/v2 v2.1.0 // indirect
+	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+	github.com/ugorji/go/codec v1.2.9 // indirect
+	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
+	golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
+	golang.org/x/crypto v0.5.0 // indirect
+	golang.org/x/net v0.7.0 // indirect
+	golang.org/x/sys v0.5.0 // indirect
+	golang.org/x/text v0.7.0 // indirect
+	google.golang.org/protobuf v1.28.1 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)

+ 101 - 0
go.sum

@@ -0,0 +1,101 @@
+github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
+github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA=
+github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
+github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
+github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
+github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
+github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
+github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
+github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
+github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
+github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
+github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
+github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
+github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/quillaja/logrus-systemd-formatter/systemdfmt v0.0.5 h1:nWWeTMbBFYFNLdXYmeyYmaNpcmfsHwvhDqMwxnKjd4U=
+github.com/quillaja/logrus-systemd-formatter/systemdfmt v0.0.5/go.mod h1:GGlXaOwns89Ec7Cqz16hEVEu1h3t0PCoxMt7E9g3Qr4=
+github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
+github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+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 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU=
+github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/urfave/cli/v2 v2.25.0 h1:ykdZKuQey2zq0yin/l7JOm9Mh+pg72ngYMeB0ABn6q8=
+github.com/urfave/cli/v2 v2.25.0/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
+github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
+github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
+golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+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=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

+ 339 - 0
main.go

@@ -0,0 +1,339 @@
+package main
+
+import (
+	"errors"
+	"io/ioutil"
+	"net"
+	"net/http"
+	_ "net/http/pprof"
+	"os"
+	"path/filepath"
+	"sort"
+	"strconv"
+	"strings"
+	"webuploader/static"
+
+	"github.com/gin-gonic/gin"
+	"github.com/quillaja/logrus-systemd-formatter/systemdfmt"
+	log "github.com/sirupsen/logrus"
+	"github.com/urfave/cli/v2"
+)
+
+var (
+	dir    string = getCurrentAbPathByExecutable() + string(filepath.Separator)
+	port   string
+	group1 *gin.RouterGroup
+)
+
+func init() {
+
+	gin.SetMode(gin.ReleaseMode)
+
+	log.SetFormatter(&systemdfmt.Formatter{})
+	log.SetOutput(os.Stdout)
+	//log.SetLevel(log.WarnLevel)
+
+	//pprof
+	go func() {
+		_ = http.ListenAndServe(":6066", nil)
+	}()
+
+}
+
+// 获取当前执行文件绝对路径
+func getCurrentAbPathByExecutable() string {
+	exePath, err := os.Executable()
+	if err != nil {
+		log.Fatal(err)
+	}
+	res, _ := filepath.EvalSymlinks(filepath.Dir(exePath))
+	return res
+}
+
+func getClientIp() (string, error) {
+	addrs, err := net.InterfaceAddrs()
+
+	if err != nil {
+		return "", err
+	}
+
+	for _, address := range addrs {
+		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
+			if ipnet.IP.To4() != nil {
+				return ipnet.IP.String(), nil
+			}
+		}
+	}
+	return "", errors.New("Can not find the client ip address!")
+}
+
+func walkDir(filestr string) ([]string, error) {
+	files, err := ioutil.ReadDir(filestr) // files为当前目录下的所有文件名称【包括文件夹】
+	if err != nil {
+		return nil, err
+	}
+
+	var allfile []string
+	for _, v := range files {
+		if v.Name() == ".DS_Store" {
+			continue
+		}
+		fullPath := filestr + string(filepath.Separator) + v.Name() // 全路径 + 文件名称
+		if v.IsDir() {                                              // 如果是目录
+			a, _ := walkDir(fullPath) // 遍历改路径下的所有文件
+			allfile = append(allfile, a...)
+		} else {
+			allfile = append(allfile, fullPath) // 如果不是文件夹,就直接追加到路径下
+		}
+	}
+
+	return allfile, nil
+}
+
+// 验证是否上传过该文件
+func check(c *gin.Context) {
+	fileMd5 := c.PostForm("md5File")
+	path := dir + "wisemodel" + string(filepath.Separator) + "merge" + string(filepath.Separator) + fileMd5
+	if _, err := os.Stat(path); os.IsNotExist(err) { //判断是否已经上传过该文件,设置返回code 为 -1 :秒传
+		log.Println("mkDir " + path)
+		_ = os.MkdirAll(path, os.ModePerm)
+		c.JSON(http.StatusOK, gin.H{
+			"resultCode": 0, //
+		})
+		return
+	}
+	result := 0
+	// 获取目录里上传文件数量
+	files, err := ioutil.ReadDir(path)
+	if err != nil {
+		log.Infof("Error ioutil.ReadDir %v", err)
+	} else if len(files) == 0 { //文件没有上传过,下标为零
+		result = 0
+	} else {
+		result = 1
+	}
+	c.JSON(http.StatusOK, gin.H{
+		"resultCode": result,
+	})
+}
+
+// 验证是否上传过该文件
+func checkChunk(c *gin.Context) {
+	fileMd5 := c.PostForm("md5File")
+	chunk := c.PostForm("chunk")
+	log.Println(fileMd5)
+	path := dir + "wisemodel" + string(filepath.Separator) + fileMd5 + string(filepath.Separator) + strings.Trim(chunk, "")
+	log.Println(path)
+	if _, err := os.Stat(path); err == nil { //判断是否已经上传过该文件,设置返回code 为 -1 :秒传
+		c.JSON(http.StatusOK, gin.H{
+			"resultCode": 1, //
+		})
+		return
+	} else {
+		c.JSON(http.StatusOK, gin.H{
+			"resultCode": 0,
+		})
+	}
+}
+
+// 上传文件分片
+func upload(c *gin.Context) {
+	fileName := c.PostForm("name")                      // 获取文件名
+	chunkIndex := strings.Trim(c.PostForm("chunk"), "") // 获取分片下标
+
+	fileMd5 := c.PostForm("md5File") //获取文件md5
+	dst := dir + "wisemodel" + string(filepath.Separator) + fileMd5
+	if chunkIndex == "" {
+		chunkIndex = "0"
+	}
+
+	result := 0
+	defer func(subResult *int) {
+		c.JSON(http.StatusOK, gin.H{
+			"resultCode": *subResult, //
+		})
+	}(&result)
+
+	if _, err := os.Stat(dst); os.IsNotExist(err) { //判断是否存在
+		_ = os.MkdirAll(dst, os.ModePerm)
+	}
+	if file, err := c.FormFile("file"); err == nil { //获取分片文件
+		if chunkIndex == "" {
+			err = c.SaveUploadedFile(file, dst+string(filepath.Separator)+fileName)
+		} else {
+			err = c.SaveUploadedFile(file, dst+string(filepath.Separator)+chunkIndex)
+		}
+		if err != nil {
+			result = 0
+			log.Errorf("Error c.SaveUploadedFile %v", err)
+		} else {
+			result = 1
+		}
+	} else {
+		result = 0
+		log.Errorf("Error c.FormFile %v", err)
+	}
+}
+
+// 合并分片
+func merge(c *gin.Context) {
+	fileName := c.PostForm("name")
+	fileMd5 := c.PostForm("md5File")
+	chunks := c.PostForm("chunks")
+	path := dir + "wisemodel" + string(filepath.Separator) + fileMd5 //分片存储位置
+
+	result := 0
+	defer func(subResult *int) {
+		c.JSON(http.StatusOK, gin.H{
+			"resultCode": *subResult, //
+		})
+	}(&result)
+
+	// 获取目录里上传文件分片数量
+	files, err := ioutil.ReadDir(path)
+	if err != nil || len(files) == 0 || chunks != strconv.Itoa(len(files)) {
+		log.Errorf("Error merge ioutil.ReadDir %v", err)
+		result = 0
+		return
+	}
+
+	//按名字排序
+	sort.SliceStable(files, func(i, j int) bool {
+		numA, _ := strconv.Atoi(files[i].Name())
+		numB, _ := strconv.Atoi(files[j].Name())
+		return numA < numB
+		//return files[i].Name() < files[j].Name()
+	})
+
+	realFilePath := dir + "wisemodel" + string(filepath.Separator) + "merge" + string(filepath.Separator) + fileMd5
+	_ = os.MkdirAll(realFilePath, os.ModePerm) //创建目录
+	// 创建一个需要合并的文件
+	realFile, err := os.OpenFile(realFilePath+string(filepath.Separator)+fileName, os.O_CREATE|os.O_TRUNC|os.O_RDWR, os.ModePerm)
+	defer realFile.Close()
+	if err != nil {
+		result = 0
+		log.Errorf("Error merge os.OpenFile %v", err)
+		return
+	}
+
+	for _, v := range files { //
+		f, err := os.OpenFile(path+string(filepath.Separator)+v.Name(), os.O_RDONLY, os.ModePerm)
+		if err != nil {
+			result = 0
+			log.Errorf("Error for os.OpenFile %v", err)
+			break
+		}
+		b, err := ioutil.ReadAll(f)
+		if err != nil {
+			result = 0
+			log.Errorf("Error for ioutil.ReadAll %v", err)
+			break
+		}
+		realFile.Write(b)
+		// 关闭分片
+		f.Close()
+		os.Remove(f.Name()) //合并后,删除分片
+		result = 1
+	}
+}
+
+// 文件list
+func getFiles(c *gin.Context) {
+	pathMerge := dir + "wisemodel" + string(filepath.Separator) + "merge" //上传文件存储位置
+	pathLocal := dir + "wisemodel" + string(filepath.Separator) + "local" //本地文件存储位置
+
+	if _, err := os.Stat(pathLocal); os.IsNotExist(err) {
+		_ = os.MkdirAll(pathLocal, os.ModePerm)
+	}
+
+	mergeFiles, err := walkDir(pathMerge)
+	if err != nil {
+		log.Errorf("Error walkDir(pathMerge) %v", err)
+	}
+
+	localFiles, err := walkDir(pathLocal)
+	if err != nil {
+		log.Errorf("Error walkDir(pathMerge) %v", err)
+	}
+
+	c.JSON(http.StatusOK, gin.H{
+		"mergeFiles": mergeFiles,
+		"localFiles": localFiles,
+	})
+
+}
+
+func doWork() {
+	ip, err := getClientIp()
+	if err != nil {
+		log.Errorf("Error getClientIp %v", err)
+		return
+	}
+	log.Infof("HTTP://" + ip + ":" + port)
+
+	r := gin.Default()
+	//加载静态文件
+	r.StaticFS("/static", http.FS(static.FS))
+
+	// 最大文件大小M
+	r.MaxMultipartMemory = 8 << 20
+
+	// 跳转上传页面
+	r.GET("/", func(c *gin.Context) {
+		c.Redirect(http.StatusMovedPermanently, "/static/upload.html")
+	})
+
+	//路由分组
+	group1 = r.Group("/bigfile")
+
+	group1.POST("/check", check)
+	group1.POST("/checkChunk", checkChunk)
+	group1.POST("/upload", upload)
+	group1.POST("/merge", merge)
+	group1.GET("/getFiles", getFiles)
+
+	group1.GET("/down", func(c *gin.Context) {
+		pathName := c.DefaultQuery("path", "")
+		fileName := filepath.Base(pathName)
+		if pathName != "" {
+			c.Header("Content-Type", "application/octet-stream")
+			c.Header("Content-Disposition", "attachment; filename="+fileName)
+			c.Header("Content-Disposition", "inline;filename="+fileName)
+			c.Header("Content-Transfer-Encoding", "binary")
+			c.Header("Cache-Control", "no-cache")
+
+			c.File(pathName)
+		}
+	})
+
+	_ = r.Run(":" + port)
+}
+
+func main() {
+
+	app := &cli.App{
+		Name:  "webuploader", //app名字
+		Usage: "文件服务",        //详细描述该app的用途
+
+		// 设置参数列表
+		Flags: []cli.Flag{
+			&cli.StringFlag{
+				Name:        "port",
+				Value:       "8888",
+				Aliases:     []string{"p"},
+				Usage:       "port",
+				Destination: &port,
+			},
+		},
+
+		Action: func(context *cli.Context) error {
+			doWork()
+			return nil
+		},
+	}
+
+	if err := app.Run(os.Args); err != nil {
+		log.Errorln("app run error: ", err.Error())
+		os.Exit(1)
+	}
+}

TEMPAT SAMPAH
static/Uploader.swf


File diff ditekan karena terlalu besar
+ 4 - 0
static/bootstrap.min.css


+ 8 - 0
static/fs.go

@@ -0,0 +1,8 @@
+package static
+
+import (
+	"embed"
+)
+
+//go:embed *.css *.js *.html *.swf
+var FS embed.FS

File diff ditekan karena terlalu besar
+ 1 - 0
static/jquery-3.1.1.min.js


+ 191 - 0
static/md5.js

@@ -0,0 +1,191 @@
+var hexcase = 0;  
+var b64pad  = ""; 
+var chrsz   = 8;  
+function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
+function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
+function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
+function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
+function calcMD5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
+
+function md5_vm_test()
+{
+  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
+}
+
+function core_md5(x, len)
+{
+
+  x[len >> 5] |= 0x80 << ((len) % 32);
+  x[(((len + 64) >>> 9) << 4) + 14] = len;
+  var a =  1732584193;
+  var b = -271733879;
+  var c = -1732584194;
+  var d =  271733878;
+  for(var i = 0; i < x.length; i += 16)
+  {
+    var olda = a;
+    var oldb = b;
+    var oldc = c;
+    var oldd = d;
+
+    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
+    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
+    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
+    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
+    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
+    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
+    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
+    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
+    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
+    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
+    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
+    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
+    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
+    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
+    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
+    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
+    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
+    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
+    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
+    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
+    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
+    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
+    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
+    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
+    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
+    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
+    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
+    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
+    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
+    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
+    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
+    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
+    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
+    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
+    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
+    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
+    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
+    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
+    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
+    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
+    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
+    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
+    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
+    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
+    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
+    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
+    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
+    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
+    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
+    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
+    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
+    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
+    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
+    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
+    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
+    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
+    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
+    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
+    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
+    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
+    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
+    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
+    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
+    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
+
+    a = safe_add(a, olda);
+    b = safe_add(b, oldb);
+    c = safe_add(c, oldc);
+    d = safe_add(d, oldd);
+  }
+  return Array(a, b, c, d);
+  
+}
+
+function md5_cmn(q, a, b, x, s, t)
+{
+  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
+}
+function md5_ff(a, b, c, d, x, s, t)
+{
+  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+function md5_gg(a, b, c, d, x, s, t)
+{
+  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+function md5_hh(a, b, c, d, x, s, t)
+{
+  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+}
+function md5_ii(a, b, c, d, x, s, t)
+{
+  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+function core_hmac_md5(key, data)
+{
+  var bkey = str2binl(key);
+  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
+
+  var ipad = Array(16), opad = Array(16);
+  for(var i = 0; i < 16; i++) 
+  {
+    ipad[i] = bkey[i] ^ 0x36363636;
+    opad[i] = bkey[i] ^ 0x5C5C5C5C;
+  }
+
+  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
+  return core_md5(opad.concat(hash), 512 + 128);
+}
+
+function safe_add(x, y)
+{
+  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+  return (msw << 16) | (lsw & 0xFFFF);
+}
+
+function bit_rol(num, cnt)
+{
+  return (num << cnt) | (num >>> (32 - cnt));
+}
+
+function str2binl(str)
+{
+  var bin = Array();
+  var mask = (1 << chrsz) - 1;
+  for(var i = 0; i < str.length * chrsz; i += chrsz)
+    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
+  return bin;
+}
+
+function binl2hex(binarray)
+{
+  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+  var str = "";
+  for(var i = 0; i < binarray.length * 4; i++)
+  {
+    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
+           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
+  }
+  return str;
+}
+
+function binl2b64(binarray)
+{
+  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  var str = "";
+  for(var i = 0; i < binarray.length * 4; i += 3)
+  {
+    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
+                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
+                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
+    for(var j = 0; j < 4; j++)
+    {
+      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
+      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
+    }
+  }
+  return str;
+}

+ 187 - 0
static/upload.html

@@ -0,0 +1,187 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<meta charset="UTF-8" />
+	<title>upload file</title>
+	<link type="text/css" href="./bootstrap.min.css" rel="stylesheet" />
+	<link type="text/css" href="./webuploader.css" rel="stylesheet" />
+</head>
+<body >
+
+	<div id="uploader" class="wu-example" >
+		<!--用来存放文件信息-->
+		<div id="thelist" class="uploader-list" style="width:500px;"></div>
+		<div class="btns">
+			<div id="picker">选择文件</div>
+		</div>
+	</div>
+	<div id="list">
+	</div>
+
+<script src="./jquery-3.1.1.min.js"></script>
+<script src="./md5.js"></script>
+<script src="./webuploader.html5only.min.js"></script>
+<script type="text/javascript">
+
+	var md5File; 
+	//监听分块上传过程中的时间点  
+	WebUploader.Uploader.register({  
+	    "before-send-file":"beforeSendFile",  // 整个文件上传前
+	    "before-send":"beforeSend",  // 每个分片上传前
+	    "after-send-file": "afterSendFile"  // 分片上传完毕
+	},{
+	    //时间点1:所有分块进行上传之前调用此函数 ,检查文件存不存在
+	    beforeSendFile:function(file){  
+	    	var deferred = WebUploader.Deferred();
+	    	md5File = hex_md5(file.name+file.size);//根据文件名称,大小确定文件唯一标记,这种方式不赞成使用
+	    	$.ajax({  
+	            type:"POST",  
+	            url:"/bigfile/check",
+	            data:{  
+	                md5File: md5File, //文件唯一标记   
+	            },  
+	            async: false,  // 同步
+	            dataType:"json",  
+	            success:function(response){  
+	                if(response.resultCode == 1){  //文件存在,跳过 ,提示文件存在
+						$('#' + file.id).find('p.state').text("file exist");
+						$("#picker").show();
+	                }else{  
+	                    deferred.resolve();  //文件不存在或不完整,发送该文件
+	                }
+	            }  
+	        } , function (jqXHR, textStatus, errorThrown) { //任何形式的验证失败,都触发重新上传
+	        	deferred.resolve();
+	        } );  
+	        return deferred.promise(); 
+	    },  
+	    //时间点2:如果有分块上传,则每个分块上传之前调用此函数  ,判断分块存不存在
+	    beforeSend:function(block){  
+	        var deferred = WebUploader.Deferred();  
+	        $.ajax({  
+	            type:"POST",  
+	            url:"/bigfile/checkChunk",
+	            data:{  
+	                md5File: md5File,  //文件唯一标记 
+	                chunk:block.chunk,  //当前分块下标  
+	            },  
+	            dataType:"json",  
+	            success:function(response){  
+	                if(response.resultCode == 1){
+	                    deferred.reject(); //分片存在,跳过 
+	                }else{  
+	                    deferred.resolve();  //分块不存在或不完整,重新发送该分块内容  
+	                }  
+	            }  
+	        }, function (jqXHR, textStatus, errorThrown) { //任何形式的验证失败,都触发重新上传
+	        	deferred.resolve();
+	        });  
+	        return deferred.promise();  
+	    },
+	    //时间点3:分片上传完成后,通知后台合成分片
+	    afterSendFile: function (file) {        
+	        var chunksTotal = Math.ceil(file.size / (5*1024*1024));
+	        if (chunksTotal >= 1) {
+	            //合并请求
+	            var deferred = WebUploader.Deferred();  
+	            $.ajax({
+	                type: "POST",
+	                url: "/bigfile/merge",
+	                data: {
+	                	name: file.name,
+	                	md5File: md5File,
+	                    chunks: chunksTotal
+	                },
+	                cache: false,
+	                async: false,  // 同步
+	                dataType: "json",  
+		            success:function(response){  
+		                if(response.resultCode == 1){
+		                	$('#' + file.id).find('p.state').text('upload success');
+		                	$('#' + file.id).find('.progress').fadeOut();
+		                }else{  
+		                	$('#' + file.id).find('p.state').text('merge error');
+			            	deferred.reject();
+		                }
+						$("#picker").show();
+						fileList();
+		            }  
+	            })
+	            return deferred.promise(); 
+	        }
+	    } 
+	}); 
+
+	var uploader = WebUploader.create({
+		auto: true,// 选完文件后,是否自动上传。
+	    swf: '../static/Uploader.swf',// swf文件路径
+	    server: '/bigfile/upload',// 文件接收服务端。
+	    pick: '#picker',// 选择文件的按钮。可选。
+	    chunked:true,//开启分片上传
+	    chunkSize:5*1024*1024,//5M
+	    chunkRetry: 3,//错误重试次数
+		prepareNextFile: true// 允许在文件传输时提前把下一个文件准备好
+	});
+	
+	//上传添加参数
+	uploader.on('uploadBeforeSend', function (obj, data, headers) {
+		 data.md5File=md5File;
+     }); 
+	
+	// 当有文件被添加进队列的时候
+	uploader.on( 'fileQueued', function( file ) {
+		$("#picker").hide();//隐藏上传框
+		$("#thelist").append( '<div id="' + file.id + '" class="item">' +
+	        '<h4 class="info">' + file.name + '</h4>' +
+	        '<p class="state"></p>' +
+	    '</div>' );
+	});
+
+	// 文件上传过程中创建进度条实时显示。
+	uploader.on( 'uploadProgress', function( file, percentage ) {
+	    var $li = $( '#'+file.id ),
+	        $percent = $li.find('.progress .progress-bar');
+
+	    // 避免重复创建
+	    if ( !$percent.length ) {
+	        $percent = $('<div class="progress progress-striped active">' +
+	          '<div class="progress-bar" role="progressbar" style="width: 0%"></div>' +
+	        '</div>').appendTo( $li ).find('.progress-bar');
+	    }
+	    $li.find('p.state').text('Uploading');
+	    $percent.css( 'width', percentage * 100 + '%' );
+	});
+
+	fileList();
+
+	function fileList() {
+		$.ajax({
+			type: "get",
+			url: '/bigfile/getFiles',
+			dataType: "json",
+			success: function (data) {
+				var listContent = "";
+				$.each(data.mergeFiles, function (index, val) {
+							if (val != null) {
+								listContent += '<li><a href="/bigfile/down?path=' + val + '">' + val + '</a></li>';
+							}
+							$('#list').html(listContent);
+						}
+				);
+				$.each(data.localFiles, function (index, val) {
+							if (val != null) {
+								listContent += '<li><a href="/bigfile/down?path=' + val + '">' + val + '</a></li>';
+							}
+							$('#list').html(listContent);
+						}
+				);
+			},
+			error: function (data) {
+				console.log(data);
+			}
+		});
+	}
+	
+</script>
+</body>
+</html>

+ 28 - 0
static/webuploader.css

@@ -0,0 +1,28 @@
+.webuploader-container {
+	position: relative;
+}
+.webuploader-element-invisible {
+	position: absolute !important;
+	clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
+    clip: rect(1px,1px,1px,1px);
+}
+.webuploader-pick {
+	position: relative;
+	display: inline-block;
+	cursor: pointer;
+	background: #00b7ee;
+	padding: 10px 15px;
+	color: #fff;
+	text-align: center;
+	border-radius: 3px;
+	overflow: hidden;
+}
+.webuploader-pick-hover {
+	background: #00a2d4;
+}
+
+.webuploader-pick-disable {
+	opacity: 0.6;
+	pointer-events:none;
+}
+

File diff ditekan karena terlalu besar
+ 0 - 0
static/webuploader.html5only.min.js


File diff ditekan karena terlalu besar
+ 0 - 0
static/webuploader.min.js


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini