User registration

Get data/bind data

  • Type of data transferred from the front end:
    1. Form form: The data is form data

    2. Ajax: Data is in JSON format. So this is — Request Payload

  • The default postForm() method can only fetch the data passed by the form form.
  • In the form of Request Payload, you need to use Data binding to obtain the transmitted data.
    • ctx.Bind()Bind data to objects.
-- web/main.goAdd r1. POST ("/users", controller.PostRet)

-- web/controller/user.goTo add, implement// Send the registration information
func PostRet(ctx *gin.Context) {
	/* mobile := ctx.PostForm("mobile") pwd := ctx.PostForm("password") sms_code := ctx.PostForm("sms_code") fmt.Println("m = ", mobile, "pwd = ", pwd, "sms_code = ",sms_code) */
	// Get data
	var regData struct {
		Mobile   string `json:"mobile"`
		PassWord string `json:"password"`
		SmsCode  string `json:"sms_code"`
	}
	ctx.Bind(&regData)
	fmt.Println("The obtained data is :", regData)
}
Copy the code

Micro server

  1. Modify the password book — proto file

    syntax = "proto3";
    
    package go.micro.srv.user;
    
    service User {
            rpc SendSms(Request) returns (Response) {};
            rpc Register(RegRequest) returns (Response) {};
    }
    
    message Request {
            string phone = 1;
            string imgCode = 2;
            string uuid = 3;
    
    }
    
    message RegRequest {
            string mobile = 1;
            string password = 2;
            string smsCode = 3;
    }
    
    message Response {
            string errno = 1;
            string errmsg = 2;
    }
    
    Copy the code
  2. Make Generates the xxx.micro. Go file

  3. Modify the handler/user. Go

    // Add method
    func (e *User) Register(ctx context.Context, req *user.RegRequest, rsp *user.Response) error {
            return nil
    }
    Copy the code
  4. You need to manipulate the MySQL database and copy web/model/model.go to the microservice project.

  5. In the service/user/model/modelFunc. Go add validation message authentication code function

    // CheckSmsCode Indicates the VERIFICATION code of the SMS
    func CheckSmsCode(mobile, smsCode string) bool {
            / / connect to redis
            conn := RedisPool.Get()
            defer conn.Close()
            // Query data
            code, err := redis.String(conn.Do("get", mobile+"_code"))
            iferr ! =nil {
                    fmt.Println("Redis query error:", err)
                    return false
            }
            return smsCode == code
    }
    Copy the code
  6. Service/user/model/modelFunc. Go, add function SaveUserInfo, realize the user registration information, write the MySQL database

    // SaveUserInfo stores user information to the user table
    func SaveUserInfo(mobile, password string) error {
            var newUser User
            // If the mobile phone number does not exist, register a new user
            if GlobalConn.Where("mobile = ?", mobile).Find(&newUser).RecordNotFound() {
                    newUser.Name = mobile
                    newUser.Mobile = mobile
                    // Use MD5 to encrypt password
                    m5 := md5.New()
                    m5.Write([]byte(password))
                    pwdHash := hex.EncodeToString(m5.Sum(nil))
                    newUser.Password_hash = pwdHash
                    return GlobalConn.Create(&newUser).Error
            }
            // If the mobile phone number already exists, the registration fails
            return errors.New("Mobile number already exists")}Copy the code
  7. Complete the Register function implementation

    // Register User registration
    func (e *User) Register(ctx context.Context, req *user.RegRequest, rsp *user.Response) error {
            // Verification code - Obtain the verification code from Redis for comparison
            result := model.CheckSmsCode(req.Mobile, req.SmsCode)
            // There was a problem getting the captcha service
            result = true
            if result { // The verification code is successfully compared
                    // Store user information to mysql database
                    err := model.SaveUserInfo(req.Mobile, req.Password)
                    iferr ! =nil {
                            fmt.Println("Error storing user information:", err)
                            rsp.Errno = utils.RECODE_DBERR
                            rsp.Errmsg = utils.RecodeText(utils.RECODE_DBERR)
                    } else {
                            rsp.Errno = utils.RECODE_OK
                            rsp.Errmsg = utils.RecodeText(utils.RECODE_OK)
                    }
            } else { // Verification code comparison failed
                    fmt.Println("Verification code comparison error")
                    rsp.Errno = utils.RECODE_DATAERR
                    rsp.Errmsg = utils.RecodeText(utils.RECODE_DATAERR)
            }
            return nil
    }
    Copy the code

Web side

  1. Copy the password book — proto

  2. Create a web/utils/utils. Go file and wrap the function to implement the initial Consul client code

    // Initialize the micro
    func InitMicro(a) micro.Service {
    	// Initialize the client
    	consulReg := consul.NewRegistry()
    	return micro.NewService(
    		micro.Registry(consulReg),
    	)
    }
    Copy the code
  3. Implement the PostRet function in Web/Controller /user.go

    // PostRet sends the registration information
    func PostRet(ctx *gin.Context) {
            // Get data
            var regData struct {
                    Mobile string `json:"mobile"`
                    Password string `json:"password"`
                    SmsCode string `json:"sms_code"`
            }
            ctx.Bind(&regData)
    
            // Call the remote function
            microClient := userMicro.NewUserService("go.micro.srv.user", client.DefaultClient)
            resp, err := microClient.Register(context.TODO(),
                    &userMicro.RegRequest{Mobile: regData.Mobile, Password: regData.Password, SmsCode: regData.SmsCode})
            iferr ! =nil {
                    fmt.Println("Failed to call remote function Register:", err)
                    return
            }
    
            // Send it to the browser
            ctx.JSON(http.StatusOK, resp)
    }
    Copy the code

Get geographic information

The interface definition

#Request:
method: GET
url:api/v1. 0/areas #data: no input data #Response #"errno": "0"."errmsg":"OK"."data": [{"aid": 1."aname": "Dongcheng District"}, 
    {"aid": 2."aname": "West Side"}, 
    {"aid": 3."aname": "Tongzhou District"}, 
    {"aid": 4."aname": "Shunyi District"}] 
    / /...} # register failed: {"errno": "400x"./ / status code
    "errmsg":"Status error message"
}
Copy the code

Business flow chart

Importing SQL Scripts

  1. Save home.sql to Linux
  2. Log in to the MySQL database. Select database:use search_house;
  3. Run the script file to insert data into the table.source /Users/yaxuan/home.sql

Web side

  1. In web/main.go, add the route and set the callback.

    r1.GET("/areas", controller.GetArea)
    Copy the code
  2. In web/ Controller /use.go, add the GetArea() function.

    func GetArea(ctx *gin.Context){}Copy the code
  3. Get data from the database, improve the user experience of the common method: first check the cache, cache does not check MySQL, write redis cache.

    // Get the location information
    func GetArea(ctx *gin.Context)  {
    // Get data from MySQL.
    var areas []model.Area
    model.GlobalConn.Find(&areas)
    
    // Write the data to redis.
    conn := model.RedisPool.Get()
    conn.Do("set"."areaData", areas) // Store the areas array directly into Redis
    
    resp := make(map[string]interface{})
    resp["errno"] = "0"
    resp["errmsg"] = utils.RecodeText(utils.RECODE_OK)
    resp["data"] = areas
    
    ctx.JSON(http.StatusOK, resp)
    }
    Copy the code

    Consider: Store data to Conn. Do(“set”, “areaData”, areas) in Redis as above for future data retrieval using Do! Hard to get! There is no corresponding reply helper function for type assertion. Select a new way to store redis: convert data to JOSN byte stream storage.

    // GetArea gets the location information
    func GetArea(ctx *gin.Context) {
            // Get data from Redis first
            conn := model.RedisPool.Get()
            areaData, _ := redis.Bytes(conn.Do("get"."areaData"))
            var areas []model.Area
            if len(areaData) == 0 { // No data in redis
                    // Get data from mysql
                    model.GlobalConn.Find(&areas)
                    // Write the data to redis -- store the serialized JSON string of the structure
                    areaBuf, _ := json.Marshal(areas)
                    conn.Do("set"."areaData", areaBuf)
            } else { // There is data in redis
                    json.Unmarshal(areaData, &areas)
            }
    
            resp := make(map[string]interface{})
            resp["errno"] = utils.RECODE_OK
            resp["errmsg"] = utils.RecodeText(utils.RECODE_OK)
            resp["data"] = areas
    
            ctx.JSON(http.StatusOK, resp)
    }
    Copy the code