gujiheimao 1 rok temu
rodzic
commit
02366c8eb1

+ 338 - 0
router/ARKConfigRouter.go

@@ -2,15 +2,41 @@ package router
 
 import (
 	"ARKItems/entity"
+	"ARKItems/entity/ark"
 	"ARKItems/util"
+	"encoding/json"
 	"fmt"
 	"github.com/gin-gonic/gin"
+	"github.com/spf13/cast"
+	"net/http"
 )
 
 func ARKConfigRouter(api *gin.RouterGroup) {
 	api.GET("/messages", GetMessages)
+
 	api.GET("/timedPointsReward", GetTimedPointsReward)
+
 	api.POST("/timedPointsReward/group", SaveGroup)
+	api.PUT("/timedPointsReward/group", UpdateGroup)
+	api.DELETE("/timedPointsReward/group", DeleteGroup)
+
+	api.GET("/general", GetGeneral)
+	api.PUT("/general", UpdateGeneral)
+
+	api.GET("/kit", GetKits)
+	api.POST("/kit", SaveKit)
+	api.PUT("/kit", UpdateKit)
+	api.DELETE("/kit", DeleteKit)
+
+	api.GET("/shopItem", GetShopItem)
+	api.POST("/shopItem", SaveShopItem)
+	api.PUT("/shopItem", UpdateShopItem)
+	api.DELETE("/shopItem", DeleteShopItem)
+
+	api.GET("/sellItem", GetSellItem)
+	api.POST("/sellItem", SaveSellItem)
+	api.PUT("/sellItem", UpdateSellItem)
+	api.DELETE("/sellItem", DeleteSellItem)
 }
 
 func GetMessages(c *gin.Context) {
@@ -19,6 +45,61 @@ func GetMessages(c *gin.Context) {
 func GetTimedPointsReward(c *gin.Context) {
 	c.JSON(200, CreateResultData(ARKConfig.General.TimedPointsReward))
 }
+func GetGeneral(c *gin.Context) {
+	marshal, err := json.Marshal(ARKConfig.General)
+	if err != nil {
+		c.JSON(200, CreateResultError(400, "参数错误"))
+		return
+	}
+	m := make(map[string]interface{})
+	json.Unmarshal(marshal, &m)
+	delete(m, "Groups")
+	c.JSON(200, CreateResultData(m))
+}
+
+func UpdateGeneral(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	g, err := param("group")
+	if err != nil {
+		c.JSON(200, CreateResultError(400, "参数错误"))
+		return
+	}
+	var General = ark.General{}
+	err = util.DataToObject(g, &General)
+	if ARKConfig.General.UseOriginalTradeCommandWithUI != General.UseOriginalTradeCommandWithUI {
+		ARKConfig.General.UseOriginalTradeCommandWithUI = General.UseOriginalTradeCommandWithUI
+	}
+	if ARKConfig.General.CryoLimitedTime != General.CryoLimitedTime {
+		ARKConfig.General.CryoLimitedTime = General.CryoLimitedTime
+	}
+	if ARKConfig.General.GiveDinosInCryopods != General.GiveDinosInCryopods {
+		ARKConfig.General.GiveDinosInCryopods = General.GiveDinosInCryopods
+	}
+	if ARKConfig.General.UseSoulTraps != General.UseSoulTraps {
+		ARKConfig.General.UseSoulTraps = General.UseSoulTraps
+	}
+	if ARKConfig.General.ItemsPerPage != General.ItemsPerPage {
+		ARKConfig.General.ItemsPerPage = General.ItemsPerPage
+	}
+	if ARKConfig.General.ShopDisplayTime != General.ShopDisplayTime {
+		ARKConfig.General.ShopDisplayTime = General.ShopDisplayTime
+	}
+	if ARKConfig.General.ShopTextSize != General.ShopTextSize {
+		ARKConfig.General.ShopTextSize = General.ShopTextSize
+	}
+	if ARKConfig.General.DefaultKit != General.DefaultKit {
+		ARKConfig.General.DefaultKit = General.DefaultKit
+	}
+	if ARKConfig.General.ShopDisplayTime != General.ShopDisplayTime {
+		ARKConfig.General.ShopDisplayTime = General.ShopDisplayTime
+	}
+	if ARKConfig.General.DbPathOverride != General.DbPathOverride {
+		ARKConfig.General.DbPathOverride = General.DbPathOverride
+	}
+	c.JSON(200, CreateResult())
+}
+
+//-----------------组修改----------------------
 
 // SaveGroup 添加VIP
 func SaveGroup(c *gin.Context) {
@@ -31,10 +112,267 @@ func SaveGroup(c *gin.Context) {
 	var Group = entity.Group{}
 	err = util.DataToObject(g, &Group)
 	fmt.Println(g, Group)
+	ARKConfig.General.TimedPointsReward.Groups[Group.Name] = ark.Group{Amount: Group.Amount}
 	c.JSON(200, CreateResult())
 }
 
 // UpdateGroup 修改VIP
 func UpdateGroup(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	g, err := param("group")
+	if err != nil {
+		c.JSON(200, CreateResultError(400, "参数错误"))
+		return
+	}
+	var Group = entity.Group{}
+	err = util.DataToObject(g, &Group)
+	if Group.Name == "" {
+		c.JSON(200, CreateResultError(400, "VIP名称不能为空"))
+		return
+	}
+	_, ok := ARKConfig.General.TimedPointsReward.Groups[Group.Name]
+	if ok {
+		ARKConfig.General.TimedPointsReward.Groups[Group.Name] = ark.Group{Amount: Group.Amount}
+		c.JSON(200, CreateResult())
+		return
+	}
+	c.JSON(200, CreateResultError(400, "VIP组名不存在"))
+}
+
+// DeleteGroup 修改VIP
+func DeleteGroup(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	name, err := param("groupName")
+	if err != nil {
+		c.JSON(200, CreateResultError(400, "参数错误"))
+		return
+	}
+
+	if cast.ToString(name) == "" {
+		c.JSON(200, CreateResultError(400, "VIP名称不能为空"))
+		return
+	}
+	_, ok := ARKConfig.General.TimedPointsReward.Groups[cast.ToString(name)]
+	if ok {
+		//删除一个元素
+		delete(ARKConfig.General.TimedPointsReward.Groups, cast.ToString(name))
+		c.JSON(200, CreateResult())
+		return
+	}
+	c.JSON(200, CreateResultError(400, "VIP组名不存在"))
+}
+
+//==================礼包==========================
+
+func GetKits(c *gin.Context) {
+	c.JSON(200, CreateResultData(ARKConfig.Kits))
+}
+func SaveKit(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	g, err := param("kit")
+	if err != nil {
+		c.JSON(200, CreateResultError(400, "参数错误"))
+		return
+	}
+	var Kit = ark.Kit{}
+	err = util.DataToObject(g, &Kit)
+	if Kit.Description == "" || Kit.Price == 0 || Kit.DefaultAmount == 0 {
+		c.JSON(200, CreateResultError(400, "礼包描述不能为空,价格,数量不能为0"))
+		return
+	}
+	ARKConfig.Kits[Kit.Description] = Kit
+}
+func UpdateKit(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	g, err := param("kit")
+	if err != nil {
+		c.JSON(200, CreateResultError(400, "参数错误"))
+		return
+	}
+	var Kit = ark.Kit{}
+	err = util.DataToObject(g, &Kit)
+	if Kit.Description == "" {
+		c.JSON(200, CreateResultError(400, "礼包描述不能为空"))
+	}
+	_, ok := ARKConfig.Kits[Kit.Description]
+	if ok {
+		if Kit.Price == 0 || Kit.DefaultAmount == 0 {
+			c.JSON(200, CreateResultError(400, "价格,数量不能为0"))
+			return
+		}
+		ARKConfig.Kits[Kit.Description] = Kit
+		c.JSON(200, CreateResult())
+		return
+	}
+	c.JSON(200, CreateResultError(400, "礼包不存在"))
+}
+func DeleteKit(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	name, err := param("kitName")
+	if err != nil {
+		c.JSON(200, CreateResultError(400, "参数错误"))
+		return
+	}
+
+	if cast.ToString(name) == "" {
+		c.JSON(200, CreateResultError(400, "礼包名称不能为空"))
+		return
+	}
+	_, ok := ARKConfig.Kits[cast.ToString(name)]
+	if ok {
+		//删除一个元素
+		delete(ARKConfig.Kits, cast.ToString(name))
+		c.JSON(200, CreateResult())
+		return
+	}
+	c.JSON(200, CreateResultError(400, "礼包不存在"))
+}
 
+//====================商店==========================
+
+func GetShopItem(c *gin.Context) {
+	c.JSON(200, CreateResultData(ARKConfig.ShopItems))
+}
+
+func SaveShopItem(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	g, err := param("shopItem")
+	if err != nil {
+		c.JSON(200, CreateResultError(400, "参数错误"))
+		return
+	}
+	var ShopItem = ark.ShopItem{}
+	err = util.DataToObject(g, &ShopItem)
+	if ShopItem.Description == "" || ShopItem.Price == 0 || ShopItem.Type == "" {
+		c.JSON(200, CreateResultError(400, "商店描述,价格,类型不能为空,为0"))
+		return
+	}
+	_, ok := ARKConfig.ShopItems[ShopItem.Description]
+	if ok {
+		c.JSON(200, CreateResultError(400, "商品名已存在"))
+		return
+	}
+	ARKConfig.ShopItems[ShopItem.Description] = ShopItem
+}
+
+func UpdateShopItem(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	g, err := param("shopItem")
+	if err != nil {
+		c.JSON(200, CreateResultError(400, "参数错误"))
+		return
+	}
+	var ShopItem = ark.ShopItem{}
+	err = util.DataToObject(g, &ShopItem)
+	if ShopItem.Description == "" {
+		c.JSON(200, CreateResultError(400, "商店名不能为空"))
+		return
+	}
+	_, ok := ARKConfig.ShopItems[ShopItem.Description]
+	if ok {
+		if ShopItem.Price == 0 || ShopItem.Type == "" {
+			c.JSON(200, CreateResultError(400, "价格,类型不能为空,为0"))
+			return
+		}
+		ARKConfig.ShopItems[ShopItem.Description] = ShopItem
+		c.JSON(200, CreateResult())
+		return
+	}
+	c.JSON(200, CreateResultError(400, "商品名不存在"))
+}
+
+func DeleteShopItem(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	name, err := param("shopItemName")
+	if err != nil {
+		c.JSON(200, CreateResultError(400, "参数错误"))
+		return
+	}
+	if cast.ToString(name) == "" {
+		c.JSON(200, CreateResultError(400, "商店名不能为空"))
+		return
+	}
+	_, ok := ARKConfig.ShopItems[cast.ToString(name)]
+	if ok {
+		//删除一个元素
+		delete(ARKConfig.ShopItems, cast.ToString(name))
+		c.JSON(200, CreateResult())
+		return
+	}
+	c.JSON(200, CreateResultError(400, "商店名不存在"))
+}
+
+//========================回收==========================
+
+func GetSellItem(c *gin.Context) {
+	c.JSON(http.StatusOK, CreateResultData(ARKConfig.SellItems))
+}
+
+func SaveSellItem(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	g, err := param("sellItem")
+	if err != nil {
+		c.JSON(http.StatusBadRequest, CreateResultError(400, "参数错误"))
+		return
+	}
+	var sellItem ark.SellItem
+	err = util.DataToObject(g, &sellItem)
+	if sellItem.Description == "" || sellItem.Price == 0 || sellItem.Type == "" {
+		c.JSON(http.StatusBadRequest, CreateResultError(400, "描述、价格、类型不能为空或为0"))
+		return
+	}
+	_, ok := ARKConfig.SellItems[sellItem.Description]
+	if ok {
+		c.JSON(http.StatusBadRequest, CreateResultError(400, "商品名已存在"))
+		return
+	}
+	ARKConfig.SellItems[sellItem.Description] = sellItem
+	c.JSON(http.StatusOK, CreateResult())
+}
+
+func UpdateSellItem(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	g, err := param("sellItem")
+	if err != nil {
+		c.JSON(http.StatusBadRequest, CreateResultError(400, "参数错误"))
+		return
+	}
+	var sellItem ark.SellItem
+	err = util.DataToObject(g, &sellItem)
+	if sellItem.Description == "" {
+		c.JSON(http.StatusBadRequest, CreateResultError(400, "商品描述不能为空"))
+		return
+	}
+	_, ok := ARKConfig.SellItems[sellItem.Description]
+	if ok {
+		if sellItem.Price == 0 || sellItem.Type == "" {
+			c.JSON(http.StatusBadRequest, CreateResultError(400, "价格、类型不能为空或为0"))
+			return
+		}
+		ARKConfig.SellItems[sellItem.Description] = sellItem
+		c.JSON(http.StatusOK, CreateResult())
+		return
+	}
+	c.JSON(http.StatusBadRequest, CreateResultError(400, "商品名不存在"))
+}
+
+func DeleteSellItem(c *gin.Context) {
+	param := util.GetJsonAnyParam(c)
+	name, err := param("sellItemName")
+	if err != nil {
+		c.JSON(http.StatusBadRequest, CreateResultError(400, "参数错误"))
+		return
+	}
+	if cast.ToString(name) == "" {
+		c.JSON(http.StatusBadRequest, CreateResultError(400, "商品描述不能为空"))
+		return
+	}
+	_, ok := ARKConfig.SellItems[cast.ToString(name)]
+	if ok {
+		// 删除一个元素
+		delete(ARKConfig.SellItems, cast.ToString(name))
+		c.JSON(http.StatusOK, CreateResult())
+		return
+	}
+	c.JSON(http.StatusBadRequest, CreateResultError(400, "商品名不存在"))
 }

+ 74 - 0
ui/src/api/ConfigFile.ts

@@ -120,12 +120,78 @@ export function GetArkConfig(): Promise<ResponseData<Messages>> {
     return GetDataByPath("/ark/messages", {}, true) as Promise<ResponseData<Messages>>;
 }
 
+//type General struct {
+// 	Discord                       Discord           `json:"Discord"`           //联系方式
+// 	TimedPointsReward             TimedPointsReward `json:"TimedPointsReward"` //计时积分奖励
+// 	UseOriginalTradeCommandWithUI bool              `json:"UseOriginalTradeCommandWithUI"`
+// 	ItemsPerPage                  int               `json:"ItemsPerPage"`        //每页项目数
+// 	ShopDisplayTime               float64           `json:"ShopDisplayTime"`     //店铺展示时间
+// 	ShopTextSize                  float64           `json:"ShopTextSize"`        //店铺文字大小
+// 	DbPathOverride                string            `json:"DbPathOverride"`      //db文件位置
+// 	DefaultKit                    string            `json:"DefaultKit"`          //默认礼包?
+// 	GiveDinosInCryopods           bool              `json:"GiveDinosInCryopods"` //在低温仓给恐龙
+// 	UseSoulTraps                  bool              `json:"UseSoulTraps"`        //使用灵魂陷阱?
+// 	CryoLimitedTime               bool              `json:"CryoLimitedTime"`     //低温仓有限时间?
+
+export class General {
+    Discord: Discord
+    TimedPointsReward: TimedPointsReward
+    UseOriginalTradeCommandWithUI: boolean
+    ItemsPerPage: number
+    ShopDisplayTime: number
+    ShopTextSize: number
+    DbPathOverride: string
+    DefaultKit: string
+    GiveDinosInCryopods: boolean
+    UseSoulTraps: boolean
+    CryoLimitedTime: boolean
+
+    static Create(): General {
+        return new General(Discord.Create(), TimedPointsReward.Create(), false, 0, 0, 0, "", "", false, false, false);
+    }
+
+    constructor(Discord: Discord, TimedPointsReward: TimedPointsReward, UseOriginalTradeCommandWithUI: boolean, ItemsPerPage: number, ShopDisplayTime: number, ShopTextSize: number, DbPathOverride: string, DefaultKit: string, GiveDinosInCryopods: boolean, UseSoulTraps: boolean, CryoLimitedTime: boolean) {
+        this.Discord = Discord;
+        this.TimedPointsReward = TimedPointsReward;
+        this.UseOriginalTradeCommandWithUI = UseOriginalTradeCommandWithUI;
+        this.ItemsPerPage = ItemsPerPage;
+        this.ShopDisplayTime = ShopDisplayTime;
+        this.ShopTextSize = ShopTextSize;
+        this.DbPathOverride = DbPathOverride;
+        this.DefaultKit = DefaultKit;
+        this.GiveDinosInCryopods = GiveDinosInCryopods;
+        this.UseSoulTraps = UseSoulTraps;
+        this.CryoLimitedTime = CryoLimitedTime;
+    }
+}
+
+export class Discord {
+    Enabled: boolean     //启用
+    SenderName: string  //发件人
+    URL: string         //地址
+
+    static Create(): Discord {
+        return new Discord(false, "", "");
+    }
+
+    constructor(Enabled: boolean, SenderName: string, URL: string) {
+        this.Enabled = Enabled;
+        this.SenderName = SenderName;
+        this.URL = URL;
+    }
+}
+
+
 export class TimedPointsReward {
     Enabled: boolean
     Interval: number
     StackRewards: boolean
     Groups: Map<string, TimedPointsRewardAmount>
 
+    static Create(): TimedPointsReward {
+        return new TimedPointsReward(false, 0, false, new Map<string, TimedPointsRewardAmount>());
+    }
+
     constructor(Enabled: boolean, Interval: number, StackRewards: boolean, Groups: Map<string, TimedPointsRewardAmount>) {
         this.Enabled = Enabled;
         this.Interval = Interval;
@@ -165,3 +231,11 @@ export function UpdateGroup(oldGroup: Group, newGroup: Group) {
         oldGroup: oldGroup, newGroup: newGroup
     }, true)
 }
+
+export function GetGeneral(): Promise<ResponseData<General>> {
+    return GetDataByPath("/ark/general", {}, true) as Promise<ResponseData<General>>;
+}
+export function UpdateGeneral(general: General) {
+    return PutDataByPath("/ark/general", general, true)
+}
+

+ 1 - 1
ui/src/page/Login.vue

@@ -9,7 +9,7 @@
           <el-input :prefix-icon="UserFilled" v-model="loginForm.username" placeholder="用户名"></el-input>
         </el-form-item>
         <el-form-item prop="password" label="密码">
-          <el-input :prefix-icon="Lock" v-model="loginForm.password" placeholder="密码"/>
+          <el-input :prefix-icon="Lock" type="password" v-model="loginForm.password" show-password placeholder="密码"/>
         </el-form-item>
         <div class="dialog-footer" style="display: flex;justify-content: center">
           <el-button type="primary" @click="onSubmit">登录</el-button>

+ 77 - 0
ui/src/page/back/GeneralView.vue

@@ -0,0 +1,77 @@
+<template>
+  <div>
+    <el-row>
+      <el-col :span="4"></el-col>
+      <el-col :span="8">
+        <el-form v-model="generalForm" label-width="155px" append-to-body>
+          <el-form-item>
+            <h2 style="margin-bottom: 10px">联系方式</h2>
+          </el-form-item>
+          <el-form-item label="启用">
+            <el-switch v-model="generalForm.Discord.Enabled"></el-switch>
+          </el-form-item>
+          <el-form-item label="发件人">
+            <el-input v-model="generalForm.Discord.SenderName"></el-input>
+          </el-form-item>
+          <el-form-item label="地址">
+            <el-input v-model="generalForm.Discord.URL"></el-input>
+          </el-form-item>
+
+          <el-divider/>
+
+          <el-form-item >
+            <h2>其他配置</h2>
+          </el-form-item><el-form-item label="使用UI的原始交易命令">
+            <el-switch v-model="generalForm.UseOriginalTradeCommandWithUI"></el-switch>
+          </el-form-item>
+          <el-form-item label="每页项目数">
+            <el-input v-model="generalForm.ItemsPerPage"></el-input>
+          </el-form-item>
+          <el-form-item label="店铺展示时间">
+            <el-input v-model="generalForm.ShopDisplayTime"></el-input>
+          </el-form-item>
+          <el-form-item label="店铺文字大小">
+            <el-input v-model="generalForm.ShopTextSize"></el-input>
+          </el-form-item>
+          <el-form-item label="DB文件位置">
+            <el-input v-model="generalForm.DbPathOverride"></el-input>
+          </el-form-item>
+          <el-form-item label="默认礼包">
+            <el-input v-model="generalForm.DefaultKit"></el-input>
+          </el-form-item>
+          <el-form-item label="使用低温仓给予恐龙">
+            <el-switch v-model="generalForm.GiveDinosInCryopods"></el-switch>
+          </el-form-item>
+          <el-form-item label="使用灵魂陷阱 ?">
+            <el-switch v-model="generalForm.UseSoulTraps"></el-switch>
+          </el-form-item>
+          <el-form-item label="低温仓时间上限 ?">
+            <el-switch v-model="General.CryoLimitedTime"></el-switch>
+          </el-form-item>
+        </el-form>
+      </el-col>
+      <el-col :span="8">
+        <VIPView/>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+<script setup lang="ts">
+import {General, GetGeneral} from "../../api/ConfigFile.ts";
+import {ref} from "vue";
+import VIPView from "./VIPView.vue";
+
+let generalForm = ref<General>(General.Create())
+replay()
+function replay() {
+  generalForm.value = General.Create()
+  GetGeneral().then(res => {
+    generalForm.value = res.data
+  })
+}
+
+
+</script>
+<style scoped>
+
+</style>

+ 85 - 20
ui/src/page/back/VIPView.vue

@@ -1,23 +1,83 @@
 <template>
   <div class="vip-body">
-    <el-row style="margin-bottom: 10px">
-      <el-col :span="1.5">
-        <el-button plain type="primary" @click="OpenDialog('save',new Group())">添加</el-button>
-        <el-button plain type="primary" @click="replay()">刷新</el-button>
+    <el-row :span="24">
+      <el-col :span="24">
+        <el-row>
+          <el-col :span="16">
+            <h2 style="text-align: center">VIP组设定</h2>
+            <el-form v-model="timedPointsReward" label-width="140px" append-to-body>
+              <el-row>
+                <el-col :span="12">
+                  <el-form-item>
+                    <template #label>
+                      <el-text>
+                        <span>是否开启</span>
+                        <el-tooltip
+                            class="box-item"
+                            effect="dark"
+                            content="这个功能用于控制VIP在线奖励的开关"
+                            placement="top">
+                          <el-icon>
+                            <QuestionFilled/>
+                          </el-icon>
+                        </el-tooltip>
+                      </el-text>
+
+                    </template>
+                    <el-switch v-model="timedPointsReward.Enabled"></el-switch>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="12">
+                  <el-form-item>
+                    <template #label>
+                      <el-text>
+                        <span>是否叠加</span>
+                        <el-tooltip
+                            class="box-item"
+                            effect="dark"
+                            content="这个应该是叠加领取下级的vip奖励"
+                            placement="top">
+                          <el-icon>
+                            <QuestionFilled/>
+                          </el-icon>
+                        </el-tooltip>
+                      </el-text>
+                    </template>
+                    <el-switch v-model="timedPointsReward.StackRewards"></el-switch>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="24">
+                  <el-form-item label="VIP金币奖励间隔">
+                    <el-input v-model="timedPointsReward.Interval">
+                      <template #append>分钟</template>
+                    </el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </el-form>
+          </el-col>
+        </el-row>
       </el-col>
-      <el-col :span="1.5"></el-col>
-      <el-col :span="1.5"></el-col>
+      <el-row>
+        <el-col :span="1.5" style="margin: 10px ">
+          <el-button plain type="primary" @click="OpenDialog('save',new Group())">添加</el-button>
+          <el-button plain type="primary" @click="replay()">刷新</el-button>
+        </el-col>
+        <el-col :span="1.5"></el-col>
+        <el-col :span="1.5"></el-col>
+      </el-row>
+      <el-table :data="groups" border>
+        <el-table-column label="VIP组名称" prop="name"></el-table-column>
+        <el-table-column label="VIP金币奖励" prop="amount"></el-table-column>
+        <el-table-column width="120" label="操作">
+          <template #default="scope">
+            <el-button link type="primary" @click="OpenDialog('update',scope.row)">修改</el-button>
+            <el-button link type="danger" @click="deleteSkuById(scope.row.id)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
     </el-row>
-    <el-table :data="groups" border style="width: 340px">
-      <el-table-column width="100" label="VIP组名称" prop="name"></el-table-column>
-      <el-table-column width="120" label="VIP金币奖励" prop="amount"></el-table-column>
-      <el-table-column width="120" label="操作">
-        <template #default="scope">
-          <el-button link type="primary" @click="OpenDialog('update',scope.row)">修改</el-button>
-          <el-button link type="danger" @click="deleteSkuById(scope.row.id)">删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
+
     <el-dialog :title="'添加VIP组'" v-model="open" width="500px" append-to-body>
       <el-form v-model="groupForm">
         <el-form-item label="VIP组名称">
@@ -29,15 +89,17 @@
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button type="primary" @click="submitSkuForm()">确 定</el-button>
-          <el-button @click="skuOpen=false">取 消</el-button>
+          <el-button type="primary" @click="submitForm()">确 定</el-button>
+          <el-button @click="open=false">取 消</el-button>
         </div>
       </template>
     </el-dialog>
   </div>
 </template>
 <script setup lang="ts">
-import {GetTimedPointsReward, Group, TimedPointsReward} from "../../api/ConfigFile.ts";
+
+import {QuestionFilled} from "@element-plus/icons-vue";
+import {GetTimedPointsReward, Group, TimedPointsReward, TimedPointsRewardAmount} from "../../api/ConfigFile.ts";
 import {ref} from "vue";
 
 
@@ -55,11 +117,13 @@ function OpenDialog(status: string, group: Group) {
   this.status = status
   groupForm.value = group
 }
+
 function submitForm() {
   if (status.value == "save") {
     timedPointsReward.value.Groups.set(groupForm.value.name, new TimedPointsRewardAmount(groupForm.value.amount))
   }
 }
+
 function replay() {
   groups.value = []
   GetTimedPointsReward().then((data) => {
@@ -77,6 +141,7 @@ replay()
 </script>
 <style scoped>
 .vip-body {
-  margin: 10px;
+  padding: 10px;
+  border: #dddddd 1px solid;
 }
 </style>

+ 70 - 12
ui/src/page/back/index.vue

@@ -7,17 +7,34 @@
       text-color="#bcbec4"
       active-text-color="#2ab19f"
       @select="handleSelect">
-    <el-menu-item index="1" @click="JumpRouter('/back/base')">基本功能</el-menu-item>
-    <el-menu-item index="2" @click="JumpRouter('/back/home')">概述</el-menu-item>
-    <el-sub-menu index="3">
-      <template #title>商城</template>
-      <el-menu-item index="2-1" @click="JumpRouter('/back/vip')">VIP</el-menu-item>
-      <el-menu-item index="2-2">礼包</el-menu-item>
-      <el-menu-item index="2-3">商品</el-menu-item>
-      <el-menu-item index="2-4">回收</el-menu-item>
-    </el-sub-menu>
-    <el-menu-item index="4" @click="JumpRouter('/back/message')">消息</el-menu-item>
-    <el-menu-item index="5">设置</el-menu-item>
+    <template v-for="menu in menus">
+      <template v-if="menu.subMenu.length > 0">
+        <el-sub-menu :index="menu.index">
+          <template #title>{{ menu.name }}</template>
+          <template v-for="subMenu in menu.subMenu">
+            <el-menu-item :index="subMenu.index" v-if="menu.path && menu.name" :key="subMenu.index"
+                          @click="JumpRouter(subMenu.path)">{{ subMenu.name }}
+            </el-menu-item>
+          </template>
+        </el-sub-menu>
+      </template>
+      <template v-else>
+        <el-menu-item v-if="menu.path && menu.name" :index="menu.index" @click="JumpRouter(menu.path)">{{ menu.name }}
+        </el-menu-item>
+      </template>
+    </template>
+    <!--    -->
+    <!--    <el-menu-item index="1" @click="JumpRouter('/back/base')">基本功能</el-menu-item>-->
+    <!--    <el-menu-item index="2" @click="JumpRouter('/back/general')">概述</el-menu-item>-->
+    <!--    <el-sub-menu index="3">-->
+    <!--      <template #title>商城</template>-->
+    <!--      <el-menu-item index="2-1" @click="JumpRouter('/back/vip')">VIP</el-menu-item>-->
+    <!--      <el-menu-item index="2-2">礼包</el-menu-item>-->
+    <!--      <el-menu-item index="2-3">商品</el-menu-item>-->
+    <!--      <el-menu-item index="2-4">回收</el-menu-item>-->
+    <!--    </el-sub-menu>-->
+    <!--    <el-menu-item index="4" @click="JumpRouter('/back/message')">消息</el-menu-item>-->
+    <!--    <el-menu-item index="5">设置</el-menu-item>-->
   </el-menu>
   <router-view/>
 </template>
@@ -26,7 +43,48 @@
 import {ref} from 'vue'
 import router from "../../router";
 
-const activeIndex = ref('1')
+const activeIndex = ref<string>('1')
+
+class Menu {
+  index: string
+  name: string
+  path: string
+  subMenu: Menu[]
+
+  constructor(index: string, name: string, path: string, subMenu: Menu[]) {
+    this.index = index;
+    this.name = name;
+    this.path = path;
+    this.subMenu = subMenu;
+  }
+}
+
+const menus = ref<Menu[]>([new Menu("1", "基本功能", "/back/base", []),
+  new Menu("2", "概述", "/back/general", []),
+  new Menu("3", "商城", "/back/vip", [
+    new Menu("2-1", "VIP", "/back/general", []),
+    new Menu("2-2", "礼包", "/back/vip", []),
+    new Menu("2-3", "商品", "/back/vip", []),
+    new Menu("2-4", "回收", "/back/vip", [])
+  ]),
+  new Menu("4", "消息", "/back/message", []),
+  new Menu("5", "设置", "/back/message", [])
+])
+
+function GetNowMenu() {
+  let map = new Map<string, string>;
+  for (let i = 0; i < menus.value.length; i++) {
+    map.set(menus.value[i].index, menus.value[i].path)
+    if (menus.value[i].subMenu.length > 0) {
+      for (let j = 0; j < menus.value[i].subMenu.length; j++) {
+        map.set(menus.value[i].subMenu[j].index, menus.value[i].subMenu[j].path)
+      }
+    }
+  }
+  activeIndex.value = map.get(router.currentRoute.value.path)
+}
+
+GetNowMenu()
 const handleSelect = (key: string, keyPath: string[]) => {
   console.log(key, keyPath)
 }

+ 5 - 0
ui/src/router/index.ts

@@ -33,6 +33,11 @@ const routes: Array<RouteRecordRaw> = [
                 path: "vip",
                 component: () => import("../page/back/VIPView.vue"),
             },
+            {
+                name: "back-general",
+                path: "general",
+                component: () => import("../page/back/GeneralView.vue"),
+            },
         ],
     },
 ];