mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-17 16:56:38 +08:00
feat: fixed bug for wechat bot to parse transactions. enable user to exchange reward with img_calls
This commit is contained in:
parent
ff4515bbf1
commit
b5641be30d
@ -13,10 +13,11 @@ ChatGLM,讯飞星火,文心一言等多个平台的大语言模型。集成了
|
|||||||
* 集成插件 API 功能,可结合大语言模型的 function 功能开发各种强大的插件,已内置实现了微博热搜,今日头条,今日早报和 AI
|
* 集成插件 API 功能,可结合大语言模型的 function 功能开发各种强大的插件,已内置实现了微博热搜,今日头条,今日早报和 AI
|
||||||
绘画函数插件。
|
绘画函数插件。
|
||||||
|
|
||||||
## 关于部署镜像申明
|
## 最新版本一键部署脚本
|
||||||
|
|
||||||
由于目前部署人数越来越多,本人的阿里云镜像仓库流量不够支撑大家使用了。所以从 v3.2.0 版本开始,一键部署脚本和部署镜像将只提供给 **[付费技术交流群]** 内用户使用。
|
```shell
|
||||||
代码依旧是全部开源的,大家可自行编译打包镜像。
|
bash -c "$(curl -fsSL https://img.r9it.com/tmp/install-v3.2.3-8b588904ef.sh)"
|
||||||
|
```
|
||||||
|
|
||||||
## 功能截图
|
## 功能截图
|
||||||
|
|
||||||
|
@ -159,6 +159,8 @@ type SystemConfig struct {
|
|||||||
EnabledMsg bool `json:"enabled_msg"` // 是否启用短信验证码服务
|
EnabledMsg bool `json:"enabled_msg"` // 是否启用短信验证码服务
|
||||||
RewardImg string `json:"reward_img"` // 众筹收款二维码地址
|
RewardImg string `json:"reward_img"` // 众筹收款二维码地址
|
||||||
EnabledReward bool `json:"enabled_reward"` // 启用众筹功能
|
EnabledReward bool `json:"enabled_reward"` // 启用众筹功能
|
||||||
|
ChatCallPrice float64 `json:"chat_call_price"` // 对话单次调用费用
|
||||||
|
ImgCallPrice float64 `json:"img_call_price"` // 绘图单次调用费用
|
||||||
EnabledAlipay bool `json:"enabled_alipay"` // 是否启用支付宝支付通道
|
EnabledAlipay bool `json:"enabled_alipay"` // 是否启用支付宝支付通道
|
||||||
OrderPayTimeout int `json:"order_pay_timeout"` //订单支付超时时间
|
OrderPayTimeout int `json:"order_pay_timeout"` //订单支付超时时间
|
||||||
DefaultModels []string `json:"default_models"` // 默认开通的 AI 模型
|
DefaultModels []string `json:"default_models"` // 默认开通的 AI 模型
|
||||||
@ -166,4 +168,5 @@ type SystemConfig struct {
|
|||||||
InviteChatCalls int `json:"invite_chat_calls"` // 邀请用户注册奖励对话次数
|
InviteChatCalls int `json:"invite_chat_calls"` // 邀请用户注册奖励对话次数
|
||||||
InviteImgCalls int `json:"invite_img_calls"` // 邀请用户注册奖励绘图次数
|
InviteImgCalls int `json:"invite_img_calls"` // 邀请用户注册奖励绘图次数
|
||||||
ForceInvite bool `json:"force_invite"` // 是否强制必须使用邀请码才能注册
|
ForceInvite bool `json:"force_invite"` // 是否强制必须使用邀请码才能注册
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -55,3 +55,16 @@ func (h *RewardHandler) List(c *gin.Context) {
|
|||||||
|
|
||||||
resp.SUCCESS(c, rewards)
|
resp.SUCCESS(c, rewards)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *RewardHandler) Remove(c *gin.Context) {
|
||||||
|
id := h.GetInt(c, "id", 0)
|
||||||
|
|
||||||
|
if id > 0 {
|
||||||
|
res := h.db.Where("id = ?", id).Delete(&model.Reward{})
|
||||||
|
if res.Error != nil {
|
||||||
|
resp.ERROR(c, "更新数据库失败!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp.SUCCESS(c)
|
||||||
|
}
|
||||||
|
@ -4,20 +4,24 @@ import (
|
|||||||
"chatplus/core"
|
"chatplus/core"
|
||||||
"chatplus/core/types"
|
"chatplus/core/types"
|
||||||
"chatplus/store/model"
|
"chatplus/store/model"
|
||||||
|
"chatplus/store/vo"
|
||||||
"chatplus/utils"
|
"chatplus/utils"
|
||||||
"chatplus/utils/resp"
|
"chatplus/utils/resp"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RewardHandler struct {
|
type RewardHandler struct {
|
||||||
BaseHandler
|
BaseHandler
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
lock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRewardHandler(server *core.AppServer, db *gorm.DB) *RewardHandler {
|
func NewRewardHandler(server *core.AppServer, db *gorm.DB) *RewardHandler {
|
||||||
h := RewardHandler{db: db}
|
h := RewardHandler{db: db, lock: sync.Mutex{}}
|
||||||
h.App = server
|
h.App = server
|
||||||
return &h
|
return &h
|
||||||
}
|
}
|
||||||
@ -26,15 +30,25 @@ func NewRewardHandler(server *core.AppServer, db *gorm.DB) *RewardHandler {
|
|||||||
func (h *RewardHandler) Verify(c *gin.Context) {
|
func (h *RewardHandler) Verify(c *gin.Context) {
|
||||||
var data struct {
|
var data struct {
|
||||||
TxId string `json:"tx_id"`
|
TxId string `json:"tx_id"`
|
||||||
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
if err := c.ShouldBindJSON(&data); err != nil {
|
if err := c.ShouldBindJSON(&data); err != nil {
|
||||||
resp.ERROR(c, types.InvalidArgs)
|
resp.ERROR(c, types.InvalidArgs)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user, err := utils.GetLoginUser(c, h.db)
|
||||||
|
if err != nil {
|
||||||
|
resp.HACKER(c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 移除转账单号中间的空格,防止有人复制的时候多复制了空格
|
// 移除转账单号中间的空格,防止有人复制的时候多复制了空格
|
||||||
data.TxId = strings.ReplaceAll(data.TxId, " ", "")
|
data.TxId = strings.ReplaceAll(data.TxId, " ", "")
|
||||||
|
|
||||||
|
h.lock.Lock()
|
||||||
|
defer h.lock.Unlock()
|
||||||
|
|
||||||
var item model.Reward
|
var item model.Reward
|
||||||
res := h.db.Where("tx_id = ?", data.TxId).First(&item)
|
res := h.db.Where("tx_id = ?", data.TxId).First(&item)
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
@ -47,15 +61,17 @@ func (h *RewardHandler) Verify(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := utils.GetLoginUser(c, h.db)
|
|
||||||
if err != nil {
|
|
||||||
resp.HACKER(c)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tx := h.db.Begin()
|
tx := h.db.Begin()
|
||||||
calls := (item.Amount + 0.1) * 10
|
exchange := vo.RewardExchange{}
|
||||||
res = h.db.Model(&user).UpdateColumn("calls", gorm.Expr("calls + ?", calls))
|
if data.Type == "chat" {
|
||||||
|
calls := math.Ceil(item.Amount / h.App.SysConfig.ChatCallPrice)
|
||||||
|
exchange.Calls = int(calls)
|
||||||
|
res = h.db.Model(&user).UpdateColumn("calls", gorm.Expr("calls + ?", calls))
|
||||||
|
} else if data.Type == "img" {
|
||||||
|
calls := math.Ceil(item.Amount / h.App.SysConfig.ImgCallPrice)
|
||||||
|
exchange.ImgCalls = int(calls)
|
||||||
|
res = h.db.Model(&user).UpdateColumn("img_calls", gorm.Expr("img_calls + ?", calls))
|
||||||
|
}
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
resp.ERROR(c, "更新数据库失败!")
|
resp.ERROR(c, "更新数据库失败!")
|
||||||
return
|
return
|
||||||
@ -64,6 +80,7 @@ func (h *RewardHandler) Verify(c *gin.Context) {
|
|||||||
// 更新核销状态
|
// 更新核销状态
|
||||||
item.Status = true
|
item.Status = true
|
||||||
item.UserId = user.Id
|
item.UserId = user.Id
|
||||||
|
item.Exchange = utils.JsonEncode(exchange)
|
||||||
res = h.db.Updates(&item)
|
res = h.db.Updates(&item)
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
|
@ -57,13 +57,7 @@ func main() {
|
|||||||
if configFile == "" {
|
if configFile == "" {
|
||||||
configFile = "config.toml"
|
configFile = "config.toml"
|
||||||
}
|
}
|
||||||
var debug bool
|
debug, _ := strconv.ParseBool(os.Getenv("APP_DEBUG"))
|
||||||
debugEnv := os.Getenv("DEBUG")
|
|
||||||
if debugEnv == "" {
|
|
||||||
debug = true
|
|
||||||
} else {
|
|
||||||
debug, _ = strconv.ParseBool(os.Getenv("DEBUG"))
|
|
||||||
}
|
|
||||||
logger.Info("Loading config file: ", configFile)
|
logger.Info("Loading config file: ", configFile)
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
@ -282,6 +276,7 @@ func main() {
|
|||||||
fx.Invoke(func(s *core.AppServer, h *admin.RewardHandler) {
|
fx.Invoke(func(s *core.AppServer, h *admin.RewardHandler) {
|
||||||
group := s.Engine.Group("/api/admin/reward/")
|
group := s.Engine.Group("/api/admin/reward/")
|
||||||
group.GET("list", h.List)
|
group.GET("list", h.List)
|
||||||
|
group.GET("remove", h.Remove)
|
||||||
}),
|
}),
|
||||||
fx.Invoke(func(s *core.AppServer, h *admin.DashboardHandler) {
|
fx.Invoke(func(s *core.AppServer, h *admin.DashboardHandler) {
|
||||||
group := s.Engine.Group("/api/admin/dashboard/")
|
group := s.Engine.Group("/api/admin/dashboard/")
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"github.com/eatmoreapple/openwechat"
|
"github.com/eatmoreapple/openwechat"
|
||||||
"github.com/skip2/go-qrcode"
|
"github.com/skip2/go-qrcode"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 微信收款机器人
|
// 微信收款机器人
|
||||||
@ -34,8 +36,13 @@ func (b *Bot) Run() error {
|
|||||||
}
|
}
|
||||||
// scan code login callback
|
// scan code login callback
|
||||||
b.bot.UUIDCallback = b.qrCodeCallBack
|
b.bot.UUIDCallback = b.qrCodeCallBack
|
||||||
|
debug, err := strconv.ParseBool(os.Getenv("APP_DEBUG"))
|
||||||
err := b.bot.Login()
|
if debug {
|
||||||
|
reloadStorage := openwechat.NewJsonFileHotReloadStorage("storage.json")
|
||||||
|
err = b.bot.HotLogin(reloadStorage, true)
|
||||||
|
} else {
|
||||||
|
err = b.bot.Login()
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -56,8 +63,8 @@ func (b *Bot) messageHandler(msg *openwechat.Message) {
|
|||||||
msg.MsgType == openwechat.MsgTypeApp ||
|
msg.MsgType == openwechat.MsgTypeApp ||
|
||||||
msg.AppMsgType == openwechat.AppMsgTypeUrl {
|
msg.AppMsgType == openwechat.AppMsgTypeUrl {
|
||||||
// 解析支付金额
|
// 解析支付金额
|
||||||
message, err := parseTransactionMessage(msg.Content)
|
message := parseTransactionMessage(msg.Content)
|
||||||
if err == nil {
|
if message.Url != "" {
|
||||||
transaction := extractTransaction(message)
|
transaction := extractTransaction(message)
|
||||||
logger.Infof("解析到收款信息:%+v", transaction)
|
logger.Infof("解析到收款信息:%+v", transaction)
|
||||||
var item model.Reward
|
var item model.Reward
|
||||||
|
@ -2,17 +2,15 @@ package wx
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Message 转账消息
|
// Message 转账消息
|
||||||
type Message struct {
|
type Message struct {
|
||||||
XMLName xml.Name `xml:"msg"`
|
Des string
|
||||||
AppMsg struct {
|
Url string
|
||||||
Des string `xml:"des"`
|
|
||||||
Url string `xml:"url"`
|
|
||||||
} `xml:"appmsg"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transaction 解析后的交易信息
|
// Transaction 解析后的交易信息
|
||||||
@ -23,20 +21,40 @@ type Transaction struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 解析微信转账消息
|
// 解析微信转账消息
|
||||||
func parseTransactionMessage(xmlData string) (*Message, error) {
|
func parseTransactionMessage(xmlData string) *Message {
|
||||||
var msg Message
|
decoder := xml.NewDecoder(strings.NewReader(xmlData))
|
||||||
if err := xml.Unmarshal([]byte(xmlData), &msg); err != nil {
|
message := Message{}
|
||||||
return nil, err
|
for {
|
||||||
}
|
token, err := decoder.Token()
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
return &msg, nil
|
switch se := token.(type) {
|
||||||
|
case xml.StartElement:
|
||||||
|
var value string
|
||||||
|
if se.Name.Local == "des" && message.Des == "" {
|
||||||
|
if err := decoder.DecodeElement(&value, &se); err == nil {
|
||||||
|
message.Des = strings.TrimSpace(value)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if se.Name.Local == "weapp_path" && !strings.Contains(message.Url, "customerDetails.html") {
|
||||||
|
if err := decoder.DecodeElement(&value, &se); err == nil {
|
||||||
|
message.Url = strings.TrimSpace(value)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &message
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出交易信息
|
// 导出交易信息
|
||||||
func extractTransaction(message *Message) Transaction {
|
func extractTransaction(message *Message) Transaction {
|
||||||
var tx = Transaction{}
|
var tx = Transaction{}
|
||||||
// 导出交易金额和备注
|
// 导出交易金额和备注
|
||||||
lines := strings.Split(message.AppMsg.Des, "\n")
|
lines := strings.Split(message.Des, "\n")
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
line = strings.TrimSpace(line)
|
line = strings.TrimSpace(line)
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
@ -59,10 +77,9 @@ func extractTransaction(message *Message) Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 解析交易 ID
|
// 解析交易 ID
|
||||||
index := strings.Index(message.AppMsg.Url, "trans_id=")
|
parse, err := url.Parse(message.Url)
|
||||||
if index != -1 {
|
if err == nil {
|
||||||
end := strings.LastIndex(message.AppMsg.Url, "&")
|
tx.TransId = parse.Query().Get("id")
|
||||||
tx.TransId = strings.TrimSpace(message.AppMsg.Url[index+9 : end])
|
|
||||||
}
|
}
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,10 @@ package model
|
|||||||
|
|
||||||
type Reward struct {
|
type Reward struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
UserId uint // 用户 ID
|
UserId uint // 用户 ID
|
||||||
TxId string // 交易ID
|
TxId string // 交易ID
|
||||||
Amount float64 // 打赏金额
|
Amount float64 // 打赏金额
|
||||||
Remark string // 打赏备注
|
Remark string // 打赏备注
|
||||||
Status bool // 核销状态
|
Status bool // 核销状态
|
||||||
|
Exchange string // 众筹兑换详情,JSON
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,16 @@ package vo
|
|||||||
|
|
||||||
type Reward struct {
|
type Reward struct {
|
||||||
BaseVo
|
BaseVo
|
||||||
UserId uint `json:"user_id"` // 用户 ID
|
UserId uint `json:"user_id"` // 用户 ID
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
TxId string `json:"tx_id"` // 交易ID
|
TxId string `json:"tx_id"` // 交易ID
|
||||||
Amount float64 `json:"amount"` // 打赏金额
|
Amount float64 `json:"amount"` // 打赏金额
|
||||||
Remark string `json:"remark"` // 打赏备注
|
Remark string `json:"remark"` // 打赏备注
|
||||||
Status bool `json:"status"` // 核销状态
|
Status bool `json:"status"` // 核销状态
|
||||||
|
Exchange RewardExchange `json:"exchange"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RewardExchange struct {
|
||||||
|
Calls int `json:"calls"`
|
||||||
|
ImgCalls int `json:"img_calls"`
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1 +1,2 @@
|
|||||||
ALTER TABLE `chatgpt_users` ADD `nickname` VARCHAR(30) NOT NULL COMMENT '昵称' AFTER `mobile`;
|
ALTER TABLE `chatgpt_users` ADD `nickname` VARCHAR(30) NOT NULL COMMENT '昵称' AFTER `mobile`;
|
||||||
|
ALTER TABLE `chatgpt_rewards` ADD `exchange` VARCHAR(255) NOT NULL COMMENT '兑换详情(json)' AFTER `status`;
|
||||||
|
@ -13,10 +13,19 @@
|
|||||||
</el-alert>
|
</el-alert>
|
||||||
|
|
||||||
<el-form :model="form">
|
<el-form :model="form">
|
||||||
<el-form-item label="">
|
<el-form-item label="转账单号">
|
||||||
<el-input v-model="form.tx_id"/>
|
<el-input v-model="form.tx_id"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
<el-form :model="form">
|
||||||
|
<el-form-item label="兑换类别">
|
||||||
|
<el-radio-group v-model="form.type">
|
||||||
|
<el-radio label="chat" border>对话聊天</el-radio>
|
||||||
|
<el-radio label="img" border>AI绘图</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -46,6 +55,7 @@ const showDialog = computed(() => {
|
|||||||
const title = ref('众筹码核销')
|
const title = ref('众筹码核销')
|
||||||
const form = ref({
|
const form = ref({
|
||||||
tx_id: '',
|
tx_id: '',
|
||||||
|
type: 'chat'
|
||||||
})
|
})
|
||||||
|
|
||||||
const emits = defineEmits(['hide']);
|
const emits = defineEmits(['hide']);
|
||||||
|
@ -142,7 +142,7 @@ const routes = [
|
|||||||
path: '/admin/reward',
|
path: '/admin/reward',
|
||||||
name: 'admin-reward',
|
name: 'admin-reward',
|
||||||
meta: {title: '众筹管理'},
|
meta: {title: '众筹管理'},
|
||||||
component: () => import('@/views/admin/RewardList.vue'),
|
component: () => import('@/views/admin/Reward.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/admin/loginLog',
|
path: '/admin/loginLog',
|
||||||
|
@ -21,6 +21,25 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="兑换详情">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row['exchange']['calls'] > 0">聊天{{ scope.row['exchange']['calls'] }}次</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row['exchange']['img_calls'] > 0" type="success">
|
||||||
|
绘图{{ scope.row['exchange']['img_calls'] }}次
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="操作" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-popconfirm title="确定要删除当前记录吗?" @confirm="remove(scope.row)">
|
||||||
|
<template #reference>
|
||||||
|
<el-button size="small" type="danger">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
@ -31,7 +50,7 @@
|
|||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
import {httpGet} from "@/utils/http";
|
import {httpGet} from "@/utils/http";
|
||||||
import {ElMessage} from "element-plus";
|
import {ElMessage} from "element-plus";
|
||||||
import {dateFormat} from "@/utils/libs";
|
import {dateFormat, removeArrayItem} from "@/utils/libs";
|
||||||
|
|
||||||
// 变量定义
|
// 变量定义
|
||||||
const items = ref([])
|
const items = ref([])
|
||||||
@ -52,6 +71,16 @@ httpGet('/api/admin/reward/list').then((res) => {
|
|||||||
ElMessage.error("获取数据失败");
|
ElMessage.error("获取数据失败");
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const remove = function (row) {
|
||||||
|
httpGet('/api/admin/reward/remove?id=' + row.id).then(() => {
|
||||||
|
ElMessage.success("删除成功!")
|
||||||
|
items.value = removeArrayItem(items.value, row, (v1, v2) => {
|
||||||
|
return v1.id === v2.id
|
||||||
|
})
|
||||||
|
}).catch((e) => {
|
||||||
|
ElMessage.error("删除失败:" + e.message)
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
@ -71,6 +71,15 @@
|
|||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<div v-if="system['enabled_reward']">
|
||||||
|
<el-form-item label="单次对话价格" prop="chat_call_price">
|
||||||
|
<el-input v-model="system['chat_call_price']" placeholder="众筹金额跟对话次数的兑换比例"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="单次绘图价格" prop="img_call_price">
|
||||||
|
<el-input v-model="system['img_call_price']" placeholder="众筹金额跟绘图次数的兑换比例"/>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-form-item label="收款二维码" prop="reward_img">
|
<el-form-item label="收款二维码" prop="reward_img">
|
||||||
<el-input v-model="system['reward_img']" placeholder="众筹收款二维码地址">
|
<el-input v-model="system['reward_img']" placeholder="众筹收款二维码地址">
|
||||||
<template #append>
|
<template #append>
|
||||||
@ -312,6 +321,8 @@ const save = function (key) {
|
|||||||
if (key === 'system') {
|
if (key === 'system') {
|
||||||
systemFormRef.value.validate((valid) => {
|
systemFormRef.value.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
system.value['img_call_price'] = parseFloat(system.value['img_call_price']) ?? 0
|
||||||
|
system.value['chat_call_price'] = parseFloat(system.value['chat_call_price']) ?? 0
|
||||||
httpPost('/api/admin/config/update', {key: key, config: system.value}).then(() => {
|
httpPost('/api/admin/config/update', {key: key, config: system.value}).then(() => {
|
||||||
ElMessage.success("操作成功!")
|
ElMessage.success("操作成功!")
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
|
Loading…
Reference in New Issue
Block a user