diff --git a/device/devices.go b/device/devices.go new file mode 100644 index 0000000..d834745 --- /dev/null +++ b/device/devices.go @@ -0,0 +1,260 @@ +package device + +import ( + "goqs/controllers" + "goqs/dbsql" + "goqs/models" + "net/http" + "strconv" + + "github.com/gin-gonic/gin" + "github.com/spf13/cast" +) + +// @Tags 设备相关 /api/device/v1/ +// @Summary 查询设备 +// @Description 根据udid查询设备 +// @accept x-www-form-urlencoded +// @Param udid query string true "设备udid" +// @Success 200 {object} models.Response "返回设备信息" +// @Router /api/device/v1/get_device [get] +func GetDeviceByUdid(c *gin.Context) { + rsp := controllers.NewResponse() + + udid := c.DefaultQuery("udid", "") + if udid == "" { + rsp.Error("udid error") + c.JSON(http.StatusOK, rsp) + return + } + db, err := dbsql.GetConn(dbsql.DSN) + if rsp.CheckErr(err) { + c.JSON(http.StatusOK, rsp) + return + } + defer dbsql.Close(db) + + var device models.Device + + db.Model(&models.Device{}).Where("udid = ?", udid).Last(&device) + + if device.ID < 1 { + rsp.Error("没有找到该设备,udid-" + udid) + c.JSON(http.StatusOK, rsp) + return + } + + rsp.Success() + rsp.Data = device + c.JSON(http.StatusOK, rsp) +} + +// @Tags 设备相关 /api/device/v1/ +// @Summary 获取设备列表 +// @Description 获取设备列表 +// @accept x-www-form-urlencoded +// @Param page_size query int false "每页大小,默认为10" +// @Param page_index query int false "第几页,默认为第一页" +// @Success 200 {object} models.Response "返回设备列表信息" +// @Router /api/device/v1/list [get] +func GetDevices(c *gin.Context) { + rsp := controllers.NewResponse() + var p models.Page + + pageIndex, err := strconv.Atoi(c.DefaultQuery("page_index", "1")) + if rsp.CheckErr(err) { + c.JSON(http.StatusOK, rsp) + return + } + p.Index = pageIndex + pageSize, err := strconv.Atoi(c.DefaultQuery("page_size", "10")) + if rsp.CheckErr(err) { + c.JSON(http.StatusOK, rsp) + return + } + p.Size = pageSize + + db, err := dbsql.GetConn(dbsql.DSN) + if rsp.CheckErr(err) { + c.JSON(http.StatusOK, rsp) + return + } + defer dbsql.Close(db) + + var list []models.Device + + db = db.Model(&models.Device{}) + var count int64 + db = db.Count(&count) + db = dbsql.SetPageQuery(db, pageIndex, pageSize) + db.Where("is_del = 0").Order("id desc").Find(&list) + dbsql.Close(db) + + db, _ = dbsql.GetConn(dbsql.DSN) + + dbsql.Close(db) + + p.MaxPage = count/(int64(p.Size)+1) + 1 + p.List = list + p.Total = int(count) + + rsp.Success() + rsp.Data = p + c.JSON(http.StatusOK, rsp) +} + +// @Tags 设备相关 /api/device/v1/ +// @Summary 新建设备 +// @Description 新建设备,UDID唯一 +// @accept x-www-form-urlencoded +// @Param project formData string true "项目" +// @Param product_name formData string true "产品" +// @Param device_name formData string true "存放设备名字型号" +// @Param os formData string false "操作系统的版本" +// @Param udid formData string true "设备唯一udid" +// @Param platform formData string true "操作系统平台adr/ios" +// @Success 200 {object} models.Response "返回创建后的设备信息" +// @Router /api/device/v1/create [post] +func CreateDevice(c *gin.Context) { + rsp := controllers.NewResponse() + + db, err := dbsql.GetConn(dbsql.DSN) + if err != nil { + rsp.Error(err.Error()) + c.JSON(http.StatusOK, rsp) + } + defer dbsql.Close(db) + + var obj models.Device + obj.Project = c.PostForm("project") + obj.ProductName = c.PostForm("product_name") + obj.DeviceName = c.PostForm("device_name") + obj.OS = c.PostForm("os") + obj.Udid = c.PostForm("udid") + obj.Platform = c.PostForm("platform") + + // || obj.Creator == "" + if obj.Project == "" || obj.ProductName == "" || + obj.DeviceName == "" || obj.Platform == "" || + obj.Udid == "" { + rsp.Error("get formdata error") + rsp.Data = obj + c.JSON(http.StatusOK, rsp) + return + } + + var _device models.Device + db.Model(models.Device{}).Where("udid = ?", obj.Udid).Find(&_device) + if _device.ID > 0 { + rsp.Error("添加失败,该设备已存在") + c.JSON(http.StatusOK, rsp) + return + } + + db.Model(models.Device{}).Create(&obj) + if db.Error != nil { + rsp.Error(db.Error.Error()) + c.JSON(http.StatusOK, rsp) + } + + rsp.Success() + rsp.Data = obj + c.JSON(http.StatusOK, rsp) +} + +// @Tags 设备相关 /api/device/v1/ +// @Summary 更新设备 +// @Description 根据主键更新设备 +// @accept x-www-form-urlencoded +// @Param id formData string true "设备id,必传" +// @Param project formData string false "项目" +// @Param product_name formData string false "产品" +// @Param device_name formData string false "存放设备名字型号" +// @Param os formData string false "操作系统的版本" +// @Param udid formData string false "设备唯一udid" +// @Param platform formData string false "操作系统平台adr/ios" +// @Success 200 {object} models.Response "返回创建后的设备信息" +// @Router /api/device/v1/update [post] +func UpdateDevice(c *gin.Context) { + rsp := controllers.NewResponse() + + id := cast.ToInt(c.PostForm("id")) + if id == 0 { + rsp.Error("device.id error - " + c.PostForm("id")) + c.JSON(http.StatusOK, rsp) + } + + db, err := dbsql.GetConn(dbsql.DSN) + if err != nil { + rsp.Error(err.Error()) + c.JSON(http.StatusOK, rsp) + } + defer dbsql.Close(db) + + var obj models.Device + db.Model(models.Device{}).Where("id = ?", obj.ID).Find(&obj) + if obj.ID < 1 { + rsp.Error("修改失败,该设备不存在") + c.JSON(http.StatusOK, rsp) + return + } + if c.PostForm("project") != "" { + obj.Project = c.PostForm("project") + } + if c.PostForm("product_name") != "" { + obj.ProductName = c.PostForm("product_name") + } + if c.PostForm("device_name") != "" { + obj.DeviceName = c.PostForm("device_name") + } + if c.PostForm("os") != "" { + obj.OS = c.PostForm("os") + } + if c.PostForm("udid") != "" { + obj.Udid = c.PostForm("udid") + } + if c.PostForm("platform") != "" { + obj.Platform = c.PostForm("platform") + } + + db.Model(models.Device{}).Where("id = ?", obj.ID).Updates(&obj) + if db.Error != nil { + rsp.Error(db.Error.Error()) + c.JSON(http.StatusOK, rsp) + } + + rsp.Success() + rsp.Data = obj + c.JSON(http.StatusOK, rsp) +} + +// @Tags 设备相关 /api/device/v1/ +// @Summary 删除设备 +// @Description 根据主键软删除设备,is_del设为1 +// @accept x-www-form-urlencoded +// @Param id path string true "设备id,必传" +// @Success 200 {object} models.Response "返回创建后的设备信息" +// @Router /api/device/v1/delete/{id} [delete] +func DeleteDevice(c *gin.Context) { + rsp := controllers.NewResponse() + + id := cast.ToInt(c.Param("id")) + if id == 0 { + rsp.Error("device.id error - " + c.Param("id")) + c.JSON(http.StatusOK, rsp) + return + } + + db, err := dbsql.GetConn(dbsql.DSN) + if err != nil { + rsp.Error(err.Error()) + c.JSON(http.StatusOK, rsp) + return + } + defer dbsql.Close(db) + + db.Model(models.Device{}).Where("id = ?", id).Update("is_del", 1) + + rsp.Success() + c.JSON(http.StatusOK, rsp) +} diff --git a/docs/docs.go b/docs/docs.go index 007ea5a..0132441 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -23,6 +23,226 @@ var doc = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/api/device/v1/create": { + "post": { + "description": "新建设备,UDID唯一", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "设备相关 /api/device/v1/" + ], + "summary": "新建设备", + "parameters": [ + { + "type": "string", + "description": "项目", + "name": "project", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "产品", + "name": "product_name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "存放设备名字型号", + "name": "device_name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "操作系统的版本", + "name": "os", + "in": "formData" + }, + { + "type": "string", + "description": "设备唯一udid", + "name": "udid", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "操作系统平台adr/ios", + "name": "platform", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "返回创建后的设备信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/device/v1/delete/{id}": { + "delete": { + "description": "根据主键软删除设备,is_del设为1", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "设备相关 /api/device/v1/" + ], + "summary": "删除设备", + "parameters": [ + { + "type": "string", + "description": "设备id,必传", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "返回创建后的设备信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/device/v1/get_device": { + "get": { + "description": "根据udid查询设备", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "设备相关 /api/device/v1/" + ], + "summary": "查询设备", + "parameters": [ + { + "type": "string", + "description": "设备udid", + "name": "udid", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "返回设备信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/device/v1/list": { + "get": { + "description": "获取设备列表", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "设备相关 /api/device/v1/" + ], + "summary": "获取设备列表", + "parameters": [ + { + "type": "integer", + "description": "每页大小,默认为10", + "name": "page_size", + "in": "query" + }, + { + "type": "integer", + "description": "第几页,默认为第一页", + "name": "page_index", + "in": "query" + } + ], + "responses": { + "200": { + "description": "返回设备列表信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/device/v1/update": { + "post": { + "description": "根据主键更新设备", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "设备相关 /api/device/v1/" + ], + "summary": "更新设备", + "parameters": [ + { + "type": "string", + "description": "设备id,必传", + "name": "id", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "项目", + "name": "project", + "in": "formData" + }, + { + "type": "string", + "description": "产品", + "name": "product_name", + "in": "formData" + }, + { + "type": "string", + "description": "存放设备名字型号", + "name": "device_name", + "in": "formData" + }, + { + "type": "string", + "description": "操作系统的版本", + "name": "os", + "in": "formData" + }, + { + "type": "string", + "description": "设备唯一udid", + "name": "udid", + "in": "formData" + }, + { + "type": "string", + "description": "操作系统平台adr/ios", + "name": "platform", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "返回创建后的设备信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/api/monkey/v1/create_task": { "post": { "description": "新建Monkey任务,创建成功后将会发送指令到monkey服务,初始status为WAITTING-等待中", @@ -59,12 +279,6 @@ var doc = `{ "name": "launch_activity", "in": "formData" }, - { - "type": "string", - "description": "运行设备数,默认1台", - "name": "device_amount", - "in": "formData" - }, { "type": "string", "description": "平台adr/ios", @@ -260,6 +474,35 @@ var doc = `{ } } }, + "/api/monkey/v1/task/devices": { + "get": { + "description": "获取安卓设备列表", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "Monkey相关 /api/monkey/v1/" + ], + "summary": "获取设备列表", + "parameters": [ + { + "type": "string", + "description": "任务id", + "name": "task_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "返回设备信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/api/monkey/v1/task/pid": { "post": { "description": "上传进程id并关联到任务", @@ -440,6 +683,42 @@ var doc = `{ } } }, + "/api/monkey/v1/task/update_devices": { + "post": { + "description": "上报运行设备Udid,调用后追加到指定任务的设备字段中", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "Monkey相关 /api/monkey/v1/" + ], + "summary": "上报运行设备", + "parameters": [ + { + "type": "integer", + "description": "任务id", + "name": "task_id", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "设备udid", + "name": "udid", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "返回成功或失败", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/api/monkey/v1/tasks": { "get": { "description": "获取任务列表", diff --git a/docs/swagger.json b/docs/swagger.json index bfac20b..238bf5b 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -4,6 +4,226 @@ "contact": {} }, "paths": { + "/api/device/v1/create": { + "post": { + "description": "新建设备,UDID唯一", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "设备相关 /api/device/v1/" + ], + "summary": "新建设备", + "parameters": [ + { + "type": "string", + "description": "项目", + "name": "project", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "产品", + "name": "product_name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "存放设备名字型号", + "name": "device_name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "操作系统的版本", + "name": "os", + "in": "formData" + }, + { + "type": "string", + "description": "设备唯一udid", + "name": "udid", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "操作系统平台adr/ios", + "name": "platform", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "返回创建后的设备信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/device/v1/delete/{id}": { + "delete": { + "description": "根据主键软删除设备,is_del设为1", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "设备相关 /api/device/v1/" + ], + "summary": "删除设备", + "parameters": [ + { + "type": "string", + "description": "设备id,必传", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "返回创建后的设备信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/device/v1/get_device": { + "get": { + "description": "根据udid查询设备", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "设备相关 /api/device/v1/" + ], + "summary": "查询设备", + "parameters": [ + { + "type": "string", + "description": "设备udid", + "name": "udid", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "返回设备信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/device/v1/list": { + "get": { + "description": "获取设备列表", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "设备相关 /api/device/v1/" + ], + "summary": "获取设备列表", + "parameters": [ + { + "type": "integer", + "description": "每页大小,默认为10", + "name": "page_size", + "in": "query" + }, + { + "type": "integer", + "description": "第几页,默认为第一页", + "name": "page_index", + "in": "query" + } + ], + "responses": { + "200": { + "description": "返回设备列表信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/device/v1/update": { + "post": { + "description": "根据主键更新设备", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "设备相关 /api/device/v1/" + ], + "summary": "更新设备", + "parameters": [ + { + "type": "string", + "description": "设备id,必传", + "name": "id", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "项目", + "name": "project", + "in": "formData" + }, + { + "type": "string", + "description": "产品", + "name": "product_name", + "in": "formData" + }, + { + "type": "string", + "description": "存放设备名字型号", + "name": "device_name", + "in": "formData" + }, + { + "type": "string", + "description": "操作系统的版本", + "name": "os", + "in": "formData" + }, + { + "type": "string", + "description": "设备唯一udid", + "name": "udid", + "in": "formData" + }, + { + "type": "string", + "description": "操作系统平台adr/ios", + "name": "platform", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "返回创建后的设备信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/api/monkey/v1/create_task": { "post": { "description": "新建Monkey任务,创建成功后将会发送指令到monkey服务,初始status为WAITTING-等待中", @@ -40,12 +260,6 @@ "name": "launch_activity", "in": "formData" }, - { - "type": "string", - "description": "运行设备数,默认1台", - "name": "device_amount", - "in": "formData" - }, { "type": "string", "description": "平台adr/ios", @@ -241,6 +455,35 @@ } } }, + "/api/monkey/v1/task/devices": { + "get": { + "description": "获取安卓设备列表", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "Monkey相关 /api/monkey/v1/" + ], + "summary": "获取设备列表", + "parameters": [ + { + "type": "string", + "description": "任务id", + "name": "task_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "返回设备信息", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/api/monkey/v1/task/pid": { "post": { "description": "上传进程id并关联到任务", @@ -421,6 +664,42 @@ } } }, + "/api/monkey/v1/task/update_devices": { + "post": { + "description": "上报运行设备Udid,调用后追加到指定任务的设备字段中", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "tags": [ + "Monkey相关 /api/monkey/v1/" + ], + "summary": "上报运行设备", + "parameters": [ + { + "type": "integer", + "description": "任务id", + "name": "task_id", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "设备udid", + "name": "udid", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "返回成功或失败", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/api/monkey/v1/tasks": { "get": { "description": "获取任务列表", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index c8f87ae..5d4c510 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -10,6 +10,152 @@ definitions: info: contact: {} paths: + /api/device/v1/create: + post: + consumes: + - application/x-www-form-urlencoded + description: 新建设备,UDID唯一 + parameters: + - description: 项目 + in: formData + name: project + required: true + type: string + - description: 产品 + in: formData + name: product_name + required: true + type: string + - description: 存放设备名字型号 + in: formData + name: device_name + required: true + type: string + - description: 操作系统的版本 + in: formData + name: os + type: string + - description: 设备唯一udid + in: formData + name: udid + required: true + type: string + - description: 操作系统平台adr/ios + in: formData + name: platform + required: true + type: string + responses: + "200": + description: 返回创建后的设备信息 + schema: + $ref: '#/definitions/models.Response' + summary: 新建设备 + tags: + - 设备相关 /api/device/v1/ + /api/device/v1/delete/{id}: + delete: + consumes: + - application/x-www-form-urlencoded + description: 根据主键软删除设备,is_del设为1 + parameters: + - description: 设备id,必传 + in: path + name: id + required: true + type: string + responses: + "200": + description: 返回创建后的设备信息 + schema: + $ref: '#/definitions/models.Response' + summary: 删除设备 + tags: + - 设备相关 /api/device/v1/ + /api/device/v1/get_device: + get: + consumes: + - application/x-www-form-urlencoded + description: 根据udid查询设备 + parameters: + - description: 设备udid + in: query + name: udid + required: true + type: string + responses: + "200": + description: 返回设备信息 + schema: + $ref: '#/definitions/models.Response' + summary: 查询设备 + tags: + - 设备相关 /api/device/v1/ + /api/device/v1/list: + get: + consumes: + - application/x-www-form-urlencoded + description: 获取设备列表 + parameters: + - description: 每页大小,默认为10 + in: query + name: page_size + type: integer + - description: 第几页,默认为第一页 + in: query + name: page_index + type: integer + responses: + "200": + description: 返回设备列表信息 + schema: + $ref: '#/definitions/models.Response' + summary: 获取设备列表 + tags: + - 设备相关 /api/device/v1/ + /api/device/v1/update: + post: + consumes: + - application/x-www-form-urlencoded + description: 根据主键更新设备 + parameters: + - description: 设备id,必传 + in: formData + name: id + required: true + type: string + - description: 项目 + in: formData + name: project + type: string + - description: 产品 + in: formData + name: product_name + type: string + - description: 存放设备名字型号 + in: formData + name: device_name + type: string + - description: 操作系统的版本 + in: formData + name: os + type: string + - description: 设备唯一udid + in: formData + name: udid + type: string + - description: 操作系统平台adr/ios + in: formData + name: platform + type: string + responses: + "200": + description: 返回创建后的设备信息 + schema: + $ref: '#/definitions/models.Response' + summary: 更新设备 + tags: + - 设备相关 /api/device/v1/ /api/monkey/v1/create_task: post: consumes: @@ -33,10 +179,6 @@ paths: in: formData name: launch_activity type: string - - description: 运行设备数,默认1台 - in: formData - name: device_amount - type: string - description: 平台adr/ios in: formData name: platform @@ -166,6 +308,25 @@ paths: summary: 更新Monkey任务崩溃数量 tags: - Monkey相关 /api/monkey/v1/ + /api/monkey/v1/task/devices: + get: + consumes: + - application/x-www-form-urlencoded + description: 获取安卓设备列表 + parameters: + - description: 任务id + in: query + name: task_id + required: true + type: string + responses: + "200": + description: 返回设备信息 + schema: + $ref: '#/definitions/models.Response' + summary: 获取设备列表 + tags: + - Monkey相关 /api/monkey/v1/ /api/monkey/v1/task/pid: post: consumes: @@ -285,6 +446,30 @@ paths: summary: 停止monkey任务 tags: - Monkey相关 /api/monkey/v1/ + /api/monkey/v1/task/update_devices: + post: + consumes: + - application/x-www-form-urlencoded + description: 上报运行设备Udid,调用后追加到指定任务的设备字段中 + parameters: + - description: 任务id + in: formData + name: task_id + required: true + type: integer + - description: 设备udid + in: formData + name: udid + required: true + type: string + responses: + "200": + description: 返回成功或失败 + schema: + $ref: '#/definitions/models.Response' + summary: 上报运行设备 + tags: + - Monkey相关 /api/monkey/v1/ /api/monkey/v1/tasks: get: consumes: diff --git a/global/model.go b/global/model.go index 609bd2b..ae5f671 100644 --- a/global/model.go +++ b/global/model.go @@ -4,7 +4,7 @@ import "time" type MODEL struct { ID uint `json:"id" gorm:"column:id;type:int(11);primary_key;not null;autoIncrement;comment:主键"` - CreateTime time.Time `json:"create_time" gorm:"column:create_time;type:int(11);not null;autoCreateTime;comment:创建时间"` - UpdateTime time.Time `json:"update_time" gorm:"column:update_time;type:int(11);not null;autoUpdateTime;comment:更新时间"` + CreateTime time.Time `json:"create_time" gorm:"column:create_time;not null;autoCreateTime;comment:创建时间"` + UpdateTime time.Time `json:"update_time" gorm:"column:update_time;not null;autoUpdateTime;comment:更新时间"` IsDel int `json:"-" gorm:"column:is_del;type:int(1);not null;comment:是否已删除"` } diff --git a/main.go b/main.go index 723693a..79cebef 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "fmt" "goqs/controllers" "goqs/dbsql" + "goqs/device" "goqs/env" "goqs/monkey" "net/http" @@ -59,15 +60,24 @@ func main() { r.POST("/api/monkey/v1/task/result", monkey.UploadMonkeyResult) r.POST("/api/monkey/v1/task/stop", monkey.StopMonkeyTask) r.POST("/api/monkey/v1/task/pid", monkey.UpdatePids) + r.POST("/api/monkey/v1/task/update_devices", monkey.UpdateDevices) r.GET("/api/monkey/v1/task/result", monkey.GetMonkeyResult) r.POST("/api/monkey/v1/task/activity", monkey.UpdataActivity) r.GET("/api/monkey/v1/task/activity", monkey.GetMonkeyActivities) r.GET("/api/monkey/v1/tasks", monkey.GetTasks) r.GET("/api/monkey/v1/task", monkey.GetTaskById) + r.GET("/api/monkey/v1/task/devices", monkey.GetDevicesByTaskId) r.GET("/api/monkey/v1/devices", monkey.GetDevices) r.POST("/api/monkey/v1/task/crash_count", monkey.UpdateTaskCrashCount) r.PUT("/webdav/monkey/task/:id/:filename", monkey.TaskReport) + // device + r.GET("/api/device/v1/list", device.GetDevices) + r.GET("/api/device/v1/get_device", device.GetDeviceByUdid) + r.POST("/api/device/v1/create", device.CreateDevice) + r.POST("/api/device/v1/update", device.UpdateDevice) + r.DELETE("/api/device/v1/delete/:id", device.DeleteDevice) + r.Run(port) } diff --git a/models/monkey_app_pages.go b/models/monkey_app_pages.go new file mode 100644 index 0000000..a0687fd --- /dev/null +++ b/models/monkey_app_pages.go @@ -0,0 +1,15 @@ +package models + +import "goqs/global" + +type AppPage struct { + global.MODEL + PkgName string `json:"pkg_name" gorm:"column:pkg_name;type:varchar(255);not null;comment:应用包名"` + PageName string `json:"page_name" gorm:"column:page_name;type:varchar(255);not null;comment:应用页面名称"` + Pf string `json:"pf" gorm:"column:pf;type:varchar(255);not null;comment:应用包名"` + Count int `json:"count" gorm:"column:is_del;type:int(13);not null;comment:计数"` +} + +func (t *AppPage) TableName() string { + return "app_pages" +} diff --git a/models/monkey_device.go b/models/monkey_device.go index 402dbc6..ceb6c09 100644 --- a/models/monkey_device.go +++ b/models/monkey_device.go @@ -6,6 +6,8 @@ type Device struct { global.MODEL Project string `json:"project"` ProductName string `json:"product_name" gorm:"product_name"` + DeviceName string `json:"device_name" gorm:"device_name"` + OS string `json:"os" gorm:"os"` Udid string `json:"udid" gorm:"udid"` Status string `json:"status" gorm:"status"` Platform string `json:"platform" gorm:"platform"` diff --git a/models/monkey_task.go b/models/monkey_task.go index 9199f39..5cfc26c 100644 --- a/models/monkey_task.go +++ b/models/monkey_task.go @@ -6,7 +6,7 @@ type MonkeyTask struct { PackageURL string `json:"package_url" gorm:"column:package_url;type:varchar(255);not null;comment:应用包下载链接"` PackageName string `json:"package_name" gorm:"column:package_name;type:varchar(255);not null;comment:应用包名"` LaunchActivity string `json:"launch_activity" gorm:"column:launch_activity;type:varchar(255);comment:启动Activity页"` - DeviceAmount int `json:"device_amount" gorm:"column:device_amount;type:int(11);not null;comment:运行设备数"` + Devices string `json:"devices" gorm:"column:devices;type:varchar(255);comment:存放设备udid"` RunTime int `json:"run_time" gorm:"column:run_time;type:int(11);not null;comment:运行时间(秒)"` RunPids string `json:"run_pids" gorm:"column:run_pids;type:varchar(255);comment:数组形式存放运行进程pid"` Platform string `json:"platform" gorm:"column:platform;type:varchar(255);comment:平台adr/ios"` diff --git a/monkey/app_pages.go b/monkey/app_pages.go new file mode 100644 index 0000000..96e43dd --- /dev/null +++ b/monkey/app_pages.go @@ -0,0 +1,84 @@ +package monkey + +import ( + "goqs/controllers" + "goqs/dbsql" + "goqs/models" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/spf13/cast" +) + +// @Tags Monkey相关 /api/monkey/v1/ +// @Summary 上报Monkey应用页 +// @Description Android上报activity名 +// @accept x-www-form-urlencoded +// @Param task_id formData int true "任务id" +// @Param device_name formData string false "设备id" +// @Param activity_name formData string false "页面名称" +// @Success 200 {object} models.Response "返回更新后的任务信息" +// @Router /api/monkey/v1/task/activity [post] +func UploadPage(c *gin.Context) { + rsp := controllers.NewResponse() + + var res models.MonkeyActivity + res.TaskId = cast.ToInt(c.PostForm("task_id")) + if res.TaskId < 1 { + rsp.Error("task_id error:" + c.PostForm("task_id")) + c.JSON(http.StatusOK, rsp) + } + res.DeviceName = c.PostForm("device_name") + if res.DeviceName == "" { + rsp.Error("device_name不能为空") + c.JSON(http.StatusOK, rsp) + } + res.ActivityName = c.PostForm("activity_name") + if res.ActivityName == "" { + rsp.Error("activity_name不能为空") + c.JSON(http.StatusOK, rsp) + } + + db, err := dbsql.GetConn(dbsql.DSN) + if err != nil { + rsp.Error(err.Error()) + c.JSON(http.StatusOK, rsp) + return + } + defer dbsql.Close(db) + db.Create(&res) + if res.ID < 1 { + rsp.Error("记录activity应用页失败") + c.JSON(http.StatusOK, rsp) + return + } + + rsp.Success() + rsp.Data = res + c.JSON(http.StatusOK, rsp) +} + +// @Tags Monkey相关 /api/monkey/v1/ +// @Summary 获取覆盖页面列表 +// @Description 通过monkey任务id获取覆盖的活动页面 +// @accept x-www-form-urlencoded +// @Param task_id query int true "任务id" +// @Success 200 {object} models.Response "返回任务覆盖的活动页" +// @Router /api/monkey/v1/task/activity [get] +func GetPages(c *gin.Context) { + rsp := controllers.NewResponse() + + var list []models.MonkeyActivity + db, err := dbsql.GetConn(dbsql.DSN) + if err != nil { + rsp.Error(err.Error()) + c.JSON(http.StatusOK, rsp) + return + } + defer dbsql.Close(db) + db.Where("task_id = ?", c.Query("task_id")).Find(&list) + + rsp.Success() + rsp.Data = list + c.JSON(http.StatusOK, rsp) +} diff --git a/monkey/cli_adr.go b/monkey/cli_adr.go index b2fcd0f..79cc663 100644 --- a/monkey/cli_adr.go +++ b/monkey/cli_adr.go @@ -11,6 +11,10 @@ import ( "github.com/spf13/cast" ) +// func runUninstallCmd(package_name string)error{ +// cmd_content := "adb " + +// } + func runAndroidMonkeyCmd(task models.MonkeyTask) { cmd_content := "cd /home/app/aimonkey && nohup python3 main_run.py" + @@ -27,7 +31,6 @@ func runAndroidMonkeyCmd(task models.MonkeyTask) { } cmd_content += " -package " + task.PackageName + " -activity " + task.LaunchActivity + - " -count " + cast.ToString(task.DeviceAmount) + " -time " + cast.ToString(task.RunTime) + " >> /home/app/logs/task_output/task_" + cast.ToString(task.Id) + ".log 2>&1" diff --git a/monkey/device.go b/monkey/device.go index f04154d..acb20c2 100644 --- a/monkey/device.go +++ b/monkey/device.go @@ -2,7 +2,10 @@ package monkey import ( "goqs/controllers" + "goqs/dbsql" + "goqs/models" "net/http" + "strings" "github.com/gin-gonic/gin" ) @@ -29,3 +32,61 @@ func GetDevices(c *gin.Context) { rsp.Data = GetAndroidDevices() c.JSON(http.StatusOK, rsp) } + +// @Tags Monkey相关 /api/monkey/v1/ +// @Summary 获取设备列表 +// @Description 获取安卓设备列表 +// @accept x-www-form-urlencoded +// @Param task_id query string true "任务id" +// @Success 200 {object} models.Response "返回设备信息" +// @Router /api/monkey/v1/task/devices [get] +func GetDevicesByTaskId(c *gin.Context) { + rsp := controllers.NewResponse() + + task_id := c.DefaultQuery("task_id", "") + if task_id == "" { + rsp.Error("task_id为空") + c.JSON(http.StatusOK, rsp) + return + } + + db, err := dbsql.GetConn(dbsql.DSN) + if err != nil { + rsp.Error(err.Error()) + c.JSON(http.StatusOK, rsp) + return + } + defer dbsql.Close(db) + + var task models.MonkeyTask + db.Model(models.MonkeyTask{}).Where("id = ?", task_id).Last(&task) + + if task.Id < 1 { + rsp.Error("没有找到该Monkey任务,task_id=" + task_id) + c.JSON(http.StatusOK, rsp) + return + } + + var devices []models.Device + if strings.Contains(task.Devices, ",") { + list := strings.Split(task.Devices, ",") + for _, v := range list { + var d models.Device + db.Model(models.Device{}).Where("udid = ?", v).Last(&d) + if d.ID > 0 { + devices = append(devices, d) + } + } + } else { + var d models.Device + db.Model(models.Device{}).Where("udid = ?", task.Devices).Last(&d) + if d.ID > 0 { + devices = append(devices, d) + } + } + + rsp.Success() + rsp.Data = devices + c.JSON(http.StatusOK, rsp) + +} diff --git a/monkey/task.go b/monkey/task.go index d3267bb..36ce444 100644 --- a/monkey/task.go +++ b/monkey/task.go @@ -7,6 +7,7 @@ import ( "goqs/models" "net/http" "strconv" + "strings" "github.com/gin-gonic/gin" "github.com/spf13/cast" @@ -20,7 +21,6 @@ import ( // @Param package_url formData string false "测试包下载链接" // @Param package_name formData string true "应用包名" // @Param launch_activity formData string false "启动activity页" -// @Param device_amount formData string false "运行设备数,默认1台" // @Param platform formData string true "平台adr/ios" // @Param run_time formData string false "运行时间(s),默认两小时(7200s)" // @Param creator formData string false "任务创建者" @@ -42,7 +42,6 @@ func CreateTask(c *gin.Context) { task.PackageURL = c.PostForm("package_url") task.PackageName = c.PostForm("package_name") task.LaunchActivity = c.PostForm("launch_activity") - task.DeviceAmount = cast.ToInt(c.DefaultPostForm("device_amount", "1")) task.Platform = c.PostForm("platform") task.RunTime = cast.ToInt(c.DefaultPostForm("run_time", "7200")) task.Creator = c.PostForm("creator") @@ -50,7 +49,7 @@ func CreateTask(c *gin.Context) { // || task.Creator == "" if task.PackageName == "" || task.LaunchActivity == "" || - task.DeviceAmount <= 0 || task.Platform == "" || + task.Platform == "" || task.RunTime <= 10 { rsp.Error("get formdata error") rsp.Data = task @@ -216,10 +215,11 @@ func GetTasks(c *gin.Context) { var list []models.MonkeyTask db = db.Model(&models.MonkeyTask{}) - var count int64 - db = db.Count(&count) + var lenght int64 + db = db.Where("is_del = 0").Count(&lenght) db = dbsql.SetPageQuery(db, pageIndex, pageSize) db.Order("id desc").Find(&list) + // lenght = len(list) dbsql.Close(db) db, _ = dbsql.GetConn(dbsql.DSN) @@ -246,9 +246,13 @@ func GetTasks(c *gin.Context) { } dbsql.Close(db) - p.MaxPage = count/(int64(p.Size)+1) + 1 + if p.Size >= int(lenght) { + p.MaxPage = 1 + } else { + p.MaxPage = int64(lenght/int64(p.Size) + 1) + } p.List = list - p.Total = int(count) + p.Total = int(lenght) rsp.Success() rsp.Data = p @@ -275,7 +279,7 @@ func GetTaskById(c *gin.Context) { var data models.MonkeyTask db = db.Model(&models.MonkeyTask{}) - db.Model(models.MonkeyActivity{}).Where("id = ?", c.DefaultQuery("id", "0")).Last(&data) + db.Model(models.MonkeyTask{}).Where("id = ?", c.DefaultQuery("id", "0")).Last(&data) dbsql.Close(db) db, _ = dbsql.GetConn(dbsql.DSN) @@ -358,6 +362,55 @@ func UpdatePids(c *gin.Context) { c.JSON(http.StatusOK, rsp) } +// @Tags Monkey相关 /api/monkey/v1/ +// @Summary 上报运行设备 +// @Description 上报运行设备Udid,调用后追加到指定任务的设备字段中 +// @accept x-www-form-urlencoded +// @Param task_id formData int true "任务id" +// @Param udid formData string true "设备udid" +// @Success 200 {object} models.Response "返回成功或失败" +// @Router /api/monkey/v1/task/update_devices [post] +func UpdateDevices(c *gin.Context) { + var rsp models.Response + + task_id := cast.ToInt(c.PostForm("task_id")) + if task_id < 1 { + rsp.Error("task_id获取失败") + c.JSON(http.StatusOK, rsp) + return + } + udid := c.PostForm("udid") + if udid == "" { + rsp.Error("pid获取失败") + c.JSON(http.StatusOK, rsp) + return + } + + db, err := dbsql.GetConn(dbsql.DSN) + if rsp.CheckErr(err) { + c.JSON(http.StatusOK, rsp) + return + } + defer dbsql.Close(db) + + var data models.MonkeyTask + + db = db.Model(&models.MonkeyTask{}) + db.Model(models.MonkeyTask{}).Where("id = ?", task_id).Last(&data) + + // 处理 + if strings.Contains(data.Devices, ",") || len(data.Devices) > 0 { + data.Devices += "," + udid + } else { + data.Devices = udid + } + db.Model(models.MonkeyTask{}).Where("id = ?", task_id).Update("devices", data.Devices) + + rsp.Success() + rsp.Data = data + c.JSON(http.StatusOK, rsp) +} + // @Tags Monkey相关 /api/monkey/v1/ // @Summary 停止monkey任务 // @Description 停止monkey任务,杀死所有关联任务的进程id