Merge branch 'master' of code.gitlink.org.cn:zolo2468216537/coeditor

master
joefalmko 3 weeks ago
commit de8a257c8b

4
.gitignore vendored

@ -4,7 +4,7 @@ GinSkeleton/.vscode
GinSkeleton/.idea/ GinSkeleton/.idea/
.idea/ .idea/
.idea .idea
GinSkeleton/storage/
GinSkeleton/storage/
ckeditor5/node_modules/* ckeditor5/node_modules/*
GinSkeleton/config/gorm_v2.yml
GinSkeleton/public/storage

@ -185,3 +185,58 @@ Authorization|Headers|string|必填|Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
"msg": "Success" "msg": "Success"
} }
``` ```
#### 请求图片文字识别
> <font color=#FF4500>*post*/admin/ai_recognition/pic_recognition</font>
参数字段|参数属性|类型|选项|默认值
---|---|---|---|---
pic|form-data|string|必填|"" (示例内容在 storage/app/test/文字识别.txt 中)
> 返回示例:
```json
{
"code": 200,
"data": {
"words": "out[entry]=\nfor each basic block ∈N -{entry}\nout[B] =\nchange = true\nwhile (changes) {\n// Find: fix point solution\nchange = false\nfor each B∈N - {entry} {\noldout = out[B]\nin[B]= Uout[P]\nP∈pred[B]\nout[B] = GEN[B] (in[B]∩ PRSV[B])\nif(out[B] ≠ oldout) change = true;\n}\n}\n"
},
"msg": "Success"
}
```
#### 请求语音识别
> <font color=#FF4500>*post*/admin/ai_recognition/voc_recognition</font>
参数字段|参数属性|类型|选项|默认值
---|---|---|---|---
voc|form-data|string|必填|"" (示例内容在 storage/app/test/A13_221.txt 中)
> 返回示例:
```json
{
"code": 200,
"data": {
"words": "韩国的基本目标是射箭三块金牌只到三块金牌羽毛球两块金牌以及举重等12块金牌。\n"
},
"msg": "Success"
}
```
#### 请求文本优化
> <font color=#FF4500>*post*/admin/ai_doc/doc_refine</font>
参数字段|参数属性|类型|选项|默认值
---|---|---|---|---
doc|form-data|string|必填|""
background|form-data|string||""
type|form-data|string|必填|"abstract"/"decorate"/"sequel_writing"/"rewrite_wrong"/"translate"
> 返回示例:
```json
{
"code": 200,
"data": {
"new_doc": "Whether it's a business report, an academic paper, or a creative piece of writing, this module can polish the language, correct grammar and spelling errors, and optimize the overall structure."
},
"msg": "Success"
}
```

@ -77,4 +77,12 @@ const (
CaptchaCheckOkMsg string = "验证码校验通过" CaptchaCheckOkMsg string = "验证码校验通过"
CaptchaCheckFailCode int = -400355 CaptchaCheckFailCode int = -400355
CaptchaCheckFailMsg string = "验证码校验失败" CaptchaCheckFailMsg string = "验证码校验失败"
// 模型功能按相关
PicRecognitionFailMsg string = "图片文字识别失败"
PicRecognitionFailCode int = -400450
VocRecognitionFailMsg string = "语音识别失败"
VocRecognitionFailCode int = -400451
DocRefineFailMsg string = "文档优化失败"
DocRefineFailCode int = -400452
) )

@ -67,4 +67,10 @@ const (
ErrorCasbinCreateAdaptFail string = "casbin NewAdapterByDBUseTableName 发生错误:" ErrorCasbinCreateAdaptFail string = "casbin NewAdapterByDBUseTableName 发生错误:"
ErrorCasbinCreateEnforcerFail string = "casbin NewEnforcer 发生错误:" ErrorCasbinCreateEnforcerFail string = "casbin NewEnforcer 发生错误:"
ErrorCasbinNewModelFromStringFail string = "NewModelFromString 调用时出错:" ErrorCasbinNewModelFromStringFail string = "NewModelFromString 调用时出错:"
// baiduCE 访问出现的错误
ErrorBaiduCEGetTokenFail string = "访问百度智能云时获得access_token 出现问题:"
ErrorBaiduCEUseOCRFail string = "使用百度智能云OCR接口失败"
ErrorBaiduCEPostFail string = "使用百度智能云接口失败(POST通用)"
ErrorBaiduCEUseVOPFail string = "使用百度智能云VOP接口失败"
) )

@ -0,0 +1,32 @@
package web
import (
"goskeleton/app/global/consts"
"goskeleton/app/service/ai_model_cli"
"goskeleton/app/utils/response"
"github.com/gin-gonic/gin"
)
type AiRecognition struct {
}
// Ai 模型识别模块与ai相关的识别功能包括图片文字识别、语音识别
//
// 图片文字识别
func (u *AiRecognition) PicRecognition(context *gin.Context) {
if r, recogWords := ai_model_cli.RequestOCR(context); r {
response.Success(context, consts.CurdStatusOkMsg, recogWords)
} else {
response.Fail(context, consts.PicRecognitionFailCode, consts.PicRecognitionFailMsg, "")
}
}
// 语音文字识别
func (u *AiRecognition) VocRecognition(context *gin.Context) {
if r, recogWords := ai_model_cli.RequestVOP(context); r {
response.Success(context, consts.CurdStatusOkMsg, recogWords)
} else {
response.Fail(context, consts.VocRecognitionFailCode, consts.VocRecognitionFailMsg, "")
}
}

@ -0,0 +1,22 @@
package web
import (
"goskeleton/app/global/consts"
"goskeleton/app/service/ai_model_cli"
"goskeleton/app/utils/response"
"github.com/gin-gonic/gin"
)
type DocRefine struct {
}
// Ai 模型进行文档优化
func (u *DocRefine) DocRefine(context *gin.Context) {
if r, recogWords := ai_model_cli.RequestQianFan(context); r {
response.Success(context, consts.CurdStatusOkMsg, recogWords)
} else {
response.Fail(context, consts.DocRefineFailCode, consts.DocRefineFailMsg, "")
}
}

@ -5,6 +5,8 @@ import (
"goskeleton/app/global/consts" "goskeleton/app/global/consts"
"goskeleton/app/http/validator/common/upload_files" "goskeleton/app/http/validator/common/upload_files"
"goskeleton/app/http/validator/common/websocket" "goskeleton/app/http/validator/common/websocket"
"goskeleton/app/http/validator/web/ai_doc.go"
"goskeleton/app/http/validator/web/ai_recognition"
"goskeleton/app/http/validator/web/users" "goskeleton/app/http/validator/web/users"
) )
@ -46,4 +48,13 @@ func WebRegisterValidator() {
// Websocket 连接验证器 // Websocket 连接验证器
key = consts.ValidatorPrefix + "WebsocketConnect" key = consts.ValidatorPrefix + "WebsocketConnect"
containers.Set(key, websocket.Connect{}) containers.Set(key, websocket.Connect{})
// ai 识别功能相关
key = consts.ValidatorPrefix + "PicRecognition"
containers.Set(key, ai_recognition.PicRecognition{})
key = consts.ValidatorPrefix + "VocRecognition"
containers.Set(key, ai_recognition.VocRecognition{})
// ai文档优化
key = consts.ValidatorPrefix + "DocRefine"
containers.Set(key, ai_doc.DocRefine{})
} }

@ -0,0 +1,47 @@
package ai_doc
import (
"goskeleton/app/global/consts"
"goskeleton/app/http/controller/web"
"goskeleton/app/http/validator/core/data_transfer"
"goskeleton/app/utils/response"
"strings"
"github.com/gin-gonic/gin"
)
type DocRefine struct {
Type string `form:"type" json:"type" binding:"required"` // 必填、
Doc string `form:"doc" json:"doc" binding:"required"` // 必填、对于文本,表示它的长度>=1
Background string `form:"background" json:"background" `
}
var Types = []string{"abstract", "decorate", "sequel_writing", "rewrite_wrong", "translate"}
func (d DocRefine) CheckParams(context *gin.Context) {
if err := context.ShouldBind(&d); err != nil {
// 将表单参数验证器出现的错误直接交给错误翻译器统一处理即可
response.ValidatorError(context, err)
return
}
// 判断是否在类型中
t := d.Type
isExit := false
for _, e := range Types {
if strings.TrimSpace(t) == e {
isExit = true
break
}
}
if !isExit {
response.ErrorSystem(context, "DocRefine表单参数验证器json化失败", "")
return
}
// 该函数主要是将本结构体的字段(成员)按照 consts.ValidatorPrefix+ json标签对应的 键 => 值 形式绑定在上下文,便于下一步(控制器)可以直接通过 context.Get(键) 获取相关值
extraAddBindDataContext := data_transfer.DataAddContext(d, consts.ValidatorPrefix, context)
if extraAddBindDataContext == nil {
response.ErrorSystem(context, "DocRefine表单参数验证器json化失败", "")
return
}
(&web.DocRefine{}).DocRefine(extraAddBindDataContext)
}

@ -0,0 +1,64 @@
package ai_recognition
import (
"bytes"
"encoding/base64"
"goskeleton/app/global/consts"
"goskeleton/app/http/controller/web"
"goskeleton/app/http/validator/core/data_transfer"
"goskeleton/app/utils/response"
"image"
"math"
"github.com/gin-gonic/gin"
)
type PicRecognition struct {
Pic string `form:"pic" json:"pic" binding:"required"` // 必填、对于文本,表示它的长度>=1
}
func (p PicRecognition) CheckParams(context *gin.Context) {
if err := context.ShouldBind(&p); err != nil {
// 将表单参数验证器出现的错误直接交给错误翻译器统一处理即可
response.ValidatorError(context, err)
return
}
// 该函数主要是将本结构体的字段(成员)按照 consts.ValidatorPrefix+ json标签对应的 键 => 值 形式绑定在上下文,便于下一步(控制器)可以直接通过 context.Get(键) 获取相关值
extraAddBindDataContext := data_transfer.DataAddContext(p, consts.ValidatorPrefix, context)
if extraAddBindDataContext == nil {
response.ErrorSystem(context, "PicRecognition表单参数验证器json化失败", "")
return
}
pic := p.Pic
// 先进行 URL 解码
// decodedPic, err := url.QueryUnescape(pic)
// if err != nil {
// response.ErrorSystem(context, "PicRecognition表单参数验证器URL解码失败", "")
// return
// }
// 再进行 Base64 解码
decodedData, err := base64.StdEncoding.DecodeString(pic)
if err != nil {
response.ErrorSystem(context, "PicRecognition表单参数验证器Base64解码失败", "")
return
}
// 检查大小不超过 10M10 * 1024 * 1024 字节)
if len(decodedData) > 10*1024*1024 {
response.ErrorSystem(context, "PicRecognition表单参数验证器图片大小超过 10M", "")
return
}
// 将字节数据转换为图像以检查格式和尺寸
img, _, err := image.Decode(bytes.NewReader(decodedData))
if err != nil {
return
}
bounds := img.Bounds()
minSide := math.Min(float64(bounds.Dx()), float64(bounds.Dy()))
maxSide := math.Max(float64(bounds.Dx()), float64(bounds.Dy()))
// 最短边至少 15px最长边最大 8192px
if minSide < 15 || maxSide > 8192 {
response.ErrorSystem(context, "PicRecognition表单参数验证器图片尺寸过大或过小", "")
return
}
(&web.AiRecognition{}).PicRecognition(extraAddBindDataContext)
}

@ -0,0 +1,43 @@
package ai_recognition
import (
"encoding/base64"
"goskeleton/app/global/consts"
"goskeleton/app/http/controller/web"
"goskeleton/app/http/validator/core/data_transfer"
"goskeleton/app/utils/response"
"github.com/gin-gonic/gin"
)
type VocRecognition struct {
Voc string `form:"voc" json:"voc" binding:"required"` // 必填、对于文本,表示它的长度>=1
}
func (v VocRecognition) CheckParams(context *gin.Context) {
if err := context.ShouldBind(&v); err != nil {
// 将表单参数验证器出现的错误直接交给错误翻译器统一处理即可
response.ValidatorError(context, err)
return
}
// 该函数主要是将本结构体的字段(成员)按照 consts.ValidatorPrefix+ json标签对应的 键 => 值 形式绑定在上下文,便于下一步(控制器)可以直接通过 context.Get(键) 获取相关值
extraAddBindDataContext := data_transfer.DataAddContext(v, consts.ValidatorPrefix, context)
if extraAddBindDataContext == nil {
response.ErrorSystem(context, "VocRecognition表单参数验证器json化失败", "")
return
}
voc := v.Voc
// 先进行 URL 解码
// decodedVoc, err := url.QueryUnescape(voc)
// if err != nil {
// response.ErrorSystem(context, "VocRecognition表单参数验证器URL解码失败", "")
// return
// }
// 再进行 Base64 解码
_, err := base64.StdEncoding.DecodeString(voc)
if err != nil {
response.ErrorSystem(context, "VocRecognition表单参数验证器Base64解码失败", "")
return
}
(&web.AiRecognition{}).VocRecognition(extraAddBindDataContext)
}

@ -0,0 +1,50 @@
package ai_model_cli
import (
"context"
"fmt"
"goskeleton/app/global/variable"
"strings"
"github.com/baidubce/bce-qianfan-sdk/go/qianfan"
"github.com/gin-gonic/gin"
)
func RequestQianFan(cont *gin.Context) (r bool, c interface{}) {
// 使用安全认证AK/SK鉴权通过环境变量初始化
qianfan.GetConfig().AccessKey = variable.ConfigYml.GetString("BaiduCE.QianFanAccessKey")
qianfan.GetConfig().SecretKey = variable.ConfigYml.GetString("BaiduCE.QianFanSecretKey")
// 指定特定模型
chat := qianfan.NewChatCompletion(
qianfan.WithModel("ERNIE-4.0-8K"),
)
message := ""
t := strings.TrimSpace(cont.PostForm("type"))
b := strings.TrimSpace(cont.PostForm("background"))
d := strings.TrimSpace(cont.PostForm("doc"))
switch t {
case "abstract":
message = "请在这个背景下:" + b + "\n对下文进行概括不要改变原有语言" + d
case "decorate":
message = "请在这个背景下:" + b + "\n对下文进行润色不要改变原有语言" + d
case "sequel_writing":
message = "请在这个背景下:" + b + "\n对下文进行续写不要改变原有语言" + d
case "rewrite_wrong":
message = "请在这个背景下:" + b + "\n对下文进行改错不要改变原有语言" + d
case "translate":
message = "请在这个背景下:" + b + "\n对下文进行翻译" + d
}
resp, _ := chat.Do(
context.TODO(),
&qianfan.ChatCompletionRequest{
Messages: []qianfan.ChatCompletionMessage{
qianfan.ChatCompletionUserMessage(message),
},
},
)
fmt.Println(resp.Result)
return true, gin.H{"new_doc": resp.Result}
}

@ -0,0 +1,76 @@
package ai_model_cli
import (
"goskeleton/app/global/my_errors"
"goskeleton/app/global/variable"
"goskeleton/app/utils/baidubce"
"net/http"
"net/url"
"strings"
"github.com/gin-gonic/gin"
)
/**
* ocr(),
* @return
*/
func RequestOCR(context *gin.Context) (r bool, c interface{}) {
path := "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=" + baidubce.GetAccessToken()
// 获得图片数据,需要 base64 和urlencode处理
// TODO:linlnf
content := context.PostForm("pic")
// 组装 body 数据参数在该网址https://cloud.baidu.com/doc/OCR/s/1k3h7y3db
data := make(url.Values)
data.Set("detect_direction", "false")
data.Set("paragraph", "false")
data.Set("probability", "false")
data.Set("multidirectional_recognize", "false")
data.Set("image", content)
payload := strings.NewReader(data.Encode())
client := &http.Client{}
// 请求数据
req, err := http.NewRequest("POST", path, payload)
if err != nil {
variable.ZapLog.Error(my_errors.ErrorBaiduCEUseOCRFail + err.Error())
return false, nil
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Accept", "application/json")
res, err := client.Do(req)
if err != nil {
variable.ZapLog.Error(my_errors.ErrorBaiduCEUseOCRFail + err.Error())
return false, nil
}
defer res.Body.Close()
//从res中提取识别出的字符信息
mbody, err := baidubce.DecodeResBody(res, "ocr")
if err != nil {
variable.ZapLog.Error(my_errors.ErrorBaiduCEUseOCRFail + err.Error())
return false, nil
}
return true, gin.H{
"words": decodeOCRBody2Str(mbody),
}
}
/*
*
* @return
*/
func decodeOCRBody2Str(mbody map[string]interface{}) (str string) {
words, ok := mbody["words_result"]
if ok {
sliceWords, ok := words.([]interface{})
if ok {
// 遍历切片
for _, word := range sliceWords {
str += word.(map[string]interface{})["words"].(string) + "\n"
}
}
return str
}
return ""
}

@ -0,0 +1,89 @@
package ai_model_cli
import (
"bytes"
"encoding/base64"
"encoding/json"
"goskeleton/app/global/my_errors"
"goskeleton/app/global/variable"
"goskeleton/app/utils/baidubce"
"net/http"
"github.com/gin-gonic/gin"
)
type BaiduBCEVOP struct {
Format string `json:"format"`
Rate int `json:"rate"`
Channel int `json:"channel"`
Cuid string `json:"cuid"`
DevPid int `json:"dev_pid"`
Speech string `json:"speech"`
Len int `json:"len"`
Token string `json:"token"`
}
/**
* ocr(),
* @return
*/
func RequestVOP(context *gin.Context) (r bool, c interface{}) {
path := "https://vop.baidu.com/pro_api"
// 获得语音数据,需要 base64 和urlencode处理
// TODO:linlnf
content := context.PostForm("voc")
// 再进行 Base64 解码
decodedVoc, _ := base64.StdEncoding.DecodeString(content)
// 组装 body 数据参数在该网址https://cloud.baidu.com/doc/SPEECH/s/4lbxdz34z
jsonData, _ := json.Marshal(BaiduBCEVOP{
Format: "pcm",
Rate: 16000,
Channel: 1,
Cuid: "kRxqyFGTgJOtBU4b5LnhWEvX6g8EU4Z7",
DevPid: 80001,
Speech: content,
Len: len(decodedVoc),
Token: baidubce.GetAccessToken(),
})
client := &http.Client{}
// 请求数据
req, err := http.NewRequest("POST", path, bytes.NewBuffer(jsonData))
if err != nil {
variable.ZapLog.Error(my_errors.ErrorBaiduCEUseVOPFail + err.Error())
return false, nil
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
res, err := client.Do(req)
if err != nil {
variable.ZapLog.Error(my_errors.ErrorBaiduCEUseVOPFail + err.Error())
return false, nil
}
defer res.Body.Close()
//从res中提取识别出的信息
mbody, err := baidubce.DecodeResBody(res, "vop")
if err != nil {
variable.ZapLog.Error(my_errors.ErrorBaiduCEUseVOPFail + err.Error())
return false, nil
}
return true, gin.H{
"words": decodeBody2Str(mbody),
}
}
/*
*
* @return
*/
func decodeBody2Str(mbody map[string]interface{}) (str string) {
words, ok := mbody["result"].([]interface{})
if ok {
for _, word := range words {
str += word.(string) + "\n"
}
return str
}
return ""
}

@ -0,0 +1,79 @@
package baidubce
import (
"encoding/json"
"errors"
"fmt"
"goskeleton/app/global/my_errors"
"goskeleton/app/global/variable"
"io"
"net/http"
"strings"
)
/**
* 使 AKSK Access Token
* @return string Access Token
*/
func GetAccessToken() string {
url := "https://aip.baidubce.com/oauth/2.0/token"
API_KEY := variable.ConfigYml.GetString("BaiduCE.ApiKey")
SECRET_KEY := variable.ConfigYml.GetString("BaiduCE.SecretKey")
postData := fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", API_KEY, SECRET_KEY)
resp, err := http.Post(url, "application/x-www-form-urlencoded", strings.NewReader(postData))
if err != nil {
variable.ZapLog.Error(my_errors.ErrorBaiduCEGetTokenFail + err.Error())
return ""
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
variable.ZapLog.Error(my_errors.ErrorBaiduCEGetTokenFail + err.Error())
return ""
}
accessTokenObj := map[string]any{}
_ = json.Unmarshal([]byte(body), &accessTokenObj)
return accessTokenObj["access_token"].(string)
}
func DecodeResBody(res *http.Response, flag string) (mbody map[string]interface{}, err error) {
body, err := io.ReadAll(res.Body)
if err != nil {
variable.ZapLog.Error(my_errors.ErrorBaiduCEPostFail + flag + ", " + err.Error())
return nil, err
}
// json 格式的 body
var jbody interface{}
fmt.Println(string(body))
err = json.Unmarshal(body, &jbody)
if err != nil {
variable.ZapLog.Error(my_errors.ErrorBaiduCEPostFail + flag + ", " + err.Error())
return nil, err
}
mbody = jbody.(map[string]interface{})
var err_str string
switch flag {
case "vop":
err_str1, _ := mbody["err_msg"].(string)
if err_str1 == "success." {
err_str = ""
} else {
err_str = err_str1
}
default:
err_str2, _ := mbody["error_msg"].(string)
if err_str2 == "" {
err_str = ""
} else {
err_str = err_str2
}
}
if err_str != "" {
variable.ZapLog.Error(my_errors.ErrorBaiduCEPostFail + flag + ", " + err_str)
err = errors.New(err_str)
return nil, err
}
return mbody, err
}

@ -1,6 +1,7 @@
package files package files
import ( import (
"encoding/base64"
"goskeleton/app/global/my_errors" "goskeleton/app/global/my_errors"
"goskeleton/app/global/variable" "goskeleton/app/global/variable"
"mime/multipart" "mime/multipart"
@ -47,3 +48,12 @@ func GetFilesMimeByFp(fp multipart.File) string {
return http.DetectContentType(buffer) return http.DetectContentType(buffer)
} }
// 读取本地文件进行Base64编码
func GetFileBase64(filePath string) (int, string, error) {
data, err := os.ReadFile(filePath)
if err != nil {
return 0, "", err
}
return len(data), base64.StdEncoding.EncodeToString(data), nil
}

@ -144,3 +144,9 @@ Captcha:
captchaValue: "captcha_value" #验证码值提交时的键名 captchaValue: "captcha_value" #验证码值提交时的键名
length: 4 # 验证码生成时的长度 length: 4 # 验证码生成时的长度
BaiduCE:
ApiKey: "AR1SUIjaKSsCcDjj11QzHDOc" # 生成鉴权签名时使用的 API_KEY
SecretKey: "zvEb5CzpuGCZNdQC1TPmDh3IOWn5aWDT" # 生成鉴权签名时使用的 SECRET_KEY
QianFanAccessKey: "ALTAKOxb5YvHncyFr7Qbuv1cK0" # 访问千帆sdk 时用的 AccessKey
QianFanSecretKey: "1edf17c358574e75b9913ebff7d95b61" # 访问千帆sdk 时用的 SecretKey

@ -31,6 +31,8 @@ require (
require ( require (
github.com/BurntSushi/toml v1.4.0 // indirect github.com/BurntSushi/toml v1.4.0 // indirect
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
github.com/baidubce/bce-qianfan-sdk/go/qianfan v0.0.12 // indirect
github.com/baidubce/bce-sdk-go v0.9.164 // indirect
github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/casbin/govaluate v1.2.0 // indirect github.com/casbin/govaluate v1.2.0 // indirect
@ -67,6 +69,7 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230126093431-47fa9a501578 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230126093431-47fa9a501578 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cast v1.6.0 // indirect

@ -20,6 +20,10 @@ github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ= github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg= github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
github.com/baidubce/bce-qianfan-sdk/go/qianfan v0.0.12 h1:IGb3rV9QyCJa/d3ZvXiuZkacO0BS2pmGi1BP7dZ5IEA=
github.com/baidubce/bce-qianfan-sdk/go/qianfan v0.0.12/go.mod h1:f/kIWWvAHAcU7bzgkfN30SkpN0I4lLvsJkljVK6v5YY=
github.com/baidubce/bce-sdk-go v0.9.164 h1:7gswLMsdQyarovMKuv3i6wxFQ3BQgvc5CmyGXb/D/xA=
github.com/baidubce/bce-sdk-go v0.9.164/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
@ -167,6 +171,8 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
@ -247,6 +253,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

@ -61,6 +61,22 @@ func InitWebRouter_Co() *gin.Engine {
// 刷新token当过期的token在允许失效的延长时间范围内用旧token换取新token // 刷新token当过期的token在允许失效的延长时间范围内用旧token换取新token
refreshToken.Use(authorization.RefreshTokenConditionCheck()).POST("refreshtoken", validatorFactory.Create(consts.ValidatorPrefix+"RefreshToken")) refreshToken.Use(authorization.RefreshTokenConditionCheck()).POST("refreshtoken", validatorFactory.Create(consts.ValidatorPrefix+"RefreshToken"))
} }
// TODO:linlnf
// 人工智能识别相关
aiRecognition := backend.Group("ai_recognition/")
{
// 请求图片文字识别
aiRecognition.POST("pic_recognition", validatorFactory.Create(consts.ValidatorPrefix+"PicRecognition"))
// 请求语音识别
aiRecognition.POST("voc_recognition", validatorFactory.Create(consts.ValidatorPrefix+"VocRecognition"))
}
// TODO:linlnf
// 人工智能文档处理相关
aiDoc := backend.Group("ai_doc/")
{
// 请求优化文字
aiDoc.POST("doc_refine", validatorFactory.Create(consts.ValidatorPrefix+"DocRefine"))
}
// 【需要token】中间件验证的路由 // 【需要token】中间件验证的路由
backend.Use(authorization.CheckTokenAuth()) backend.Use(authorization.CheckTokenAuth())

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

File diff suppressed because one or more lines are too long

@ -1,5 +1,5 @@
# 后端启动 # 后端启动
`cd GinSkeleton; go mod tidy; go run main.go` `cd GinSkeleton; go mod tidy; go run main.go `
api文档见 `GinSkeleton/api_doc.md` api文档见 `GinSkeleton/api_doc.md`
# CKEditor # CKEditor
`ckeditor5-build-classic/handbook.md`中有一些参考, `ckeditor5-build-classic/handbook.md`中有一些参考,

Loading…
Cancel
Save