feat: redesign crypto market with synced favorites
This commit is contained in:
@@ -2,12 +2,59 @@
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\api\logic\CryptoLogic;
|
||||
use app\api\validate\CryptoValidate;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Log;
|
||||
|
||||
class CryptoController extends BaseApiController
|
||||
{
|
||||
public array $notNeedLogin = ['proxy'];
|
||||
public array $notNeedLogin = ['proxy', 'market'];
|
||||
|
||||
/**
|
||||
* 人民币加密行情与市场概览
|
||||
*/
|
||||
public function market()
|
||||
{
|
||||
try {
|
||||
return $this->data(CryptoLogic::market());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('[CryptoMarket] controller failed: ' . $e->getMessage());
|
||||
return $this->fail('行情加载失败,请稍后重试');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号的加密自选列表
|
||||
*/
|
||||
public function favorites()
|
||||
{
|
||||
return $this->data(['symbols' => CryptoLogic::favorites($this->userId)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加入加密自选
|
||||
*/
|
||||
public function addFavorite()
|
||||
{
|
||||
$params = (new CryptoValidate())->post()->goCheck('favorite');
|
||||
if (!CryptoLogic::addFavorite($this->userId, (string) $params['symbol'])) {
|
||||
return $this->fail(CryptoLogic::getError());
|
||||
}
|
||||
return $this->success('已加入自选');
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消加密自选
|
||||
*/
|
||||
public function cancelFavorite()
|
||||
{
|
||||
$params = (new CryptoValidate())->post()->goCheck('favorite');
|
||||
if (!CryptoLogic::cancelFavorite($this->userId, (string) $params['symbol'])) {
|
||||
return $this->fail(CryptoLogic::getError());
|
||||
}
|
||||
return $this->success('已取消自选');
|
||||
}
|
||||
|
||||
/**
|
||||
* Binance API 代理(解决客户端直连被墙问题)
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\logic;
|
||||
|
||||
use app\common\enum\YesNoEnum;
|
||||
use app\common\logic\BaseLogic;
|
||||
use app\common\model\crypto\CryptoFavorite;
|
||||
use app\common\service\crypto\CryptoMarketService;
|
||||
|
||||
class CryptoLogic extends BaseLogic
|
||||
{
|
||||
public static function market(): array
|
||||
{
|
||||
return CryptoMarketService::snapshot();
|
||||
}
|
||||
|
||||
public static function favorites(int $userId): array
|
||||
{
|
||||
$symbols = CryptoFavorite::where([
|
||||
'user_id' => $userId,
|
||||
'status' => YesNoEnum::YES,
|
||||
])->order('create_time asc')->column('symbol');
|
||||
|
||||
return array_values(array_unique(array_map('strtoupper', $symbols)));
|
||||
}
|
||||
|
||||
public static function addFavorite(int $userId, string $symbol): bool
|
||||
{
|
||||
$symbol = strtoupper(trim($symbol));
|
||||
if (!CryptoMarketService::isSupportedSymbol($symbol)) {
|
||||
self::setError('暂不支持该币种');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$where = ['user_id' => $userId, 'symbol' => $symbol];
|
||||
$favorite = CryptoFavorite::where($where)->findOrEmpty();
|
||||
if ($favorite->isEmpty()) {
|
||||
try {
|
||||
CryptoFavorite::create($where + ['status' => YesNoEnum::YES]);
|
||||
} catch (\Throwable $e) {
|
||||
CryptoFavorite::update(['status' => YesNoEnum::YES], $where);
|
||||
}
|
||||
} else {
|
||||
$favorite->status = YesNoEnum::YES;
|
||||
$favorite->save();
|
||||
}
|
||||
return true;
|
||||
} catch (\Throwable $e) {
|
||||
self::setError('收藏失败,请稍后重试');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function cancelFavorite(int $userId, string $symbol): bool
|
||||
{
|
||||
try {
|
||||
CryptoFavorite::update(
|
||||
['status' => YesNoEnum::NO],
|
||||
['user_id' => $userId, 'symbol' => strtoupper(trim($symbol))]
|
||||
);
|
||||
return true;
|
||||
} catch (\Throwable $e) {
|
||||
self::setError('取消收藏失败,请稍后重试');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\validate;
|
||||
|
||||
use app\common\validate\BaseValidate;
|
||||
|
||||
class CryptoValidate extends BaseValidate
|
||||
{
|
||||
protected $rule = [
|
||||
'symbol' => 'require|alphaNum|max:20',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'symbol.require' => '币种不能为空',
|
||||
'symbol.alphaNum' => '币种格式错误',
|
||||
'symbol.max' => '币种格式错误',
|
||||
];
|
||||
|
||||
public function sceneFavorite()
|
||||
{
|
||||
return $this->only(['symbol']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user