feat: 完善对接接口
This commit is contained in:
@@ -56,6 +56,7 @@ namespace Yi.Framework.Stock.Application.Services
|
|||||||
StockId = h.StockId,
|
StockId = h.StockId,
|
||||||
StockCode = h.StockCode,
|
StockCode = h.StockCode,
|
||||||
StockName = h.StockName,
|
StockName = h.StockName,
|
||||||
|
Quantity = h.Quantity,
|
||||||
CreationTime = h.CreationTime
|
CreationTime = h.CreationTime
|
||||||
})
|
})
|
||||||
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
|
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ namespace Yi.Framework.Stock.Application.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 卖出股票
|
/// 卖出股票
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpPost("stock/sell")]
|
[HttpDelete("stock/sell")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public async Task SellStockAsync(SellStockInputDto input)
|
public async Task SellStockAsync(SellStockInputDto input)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Volo.Abp.DependencyInjection;
|
||||||
|
using Volo.Abp.EventBus;
|
||||||
|
using Yi.Framework.Stock.Domain.Entities;
|
||||||
|
using Yi.Framework.Stock.Domain.Shared.Etos;
|
||||||
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Stock.Domain.EventHandlers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 股票交易事件处理器
|
||||||
|
/// </summary>
|
||||||
|
public class StockTransactionEventHandler : ILocalEventHandler<StockTransactionEto>, ITransientDependency
|
||||||
|
{
|
||||||
|
private readonly ISqlSugarRepository<StockTransactionEntity> _transactionRepository;
|
||||||
|
|
||||||
|
public StockTransactionEventHandler(
|
||||||
|
ISqlSugarRepository<StockTransactionEntity> transactionRepository)
|
||||||
|
{
|
||||||
|
_transactionRepository = transactionRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task HandleEventAsync(StockTransactionEto eventData)
|
||||||
|
{
|
||||||
|
// 创建交易记录实体
|
||||||
|
var transaction = new StockTransactionEntity(
|
||||||
|
eventData.UserId,
|
||||||
|
eventData.StockId,
|
||||||
|
eventData.StockCode,
|
||||||
|
eventData.StockName,
|
||||||
|
eventData.TransactionType,
|
||||||
|
eventData.Price,
|
||||||
|
eventData.Quantity,
|
||||||
|
eventData.Fee
|
||||||
|
);
|
||||||
|
|
||||||
|
// 保存交易记录
|
||||||
|
await _transactionRepository.InsertAsync(transaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ using Yi.Framework.Stock.Domain.Shared.Etos;
|
|||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
using Yi.Framework.Stock.Domain.Managers.SemanticKernel;
|
using Yi.Framework.Stock.Domain.Managers.SemanticKernel;
|
||||||
using Yi.Framework.Stock.Domain.Managers.SemanticKernel.Plugins;
|
using Yi.Framework.Stock.Domain.Managers.SemanticKernel.Plugins;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
namespace Yi.Framework.Stock.Domain.Managers
|
namespace Yi.Framework.Stock.Domain.Managers
|
||||||
{
|
{
|
||||||
@@ -27,12 +28,16 @@ namespace Yi.Framework.Stock.Domain.Managers
|
|||||||
private readonly ISqlSugarRepository<StockMarketAggregateRoot> _stockMarketRepository;
|
private readonly ISqlSugarRepository<StockMarketAggregateRoot> _stockMarketRepository;
|
||||||
private readonly ILocalEventBus _localEventBus;
|
private readonly ILocalEventBus _localEventBus;
|
||||||
private readonly SemanticKernelClient _skClient;
|
private readonly SemanticKernelClient _skClient;
|
||||||
|
private readonly IHostEnvironment _hostEnvironment;
|
||||||
|
|
||||||
public StockMarketManager(
|
public StockMarketManager(
|
||||||
ISqlSugarRepository<StockHoldingAggregateRoot> stockHoldingRepository,
|
ISqlSugarRepository<StockHoldingAggregateRoot> stockHoldingRepository,
|
||||||
ISqlSugarRepository<StockTransactionEntity> stockTransactionRepository,
|
ISqlSugarRepository<StockTransactionEntity> stockTransactionRepository,
|
||||||
ISqlSugarRepository<StockPriceRecordEntity> stockPriceRecordRepository,
|
ISqlSugarRepository<StockPriceRecordEntity> stockPriceRecordRepository,
|
||||||
ISqlSugarRepository<StockMarketAggregateRoot> stockMarketRepository,
|
ISqlSugarRepository<StockMarketAggregateRoot> stockMarketRepository,
|
||||||
ILocalEventBus localEventBus, SemanticKernelClient skClient)
|
ILocalEventBus localEventBus,
|
||||||
|
SemanticKernelClient skClient,
|
||||||
|
IHostEnvironment hostEnvironment)
|
||||||
{
|
{
|
||||||
_stockHoldingRepository = stockHoldingRepository;
|
_stockHoldingRepository = stockHoldingRepository;
|
||||||
_stockTransactionRepository = stockTransactionRepository;
|
_stockTransactionRepository = stockTransactionRepository;
|
||||||
@@ -40,6 +45,7 @@ namespace Yi.Framework.Stock.Domain.Managers
|
|||||||
_stockMarketRepository = stockMarketRepository;
|
_stockMarketRepository = stockMarketRepository;
|
||||||
_localEventBus = localEventBus;
|
_localEventBus = localEventBus;
|
||||||
_skClient = skClient;
|
_skClient = skClient;
|
||||||
|
_hostEnvironment = hostEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -103,20 +109,6 @@ namespace Yi.Framework.Stock.Domain.Managers
|
|||||||
holding.AddQuantity(quantity, currentPrice);
|
holding.AddQuantity(quantity, currentPrice);
|
||||||
await _stockHoldingRepository.UpdateAsync(holding);
|
await _stockHoldingRepository.UpdateAsync(holding);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建交易记录
|
|
||||||
var transaction = new StockTransactionEntity(
|
|
||||||
userId,
|
|
||||||
stockId,
|
|
||||||
stockCode,
|
|
||||||
stockName,
|
|
||||||
TransactionTypeEnum.Buy,
|
|
||||||
currentPrice,
|
|
||||||
quantity,
|
|
||||||
fee);
|
|
||||||
|
|
||||||
await _stockTransactionRepository.InsertAsync(transaction);
|
|
||||||
|
|
||||||
// 发布交易事件
|
// 发布交易事件
|
||||||
await _localEventBus.PublishAsync(new StockTransactionEto
|
await _localEventBus.PublishAsync(new StockTransactionEto
|
||||||
{
|
{
|
||||||
@@ -189,19 +181,6 @@ namespace Yi.Framework.Stock.Domain.Managers
|
|||||||
await _stockHoldingRepository.DeleteAsync(holding);
|
await _stockHoldingRepository.DeleteAsync(holding);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建交易记录
|
|
||||||
var transaction = new StockTransactionEntity(
|
|
||||||
userId,
|
|
||||||
stockId,
|
|
||||||
holding.StockCode,
|
|
||||||
holding.StockName,
|
|
||||||
TransactionTypeEnum.Sell,
|
|
||||||
currentPrice,
|
|
||||||
quantity,
|
|
||||||
fee);
|
|
||||||
|
|
||||||
await _stockTransactionRepository.InsertAsync(transaction);
|
|
||||||
|
|
||||||
// 发布交易事件
|
// 发布交易事件
|
||||||
await _localEventBus.PublishAsync(new StockTransactionEto
|
await _localEventBus.PublishAsync(new StockTransactionEto
|
||||||
{
|
{
|
||||||
@@ -246,8 +225,8 @@ namespace Yi.Framework.Stock.Domain.Managers
|
|||||||
/// <returns>手续费</returns>
|
/// <returns>手续费</returns>
|
||||||
private decimal CalculateTradingFee(decimal amount, TransactionTypeEnum transactionType)
|
private decimal CalculateTradingFee(decimal amount, TransactionTypeEnum transactionType)
|
||||||
{
|
{
|
||||||
// 示例费率:买入0.1%,卖出0.2%
|
// 买入不收手续费,卖出收2%
|
||||||
decimal feeRate = transactionType == TransactionTypeEnum.Buy ? 0.001m : 0.002m;
|
decimal feeRate = transactionType == TransactionTypeEnum.Buy ? 0m : 0.02m;
|
||||||
return amount * feeRate;
|
return amount * feeRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,6 +236,12 @@ namespace Yi.Framework.Stock.Domain.Managers
|
|||||||
/// <exception cref="UserFriendlyException">如果不在允许卖出的时间范围内</exception>
|
/// <exception cref="UserFriendlyException">如果不在允许卖出的时间范围内</exception>
|
||||||
private void VerifySellTime()
|
private void VerifySellTime()
|
||||||
{
|
{
|
||||||
|
// 如果是开发环境,跳过验证
|
||||||
|
if (_hostEnvironment.IsDevelopment())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DateTime now = DateTime.Now;
|
DateTime now = DateTime.Now;
|
||||||
|
|
||||||
// 检查是否为工作日(周一到周五)
|
// 检查是否为工作日(周一到周五)
|
||||||
|
|||||||
@@ -47,3 +47,21 @@ export function getStockMarkets() {
|
|||||||
method: "get"
|
method: "get"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 买入股票
|
||||||
|
export function buyStock(data) {
|
||||||
|
return request({
|
||||||
|
url: "/stock/buy",
|
||||||
|
method: "post",
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 卖出股票
|
||||||
|
export function sellStock(params) {
|
||||||
|
return request({
|
||||||
|
url: "/stock/sell",
|
||||||
|
method: "delete",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -75,9 +75,9 @@ export function getUserProfile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询bbs个人信息
|
// 查询bbs个人信息
|
||||||
export function getBbsUserProfile(userName) {
|
export function getBbsUserProfile(userNameOrId) {
|
||||||
return request({
|
return request({
|
||||||
url: `/bbs-user/${userName}`,
|
url: `/bbs-user/${userNameOrId}`,
|
||||||
method: "get",
|
method: "get",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,14 +144,6 @@ const router = createRouter({
|
|||||||
title: "面试宝典",
|
title: "面试宝典",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "stock",
|
|
||||||
path: "/stock",
|
|
||||||
component: () => import("../views/stock/Index.vue"),
|
|
||||||
meta: {
|
|
||||||
title: "股票",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -203,7 +195,14 @@ const router = createRouter({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "stock",
|
||||||
|
path: "/stock",
|
||||||
|
component: () => import("../views/stock/Index.vue"),
|
||||||
|
meta: {
|
||||||
|
title: "股票",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/hub",
|
path: "/hub",
|
||||||
name: "hub",
|
name: "hub",
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="selector-area">
|
<div class="selector-area">
|
||||||
|
<div class="user-money">当前钱钱: <span class="money-value">{{ userInfo.money || 0 }}</span></div>
|
||||||
|
|
||||||
<el-select
|
<el-select
|
||||||
v-model="currentStock"
|
v-model="currentStock"
|
||||||
placeholder="选择股票"
|
placeholder="选择股票"
|
||||||
@@ -24,6 +26,15 @@
|
|||||||
<span class="stock-code">{{ item.code }}</span>
|
<span class="stock-code">{{ item.code }}</span>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
class="return-button"
|
||||||
|
@click="returnToHome"
|
||||||
|
>
|
||||||
|
<i class="el-icon-back"></i> 返回社区
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -44,6 +55,7 @@
|
|||||||
v-for="news in newsList"
|
v-for="news in newsList"
|
||||||
:key="news.id"
|
:key="news.id"
|
||||||
class="news-item"
|
class="news-item"
|
||||||
|
@click="showNewsDetail(news)"
|
||||||
>
|
>
|
||||||
<div class="news-date">
|
<div class="news-date">
|
||||||
{{ dayjs(news.publishTime).format('YYYY-MM-DD') }}
|
{{ dayjs(news.publishTime).format('YYYY-MM-DD') }}
|
||||||
@@ -144,7 +156,7 @@
|
|||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<span class="icon"><i class="el-icon-wallet"></i></span>
|
<span class="icon"><i class="el-icon-wallet"></i></span>
|
||||||
<h3>我的持仓</h3>
|
<h3>我的持仓</h3>
|
||||||
<span class="total-value">总资产: ¥{{ totalAssets }}</span>
|
<span class="total-value">持有钱钱: ¥{{ totalAssets }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isLoadingPortfolio" class="loading-portfolio">
|
<div v-if="isLoadingPortfolio" class="loading-portfolio">
|
||||||
@@ -170,14 +182,52 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 添加新闻详情弹窗 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="newsDialogVisible"
|
||||||
|
:title="currentNewsDetail.title"
|
||||||
|
width="50%"
|
||||||
|
class="news-detail-dialog"
|
||||||
|
>
|
||||||
|
<div class="news-detail-header">
|
||||||
|
<span class="news-detail-time">{{ dayjs(currentNewsDetail.publishTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||||
|
<span class="news-detail-source" v-if="currentNewsDetail.source">来源: {{ currentNewsDetail.source }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="news-detail-content">{{ currentNewsDetail.content }}</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted, reactive } from 'vue';
|
import { ref, computed, onMounted, reactive } from 'vue';
|
||||||
import StockChart from './components/StockChart.vue';
|
import StockChart from './components/StockChart.vue';
|
||||||
import { getStockNews, getUserHoldings, getUserTransactions, getStockPriceRecords, getStockMarkets } from '@/apis/stockApi.js';
|
import { getStockNews, getUserHoldings, getUserTransactions, getStockPriceRecords, getStockMarkets, buyStock as buyStockApi, sellStock as sellStockApi } from '@/apis/stockApi.js';
|
||||||
|
import { getBbsUserProfile } from '@/apis/userApi.js';
|
||||||
import { dayjs } from 'element-plus';
|
import { dayjs } from 'element-plus';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import useUserStore from "@/stores/user";
|
||||||
|
|
||||||
|
// 获取路由器实例
|
||||||
|
const router = useRouter();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const userInfo = ref({});
|
||||||
|
|
||||||
|
// 返回首页函数
|
||||||
|
const returnToHome = () => {
|
||||||
|
router.push('/index');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取用户信息,包括钱钱
|
||||||
|
const loadUserInfo = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await getBbsUserProfile(userStore.id);
|
||||||
|
userInfo.value = data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取用户信息失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 股票列表数据
|
// 股票列表数据
|
||||||
const stockList = ref([]);
|
const stockList = ref([]);
|
||||||
@@ -221,7 +271,6 @@ const fetchStockMarkets = async () => {
|
|||||||
|
|
||||||
// 加载默认选中股票的数据
|
// 加载默认选中股票的数据
|
||||||
await fetchStockPriceRecords();
|
await fetchStockPriceRecords();
|
||||||
await fetchTradeHistory();
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取股市列表失败:', error);
|
console.error('获取股市列表失败:', error);
|
||||||
@@ -385,7 +434,7 @@ const totalAssets = computed(() => {
|
|||||||
const stockValue = portfolioList.value.reduce((sum, stock) => {
|
const stockValue = portfolioList.value.reduce((sum, stock) => {
|
||||||
return sum + parseFloat(stock.currentPrice) * stock.amount;
|
return sum + parseFloat(stock.currentPrice) * stock.amount;
|
||||||
}, 0);
|
}, 0);
|
||||||
return (stockValue + 50000).toFixed(2); // 假设有50000现金
|
return (stockValue + (userInfo.value.money || 0)).toFixed(2); // 使用API获取的钱钱,而不是固定值
|
||||||
});
|
});
|
||||||
|
|
||||||
// 切换股票
|
// 切换股票
|
||||||
@@ -408,20 +457,98 @@ const changeStock = async (stockId) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 买入股票
|
// 买入股票
|
||||||
const buyStock = () => {
|
const buyStock = async () => {
|
||||||
// 实现买入逻辑
|
if (!currentStock.value) {
|
||||||
alert(`买入${tradeAmount.value}股 ${currentStockInfo.value.name}`);
|
ElMessage.warning('请先选择股票');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(
|
||||||
|
`确定要买入 ${tradeAmount.value}股 ${currentStockInfo.value.name} 吗?`,
|
||||||
|
'买入确认',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await buyStockApi({
|
||||||
|
stockId: currentStock.value,
|
||||||
|
quantity: tradeAmount.value
|
||||||
|
});
|
||||||
|
|
||||||
|
ElMessage.success(`已成功买入 ${tradeAmount.value}股 ${currentStockInfo.value.name}`);
|
||||||
|
|
||||||
|
// 刷新数据
|
||||||
|
await Promise.all([
|
||||||
|
fetchTradeHistory(),
|
||||||
|
fetchPortfolioList(),
|
||||||
|
loadUserInfo() // 买入后更新用户钱钱
|
||||||
|
]);
|
||||||
|
} catch (error) {
|
||||||
|
if (error !== 'cancel') {
|
||||||
|
console.error('买入股票失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 卖出股票
|
// 卖出股票
|
||||||
const sellStock = () => {
|
const sellStock = async () => {
|
||||||
// 实现卖出逻辑
|
if (!currentStock.value) {
|
||||||
alert(`卖出${tradeAmount.value}股 ${currentStockInfo.value.name}`);
|
ElMessage.warning('请先选择股票');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(
|
||||||
|
`确定要卖出 ${tradeAmount.value}股 ${currentStockInfo.value.name} 吗?`,
|
||||||
|
'卖出确认',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await sellStockApi({
|
||||||
|
StockId: currentStock.value,
|
||||||
|
Quantity: tradeAmount.value
|
||||||
|
});
|
||||||
|
|
||||||
|
ElMessage.success(`已成功卖出 ${tradeAmount.value}股 ${currentStockInfo.value.name}`);
|
||||||
|
|
||||||
|
// 刷新数据
|
||||||
|
await Promise.all([
|
||||||
|
fetchTradeHistory(),
|
||||||
|
fetchPortfolioList(),
|
||||||
|
loadUserInfo() // 卖出后更新用户钱钱
|
||||||
|
]);
|
||||||
|
} catch (error) {
|
||||||
|
if (error !== 'cancel') {
|
||||||
|
console.error('卖出股票失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 新闻详情弹窗
|
||||||
|
const newsDialogVisible = ref(false);
|
||||||
|
const currentNewsDetail = ref({
|
||||||
|
title: '',
|
||||||
|
content: '',
|
||||||
|
publishTime: '',
|
||||||
|
source: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
// 显示新闻详情
|
||||||
|
const showNewsDetail = (news) => {
|
||||||
|
currentNewsDetail.value = news;
|
||||||
|
newsDialogVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 生命周期钩子
|
// 生命周期钩子
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
|
||||||
// 先获取股市列表
|
// 先获取股市列表
|
||||||
await fetchStockMarkets();
|
await fetchStockMarkets();
|
||||||
|
|
||||||
@@ -431,6 +558,9 @@ onMounted(async () => {
|
|||||||
fetchPortfolioList(),
|
fetchPortfolioList(),
|
||||||
fetchTradeHistory()
|
fetchTradeHistory()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// 加载用户信息
|
||||||
|
await loadUserInfo();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -469,8 +599,9 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.selector-area {
|
.selector-area {
|
||||||
flex: 0 0 150px;
|
display: flex;
|
||||||
text-align: right;
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@@ -803,4 +934,84 @@ onMounted(async () => {
|
|||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 新闻详情弹窗样式 */
|
||||||
|
.news-detail-dialog :deep(.el-dialog__header) {
|
||||||
|
padding: 15px 20px;
|
||||||
|
border-bottom: 1px solid #30363d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-detail-dialog :deep(.el-dialog__title) {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ffffff !important;
|
||||||
|
text-shadow: 0 0 3px rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-detail-dialog :deep(.el-dialog__body) {
|
||||||
|
padding: 20px;
|
||||||
|
color: #e6edf3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.news-detail-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-bottom: 1px solid #30363d;
|
||||||
|
color: #8b949e;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-detail-content {
|
||||||
|
line-height: 1.6;
|
||||||
|
white-space: pre-line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 修改Element弹窗适应深色主题 */
|
||||||
|
.stock-dashboard :deep(.el-dialog) {
|
||||||
|
background-color: #161b22;
|
||||||
|
border: 1px solid #30363d;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stock-dashboard :deep(.el-dialog__headerbtn .el-dialog__close) {
|
||||||
|
color: #8b949e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stock-dashboard :deep(.el-dialog__headerbtn:hover .el-dialog__close) {
|
||||||
|
color: #58a6ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.return-button {
|
||||||
|
margin-left: 10px;
|
||||||
|
background-color: #58a6ff;
|
||||||
|
border-color: #58a6ff;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.return-button:hover {
|
||||||
|
background-color: #388bfd;
|
||||||
|
border-color: #388bfd;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 2px 5px rgba(88, 166, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-money {
|
||||||
|
color: #e6edf3;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-right: 15px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
background-color: #21262d;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #30363d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.money-value {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #7ee787;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user