You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by zh...@apache.org on 2021/09/04 15:57:34 UTC

[dubbo-go-samples] 02/12: add: game api (#111)

This is an automated email from the ASF dual-hosted git repository.

zhaoyunxing pushed a commit to branch compress
in repository https://gitbox.apache.org/repos/asf/dubbo-go-samples.git

commit d3073eb3ba8181b48bbfc26adfb5b102c88d1548
Author: 氕氘氚 <cj...@163.com>
AuthorDate: Sun May 16 22:30:01 2021 +0800

    add: game api (#111)
    
    * add login
    
    * add base api
    
    * del env
    
    * add test
    
    Co-authored-by: 氕氘氚 <ch...@bilibili.com>
---
 game/README.md                                     | 78 +++++++++++++------
 game/README_zh.md                                  | 80 ++++++++++++++------
 game/go-server-game/pkg/provider.go                | 87 +++++++++++++++++++---
 .../tests/integration/gameprovider_test.go         | 14 ++--
 game/go-server-gate/cmd/server.go                  | 58 +++++++++------
 game/go-server-gate/pkg/consumer.go                | 15 ++--
 game/pkg/consumer/game/basketball.go               |  6 +-
 game/pkg/pojo/info.go                              | 10 +++
 game/website/css/style.css                         |  5 +-
 game/website/index.html                            |  9 ++-
 game/website/js/api.js                             | 64 ++++++++++++++++
 game/website/js/index.js                           | 46 ++++++++++--
 12 files changed, 365 insertions(+), 107 deletions(-)

diff --git a/game/README.md b/game/README.md
index 8955e7a..18e6389 100644
--- a/game/README.md
+++ b/game/README.md
@@ -53,15 +53,15 @@ The server provides three services, message, online and offline. The code is as
 ```go
 type BasketballService struct{}
 
-func (p *BasketballService) Online(...) (...) {
+func Login(ctx context.Context, data string) (*pojo.Result, error) {
     ...
 }
 
-func (p *BasketballService) Offline(...) (...) {
+func Score(ctx context.Context, uid, score string) (*pojo.Result, error) {
     ...
 }
 
-func (p *BasketballService) Message(...) (...) {
+func Rank (ctx context.Context, uid string) (*pojo.Result, error) {
     ...
 }
 
@@ -175,23 +175,23 @@ services:
         retries: 0
 ```
 
-#### consumer size
+#### consumer side
 
 The consumer side of the gate is relatively special. Because the consumer of the gate needs to call the service in the game, the consumer directly instantiates the service of a game, and its method directly uses the instantiated object gamebasketball to call, thus realizing the function of a gateway.
 
 ```go
 var GameBasketball = new(game.BasketballService)
 
-func Message(ctx context.Context, uid string, data string) (*pojo.Result, error) {
-    return GameBasketball.Message(ctx, uid, data)
+func Login(ctx context.Context, data string) (*pojo.Result, error) {
+    return GameBasketball.Login(ctx, data)
 }
 
-func Online(ctx context.Context, uid string) (*pojo.Result, error) {
-    return GameBasketball.Online(ctx, uid)
+func Score(ctx context.Context, uid, score string) (*pojo.Result, error) {
+    return GameBasketball.Score(ctx, uid, score)
 }
 
-func Offline(ctx context.Context, uid string) (*pojo.Result, error) {
-    return GameBasketball.Offline(ctx, uid)
+func Rank (ctx context.Context, uid string) (*pojo.Result, error) {
+    return GameBasketball.Rank(ctx, uid)
 }
 ```
 
@@ -224,45 +224,79 @@ references:
 
 ### HTTP access
 
-access message
+access login
 
-```http
-http://localhost:8000/message
+```bash
+curl --location --request GET 'http://127.0.0.1:8089/login?name=dubbogo'
 ```
 
 received
 
 ```json
-{"code":0,"data":{"message":"hello from game provider","to":"abc"}}
+{
+    "code": 0,
+    "msg": "dubbogo, your score is 0",
+    "data": {
+        "score": 0,
+        "to": "dubbogo"
+    }
+}
 ```
 
 
 
-access online
+access score
 
-```http
-http://localhost:8000/online
+```bash
+curl --location --request POST 'http://127.0.0.1:8089/score' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+    "name":"cjp",
+    "score":1
+}'
 ```
 
 received
 
 ```json
-{"code":0,"msg":"hello this is game provider"}
+{
+    "code": 0,
+    "msg": "dubbogo, your score is 0",
+    "data": {
+        "score": 0,
+        "to": "dubbogo"
+    }
+}
 ```
 
-access offline
+access rank
 
-```http
-http://localhost:8000/online
+```bash
+curl --location --request POST 'http://127.0.0.1:8089/rank?name=dubbogo'
 ```
 
 received
 
 ```json
-{"code":0,"msg":"hello this is game provider"}
+{
+    "code": 0,
+    "msg": "success",
+    "data": {
+        "rank": 3,
+        "to": "dubbogo"
+    }
+}
 ```
 
 It can be found that all HTTP requests are successfully forwarded to game, and the processed data is returned to gate by calling the send method of gate
 
+
+
+### Start the front end
+
+Switch to webside directory and open index.html (Chrome browser is recommended)
+
+![image-20210516173728198](http://cdn.cjpa.top/image-20210516173728198.png)
+
 Pls. refer to [HOWTO.md](../HOWTO.md) under the root directory to run this sample.
 
diff --git a/game/README_zh.md b/game/README_zh.md
index 7090305..1b4592d 100644
--- a/game/README_zh.md
+++ b/game/README_zh.md
@@ -48,20 +48,20 @@ game提供了basketball服务端,gate提供了http服务端。
 
 #### server端
 
-server 端提供三个服务,message、online 及 offline,代码如下,具体的实现可以在 'game/go-server-game/pkg/provider.go' 中看到
+server 端提供三个服务,Login、Score 及 Rank,代码如下,具体的实现可以在 'game/go-server-game/pkg/provider.go' 中看到
 
 ```go
 type BasketballService struct{}
 
-func (p *BasketballService) Online(...) (...) {
+func Login(ctx context.Context, data string) (*pojo.Result, error) {
     ...
 }
 
-func (p *BasketballService) Offline(...) (...) {
+func Score(ctx context.Context, uid, score string) (*pojo.Result, error) {
     ...
 }
 
-func (p *BasketballService) Message(...) (...) {
+func Rank (ctx context.Context, uid string) (*pojo.Result, error) {
     ...
 }
 
@@ -177,21 +177,21 @@ services:
 
 #### consumer端
 
-gate 中的 consumer 端比较特使,由于 gate的consumer 需要调用 game 中的 service,所以在gaet中,consumer 直接实例化一个game的service,其方法便直接使用实例化的对象 GameBasketball 调用,这样就实现了一个网关的功能。
+gate 中的 consumer 端比较特殊,由于 gate的consumer 需要调用 game 中的 service,所以在gaet中,consumer 直接实例化一个game的service,其方法便直接使用实例化的对象 GameBasketball 调用,这样就实现了一个网关的功能。
 
 ```go
 var GameBasketball = new(game.BasketballService)
 
-func Message(ctx context.Context, uid string, data string) (*pojo.Result, error) {
-    return GameBasketball.Message(ctx, uid, data)
+func Login(ctx context.Context, data string) (*pojo.Result, error) {
+    return GameBasketball.Login(ctx, data)
 }
 
-func Online(ctx context.Context, uid string) (*pojo.Result, error) {
-    return GameBasketball.Online(ctx, uid)
+func Score(ctx context.Context, uid, score string) (*pojo.Result, error) {
+    return GameBasketball.Score(ctx, uid, score)
 }
 
-func Offline(ctx context.Context, uid string) (*pojo.Result, error) {
-    return GameBasketball.Offline(ctx, uid)
+func Rank (ctx context.Context, uid string) (*pojo.Result, error) {
+    return GameBasketball.Rank(ctx, uid)
 }
 ```
 
@@ -227,47 +227,81 @@ references:
 
 ### HTTP访问
 
-访问message
+访问login
 
-```http
-http://localhost:8000/message
+```bash
+curl --location --request GET 'http://127.0.0.1:8089/login?name=dubbogo'
 ```
 
-收到
+收到账户的信息
 
 ```json
-{"code":0,"data":{"message":"hello from game provider","to":"abc"}}
+{
+    "code": 0,
+    "msg": "dubbogo, your score is 0",
+    "data": {
+        "score": 0,
+        "to": "dubbogo"
+    }
+}
 ```
 
 
 
-访问 online
+访问 score
 
-```http
-http://localhost:8000/online
+```bash
+curl --location --request POST 'http://127.0.0.1:8089/score' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+    "name":"cjp",
+    "score":1
+}'
 ```
 
 收到
 
 ```json
-{"code":0,"msg":"hello this is game provider"}
+{
+    "code": 0,
+    "msg": "dubbogo, your score is 0",
+    "data": {
+        "score": 0,
+        "to": "dubbogo"
+    }
+}
 ```
 
-访问 offline
+访问 rank
 
 ```http
-http://localhost:8000/online
+curl --location --request POST 'http://127.0.0.1:8089/rank?name=dubbogo'
 ```
 
 收到
 
 ```json
-{"code":0,"msg":"hello this is game provider"}
+{
+    "code": 0,
+    "msg": "success",
+    "data": {
+        "rank": 3,
+        "to": "dubbogo"
+    }
+}
 ```
 
 可以发现,所有的http请求,都成功的转发到了 game,并且又通过调用 gate 的 send 方法把处理过的数据返回给 gate
 
 
 
+### 启动前端
+
+切换到 webside 目录,打开 index.html 即可(推荐使用chrome浏览器)
+
+![image-20210516173728198](http://cdn.cjpa.top/image-20210516173728198.png)
+
+点击小人即可进行游戏
+
 请参阅根目录中的 [HOWTO.md](../HOWTO_zh.md) 来运行本例。
 
diff --git a/game/go-server-game/pkg/provider.go b/game/go-server-game/pkg/provider.go
index 5ab380f..7892000 100644
--- a/game/go-server-game/pkg/provider.go
+++ b/game/go-server-game/pkg/provider.go
@@ -3,6 +3,7 @@ package pkg
 import (
     "context"
     "fmt"
+    "strconv"
 
     "github.com/apache/dubbo-go/common/logger"
 
@@ -11,27 +12,93 @@ import (
 
 type BasketballService struct{}
 
-func (p *BasketballService) Online(ctx context.Context, uid string) (*pojo.Result, error) {
-    logger.Infof("online: %s", uid)
-    return &pojo.Result{Code: 0, Msg: "hello this is game provider"}, nil
+var userMap = make(map[string]*pojo.Info, 0)
+
+func (p *BasketballService) Login(ctx context.Context, uid string) (*pojo.Result, error) {
+    logger.Infof("message: %#v", uid)
+    var (
+        info *pojo.Info
+        ok bool
+    )
+
+    // auto reply the same message
+    rsp, err := GateBasketball.Send(context.TODO(), uid, "")
+    if err != nil {
+        logger.Errorf("send fail: %#s", err.Error())
+        return &pojo.Result{Code: 1, Msg: err.Error()}, err
+    }
+
+    fmt.Println("receive data from gate:", rsp)
+
+    if info, ok = userMap[uid]; !ok {
+        info = &pojo.Info{}
+        info.Name = uid
+        userMap[uid] = info
+    }
+    return &pojo.Result{Code: 0, Msg: info.Name + ", your score is " + strconv.Itoa(info.Score) , Data: map[string]interface{}{"to": uid, "score": info.Score}}, nil
 }
 
-func (p *BasketballService) Offline(ctx context.Context, uid string) (*pojo.Result, error) {
-    logger.Infof("offline: %#s", uid)
-    return &pojo.Result{Code: 0, Msg: "hello this is game provider"}, nil
+func (p *BasketballService) Score (ctx context.Context, uid, score string) (*pojo.Result, error) {
+    logger.Infof("message: %#v, %#v", uid, score)
+    var (
+        info = &pojo.Info{}
+        ok bool
+    )
+
+    // auto reply the same message
+    rsp, err := GateBasketball.Send(context.TODO(), uid, score)
+    if err != nil {
+        logger.Errorf("send fail: %#s", err.Error())
+        return &pojo.Result{Code: 1, Msg: err.Error()}, err
+    }
+
+    fmt.Println("receive data from gate:", rsp)
+
+    if info, ok = userMap[uid]; !ok {
+      info = &pojo.Info{
+          Name: uid,
+      }
+      userMap[uid] = info
+      logger.Error("user data not found")
+      return &pojo.Result{Code: 1, Msg: "user data not found", Data: map[string]interface{}{}}, nil
+    }
+    intSource, err := strconv.Atoi(score)
+    if err != nil {
+        logger.Error(err.Error())
+    }
+    info.Score += intSource
+
+    return &pojo.Result{Code: 0, Msg: "进球成功", Data: map[string]interface{}{"to": uid, "score": info.Score}}, nil
 }
 
-func (p *BasketballService) Message(ctx context.Context, uid, data string) (*pojo.Result, error) {
-    logger.Infof("message: %#v, %#v", uid, data)
+func (p *BasketballService) Rank (ctx context.Context, uid string) (*pojo.Result, error) {
+    var (
+        rank = 1
+        info  *pojo.Info
+        ok bool
+    )
 
     // auto reply the same message
-    rsp, err := GateBasketball.Send(context.TODO(), uid, data)
+    rsp, err := GateBasketball.Send(context.TODO(), uid, "")
     if err != nil {
         logger.Errorf("send fail: %#s", err.Error())
         return &pojo.Result{Code: 1, Msg: err.Error()}, err
     }
+
     fmt.Println("receive data from gate:", rsp)
-    return &pojo.Result{Code: 0, Data: map[string]interface{}{"to": uid, "message": data + " from game provider"}}, nil
+
+    if info, ok = userMap[uid]; !ok {
+        logger.Error("no user found")
+        return &pojo.Result{Code: 1, Msg: "no user found", Data: map[string]interface{}{"to": uid, "rank": rank}}, nil
+    }
+
+    for _, v := range userMap {
+        if v.Score > info.Score {
+            rank ++
+        }
+    }
+
+    return &pojo.Result{Code: 0, Msg: "success", Data: map[string]interface{}{"to": uid, "rank": rank}}, nil
 }
 
 func (p *BasketballService) Reference() string {
diff --git a/game/go-server-game/tests/integration/gameprovider_test.go b/game/go-server-game/tests/integration/gameprovider_test.go
old mode 100644
new mode 100755
index 8502d40..02dcf4a
--- a/game/go-server-game/tests/integration/gameprovider_test.go
+++ b/game/go-server-game/tests/integration/gameprovider_test.go
@@ -7,25 +7,25 @@ import (
     "github.com/stretchr/testify/assert"
 )
 
-func TestMessage(t *testing.T) {
-    res, err := gameProvider.Message(context.TODO(), "A001", "hello")
+func TestLogin(t *testing.T) {
+    res, err := gameProvider.Login(context.TODO(), "A001")
     assert.Nil(t, err)
     assert.NotNil(t, res)
     assert.Equal(t, int32(0), res.Code)
     assert.NotNil(t, res.Data)
     assert.Equal(t, "A001", res.Data["to"])
-    assert.Equal(t, "hello", res.Data["message"])
+    assert.Equal(t, 0, res.Data["score"])
 }
 
-func TestOnline(t *testing.T) {
-    res, err := gameProvider.Online(context.TODO(), "A001")
+func TestScore(t *testing.T) {
+    res, err := gameProvider.Score(context.TODO(), "A001", "1")
     assert.Nil(t, err)
     assert.NotNil(t, res)
     assert.Equal(t, int32(0), res.Code)
 }
 
-func TestOffline(t *testing.T) {
-    res, err := gameProvider.Offline(context.TODO(), "A001")
+func TestRank(t *testing.T) {
+    res, err := gameProvider.Rank(context.TODO(), "A001")
     assert.Nil(t, err)
     assert.NotNil(t, res)
     assert.Equal(t, int32(0), res.Code)
diff --git a/game/go-server-gate/cmd/server.go b/game/go-server-gate/cmd/server.go
old mode 100644
new mode 100755
index 232f16d..b16297b
--- a/game/go-server-gate/cmd/server.go
+++ b/game/go-server-gate/cmd/server.go
@@ -3,15 +3,17 @@ package main
 import (
     "context"
     "encoding/json"
+    "io/ioutil"
     "net/http"
     "os"
     "os/signal"
+    "strconv"
     "syscall"
     "time"
 
+    hessian "github.com/apache/dubbo-go-hessian2"
     "github.com/apache/dubbo-go/common/logger"
     "github.com/apache/dubbo-go/config"
-    hessian "github.com/apache/dubbo-go-hessian2"
 
     _ "github.com/apache/dubbo-go/protocol/dubbo"
     _ "github.com/apache/dubbo-go/registry/protocol"
@@ -71,53 +73,67 @@ func initSignal() {
 
 func startHttp() {
 
-    http.HandleFunc("/message", func(w http.ResponseWriter, r *http.Request) {
-        res, err := pkg.Message(context.TODO(), "abc", "hello")
+    http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
+        res, err := pkg.Login(context.TODO(), r.URL.Query().Get("name"))
         if err != nil {
-            _, _ = w.Write([]byte(err.Error()))
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
             return
         }
 
         b, err := json.Marshal(res)
         if err != nil {
-            _, _ = w.Write([]byte(err.Error()))
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
             return
         }
-
-        _, _ = w.Write(b)
+        responseWithOrigin(w, r, 200, b)
     })
 
-    http.HandleFunc("/online", func(w http.ResponseWriter, r *http.Request) {
-        res, err := pkg.Online(context.TODO(), "abc")
+    http.HandleFunc("/score", func(w http.ResponseWriter, r *http.Request) {
+        reqBody, err := ioutil.ReadAll(r.Body)
+        if err != nil {
+            logger.Error(err.Error())
+        }
+        var info pojo.Info
+        json.Unmarshal(reqBody, &info)
+        res, err := pkg.Score(context.TODO(), info.Name, strconv.Itoa(info.Score))
         if err != nil {
-            _, _ = w.Write([]byte(err.Error()))
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
             return
         }
 
         b, err := json.Marshal(res)
         if err != nil {
-            _, _ = w.Write([]byte(err.Error()))
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
             return
         }
-
-        _, _ = w.Write(b)
+        responseWithOrigin(w, r, 200, b)
     })
 
-    http.HandleFunc("/offline", func(w http.ResponseWriter, r *http.Request) {
-        res, err := pkg.Offline(context.TODO(), "abc")
+    http.HandleFunc("/rank", func(w http.ResponseWriter, r *http.Request) {
+        res, err := pkg.Rank(context.TODO(), r.URL.Query().Get("name"))
         if err != nil {
-            _, _ = w.Write([]byte(err.Error()))
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
             return
         }
-
         b, err := json.Marshal(res)
         if err != nil {
-            _, _ = w.Write([]byte(err.Error()))
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
             return
         }
-
-        _, _ = w.Write(b)
+        responseWithOrigin(w, r, 200, b)
     })
 
-    _ = http.ListenAndServe(":8000", nil)
+    _ = http.ListenAndServe("127.0.0.1:8089", nil)
+}
+
+// avoid cors
+func responseWithOrigin(w http.ResponseWriter, r *http.Request, code int, json []byte) {
+    w.Header().Set("Access-Control-Allow-Origin", "*")
+    w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
+    w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
+    w.Header().Set("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
+    w.Header().Set("Access-Control-Allow-Credentials", "true")
+    w.Header().Set("Content-Type", "application/json; charset=utf-8")
+    w.WriteHeader(code)
+    w.Write(json)
 }
\ No newline at end of file
diff --git a/game/go-server-gate/pkg/consumer.go b/game/go-server-gate/pkg/consumer.go
index 04c4d33..74bd910 100644
--- a/game/go-server-gate/pkg/consumer.go
+++ b/game/go-server-gate/pkg/consumer.go
@@ -12,17 +12,14 @@ var GameBasketball = new(game.BasketballService)
 
 // just easy for demo test
 
-func Message(ctx context.Context, uid string, data string) (*pojo.Result, error) {
-    return GameBasketball.Message(ctx, uid, data)
-    // return gameJump.Message(ctx, uid, data)
+func Login(ctx context.Context, data string) (*pojo.Result, error) {
+    return GameBasketball.Login(ctx, data)
 }
 
-func Online(ctx context.Context, uid string) (*pojo.Result, error) {
-    return GameBasketball.Online(ctx, uid)
-    // return gameJump.Online(ctx, uid)
+func Score(ctx context.Context, uid, score string) (*pojo.Result, error) {
+    return GameBasketball.Score(ctx, uid, score)
 }
 
-func Offline(ctx context.Context, uid string) (*pojo.Result, error) {
-    return GameBasketball.Offline(ctx, uid)
-    // return gameJump.Offline(ctx, uid)
+func Rank (ctx context.Context, uid string) (*pojo.Result, error) {
+    return GameBasketball.Rank(ctx, uid)
 }
diff --git a/game/pkg/consumer/game/basketball.go b/game/pkg/consumer/game/basketball.go
index 5e900e5..20dc0b6 100644
--- a/game/pkg/consumer/game/basketball.go
+++ b/game/pkg/consumer/game/basketball.go
@@ -6,9 +6,9 @@ import (
 )
 
 type BasketballService struct {
-    Online  func(ctx context.Context, uid string) (*pojo.Result, error)
-    Offline func(ctx context.Context, uid string) (*pojo.Result, error)
-    Message func(ctx context.Context, uid string, data string) (*pojo.Result, error)
+    Login   func(ctx context.Context, uid string) (*pojo.Result, error)
+    Score   func(ctx context.Context, uid, score string) (*pojo.Result, error)
+    Rank  func(ctx context.Context, uid string) (*pojo.Result, error)
 }
 
 func (p *BasketballService) Reference() string {
diff --git a/game/pkg/pojo/info.go b/game/pkg/pojo/info.go
new file mode 100644
index 0000000..59d47dc
--- /dev/null
+++ b/game/pkg/pojo/info.go
@@ -0,0 +1,10 @@
+package pojo
+
+type Info struct {
+	Name string `json:"name"`
+	Score int	`json:"score"`
+}
+
+func (m Info) JavaClassName() string {
+	return "org.apache.dubbo.pojo.Info"
+}
\ No newline at end of file
diff --git a/game/website/css/style.css b/game/website/css/style.css
index 9a6875d..5f21f5a 100644
--- a/game/website/css/style.css
+++ b/game/website/css/style.css
@@ -48,6 +48,7 @@
 }
 .info{
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 10px;
+    left: 10px;
+    color: white;
 }
\ No newline at end of file
diff --git a/game/website/index.html b/game/website/index.html
index 5d073e4..a3554db 100644
--- a/game/website/index.html
+++ b/game/website/index.html
@@ -6,6 +6,7 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>FootBall Game</title>
+    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
     <!-- import Vue before Element -->
     <script src="https://unpkg.com/vue/dist/vue.js"></script>
     <!-- 引入样式 -->
@@ -25,14 +26,17 @@
             用户:{{info.name}}
             <br>
             分数:{{info.score}}
+            <br>
+            排名:{{info.rank}}
         </div>
         <svg id="gate" class="gate" t="1620527545136" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2966" width="400" height="400"><path d="M861.414041 192.806237 179.968861 192.806237c-51.828412 0-93.985558 42.164309-93.985558 93.985558l0 514.915399 61.975517 0 0-0.276293 0.796132 0.650823 74.704422-89.905636 597.571934 0 72.39482 87.839581 0 1.691525 62.007239 0L955.433368 286.791795C955.432345 234.970546 913.228127 192.806237 861.414041 19 [...]
         <svg id="ball" class="ball" t="1620527208144" class="icon" viewBox="0 0 1365 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1801" width="400" height="400"><path d="M647.937 1023.573c-40.96 0-82.133-5.12-122.24-14.933-66.773-16.427-128.427-45.44-183.04-86.4-52.693-39.467-96.853-88.107-131.2-144.853-34.347-56.747-56.96-118.4-67.2-183.467-10.88-67.413-7.893-135.467 8.533-202.24 14.08-56.747 37.334-110.293 69.12-158.72 30.934-46.72 69.12-88.107 113.707-122.453 44.16-34. [...]
         <svg class="people" @click="clickPeople" t="1620527325090" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2618" width="400" height="400"><path d="M563.240423 102.320551m-102.320551 0a102.320551 102.320551 0 1 0 204.641102 0 102.320551 102.320551 0 1 0-204.641102 0Z" p-id="2619" fill="#e6e6e6"></path><path d="M322.895467 827.809372c-8.907907 20.054828-155.767992 195.805422-155.767992 195.805421h122.447605s106.292996-119.58263 113.924906 [...]
         <el-dialog
         title="输入姓名"
-        :visible.sync="dialogVisible"
+        :visible="dialogVisible"
         width="30%"
+        :show-close="false"
         >
         <el-form v-model="info">
             <el-form-item label="姓名">
@@ -40,12 +44,13 @@
             </el-form-item>
         </el-form>
         <span slot="footer" class="dialog-footer">
-            <el-button @click="dialogVisible = false">取 消</el-button>
             <el-button type="primary" @click="submitInfo">确 定</el-button>
         </span>
         </el-dialog>
     </div>
+    <script src="js/api.js"></script>
     <script src="js/index.js"></script>
+    
 </body>
 
 </html>
\ No newline at end of file
diff --git a/game/website/js/api.js b/game/website/js/api.js
new file mode 100644
index 0000000..32a2358
--- /dev/null
+++ b/game/website/js/api.js
@@ -0,0 +1,64 @@
+var baseURL = 'http://127.0.0.1:8089/'
+
+function login(data) {
+    return new Promise(function(resolve, reject) {
+        $.ajax({
+            type: "get",
+            url: baseURL + 'login',
+            data:data,
+            dataType: "json", //指定服务器返回的数据类型
+            success: function (response) {
+                if (response.code != 0) {
+                    reject(response.msg)
+                } else {
+                    resolve(response)
+                }
+            },
+            error:function(err){
+                reject(err)
+            }
+        });
+    })
+}
+
+function score(data) {
+    return new Promise(function(resolve, reject) {
+        $.ajax({
+            type: "post",
+            url: baseURL + 'score',
+            data:data,
+            dataType: "json", //指定服务器返回的数据类型
+            success: function (response) {
+                if (response.code != 0) {
+                    reject(response.msg)
+                } else {
+                    resolve(response)
+                }
+            },
+            error:function(err){
+                reject(err)
+            }
+        })
+    })
+}
+
+function rank(data) {
+    return new Promise(function(resolve, reject) {
+        $.ajax({
+            type: "get",
+            url: baseURL + 'rank',
+            data:data,
+            dataType: "json", //指定服务器返回的数据类型
+            success: function (response) {
+                if (response.code != 0) {
+                    reject(response.msg)
+                } else {
+                    resolve(response)
+                }
+            },
+            error:function(err){
+                reject(err)
+            }
+        })
+    })
+}
\ No newline at end of file
diff --git a/game/website/js/index.js b/game/website/js/index.js
index 49b58cc..7e9be35 100644
--- a/game/website/js/index.js
+++ b/game/website/js/index.js
@@ -3,11 +3,11 @@ new Vue({
     data: function () {
         return { 
             visible: false,
-            rootDom:Object, 
             dialogVisible:true,
             info:{
                 name:'',
-                score:0
+                score:0,
+                rank:0
             },
             isMeet:false
         }
@@ -26,8 +26,30 @@ new Vue({
         }
     },
     methods: {
+        getRank:function(){
+            rank({name: this.info.name}).then(Response => {
+                this.info.rank = Response.data.rank
+            }).catch(e => {
+                this.$message({
+                    message: "获取排名失败" + e,
+                    type:"danger"
+                })
+            })
+        },
         submitInfo:function(){
             this.dialogVisible = false
+            login({name: this.info.name}).then(Response => {
+                this.info.name = Response.data.to
+                this.$message({
+                    message:"欢迎" + Response.msg
+                })
+                this.getRank()
+            }).catch(e => {
+                this.$message({
+                    message: "登陆失败" + e,
+                    type:"danger"
+                })
+            })
         },
         moveBall:function(){
             var elem = document.getElementsByClassName("ball")
@@ -38,15 +60,24 @@ new Vue({
             function frame() {
                 var space = elem[0].getBoundingClientRect().left - gate.getBoundingClientRect().left
                 var hight = elem[0].getBoundingClientRect().top - gate.getBoundingClientRect().top
-                console.log(space < 20)
-                if (!that.isMeet && (space <20 && space > -20 && hight < 20 && hight > -20)) {
+                if (!that.isMeet && (space <60 && space > -20 && hight < 20 && hight > -20)) {
                     that.isMeet = true
-                    that.$message({
-                        message:"进球成功",
-                        type:"success"
+                    score(JSON.stringify({name:that.info.name, score:1})).then(Response => {
+                        that.info.score = Response.data.score
+                        that.$message({
+                            message:"进球成功, 总分数为:" + Response.data.score,
+                            type:"success"
+                        })
+                        that.getRank()
+                    }).catch( e => {
+                        that.$message({
+                            message: "分数统计失败" + e,
+                            type:"danger"
+                        })
                     })
                 }
                 if (tempHeight >= that.clientHeight) {
+                    elem[0].style.bottom = 0 + ''
                     clearInterval(id)
                 } else{
                     tempHeight += 20
@@ -92,7 +123,6 @@ new Vue({
     mounted(){
         this.move()
         this.moveGate()
-        this.rootDom = document.getElementById("app")
     },
     created() {