mirror of
https://github.com/skyle1995/NetworkAuth.git
synced 2026-05-25 02:24:05 +08:00
Add application variables
This commit is contained in:
@@ -168,7 +168,7 @@ func APIUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
var req struct {
|
||||
ID uint `json:"id"`
|
||||
UUID string `json:"uuid"`
|
||||
Status int `json:"status"`
|
||||
SubmitAlgorithm int `json:"submit_algorithm"`
|
||||
ReturnAlgorithm int `json:"return_algorithm"`
|
||||
@@ -184,8 +184,8 @@ func APIUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// 验证必填字段
|
||||
if req.ID == 0 {
|
||||
http.Error(w, "接口ID不能为空", http.StatusBadRequest)
|
||||
if strings.TrimSpace(req.UUID) == "" {
|
||||
http.Error(w, "接口UUID不能为空", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ func APIUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 查找并更新API记录
|
||||
var api models.API
|
||||
if err := db.First(&api, req.ID).Error; err != nil {
|
||||
if err := db.Where("uuid = ?", strings.TrimSpace(req.UUID)).First(&api).Error; err != nil {
|
||||
http.Error(w, "接口不存在", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
429
controllers/admin/variable.go
Normal file
429
controllers/admin/variable.go
Normal file
@@ -0,0 +1,429 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"networkDev/database"
|
||||
"networkDev/models"
|
||||
"networkDev/utils"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// VariableFragmentHandler 变量列表页面片段处理器
|
||||
func VariableFragmentHandler(w http.ResponseWriter, r *http.Request) {
|
||||
utils.RenderTemplate(w, "variables", map[string]interface{}{
|
||||
"Title": "变量管理",
|
||||
})
|
||||
}
|
||||
|
||||
// VariableListHandler 变量列表API处理器
|
||||
func VariableListHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取分页参数
|
||||
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
|
||||
if limit <= 0 {
|
||||
limit = 10
|
||||
}
|
||||
|
||||
// 获取应用UUID参数(用于按应用筛选变量)
|
||||
appUUID := strings.TrimSpace(r.URL.Query().Get("app_uuid"))
|
||||
|
||||
// 获取别名搜索参数
|
||||
alias := strings.TrimSpace(r.URL.Query().Get("alias"))
|
||||
|
||||
// 构建查询
|
||||
db, err := database.GetDB()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to get database connection")
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 构建基础查询
|
||||
query := db.Model(&models.Variable{})
|
||||
|
||||
// 如果指定了应用UUID,则按应用筛选
|
||||
if appUUID != "" {
|
||||
query = query.Where("app_uuid = ?", appUUID)
|
||||
}
|
||||
|
||||
// 如果指定了别名搜索,则按别名模糊搜索
|
||||
if alias != "" {
|
||||
query = query.Where("alias LIKE ?", "%"+alias+"%")
|
||||
}
|
||||
|
||||
// 获取总数
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
logrus.WithError(err).Error("Failed to count variables")
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取分页数据
|
||||
var variables []models.Variable
|
||||
offset := (page - 1) * limit
|
||||
if err := query.Offset(offset).Limit(limit).Order("created_at DESC").Find(&variables).Error; err != nil {
|
||||
logrus.WithError(err).Error("Failed to fetch variables")
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取关联的应用信息
|
||||
var appUUIDs []string
|
||||
for _, variable := range variables {
|
||||
appUUIDs = append(appUUIDs, variable.AppUUID)
|
||||
}
|
||||
|
||||
var apps []models.App
|
||||
if len(appUUIDs) > 0 {
|
||||
if err := db.Where("uuid IN ?", appUUIDs).Find(&apps).Error; err != nil {
|
||||
logrus.WithError(err).Error("Failed to fetch related apps")
|
||||
}
|
||||
}
|
||||
|
||||
// 创建应用UUID到应用名称的映射
|
||||
appMap := make(map[string]string)
|
||||
for _, app := range apps {
|
||||
appMap[app.UUID] = app.Name
|
||||
}
|
||||
|
||||
// 构建响应数据
|
||||
type VariableResponse struct {
|
||||
ID uint `json:"id"`
|
||||
UUID string `json:"uuid"`
|
||||
Number string `json:"number"`
|
||||
AppUUID string `json:"app_uuid"`
|
||||
AppName string `json:"app_name"`
|
||||
Alias string `json:"alias"`
|
||||
Data string `json:"data"`
|
||||
Remark string `json:"remark"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
var responseData []VariableResponse
|
||||
for _, variable := range variables {
|
||||
appName := appMap[variable.AppUUID]
|
||||
if appName == "" {
|
||||
appName = "未知应用"
|
||||
}
|
||||
|
||||
responseData = append(responseData, VariableResponse{
|
||||
ID: variable.ID,
|
||||
UUID: variable.UUID,
|
||||
Number: variable.Number,
|
||||
AppUUID: variable.AppUUID,
|
||||
AppName: appName,
|
||||
Alias: variable.Alias,
|
||||
Data: variable.Data,
|
||||
Remark: variable.Remark,
|
||||
CreatedAt: variable.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: variable.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
response := map[string]interface{}{
|
||||
"code": 0,
|
||||
"msg": "success",
|
||||
"count": total,
|
||||
"data": responseData,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
utils.WriteJSONResponse(w, http.StatusOK, response)
|
||||
}
|
||||
|
||||
// VariableCreateHandler 新增变量API处理器
|
||||
func VariableCreateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
AppUUID string `json:"app_uuid"`
|
||||
Alias string `json:"alias"`
|
||||
Data string `json:"data"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
logrus.WithError(err).Error("Failed to decode JSON request")
|
||||
http.Error(w, "Invalid JSON", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 验证必填字段
|
||||
if strings.TrimSpace(req.AppUUID) == "" {
|
||||
http.Error(w, "应用UUID不能为空", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(req.Alias) == "" {
|
||||
http.Error(w, "变量别名不能为空", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 验证别名格式:必须以英文字母开头,只能包含数字和英文字母
|
||||
aliasPattern := regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9]*$`)
|
||||
if !aliasPattern.MatchString(req.Alias) {
|
||||
http.Error(w, "别名必须以英文字母开头,只能包含数字和英文字母", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
db, err := database.GetDB()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to get database connection")
|
||||
http.Error(w, "数据库连接失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 验证应用是否存在
|
||||
var app models.App
|
||||
if err := db.Where("uuid = ?", req.AppUUID).First(&app).Error; err != nil {
|
||||
http.Error(w, "应用不存在", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 创建变量
|
||||
variable := models.Variable{
|
||||
AppUUID: strings.TrimSpace(req.AppUUID),
|
||||
Alias: strings.TrimSpace(req.Alias),
|
||||
Data: req.Data,
|
||||
Remark: strings.TrimSpace(req.Remark),
|
||||
}
|
||||
|
||||
if err := db.Create(&variable).Error; err != nil {
|
||||
logrus.WithError(err).Error("Failed to create variable")
|
||||
http.Error(w, "创建变量失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response := map[string]interface{}{
|
||||
"code": 0,
|
||||
"msg": "创建成功",
|
||||
"data": variable,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
// VariableUpdateHandler 更新变量API处理器
|
||||
func VariableUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
UUID string `json:"uuid"`
|
||||
AppUUID string `json:"app_uuid"`
|
||||
Alias string `json:"alias"`
|
||||
Data string `json:"data"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "Invalid JSON", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 验证必填字段
|
||||
if strings.TrimSpace(req.UUID) == "" {
|
||||
http.Error(w, "变量UUID不能为空", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(req.AppUUID) == "" {
|
||||
http.Error(w, "应用UUID不能为空", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(req.Alias) == "" {
|
||||
http.Error(w, "变量别名不能为空", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 验证别名格式:必须以英文字母开头,只能包含数字和英文字母
|
||||
aliasPattern := regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9]*$`)
|
||||
if !aliasPattern.MatchString(req.Alias) {
|
||||
http.Error(w, "别名必须以英文字母开头,只能包含数字和英文字母", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
db, err := database.GetDB()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to get database connection")
|
||||
http.Error(w, "数据库连接失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 验证应用是否存在
|
||||
var app models.App
|
||||
if err := db.Where("uuid = ?", req.AppUUID).First(&app).Error; err != nil {
|
||||
http.Error(w, "应用不存在", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 通过uuid字段查找变量
|
||||
var variable models.Variable
|
||||
if err := db.Where("uuid = ?", strings.TrimSpace(req.UUID)).First(&variable).Error; err != nil {
|
||||
http.Error(w, "变量不存在", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
variable.AppUUID = strings.TrimSpace(req.AppUUID)
|
||||
variable.Alias = strings.TrimSpace(req.Alias)
|
||||
variable.Data = req.Data
|
||||
variable.Remark = strings.TrimSpace(req.Remark)
|
||||
|
||||
if err := db.Save(&variable).Error; err != nil {
|
||||
logrus.WithError(err).Error("Failed to update variable")
|
||||
http.Error(w, "更新变量失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response := map[string]interface{}{
|
||||
"code": 0,
|
||||
"msg": "更新成功",
|
||||
"data": variable,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
// VariableDeleteHandler 删除变量API处理器
|
||||
func VariableDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
ID uint `json:"id"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "Invalid JSON", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if req.ID == 0 {
|
||||
http.Error(w, "变量ID不能为空", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
db, err := database.GetDB()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to get database connection")
|
||||
http.Error(w, "数据库连接失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 删除变量
|
||||
if err := db.Delete(&models.Variable{}, req.ID).Error; err != nil {
|
||||
logrus.WithError(err).Error("Failed to delete variable")
|
||||
http.Error(w, "删除变量失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
logrus.WithField("variable_id", req.ID).Info("Successfully deleted variable")
|
||||
|
||||
response := map[string]interface{}{
|
||||
"code": 0,
|
||||
"msg": "删除成功",
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
// VariablesBatchDeleteHandler 批量删除变量API处理器
|
||||
func VariablesBatchDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
IDs []uint `json:"ids"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "Invalid JSON", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if len(req.IDs) == 0 {
|
||||
http.Error(w, "请选择要删除的变量", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
db, err := database.GetDB()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to get database connection")
|
||||
http.Error(w, "数据库连接失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 批量删除变量
|
||||
if err := db.Delete(&models.Variable{}, req.IDs).Error; err != nil {
|
||||
logrus.WithError(err).Error("Failed to batch delete variables")
|
||||
http.Error(w, "批量删除失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
logrus.WithField("variable_ids", req.IDs).Info("Successfully batch deleted variables")
|
||||
|
||||
response := map[string]interface{}{
|
||||
"code": 0,
|
||||
"msg": "批量删除成功",
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
// VariableGetAppsHandler 获取应用列表(用于筛选下拉框)
|
||||
func VariableGetAppsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
db, err := database.GetDB()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to get database connection")
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var apps []models.App
|
||||
if err := db.Select("uuid, name").Find(&apps).Error; err != nil {
|
||||
logrus.WithError(err).Error("Failed to fetch apps")
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response := map[string]interface{}{
|
||||
"code": 0,
|
||||
"msg": "success",
|
||||
"data": apps,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
utils.WriteJSONResponse(w, http.StatusOK, response)
|
||||
}
|
||||
Reference in New Issue
Block a user