优化弹窗和后台设置字体

This commit is contained in:
yml2213
2026-06-05 03:06:09 +08:00
parent 498e3d7bde
commit 3c28297dee
12 changed files with 910 additions and 12 deletions
@@ -27,6 +27,16 @@ type HomeConfigDTO struct {
PublishOptions PublishOptionsDTO `json:"publish_options"`
}
type OrderAgreementsDTO struct {
VirtualAssetPurchase AgreementContentDTO `json:"virtual_asset_purchase"`
RenterAgreement AgreementContentDTO `json:"renter_agreement"`
}
type AgreementContentDTO struct {
Title string `json:"title"`
Content string `json:"content"`
}
type HomeBannerItem struct {
Eyebrow string `json:"eyebrow"`
Title string `json:"title"`
@@ -45,6 +45,15 @@ func (h *Handler) SalePriceConfig(c *gin.Context) {
response.OK(c, config)
}
func (h *Handler) OrderAgreements(c *gin.Context) {
agreements, err := h.service.OrderAgreements()
if err != nil {
writeConfigError(c, err)
return
}
response.OK(c, agreements)
}
func (h *Handler) HomeAnnouncements(c *gin.Context) {
announcements, err := h.service.HomeAnnouncements()
if err != nil {
@@ -0,0 +1,56 @@
package systemconfig
import "encoding/json"
const orderAgreementsConfigKey = "order.agreements"
func defaultOrderAgreementsConfigValue() string {
raw, err := json.Marshal(DefaultOrderAgreements())
if err != nil {
return "{}"
}
return string(raw)
}
func DefaultOrderAgreements() OrderAgreementsDTO {
return OrderAgreementsDTO{
VirtualAssetPurchase: AgreementContentDTO{
Title: "虚拟资产购买协议",
Content: `请您在下单前仔细阅读并确认以下内容:
一、交易性质
1. 本平台商品涉及游戏账号租用期间的虚拟资产使用权益、租金和押金托管服务。
2. 虚拟资产、游戏账号及相关数据均受游戏厂商规则约束,平台不承诺虚拟资产具备现实货币价值或永久可用性。
3. 您下单即表示已理解商品页面展示的哈夫币、装备、皮肤、消耗品、租期、押金和交接规则。
二、风险告知
1. 游戏厂商可能因版本更新、风控策略、账号安全策略等因素调整游戏资产状态。
2. 因租客违规操作、使用外挂、恶意消耗、转移资产、私下交易或违反游戏规则造成的损失,可能从押金中扣除或进入争议处理。
3. 请勿绕过平台私下付款、私下交接或私下协商退款,否则平台可能无法保障您的资金与交易权益。
三、费用与结算
1. 订单租金、押金和可能产生的额外消耗品费用以平台订单和结账页面展示为准。
2. 未实际使用完的租金或剩余押金,将按平台结账规则退回。
3. 若发生争议,平台将依据订单记录、聊天记录、截图证据和双方说明进行处理。`,
},
RenterAgreement: AgreementContentDTO{
Title: "租客协议",
Content: `请您作为租客在下单前确认并遵守以下约定:
一、账号使用义务
1. 您仅可在订单约定时间内按商品说明使用账号,不得转租、转借、出售、赠与或用于任何非订单目的。
2. 您不得使用外挂、脚本、漏洞、恶意组队、违规交易、消极比赛、辱骂举报等可能导致账号异常的行为。
3. 您不得修改账号绑定信息、登录凭证、安全设置、实名信息或任何影响号主取回账号的内容。
二、资产保护义务
1. 您应按商品详情和订单快照合理使用哈夫币、装备、物资、皮肤及其他虚拟资产。
2. 额外消耗品、哈夫币消耗、违规损失、封禁损失等应在结账时如实登记。
3. 因您未按约定使用账号造成的损失,平台可根据证据从押金中扣除相应赔付。
三、交接与结账
1. 下单后请通过平台流程完成交接、沟通、归还和结账,不要私下交易。
2. 租用结束后请及时发起结账并说明资产状态;号主确认或双方完成争议处理后,订单结算完成。
3. 您同意平台依据订单记录、资产快照、聊天记录、截图证据和相关规则处理退款、赔付及争议。`,
},
}
}
@@ -31,6 +31,7 @@ var defaultConfigs = []defaultConfig{
{Key: "order.pending_payment_timeout_minutes", Value: "15", Description: "订单待支付超时取消分钟数"},
{Key: "order.return_overdue_grace_minutes", Value: "10", Description: "预计截止后结账宽限分钟数"},
{Key: "listing.review_required", Value: "false", Description: "发布账号是否需要后台人工审核"},
{Key: orderAgreementsConfigKey, Value: defaultOrderAgreementsConfigValue(), Description: "下单前协议配置 JSON"},
{Key: "chat.default_support_admin_id", Value: "1", Description: "订单群聊回退客服 ID(仅当无可用客服时使用)"},
{Key: "chat.auto_welcome_message", Value: "欢迎加入订单群聊!如有任何问题,请随时沟通。", Description: "建群后自动发送的欢迎话术"},
{Key: homeAnnouncementsConfigKey, Value: defaultHomeAnnouncementsConfigValue(), Description: "移动端首页公告 JSON 数组"},
@@ -50,6 +51,7 @@ var adminVisibleConfigKeys = []string{
"listing.sale_price_config",
"mobile.home_announcements",
"mobile.home_banners",
"order.agreements",
"order.pending_payment_timeout_minutes",
"order.return_overdue_grace_minutes",
}
@@ -48,6 +48,17 @@ func (s *Service) SalePriceConfig() (*PublishSalePriceConfig, error) {
return &config, nil
}
func (s *Service) OrderAgreements() (*OrderAgreementsDTO, error) {
if s.repo == nil {
return nil, ErrDependencyUnavailable
}
agreements, err := s.orderAgreements()
if err != nil {
return nil, err
}
return &agreements, nil
}
func (s *Service) publishOptions() (PublishOptionsDTO, error) {
value, err := s.repo.FindValue(publishOptionsConfigKey)
if err != nil {
@@ -74,6 +85,19 @@ func (s *Service) salePriceConfig() (PublishSalePriceConfig, error) {
return config, nil
}
func (s *Service) orderAgreements() (OrderAgreementsDTO, error) {
value, err := s.repo.FindValue(orderAgreementsConfigKey)
if err != nil {
return OrderAgreementsDTO{}, err
}
agreements := DefaultOrderAgreements()
if err := json.Unmarshal([]byte(value), &agreements); err != nil {
agreements = DefaultOrderAgreements()
}
normalizeOrderAgreements(&agreements)
return agreements, nil
}
func (s *Service) HomeAnnouncements() (*HomeAnnouncementsDTO, error) {
if s.repo == nil {
return nil, ErrDependencyUnavailable
@@ -179,6 +203,26 @@ func normalizeHomeBanners(items []HomeBannerItem) []HomeBannerItem {
return normalized
}
func normalizeOrderAgreements(agreements *OrderAgreementsDTO) {
defaults := DefaultOrderAgreements()
agreements.VirtualAssetPurchase.Title = strings.TrimSpace(agreements.VirtualAssetPurchase.Title)
agreements.VirtualAssetPurchase.Content = strings.TrimSpace(agreements.VirtualAssetPurchase.Content)
agreements.RenterAgreement.Title = strings.TrimSpace(agreements.RenterAgreement.Title)
agreements.RenterAgreement.Content = strings.TrimSpace(agreements.RenterAgreement.Content)
if agreements.VirtualAssetPurchase.Title == "" {
agreements.VirtualAssetPurchase.Title = defaults.VirtualAssetPurchase.Title
}
if agreements.VirtualAssetPurchase.Content == "" {
agreements.VirtualAssetPurchase.Content = defaults.VirtualAssetPurchase.Content
}
if agreements.RenterAgreement.Title == "" {
agreements.RenterAgreement.Title = defaults.RenterAgreement.Title
}
if agreements.RenterAgreement.Content == "" {
agreements.RenterAgreement.Content = defaults.RenterAgreement.Content
}
}
func normalizePublishOptions(options *PublishOptionsDTO) {
defaults := DefaultPublishOptions()
if len(options.ServerOptions) == 0 {