feat: function add for admin page is ready

This commit is contained in:
RockYang 2023-12-23 22:30:27 +08:00
parent 18b7484c5b
commit 4936896ff7
7 changed files with 103 additions and 48 deletions

View File

@ -32,46 +32,21 @@ const (
var InnerFunctions = []Function{
{
Name: FuncZaoBao,
Description: "每日早报,获取当天全球的热门新闻事件列表",
Description: "每日早报,获取当天新闻事件列表",
Parameters: Parameters{
Type: "object",
Properties: map[string]Property{
"text": {
Type: "string",
Description: "",
},
},
Required: []string{},
Type: "object",
Properties: map[string]Property{},
Required: []string{},
},
},
{
Name: FuncWeibo,
Description: "新浪微博热搜榜,微博当日热搜榜单",
Parameters: Parameters{
Type: "object",
Properties: map[string]Property{
"text": {
Type: "string",
Description: "",
},
},
Required: []string{},
},
},
{
Name: FuncHeadLine,
Description: "今日头条,给用户推荐当天的头条新闻,周榜热文",
Parameters: Parameters{
Type: "object",
Properties: map[string]Property{
"text": {
Type: "string",
Description: "",
},
},
Required: []string{},
Type: "object",
Properties: map[string]Property{},
Required: []string{},
},
},

View File

@ -8,6 +8,7 @@ import (
"chatplus/store/vo"
"chatplus/utils"
"chatplus/utils/resp"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
@ -33,22 +34,64 @@ func (h *FunctionHandler) Save(c *gin.Context) {
var f = model.Function{
Id: data.Id,
Name: data.Name,
Label: data.Label,
Description: data.Description,
Parameters: utils.JsonEncode(data.Parameters),
Required: utils.JsonEncode(data.Required),
Action: data.Action,
Enabled: false,
Token: data.Token,
Enabled: data.Enabled,
}
logger.Info(f)
res := h.db.Save(&f)
if res.Error != nil {
resp.ERROR(c, "error with save data:"+res.Error.Error())
return
}
data.Id = f.Id
resp.SUCCESS(c, data)
}
func (h *FunctionHandler) List(c *gin.Context) {
func (h *FunctionHandler) Set(c *gin.Context) {
var data struct {
Id uint `json:"id"`
Filed string `json:"filed"`
Value interface{} `json:"value"`
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
res := h.db.Model(&model.Function{}).Where("id = ?", data.Id).Update(data.Filed, data.Value)
if res.Error != nil {
resp.ERROR(c, "更新数据库失败!")
return
}
resp.SUCCESS(c)
}
func (h *FunctionHandler) List(c *gin.Context) {
var items []model.Function
res := h.db.Find(&items)
if res.Error != nil {
resp.ERROR(c, "No data found")
return
}
functions := make([]vo.Function, 0)
for _, v := range items {
var f vo.Function
err := utils.CopyObject(v, &f)
if err != nil {
continue
}
functions = append(functions, f)
}
resp.SUCCESS(c, functions)
}
func (h *FunctionHandler) Remove(c *gin.Context) {
id := h.GetInt(c, "id", 0)

View File

@ -17,7 +17,6 @@ import (
"chatplus/store"
"context"
"embed"
"github.com/go-redis/redis/v8"
"io"
"log"
"os"
@ -26,6 +25,8 @@ import (
"syscall"
"time"
"github.com/go-redis/redis/v8"
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
"go.uber.org/fx"
"gorm.io/gorm"
@ -351,6 +352,7 @@ func main() {
fx.Invoke(func(s *core.AppServer, h *admin.FunctionHandler) {
group := s.Engine.Group("/api/admin/function/")
group.POST("save", h.Save)
group.POST("set", h.Set)
group.GET("list", h.List)
group.GET("remove", h.Remove)
}),

View File

@ -8,5 +8,6 @@ type Function struct {
Parameters string
Required string
Action string
Token string
Enabled bool
}

View File

@ -14,9 +14,11 @@ type Property struct {
type Function struct {
Id uint `json:"id"`
Name string `json:"name"`
Label string `json:"label"`
Description string `json:"description"`
Parameters Parameters `json:"parameters"`
Required []string `json:"required"`
Action string `json:"action"`
Token string `json:"token"`
Enabled bool `json:"enabled"`
}

View File

@ -21,4 +21,6 @@ ALTER TABLE `chatgpt_functions` ADD `enabled` TINYINT(1) NOT NULL DEFAULT '0' CO
ALTER TABLE `chatgpt_functions` ADD `label` VARCHAR(30) NULL COMMENT '函数标签' AFTER `name`;
ALTER TABLE `chatgpt_mj_jobs` ADD `use_proxy` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '是否使用反代' AFTER `progress`;
ALTER TABLE `chatgpt_mj_jobs` CHANGE `img_url` `img_url` VARCHAR(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图片URL';
ALTER TABLE `chatgpt_mj_jobs` CHANGE `img_url` `img_url` VARCHAR(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图片URL';
ALTER TABLE `chatgpt_functions` ADD `token` VARCHAR(255) NULL COMMENT 'API授权token' AFTER `action`;

View File

@ -1,7 +1,7 @@
<template>
<div class="container role-list" v-loading="loading">
<div class="handle-box">
<el-button type="primary" :icon="Plus" @click="addRole">新增</el-button>
<el-button type="primary" :icon="Plus" @click="addRow">新增</el-button>
</div>
<el-row>
<el-table :data="tableData" :border="parentBorder" style="width: 100%">
@ -10,10 +10,11 @@
<span class="sort" :data-id="scope.row.id">{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="函数别名" prop="label"/>
<el-table-column label="功能描述" prop="description"/>
<el-table-column label="启用状态">
<template #default="scope">
<el-switch v-model="scope.row.enabled" @change="functionSet(scope.row)"/>
<el-switch v-model="scope.row.enabled" @change="functionSet('enabled',scope.row)"/>
</template>
</el-table-column>
@ -39,6 +40,7 @@
<el-form-item label="函数名称:" prop="name">
<el-input
v-model="item.name"
placeholder="函数名称最好为英文"
autocomplete="off"
/>
</el-form-item>
@ -113,6 +115,19 @@
</template>
</el-form-item>
<el-form-item label="API 地址:" prop="action">
<el-input
v-model="item.action"
autocomplete="off"
/>
</el-form-item>
<el-form-item label="API Token" prop="token">
<el-input
v-model="item.token"
autocomplete="off"
/>
</el-form-item>
<el-form-item label="启用状态">
<el-switch v-model="item.enabled"/>
</el-form-item>
@ -130,21 +145,19 @@
<script setup>
import {Delete, Plus, RemoveFilled} from "@element-plus/icons-vue";
import {Delete, Plus} from "@element-plus/icons-vue";
import {onMounted, reactive, ref} from "vue";
import {httpGet, httpPost} from "@/utils/http";
import {ElMessage} from "element-plus";
import {copyObj, removeArrayItem} from "@/utils/libs";
import {Sortable} from "sortablejs"
import {arrayContains, copyObj} from "@/utils/libs";
const showDialog = ref(false)
const parentBorder = ref(true)
const childBorder = ref(true)
const tableData = ref([])
const item = ref({parameters: []})
const item = ref({})
const params = ref([])
const formRef = ref(null)
const editRow = ref({})
const loading = ref(true)
const title = ref("新增函数")
@ -176,11 +189,24 @@ const curIndex = ref(0)
const rowEdit = function (index, row) {
curIndex.value = index
item.value = copyObj(row)
// initialize parameters
const props = item.value?.parameters?.properties
const required = item.value?.parameters?.required
const _params = []
for (let key in props) {
_params.push({
name: key,
type: props[key].type,
desc: props[key].description,
required: arrayContains(required, key)
})
}
params.value = _params
showDialog.value = true
}
const addRole = function () {
item.value = {parameters: []}
const addRow = function () {
item.value = {enabled:true}
showDialog.value = true
}
@ -233,8 +259,12 @@ const removeParam = function (index) {
params.value.splice(index, 1);
}
const functionSet = (row) => {
const functionSet = (filed,row) => {
httpPost('/api/admin/function/set', {id: row.id, filed: filed, value: row[filed]}).then(() => {
ElMessage.success("操作成功!")
}).catch(e => {
ElMessage.error("操作失败:" + e.message)
})
}
</script>