mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-18 01:06:39 +08:00
feat: the power log page is ready
This commit is contained in:
parent
8487d2c9eb
commit
8dda639b23
@ -56,6 +56,7 @@ type ChatSession struct {
|
|||||||
type ChatModel struct {
|
type ChatModel struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
Platform Platform `json:"platform"`
|
Platform Platform `json:"platform"`
|
||||||
|
Name string `json:"name"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
Power int `json:"power"`
|
Power int `json:"power"`
|
||||||
MaxTokens int `json:"max_tokens"` // 最大响应长度
|
MaxTokens int `json:"max_tokens"` // 最大响应长度
|
||||||
@ -86,6 +87,21 @@ const (
|
|||||||
PowerReward = PowerType(5) // 众筹
|
PowerReward = PowerType(5) // 众筹
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (t PowerType) String() string {
|
||||||
|
switch t {
|
||||||
|
case PowerRecharge:
|
||||||
|
return "充值"
|
||||||
|
case PowerConsume:
|
||||||
|
return "消费"
|
||||||
|
case PowerRefund:
|
||||||
|
return "退款"
|
||||||
|
case PowerReward:
|
||||||
|
return "众筹"
|
||||||
|
|
||||||
|
}
|
||||||
|
return "其他"
|
||||||
|
}
|
||||||
|
|
||||||
type PowerMark int
|
type PowerMark int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -22,6 +22,7 @@ func NewChatRoleHandler(app *core.AppServer, db *gorm.DB) *ChatRoleHandler {
|
|||||||
|
|
||||||
// List 获取用户聊天应用列表
|
// List 获取用户聊天应用列表
|
||||||
func (h *ChatRoleHandler) List(c *gin.Context) {
|
func (h *ChatRoleHandler) List(c *gin.Context) {
|
||||||
|
all := h.GetBool(c, "all")
|
||||||
userId := h.GetLoginUserId(c)
|
userId := h.GetLoginUserId(c)
|
||||||
var roles []model.ChatRole
|
var roles []model.ChatRole
|
||||||
res := h.DB.Where("enable", true).Order("sort_num ASC").Find(&roles)
|
res := h.DB.Where("enable", true).Order("sort_num ASC").Find(&roles)
|
||||||
@ -31,7 +32,7 @@ func (h *ChatRoleHandler) List(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取所有角色
|
// 获取所有角色
|
||||||
if userId == 0 {
|
if userId == 0 || all {
|
||||||
// 转成 vo
|
// 转成 vo
|
||||||
var roleVos = make([]vo.ChatRole, 0)
|
var roleVos = make([]vo.ChatRole, 0)
|
||||||
for _, r := range roles {
|
for _, r := range roles {
|
||||||
|
@ -105,6 +105,7 @@ func (h *ChatHandler) ChatHandle(c *gin.Context) {
|
|||||||
session.ChatId = chatId
|
session.ChatId = chatId
|
||||||
session.Model = types.ChatModel{
|
session.Model = types.ChatModel{
|
||||||
Id: chatModel.Id,
|
Id: chatModel.Id,
|
||||||
|
Name: chatModel.Name,
|
||||||
Value: chatModel.Value,
|
Value: chatModel.Value,
|
||||||
Power: chatModel.Power,
|
Power: chatModel.Power,
|
||||||
MaxTokens: chatModel.MaxTokens,
|
MaxTokens: chatModel.MaxTokens,
|
||||||
@ -535,7 +536,7 @@ func (h *ChatHandler) subUserPower(userVo vo.User, session *types.ChatSession, p
|
|||||||
Mark: types.PowerSub,
|
Mark: types.PowerSub,
|
||||||
Balance: userVo.Power - power,
|
Balance: userVo.Power - power,
|
||||||
Model: session.Model.Value,
|
Model: session.Model.Value,
|
||||||
Remark: fmt.Sprintf("提问长度:%d,回复长度:%d", promptTokens, replyTokens),
|
Remark: fmt.Sprintf("模型名称:%s, 提问长度:%d,回复长度:%d", session.Model.Name, promptTokens, replyTokens),
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
65
api/handler/power_log_handler.go
Normal file
65
api/handler/power_log_handler.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"chatplus/core"
|
||||||
|
"chatplus/core/types"
|
||||||
|
"chatplus/store/model"
|
||||||
|
"chatplus/store/vo"
|
||||||
|
"chatplus/utils"
|
||||||
|
"chatplus/utils/resp"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PowerLogHandler struct {
|
||||||
|
BaseHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPowerLogHandler(app *core.AppServer, db *gorm.DB) *PowerLogHandler {
|
||||||
|
return &PowerLogHandler{BaseHandler: BaseHandler{App: app, DB: db}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *PowerLogHandler) List(c *gin.Context) {
|
||||||
|
var data struct {
|
||||||
|
Model string `json:"model"`
|
||||||
|
Date []string `json:"date"`
|
||||||
|
Page int `json:"page"`
|
||||||
|
PageSize int `json:"page_size"`
|
||||||
|
}
|
||||||
|
if err := c.ShouldBindJSON(&data); err != nil {
|
||||||
|
resp.ERROR(c, types.InvalidArgs)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
session := h.DB.Session(&gorm.Session{})
|
||||||
|
if data.Model != "" {
|
||||||
|
session = session.Where("model", data.Model)
|
||||||
|
}
|
||||||
|
if len(data.Date) == 2 {
|
||||||
|
start := data.Date[0] + " 00:00:00"
|
||||||
|
end := data.Date[1] + " 00:00:00"
|
||||||
|
session = session.Where("created_at >= ? AND created_at <= ?", start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
var total int64
|
||||||
|
session.Model(&model.PowerLog{}).Count(&total)
|
||||||
|
var items []model.PowerLog
|
||||||
|
var list = make([]vo.PowerLog, 0)
|
||||||
|
offset := (data.Page - 1) * data.PageSize
|
||||||
|
res := session.Debug().Order("id DESC").Offset(offset).Limit(data.PageSize).Find(&items)
|
||||||
|
if res.Error == nil {
|
||||||
|
for _, item := range items {
|
||||||
|
var log vo.PowerLog
|
||||||
|
err := utils.CopyObject(item, &log)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.Id = item.Id
|
||||||
|
log.CreatedAt = item.CreatedAt.Unix()
|
||||||
|
log.TypeStr = item.Type.String()
|
||||||
|
list = append(list, log)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp.SUCCESS(c, vo.NewPage(total, data.Page, data.PageSize, list))
|
||||||
|
}
|
@ -108,6 +108,20 @@ func (h *UserHandler) Register(c *gin.Context) {
|
|||||||
h.DB.Model(&model.InviteCode{}).Where("code = ?", data.InviteCode).UpdateColumn("reg_num", gorm.Expr("reg_num + ?", 1))
|
h.DB.Model(&model.InviteCode{}).Where("code = ?", data.InviteCode).UpdateColumn("reg_num", gorm.Expr("reg_num + ?", 1))
|
||||||
if h.App.SysConfig.InvitePower > 0 {
|
if h.App.SysConfig.InvitePower > 0 {
|
||||||
h.DB.Model(&model.User{}).Where("id = ?", inviteCode.UserId).UpdateColumn("power", gorm.Expr("power + ?", h.App.SysConfig.InvitePower))
|
h.DB.Model(&model.User{}).Where("id = ?", inviteCode.UserId).UpdateColumn("power", gorm.Expr("power + ?", h.App.SysConfig.InvitePower))
|
||||||
|
// 记录邀请算力充值日志
|
||||||
|
var inviter model.User
|
||||||
|
h.DB.Where("id", inviteCode.UserId).First(&inviter)
|
||||||
|
h.DB.Create(&model.PowerLog{
|
||||||
|
UserId: inviter.Id,
|
||||||
|
Username: inviter.Username,
|
||||||
|
Type: types.PowerInvite,
|
||||||
|
Amount: h.App.SysConfig.InvitePower,
|
||||||
|
Balance: inviter.Power,
|
||||||
|
Mark: types.PowerAdd,
|
||||||
|
Model: "",
|
||||||
|
Remark: fmt.Sprintf("邀请用户注册奖励,金额:%d,邀请码:%s,新用户:%s", h.App.SysConfig.InvitePower, inviteCode.Code, user.Username),
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加邀请记录
|
// 添加邀请记录
|
||||||
|
@ -126,6 +126,7 @@ func main() {
|
|||||||
fx.Provide(handler.NewOrderHandler),
|
fx.Provide(handler.NewOrderHandler),
|
||||||
fx.Provide(handler.NewProductHandler),
|
fx.Provide(handler.NewProductHandler),
|
||||||
fx.Provide(handler.NewConfigHandler),
|
fx.Provide(handler.NewConfigHandler),
|
||||||
|
fx.Provide(handler.NewPowerLogHandler),
|
||||||
|
|
||||||
fx.Provide(admin.NewConfigHandler),
|
fx.Provide(admin.NewConfigHandler),
|
||||||
fx.Provide(admin.NewAdminHandler),
|
fx.Provide(admin.NewAdminHandler),
|
||||||
@ -401,8 +402,9 @@ func main() {
|
|||||||
group.GET("remove", h.RemoveChat)
|
group.GET("remove", h.RemoveChat)
|
||||||
group.GET("message/remove", h.RemoveMessage)
|
group.GET("message/remove", h.RemoveMessage)
|
||||||
}),
|
}),
|
||||||
fx.Provide(handler.NewTestHandler),
|
fx.Invoke(func(s *core.AppServer, h *handler.PowerLogHandler) {
|
||||||
fx.Invoke(func(s *core.AppServer, h *handler.TestHandler) {
|
group := s.Engine.Group("/api/powerLog/")
|
||||||
|
group.POST("list", h.List)
|
||||||
}),
|
}),
|
||||||
fx.Invoke(func(s *core.AppServer, db *gorm.DB) {
|
fx.Invoke(func(s *core.AppServer, db *gorm.DB) {
|
||||||
err := s.Run(db)
|
err := s.Run(db)
|
||||||
|
@ -6,9 +6,10 @@ type PowerLog struct {
|
|||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
UserId uint `json:"user_id"`
|
UserId uint `json:"user_id"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Type types.PowerType `json:"name"`
|
Type types.PowerType `json:"type"`
|
||||||
|
TypeStr string `json:"type_str"`
|
||||||
Amount int `json:"amount"`
|
Amount int `json:"amount"`
|
||||||
Mark types.PowerMark `json:"fund_type"`
|
Mark types.PowerMark `json:"mark"`
|
||||||
Balance int `json:"balance"`
|
Balance int `json:"balance"`
|
||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
.page-mj {
|
.page-mj {
|
||||||
background-color: #282c34;
|
background-color: #282c34;
|
||||||
|
height: 100vh;
|
||||||
}
|
}
|
||||||
.page-mj .inner {
|
.page-mj .inner {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -396,6 +397,10 @@
|
|||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
.page-mj .inner .task-list-box .no-more-data {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
.mj-list-item-prompt .el-icon {
|
.mj-list-item-prompt .el-icon {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
.page-mj {
|
.page-mj {
|
||||||
background-color: #282c34;
|
background-color: #282c34;
|
||||||
|
height 100vh
|
||||||
|
|
||||||
.inner {
|
.inner {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -281,6 +281,10 @@
|
|||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
.page-sd .inner .task-list-box .no-more-data {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
.page-sd .el-overlay-dialog .el-dialog {
|
.page-sd .el-overlay-dialog .el-dialog {
|
||||||
background-color: #1a1b1e;
|
background-color: #1a1b1e;
|
||||||
}
|
}
|
||||||
|
@ -6,107 +6,87 @@ body,
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
|
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home a {
|
.admin-home a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box {
|
.admin-home .content-box {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 250px;
|
left: 250px;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
/*padding-bottom: 30px;*/
|
padding-bottom: 30px;
|
||||||
-webkit-transition: left 0.3s ease-in-out;
|
-webkit-transition: left 0.3s ease-in-out;
|
||||||
transition: left 0.3s ease-in-out;
|
transition: left 0.3s ease-in-out;
|
||||||
background: #f0f0f0;
|
background: #f0f0f0;
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content {
|
.admin-home .content-box .content {
|
||||||
width: auto;
|
width: auto;
|
||||||
padding: 10px;
|
height: 100vh;
|
||||||
|
overflow-y: scroll;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
/*BaseForm*/
|
/*BaseForm*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .container {
|
.admin-home .content-box .content .container {
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .container .handle-box {
|
.admin-home .content-box .content .container .handle-box {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .crumbs {
|
.admin-home .content-box .content .crumbs {
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .el-table th {
|
.admin-home .content-box .content .el-table th {
|
||||||
background-color: #f5f7fa !important;
|
background-color: #f5f7fa !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .pagination {
|
.admin-home .content-box .content .pagination {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .plugins-tips {
|
.admin-home .content-box .content .plugins-tips {
|
||||||
padding: 20px 10px;
|
padding: 20px 10px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .el-button + .el-tooltip {
|
.admin-home .content-box .content .el-button + .el-tooltip {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .el-table tr:hover {
|
.admin-home .content-box .content .el-table tr:hover {
|
||||||
background: #f6faff;
|
background: #f6faff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .mgb20 {
|
.admin-home .content-box .content .mgb20 {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .move-enter-active,
|
.admin-home .content-box .content .move-enter-active,
|
||||||
.admin-home .content-box .content .move-leave-active {
|
.admin-home .content-box .content .move-leave-active {
|
||||||
transition: opacity 0.1s ease;
|
transition: opacity 0.1s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .move-enter-from,
|
.admin-home .content-box .content .move-enter-from,
|
||||||
.admin-home .content-box .content .move-leave-to {
|
.admin-home .content-box .content .move-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .form-box {
|
.admin-home .content-box .content .form-box {
|
||||||
width: 600px;
|
width: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .form-box .line {
|
.admin-home .content-box .content .form-box .line {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .el-time-panel__content::after,
|
.admin-home .content-box .content .el-time-panel__content::after,
|
||||||
.admin-home .content-box .content .el-time-panel__content::before {
|
.admin-home .content-box .content .el-time-panel__content::before {
|
||||||
margin-top: -7px;
|
margin-top: -7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) {
|
.admin-home .content-box .content .el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content [class*=" el-icon-"],
|
.admin-home .content-box .content [class*=" el-icon-"],
|
||||||
.admin-home .content-box .content [class^=el-icon-] {
|
.admin-home .content-box .content [class^=el-icon-] {
|
||||||
speak: none;
|
speak: none;
|
||||||
@ -120,7 +100,6 @@ body {
|
|||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content .el-sub-menu [class^=el-icon-] {
|
.admin-home .content-box .content .el-sub-menu [class^=el-icon-] {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
@ -128,11 +107,9 @@ body {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-box .content [hidden] {
|
.admin-home .content-box .content [hidden] {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-home .content-collapse {
|
.admin-home .content-collapse {
|
||||||
left: 65px;
|
left: 65px;
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,7 @@ body {
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
width: auto;
|
width: auto;
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
padding: 10px;
|
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
@ -292,4 +292,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-more-data {
|
||||||
|
text-align center
|
||||||
|
padding 20px
|
||||||
|
}
|
||||||
}
|
}
|
@ -69,6 +69,7 @@
|
|||||||
<el-input placeholder="手机号码"
|
<el-input placeholder="手机号码"
|
||||||
size="large"
|
size="large"
|
||||||
v-model="data.username"
|
v-model="data.username"
|
||||||
|
maxlength="11"
|
||||||
autocomplete="off">
|
autocomplete="off">
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
|
@ -57,7 +57,6 @@ const changeNav = (item) => {
|
|||||||
@import '@/assets/iconfont/iconfont.css';
|
@import '@/assets/iconfont/iconfont.css';
|
||||||
.home {
|
.home {
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: #25272D;
|
|
||||||
height 100vh
|
height 100vh
|
||||||
width 100%
|
width 100%
|
||||||
|
|
||||||
@ -67,6 +66,7 @@ const changeNav = (item) => {
|
|||||||
width 70px
|
width 70px
|
||||||
padding 10px 6px
|
padding 10px 6px
|
||||||
border-right: 1px solid #3c3c3c
|
border-right: 1px solid #3c3c3c
|
||||||
|
background-color: #25272D
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
display flex
|
display flex
|
||||||
|
@ -391,8 +391,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>创作记录</h2>
|
<h2>创作记录</h2>
|
||||||
<div class="finish-job-list" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.7)">
|
<div class="finish-job-list" v-loading="loading" element-loading-background="rgba(255, 255, 255, 0.5)">
|
||||||
<ItemList :items="finishedJobs" v-if="finishedJobs.length > 0" :width="240" :gap="16">
|
<div v-if="finishedJobs.length > 0">
|
||||||
|
<ItemList :items="finishedJobs" :width="240" :gap="16">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="job-item">
|
<div class="job-item">
|
||||||
<el-image
|
<el-image
|
||||||
@ -472,7 +473,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ItemList>
|
</ItemList>
|
||||||
|
<div class="no-more-data" v-if="isOver">
|
||||||
|
<span>没有更多数据了</span>
|
||||||
|
<i class="iconfont icon-face"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<el-empty :image-size="100" v-else/>
|
<el-empty :image-size="100" v-else/>
|
||||||
</div> <!-- end finish job list-->
|
</div> <!-- end finish job list-->
|
||||||
</div>
|
</div>
|
||||||
|
@ -350,8 +350,9 @@
|
|||||||
<el-empty :image-size="100" v-else/>
|
<el-empty :image-size="100" v-else/>
|
||||||
</div>
|
</div>
|
||||||
<h2>创作记录</h2>
|
<h2>创作记录</h2>
|
||||||
<div class="finish-job-list" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.7)">
|
<div class="finish-job-list" v-loading="loading" element-loading-background="rgba(255, 255, 255, 0.5)">
|
||||||
<ItemList :items="finishedJobs" v-if="finishedJobs.length > 0" :width="240" :gap="16">
|
<div v-if="finishedJobs.length > 0">
|
||||||
|
<ItemList :items="finishedJobs" :width="240" :gap="16">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="job-item animate" @click="showTask(scope.item)">
|
<div class="job-item animate" @click="showTask(scope.item)">
|
||||||
<el-image
|
<el-image
|
||||||
@ -387,6 +388,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ItemList>
|
</ItemList>
|
||||||
|
|
||||||
|
<div class="no-more-data" v-if="isOver">
|
||||||
|
<span>没有更多数据了</span>
|
||||||
|
<i class="iconfont icon-face"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<el-empty :image-size="100" v-else/>
|
<el-empty :image-size="100" v-else/>
|
||||||
</div> <!-- end finish job list-->
|
</div> <!-- end finish job list-->
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,31 +1,149 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="power-log" :style="{ height: winHeight + 'px' }">
|
<div class="power-log" v-loading="loading">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h2>消费日志</h2>
|
<h2>消费日志</h2>
|
||||||
|
|
||||||
|
<div class="list-box" :style="{height: listBoxHeight + 'px'}">
|
||||||
|
<div class="handle-box">
|
||||||
|
<el-input v-model="query.model" placeholder="模型" class="handle-input mr10" clearable></el-input>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="query.date"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
style="margin: 0 10px;width: 200px; position: relative;top:3px;"
|
||||||
|
/>
|
||||||
|
<el-button type="primary" :icon="Search" @click="fetchData">搜索</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-row v-if="items.length > 0">
|
||||||
|
<el-table :data="items" :row-key="row => row.id" table-layout="auto" border>
|
||||||
|
<el-table-column prop="username" label="用户"/>
|
||||||
|
<el-table-column prop="model" label="模型"/>
|
||||||
|
<el-table-column prop="type" label="类型">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag size="small" :type="tagColors[scope.row.type]">{{ scope.row.type_str }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="数额">
|
||||||
|
<template #default="scope">
|
||||||
|
<div>
|
||||||
|
<el-text type="success" v-if="scope.row.mark === 1">+{{ scope.row.amount }}</el-text>
|
||||||
|
<el-text type="danger" v-if="scope.row.mark === 0">-{{ scope.row.amount }}</el-text>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="balance" label="余额"/>
|
||||||
|
<el-table-column label="发生时间">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ dateFormat(scope.row['created_at']) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="remark" label="备注"/>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="pagination">
|
||||||
|
<el-pagination v-if="total > 0" background
|
||||||
|
layout="total,prev, pager, next"
|
||||||
|
:hide-on-single-page="true"
|
||||||
|
v-model:current-page="page"
|
||||||
|
v-model:page-size="pageSize"
|
||||||
|
@current-change="fetchData()"
|
||||||
|
:total="total"/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
<el-empty :image-size="100" v-else/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {ref} from "vue"
|
import {onMounted, ref} from "vue"
|
||||||
|
import {dateFormat} from "@/utils/libs";
|
||||||
|
import {Back, DocumentCopy, Search} from "@element-plus/icons-vue";
|
||||||
|
import Clipboard from "clipboard";
|
||||||
|
import {ElMessage} from "element-plus";
|
||||||
|
import {httpPost} from "@/utils/http";
|
||||||
|
|
||||||
|
const items = ref([])
|
||||||
|
const total = ref(0)
|
||||||
|
const page = ref(1)
|
||||||
|
const pageSize = ref(20)
|
||||||
|
const loading = ref(false)
|
||||||
|
const listBoxHeight = window.innerHeight - 117
|
||||||
|
const query = ref({
|
||||||
|
model: "",
|
||||||
|
date: []
|
||||||
|
})
|
||||||
|
const tagColors = ref(["", "success", "primary", "danger", "info", "warning"])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
fetchData()
|
||||||
|
const clipboard = new Clipboard('.copy-order-no');
|
||||||
|
clipboard.on('success', () => {
|
||||||
|
ElMessage.success("复制成功!");
|
||||||
|
})
|
||||||
|
|
||||||
|
clipboard.on('error', () => {
|
||||||
|
ElMessage.error('复制失败!');
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = () => {
|
||||||
|
loading.value = true
|
||||||
|
httpPost('/api/powerLog/list', {
|
||||||
|
model: query.value.model,
|
||||||
|
date: query.value.date,
|
||||||
|
page: page.value,
|
||||||
|
page_size: pageSize.value
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
items.value = res.data.items
|
||||||
|
total.value = res.data.total
|
||||||
|
page.value = res.data.page
|
||||||
|
pageSize.value = res.data.page_size
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
}).catch(e => {
|
||||||
|
loading.value = false
|
||||||
|
ElMessage.error("获取数据失败:" + e.message);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const winHeight = ref(window.innerHeight)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.power-log {
|
.power-log {
|
||||||
display: flex;
|
background-color #ffffff
|
||||||
justify-content: center;
|
|
||||||
background-color: #282c34;
|
|
||||||
color #ffffff
|
|
||||||
|
|
||||||
.inner {
|
.inner {
|
||||||
display flex
|
|
||||||
justify-content left
|
|
||||||
width 100%
|
|
||||||
padding 0 20px 20px 20px
|
padding 0 20px 20px 20px
|
||||||
|
|
||||||
|
.list-box {
|
||||||
|
.handle-box {
|
||||||
|
padding 20px 0
|
||||||
|
|
||||||
|
.el-input {
|
||||||
|
max-width 150px
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-date-editor {
|
||||||
|
max-width 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
display flex
|
||||||
|
justify-content center
|
||||||
|
width 100%
|
||||||
|
padding 20px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -44,6 +44,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="MidJourney算力" prop="mj_power">
|
||||||
|
<el-input v-model.number="system['mj_power']" placeholder="使用MidJourney画一张图消耗算力"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Stable-Diffusion算力" prop="sd_power">
|
||||||
|
<el-input v-model.number="system['sd_power']" placeholder="使用Stable-Diffusion画一张图消耗算力"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="DALL-E-3算力" prop="dall_power">
|
||||||
|
<el-input v-model.number="system['dall_power']" placeholder="使用DALL-E-3画一张图消耗算力"/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="开放注册" prop="enabled_register">
|
<el-form-item label="开放注册" prop="enabled_register">
|
||||||
<el-switch v-model="system['enabled_register']"/>
|
<el-switch v-model="system['enabled_register']"/>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
|
Loading…
Reference in New Issue
Block a user