mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 08:13:43 +08:00 
			
		
		
		
	style: 调整后台管理框架样式
This commit is contained in:
		@@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"chatplus/core/types"
 | 
			
		||||
	"chatplus/handler"
 | 
			
		||||
	logger2 "chatplus/logger"
 | 
			
		||||
	"chatplus/store/model"
 | 
			
		||||
	"chatplus/utils"
 | 
			
		||||
	"chatplus/utils/resp"
 | 
			
		||||
 | 
			
		||||
@@ -70,3 +71,37 @@ func (h *ManagerHandler) Session(c *gin.Context) {
 | 
			
		||||
		resp.SUCCESS(c)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestUser 修正用户配置数据接口
 | 
			
		||||
// 将用户订阅角色的数据结构从 map 改成数组
 | 
			
		||||
func (h *ManagerHandler) TestUser(c *gin.Context) {
 | 
			
		||||
	var users []model.User
 | 
			
		||||
	h.db.Find(&users)
 | 
			
		||||
	for _, u := range users {
 | 
			
		||||
		var m map[string]int
 | 
			
		||||
		var roleKeys = make([]string, 0)
 | 
			
		||||
		err := utils.JsonDecode(u.ChatRoles, &m)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for k, _ := range m {
 | 
			
		||||
			roleKeys = append(roleKeys, k)
 | 
			
		||||
		}
 | 
			
		||||
		u.ChatRoles = utils.JsonEncode(roleKeys)
 | 
			
		||||
		h.db.Updates(&u)
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	resp.SUCCESS(c, "SUCCESS")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestRole 修改角色图片,改成绝对路径
 | 
			
		||||
func (h *ManagerHandler) TestRole(c *gin.Context) {
 | 
			
		||||
	var roles []model.ChatRole
 | 
			
		||||
	h.db.Find(&roles)
 | 
			
		||||
	for _, r := range roles {
 | 
			
		||||
		r.Icon = "/" + r.Icon
 | 
			
		||||
		h.db.Updates(&r)
 | 
			
		||||
	}
 | 
			
		||||
	resp.SUCCESS(c, "SUCCESS")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -143,20 +143,3 @@ func (h *UserHandler) LoginLog(c *gin.Context) {
 | 
			
		||||
 | 
			
		||||
	resp.SUCCESS(c, vo.NewPage(total, page, pageSize, logs))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *UserHandler) InitUser(c *gin.Context) {
 | 
			
		||||
	var users []model.User
 | 
			
		||||
	h.db.Find(&users)
 | 
			
		||||
	for _, u := range users {
 | 
			
		||||
		var m map[string]int
 | 
			
		||||
		var roleKeys = make([]string, 0)
 | 
			
		||||
		utils.JsonDecode(u.ChatRoles, &m)
 | 
			
		||||
		for k, _ := range m {
 | 
			
		||||
			roleKeys = append(roleKeys, k)
 | 
			
		||||
		}
 | 
			
		||||
		u.ChatRoles = utils.JsonEncode(roleKeys)
 | 
			
		||||
		h.db.Updates(&u)
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	resp.SUCCESS(c, "SUCCESS")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -125,19 +125,19 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session types.ChatSession
 | 
			
		||||
 | 
			
		||||
	if userVo.Status == false {
 | 
			
		||||
		replyMessage(ws, "您的账号已经被禁用,如果疑问,请联系管理员!")
 | 
			
		||||
		replyMessage(ws, "")
 | 
			
		||||
		replyMessage(ws, "")
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if userVo.Calls <= 0 {
 | 
			
		||||
		replyMessage(ws, "您的对话次数已经用尽,请联系管理员充值!")
 | 
			
		||||
		replyMessage(ws, "")
 | 
			
		||||
		replyMessage(ws, "")
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if userVo.ExpiredTime > 0 && userVo.ExpiredTime <= time.Now().Unix() {
 | 
			
		||||
		replyMessage(ws, "您的账号已经过期,请联系管理员!")
 | 
			
		||||
		replyMessage(ws, "")
 | 
			
		||||
		replyMessage(ws, "")
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	var req = types.ApiRequest{
 | 
			
		||||
@@ -189,7 +189,7 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session types.ChatSession
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		replyMessage(ws, ErrorMsg)
 | 
			
		||||
		replyMessage(ws, "")
 | 
			
		||||
		replyMessage(ws, "")
 | 
			
		||||
		return err
 | 
			
		||||
	} else {
 | 
			
		||||
		defer response.Body.Close()
 | 
			
		||||
@@ -221,7 +221,7 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session types.ChatSession
 | 
			
		||||
			if err != nil { // 数据解析出错
 | 
			
		||||
				logger.Error(err, line)
 | 
			
		||||
				replyMessage(ws, ErrorMsg)
 | 
			
		||||
				replyMessage(ws, "")
 | 
			
		||||
				replyMessage(ws, "")
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -125,6 +125,8 @@ func main() {
 | 
			
		||||
			group.POST("login", h.Login)
 | 
			
		||||
			group.GET("logout", h.Logout)
 | 
			
		||||
			group.GET("session", h.Session)
 | 
			
		||||
			group.GET("test/user", h.TestUser)
 | 
			
		||||
			group.GET("test/role", h.TestRole)
 | 
			
		||||
		}),
 | 
			
		||||
		fx.Invoke(func(s *core.AppServer, h *admin.ApiKeyHandler) {
 | 
			
		||||
			group := s.Engine.Group("/api/admin/apikey/")
 | 
			
		||||
@@ -138,7 +140,6 @@ func main() {
 | 
			
		||||
			group.POST("update", h.Update)
 | 
			
		||||
			group.GET("remove", h.Remove)
 | 
			
		||||
			group.GET("loginLog", h.LoginLog)
 | 
			
		||||
			group.GET("test", h.InitUser)
 | 
			
		||||
		}),
 | 
			
		||||
		fx.Invoke(func(s *core.AppServer, h *admin.ChatRoleHandler) {
 | 
			
		||||
			group := s.Engine.Group("/api/admin/role/")
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +1,22 @@
 | 
			
		||||
.header{
 | 
			
		||||
    background-color: #242f42;
 | 
			
		||||
}
 | 
			
		||||
.login-wrap{
 | 
			
		||||
    background: #324157;
 | 
			
		||||
}
 | 
			
		||||
.plugins-tips{
 | 
			
		||||
    background: #eef1f6;
 | 
			
		||||
}
 | 
			
		||||
.plugins-tips a{
 | 
			
		||||
    color: #20a0ff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tags-li.active {
 | 
			
		||||
    border: 1px solid #409EFF;
 | 
			
		||||
    background-color: #409EFF;
 | 
			
		||||
}
 | 
			
		||||
.message-title{
 | 
			
		||||
    color: #20a0ff;
 | 
			
		||||
}
 | 
			
		||||
.collapse-btn:hover{
 | 
			
		||||
    background: rgb(40,52,70);
 | 
			
		||||
}
 | 
			
		||||
.admin-home .header {
 | 
			
		||||
  background-color: #242f42;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .login-wrap {
 | 
			
		||||
  background: #324157;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .plugins-tips {
 | 
			
		||||
  background: #eef1f6;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .plugins-tips a {
 | 
			
		||||
  color: #20a0ff;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .tags-li.active {
 | 
			
		||||
  border: 1px solid #409eff;
 | 
			
		||||
  background-color: #409eff;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .message-title {
 | 
			
		||||
  color: #20a0ff;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .collapse-btn:hover {
 | 
			
		||||
  background: #283446;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								web/src/assets/css/color-dark.styl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								web/src/assets/css/color-dark.styl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
.admin-home {
 | 
			
		||||
  .header {
 | 
			
		||||
    background-color: #242f42;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .login-wrap {
 | 
			
		||||
    background: #324157;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .plugins-tips {
 | 
			
		||||
    background: #eef1f6;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .plugins-tips a {
 | 
			
		||||
    color: #20a0ff;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .tags-li.active {
 | 
			
		||||
    border: 1px solid #409EFF;
 | 
			
		||||
    background-color: #409EFF;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .message-title {
 | 
			
		||||
    color: #20a0ff;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .collapse-btn:hover {
 | 
			
		||||
    background: rgb(40, 52, 70);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,138 +1,118 @@
 | 
			
		||||
* {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html,
 | 
			
		||||
body,
 | 
			
		||||
#app,
 | 
			
		||||
.wrapper {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
    font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif;
 | 
			
		||||
  font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a {
 | 
			
		||||
    text-decoration: none
 | 
			
		||||
.admin-home a {
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.content-box {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    left: 250px;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    top: 70px;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    padding-bottom: 30px;
 | 
			
		||||
    -webkit-transition: left .3s ease-in-out;
 | 
			
		||||
    transition: left .3s ease-in-out;
 | 
			
		||||
    background: #f0f0f0;
 | 
			
		||||
.admin-home .content-box {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  left: 250px;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  top: 70px;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  padding-bottom: 30px;
 | 
			
		||||
  -webkit-transition: left 0.3s ease-in-out;
 | 
			
		||||
  transition: left 0.3s ease-in-out;
 | 
			
		||||
  background: #f0f0f0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.content {
 | 
			
		||||
    width: auto;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
    overflow-y: scroll;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.content-collapse {
 | 
			
		||||
    left: 65px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.container {
 | 
			
		||||
    padding: 30px;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    border: 1px solid #ddd;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.crumbs {
 | 
			
		||||
    margin: 10px 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-table th {
 | 
			
		||||
    background-color: #f5f7fa !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pagination {
 | 
			
		||||
    margin: 20px 0;
 | 
			
		||||
    text-align: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.plugins-tips {
 | 
			
		||||
    padding: 20px 10px;
 | 
			
		||||
    margin-bottom: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-button + .el-tooltip {
 | 
			
		||||
    margin-left: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-table tr:hover {
 | 
			
		||||
    background: #f6faff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.mgb20 {
 | 
			
		||||
    margin-bottom: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.move-enter-active,
 | 
			
		||||
.move-leave-active {
 | 
			
		||||
    transition: opacity .1s ease;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.move-enter-from,
 | 
			
		||||
.move-leave-to {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.admin-home .content-box .content {
 | 
			
		||||
  width: auto;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  overflow-y: scroll;
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
/*BaseForm*/
 | 
			
		||||
 | 
			
		||||
.form-box {
 | 
			
		||||
    width: 600px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.form-box .line {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
.admin-home .content-box .content .container {
 | 
			
		||||
  padding: 30px;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  border: 1px solid #ddd;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-time-panel__content::after,
 | 
			
		||||
.el-time-panel__content::before {
 | 
			
		||||
    margin-top: -7px;
 | 
			
		||||
.admin-home .content-box .content .container .handle-box {
 | 
			
		||||
  margin-bottom: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) {
 | 
			
		||||
    padding-bottom: 0;
 | 
			
		||||
.admin-home .content-box .content .crumbs {
 | 
			
		||||
  margin: 10px 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[class*=" el-icon-"], [class^=el-icon-] {
 | 
			
		||||
    speak: none;
 | 
			
		||||
    font-style: normal;
 | 
			
		||||
    font-weight: 400;
 | 
			
		||||
    font-variant: normal;
 | 
			
		||||
    text-transform: none;
 | 
			
		||||
    line-height: 1;
 | 
			
		||||
    vertical-align: baseline;
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    -webkit-font-smoothing: antialiased;
 | 
			
		||||
    -moz-osx-font-smoothing: grayscale;
 | 
			
		||||
.admin-home .content-box .content .el-table th {
 | 
			
		||||
  background-color: #f5f7fa !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-sub-menu [class^=el-icon-] {
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
    margin-right: 5px;
 | 
			
		||||
    width: 24px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    font-size: 18px;
 | 
			
		||||
.admin-home .content-box .content .pagination {
 | 
			
		||||
  margin: 20px 0;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .plugins-tips {
 | 
			
		||||
  padding: 20px 10px;
 | 
			
		||||
  margin-bottom: 20px;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .el-button + .el-tooltip {
 | 
			
		||||
  margin-left: 10px;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .el-table tr:hover {
 | 
			
		||||
  background: #f6faff;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .mgb20 {
 | 
			
		||||
  margin-bottom: 20px;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .move-enter-active,
 | 
			
		||||
.admin-home .content-box .content .move-leave-active {
 | 
			
		||||
  transition: opacity 0.1s ease;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .move-enter-from,
 | 
			
		||||
.admin-home .content-box .content .move-leave-to {
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .form-box {
 | 
			
		||||
  width: 600px;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .form-box .line {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .el-time-panel__content::after,
 | 
			
		||||
.admin-home .content-box .content .el-time-panel__content::before {
 | 
			
		||||
  margin-top: -7px;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) {
 | 
			
		||||
  padding-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content [class*=" el-icon-"],
 | 
			
		||||
.admin-home .content-box .content [class^=el-icon-] {
 | 
			
		||||
  speak: none;
 | 
			
		||||
  font-style: normal;
 | 
			
		||||
  font-weight: 400;
 | 
			
		||||
  font-variant: normal;
 | 
			
		||||
  text-transform: none;
 | 
			
		||||
  line-height: 1;
 | 
			
		||||
  vertical-align: baseline;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  -webkit-font-smoothing: antialiased;
 | 
			
		||||
  -moz-osx-font-smoothing: grayscale;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content .el-sub-menu [class^=el-icon-] {
 | 
			
		||||
  vertical-align: middle;
 | 
			
		||||
  margin-right: 5px;
 | 
			
		||||
  width: 24px;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  font-size: 18px;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-box .content [hidden] {
 | 
			
		||||
  display: none !important;
 | 
			
		||||
}
 | 
			
		||||
.admin-home .content-collapse {
 | 
			
		||||
  left: 65px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[hidden] {
 | 
			
		||||
    display: none !important;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										149
									
								
								web/src/assets/css/main.styl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								web/src/assets/css/main.styl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
* {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html,
 | 
			
		||||
body,
 | 
			
		||||
#app,
 | 
			
		||||
.wrapper {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
  font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.admin-home {
 | 
			
		||||
  a {
 | 
			
		||||
    text-decoration: none
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .content-box {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    left: 250px;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    top: 70px;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    padding-bottom: 30px;
 | 
			
		||||
    -webkit-transition: left .3s ease-in-out;
 | 
			
		||||
    transition: left .3s ease-in-out;
 | 
			
		||||
    background: #f0f0f0;
 | 
			
		||||
 | 
			
		||||
    .content {
 | 
			
		||||
      width: auto;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      padding: 10px;
 | 
			
		||||
      overflow-y: scroll;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
 | 
			
		||||
      .container {
 | 
			
		||||
        padding: 30px;
 | 
			
		||||
        background: #fff;
 | 
			
		||||
        border: 1px solid #ddd;
 | 
			
		||||
        border-radius: 5px;
 | 
			
		||||
 | 
			
		||||
        .handle-box {
 | 
			
		||||
          margin-bottom: 20px;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .crumbs {
 | 
			
		||||
        margin: 10px 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-table th {
 | 
			
		||||
        background-color: #f5f7fa !important;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .pagination {
 | 
			
		||||
        margin: 20px 0;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .plugins-tips {
 | 
			
		||||
        padding: 20px 10px;
 | 
			
		||||
        margin-bottom: 20px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-button + .el-tooltip {
 | 
			
		||||
        margin-left: 10px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-table tr:hover {
 | 
			
		||||
        background: #f6faff;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .mgb20 {
 | 
			
		||||
        margin-bottom: 20px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .move-enter-active,
 | 
			
		||||
      .move-leave-active {
 | 
			
		||||
        transition: opacity .1s ease;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .move-enter-from,
 | 
			
		||||
      .move-leave-to {
 | 
			
		||||
        opacity: 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /*BaseForm*/
 | 
			
		||||
 | 
			
		||||
      .form-box {
 | 
			
		||||
        width: 600px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .form-box .line {
 | 
			
		||||
        text-align: center;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-time-panel__content::after,
 | 
			
		||||
      .el-time-panel__content::before {
 | 
			
		||||
        margin-top: -7px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) {
 | 
			
		||||
        padding-bottom: 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      [class*=" el-icon-"], [class^=el-icon-] {
 | 
			
		||||
        speak: none;
 | 
			
		||||
        font-style: normal;
 | 
			
		||||
        font-weight: 400;
 | 
			
		||||
        font-variant: normal;
 | 
			
		||||
        text-transform: none;
 | 
			
		||||
        line-height: 1;
 | 
			
		||||
        vertical-align: baseline;
 | 
			
		||||
        display: inline-block;
 | 
			
		||||
        -webkit-font-smoothing: antialiased;
 | 
			
		||||
        -moz-osx-font-smoothing: grayscale;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-sub-menu [class^=el-icon-] {
 | 
			
		||||
        vertical-align: middle;
 | 
			
		||||
        margin-right: 5px;
 | 
			
		||||
        width: 24px;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        font-size: 18px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [hidden] {
 | 
			
		||||
        display: none !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .content-collapse {
 | 
			
		||||
    left: 65px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
@font-face {
 | 
			
		||||
  font-family: "iconfont"; /* Project id 4125778 */
 | 
			
		||||
  src: url('iconfont.woff2?t=1687330009953') format('woff2'),
 | 
			
		||||
       url('iconfont.woff?t=1687330009953') format('woff'),
 | 
			
		||||
       url('iconfont.ttf?t=1687330009953') format('truetype');
 | 
			
		||||
  src: url('iconfont.woff2?t=1687341905766') format('woff2'),
 | 
			
		||||
       url('iconfont.woff?t=1687341905766') format('woff'),
 | 
			
		||||
       url('iconfont.ttf?t=1687341905766') format('truetype');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.iconfont {
 | 
			
		||||
@@ -13,6 +13,10 @@
 | 
			
		||||
  -moz-osx-font-smoothing: grayscale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.icon-sub-menu:before {
 | 
			
		||||
  content: "\e86b";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.icon-wechat-pay:before {
 | 
			
		||||
  content: "\e639";
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -5,6 +5,13 @@
 | 
			
		||||
  "css_prefix_text": "icon-",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "glyphs": [
 | 
			
		||||
    {
 | 
			
		||||
      "icon_id": "6343824",
 | 
			
		||||
      "name": "menu",
 | 
			
		||||
      "font_class": "sub-menu",
 | 
			
		||||
      "unicode": "e86b",
 | 
			
		||||
      "unicode_decimal": 59499
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "icon_id": "1487626",
 | 
			
		||||
      "name": "微信支付",
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -1,5 +1,9 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="header">
 | 
			
		||||
  <div class="header admin-header">
 | 
			
		||||
    <div class="logo">
 | 
			
		||||
      <el-image :src="logo"/>
 | 
			
		||||
      <span class="text">{{ title }}</span>
 | 
			
		||||
    </div>
 | 
			
		||||
    <!-- 折叠按钮 -->
 | 
			
		||||
    <div class="collapse-btn" @click="collapseChange">
 | 
			
		||||
      <el-icon v-if="sidebar.collapse">
 | 
			
		||||
@@ -9,8 +13,6 @@
 | 
			
		||||
        <Fold/>
 | 
			
		||||
      </el-icon>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="logo">后台管理系统</div>
 | 
			
		||||
    <div class="header-right">
 | 
			
		||||
      <div class="header-user-con">
 | 
			
		||||
        <!-- 消息中心 -->
 | 
			
		||||
@@ -87,6 +89,21 @@ const avatar = ref('/images/user-info.jpg')
 | 
			
		||||
const donateImg = ref('/images/wechat-pay.png')
 | 
			
		||||
const showDialog = ref(false)
 | 
			
		||||
const sidebar = useSidebarStore();
 | 
			
		||||
const title = ref('Chat-Plus 控制台')
 | 
			
		||||
const logo = ref('/images/logo.png')
 | 
			
		||||
 | 
			
		||||
// 获取会话信息
 | 
			
		||||
httpGet("/api/admin/session").then(() => {
 | 
			
		||||
  // 加载系统配置
 | 
			
		||||
  httpGet('/api/admin/config/get?key=system').then(res => {
 | 
			
		||||
    title.value = res.data['admin_title'];
 | 
			
		||||
  }).catch(e => {
 | 
			
		||||
    ElMessage.error("加载系统配置失败: " + e.message)
 | 
			
		||||
  })
 | 
			
		||||
}).catch(() => {
 | 
			
		||||
  router.replace('/admin/login')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// 侧边栏折叠
 | 
			
		||||
const collapseChange = () => {
 | 
			
		||||
  sidebar.handleCollapse();
 | 
			
		||||
@@ -101,7 +118,7 @@ onMounted(() => {
 | 
			
		||||
const router = useRouter();
 | 
			
		||||
const logout = function () {
 | 
			
		||||
  httpGet("/api/admin/logout").then(() => {
 | 
			
		||||
    router.push('/admin/login')
 | 
			
		||||
    router.replace('/admin/login')
 | 
			
		||||
  }).catch((e) => {
 | 
			
		||||
    ElMessage.error("注销失败: " + e.message);
 | 
			
		||||
  })
 | 
			
		||||
@@ -128,13 +145,18 @@ const logout = function () {
 | 
			
		||||
 | 
			
		||||
  .logo {
 | 
			
		||||
    float: left;
 | 
			
		||||
    width: 250px;
 | 
			
		||||
    line-height: 70px;
 | 
			
		||||
    padding-left 10px;
 | 
			
		||||
    display flex
 | 
			
		||||
 | 
			
		||||
    .text {
 | 
			
		||||
      line-height: 66px;
 | 
			
		||||
      margin-left 10px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .header-right {
 | 
			
		||||
    float: right;
 | 
			
		||||
    padding-right: 50px;
 | 
			
		||||
    padding-right: 20px;
 | 
			
		||||
 | 
			
		||||
    .header-user-con {
 | 
			
		||||
      display: flex;
 | 
			
		||||
@@ -208,4 +230,17 @@ const logout = function () {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.admin-header {
 | 
			
		||||
  .logo {
 | 
			
		||||
    .el-image {
 | 
			
		||||
      padding-top 10px
 | 
			
		||||
 | 
			
		||||
      .el-image__inner {
 | 
			
		||||
        height 40px
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
        <template v-if="item.subs">
 | 
			
		||||
          <el-sub-menu :index="item.index" :key="item.index">
 | 
			
		||||
            <template #title>
 | 
			
		||||
              <i :class="'iconfont '+item.icon"></i>
 | 
			
		||||
              <i :class="'iconfont icon-'+item.icon"></i>
 | 
			
		||||
              <span>{{ item.title }}</span>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template v-for="subItem in item.subs">
 | 
			
		||||
@@ -29,6 +29,7 @@
 | 
			
		||||
                </el-menu-item>
 | 
			
		||||
              </el-sub-menu>
 | 
			
		||||
              <el-menu-item v-else :index="subItem.index">
 | 
			
		||||
                <i v-if="subItem.icon" :class="'iconfont icon-'+subItem.icon"></i>
 | 
			
		||||
                {{ subItem.title }}
 | 
			
		||||
              </el-menu-item>
 | 
			
		||||
            </template>
 | 
			
		||||
@@ -62,13 +63,33 @@ const items = [
 | 
			
		||||
    title: '系统设置',
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    icon: 'user-fill',
 | 
			
		||||
    index: '/admin/user',
 | 
			
		||||
    title: '用户管理',
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    icon: 'role',
 | 
			
		||||
    index: '/admin/role',
 | 
			
		||||
    title: '角色管理',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    icon: 'api-key',
 | 
			
		||||
    index: '/admin/apikey',
 | 
			
		||||
    title: 'API-KEY 管理',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    icon: 'log',
 | 
			
		||||
    index: '/admin/loginLog',
 | 
			
		||||
    title: '用户登录日志',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    icon: 'menu',
 | 
			
		||||
    index: '1',
 | 
			
		||||
    title: '常用模板页面',
 | 
			
		||||
    subs: [
 | 
			
		||||
      {
 | 
			
		||||
        icon: 'menu',
 | 
			
		||||
        index: '/admin/demo/form',
 | 
			
		||||
        title: '表单页面',
 | 
			
		||||
      },
 | 
			
		||||
@@ -108,16 +129,12 @@ const sidebar = useSidebarStore();
 | 
			
		||||
  ul {
 | 
			
		||||
    height: 100%;
 | 
			
		||||
 | 
			
		||||
    .el-menu-item {
 | 
			
		||||
    .el-menu-item, .el-sub-menu {
 | 
			
		||||
      .iconfont {
 | 
			
		||||
        font-size 16px;
 | 
			
		||||
        margin-right 5px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-menu-item.is-active {
 | 
			
		||||
      background-color #242f42
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .sidebar-el-menu:not(.el-menu--collapse) {
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@ const closeTags = (index) => {
 | 
			
		||||
  if (item) {
 | 
			
		||||
    delItem.path === route.fullPath && router.push(item.path);
 | 
			
		||||
  } else {
 | 
			
		||||
    router.push('/');
 | 
			
		||||
    router.push('/admin');
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -78,7 +78,7 @@ onBeforeRouteUpdate(to => {
 | 
			
		||||
// 关闭全部标签
 | 
			
		||||
const closeAll = () => {
 | 
			
		||||
  tags.clearTags();
 | 
			
		||||
  router.push('/');
 | 
			
		||||
  router.push('/admin');
 | 
			
		||||
};
 | 
			
		||||
// 关闭其他标签
 | 
			
		||||
const closeOther = () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,9 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="list" v-loading="loading">
 | 
			
		||||
    <el-row class="opt-box">
 | 
			
		||||
      <el-button type="primary" @click="add" size="small">
 | 
			
		||||
        <el-icon>
 | 
			
		||||
          <Plus/>
 | 
			
		||||
        </el-icon>
 | 
			
		||||
        新增
 | 
			
		||||
      </el-button>
 | 
			
		||||
    </el-row>
 | 
			
		||||
  <div class="container list" v-loading="loading">
 | 
			
		||||
 | 
			
		||||
    <div class="handle-box">
 | 
			
		||||
      <el-button type="primary" :icon="Plus" @click="add">新增</el-button>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <el-row>
 | 
			
		||||
      <el-table :data="items" :row-key="row => row.id">
 | 
			
		||||
@@ -158,13 +154,6 @@ const remove = function (row) {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .pagination {
 | 
			
		||||
    padding-top 20px;
 | 
			
		||||
    display flex
 | 
			
		||||
    justify-content center
 | 
			
		||||
    width 100%
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-select {
 | 
			
		||||
    width: 100%
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
  <div class="admin-home">
 | 
			
		||||
    <admin-header/>
 | 
			
		||||
    <admin-sidebar/>
 | 
			
		||||
    <div class="content-box" :class="{ 'content-collapse': sidebar.collapse }">
 | 
			
		||||
@@ -27,7 +27,7 @@ const sidebar = useSidebarStore();
 | 
			
		||||
const tags = useTagsStore();
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus">
 | 
			
		||||
<style scoped lang="stylus">
 | 
			
		||||
@import '@/assets/css/main.css';
 | 
			
		||||
@import '@/assets/css/color-dark.css';
 | 
			
		||||
@import '@/assets/iconfont/iconfont.css';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
  <div class="admin-login">
 | 
			
		||||
    <div class="bg"></div>
 | 
			
		||||
    <div class="main">
 | 
			
		||||
      <div class="contain">
 | 
			
		||||
@@ -85,91 +85,98 @@ const login = function () {
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.bg {
 | 
			
		||||
  position fixed
 | 
			
		||||
  left 0
 | 
			
		||||
  right 0
 | 
			
		||||
  top 0
 | 
			
		||||
  bottom 0
 | 
			
		||||
  background-color #313237
 | 
			
		||||
  background-image url("~@/assets/img/admin-login-bg.jpg")
 | 
			
		||||
  background-size cover
 | 
			
		||||
  background-position center
 | 
			
		||||
  background-repeat no-repeat
 | 
			
		||||
  filter: blur(10px); /* 调整模糊程度,可以根据需要修改值 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.main {
 | 
			
		||||
  .contain {
 | 
			
		||||
.admin-login {
 | 
			
		||||
  .bg {
 | 
			
		||||
    position fixed
 | 
			
		||||
    left 50%
 | 
			
		||||
    top 40%
 | 
			
		||||
    width 90%
 | 
			
		||||
    max-width 400px;
 | 
			
		||||
    transform translate(-50%, -50%)
 | 
			
		||||
    padding 20px 40px;
 | 
			
		||||
    color #ffffff
 | 
			
		||||
    border-radius 10px;
 | 
			
		||||
    background rgba(255, 255, 255, 0.3)
 | 
			
		||||
    left 0
 | 
			
		||||
    right 0
 | 
			
		||||
    top 0
 | 
			
		||||
    bottom 0
 | 
			
		||||
    background-color #313237
 | 
			
		||||
    background-image url("~@/assets/img/admin-login-bg.jpg")
 | 
			
		||||
    background-size cover
 | 
			
		||||
    background-position center
 | 
			
		||||
    background-repeat no-repeat
 | 
			
		||||
    filter: blur(10px); /* 调整模糊程度,可以根据需要修改值 */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    .logo {
 | 
			
		||||
      text-align center
 | 
			
		||||
  .main {
 | 
			
		||||
    .contain {
 | 
			
		||||
      position fixed
 | 
			
		||||
      left 50%
 | 
			
		||||
      top 40%
 | 
			
		||||
      width 90%
 | 
			
		||||
      max-width 400px;
 | 
			
		||||
      transform translate(-50%, -50%)
 | 
			
		||||
      padding 20px 40px;
 | 
			
		||||
      color #ffffff
 | 
			
		||||
      border-radius 10px;
 | 
			
		||||
      background rgba(255, 255, 255, 0.3)
 | 
			
		||||
 | 
			
		||||
      .el-image {
 | 
			
		||||
        width 120px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
      .logo {
 | 
			
		||||
        text-align center
 | 
			
		||||
 | 
			
		||||
    .header {
 | 
			
		||||
      width 100%
 | 
			
		||||
      margin-bottom 24px
 | 
			
		||||
      font-size 24px
 | 
			
		||||
      color $white_v1
 | 
			
		||||
      letter-space 2px
 | 
			
		||||
      text-align center
 | 
			
		||||
    }
 | 
			
		||||
        .el-image {
 | 
			
		||||
          width 120px;
 | 
			
		||||
 | 
			
		||||
    .content {
 | 
			
		||||
      width 100%
 | 
			
		||||
      height: auto
 | 
			
		||||
      border-radius 3px
 | 
			
		||||
 | 
			
		||||
      .block {
 | 
			
		||||
        margin-bottom 16px
 | 
			
		||||
 | 
			
		||||
        .el-input__inner {
 | 
			
		||||
          border 1px solid $gray-v6 !important
 | 
			
		||||
 | 
			
		||||
          .el-icon-user, .el-icon-lock {
 | 
			
		||||
            font-size 20px
 | 
			
		||||
          .el-image__inner {
 | 
			
		||||
            height 100%
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .btn-row {
 | 
			
		||||
        padding-top 10px;
 | 
			
		||||
      .header {
 | 
			
		||||
        width 100%
 | 
			
		||||
        margin-bottom 24px
 | 
			
		||||
        font-size 24px
 | 
			
		||||
        color $white_v1
 | 
			
		||||
        letter-space 2px
 | 
			
		||||
        text-align center
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
        .login-btn {
 | 
			
		||||
          width 100%
 | 
			
		||||
          font-size 16px
 | 
			
		||||
          letter-spacing 2px
 | 
			
		||||
      .content {
 | 
			
		||||
        width 100%
 | 
			
		||||
        height: auto
 | 
			
		||||
        border-radius 3px
 | 
			
		||||
 | 
			
		||||
        .block {
 | 
			
		||||
          margin-bottom 16px
 | 
			
		||||
 | 
			
		||||
          .el-input__inner {
 | 
			
		||||
            border 1px solid $gray-v6 !important
 | 
			
		||||
 | 
			
		||||
            .el-icon-user, .el-icon-lock {
 | 
			
		||||
              font-size 20px
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .btn-row {
 | 
			
		||||
          padding-top 10px;
 | 
			
		||||
 | 
			
		||||
          .login-btn {
 | 
			
		||||
            width 100%
 | 
			
		||||
            font-size 16px
 | 
			
		||||
            letter-spacing 2px
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .text-line {
 | 
			
		||||
          justify-content center
 | 
			
		||||
          padding-top 10px;
 | 
			
		||||
          font-size 14px;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .text-line {
 | 
			
		||||
        justify-content center
 | 
			
		||||
        padding-top 10px;
 | 
			
		||||
        font-size 14px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .footer {
 | 
			
		||||
    color #ffffff;
 | 
			
		||||
    .footer {
 | 
			
		||||
      color #ffffff;
 | 
			
		||||
 | 
			
		||||
    .container {
 | 
			
		||||
      padding 20px;
 | 
			
		||||
      .container {
 | 
			
		||||
        padding 20px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="list" v-loading="loading">
 | 
			
		||||
  <div class="container list" v-loading="loading">
 | 
			
		||||
    <el-row>
 | 
			
		||||
      <el-table :data="items" :row-key="row => row.id">
 | 
			
		||||
      <el-table :data="items" border :row-key="row => row.id">
 | 
			
		||||
        <el-table-column label="用户名" prop="username"/>
 | 
			
		||||
        <el-table-column label="登录IP" prop="login_ip"/>
 | 
			
		||||
        <el-table-column label="登录地址" prop="login_address"/>
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
 | 
			
		||||
    <div class="pagination">
 | 
			
		||||
      <el-pagination v-if="total > 0" background
 | 
			
		||||
                     layout="prev, pager, next"
 | 
			
		||||
                     layout="total,prev, pager, next"
 | 
			
		||||
                     :hide-on-single-page="true"
 | 
			
		||||
                     v-model:current-page="page"
 | 
			
		||||
                     v-model:page-size="pageSize"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,8 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="role-list">
 | 
			
		||||
    <el-row class="opt-box">
 | 
			
		||||
      <el-button type="primary" @click="addRole" size="small">
 | 
			
		||||
        <el-icon>
 | 
			
		||||
          <Plus/>
 | 
			
		||||
        </el-icon>
 | 
			
		||||
        新增
 | 
			
		||||
      </el-button>
 | 
			
		||||
    </el-row>
 | 
			
		||||
 | 
			
		||||
  <div class="container role-list">
 | 
			
		||||
    <div class="handle-box">
 | 
			
		||||
      <el-button type="primary" :icon="Plus" @click="addRole">新增</el-button>
 | 
			
		||||
    </div>
 | 
			
		||||
    <el-row>
 | 
			
		||||
      <el-table :data="tableData" :border="parentBorder" style="width: 100%">
 | 
			
		||||
        <el-table-column type="expand">
 | 
			
		||||
@@ -157,7 +151,7 @@ import {copyObj, removeArrayItem} from "@/utils/libs";
 | 
			
		||||
import {Sortable} from "sortablejs"
 | 
			
		||||
 | 
			
		||||
const showDialog = ref(false)
 | 
			
		||||
const parentBorder = ref(false)
 | 
			
		||||
const parentBorder = ref(true)
 | 
			
		||||
const childBorder = ref(true)
 | 
			
		||||
const tableData = ref([])
 | 
			
		||||
const sortedTableData = ref([])
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,9 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="user-list" v-loading="loading">
 | 
			
		||||
  <div class="container user-list" v-loading="loading">
 | 
			
		||||
    <el-row>
 | 
			
		||||
      <el-table :data="users.items" :row-key="row => row.id" @selection-change="handleSelectionChange">
 | 
			
		||||
        <el-table-column type="selection" width="55"/>
 | 
			
		||||
      <el-table :data="users.items" border class="table" :row-key="row => row.id"
 | 
			
		||||
                @selection-change="handleSelectionChange">
 | 
			
		||||
        <el-table-column type="selection" width="38"/>
 | 
			
		||||
        <el-table-column prop="username" label="用户名"/>
 | 
			
		||||
        <el-table-column prop="nickname" label="昵称"/>
 | 
			
		||||
        <el-table-column prop="calls" label="提问次数" width="100"/>
 | 
			
		||||
@@ -34,13 +35,14 @@
 | 
			
		||||
      </el-table>
 | 
			
		||||
 | 
			
		||||
      <div class="pagination">
 | 
			
		||||
        <el-pagination v-if="users.total > 0" background
 | 
			
		||||
                       layout="prev, pager, next"
 | 
			
		||||
                       :hide-on-single-page="true"
 | 
			
		||||
                       v-model:current-page="users.page"
 | 
			
		||||
                       v-model:page-size="users.page_size"
 | 
			
		||||
        <el-pagination v-if="users.total > 0"
 | 
			
		||||
                       background
 | 
			
		||||
                       layout="total, prev, pager, next"
 | 
			
		||||
                       :current-page="users.page"
 | 
			
		||||
                       :page-size="users.page_size"
 | 
			
		||||
                       :total="users.total"
 | 
			
		||||
                       @current-change="fetchUserList(users.page, users.page_size)"
 | 
			
		||||
                       :total="users.total"/>
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
    </el-row>
 | 
			
		||||
@@ -148,6 +150,9 @@ const fetchUserList = function (page, pageSize) {
 | 
			
		||||
        arr[i].expired_time = dateFormat(arr[i].expired_time)
 | 
			
		||||
      }
 | 
			
		||||
      users.value.items = arr
 | 
			
		||||
      users.value.total = res.data.total
 | 
			
		||||
      users.value.page = res.data.page
 | 
			
		||||
      user.value.page_size = res.data.page_size
 | 
			
		||||
    }
 | 
			
		||||
  }).catch(() => {
 | 
			
		||||
    ElMessage.error('加载用户列表失败')
 | 
			
		||||
 
 | 
			
		||||
@@ -2,20 +2,18 @@
 | 
			
		||||
  <div>
 | 
			
		||||
    <div class="container">
 | 
			
		||||
      <div class="handle-box">
 | 
			
		||||
        <el-select v-model="query.address" placeholder="地址" class="handle-select mr10">
 | 
			
		||||
          <el-option key="1" label="广东省" value="广东省"></el-option>
 | 
			
		||||
          <el-option key="2" label="湖南省" value="湖南省"></el-option>
 | 
			
		||||
        <el-select v-model="query.address" placeholder="模型" class="handle-select mr10">
 | 
			
		||||
          <el-option key="1" label="GPT-3.5" value="GPT-3.5"></el-option>
 | 
			
		||||
          <el-option key="2" label="GPT-4.0" value="GPT-4.0"></el-option>
 | 
			
		||||
          <el-option key="2" label="GPT-5.0" value="GPT-5.0"></el-option>
 | 
			
		||||
        </el-select>
 | 
			
		||||
        <el-input v-model="query.name" placeholder="用户名" class="handle-input mr10"></el-input>
 | 
			
		||||
        <el-input v-model="query.name" placeholder="姓名" class="handle-input mr10"></el-input>
 | 
			
		||||
        <el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
 | 
			
		||||
        <el-button type="primary" :icon="Plus">新增</el-button>
 | 
			
		||||
      </div>
 | 
			
		||||
      <el-table :data="tableData" border class="table" ref="multipleTable" header-cell-class-name="table-header">
 | 
			
		||||
        <el-table-column prop="id" label="ID" width="55" align="center"></el-table-column>
 | 
			
		||||
        <el-table-column prop="name" label="用户名"></el-table-column>
 | 
			
		||||
        <el-table-column label="账户余额">
 | 
			
		||||
          <template #default="scope">¥{{ scope.row.money }}</template>
 | 
			
		||||
        </el-table-column>
 | 
			
		||||
        <el-table-column prop="name" label="姓名"></el-table-column>
 | 
			
		||||
        <el-table-column label="头像(查看大图)" align="center">
 | 
			
		||||
          <template #default="scope">
 | 
			
		||||
            <el-image
 | 
			
		||||
@@ -28,11 +26,11 @@
 | 
			
		||||
            </el-image>
 | 
			
		||||
          </template>
 | 
			
		||||
        </el-table-column>
 | 
			
		||||
        <el-table-column prop="address" label="地址"></el-table-column>
 | 
			
		||||
        <el-table-column prop="info" label="简介"></el-table-column>
 | 
			
		||||
        <el-table-column label="状态" align="center">
 | 
			
		||||
          <template #default="scope">
 | 
			
		||||
            <el-tag
 | 
			
		||||
                :type="scope.row.state === '成功' ? 'success' : scope.row.state === '失败' ? 'danger' : ''"
 | 
			
		||||
                :type="scope.row.state === '启用' ? 'success' : scope.row.state === '禁用' ? 'danger' : ''"
 | 
			
		||||
            >
 | 
			
		||||
              {{ scope.row.state }}
 | 
			
		||||
            </el-tag>
 | 
			
		||||
@@ -66,11 +64,11 @@
 | 
			
		||||
    <!-- 编辑弹出框 -->
 | 
			
		||||
    <el-dialog title="编辑" v-model="editVisible" width="30%">
 | 
			
		||||
      <el-form label-width="70px">
 | 
			
		||||
        <el-form-item label="用户名">
 | 
			
		||||
        <el-form-item label="姓名">
 | 
			
		||||
          <el-input v-model="form.name"></el-input>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="地址">
 | 
			
		||||
          <el-input v-model="form.address"></el-input>
 | 
			
		||||
        <el-form-item label="简介">
 | 
			
		||||
          <el-input v-model="form.info"></el-input>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
      </el-form>
 | 
			
		||||
      <template #footer>
 | 
			
		||||
@@ -89,7 +87,6 @@ import {ElMessage, ElMessageBox} from 'element-plus';
 | 
			
		||||
import {Delete, Edit, Plus, Search} from '@element-plus/icons-vue';
 | 
			
		||||
 | 
			
		||||
const query = reactive({
 | 
			
		||||
  address: '',
 | 
			
		||||
  name: '',
 | 
			
		||||
  pageIndex: 1,
 | 
			
		||||
  pageSize: 10
 | 
			
		||||
@@ -100,39 +97,35 @@ const pageTotal = ref(0);
 | 
			
		||||
const getData = () => {
 | 
			
		||||
  tableData.value = [{
 | 
			
		||||
    "id": 1,
 | 
			
		||||
    "name": "张三",
 | 
			
		||||
    "money": 123,
 | 
			
		||||
    "address": "广东省东莞市长安镇",
 | 
			
		||||
    "state": "成功",
 | 
			
		||||
    "date": "2019-11-1",
 | 
			
		||||
    "thumb": "https://lin-xin.gitee.io/images/post/wms.png"
 | 
			
		||||
    "name": "孔子",
 | 
			
		||||
    "info": "有朋自远方来,不亦说乎?",
 | 
			
		||||
    "state": "禁用",
 | 
			
		||||
    "date": "2023-06-21",
 | 
			
		||||
    "thumb": "/images/avatar/kong_zi.jpg"
 | 
			
		||||
  },
 | 
			
		||||
    {
 | 
			
		||||
      "id": 2,
 | 
			
		||||
      "name": "李四",
 | 
			
		||||
      "money": 456,
 | 
			
		||||
      "address": "广东省广州市白云区",
 | 
			
		||||
      "state": "成功",
 | 
			
		||||
      "date": "2019-10-11",
 | 
			
		||||
      "thumb": "https://lin-xin.gitee.io/images/post/node3.png"
 | 
			
		||||
      "name": "乔布斯",
 | 
			
		||||
      "info": "活着就是为了改变世界!难道还有其他原因吗?",
 | 
			
		||||
      "state": "禁用",
 | 
			
		||||
      "date": "2023-06-21",
 | 
			
		||||
      "thumb": "/images/avatar/steve_jobs.jpg"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": 3,
 | 
			
		||||
      "name": "王五",
 | 
			
		||||
      "money": 789,
 | 
			
		||||
      "address": "湖南省长沙市",
 | 
			
		||||
      "state": "失败",
 | 
			
		||||
      "date": "2019-11-11",
 | 
			
		||||
      "thumb": "https://lin-xin.gitee.io/images/post/parcel.png"
 | 
			
		||||
      "name": "马斯克",
 | 
			
		||||
      "info": "梦想要远大,如果你的梦想没有吓到你,说明你做得不对。",
 | 
			
		||||
      "state": "启用",
 | 
			
		||||
      "date": "2023-06-21",
 | 
			
		||||
      "thumb": "/images/avatar/elon_musk.jpg"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": 4,
 | 
			
		||||
      "name": "赵六",
 | 
			
		||||
      "money": 1011,
 | 
			
		||||
      "address": "福建省厦门市鼓浪屿",
 | 
			
		||||
      "state": "成功",
 | 
			
		||||
      "date": "2019-10-20",
 | 
			
		||||
      "thumb": "https://lin-xin.gitee.io/images/post/notice.png"
 | 
			
		||||
      "name": "鲁迅",
 | 
			
		||||
      "info": "自由之歌,永不过时,横眉冷对千夫指,俯首甘为孺子牛。",
 | 
			
		||||
      "state": "启用",
 | 
			
		||||
      "date": "2023-06-21",
 | 
			
		||||
      "thumb": "/images/avatar/lu_xun.jpg"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
  pageTotal.value = 5
 | 
			
		||||
@@ -168,20 +161,20 @@ const handleDelete = (index) => {
 | 
			
		||||
const editVisible = ref(false);
 | 
			
		||||
let form = reactive({
 | 
			
		||||
  name: '',
 | 
			
		||||
  address: ''
 | 
			
		||||
  info: ''
 | 
			
		||||
});
 | 
			
		||||
let idx = -1;
 | 
			
		||||
const handleEdit = (index, row) => {
 | 
			
		||||
  idx = index;
 | 
			
		||||
  form.name = row.name;
 | 
			
		||||
  form.address = row.address;
 | 
			
		||||
  form.info = row.info;
 | 
			
		||||
  editVisible.value = true;
 | 
			
		||||
};
 | 
			
		||||
const saveEdit = () => {
 | 
			
		||||
  editVisible.value = false;
 | 
			
		||||
  ElMessage.success(`修改第 ${idx + 1} 行成功`);
 | 
			
		||||
  tableData.value[idx].name = form.name;
 | 
			
		||||
  tableData.value[idx].address = form.address;
 | 
			
		||||
  tableData.value[idx].info = form.info;
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user