ljw 1 год назад
Родитель
Сommit
6c94566e83

+ 1 - 1
cmd/apimain.go

@@ -101,7 +101,7 @@ func main() {
101 101
 }
102 102
 
103 103
 func DatabaseAutoUpdate() {
104
-	version := 243
104
+	version := 244
105 105
 
106 106
 	db := global.DB
107 107
 

+ 166 - 3
docs/admin/admin_docs.go

@@ -1485,7 +1485,7 @@ const docTemplateadmin = `{
1485 1485
                 }
1486 1486
             }
1487 1487
         },
1488
-        "/admin/loginLog/delete": {
1488
+        "/admin/login_log/delete": {
1489 1489
             "post": {
1490 1490
                 "security": [
1491 1491
                     {
@@ -1530,7 +1530,7 @@ const docTemplateadmin = `{
1530 1530
                 }
1531 1531
             }
1532 1532
         },
1533
-        "/admin/loginLog/detail/{id}": {
1533
+        "/admin/login_log/detail/{id}": {
1534 1534
             "get": {
1535 1535
                 "security": [
1536 1536
                     {
@@ -1585,7 +1585,7 @@ const docTemplateadmin = `{
1585 1585
                 }
1586 1586
             }
1587 1587
         },
1588
-        "/admin/loginLog/list": {
1588
+        "/admin/login_log/list": {
1589 1589
             "get": {
1590 1590
                 "security": [
1591 1591
                     {
@@ -2216,6 +2216,12 @@ const docTemplateadmin = `{
2216 2216
                         "description": "主机名",
2217 2217
                         "name": "hostname",
2218 2218
                         "in": "query"
2219
+                    },
2220
+                    {
2221
+                        "type": "string",
2222
+                        "description": "uuids 用逗号分隔",
2223
+                        "name": "uuids",
2224
+                        "in": "query"
2219 2225
                     }
2220 2226
                 ],
2221 2227
                 "responses": {
@@ -3087,6 +3093,117 @@ const docTemplateadmin = `{
3087 3093
                     }
3088 3094
                 }
3089 3095
             }
3096
+        },
3097
+        "/admin/user_token/delete": {
3098
+            "post": {
3099
+                "security": [
3100
+                    {
3101
+                        "token": []
3102
+                    }
3103
+                ],
3104
+                "description": "登录凭证删除",
3105
+                "consumes": [
3106
+                    "application/json"
3107
+                ],
3108
+                "produces": [
3109
+                    "application/json"
3110
+                ],
3111
+                "tags": [
3112
+                    "登录凭证"
3113
+                ],
3114
+                "summary": "登录凭证删除",
3115
+                "parameters": [
3116
+                    {
3117
+                        "description": "登录凭证信息",
3118
+                        "name": "body",
3119
+                        "in": "body",
3120
+                        "required": true,
3121
+                        "schema": {
3122
+                            "$ref": "#/definitions/model.UserToken"
3123
+                        }
3124
+                    }
3125
+                ],
3126
+                "responses": {
3127
+                    "200": {
3128
+                        "description": "OK",
3129
+                        "schema": {
3130
+                            "$ref": "#/definitions/response.Response"
3131
+                        }
3132
+                    },
3133
+                    "500": {
3134
+                        "description": "Internal Server Error",
3135
+                        "schema": {
3136
+                            "$ref": "#/definitions/response.Response"
3137
+                        }
3138
+                    }
3139
+                }
3140
+            }
3141
+        },
3142
+        "/admin/user_token/list": {
3143
+            "get": {
3144
+                "security": [
3145
+                    {
3146
+                        "token": []
3147
+                    }
3148
+                ],
3149
+                "description": "登录凭证列表",
3150
+                "consumes": [
3151
+                    "application/json"
3152
+                ],
3153
+                "produces": [
3154
+                    "application/json"
3155
+                ],
3156
+                "tags": [
3157
+                    "登录凭证"
3158
+                ],
3159
+                "summary": "登录凭证列表",
3160
+                "parameters": [
3161
+                    {
3162
+                        "type": "integer",
3163
+                        "description": "页码",
3164
+                        "name": "page",
3165
+                        "in": "query"
3166
+                    },
3167
+                    {
3168
+                        "type": "integer",
3169
+                        "description": "页大小",
3170
+                        "name": "page_size",
3171
+                        "in": "query"
3172
+                    },
3173
+                    {
3174
+                        "type": "integer",
3175
+                        "description": "用户ID",
3176
+                        "name": "user_id",
3177
+                        "in": "query"
3178
+                    }
3179
+                ],
3180
+                "responses": {
3181
+                    "200": {
3182
+                        "description": "OK",
3183
+                        "schema": {
3184
+                            "allOf": [
3185
+                                {
3186
+                                    "$ref": "#/definitions/response.Response"
3187
+                                },
3188
+                                {
3189
+                                    "type": "object",
3190
+                                    "properties": {
3191
+                                        "data": {
3192
+                                            "$ref": "#/definitions/model.UserTokenList"
3193
+                                        }
3194
+                                    }
3195
+                                }
3196
+                            ]
3197
+                        }
3198
+                    },
3199
+                    "500": {
3200
+                        "description": "Internal Server Error",
3201
+                        "schema": {
3202
+                            "$ref": "#/definitions/response.Response"
3203
+                        }
3204
+                    }
3205
+                }
3206
+            }
3090 3207
         }
3091 3208
     },
3092 3209
     "definitions": {
@@ -3801,6 +3918,9 @@ const docTemplateadmin = `{
3801 3918
                 "user_id": {
3802 3919
                     "type": "integer"
3803 3920
                 },
3921
+                "user_token_id": {
3922
+                    "type": "integer"
3923
+                },
3804 3924
                 "uuid": {
3805 3925
                     "type": "string"
3806 3926
                 }
@@ -4068,6 +4188,49 @@ const docTemplateadmin = `{
4068 4188
                 }
4069 4189
             }
4070 4190
         },
4191
+        "model.UserToken": {
4192
+            "type": "object",
4193
+            "properties": {
4194
+                "created_at": {
4195
+                    "type": "string"
4196
+                },
4197
+                "expired_at": {
4198
+                    "type": "integer"
4199
+                },
4200
+                "id": {
4201
+                    "type": "integer"
4202
+                },
4203
+                "token": {
4204
+                    "type": "string"
4205
+                },
4206
+                "updated_at": {
4207
+                    "type": "string"
4208
+                },
4209
+                "user_id": {
4210
+                    "type": "integer"
4211
+                }
4212
+            }
4213
+        },
4214
+        "model.UserTokenList": {
4215
+            "type": "object",
4216
+            "properties": {
4217
+                "list": {
4218
+                    "type": "array",
4219
+                    "items": {
4220
+                        "$ref": "#/definitions/model.UserToken"
4221
+                    }
4222
+                },
4223
+                "page": {
4224
+                    "type": "integer"
4225
+                },
4226
+                "page_size": {
4227
+                    "type": "integer"
4228
+                },
4229
+                "total": {
4230
+                    "type": "integer"
4231
+                }
4232
+            }
4233
+        },
4071 4234
         "response.ErrorResponse": {
4072 4235
             "type": "object",
4073 4236
             "properties": {

+ 166 - 3
docs/admin/admin_swagger.json

@@ -1478,7 +1478,7 @@
1478 1478
                 }
1479 1479
             }
1480 1480
         },
1481
-        "/admin/loginLog/delete": {
1481
+        "/admin/login_log/delete": {
1482 1482
             "post": {
1483 1483
                 "security": [
1484 1484
                     {
@@ -1523,7 +1523,7 @@
1523 1523
                 }
1524 1524
             }
1525 1525
         },
1526
-        "/admin/loginLog/detail/{id}": {
1526
+        "/admin/login_log/detail/{id}": {
1527 1527
             "get": {
1528 1528
                 "security": [
1529 1529
                     {
@@ -1578,7 +1578,7 @@
1578 1578
                 }
1579 1579
             }
1580 1580
         },
1581
-        "/admin/loginLog/list": {
1581
+        "/admin/login_log/list": {
1582 1582
             "get": {
1583 1583
                 "security": [
1584 1584
                     {
@@ -2209,6 +2209,12 @@
2209 2209
                         "description": "主机名",
2210 2210
                         "name": "hostname",
2211 2211
                         "in": "query"
2212
+                    },
2213
+                    {
2214
+                        "type": "string",
2215
+                        "description": "uuids 用逗号分隔",
2216
+                        "name": "uuids",
2217
+                        "in": "query"
2212 2218
                     }
2213 2219
                 ],
2214 2220
                 "responses": {
@@ -3080,6 +3086,117 @@
3080 3086
                     }
3081 3087
                 }
3082 3088
             }
3089
+        },
3090
+        "/admin/user_token/delete": {
3091
+            "post": {
3092
+                "security": [
3093
+                    {
3094
+                        "token": []
3095
+                    }
3096
+                ],
3097
+                "description": "登录凭证删除",
3098
+                "consumes": [
3099
+                    "application/json"
3100
+                ],
3101
+                "produces": [
3102
+                    "application/json"
3103
+                ],
3104
+                "tags": [
3105
+                    "登录凭证"
3106
+                ],
3107
+                "summary": "登录凭证删除",
3108
+                "parameters": [
3109
+                    {
3110
+                        "description": "登录凭证信息",
3111
+                        "name": "body",
3112
+                        "in": "body",
3113
+                        "required": true,
3114
+                        "schema": {
3115
+                            "$ref": "#/definitions/model.UserToken"
3116
+                        }
3117
+                    }
3118
+                ],
3119
+                "responses": {
3120
+                    "200": {
3121
+                        "description": "OK",
3122
+                        "schema": {
3123
+                            "$ref": "#/definitions/response.Response"
3124
+                        }
3125
+                    },
3126
+                    "500": {
3127
+                        "description": "Internal Server Error",
3128
+                        "schema": {
3129
+                            "$ref": "#/definitions/response.Response"
3130
+                        }
3131
+                    }
3132
+                }
3133
+            }
3134
+        },
3135
+        "/admin/user_token/list": {
3136
+            "get": {
3137
+                "security": [
3138
+                    {
3139
+                        "token": []
3140
+                    }
3141
+                ],
3142
+                "description": "登录凭证列表",
3143
+                "consumes": [
3144
+                    "application/json"
3145
+                ],
3146
+                "produces": [
3147
+                    "application/json"
3148
+                ],
3149
+                "tags": [
3150
+                    "登录凭证"
3151
+                ],
3152
+                "summary": "登录凭证列表",
3153
+                "parameters": [
3154
+                    {
3155
+                        "type": "integer",
3156
+                        "description": "页码",
3157
+                        "name": "page",
3158
+                        "in": "query"
3159
+                    },
3160
+                    {
3161
+                        "type": "integer",
3162
+                        "description": "页大小",
3163
+                        "name": "page_size",
3164
+                        "in": "query"
3165
+                    },
3166
+                    {
3167
+                        "type": "integer",
3168
+                        "description": "用户ID",
3169
+                        "name": "user_id",
3170
+                        "in": "query"
3171
+                    }
3172
+                ],
3173
+                "responses": {
3174
+                    "200": {
3175
+                        "description": "OK",
3176
+                        "schema": {
3177
+                            "allOf": [
3178
+                                {
3179
+                                    "$ref": "#/definitions/response.Response"
3180
+                                },
3181
+                                {
3182
+                                    "type": "object",
3183
+                                    "properties": {
3184
+                                        "data": {
3185
+                                            "$ref": "#/definitions/model.UserTokenList"
3186
+                                        }
3187
+                                    }
3188
+                                }
3189
+                            ]
3190
+                        }
3191
+                    },
3192
+                    "500": {
3193
+                        "description": "Internal Server Error",
3194
+                        "schema": {
3195
+                            "$ref": "#/definitions/response.Response"
3196
+                        }
3197
+                    }
3198
+                }
3199
+            }
3083 3200
         }
3084 3201
     },
3085 3202
     "definitions": {
@@ -3794,6 +3911,9 @@
3794 3911
                 "user_id": {
3795 3912
                     "type": "integer"
3796 3913
                 },
3914
+                "user_token_id": {
3915
+                    "type": "integer"
3916
+                },
3797 3917
                 "uuid": {
3798 3918
                     "type": "string"
3799 3919
                 }
@@ -4061,6 +4181,49 @@
4061 4181
                 }
4062 4182
             }
4063 4183
         },
4184
+        "model.UserToken": {
4185
+            "type": "object",
4186
+            "properties": {
4187
+                "created_at": {
4188
+                    "type": "string"
4189
+                },
4190
+                "expired_at": {
4191
+                    "type": "integer"
4192
+                },
4193
+                "id": {
4194
+                    "type": "integer"
4195
+                },
4196
+                "token": {
4197
+                    "type": "string"
4198
+                },
4199
+                "updated_at": {
4200
+                    "type": "string"
4201
+                },
4202
+                "user_id": {
4203
+                    "type": "integer"
4204
+                }
4205
+            }
4206
+        },
4207
+        "model.UserTokenList": {
4208
+            "type": "object",
4209
+            "properties": {
4210
+                "list": {
4211
+                    "type": "array",
4212
+                    "items": {
4213
+                        "$ref": "#/definitions/model.UserToken"
4214
+                    }
4215
+                },
4216
+                "page": {
4217
+                    "type": "integer"
4218
+                },
4219
+                "page_size": {
4220
+                    "type": "integer"
4221
+                },
4222
+                "total": {
4223
+                    "type": "integer"
4224
+                }
4225
+            }
4226
+        },
4064 4227
         "response.ErrorResponse": {
4065 4228
             "type": "object",
4066 4229
             "properties": {

+ 104 - 3
docs/admin/admin_swagger.yaml

@@ -476,6 +476,8 @@ definitions:
476 476
         type: string
477 477
       user_id:
478 478
         type: integer
479
+      user_token_id:
480
+        type: integer
479 481
       uuid:
480 482
         type: string
481 483
     type: object
@@ -653,6 +655,34 @@ definitions:
653 655
       total:
654 656
         type: integer
655 657
     type: object
658
+  model.UserToken:
659
+    properties:
660
+      created_at:
661
+        type: string
662
+      expired_at:
663
+        type: integer
664
+      id:
665
+        type: integer
666
+      token:
667
+        type: string
668
+      updated_at:
669
+        type: string
670
+      user_id:
671
+        type: integer
672
+    type: object
673
+  model.UserTokenList:
674
+    properties:
675
+      list:
676
+        items:
677
+          $ref: '#/definitions/model.UserToken'
678
+        type: array
679
+      page:
680
+        type: integer
681
+      page_size:
682
+        type: integer
683
+      total:
684
+        type: integer
685
+    type: object
656 686
   response.ErrorResponse:
657 687
     properties:
658 688
       error:
@@ -1546,7 +1576,7 @@ paths:
1546 1576
       summary: 登录选项
1547 1577
       tags:
1548 1578
       - 登录
1549
-  /admin/loginLog/delete:
1579
+  /admin/login_log/delete:
1550 1580
     post:
1551 1581
       consumes:
1552 1582
       - application/json
@@ -1574,7 +1604,7 @@ paths:
1574 1604
       summary: 登录日志删除
1575 1605
       tags:
1576 1606
       - 登录日志
1577
-  /admin/loginLog/detail/{id}:
1607
+  /admin/login_log/detail/{id}:
1578 1608
     get:
1579 1609
       consumes:
1580 1610
       - application/json
@@ -1606,7 +1636,7 @@ paths:
1606 1636
       summary: 登录日志详情
1607 1637
       tags:
1608 1638
       - 登录日志
1609
-  /admin/loginLog/list:
1639
+  /admin/login_log/list:
1610 1640
     get:
1611 1641
       consumes:
1612 1642
       - application/json
@@ -1979,6 +2009,10 @@ paths:
1979 2009
         in: query
1980 2010
         name: hostname
1981 2011
         type: string
2012
+      - description: uuids 用逗号分隔
2013
+        in: query
2014
+        name: uuids
2015
+        type: string
1982 2016
       produces:
1983 2017
       - application/json
1984 2018
       responses:
@@ -2498,6 +2532,73 @@ paths:
2498 2532
       summary: 修改密码
2499 2533
       tags:
2500 2534
       - 用户
2535
+  /admin/user_token/delete:
2536
+    post:
2537
+      consumes:
2538
+      - application/json
2539
+      description: 登录凭证删除
2540
+      parameters:
2541
+      - description: 登录凭证信息
2542
+        in: body
2543
+        name: body
2544
+        required: true
2545
+        schema:
2546
+          $ref: '#/definitions/model.UserToken'
2547
+      produces:
2548
+      - application/json
2549
+      responses:
2550
+        "200":
2551
+          description: OK
2552
+          schema:
2553
+            $ref: '#/definitions/response.Response'
2554
+        "500":
2555
+          description: Internal Server Error
2556
+          schema:
2557
+            $ref: '#/definitions/response.Response'
2558
+      security:
2559
+      - token: []
2560
+      summary: 登录凭证删除
2561
+      tags:
2562
+      - 登录凭证
2563
+  /admin/user_token/list:
2564
+    get:
2565
+      consumes:
2566
+      - application/json
2567
+      description: 登录凭证列表
2568
+      parameters:
2569
+      - description: 页码
2570
+        in: query
2571
+        name: page
2572
+        type: integer
2573
+      - description: 页大小
2574
+        in: query
2575
+        name: page_size
2576
+        type: integer
2577
+      - description: 用户ID
2578
+        in: query
2579
+        name: user_id
2580
+        type: integer
2581
+      produces:
2582
+      - application/json
2583
+      responses:
2584
+        "200":
2585
+          description: OK
2586
+          schema:
2587
+            allOf:
2588
+            - $ref: '#/definitions/response.Response'
2589
+            - properties:
2590
+                data:
2591
+                  $ref: '#/definitions/model.UserTokenList'
2592
+              type: object
2593
+        "500":
2594
+          description: Internal Server Error
2595
+          schema:
2596
+            $ref: '#/definitions/response.Response'
2597
+      security:
2598
+      - token: []
2599
+      summary: 登录凭证列表
2600
+      tags:
2601
+      - 登录凭证
2501 2602
 securityDefinitions:
2502 2603
   BearerAuth:
2503 2604
     in: header

+ 2 - 2
http/controller/admin/login.go

@@ -53,10 +53,10 @@ func (ct *Login) Login(c *gin.Context) {
53 53
 
54 54
 	ut := service.AllService.UserService.Login(u, &model.LoginLog{
55 55
 		UserId:   u.Id,
56
-		Client:   "webadmin",
56
+		Client:   model.LoginLogClientWebAdmin,
57 57
 		Uuid:     "", //must be empty
58 58
 		Ip:       c.ClientIP(),
59
-		Type:     "account",
59
+		Type:     model.LoginLogTypeAccount,
60 60
 		Platform: f.Platform,
61 61
 	})
62 62
 

+ 3 - 3
http/controller/admin/loginLog.go

@@ -23,7 +23,7 @@ type LoginLog struct {
23 23
 // @Param id path int true "ID"
24 24
 // @Success 200 {object} response.Response{data=model.LoginLog}
25 25
 // @Failure 500 {object} response.Response
26
-// @Router /admin/loginLog/detail/{id} [get]
26
+// @Router /admin/login_log/detail/{id} [get]
27 27
 // @Security token
28 28
 func (ct *LoginLog) Detail(c *gin.Context) {
29 29
 	id := c.Param("id")
@@ -48,7 +48,7 @@ func (ct *LoginLog) Detail(c *gin.Context) {
48 48
 // @Param user_id query int false "用户ID"
49 49
 // @Success 200 {object} response.Response{data=model.LoginLogList}
50 50
 // @Failure 500 {object} response.Response
51
-// @Router /admin/loginLog/list [get]
51
+// @Router /admin/login_log/list [get]
52 52
 // @Security token
53 53
 func (ct *LoginLog) List(c *gin.Context) {
54 54
 	query := &admin.LoginLogQuery{}
@@ -78,7 +78,7 @@ func (ct *LoginLog) List(c *gin.Context) {
78 78
 // @Param body body model.LoginLog true "登录日志信息"
79 79
 // @Success 200 {object} response.Response
80 80
 // @Failure 500 {object} response.Response
81
-// @Router /admin/loginLog/delete [post]
81
+// @Router /admin/login_log/delete [post]
82 82
 // @Security token
83 83
 func (ct *LoginLog) Delete(c *gin.Context) {
84 84
 	f := &model.LoginLog{}

+ 4 - 0
http/controller/admin/peer.go

@@ -79,6 +79,7 @@ func (ct *Peer) Create(c *gin.Context) {
79 79
 // @Param time_ago query int false "时间"
80 80
 // @Param id query string false "ID"
81 81
 // @Param hostname query string false "主机名"
82
+// @Param uuids query string false "uuids 用逗号分隔"
82 83
 // @Success 200 {object} response.Response{data=model.PeerList}
83 84
 // @Failure 500 {object} response.Response
84 85
 // @Router /admin/peer/list [get]
@@ -104,6 +105,9 @@ func (ct *Peer) List(c *gin.Context) {
104 105
 		if query.Hostname != "" {
105 106
 			tx.Where("hostname like ?", "%"+query.Hostname+"%")
106 107
 		}
108
+		if query.Uuids != "" {
109
+			tx.Where("uuid in (?)", query.Uuids)
110
+		}
107 111
 	})
108 112
 	response.Success(c, res)
109 113
 }

+ 83 - 0
http/controller/admin/userToken.go

@@ -0,0 +1,83 @@
1
+package admin
2
+
3
+import (
4
+	"Gwen/global"
5
+	"Gwen/http/request/admin"
6
+	"Gwen/http/response"
7
+	"Gwen/model"
8
+	"Gwen/service"
9
+	"github.com/gin-gonic/gin"
10
+	"gorm.io/gorm"
11
+)
12
+
13
+type UserToken struct {
14
+}
15
+
16
+// List 列表
17
+// @Tags 登录凭证
18
+// @Summary 登录凭证列表
19
+// @Description 登录凭证列表
20
+// @Accept  json
21
+// @Produce  json
22
+// @Param page query int false "页码"
23
+// @Param page_size query int false "页大小"
24
+// @Param user_id query int false "用户ID"
25
+// @Success 200 {object} response.Response{data=model.UserTokenList}
26
+// @Failure 500 {object} response.Response
27
+// @Router /admin/user_token/list [get]
28
+// @Security token
29
+func (ct *UserToken) List(c *gin.Context) {
30
+	query := &admin.LoginTokenQuery{}
31
+	if err := c.ShouldBindQuery(query); err != nil {
32
+		response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
33
+		return
34
+	}
35
+	res := service.AllService.UserService.TokenList(query.Page, query.PageSize, func(tx *gorm.DB) {
36
+		if query.UserId > 0 {
37
+			tx.Where("user_id = ?", query.UserId)
38
+		}
39
+		tx.Order("id desc")
40
+	})
41
+	response.Success(c, res)
42
+}
43
+
44
+// Delete 删除
45
+// @Tags 登录凭证
46
+// @Summary 登录凭证删除
47
+// @Description 登录凭证删除
48
+// @Accept  json
49
+// @Produce  json
50
+// @Param body body model.UserToken true "登录凭证信息"
51
+// @Success 200 {object} response.Response
52
+// @Failure 500 {object} response.Response
53
+// @Router /admin/user_token/delete [post]
54
+// @Security token
55
+func (ct *UserToken) Delete(c *gin.Context) {
56
+	f := &model.UserToken{}
57
+	if err := c.ShouldBindJSON(f); err != nil {
58
+		response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
59
+		return
60
+	}
61
+	id := f.Id
62
+	errList := global.Validator.ValidVar(c, id, "required,gt=0")
63
+	if len(errList) > 0 {
64
+		response.Fail(c, 101, errList[0])
65
+		return
66
+	}
67
+	l := service.AllService.UserService.TokenInfoById(f.Id)
68
+	u := service.AllService.UserService.CurUser(c)
69
+	if !service.AllService.UserService.IsAdmin(u) && l.UserId != u.Id {
70
+		response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
71
+		return
72
+	}
73
+	if l.Id > 0 {
74
+		err := service.AllService.UserService.DeleteToken(l)
75
+		if err == nil {
76
+			response.Success(c, nil)
77
+			return
78
+		}
79
+		response.Fail(c, 101, err.Error())
80
+		return
81
+	}
82
+	response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
83
+}

+ 1 - 1
http/controller/api/login.go

@@ -54,7 +54,7 @@ func (l *Login) Login(c *gin.Context) {
54 54
 	//根据refer判断是webclient还是app
55 55
 	ref := c.GetHeader("referer")
56 56
 	if ref != "" {
57
-		f.DeviceInfo.Type = "webclient"
57
+		f.DeviceInfo.Type = model.LoginLogClientWeb
58 58
 	}
59 59
 
60 60
 	ut := service.AllService.UserService.Login(u, &model.LoginLog{

+ 4 - 0
http/request/admin/login.go

@@ -11,3 +11,7 @@ type LoginLogQuery struct {
11 11
 	IsMy   int `form:"is_my"`
12 12
 	PageQuery
13 13
 }
14
+type LoginTokenQuery struct {
15
+	UserId int `form:"user_id"`
16
+	PageQuery
17
+}

+ 1 - 0
http/request/admin/peer.go

@@ -38,6 +38,7 @@ type PeerQuery struct {
38 38
 	TimeAgo  int    `json:"time_ago" form:"time_ago"`
39 39
 	Id       string `json:"id" form:"id"`
40 40
 	Hostname string `json:"hostname" form:"hostname"`
41
+	Uuids    string `json:"uuids" form:"uuids"`
41 42
 }
42 43
 
43 44
 type SimpleDataQuery struct {

+ 7 - 0
http/router/admin.go

@@ -30,6 +30,7 @@ func Init(g *gin.Engine) {
30 30
 	AuditBind(adg)
31 31
 	AddressBookCollectionBind(adg)
32 32
 	AddressBookCollectionRuleBind(adg)
33
+	UserTokenBind(adg)
33 34
 	rs := &admin.Rustdesk{}
34 35
 	adg.GET("/server-config", rs.ServerConfig)
35 36
 	adg.GET("/app-config", rs.AppConfig)
@@ -181,6 +182,12 @@ func AddressBookCollectionRuleBind(rg *gin.RouterGroup) {
181 182
 		aR.POST("/delete", cont.Delete)
182 183
 	}
183 184
 }
185
+func UserTokenBind(rg *gin.RouterGroup) {
186
+	aR := rg.Group("/user_token").Use(middleware.AdminPrivilege())
187
+	cont := &admin.UserToken{}
188
+	aR.GET("/list", cont.List)
189
+	aR.POST("/delete", cont.Delete)
190
+}
184 191
 
185 192
 /*
186 193
 func FileBind(rg *gin.RouterGroup) {

+ 7 - 7
model/loginLog.go

@@ -2,13 +2,13 @@ package model
2 2
 
3 3
 type LoginLog struct {
4 4
 	IdModel
5
-	UserId   uint   `json:"user_id"`
6
-	Client   string `json:"client"` //webadmin,webclient,app,
7
-	Uuid     string `json:"uuid"`
8
-	Ip       string `json:"ip"`
9
-	Type     string `json:"type"`     //account,oauth
10
-	Platform string `json:"platform"` //windows,linux,mac,android,ios
11
-
5
+	UserId      uint   `json:"user_id" gorm:"default:0;not null;"`
6
+	Client      string `json:"client"` //webadmin,webclient,app,
7
+	Uuid        string `json:"uuid"`
8
+	Ip          string `json:"ip"`
9
+	Type        string `json:"type"`     //account,oauth
10
+	Platform    string `json:"platform"` //windows,linux,mac,android,ios
11
+	UserTokenId uint   `json:"user_token_id" gorm:"default:0;not null;"`
12 12
 	TimeModel
13 13
 }
14 14
 

+ 5 - 0
model/userToken.go

@@ -7,3 +7,8 @@ type UserToken struct {
7 7
 	ExpiredAt int64  `json:"expired_at" gorm:"default:0;not null;"`
8 8
 	TimeModel
9 9
 }
10
+
11
+type UserTokenList struct {
12
+	UserTokens []UserToken `json:"list"`
13
+	Pagination
14
+}

+ 25 - 0
service/user.go

@@ -70,6 +70,7 @@ func (us *UserService) Login(u *model.User, llog *model.LoginLog) *model.UserTok
70 70
 		ExpiredAt: time.Now().Add(time.Hour * 24 * 7).Unix(),
71 71
 	}
72 72
 	global.DB.Create(ut)
73
+	llog.UserTokenId = ut.UserId
73 74
 	global.DB.Create(llog)
74 75
 	if llog.Uuid != "" {
75 76
 		AllService.PeerService.UuidBindUserId(llog.Uuid, u.Id)
@@ -356,3 +357,27 @@ func (us *UserService) Register(username string, password string) *model.User {
356 357
 	global.DB.Create(u)
357 358
 	return u
358 359
 }
360
+
361
+func (us *UserService) TokenList(page uint, size uint, f func(tx *gorm.DB)) *model.UserTokenList {
362
+	res := &model.UserTokenList{}
363
+	res.Page = int64(page)
364
+	res.PageSize = int64(size)
365
+	tx := global.DB.Model(&model.UserToken{})
366
+	if f != nil {
367
+		f(tx)
368
+	}
369
+	tx.Count(&res.Total)
370
+	tx.Scopes(Paginate(page, size))
371
+	tx.Find(&res.UserTokens)
372
+	return res
373
+}
374
+
375
+func (us *UserService) TokenInfoById(id uint) *model.UserToken {
376
+	ut := &model.UserToken{}
377
+	global.DB.Where("id = ?", id).First(ut)
378
+	return ut
379
+}
380
+
381
+func (us *UserService) DeleteToken(l *model.UserToken) error {
382
+	return global.DB.Delete(l).Error
383
+}