This commit is contained in:
Putoo
2026-07-13 19:52:55 +08:00
parent 5d375e94bd
commit b5de98a214
20 changed files with 873 additions and 64 deletions

View File

@@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AActionMethodExecutor_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FSourcesCache_003F294078ecfce6fdb942ecfee089f09717de7a6fcfe5efd9fdb6f4f93c0fb4813_003FActionMethodExecutor_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIRedisCache_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F55e5569a0f314a0db6a665eafad446dd6800_003F9e_003F88bbb06d_003FIRedisCache_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AISqlSugarClient_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6c0f22f0a47643a3b2a40899acd2044c2e3a00_003F5b_003F113fef0a_003FISqlSugarClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AITimerJobManager_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F16de42b578c24823a56e75bd74225f401c00_003Fbf_003Fb5f6dd44_003FITimerJobManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

View File

@@ -12,6 +12,12 @@ namespace Application.Domain.Entity
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string tradeId { get; set; }
/// <summary>
/// areaId
/// </summary>
[SugarColumn(IsNullable = true)]
public int? areaId { get; set; }
/// <summary>
/// userId
/// </summary>

View File

@@ -2,6 +2,12 @@
public interface ITradeService
{
Task<bool> AddTrade(string userId, string code,string name, string propId, int count, long price,string content);
Task<game_trade> GetTradeInfo(string tradeId);
Task<bool> AddTrade(int areaId, string userId, string code,string name, string propId, int count, long price,string content);
Task<bool> UpdateTradeCount(string tradeId, int op, int count, bool isDel = false);
Task<int> GetUserTradeCount(string userId);
Task<List<game_trade>> GetUserTradeData(string userId);
Task<List<game_trade>> GetUserTradeData(int areaId,string userId, int type, string query, int page, int limit,
RefAsync<int> total);
}

View File

@@ -2,11 +2,19 @@
public class TradeService(ISqlSugarClient DbClient, IRedisCache redis) : ITradeService, ITransient
{
public async Task<bool> AddTrade(string userId, string code,string name, string propId, int count,long price, string content)
public async Task<game_trade> GetTradeInfo(string tradeId)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_trade>();
return await db.Queryable<game_trade>().Where(it => it.tradeId == tradeId).SingleAsync();
}
public async Task<bool> AddTrade(int areaId, string userId, string code, string name, string propId, int count,
long price, string content)
{
game_trade trade = new game_trade()
{
tradeId = StringAssist.NewGuid,
areaId = areaId,
userId = userId,
code = code,
name = name,
@@ -20,9 +28,47 @@ public class TradeService(ISqlSugarClient DbClient, IRedisCache redis) : ITradeS
return await db.Insertable(trade).ExecuteCommandAsync() > 0;
}
public async Task<bool> UpdateTradeCount(string tradeId, int op, int count, bool isDel = false)
{
bool result = false;
var db = DbClient.AsTenant().GetConnectionWithAttr<game_trade>();
if (isDel)
{
result = await db.Deleteable<game_trade>().Where(it => it.tradeId == tradeId).ExecuteCommandAsync() > 0;
}
else
{
int opCount = op == 1 ? count : (0 - count);
result = await db.Updateable<game_trade>()
.SetColumns(it => it.count == it.count + opCount)
.Where(it => it.tradeId == tradeId).ExecuteCommandAsync() > 0;
}
return result;
}
public async Task<int> GetUserTradeCount(string userId)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_trade>();
return await db.Queryable<game_trade>().Where(it => it.userId == userId).CountAsync();
}
public async Task<List<game_trade>> GetUserTradeData(string userId)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_trade>();
return await db.Queryable<game_trade>().Where(it => it.userId == userId).ToListAsync();
}
public async Task<List<game_trade>> GetUserTradeData(int areaId, string userId, int type, string query, int page, int limit,
RefAsync<int> total)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_trade>();
return await db.Queryable<game_trade>().Where(it=>it.areaId==areaId)
.WhereIF(!string.IsNullOrEmpty(userId), it => it.userId == userId)
.WhereIF(type==1,it=>it.code=="Equ")
.WhereIF(type==2,it=>it.code=="Goods")
.WhereIF(!string.IsNullOrEmpty(query),it=>it.name.Contains(query))
.OrderByDescending(it=>it.addTime)
.ToPageListAsync(page, limit, total);
}
}

View File

@@ -514,7 +514,7 @@ public class UnitUserAttrService(ISqlSugarClient DbClient, IRedisCache redis) :
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_online_time>();
await db.Updateable<unit_user_online_time>().SetColumns(it => it.dayTime == 0)
.WhereIF(day == 1, it => it.monthTime == 0)
.Where(it => true).ExecuteCommandAsync();
.Where(it => it.userId != "0").ExecuteCommandAsync();
}
#endregion

View File

@@ -1,5 +1,4 @@
namespace Application.Web.Controllers.Map;
namespace Application.Web.Controllers.Map;
/// <summary>
/// 地图接口
@@ -125,34 +124,24 @@ public class MapController : ControllerBase
string ip = ComHelper.GetClientUserIp(HttpContext);
await _mapService.UpdateUserOnMap(userId, ip, mapInfo.mapId);
//地图业务
IEnumerable<object> business = new List<object>();
if (mapInfo.isBus == 1)
{
var busData = await _mapService.GetMapBus(mapInfo.mapId, 0, 0);
business = busData.Select(it => new
{
busId = it.busId,
busName = it.busName
});
}
//地图资源
List<MapResModel> mapRes = new List<MapResModel>();
if (mapInfo.isRes == 1)
{
mapRes = await _mapService.GetMapResData(mapInfo.mapId, area);
}
#endregion
var busData = await _mapService.GetMapBus(mapInfo.mapId, 0, 0);//地图业务
IEnumerable<object> business = busData.Select(it => new
{
busId = it.busId,
busName = it.busName
});
List<MapResModel> mapRes = await _mapService.GetMapResData(mapInfo.mapId, area); //地图资源
var broadcast = await _messageService.GetBroadcastData(area);
var userFight = await _fightService.GetUserFight(userId);
string fightId = userFight.Count > 0 ? userFight[0] : "";
var mapGoods = await _fightService.GetMapFightGoods(mapInfo.mapId);
mapGoods = mapGoods.FindAll(it => it.userId == "0" || it.userId == userId).Take(3).ToList();
var taskData = await _taskService.GetUserTaskData(userId);
var taskData = await _taskService.GetUserTaskData(userId);
int isHook = 0; //挂机处理
var onHook = await _hookService.GetUserOnHook(userId);
isHook = (int)onHook.status;

View File

@@ -100,7 +100,10 @@ public class TaskController : ControllerBase
int toGoods = await _goodsService.GetUserGoodsCount(userId, GameConfig.GameGetTaskGoods);
int retGoods = await _goodsService.GetUserGoodsCount(userId, GameConfig.GameRetTaskGoods);
return PoAction.Ok(new
{ npc = npcInfo, data = data, talkMsg, taskState, btnTips = taskInfo.btnTips, toGoods, retGoods });
{
npc = npcInfo, data = data, talkMsg, taskState, award = taskInfo.award, btnTips = taskInfo.btnTips, toGoods,
retGoods
});
}
/// <summary>
@@ -124,7 +127,7 @@ public class TaskController : ControllerBase
public async Task<IPoAction> RestTask(int task)
{
string userId = StateHelper.userId;
var onTaskInfo = await _taskService.GetUserTaskInfo(userId,task);
var onTaskInfo = await _taskService.GetUserTaskInfo(userId, task);
if (onTaskInfo == null)
{
return PoAction.Message("暂无任务!");
@@ -188,7 +191,7 @@ public class TaskController : ControllerBase
int toGoods = await _goodsService.GetUserGoodsCount(userId, GameConfig.GameGetTaskGoods);
int retGoods = await _goodsService.GetUserGoodsCount(userId, GameConfig.GameRetTaskGoods);
return PoAction.Ok(new
{ data = data, talkMsg, taskState, toGoods, retGoods,lev = taskInfo.lev });
{ data = data, talkMsg, taskState, toGoods, retGoods, lev = taskInfo.lev, award = taskInfo.award });
}
/// <summary>
@@ -263,7 +266,7 @@ public class TaskController : ControllerBase
}
message = message.TrimEnd(',');
await GameBus.UpdateBag(userId, 1, award, "完成任务");//发放奖励
await GameBus.UpdateBag(userId, 1, award, "完成任务"); //发放奖励
}
return PoAction.Ok(true, message);

View File

@@ -15,10 +15,11 @@ public class TradeController : ControllerBase
private readonly IGameChatService _chatService;
private readonly IUnitUserAttrService _attrService;
private readonly ITradeService _tradeService;
private readonly IUnitUserAccService _accService;
public TradeController(IGameGoodsService goodsService, IGameEquService equService, IUnitUserWeight weightService,
IUnitUserService userService, IGameChatService chatService,
IUnitUserAttrService attrService, ITradeService tradeService)
IUnitUserAttrService attrService, ITradeService tradeService, IUnitUserAccService accService)
{
_goodsService = goodsService;
_equService = equService;
@@ -27,6 +28,7 @@ public class TradeController : ControllerBase
_chatService = chatService;
_attrService = attrService;
_tradeService = tradeService;
_accService = accService;
}
/// <summary>
@@ -41,6 +43,7 @@ public class TradeController : ControllerBase
{
count = count < 1 ? 1 : count;
string userId = StateHelper.userId;
int areaId = StateHelper.areaId;
int lev = await _attrService.GetUserLev(userId);
if (lev < 60)
{
@@ -75,7 +78,7 @@ public class TradeController : ControllerBase
if (await _equService.DeductUserEqu(userId, [equInfo], "寄售装备"))
{
string data = JsonConvert.SerializeObject(equInfo);
if (await _tradeService.AddTrade(userId, nameof(GameEnum.PropCode.Equ), equInfo.unitEquName,
if (await _tradeService.AddTrade(areaId, userId, nameof(GameEnum.PropCode.Equ), equInfo.unitEquName,
equInfo.ueId, 1, price, data))
{
return PoAction.Ok(true);
@@ -123,7 +126,8 @@ public class TradeController : ControllerBase
if (await _goodsService.UpdateUserGoods(userId, 0, goodsId, count, "寄售物品"))
{
if (await _tradeService.AddTrade(userId, nameof(GameEnum.PropCode.Goods), MyGoods.goodsName, prop,
if (await _tradeService.AddTrade(areaId, userId, nameof(GameEnum.PropCode.Goods), MyGoods.goodsName,
prop,
count, price,
""))
{
@@ -145,4 +149,236 @@ public class TradeController : ControllerBase
return PoAction.Message("该物品不允许寄售!");
}
}
/// <summary>
/// 购买
/// </summary>
/// <param name="tradeId"></param>
/// <param name="count"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> Buy(string tradeId, int count)
{
count = count < 1 ? 1 : count;
string userId = StateHelper.userId;
int areaId = StateHelper.areaId;
var info = await _tradeService.GetTradeInfo(tradeId);
if (info == null)
{
return PoAction.Message("交易信息不存在!");
}
if (info.areaId != areaId)
{
return PoAction.Message("交易信息不存在!");
}
if (info.count < count)
{
return PoAction.Message("交易剩余数量不足!");
}
if (info.code == nameof(GameEnum.PropCode.Equ))
{
var myAcc = await _accService.GetUserAccInfo(userId, nameof(AccEnum.AccType.copper));
if (myAcc < info.price)
{
return PoAction.Message("您的铜贝不足!");
}
if (await _accService.UpdateUserCopper(userId, 0, (long)info.price, $"交易支付:{info.name}"))
{
if (await _tradeService.UpdateTradeCount(info.tradeId, 0, 1, true))
{
unit_user_equ equInfo = JsonConvert.DeserializeObject<unit_user_equ>(info.content);
equInfo.userId = userId;
await _equService.AddUserEqu(equInfo, "交易获得");
long GetCopper = Convert.ToInt64(info.price * 0.9M);
if (await _accService.UpdateUserCopper(info.userId, 1, GetCopper, $"交易收入:{info.name}"))
{
string msg = $"您的装备[{info.name}]成功交易,交易价格{info.price}铜贝,到账{GetCopper}铜贝!";
await _chatService.SendChat(info.userId, areaId, nameof(GameChatEnum.Code.Notice), msg);
}
return PoAction.Ok(true);
}
else
{
return PoAction.Message("交易失败,请稍后尝试!");
}
}
else
{
return PoAction.Message("交易失败,请稍后尝试!");
}
}
else if (info.code == nameof(GameEnum.PropCode.Goods))
{
var myAcc = await _accService.GetUserAccInfo(userId, nameof(AccEnum.AccType.copper));
var needCopper = Convert.ToInt64(info.price) * count;
if (myAcc < needCopper)
{
return PoAction.Message("您的铜贝不足!");
}
if (await _accService.UpdateUserCopper(userId, 0, needCopper, $"交易支付:{info.name}×{count}"))
{
if (await _tradeService.UpdateTradeCount(info.tradeId, 0, count, info.count == count))
{
long GetCopper = Convert.ToInt64(needCopper * 0.9M);
if (await _accService.UpdateUserCopper(info.userId, 1, GetCopper, $"交易收入:{info.name}"))
{
await _goodsService.UpdateUserGoods(userId, 1, Convert.ToInt32(info.propId), count, "交易获得");
string msg = $"您成功交易物品[{info.name}]×{count},交易价格{needCopper}铜贝,到账{GetCopper}铜贝!";
await _chatService.SendChat(info.userId, areaId, nameof(GameChatEnum.Code.Notice), msg);
}
return PoAction.Ok(true);
}
else
{
return PoAction.Message("交易失败,请稍后尝试!");
}
}
else
{
return PoAction.Message("交易失败,请稍后尝试!");
}
}
else
{
return PoAction.Message("交易失败,请稍后尝试!");
}
}
/// <summary>
/// 获取交易列表
/// </summary>
/// <param name="no"></param>
/// <param name="type"></param>
/// <param name="query"></param>
/// <param name="page"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> GetTradeData(string? no, int type, string? query, int page)
{
string userId = string.Empty;
int areaId = StateHelper.areaId;
if (!string.IsNullOrEmpty(no))
{
var userInfo = await _userService.GetUserInfoByUserNo(no);
if (userInfo != null)
{
userId = userInfo.userId;
}
}
RefAsync<int> total = 0;
var data = await _tradeService.GetUserTradeData(areaId, userId, type, query, page, 10, total);
return PoAction.Ok(new { data, total = total.Value });
}
/// <summary>
/// 获取个人交易列表
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> GetMyTrade()
{
string userId = StateHelper.userId;
var data = await _tradeService.GetUserTradeData(userId);
return PoAction.Ok(data);
}
/// <summary>
/// 下架交易
/// </summary>
/// <param name="tradeId"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> DownTrade(string tradeId)
{
string userId = StateHelper.userId;
var info = await _tradeService.GetTradeInfo(tradeId);
if (info == null)
{
return PoAction.Message("交易信息不存在!");
}
if (info.userId != userId)
{
return PoAction.Message("交易信息不存在!");
}
if (info.code == nameof(GameEnum.PropCode.Equ))
{
if (await _tradeService.UpdateTradeCount(info.tradeId, 0, 1, true))
{
unit_user_equ equInfo = JsonConvert.DeserializeObject<unit_user_equ>(info.content);
await _equService.AddUserEqu(equInfo, "下架交易装备");
return PoAction.Ok(true);
}
else
{
return PoAction.Message("下架失败,请稍后尝试!");
}
}
else if (info.code == nameof(GameEnum.PropCode.Goods))
{
int count = Convert.ToInt32(info.count);
if (await _tradeService.UpdateTradeCount(info.tradeId, 0, count, true))
{
await _goodsService.UpdateUserGoods(userId, 1, Convert.ToInt32(info.propId), count, "下架交易物品");
return PoAction.Ok(true);
}
else
{
return PoAction.Message("下架失败,请稍后尝试!");
}
}
else
{
return PoAction.Message("下架失败,请稍后尝试!");
}
}
/// <summary>
/// 获取交易详情
/// </summary>
/// <param name="tradeId"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> GetTradeInfo(string tradeId)
{
string userId = StateHelper.userId;
int areaId = StateHelper.areaId;
var info = await _tradeService.GetTradeInfo(tradeId);
if (info == null)
{
return PoAction.Message("交易信息不存在!");
}
if (info.areaId != areaId)
{
return PoAction.Message("交易信息不存在!");
}
if (info.code != nameof(GameEnum.PropCode.Equ))
{
return PoAction.Message(info.propId, 100);
}
var ueInfo = JsonConvert.DeserializeObject<unit_user_equ>(info.content);
var equInfo = await _equService.GetEquInfo((int)ueInfo.equId);
game_equ_suit suit = new game_equ_suit();
if (ueInfo.suitCode != "0" && !string.IsNullOrEmpty(ueInfo.suitCode))
{
suit = await _equService.GetEuqSuitInfo(ueInfo.suitCode);
}
UserModel user = await UserModelTool.GetUserView(ueInfo.owerId);
return PoAction.Ok(new { equ = equInfo, suit, equData = ueInfo, user });
}
}

View File

@@ -2,8 +2,8 @@
统一配置中心
*/
export class BaseConfig {
public static BaseUrl: string = 'https://192.168.0.142:7198'
public static BaseMediaUrl: string = 'https://192.168.0.142:7198/'
public static BaseUrl: string = 'https://localhost:7198'
public static BaseMediaUrl: string = 'https://localhost:7198/'
// public static BaseUrl:string="http://v3.pccsh.com";
// public static BaseMediaUrl:string="http://v3.pccsh.com";
}

View File

@@ -3,13 +3,17 @@
<strong>{{ npcData.npcName }}</strong>:{{ talkMsg }}
</div>
<div class="content" v-if="taskState == 100">
恭喜,任务已全部完成!
恭喜,任务已全部完成!
</div>
<div v-else>
<div v-if="data.state != -1">
<div class="content" v-if="needs.length > 0">
任务要求:<br>
<GameTaskPropVerify :data="verifyData.needs" @mapTo="mapTo"></GameTaskPropVerify>
<GameTaskPropVerify :data="verifyData.needs" @mapTo="mapTo"></GameTaskPropVerify>
</div>
<div class="content" v-if="award.length > 0">
任务奖励:<br>
<GameProp :data="award" :count="1"></GameProp>
</div>
<div class="content" v-if="verifyData.result">
<div v-if="taskState == 1">
@@ -37,6 +41,7 @@ const btnTips = ref('');
const taskState = ref(-1);
const toGoods = ref(0);
const retGoods = ref(0);
const award = ref<Array<any>>([]);
let taskId = PageExtend.QueryString("task");
let npcId = LocalStorageHelper.GetOnNpc();
onMounted(async () => {
@@ -60,6 +65,9 @@ const BindData = async (): Promise<void> => {
taskState.value = result.data.taskState;
toGoods.value = result.data.toGoods;
retGoods.value = result.data.retGoods;
if (result.data.award != '') {
award.value = JSON.parse(result.data.award);
}
verifyData.value = data.value.result;
needs.value = verifyData.value.needs;
taskId = data.value.itemId;
@@ -84,9 +92,9 @@ const ReturnTask = async () => {
}
}
const mapTo = async (btnData: any) => {
const mapTo = async (btnData: any) => {
MessageExtend.LoadingToast("传送中...");
let result = await TaskService.NeedMapTo( Number(data.value.itemId), btnData.num);
let result = await TaskService.NeedMapTo(Number(data.value.itemId), btnData.num);
MessageExtend.LoadingClose();
if (result.code == 0) {
PageExtend.RedirectTo("/map");
@@ -96,9 +104,9 @@ const mapTo = async (btnData: any) => {
}
}
const retTask = async (btnData: any) => {
const retTask = async (btnData: any) => {
MessageExtend.LoadingToast("传送中...");
let result = await TaskService.ReturnTask( Number(data.value.itemId));
let result = await TaskService.ReturnTask(Number(data.value.itemId));
MessageExtend.LoadingClose();
if (result.code == 0) {
PageExtend.RedirectTo("/map");

View File

@@ -14,6 +14,10 @@
任务要求:<br>
<GameTaskPropVerify :data="verifyData.needs" @mapTo="mapTo"></GameTaskPropVerify>
</div>
<div class="content" v-if="award.length > 0">
任务奖励:<br>
<GameProp :data="award" :count="1"></GameProp>
</div>
<div class="content" v-if="verifyData.result">
<Abutton @click="retTask">我要传送</Abutton>(领路蝶:{{ retGoods }})
</div>
@@ -32,6 +36,7 @@ definePageMeta({
const data = ref<any>({});
const verifyData = ref<any>({});
const needs = ref<Array<any>>([]);
const award = ref<Array<any>>([]);
const talkMsg = ref('');
const taskState = ref(-1);
const toGoods = ref(0);
@@ -58,7 +63,10 @@ const BindData = async (): Promise<void> => {
taskState.value = result.data.taskState;
toGoods.value = result.data.toGoods;
retGoods.value = result.data.retGoods;
lev.value =result.data.lev;
if (result.data.award != '') {
award.value = JSON.parse(result.data.award);
}
lev.value = result.data.lev;
verifyData.value = data.value.result;
needs.value = verifyData.value.needs;
taskId = data.value.itemId;
@@ -111,7 +119,7 @@ const restTask = async (btnData: any) => {
let result = await TaskService.RestTask(Number(data.value.taskId));
MessageExtend.LoadingClose();
if (result.code == 0) {
MessageExtend.Notify("任务重置成功!","success");
MessageExtend.Notify("任务重置成功!", "success");
}
else {
MessageExtend.Notify(result.msg, "danger");

View File

@@ -1 +1,123 @@
<template></template>
<template>
<div class="module-title">
交易大厅.<Abar href="/trade/my">我的交易</Abar>
</div>
<div class="module-content">
分类:
<Acheak @click="Change('0')" :on-value="type" on-cheak="0">全部</Acheak>
<span>&nbsp;.&nbsp;</span>
<Acheak @click="Change('1')" :on-value="type" on-cheak="1">装备</Acheak>
<span>&nbsp;.&nbsp;</span>
<Acheak @click="Change('2')" :on-value="type" on-cheak="2">物品</Acheak>
</div>
<div class="module-content serch">
搜索内容<input type="text" class="search-ipt" v-model="serch">&nbsp;
<button class="ipt-btn" name="serch" @click="BindData">搜索</button>
</div>
<div class="module-content">
<div class="item border-btm" v-for="(item, index) in data" :key="index">
{{ PageExtend.GetPageIndex(currentPage, 10, index + 1) }}.
<span v-if="item.code == 'Equ'">
<Abar :href='"/trade/info?id=" + item.tradeId'>{{ item.name }}({{ item.price }}铜贝)</Abar>
</span>
<span v-else>
<Abar :href='"/prop/goods?id=" + item.propId'>{{ item.name }}({{ item.price }}铜贝)</Abar>
</span>
[<Abutton @click="Buy(item)">购买</Abutton>]
</div>
<span v-if="data.length == 0">
暂无交易.
</span>
</div>
<div class="content">
<Pagination :currentPage="currentPage" :limit="10" :total="total" @pageChange="handlePageChange" />
</div>
<GamePopup v-model:show="showBuy" title="【购买】">
<!-- 自定义内容 -->
<div class="common">
物品名称{{ showGoods.name }}<br>
购买单价{{ showGoods.price }} 铜贝<br>
<span v-if="showGoods.code != 'Equ'">
剩余数量{{ showGoods.count }}
</span>
</div>
<div class="common" style="text-align: center;">
<span v-if="showGoods.code != 'Equ'">
购买数量<input type="number" class="search-ipt" v-model="count"><br>
</span>
<button class="ipt-btn" name="serch" @click="ShopOk" style="margin-top: 15px;">购买</button>
</div>
</GamePopup>
</template>
<script setup lang="ts">
definePageMeta({
layout: layout.default,
middleware: 'page-loading'
})
const currentPage = ref<number>(1);
const total = ref<number>(0);
const data = ref<Array<any>>([]);
const showBuy = ref(false);
const count = ref(1);
const showGoods = ref<any>({});
const type = ref('0');
const serch = ref('');
onMounted(async () => {
try {
await BindData();
}
finally {
PageLoading.Close();
}
})
const BindData = async (): Promise<void> => {
let result = await TradeService.GetTradeData("", Number(type.value), serch.value, currentPage.value);
if (result.code == 0) {
data.value = result.data.data;
total.value = result.data.total;
}
else {
MessageExtend.ShowDialog("提示", result.msg);
}
};
const Change = async (_type: string) => {
type.value = _type;
await BindData();
}
/**翻页 */
const handlePageChange = async (page: number): Promise<void> => {
currentPage.value = page;
await BindData();
};
const Buy = (info: any) => {
showGoods.value = info;
count.value = 1;
showBuy.value = true;
}
const ShopOk = async () => {
if (count.value < 1 || count.value > 99) {
MessageExtend.ShowToast("每次购买数量在1~99哦.");
return;
}
MessageExtend.LoadingToast("购买中...");
let result = await TradeService.Buy(showGoods.value.tradeId, count.value);
MessageExtend.LoadingClose();
if (result.code == 0) {
showBuy.value = false;
await BindData();
MessageExtend.Notify(`成功购买${showGoods.value.name}×${count.value}`, "success");
}
else {
MessageExtend.ShowDialog("提示", result.msg);
}
}
</script>

View File

@@ -0,0 +1,122 @@
<template>
<div class="content">
<div class="common" v-if="equInfo.img != ''">
<Aimage :url="equInfo.img" _alt="."></Aimage>
</div>
<div class="common">
名称:<span v-html="EquTool.ConvertEquName(equData, 0)"></span> <br>
<span v-if="equData.equName != equData.unitEquName">
装备名称:{{ equData.unitEquName }}<br>
</span>
部位:{{ EquTool.GetEquPlaceName(equData.code) }}<br>
等级:{{ equData.lev }}<br>
品质:{{ equData.qualityName }}<br>
交易:{{ equData.isDeal == 1 ? "可交易" : "不可交易" }}<br>
赠送:{{ equData.isGive == 1 ? "可赠送" : "不可赠送" }}<br>
获取途径:{{ equInfo.source }}<br>
说明:{{ equInfo.remark }}<br>
签名:{{ equData.sign }}<br>
获得人:<GameUser :data="owUser" :show-icon="0" :show-area="0"></GameUser><br>
<span v-if="equData.sex != 'Default'">
性别:{{ equData.sex == 'Boy' ? "" : "" }}<br>
</span>
强化:{{ equData.isIntensify == 1 ? "可强化" : "不可强化" }}<br>
<span v-if="equData.intensifyLev > 0">
强化等级:{{ equData.intensifyLev }}<br>
</span>
<span v-if="equAwaken.length > 0">
<Abar :href='"/user/equ/awaken?ue=" + equData.ueId'>装备特性:{{ equAwaken[0].name }}({{ equAwaken[0].lev
}})
</Abar><br>
</span>
附魔:{{ equMent.name }}<br>
负重:{{ equData.weight }}<br>
<div v-if="equData.isAppr == 1" style="margin:0px;">
<span v-if="Number(equData.blood) > 0">
体力:{{ equData.blood }}<br>
</span>
<span v-if="Number(equData.minAtk) > 0">
攻击:{{ equData.minAtk }}-{{ equData.maxAtk }}<br>
</span>
<span v-if="Number(equData.defense) > 0">
防御:{{ equData.defense }}<br>
</span>
<span v-if="Number(equData.agility) > 0">
敏捷:{{ equData.agility }}<br>
</span>
<span v-if="Number(equData.morale) > 0">
士气:{{ equData.morale }}<br>
</span>
</div>
耐久:{{ equData.maxdurability }}/{{ equData.durability }}<br>
<span v-if="equData.suitCode != '0' && equData.suitCode != ''">
套装:<Abar :href='"/prop/suit?no=" + equData.suitCode'>{{ suitInfo.suitName }}</Abar><br>
</span>
特性:{{ EquTool.GetEquAttrName(equData.equAttr, 0) }}<br>
<span v-if="equData.holeCount > 0">
镶嵌:({{ gemMent.length }}/{{ equData.holeCount }})<br>
</span>
<span v-if="equData.opTime == 0">
<span v-if="equInfo.useTime > 0">
有效期:{{ equInfo.useTime }}
</span>
</span>
<span v-else>
<span v-if="equInfo.useTime > 0">
到期时间:{{ TimeExtend.Format(equData.useEndTime, "yyyy-MM-dd") }}
</span>
</span>
<div v-if="equData.isAppr == 0">
(*该装备需要鉴定)
</div>
</div>
</div>
</template>
<script setup lang="ts">
definePageMeta({
layout: layout.default,
middleware: 'page-loading'
})
const equData = ref<any>({});
const equInfo = ref<any>({});
const suitInfo = ref<any>({});
const owUser = ref<any>({});
const equAwaken = ref<Array<any>>([]);
const equMent = ref<any>({});
const gemMent = ref<Array<any>>([]);
onMounted(async () => {
try {
await BindData();
}
finally {
PageLoading.Close();
}
})
const BindData = async (): Promise<void> => {
let tradeId = PageExtend.QueryString("id");
let result = await TradeService.GetTradeInfo(tradeId);
if (result.code == 0) {
equData.value = result.data.equData;
equInfo.value = result.data.equ;
suitInfo.value = result.data.suit;
owUser.value = result.data.user;
equAwaken.value = result.data.equData.equAwaken;
equMent.value = result.data.equData.equMent;
gemMent.value = result.data.equData.gemMent;
}
else if (result.code == 100) {
PageExtend.RedirectTo("/prop/goods?id=" + result.msg);
}
else {
MessageExtend.ShowDialog("提示", result.msg);
}
};
</script>

View File

@@ -1 +1,79 @@
<template></template>
<template>
<div class="module-title">
我的交易
</div>
<div class="module-content">
<div class="item border-btm" v-for="(item, index) in data" :key="index">
{{ index + 1 }}.[{{ GetRankName(item.code) }}]
<span v-if="item.code == 'Equ'">
<Abar :href='"/trade/info?id=" + item.tradeId'>{{ item.name }}({{ item.price }}铜贝)</Abar>
</span>
<span v-else>
<Abar :href='"/prop/goods?id=" + item.propId'>{{ item.name }}({{ item.price }}铜贝)</Abar>
</span>
(<Abutton @click="Down(item.tradeId)">下架</Abutton>)<br>
<span v-if="item.code != 'Equ'">
数量:{{ item.count }}
</span>
</div>
<span v-if="data.length == 0">
暂无交易.
</span>
</div>
</template>
<script setup lang="ts">
definePageMeta({
layout: layout.default,
middleware: 'page-loading'
})
const data = ref<Array<any>>([]);
onMounted(async () => {
try {
await BindData();
}
finally {
PageLoading.Close();
}
})
const BindData = async (): Promise<void> => {
let result = await TradeService.GetMyTrade();
if (result.code == 0) {
data.value = result.data;
}
else {
MessageExtend.ShowDialog("提示", result.msg);
}
};
const GetRankName = (type: string) => {
let result = '其他';
switch (type) {
case "Equ":
result = "装备"; break;
case "Goods":
result = "物品"; break;
}
return result;
}
const Down = async (tradeId: string) => {
MessageExtend.ShowConfirmDialogAsyc("下架操作", `您确定要下架吗?`, async () => {
let result = await TradeService.DownTrade(tradeId);
if (result.code == 0) {
await BindData();
MessageExtend.Notify("下架成功!", "success");
}
else {
MessageExtend.Notify(result.msg, "danger");
}
return true;
});
}
</script>

View File

@@ -1 +1,117 @@
<template></template>
<template>
<div class="module-title">
交易信息
</div>
<div class="module-content">
<div class="item border-btm" v-for="(item, index) in data" :key="index">
{{ PageExtend.GetPageIndex(currentPage, 10, index + 1) }}.[{{ GetRankName(item.code) }}]
<span v-if="item.code == 'Equ'">
<Abar :href='"/trade/info?id=" + item.tradeId'>{{ item.name }}({{ item.price }}铜贝)</Abar>
</span>
<span v-else>
<Abar :href='"/prop/goods?id=" + item.propId'>{{ item.name }}({{ item.price }}铜贝)</Abar>
</span>
[<Abutton @click="Buy(item)">购买</Abutton>]
</div>
<span v-if="data.length == 0">
暂无交易.
</span>
</div>
<div class="content">
<Pagination :currentPage="currentPage" :limit="10" :total="total" @pageChange="handlePageChange" />
</div>
<GamePopup v-model:show="showBuy" title="【购买】">
<!-- 自定义内容 -->
<div class="common">
物品名称{{ showGoods.name }}<br>
购买单价{{ showGoods.price }} 铜贝<br>
<span v-if="showGoods.code != 'Equ'">
剩余数量{{ showGoods.count }}
</span>
</div>
<div class="common" style="text-align: center;">
<span v-if="showGoods.code != 'Equ'">
购买数量<input type="number" class="search-ipt" v-model="count"><br>
</span>
<button class="ipt-btn" name="serch" @click="ShopOk" style="margin-top: 15px;">购买</button>
</div>
</GamePopup>
</template>
<script setup lang="ts">
definePageMeta({
layout: layout.default,
middleware: 'page-loading'
})
const currentPage = ref<number>(1);
const total = ref<number>(0);
const data = ref<Array<any>>([]);
const showBuy = ref(false);
const count = ref(1);
const showGoods = ref<any>({});
let no = PageExtend.QueryString("no");
onMounted(async () => {
try {
await BindData();
}
finally {
PageLoading.Close();
}
})
const BindData = async (): Promise<void> => {
let result = await TradeService.GetTradeData(no, 0, "", currentPage.value);
if (result.code == 0) {
data.value = result.data.data;
total.value = result.data.total;
}
else {
MessageExtend.ShowDialog("提示", result.msg);
}
};
/**翻页 */
const handlePageChange = async (page: number): Promise<void> => {
currentPage.value = page;
await BindData();
};
const GetRankName = (type: string) => {
let result = '其他';
switch (type) {
case "Equ":
result = "装备"; break;
case "Goods":
result = "物品"; break;
}
return result;
}
const Buy = (info: any) => {
showGoods.value = info;
count.value = 1;
showBuy.value = true;
}
const ShopOk = async () => {
if (count.value < 1 || count.value > 99) {
MessageExtend.ShowToast("每次购买数量在1~99哦.");
return;
}
MessageExtend.LoadingToast("购买中...");
let result = await TradeService.Buy(showGoods.value.tradeId, count.value);
MessageExtend.LoadingClose();
if (result.code == 0) {
showBuy.value = false;
await BindData();
MessageExtend.Notify(`成功购买${showGoods.value.name}×${count.value}`, "success");
}
else {
MessageExtend.ShowDialog("提示", result.msg);
}
}
</script>

View File

@@ -1,11 +1,14 @@
<template>
<div class="module-title">
更改徽章
我的徽章
</div>
<div class="content" v-for="item in maxList" :key="item.umnId">
<Aimage :url="item.img"></Aimage>
<span style="margin: 0 4px;">{{ item.name }} </span>
<Abutton @click="updown(item.ubId)"> {{ item.show == 0 ? '佩戴' : '卸下' }} </Abutton>
<div class="content">
<div class="item" v-for="item in maxList" :key="item.umnId">
<Aimage :url="item.img"></Aimage>
<span style="margin: 0 4px;">{{ item.name }} </span>
<Abutton @click="updown(item.ubId)"> {{ item.show == 0 ? '佩戴' : '卸下' }} </Abutton>
</div>
<span v-if="maxList.length == 0">暂无徽章.</span>
</div>
<div class="content">
<Pagination :currentPage="currentPage" :limit="10" :total="total" @pageChange="handlePageChange" />

View File

@@ -1,11 +1,16 @@
<template>
<div class="module-title">
更改称号
我的称号
</div>
<div class="content" v-for="item in maxList" :key="item.umnId">
<Aimage :url="item.img"></Aimage>
<span @click="getDetail(item.umnId)" style="margin: 0 4px;">{{ item.name }} ×{{ item.count }}</span>
<Abutton @click="updown(item.umnId)"> {{ item.show == 0 ? '佩戴' : '卸下' }} </Abutton>
<div class="content">
<div class="item" v-for="item in maxList" :key="item.umnId">
<Aimage :url="item.img"></Aimage>
<span @click="getDetail(item.umnId)" style="margin: 0 4px;">{{ item.name }} ×{{ item.count }}</span>
<Abutton @click="updown(item.umnId)"> {{ item.show == 0 ? '佩戴' : '卸下' }} </Abutton>
</div>
<span v-if="maxList.length==0">
暂无称号.
</span>
</div>
<div class="content">
<Pagination :currentPage="currentPage" :limit="10" :total="total" @pageChange="handlePageChange" />

View File

@@ -6,4 +6,44 @@ export class TradeService {
static async Trade(type: number, prop: string, price: number, count: number) {
return await ApiService.Request("get", "/Trade/Trade", { type, prop, price, count });
}
/**
* 购买
* GET /Trade/Buy
*/
static async Buy(tradeId: string, count: number) {
return await ApiService.Request("get", "/Trade/Buy", { tradeId, count });
}
/**
* 获取交易列表
* GET /Trade/GetTradeData
*/
static async GetTradeData(no: string, type: number, query: string, page: number) {
return await ApiService.Request("get", "/Trade/GetTradeData", { no, type, query, page });
}
/**
* 获取个人交易列表
* GET /Trade/GetMyTrade
*/
static async GetMyTrade() {
return await ApiService.Request("get", "/Trade/GetMyTrade");
}
/**
* 下架交易
* GET /Trade/DownTrade
*/
static async DownTrade(tradeId: string) {
return await ApiService.Request("get", "/Trade/DownTrade", { tradeId });
}
/**
* 获取交易详情
* GET /Trade/GetTradeInfo
*/
static async GetTradeInfo(tradeId: string) {
return await ApiService.Request("get", "/Trade/GetTradeInfo", { tradeId });
}
}

View File

@@ -22,6 +22,14 @@
地图名称:地图点的名称。
城市名称:地图点所在城市的名称。
-npc.xls : 这是NPC文件表示当前已存在的可用的NPC
npcID :NPC的主键ID
npc名称 NPC的名字
地图ID NPC所在的地图ID
地图名称: 所在的地图点名称
所在城市: NPC所在的城市
功能: NPC的功能任务NPC进行任务对话和完成商店NPC可以购买物品
### create 文件夹数据结构说明
@@ -31,15 +39,15 @@
NPCID根据NPC规则对应任务绑定的NPCID。
任务提示指NPC说出的内容即任务串联起来的故事。
我的回答:指玩家应该回答的内容。
下一环任务摘要:指玩家完成该任务后,下一环任务的摘要,摘要需要包含城市和地图名称,例如"去威尼斯广场和某某NPC兑换"如果下一环任务要求中是击杀怪物获得的道具作为任务要求的要在任务中说明去哪里击杀怪物收集哪些物品交给哪个NPC同时要内容丰富的介绍下一环完成条件如果有条件
下一环任务摘要:指玩家完成该任务后,下一环任务的摘要,摘要需要包含城市和地图名称,例如"去威尼斯广场和某某NPC兑换";如果下一环任务要求中是击杀怪物获得的道具作为任务要求的,要在任务中说明去哪个城市的哪里击杀怪物收集哪些物品交给哪个NPC(包含采集类任务要求),同时要内容丰富的介绍下一环完成条件(如果有条件)*特别注意生成的说明地点要和地图ID的名称匹配不要有错误地点
任务要求:任务可以需要任务物品/或者击杀怪物,当本环任务没有任务要求,仅对话任务时,该字段内容为:“[]”,如果有要求时该字段为数组json结构结构模型如下
[
{
"code":"Monster",//要求类型Monster:怪物Goods:物品copper铜贝
"name":"病鸡",//相关名称:为怪物名称或者物品名称,如果是铜贝名称为“铜贝”
"parameter":"0AA26D21-B220-A830-A355-63C344C54079",//物品参数怪物的怪物ID或者物品ID
"count":3,//要求达到的数量
"mapId":"10_19",//怪物所在的地图ID如果是怪物掉落物品的话为怪物所在的地图ID如果需要购买的物品为NPC所在的地图ID;非怪物或物品,该参数值为空
"count":3,//要求达到的数量,如果是怪物/采集等保持数量在10以内。
"mapId":"10_19",//怪物所在的地图ID如果是怪物掉落物品的话为怪物所在的地图ID如果需要购买的物品为NPC所在的地图ID如果是采集时该值为采集配置中所在的地图ID其他时该参数值为空
"areaCode":"Own", //如果是怪物类型的话仅个人击杀怪物参数为“Own”,如果是队伍都可以击杀为“Team”,非怪物类型该参数为空。
"isOp":0//如果是物品或者铜贝需要扣除的该参数值为1否则为0如果时任务物品且后续任务环不再需要该物品要进行扣除处理如果后续还需要且后续不再奖励该任务道具则不要进行扣除要保证任务连贯性。
}
@@ -81,7 +89,7 @@ NPCID根据NPC规则对应任务绑定的NPCID。
]
- npc.xls 生成任务的NPC数据结构进行任务生成时同时任务对应的NPC数据结构结构参数说明如下:
- npc.xls 生成任务的NPC数据结构当任务生成时使用资源文件夹中已存在的npc时则不需要再次生成直接使用对应的NPC信息即可如果任务类型为购买物品可以直接使用在资源文件夹NPC文件中的商店NPC非必要无需重新生成同时要注意商店NPC仅做购买使用不要参与任务对话与完成如果需要新的NPC时进行生成生成结构参数说明如下:
NPCID生成的NPCID为数字类型参考提示要求的数字起始值进行叠加1生成。
npc名称生成任务时对话的NPC名称。
地图IDNPC所在地图点ID参考任务生成npc所在地图。
@@ -90,11 +98,11 @@ npc类型类型值为“Task”。
npc介绍 对生成的该npc有一个性格或者人物的背景介绍要求不超过50字。
- goods.xls : 任务需要的物品,为串联任务或怪物掉落或任务剧情道具物品生成在该表格,参数说明:
- goods.xls : 任务需要的物品,为串联任务或怪物掉落或任务剧情道具(含采集)物品生成在该表格,参数说明:
物品ID物品的主键ID为数组类型生成按照提示进行+1生成设计。
物品名称: 物品或道具名称
物品介绍该物品的简单说明不超过30字。
获取途径:说明该物品如何获取。
物品介绍该物品的简单说明不超过30字,不要写获取的方式相关内容
获取途径:说明该物品如何获取如果你生成的说明带地点时要写明具体地点不要写地图ID
- monster.xls : 怪物表格,任务进行中如果有击杀怪物要求,对应的怪物表格
@@ -137,6 +145,18 @@ NPCID对应的NPCID
物品ID对应生成的物品ID
物品价格:按照提示中要求的物品价格区间进行随机生成。
- collect.xls :这是地图绑定的采集配置表,如果生成任务中包含采集类任务,需要先在物品表中生成对应的采集物品,再设计采集信息配置在采集配置表中,具体参数如下:
采集ID 按照给定的提示要求进行ID+1生成即可数字类型。
地图ID: 该采集所绑定的地图ID。
物品名称: 采集成功后获得的物品的名称。
物品ID 采集成功后获得的物品的ID。
采集数量: 采集成功给与的数量,格式为【最小数量-最大数量】例如采集成功后随机给1-2个该值为“1-2”如果固定给1个该值为“1-1”。
采集需要活力采集时消耗的活力数值类型在1-3点之间生成具体的所需数值。
采集成功率: 采集的成功率最大值为100例如采集成功率50%该值为50。
冷却时间: 采集完成后的冷却时间生成该属性时不超过10秒数值类型为秒数。
### resutlt 文件夹数据结构说明
@@ -151,9 +171,9 @@ NPCID对应的NPCID
5. 如果该任务完成后发放奖励则任务奖励中的每一项奖励的count不能小于0。
6. 如果怪物掉落任务物品那么掉落的数量大于任务要求数量例如如果任务要求3个物品怪物设置了1个那么这个怪物击杀后奖励必须为最少3个可以设置击多个怪物数量。
7. 如果是怪物掉落的物品作为任务道具,则怪物也要同时作为任务完成条件。
8. 一定要检查下一环任务摘要中的描述和下一环实际场景是否对战,如果下一环有击杀任务要求,要验证是否和描述中的地图点是否一致。
8. 一定要检查下一环任务摘要中的描述和下一环实际场景是否一致同时如果包含物品要确定物品后续是否再次使用来根据情况确定物品扣除参数是0或者是1如果下一环有击杀任务要求,要验证是否和描述中的地图点是否一致。
9. 生成NPC名称物品名称怪物名称不能出线不同的主键ID相同的名称保证NPC唯一性NPC和怪物的名称直接起名不要带身份文字。例如【商人马尔科】直接名字为【马尔科】。
10. 如果有新生成的NPC需要放置在建筑类地图点不要放置在野外地图点同样怪物的放置点应该放置在野外地图点。
## 验证

Binary file not shown.