增加发布协议确认配置

This commit is contained in:
yml2213
2026-06-07 21:14:49 +08:00
parent 954c3d6be3
commit eebd2d3b04
19 changed files with 760 additions and 13 deletions
@@ -32,6 +32,11 @@ type OrderAgreementsDTO struct {
RenterAgreement AgreementContentDTO `json:"renter_agreement"`
}
type ListingPublishAgreementsDTO struct {
VirtualAssetSale AgreementContentDTO `json:"virtual_asset_sale"`
SellerAgreement AgreementContentDTO `json:"seller_agreement"`
}
type PostRentalNoticeDTO struct {
Title string `json:"title"`
Content string `json:"content"`
@@ -54,6 +54,15 @@ func (h *Handler) OrderAgreements(c *gin.Context) {
response.OK(c, agreements)
}
func (h *Handler) ListingPublishAgreements(c *gin.Context) {
agreements, err := h.service.ListingPublishAgreements()
if err != nil {
writeConfigError(c, err)
return
}
response.OK(c, agreements)
}
func (h *Handler) PostRentalNotice(c *gin.Context) {
notice, err := h.service.PostRentalNotice()
if err != nil {
@@ -0,0 +1,56 @@
package systemconfig
import "encoding/json"
const listingPublishAgreementsConfigKey = "listing.publish_agreements"
func defaultListingPublishAgreementsConfigValue() string {
raw, err := json.Marshal(DefaultListingPublishAgreements())
if err != nil {
return "{}"
}
return string(raw)
}
func DefaultListingPublishAgreements() ListingPublishAgreementsDTO {
return ListingPublishAgreementsDTO{
VirtualAssetSale: AgreementContentDTO{
Title: "虚拟资产出售协议",
Content: `请您在发布账号前仔细阅读并确认以下内容:
一、发布性质
1. 您发布的账号、哈夫币、皮肤、装备、消耗品等均属于游戏内虚拟资产或使用权益展示。
2. 虚拟资产受游戏厂商规则、版本更新、风控策略和账号状态影响,平台不承诺其具备现实货币价值或永久可用性。
3. 您应确保发布信息真实、完整、可交接,且与截图材料和账号实际资产一致。
二、风险告知
1. 发布账号后,买家下单前后可能因游戏环境变化、资产变动、封禁记录、登录限制等产生交易风险。
2. 若您隐瞒账号异常、资产缺失、封禁记录、不可用物资或其他影响交易的信息,平台可依据证据处理赔付、退款或下架。
3. 请勿绕过平台私下收款、私下交接或诱导用户脱离平台沟通,否则平台可能限制账号发布权限。
三、费用与结算
1. 发布价格、押金、额外消耗品价值以平台发布页和订单页面展示为准。
2. 订单完成后,平台将按订单记录、结账结果和相关规则进行结算。
3. 若发生争议,平台将依据订单记录、资产快照、聊天记录、截图证据和双方说明进行处理。`,
},
SellerAgreement: 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: listingPublishAgreementsConfigKey, Value: defaultListingPublishAgreementsConfigValue(), Description: "发布账号前协议配置 JSON"},
{Key: orderAgreementsConfigKey, Value: defaultOrderAgreementsConfigValue(), Description: "下单前协议配置 JSON"},
{Key: postRentalNoticeConfigKey, Value: defaultPostRentalNoticeConfigValue(), Description: "租后须知配置 JSON"},
{Key: "chat.default_support_admin_id", Value: "1", Description: "订单群聊回退客服 ID(仅当无可用客服时使用)"},
@@ -47,6 +48,7 @@ var adminVisibleConfigKeys = []string{
"handoff.owner_return_confirm_timeout_minutes",
"handoff.owner_submit_timeout_minutes",
"handoff.renter_confirm_timeout_minutes",
"listing.publish_agreements",
"listing.publish_options",
"listing.review_required",
"listing.sale_price_config",
@@ -59,6 +59,17 @@ func (s *Service) OrderAgreements() (*OrderAgreementsDTO, error) {
return &agreements, nil
}
func (s *Service) ListingPublishAgreements() (*ListingPublishAgreementsDTO, error) {
if s.repo == nil {
return nil, ErrDependencyUnavailable
}
agreements, err := s.listingPublishAgreements()
if err != nil {
return nil, err
}
return &agreements, nil
}
func (s *Service) PostRentalNotice() (*PostRentalNoticeDTO, error) {
if s.repo == nil {
return nil, ErrDependencyUnavailable
@@ -109,6 +120,19 @@ func (s *Service) orderAgreements() (OrderAgreementsDTO, error) {
return agreements, nil
}
func (s *Service) listingPublishAgreements() (ListingPublishAgreementsDTO, error) {
value, err := s.repo.FindValue(listingPublishAgreementsConfigKey)
if err != nil {
return ListingPublishAgreementsDTO{}, err
}
agreements := DefaultListingPublishAgreements()
if err := json.Unmarshal([]byte(value), &agreements); err != nil {
agreements = DefaultListingPublishAgreements()
}
normalizeListingPublishAgreements(&agreements)
return agreements, nil
}
func (s *Service) postRentalNotice() (PostRentalNoticeDTO, error) {
value, err := s.repo.FindValue(postRentalNoticeConfigKey)
if err != nil {
@@ -247,6 +271,26 @@ func normalizeOrderAgreements(agreements *OrderAgreementsDTO) {
}
}
func normalizeListingPublishAgreements(agreements *ListingPublishAgreementsDTO) {
defaults := DefaultListingPublishAgreements()
agreements.VirtualAssetSale.Title = strings.TrimSpace(agreements.VirtualAssetSale.Title)
agreements.VirtualAssetSale.Content = strings.TrimSpace(agreements.VirtualAssetSale.Content)
agreements.SellerAgreement.Title = strings.TrimSpace(agreements.SellerAgreement.Title)
agreements.SellerAgreement.Content = strings.TrimSpace(agreements.SellerAgreement.Content)
if agreements.VirtualAssetSale.Title == "" {
agreements.VirtualAssetSale.Title = defaults.VirtualAssetSale.Title
}
if agreements.VirtualAssetSale.Content == "" {
agreements.VirtualAssetSale.Content = defaults.VirtualAssetSale.Content
}
if agreements.SellerAgreement.Title == "" {
agreements.SellerAgreement.Title = defaults.SellerAgreement.Title
}
if agreements.SellerAgreement.Content == "" {
agreements.SellerAgreement.Content = defaults.SellerAgreement.Content
}
}
func normalizePostRentalNotice(notice *PostRentalNoticeDTO) {
defaults := DefaultPostRentalNotice()
notice.Title = strings.TrimSpace(notice.Title)