mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 16:23:42 +08:00 
			
		
		
		
	feat: add support for registing use force use invite code
This commit is contained in:
		@@ -140,12 +140,12 @@ type SystemConfig struct {
 | 
			
		||||
	Title            string   `json:"title"`
 | 
			
		||||
	AdminTitle       string   `json:"admin_title"`
 | 
			
		||||
	Models           []string `json:"models"`
 | 
			
		||||
	InitChatCalls    int      `json:"init_chat_calls"` // 新用户注册赠送对话次数
 | 
			
		||||
	InitImgCalls     int      `json:"init_img_calls"`  // 新用户注册赠送绘图次数
 | 
			
		||||
	VipMonthCalls    int      `json:"vip_month_calls"` // 会员每个赠送的调用次数
 | 
			
		||||
	EnabledRegister  bool     `json:"enabled_register"`
 | 
			
		||||
	EnabledMsg       bool     `json:"enabled_msg"`         // 启用短信验证码服务
 | 
			
		||||
	EnabledDraw      bool     `json:"enabled_draw"`        // 启动 AI 绘画功能
 | 
			
		||||
	InitChatCalls    int      `json:"init_chat_calls"`     // 新用户注册赠送对话次数
 | 
			
		||||
	InitImgCalls     int      `json:"init_img_calls"`      // 新用户注册赠送绘图次数
 | 
			
		||||
	VipMonthCalls    int      `json:"vip_month_calls"`     // 会员每个赠送的调用次数
 | 
			
		||||
	EnabledRegister  bool     `json:"enabled_register"`    // 是否启用注册功能,关闭注册功能之后将无法注册
 | 
			
		||||
	EnabledMsg       bool     `json:"enabled_msg"`         // 是否启用短信验证码服务
 | 
			
		||||
	EnabledDraw      bool     `json:"enabled_draw"`        // 是否启用 AI 绘画功能
 | 
			
		||||
	RewardImg        string   `json:"reward_img"`          // 众筹收款二维码地址
 | 
			
		||||
	EnabledFunction  bool     `json:"enabled_function"`    // 启用 API 函数功能
 | 
			
		||||
	EnabledReward    bool     `json:"enabled_reward"`      // 启用众筹功能
 | 
			
		||||
@@ -155,4 +155,5 @@ type SystemConfig struct {
 | 
			
		||||
	OrderPayInfoText string   `json:"order_pay_info_text"` // 订单支付页面说明文字
 | 
			
		||||
	InviteChatCalls  int      `json:"invite_chat_calls"`   // 邀请用户注册奖励对话次数
 | 
			
		||||
	InviteImgCalls   int      `json:"invite_img_calls"`    // 邀请用户注册奖励绘图次数
 | 
			
		||||
	ForceInvite      bool     `json:"force_invite"`        // 是否强制必须使用邀请码才能注册
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -58,13 +58,3 @@ func (h *SmsHandler) SendCode(c *gin.Context) {
 | 
			
		||||
 | 
			
		||||
	resp.SUCCESS(c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type statusVo struct {
 | 
			
		||||
	EnabledMsgService bool `json:"enabled_msg_service"`
 | 
			
		||||
	EnabledRegister   bool `json:"enabled_register"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Status check if the message service is enabled
 | 
			
		||||
func (h *SmsHandler) Status(c *gin.Context) {
 | 
			
		||||
	resp.SUCCESS(c, statusVo{EnabledMsgService: h.App.SysConfig.EnabledMsg, EnabledRegister: h.App.SysConfig.EnabledRegister})
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,12 @@ func (h *UserHandler) Register(c *gin.Context) {
 | 
			
		||||
 | 
			
		||||
	// 验证邀请码
 | 
			
		||||
	inviteCode := model.InviteCode{}
 | 
			
		||||
	if data.InviteCode != "" {
 | 
			
		||||
	if data.InviteCode == "" {
 | 
			
		||||
		if h.App.SysConfig.ForceInvite {
 | 
			
		||||
			resp.ERROR(c, "当前系统设定必须使用邀请码才能注册")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		res := h.db.Where("code = ?", data.InviteCode).First(&inviteCode)
 | 
			
		||||
		if res.Error != nil {
 | 
			
		||||
			resp.ERROR(c, "无效的邀请码")
 | 
			
		||||
 
 | 
			
		||||
@@ -237,7 +237,6 @@ func main() {
 | 
			
		||||
		}),
 | 
			
		||||
		fx.Invoke(func(s *core.AppServer, h *handler.SmsHandler) {
 | 
			
		||||
			group := s.Engine.Group("/api/sms/")
 | 
			
		||||
			group.GET("status", h.Status)
 | 
			
		||||
			group.POST("code", h.SendCode)
 | 
			
		||||
		}),
 | 
			
		||||
		fx.Invoke(func(s *core.AppServer, h *handler.CaptchaHandler) {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"chatplus/core/types"
 | 
			
		||||
	"chatplus/service/mj"
 | 
			
		||||
	"chatplus/utils"
 | 
			
		||||
	"errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// AI 绘画函数
 | 
			
		||||
@@ -11,15 +12,21 @@ import (
 | 
			
		||||
type FuncMidJourney struct {
 | 
			
		||||
	name    string
 | 
			
		||||
	service *mj.Service
 | 
			
		||||
	config  types.MidJourneyConfig
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewMidJourneyFunc(mjService *mj.Service) FuncMidJourney {
 | 
			
		||||
func NewMidJourneyFunc(mjService *mj.Service, config types.MidJourneyConfig) FuncMidJourney {
 | 
			
		||||
	return FuncMidJourney{
 | 
			
		||||
		name:    "MidJourney AI 绘画",
 | 
			
		||||
		config:  config,
 | 
			
		||||
		service: mjService}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f FuncMidJourney) Invoke(params map[string]interface{}) (string, error) {
 | 
			
		||||
	if !f.config.Enabled {
 | 
			
		||||
		return "", errors.New("MidJourney AI 绘画功能没有启用")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logger.Infof("MJ 绘画参数:%+v", params)
 | 
			
		||||
	prompt := utils.InterfaceToString(params["prompt"])
 | 
			
		||||
	f.service.PushTask(types.MjTask{
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,6 @@ func NewFunctions(config *types.AppConfig, mjService *mj.Service) map[string]Fun
 | 
			
		||||
		types.FuncZaoBao:     NewZaoBao(config.ApiConfig),
 | 
			
		||||
		types.FuncWeibo:      NewWeiboHot(config.ApiConfig),
 | 
			
		||||
		types.FuncHeadLine:   NewHeadLines(config.ApiConfig),
 | 
			
		||||
		types.FuncMidJourney: NewMidJourneyFunc(mjService),
 | 
			
		||||
		types.FuncMidJourney: NewMidJourneyFunc(mjService, config.MjConfig),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -78,7 +78,7 @@
 | 
			
		||||
      <h2>您推荐用户</h2>
 | 
			
		||||
 | 
			
		||||
      <div class="invite-logs">
 | 
			
		||||
        <invite-list/>
 | 
			
		||||
        <invite-list v-if="isLogin"/>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
@@ -91,6 +91,8 @@ import {httpGet} from "@/utils/http";
 | 
			
		||||
import {ElMessage} from "element-plus";
 | 
			
		||||
import Clipboard from "clipboard";
 | 
			
		||||
import InviteList from "@/components/InviteList.vue";
 | 
			
		||||
import {checkSession} from "@/action/session";
 | 
			
		||||
import {useRouter} from "vue-router";
 | 
			
		||||
 | 
			
		||||
const inviteURL = ref("")
 | 
			
		||||
const qrImg = ref("")
 | 
			
		||||
@@ -100,34 +102,40 @@ const users = ref([])
 | 
			
		||||
const hits = ref(0)
 | 
			
		||||
const regNum = ref(0)
 | 
			
		||||
const rate = ref(0)
 | 
			
		||||
 | 
			
		||||
const router = useRouter()
 | 
			
		||||
const isLogin = ref(false)
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  httpGet("/api/invite/code").then(res => {
 | 
			
		||||
    const text = `${location.protocol}//${location.host}/register?invite_code=${res.data.code}`
 | 
			
		||||
    hits.value = res.data["hits"]
 | 
			
		||||
    regNum.value = res.data["reg_num"]
 | 
			
		||||
    if (hits.value > 0) {
 | 
			
		||||
      rate.value = ((regNum.value / hits.value) * 100).toFixed(2)
 | 
			
		||||
    }
 | 
			
		||||
    QRCode.toDataURL(text, {width: 400, height: 400, margin: 2}, (error, url) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        console.error(error)
 | 
			
		||||
      } else {
 | 
			
		||||
        qrImg.value = url;
 | 
			
		||||
  checkSession().then(() => {
 | 
			
		||||
    isLogin.value = true
 | 
			
		||||
    httpGet("/api/invite/code").then(res => {
 | 
			
		||||
      const text = `${location.protocol}//${location.host}/register?invite_code=${res.data.code}`
 | 
			
		||||
      hits.value = res.data["hits"]
 | 
			
		||||
      regNum.value = res.data["reg_num"]
 | 
			
		||||
      if (hits.value > 0) {
 | 
			
		||||
        rate.value = ((regNum.value / hits.value) * 100).toFixed(2)
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    inviteURL.value = text
 | 
			
		||||
  }).catch(e => {
 | 
			
		||||
    ElMessage.error("获取邀请码失败:" + e.message)
 | 
			
		||||
  })
 | 
			
		||||
      QRCode.toDataURL(text, {width: 400, height: 400, margin: 2}, (error, url) => {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          console.error(error)
 | 
			
		||||
        } else {
 | 
			
		||||
          qrImg.value = url;
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      inviteURL.value = text
 | 
			
		||||
    }).catch(e => {
 | 
			
		||||
      ElMessage.error("获取邀请码失败:" + e.message)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
  httpGet("/api/admin/config/get?key=system").then(res => {
 | 
			
		||||
    inviteChatCalls.value = res.data["invite_chat_calls"]
 | 
			
		||||
    inviteImgCalls.value = res.data["invite_img_calls"]
 | 
			
		||||
  }).catch(e => {
 | 
			
		||||
    ElMessage.error("获取系统配置失败:" + e.message)
 | 
			
		||||
  })
 | 
			
		||||
    httpGet("/api/admin/config/get?key=system").then(res => {
 | 
			
		||||
      inviteChatCalls.value = res.data["invite_chat_calls"]
 | 
			
		||||
      inviteImgCalls.value = res.data["invite_img_calls"]
 | 
			
		||||
    }).catch(e => {
 | 
			
		||||
      ElMessage.error("获取系统配置失败:" + e.message)
 | 
			
		||||
    })
 | 
			
		||||
  }).catch(() => {
 | 
			
		||||
    router.push('/login')
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // 复制链接
 | 
			
		||||
  const clipboard = new Clipboard('.copy-link');
 | 
			
		||||
 
 | 
			
		||||
@@ -118,7 +118,7 @@
 | 
			
		||||
import {ref} from "vue";
 | 
			
		||||
import {Checked, Iphone, Lock, Message} from "@element-plus/icons-vue";
 | 
			
		||||
import {httpGet, httpPost} from "@/utils/http";
 | 
			
		||||
import {ElMessage} from "element-plus";
 | 
			
		||||
import {ElMessage, ElNotification} from "element-plus";
 | 
			
		||||
import {useRouter} from "vue-router";
 | 
			
		||||
import FooterBar from "@/components/FooterBar.vue";
 | 
			
		||||
import SendMsg from "@/components/SendMsg.vue";
 | 
			
		||||
@@ -141,11 +141,23 @@ const enableMsg = ref(false)
 | 
			
		||||
const enableRegister = ref(true)
 | 
			
		||||
const wxImg = ref("/images/wx.png")
 | 
			
		||||
 | 
			
		||||
httpGet('/api/sms/status').then(res => {
 | 
			
		||||
httpGet("/api/admin/config/get?key=system").then(res => {
 | 
			
		||||
  if (res.data) {
 | 
			
		||||
    enableMsg.value = res.data['enabled_msg_service']
 | 
			
		||||
    enableMsg.value = res.data['enabled_msg']
 | 
			
		||||
    enableRegister.value = res.data['enabled_register']
 | 
			
		||||
    console.log(res.data)
 | 
			
		||||
    if (res.data['force_invite']) {
 | 
			
		||||
      ElNotification({
 | 
			
		||||
        title: '提示:',
 | 
			
		||||
        dangerouslyUseHTMLString: true,
 | 
			
		||||
        message: '当前系统开启了强制邀请注册功能,必须有邀请码才能注册哦。扫描下面二维码获取邀请码。<br/> <img alt="qrcode" src="/images/wx.png" />',
 | 
			
		||||
        type: 'info',
 | 
			
		||||
        duration: 0,
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}).catch(e => {
 | 
			
		||||
  ElMessage.error("获取系统配置失败:" + e.message)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
httpGet("/api/invite/hits", {code: formData.value.invite_code}).then(() => {
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,19 @@
 | 
			
		||||
        <el-form-item label="开放注册服务" prop="enabled_register">
 | 
			
		||||
          <el-switch v-model="system['enabled_register']"/>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="强制邀请码注册" prop="force_invite">
 | 
			
		||||
          <el-switch v-model="system['force_invite']"/>
 | 
			
		||||
          <el-tooltip
 | 
			
		||||
              effect="dark"
 | 
			
		||||
              content="开启之后,用户必须使用邀请码才能注册"
 | 
			
		||||
              raw-content
 | 
			
		||||
              placement="right"
 | 
			
		||||
          >
 | 
			
		||||
            <el-icon>
 | 
			
		||||
              <InfoFilled/>
 | 
			
		||||
            </el-icon>
 | 
			
		||||
          </el-tooltip>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="短信服务" prop="enabled_msg">
 | 
			
		||||
          <el-switch v-model="system['enabled_msg']"/>
 | 
			
		||||
          <el-tooltip
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user