refactor: 重构状态更新接口,新增商品管理与勋章规则配置
1. 重构用户、宠物模板、勋章、管理员状态更新接口,移除冗余参数改为自动切换状态 2. 重命名宠物背景枚举为宠物皮肤,调整商品状态字段为枚举类型 3. 新增商品上下架状态管理接口与对应逻辑 4. 新增勋章规则配置系统,支持动态加载可用表和字段 5. 优化商品查询与展示逻辑,适配新的状态字段
This commit is contained in:
@ -43,4 +43,11 @@ public interface IAdminUserService : IBaseService<AdminUser>
|
|||||||
/// <param name="input">查询条件</param>
|
/// <param name="input">查询条件</param>
|
||||||
/// <returns>分页结果</returns>
|
/// <returns>分页结果</returns>
|
||||||
Task<PageListModel<AdminUserOutput>> GetListAsync(AdminUserQueryInput input);
|
Task<PageListModel<AdminUserOutput>> GetListAsync(AdminUserQueryInput input);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 切换管理员状态(激活/冻结)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">管理员ID</param>
|
||||||
|
/// <param name="status">目标状态:1=激活,0=冻结</param>
|
||||||
|
Task ToggleStatusAsync(long id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@ public interface IMedalService : IBaseService<Medal>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">勋章ID</param>
|
/// <param name="id">勋章ID</param>
|
||||||
/// <param name="status">状态: 0=禁用, 1=启用</param>
|
/// <param name="status">状态: 0=禁用, 1=启用</param>
|
||||||
Task UpdateStatusAsync(long id, int status);
|
Task<bool> UpdateStatusAsync(long id);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取勋章的规则列表
|
/// 获取勋章的规则列表
|
||||||
@ -77,4 +77,15 @@ public interface IMedalService : IBaseService<Medal>
|
|||||||
/// <param name="userId">用户ID</param>
|
/// <param name="userId">用户ID</param>
|
||||||
/// <param name="input">激活输入</param>
|
/// <param name="input">激活输入</param>
|
||||||
Task ActivateMedalAsync(long userId, WxMedalActivateInput input);
|
Task ActivateMedalAsync(long userId, WxMedalActivateInput input);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取规则配置中可用的目标表列表
|
||||||
|
/// </summary>
|
||||||
|
Task<List<MedalRuleTableOptionOutput>> GetAvailableTablesAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定表的可用字段列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">表名</param>
|
||||||
|
Task<List<MedalRuleFieldOptionOutput>> GetTableFieldsAsync(string tableName);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ public interface IPetService : IBaseService<UserPet>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新模板状态(启用/禁用)
|
/// 更新模板状态(启用/禁用)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task UpdateTemplateStatusAsync(long id, int status);
|
Task UpdateTemplateStatusAsync(long id);
|
||||||
|
|
||||||
// ==================== 后台管理:进化链 ====================
|
// ==================== 后台管理:进化链 ====================
|
||||||
|
|
||||||
|
|||||||
@ -42,4 +42,10 @@ public interface IProductService : IBaseService<Product>
|
|||||||
/// <param name="input">查询条件</param>
|
/// <param name="input">查询条件</param>
|
||||||
/// <returns>分页结果</returns>
|
/// <returns>分页结果</returns>
|
||||||
Task<PageListModel<ProductOutput>> GetListAsync(ProductQueryInput input);
|
Task<PageListModel<ProductOutput>> GetListAsync(ProductQueryInput input);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新商品上架/下架状态(取反)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">商品ID</param>
|
||||||
|
Task UpdateSaleStatusAsync(long id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ public interface IUsersService : IBaseService<Users>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新用户状态
|
/// 更新用户状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<BaseResponse> UpdateStatusAsync(long id, UpdateUserStatusInput input);
|
Task<BaseResponse> UpdateStatusAsync(long id);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 手动增加用户积分
|
/// 手动增加用户积分
|
||||||
|
|||||||
@ -36,7 +36,7 @@ public class ProductInput
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 售卖状态: OnSale, OffSale
|
/// 售卖状态: OnSale, OffSale
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SaleStatus { get; set; } = "OnSale";
|
public ProductStatusEnum Status { get; set; } = ProductStatusEnum.OnSale;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 扩展数据
|
/// 扩展数据
|
||||||
@ -90,9 +90,9 @@ public class ProductOutput
|
|||||||
public string Type { get; set; } = string.Empty;
|
public string Type { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 售卖状态
|
/// 状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SaleStatus { get; set; } = string.Empty;
|
public string Status { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 扩展数据
|
/// 扩展数据
|
||||||
@ -146,9 +146,9 @@ public class ProductQueryInput : PageQueryModel
|
|||||||
public string? Type { get; set; }
|
public string? Type { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 售卖状态: OnSale, OffSale
|
/// 售卖状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? SaleStatus { get; set; }
|
public ProductStatusEnum? Status { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否上架
|
/// 是否上架
|
||||||
|
|||||||
@ -364,3 +364,35 @@ public class WxMedalActivateInput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public long MedalId { get; set; }
|
public long MedalId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 勋章规则目标表下拉输出
|
||||||
|
/// </summary>
|
||||||
|
public class MedalRuleTableOptionOutput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 表名
|
||||||
|
/// </summary>
|
||||||
|
public string TableName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示名称
|
||||||
|
/// </summary>
|
||||||
|
public string DisplayName { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 勋章规则字段下拉输出
|
||||||
|
/// </summary>
|
||||||
|
public class MedalRuleFieldOptionOutput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 字段名
|
||||||
|
/// </summary>
|
||||||
|
public string FieldName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示名称
|
||||||
|
/// </summary>
|
||||||
|
public string DisplayName { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|||||||
@ -49,14 +49,6 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ProductTypeEnum Type {get;set;}
|
public ProductTypeEnum Type {get;set;}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Desc:售卖状态: OnSale, OffSale
|
|
||||||
/// Default:OnSale
|
|
||||||
/// Nullable:False
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnName = "SaleStatus")]
|
|
||||||
public string SaleStatus {get;set;}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:扩展数据
|
/// Desc:扩展数据
|
||||||
/// Default:
|
/// Default:
|
||||||
|
|||||||
21
QYZH.InteractiveMagazine.Models/Enum/ProductStatusEnum.cs
Normal file
21
QYZH.InteractiveMagazine.Models/Enum/ProductStatusEnum.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace QYZH.InteractiveMagazine.Models.Enum;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 商品上架/下架状态枚举
|
||||||
|
/// </summary>
|
||||||
|
public enum ProductStatusEnum
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 上架
|
||||||
|
/// </summary>
|
||||||
|
[Description("上架")]
|
||||||
|
OnSale = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下架
|
||||||
|
/// </summary>
|
||||||
|
[Description("下架")]
|
||||||
|
OffSale = 0
|
||||||
|
}
|
||||||
@ -15,6 +15,6 @@ public enum ProductTypeEnum
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 宠物背景
|
/// 宠物背景
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("宠物背景")]
|
[Description("宠物皮肤")]
|
||||||
PetBg = 2
|
PetSkin = 2
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,49 @@
|
|||||||
|
namespace QYZH.InteractiveMagazine.Models.Settings;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 勋章规则配置(可配置的目标表和字段)
|
||||||
|
/// </summary>
|
||||||
|
public class MedalRuleConfigSettings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 可用的目标表列表
|
||||||
|
/// </summary>
|
||||||
|
public List<MedalRuleTableConfig> Tables { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 勋章规则目标表配置
|
||||||
|
/// </summary>
|
||||||
|
public class MedalRuleTableConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 表名
|
||||||
|
/// </summary>
|
||||||
|
public string TableName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示名称
|
||||||
|
/// </summary>
|
||||||
|
public string DisplayName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可用字段列表
|
||||||
|
/// </summary>
|
||||||
|
public List<MedalRuleFieldConfig> Fields { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 勋章规则字段配置
|
||||||
|
/// </summary>
|
||||||
|
public class MedalRuleFieldConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 字段名
|
||||||
|
/// </summary>
|
||||||
|
public string FieldName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示名称
|
||||||
|
/// </summary>
|
||||||
|
public string DisplayName { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@ -203,4 +203,32 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
|
|||||||
.ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
|
.ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
|
||||||
return new PageListModel<AdminUserOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
|
return new PageListModel<AdminUserOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 切换管理员状态(激活/冻结)
|
||||||
|
/// </summary>
|
||||||
|
public async Task ToggleStatusAsync(long id)
|
||||||
|
{
|
||||||
|
logger.LogInformation("正在切换管理员状态,ID: {Id}", id);
|
||||||
|
|
||||||
|
var adminUser = await adminUserRepository.GetByIdAsync(id);
|
||||||
|
if (adminUser == null)
|
||||||
|
{
|
||||||
|
logger.LogWarning("未找到要更新状态的管理员,ID: {Id}", id);
|
||||||
|
throw new BusinessException("管理员不存在", 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
adminUser.Status = adminUser.Status==(int)AdminUserStatusEnum.Active?(int)AdminUserStatusEnum.Inactive:(int)AdminUserStatusEnum.Active;
|
||||||
|
adminUser.UpdatedBy = "System";
|
||||||
|
adminUser.UpdatedAt = DateTime.Now;
|
||||||
|
|
||||||
|
var result = await adminUserRepository.UpdateAsync(adminUser);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
logger.LogError("管理员状态更新失败,ID: {Id}", id);
|
||||||
|
throw new BusinessException("更新管理员状态失败", 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.LogInformation("管理员状态更新成功,ID: {Id}", id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using QYZH.InteractiveMagazine.IService;
|
using QYZH.InteractiveMagazine.IService;
|
||||||
using QYZH.InteractiveMagazine.Models.Common;
|
using QYZH.InteractiveMagazine.Models.Common;
|
||||||
using QYZH.InteractiveMagazine.Models.Dto;
|
using QYZH.InteractiveMagazine.Models.Dto;
|
||||||
using QYZH.InteractiveMagazine.Models.Entity;
|
using QYZH.InteractiveMagazine.Models.Entity;
|
||||||
using QYZH.InteractiveMagazine.Models.Enum;
|
using QYZH.InteractiveMagazine.Models.Enum;
|
||||||
|
using QYZH.InteractiveMagazine.Models.Settings;
|
||||||
using QYZH.InteractiveMagazine.Repository;
|
using QYZH.InteractiveMagazine.Repository;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
|
||||||
@ -13,7 +15,7 @@ namespace QYZH.InteractiveMagazine.Service;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 勋章服务实现
|
/// 勋章服务实现
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MedalService(BaseRepository<Medal> medalRepository, ILogger<MedalService> logger) : BaseRepository<Medal>, IMedalService
|
public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalRuleConfigSettings> medalRuleConfig, ILogger<MedalService> logger) : BaseRepository<Medal>, IMedalService
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -257,15 +259,8 @@ public class MedalService(BaseRepository<Medal> medalRepository, ILogger<MedalSe
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新勋章启用/禁用状态
|
/// 更新勋章启用/禁用状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task UpdateStatusAsync(long id, int status)
|
public async Task<bool> UpdateStatusAsync(long id)
|
||||||
{
|
{
|
||||||
logger.LogInformation("正在更新勋章状态,ID: {Id}, Status: {Status}", id, status);
|
|
||||||
|
|
||||||
if (status != 0 && status != 1)
|
|
||||||
{
|
|
||||||
throw new BusinessException("状态值无效,只能为0(禁用)或1(启用)", 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
var medal = await medalRepository.GetByIdAsync(id);
|
var medal = await medalRepository.GetByIdAsync(id);
|
||||||
if (medal == null)
|
if (medal == null)
|
||||||
{
|
{
|
||||||
@ -273,7 +268,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, ILogger<MedalSe
|
|||||||
throw new BusinessException("勋章不存在", 404);
|
throw new BusinessException("勋章不存在", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
medal.Status = status;
|
medal.Status = medal.Status == 0 ? 1 : 0;
|
||||||
medal.UpdatedBy = "System";
|
medal.UpdatedBy = "System";
|
||||||
medal.UpdatedAt = DateTime.Now;
|
medal.UpdatedAt = DateTime.Now;
|
||||||
|
|
||||||
@ -283,8 +278,9 @@ public class MedalService(BaseRepository<Medal> medalRepository, ILogger<MedalSe
|
|||||||
logger.LogError("勋章状态更新失败,ID: {Id}", id);
|
logger.LogError("勋章状态更新失败,ID: {Id}", id);
|
||||||
throw new BusinessException("更新勋章状态失败", 500);
|
throw new BusinessException("更新勋章状态失败", 500);
|
||||||
}
|
}
|
||||||
|
logger.LogInformation("勋章状态更新成功,ID: {Id}, Status: {Status}", id, medal.Status);
|
||||||
|
return result;
|
||||||
|
|
||||||
logger.LogInformation("勋章状态更新成功,ID: {Id}, Status: {Status}", id, status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -423,6 +419,40 @@ public class MedalService(BaseRepository<Medal> medalRepository, ILogger<MedalSe
|
|||||||
logger.LogInformation("勋章激活成功,用户ID: {UserId}, 勋章ID: {MedalId}", userId, input.MedalId);
|
logger.LogInformation("勋章激活成功,用户ID: {UserId}, 勋章ID: {MedalId}", userId, input.MedalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取规则配置中可用的目标表列表
|
||||||
|
/// </summary>
|
||||||
|
public Task<List<MedalRuleTableOptionOutput>> GetAvailableTablesAsync()
|
||||||
|
{
|
||||||
|
var tables = medalRuleConfig.Value.Tables?.Select(t => new MedalRuleTableOptionOutput
|
||||||
|
{
|
||||||
|
TableName = t.TableName,
|
||||||
|
DisplayName = t.DisplayName
|
||||||
|
}).ToList() ?? new List<MedalRuleTableOptionOutput>();
|
||||||
|
|
||||||
|
return Task.FromResult(tables);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定表的可用字段列表
|
||||||
|
/// </summary>
|
||||||
|
public Task<List<MedalRuleFieldOptionOutput>> GetTableFieldsAsync(string tableName)
|
||||||
|
{
|
||||||
|
var table = medalRuleConfig.Value.Tables?.FirstOrDefault(t => t.TableName == tableName);
|
||||||
|
if (table == null)
|
||||||
|
{
|
||||||
|
return Task.FromResult(new List<MedalRuleFieldOptionOutput>());
|
||||||
|
}
|
||||||
|
|
||||||
|
var fields = table.Fields.Select(f => new MedalRuleFieldOptionOutput
|
||||||
|
{
|
||||||
|
FieldName = f.FieldName,
|
||||||
|
DisplayName = f.DisplayName
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
return Task.FromResult(fields);
|
||||||
|
}
|
||||||
|
|
||||||
#region 私有辅助方法
|
#region 私有辅助方法
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -484,18 +484,20 @@ public class PetService(
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新模板状态(启用/禁用)
|
/// 更新模板状态(启用/禁用)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task UpdateTemplateStatusAsync(long id, int status)
|
public async Task UpdateTemplateStatusAsync(long id)
|
||||||
{
|
{
|
||||||
var template = await petTemplateRepository.GetByIdAsync(id);
|
var template = await petTemplateRepository.GetByIdAsync(id);
|
||||||
if (template == null || template.IsDeleted)
|
if (template == null || template.IsDeleted)
|
||||||
throw new BusinessException("宠物模板不存在", 404);
|
throw new BusinessException("宠物模板不存在", 404);
|
||||||
|
|
||||||
template.Status = status;
|
template.Status = template.Status == (int)PetTemplateStatusEnum.Active
|
||||||
|
? (int)PetTemplateStatusEnum.Inactive
|
||||||
|
: (int)PetTemplateStatusEnum.Active;
|
||||||
template.UpdatedBy = "System";
|
template.UpdatedBy = "System";
|
||||||
template.UpdatedAt = DateTime.Now;
|
template.UpdatedAt = DateTime.Now;
|
||||||
await petTemplateRepository.UpdateAsync(template);
|
await petTemplateRepository.UpdateAsync(template);
|
||||||
|
|
||||||
logger.LogInformation("更新模板状态成功,Id: {Id}, Status: {Status}", id, status);
|
logger.LogInformation("更新模板状态成功,Id: {Id}, Status: {Status}", id, template.Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PetTemplateOutput BuildTemplateOutput(PetTemplate t)
|
private static PetTemplateOutput BuildTemplateOutput(PetTemplate t)
|
||||||
|
|||||||
@ -44,7 +44,7 @@ public class ProductService(BaseRepository<Product> productRepository, ILogger<P
|
|||||||
ImageUrl = input.ImageUrl,
|
ImageUrl = input.ImageUrl,
|
||||||
Price = input.Price,
|
Price = input.Price,
|
||||||
Type = Enum.Parse<ProductTypeEnum>(input.Type, true),
|
Type = Enum.Parse<ProductTypeEnum>(input.Type, true),
|
||||||
SaleStatus = input.SaleStatus,
|
Status = (int)input.Status,
|
||||||
MetaData = input.MetaData,
|
MetaData = input.MetaData,
|
||||||
IsActive = input.IsActive,
|
IsActive = input.IsActive,
|
||||||
Stock = input.Stock,
|
Stock = input.Stock,
|
||||||
@ -72,7 +72,7 @@ public class ProductService(BaseRepository<Product> productRepository, ILogger<P
|
|||||||
ImageUrl = product.ImageUrl,
|
ImageUrl = product.ImageUrl,
|
||||||
Price = product.Price,
|
Price = product.Price,
|
||||||
Type = product.Type.ToString(),
|
Type = product.Type.ToString(),
|
||||||
SaleStatus = product.SaleStatus,
|
Status = product.Status.ToString(),
|
||||||
MetaData = product.MetaData,
|
MetaData = product.MetaData,
|
||||||
IsActive = product.IsActive,
|
IsActive = product.IsActive,
|
||||||
Stock = product.Stock,
|
Stock = product.Stock,
|
||||||
@ -117,7 +117,7 @@ public class ProductService(BaseRepository<Product> productRepository, ILogger<P
|
|||||||
product.ImageUrl = input.ImageUrl;
|
product.ImageUrl = input.ImageUrl;
|
||||||
product.Price = input.Price;
|
product.Price = input.Price;
|
||||||
product.Type = Enum.Parse<ProductTypeEnum>(input.Type, true);
|
product.Type = Enum.Parse<ProductTypeEnum>(input.Type, true);
|
||||||
product.SaleStatus = input.SaleStatus;
|
product.Status = (int)input.Status;
|
||||||
product.MetaData = input.MetaData;
|
product.MetaData = input.MetaData;
|
||||||
product.IsActive = input.IsActive;
|
product.IsActive = input.IsActive;
|
||||||
product.Stock = input.Stock;
|
product.Stock = input.Stock;
|
||||||
@ -141,7 +141,7 @@ public class ProductService(BaseRepository<Product> productRepository, ILogger<P
|
|||||||
ImageUrl = product.ImageUrl,
|
ImageUrl = product.ImageUrl,
|
||||||
Price = product.Price,
|
Price = product.Price,
|
||||||
Type = product.Type.ToString(),
|
Type = product.Type.ToString(),
|
||||||
SaleStatus = product.SaleStatus,
|
Status = product.Status.ToString(),
|
||||||
MetaData = product.MetaData,
|
MetaData = product.MetaData,
|
||||||
IsActive = product.IsActive,
|
IsActive = product.IsActive,
|
||||||
Stock = product.Stock,
|
Stock = product.Stock,
|
||||||
@ -198,7 +198,7 @@ public class ProductService(BaseRepository<Product> productRepository, ILogger<P
|
|||||||
ImageUrl = product.ImageUrl,
|
ImageUrl = product.ImageUrl,
|
||||||
Price = product.Price,
|
Price = product.Price,
|
||||||
Type = product.Type.ToString(),
|
Type = product.Type.ToString(),
|
||||||
SaleStatus = product.SaleStatus,
|
Status = product.Status.ToString(),
|
||||||
MetaData = product.MetaData,
|
MetaData = product.MetaData,
|
||||||
IsActive = product.IsActive,
|
IsActive = product.IsActive,
|
||||||
Stock = product.Stock,
|
Stock = product.Stock,
|
||||||
@ -230,7 +230,7 @@ public class ProductService(BaseRepository<Product> productRepository, ILogger<P
|
|||||||
var pageResult = await productRepository.Queryable()
|
var pageResult = await productRepository.Queryable()
|
||||||
.WhereIF(!string.IsNullOrWhiteSpace(input.Name), p => p.Name.Contains(input.Name))
|
.WhereIF(!string.IsNullOrWhiteSpace(input.Name), p => p.Name.Contains(input.Name))
|
||||||
.WhereIF(!string.IsNullOrWhiteSpace(input.Type), p => p.Type.ToString() == input.Type)
|
.WhereIF(!string.IsNullOrWhiteSpace(input.Type), p => p.Type.ToString() == input.Type)
|
||||||
.WhereIF(!string.IsNullOrWhiteSpace(input.SaleStatus), p => p.SaleStatus == input.SaleStatus)
|
.WhereIF(input.Status.HasValue, p => p.Status == (int)input.Status)
|
||||||
.WhereIF(input.IsActive.HasValue, p => p.IsActive == input.IsActive.Value)
|
.WhereIF(input.IsActive.HasValue, p => p.IsActive == input.IsActive.Value)
|
||||||
.OrderByDescending(p => p.CreatedAt)
|
.OrderByDescending(p => p.CreatedAt)
|
||||||
.Select(p => new ProductOutput
|
.Select(p => new ProductOutput
|
||||||
@ -241,7 +241,7 @@ public class ProductService(BaseRepository<Product> productRepository, ILogger<P
|
|||||||
ImageUrl = p.ImageUrl,
|
ImageUrl = p.ImageUrl,
|
||||||
Price = p.Price,
|
Price = p.Price,
|
||||||
Type = p.Type.ToString(),
|
Type = p.Type.ToString(),
|
||||||
SaleStatus = p.SaleStatus,
|
Status = p.Status.ToString(),
|
||||||
MetaData = p.MetaData,
|
MetaData = p.MetaData,
|
||||||
IsActive = p.IsActive,
|
IsActive = p.IsActive,
|
||||||
Stock = p.Stock,
|
Stock = p.Stock,
|
||||||
@ -254,4 +254,34 @@ public class ProductService(BaseRepository<Product> productRepository, ILogger<P
|
|||||||
|
|
||||||
return new PageListModel<ProductOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
|
return new PageListModel<ProductOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新商品上架/下架状态(取反)
|
||||||
|
/// </summary>
|
||||||
|
public async Task UpdateSaleStatusAsync(long id)
|
||||||
|
{
|
||||||
|
logger.LogInformation("正在更新商品上下架状态,ID: {Id}", id);
|
||||||
|
|
||||||
|
var product = await productRepository.GetByIdAsync(id);
|
||||||
|
if (product == null)
|
||||||
|
{
|
||||||
|
logger.LogWarning("未找到要更新状态的商品,ID: {Id}", id);
|
||||||
|
throw new BusinessException("商品不存在", 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
product.Status = product.Status == (int)ProductStatusEnum.OnSale
|
||||||
|
? (int)ProductStatusEnum.OffSale
|
||||||
|
: (int)ProductStatusEnum.OnSale;
|
||||||
|
product.UpdatedBy = "System";
|
||||||
|
product.UpdatedAt = DateTime.Now;
|
||||||
|
|
||||||
|
var result = await productRepository.UpdateAsync(product);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
logger.LogError("商品状态更新失败,ID: {Id}", id);
|
||||||
|
throw new BusinessException("更新商品状态失败", 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.LogInformation("商品上下架状态更新成功,ID: {Id}, SaleStatus: {SaleStatus}", id, product.Status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -170,15 +170,14 @@ public class UsersService(
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新用户状态
|
/// 更新用户状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<BaseResponse> UpdateStatusAsync(long id, UpdateUserStatusInput input)
|
public async Task<BaseResponse> UpdateStatusAsync(long id)
|
||||||
{
|
{
|
||||||
var exists = await Queryable().AnyAsync(u => u.Id == id);
|
var exists = await usersRepository.GetByIdAsync(id);
|
||||||
if (!exists)
|
if (exists == null)
|
||||||
{
|
{
|
||||||
return BaseResponse.Fail("用户不存在");
|
return BaseResponse.Fail("用户不存在");
|
||||||
}
|
}
|
||||||
|
var statusValue = exists.Status == (int)UserStatusEnum.Active ? UserStatusEnum.Disabled : UserStatusEnum.Active;
|
||||||
var statusValue = input.Status == 1 ? UserStatusEnum.Active : UserStatusEnum.Disabled;
|
|
||||||
var result = await UpdateAsync(
|
var result = await UpdateAsync(
|
||||||
u => new Users { Status = (int)statusValue },
|
u => new Users { Status = (int)statusValue },
|
||||||
u => u.Id == id
|
u => u.Id == id
|
||||||
|
|||||||
@ -45,7 +45,7 @@ public class WxMallService(
|
|||||||
public async Task<List<WxProductOutput>> GetProductsAsync(long userId, string? type = null)
|
public async Task<List<WxProductOutput>> GetProductsAsync(long userId, string? type = null)
|
||||||
{
|
{
|
||||||
var query = exchangeRecordRepository.Context.Queryable<Product>()
|
var query = exchangeRecordRepository.Context.Queryable<Product>()
|
||||||
.Where(p => !p.IsDeleted && p.IsActive && p.SaleStatus == "OnSale")
|
.Where(p => !p.IsDeleted && p.IsActive && p.Status == (int)ProductStatusEnum.OnSale)
|
||||||
.WhereIF(!string.IsNullOrEmpty(type), p => p.Type.ToString() == type)
|
.WhereIF(!string.IsNullOrEmpty(type), p => p.Type.ToString() == type)
|
||||||
.OrderByDescending(p => p.CreatedAt);
|
.OrderByDescending(p => p.CreatedAt);
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ public class WxMallService(
|
|||||||
|
|
||||||
// 批量提取 PetBg 商品的 SkinId
|
// 批量提取 PetBg 商品的 SkinId
|
||||||
var skinProductMap = products
|
var skinProductMap = products
|
||||||
.Where(p => p.Type == ProductTypeEnum.PetBg)
|
.Where(p => p.Type == ProductTypeEnum.PetSkin)
|
||||||
.Select(p => new { ProductId = p.Id, SkinId = GetSkinIdFromMetaData(p.MetaData) })
|
.Select(p => new { ProductId = p.Id, SkinId = GetSkinIdFromMetaData(p.MetaData) })
|
||||||
.Where(x => x.SkinId > 0)
|
.Where(x => x.SkinId > 0)
|
||||||
.ToList();
|
.ToList();
|
||||||
@ -122,13 +122,13 @@ public class WxMallService(
|
|||||||
public async Task<WxProductOutput?> GetProductDetailAsync(long userId, long productId)
|
public async Task<WxProductOutput?> GetProductDetailAsync(long userId, long productId)
|
||||||
{
|
{
|
||||||
var product = await exchangeRecordRepository.Context.Queryable<Product>()
|
var product = await exchangeRecordRepository.Context.Queryable<Product>()
|
||||||
.Where(p => p.Id == productId && !p.IsDeleted && p.IsActive && p.SaleStatus == "OnSale")
|
.Where(p => p.Id == productId && !p.IsDeleted && p.IsActive && p.Status == (int)ProductStatusEnum.OnSale)
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
|
|
||||||
if (product == null) return null;
|
if (product == null) return null;
|
||||||
|
|
||||||
PetSkinBrief? skinBrief = null;
|
PetSkinBrief? skinBrief = null;
|
||||||
if (product.Type == ProductTypeEnum.PetBg)
|
if (product.Type == ProductTypeEnum.PetSkin)
|
||||||
{
|
{
|
||||||
var skinId = GetSkinIdFromMetaData(product.MetaData);
|
var skinId = GetSkinIdFromMetaData(product.MetaData);
|
||||||
if (skinId > 0)
|
if (skinId > 0)
|
||||||
@ -190,7 +190,7 @@ public class WxMallService(
|
|||||||
|
|
||||||
// 查询商品
|
// 查询商品
|
||||||
var product = await exchangeRecordRepository.Context.Queryable<Product>()
|
var product = await exchangeRecordRepository.Context.Queryable<Product>()
|
||||||
.Where(p => p.Id == input.ProductId && !p.IsDeleted && p.IsActive && p.SaleStatus == "OnSale")
|
.Where(p => p.Id == input.ProductId && !p.IsDeleted && p.IsActive && p.Status == (int)ProductStatusEnum.OnSale)
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
|
|
||||||
if (product == null)
|
if (product == null)
|
||||||
|
|||||||
@ -214,6 +214,31 @@ public class AdminController : BaseController
|
|||||||
return BaseResponse<PageListModel<AdminUserOutput>>.Fail("查询管理员列表失败,请稍后重试");
|
return BaseResponse<PageListModel<AdminUserOutput>>.Fail("查询管理员列表失败,请稍后重试");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 切换管理员状态(激活/冻结)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">管理员ID</param>
|
||||||
|
/// <returns>操作结果</returns>
|
||||||
|
[HttpPut("users/{id}/status")]
|
||||||
|
public async Task<BaseResponse<object>> ToggleUserStatusAsync(long id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _adminUserService.ToggleStatusAsync(id);
|
||||||
|
return Success(new object(), "切换管理员状态成功");
|
||||||
|
}
|
||||||
|
catch (BusinessException ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(ex, "切换管理员状态业务异常: {Message}", ex.Message);
|
||||||
|
return BaseResponse<object>.Fail(ex.Message);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "切换管理员状态系统异常,ID:{Id}", id);
|
||||||
|
return BaseResponse<object>.Fail("切换状态失败,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChangePasswordInput
|
public class ChangePasswordInput
|
||||||
|
|||||||
@ -156,22 +156,59 @@ public class MedalController : BaseController
|
|||||||
/// <param name="status">状态: 0=禁用, 1=启用</param>
|
/// <param name="status">状态: 0=禁用, 1=启用</param>
|
||||||
/// <returns>操作结果</returns>
|
/// <returns>操作结果</returns>
|
||||||
[HttpPut("{id}/status")]
|
[HttpPut("{id}/status")]
|
||||||
public async Task<BaseResponse<object>> UpdateStatusAsync(long id, [FromBody] int status)
|
public async Task<BaseResponse<bool>> UpdateStatusAsync(long id)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _medalService.UpdateStatusAsync(id, status);
|
var res = await _medalService.UpdateStatusAsync(id);
|
||||||
return Success(new object(), status == 1 ? "启用勋章成功" : "禁用勋章成功");
|
return Success(res, "更新勋章状态成功");
|
||||||
}
|
}
|
||||||
catch (BusinessException ex)
|
catch (BusinessException ex)
|
||||||
{
|
{
|
||||||
_logger.LogWarning(ex, "更新勋章状态业务异常: {Message}", ex.Message);
|
_logger.LogWarning(ex, "更新勋章状态业务异常: {Message}", ex.Message);
|
||||||
return BaseResponse<object>.Fail(ex.Message);
|
return BaseResponse<bool>.Fail(ex.Message);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "更新勋章状态系统异常,ID:{Id},Status:{Status}", id, status);
|
_logger.LogError(ex, "更新勋章状态系统异常,ID:{Id}", id);
|
||||||
return BaseResponse<object>.Fail("更新勋章状态失败,请稍后重试");
|
return BaseResponse<bool>.Fail("更新勋章状态失败,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取规则配置中可用的目标表列表
|
||||||
|
/// </summary>
|
||||||
|
[HttpGet("rule-config/tables")]
|
||||||
|
public async Task<BaseResponse<List<MedalRuleTableOptionOutput>>> GetAvailableTables()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await _medalService.GetAvailableTablesAsync();
|
||||||
|
return Success(result);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "获取可用目标表列表系统异常");
|
||||||
|
return BaseResponse<List<MedalRuleTableOptionOutput>>.Fail("获取可用目标表列表失败,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定表的可用字段列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">表名</param>
|
||||||
|
[HttpGet("rule-config/tables/{tableName}/fields")]
|
||||||
|
public async Task<BaseResponse<List<MedalRuleFieldOptionOutput>>> GetTableFields(string tableName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await _medalService.GetTableFieldsAsync(tableName);
|
||||||
|
return Success(result);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "获取可用字段列表系统异常,表名:{TableName}", tableName);
|
||||||
|
return BaseResponse<List<MedalRuleFieldOptionOutput>>.Fail("获取可用字段列表失败,请稍后重试");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -145,11 +145,11 @@ public class PetManageController : BaseController
|
|||||||
/// 更新宠物模板状态(启用/禁用)
|
/// 更新宠物模板状态(启用/禁用)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpPut("{id}/status")]
|
[HttpPut("{id}/status")]
|
||||||
public async Task<BaseResponse<object>> UpdateTemplateStatusAsync(long id, [FromBody] int status)
|
public async Task<BaseResponse<object>> UpdateTemplateStatusAsync(long id)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _petService.UpdateTemplateStatusAsync(id, status);
|
await _petService.UpdateTemplateStatusAsync(id);
|
||||||
return Success(new object(), "更新状态成功");
|
return Success(new object(), "更新状态成功");
|
||||||
}
|
}
|
||||||
catch (BusinessException ex)
|
catch (BusinessException ex)
|
||||||
|
|||||||
@ -148,4 +148,29 @@ public class ProductController : BaseController
|
|||||||
return BaseResponse<PageListModel<ProductOutput>>.Fail("查询商品列表失败,请稍后重试");
|
return BaseResponse<PageListModel<ProductOutput>>.Fail("查询商品列表失败,请稍后重试");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新商品上架/下架状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">商品ID</param>
|
||||||
|
/// <returns>操作结果</returns>
|
||||||
|
[HttpPut("{id}/status")]
|
||||||
|
public async Task<BaseResponse<object>> UpdateSaleStatusAsync(long id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _productService.UpdateSaleStatusAsync(id);
|
||||||
|
return Success(new object(), "更新商品状态成功");
|
||||||
|
}
|
||||||
|
catch (BusinessException ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(ex, "更新商品状态业务异常: {Message}", ex.Message);
|
||||||
|
return BaseResponse<object>.Fail(ex.Message);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "更新商品状态系统异常,ID:{Id}", id);
|
||||||
|
return BaseResponse<object>.Fail("更新商品状态失败,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,9 +45,9 @@ public class UsersController : BaseController
|
|||||||
/// 更新用户状态
|
/// 更新用户状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpPut("{id}/status")]
|
[HttpPut("{id}/status")]
|
||||||
public async Task<BaseResponse> UpdateStatus(long id, [FromBody] UpdateUserStatusInput input)
|
public async Task<BaseResponse> UpdateStatus(long id)
|
||||||
{
|
{
|
||||||
return await _usersService.UpdateStatusAsync(id, input);
|
return await _usersService.UpdateStatusAsync(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -14,6 +14,7 @@ using QYZH.InteractiveMagazine.Infrastructure.Extensions;
|
|||||||
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
|
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
|
||||||
using QYZH.InteractiveMagazine.Models.Entity;
|
using QYZH.InteractiveMagazine.Models.Entity;
|
||||||
using QYZH.InteractiveMagazine.Models.Enum;
|
using QYZH.InteractiveMagazine.Models.Enum;
|
||||||
|
using QYZH.InteractiveMagazine.Models.Settings;
|
||||||
using QYZH.InteractiveMagazine.Repository;
|
using QYZH.InteractiveMagazine.Repository;
|
||||||
using QYZH.InteractiveMagazine.Repository.Core;
|
using QYZH.InteractiveMagazine.Repository.Core;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
@ -25,6 +26,9 @@ using Yitter.IdGenerator;
|
|||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// 加载勋章规则独立配置文件
|
||||||
|
builder.Configuration.AddJsonFile("medal-rule-config.json", optional: false, reloadOnChange: true);
|
||||||
|
|
||||||
// 初始化雪花ID生成器
|
// 初始化雪花ID生成器
|
||||||
YitIdHelper.SetIdGenerator(new IdGeneratorOptions() { WorkerId = 1 });
|
YitIdHelper.SetIdGenerator(new IdGeneratorOptions() { WorkerId = 1 });
|
||||||
// autofac注入 允许使用autofac作为DI容器
|
// autofac注入 允许使用autofac作为DI容器
|
||||||
@ -141,6 +145,9 @@ builder.Services.AddInfrastructureServices(builder.Configuration, builder.Enviro
|
|||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddHttpContextAccessor();
|
||||||
builder.Services.AddScoped(typeof(BaseRepository<>));
|
builder.Services.AddScoped(typeof(BaseRepository<>));
|
||||||
|
|
||||||
|
// 注册勋章规则配置
|
||||||
|
builder.Services.Configure<MedalRuleConfigSettings>(builder.Configuration.GetSection("MedalRuleConfig"));
|
||||||
|
|
||||||
// 添加CORS
|
// 添加CORS
|
||||||
builder.Services.AddCors(options =>
|
builder.Services.AddCors(options =>
|
||||||
{
|
{
|
||||||
|
|||||||
43
QYZH.InteractiveMagazine.WebApi/medal-rule-config.json
Normal file
43
QYZH.InteractiveMagazine.WebApi/medal-rule-config.json
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"MedalRuleConfig": {
|
||||||
|
"Tables": [
|
||||||
|
{
|
||||||
|
"TableName": "CheckInRecord",
|
||||||
|
"DisplayName": "签到记录",
|
||||||
|
"Fields": [
|
||||||
|
{ "FieldName": "ContinuousDays", "DisplayName": "连续天数" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"TableName": "UserPet",
|
||||||
|
"DisplayName": "宠物",
|
||||||
|
"Fields": [
|
||||||
|
{
|
||||||
|
"FieldName": "GrowthPoints",
|
||||||
|
"DisplayName": "成长值"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "FeedingCount",
|
||||||
|
"DisplayName": "喂养次数"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Comprehension",
|
||||||
|
"DisplayName": "理解力"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Judgment",
|
||||||
|
"DisplayName": "判断力"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Expression",
|
||||||
|
"DisplayName": "表达力"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Persuasiveness",
|
||||||
|
"DisplayName": "说服力"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user