refactor(api):重构API服务接口与实现
- 移除多余的接口定义文件,简化依赖关系- 更新控制器和服务实现类的注入方式-优化请求参数处理逻辑 - 统一响应数据结构格式- 调整方法签名以提高一致性 - 删除冗余注释和无用代码- 修改系统API调用路径引用位置 - 简化认证服务实现并移除不必要的抽象层 - 优化Excel文件解析相关功能 - 清理无用的工具类和配置项 - 调整错误上报机制的依赖注入方式 - 更新跟卖精灵服务的实现细节- 优化HTTP请求工具函数结构 - 移除废弃的缓存管理服务接口定义 - 调整设备配额检查逻辑复用性 - 优化订单服务的数据返回格式 - 更新产品服务中的数据处理方式 - 重构客户端账户控制器中的设备限制检查逻辑
This commit is contained in:
@@ -1,35 +1,17 @@
|
||||
import { http } from './http';
|
||||
|
||||
export const amazonApi = {
|
||||
// 上传Excel文件解析ASIN列表
|
||||
importAsinFromExcel(file: File) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return http.upload<{ code: number, data: { asinList: string[], total: number }, msg: string | null }>('/api/amazon/import/asin', formData);
|
||||
},
|
||||
|
||||
getProductsBatch(asinList: string[], batchId: string, region: string) {
|
||||
return http.post<{ code: number, data: { products: any[] }, msg: string | null }>('/api/amazon/products/batch', { asinList, batchId, region });
|
||||
getProductsBatch(asinList: string[], batchId: string, region: string, signal?: AbortSignal) {
|
||||
return http.post<{ code: number, data: { products: any[] }, msg: string | null }>('/api/amazon/products/batch', { asinList, batchId, region }, signal);
|
||||
},
|
||||
|
||||
getLatestProducts() {
|
||||
return http.get<{ code: number, data: { products: any[] }, msg: string | null }>('/api/amazon/products/latest');
|
||||
},
|
||||
getProductsByBatch(batchId: string) {
|
||||
return http.get<{ products: any[] }>(`/api/amazon/products/batch/${batchId}`);
|
||||
},
|
||||
updateProduct(productData: unknown) {
|
||||
return http.post('/api/amazon/products/update', productData);
|
||||
},
|
||||
deleteProduct(productId: string) {
|
||||
return http.post('/api/amazon/products/delete', { id: productId });
|
||||
},
|
||||
getProductStats() {
|
||||
return http.get('/api/amazon/stats');
|
||||
},
|
||||
searchProducts(searchParams: Record<string, unknown>) {
|
||||
return http.get('/api/amazon/products/search', searchParams);
|
||||
},
|
||||
openGenmaiSpirit() {
|
||||
return http.post('/api/system/genmai/open');
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
// HTTP 工具:统一管理后端服务配置和请求
|
||||
export type HttpMethod = 'GET' | 'POST' | 'DELETE';
|
||||
|
||||
// 集中管理所有后端服务配置
|
||||
export const CONFIG = {
|
||||
CLIENT_BASE: 'http://localhost:8081',
|
||||
// RUOYI_BASE: 'http://192.168.1.89:8085',
|
||||
RUOYI_BASE: 'http://8.138.23.49:8085',
|
||||
SSE_URL: 'http://8.138.23.49:8085/monitor/account/events'
|
||||
//RUOYI_BASE: 'http://8.138.23.49:8085',
|
||||
RUOYI_BASE: 'http://192.168.1.89:8085',
|
||||
SSE_URL: 'http://192.168.1.89:8085/monitor/account/events'
|
||||
} as const;
|
||||
|
||||
function resolveBase(path: string): string {
|
||||
// RuoYi 后端路径:鉴权、设备、反馈、版本、工具
|
||||
if (path.startsWith('/monitor/') || path.startsWith('/system/') || path.startsWith('/tool/banma')) {
|
||||
return CONFIG.RUOYI_BASE;
|
||||
}
|
||||
@@ -26,16 +23,17 @@ function buildQuery(params?: Record<string, unknown>): string {
|
||||
return query.toString() ? `?${query}` : '';
|
||||
}
|
||||
|
||||
async function request<T>(path: string, options: RequestInit): Promise<T> {
|
||||
// 获取token
|
||||
let token = '';
|
||||
async function getToken(): Promise<string> {
|
||||
try {
|
||||
const tokenModule = await import('../utils/token');
|
||||
token = tokenModule.getToken() || '';
|
||||
} catch (e) {
|
||||
console.warn('获取token失败:', e);
|
||||
return tokenModule.getToken() || '';
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async function request<T>(path: string, options: RequestInit & { signal?: AbortSignal }): Promise<T> {
|
||||
const token = await getToken();
|
||||
const res = await fetch(`${resolveBase(path)}${path}`, {
|
||||
credentials: 'omit',
|
||||
cache: 'no-store',
|
||||
@@ -55,9 +53,6 @@ async function request<T>(path: string, options: RequestInit): Promise<T> {
|
||||
const contentType = res.headers.get('content-type') || '';
|
||||
if (contentType.includes('application/json')) {
|
||||
const json: any = await res.json();
|
||||
// 业务状态码判断:支持两种格式
|
||||
// - erp_client_sb (本地服务): code=0 表示成功
|
||||
// - RuoYi 后端: code=200 表示成功
|
||||
if (json.code !== undefined && json.code !== 0 && json.code !== 200) {
|
||||
throw new Error(json.msg || '请求失败');
|
||||
}
|
||||
@@ -68,13 +63,14 @@ async function request<T>(path: string, options: RequestInit): Promise<T> {
|
||||
}
|
||||
|
||||
export const http = {
|
||||
get<T>(path: string, params?: Record<string, unknown>) {
|
||||
return request<T>(`${path}${buildQuery(params)}`, { method: 'GET' });
|
||||
get<T>(path: string, params?: Record<string, unknown>, signal?: AbortSignal) {
|
||||
return request<T>(`${path}${buildQuery(params)}`, { method: 'GET', signal });
|
||||
},
|
||||
post<T>(path: string, body?: unknown) {
|
||||
post<T>(path: string, body?: unknown, signal?: AbortSignal) {
|
||||
return request<T>(path, {
|
||||
method: 'POST',
|
||||
body: body ? JSON.stringify(body) : undefined
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
signal
|
||||
});
|
||||
},
|
||||
|
||||
@@ -82,32 +78,22 @@ export const http = {
|
||||
return request<T>(path, { method: 'DELETE' });
|
||||
},
|
||||
|
||||
async upload<T>(path: string, form: FormData) {
|
||||
// 获取token
|
||||
let token = '';
|
||||
try {
|
||||
const tokenModule = await import('../utils/token');
|
||||
token = tokenModule.getToken() || '';
|
||||
} catch (e) {
|
||||
console.warn('获取token失败:', e);
|
||||
}
|
||||
|
||||
const headers: Record<string, string> = {};
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
return fetch(`${resolveBase(path)}${path}`, {
|
||||
async upload<T>(path: string, form: FormData, signal?: AbortSignal) {
|
||||
const token = await getToken();
|
||||
const res = await fetch(`${resolveBase(path)}${path}`, {
|
||||
method: 'POST',
|
||||
body: form,
|
||||
credentials: 'omit',
|
||||
cache: 'no-store',
|
||||
headers
|
||||
}).then(async res => {
|
||||
headers: token ? { 'Authorization': `Bearer ${token}` } : {},
|
||||
signal
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => '');
|
||||
throw new Error(text || `HTTP ${res.status}`);
|
||||
}
|
||||
|
||||
const contentType = res.headers.get('content-type') || '';
|
||||
if (contentType.includes('application/json')) {
|
||||
const json: any = await res.json();
|
||||
@@ -117,7 +103,6 @@ export const http = {
|
||||
return json as T;
|
||||
}
|
||||
return (await res.text()) as unknown as T;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
12
electron-vue-template/src/renderer/api/system.ts
Normal file
12
electron-vue-template/src/renderer/api/system.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { http } from './http';
|
||||
|
||||
export const systemApi = {
|
||||
openGenmaiSpirit() {
|
||||
return http.post('/api/system/genmai/open');
|
||||
},
|
||||
|
||||
clearCache() {
|
||||
return http.post('/api/system/cache/clear');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,23 +18,11 @@ export const zebraApi = {
|
||||
return http.get('/api/banma/shops', params as Record<string, unknown>)
|
||||
},
|
||||
|
||||
getOrders(params: any) {
|
||||
return http.get('/api/banma/orders', params as Record<string, unknown>)
|
||||
},
|
||||
|
||||
getOrdersByBatch(batchId: string) {
|
||||
return http.get(`/api/banma/orders/batch/${batchId}`)
|
||||
getOrders(params: any, signal?: AbortSignal) {
|
||||
return http.get('/api/banma/orders', params as Record<string, unknown>, signal)
|
||||
},
|
||||
|
||||
getLatestOrders() {
|
||||
return http.get('/api/banma/orders/latest')
|
||||
},
|
||||
|
||||
getOrderStats() {
|
||||
return http.get('/api/banma/orders/stats')
|
||||
},
|
||||
|
||||
searchOrders(searchParams: Record<string, unknown>) {
|
||||
return http.get('/api/banma/orders/search', searchParams)
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
import { ref, computed, onMounted, defineAsyncComponent, inject } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { amazonApi } from '../../api/amazon'
|
||||
import { systemApi } from '../../api/system'
|
||||
import { handlePlatformFileExport } from '../../utils/settings'
|
||||
|
||||
const TrialExpiredDialog = defineAsyncComponent(() => import('../common/TrialExpiredDialog.vue'))
|
||||
@@ -21,6 +22,7 @@ const progressVisible = ref(false) // 进度条是否显示(完成后仍保留
|
||||
const localProductData = ref<any[]>([]) // 本地产品数据
|
||||
const currentAsin = ref('') // 当前处理的ASIN
|
||||
const genmaiLoading = ref(false) // Genmai Spirit加载状态
|
||||
let abortController: AbortController | null = null // 请求取消控制器
|
||||
|
||||
// 分页配置
|
||||
const currentPage = ref(1)
|
||||
@@ -130,7 +132,7 @@ async function batchGetProductInfo(asinList: string[]) {
|
||||
currentAsin.value = `正在处理第${i + 1}/${totalBatches}批 (${batchAsins.join(', ')})`
|
||||
|
||||
try {
|
||||
const result = await amazonApi.getProductsBatch(batchAsins, batchId, region.value)
|
||||
const result = await amazonApi.getProductsBatch(batchAsins, batchId, region.value, abortController?.signal)
|
||||
|
||||
if (result?.data?.products?.length > 0) {
|
||||
localProductData.value.push(...result.data.products)
|
||||
@@ -142,7 +144,8 @@ async function batchGetProductInfo(asinList: string[]) {
|
||||
const actualCount = result?.data?.products?.length || 0
|
||||
failedCount += Math.max(0, expectedCount - actualCount)
|
||||
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
if (error.name === 'AbortError') break
|
||||
failedCount += batchAsins.length
|
||||
console.error(`批次${i + 1}失败:`, error)
|
||||
}
|
||||
@@ -164,8 +167,10 @@ async function batchGetProductInfo(asinList: string[]) {
|
||||
|
||||
|
||||
} catch (error: any) {
|
||||
if (error.name !== 'AbortError') {
|
||||
showMessage(error.message || '批量获取产品信息失败', 'error')
|
||||
currentAsin.value = '处理失败'
|
||||
}
|
||||
} finally {
|
||||
tableLoading.value = false
|
||||
}
|
||||
@@ -177,6 +182,7 @@ async function startQueuedFetch() {
|
||||
showMessage('请先导入ASIN列表', 'warning')
|
||||
return
|
||||
}
|
||||
abortController = new AbortController()
|
||||
loading.value = true
|
||||
progressVisible.value = true
|
||||
tableLoading.value = true
|
||||
@@ -185,6 +191,7 @@ async function startQueuedFetch() {
|
||||
} finally {
|
||||
tableLoading.value = false
|
||||
loading.value = false
|
||||
abortController = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,12 +247,13 @@ function isOutOfStock(product: any) {
|
||||
|
||||
// 停止获取操作
|
||||
function stopFetch() {
|
||||
abortController?.abort()
|
||||
abortController = null
|
||||
loading.value = false
|
||||
currentAsin.value = '已停止'
|
||||
showMessage('已停止获取产品数据', 'info')
|
||||
}
|
||||
|
||||
// 打开Genmai Spirit工具
|
||||
async function openGenmaiSpirit() {
|
||||
try {
|
||||
await ElMessageBox.confirm('打开跟卖精灵会关闭所有谷歌浏览器进程,是否继续?', '提示', {
|
||||
@@ -255,7 +263,7 @@ async function openGenmaiSpirit() {
|
||||
})
|
||||
genmaiLoading.value = true
|
||||
try {
|
||||
await amazonApi.openGenmaiSpirit()
|
||||
await systemApi.openGenmaiSpirit()
|
||||
} catch (error: any) {
|
||||
showMessage(error.message || '打开跟卖精灵失败', 'error')
|
||||
} finally {
|
||||
|
||||
@@ -40,6 +40,7 @@ const fetchCurrentPage = ref(1)
|
||||
const fetchTotalPages = ref(0)
|
||||
const fetchTotalItems = ref(0)
|
||||
const isFetching = ref(false)
|
||||
let abortController: AbortController | null = null
|
||||
|
||||
// 试用期过期弹框
|
||||
const showTrialExpiredDialog = ref(false)
|
||||
@@ -113,6 +114,7 @@ async function fetchData() {
|
||||
return
|
||||
}
|
||||
|
||||
abortController = new AbortController()
|
||||
loading.value = true
|
||||
isFetching.value = true
|
||||
showProgress.value = true
|
||||
@@ -130,7 +132,7 @@ async function fetchPageData(startDate: string, endDate: string) {
|
||||
if (!isFetching.value) return
|
||||
|
||||
try {
|
||||
const data = await zebraApi.getOrders({
|
||||
const response = await zebraApi.getOrders({
|
||||
accountId: Number(accountId.value) || undefined,
|
||||
startDate,
|
||||
endDate,
|
||||
@@ -138,8 +140,9 @@ async function fetchPageData(startDate: string, endDate: string) {
|
||||
pageSize: 50,
|
||||
shopIds: selectedShops.value.join(','),
|
||||
batchId: currentBatchId.value
|
||||
})
|
||||
}, abortController?.signal)
|
||||
|
||||
const data = (response as any)?.data || response
|
||||
const orders = data.orders || []
|
||||
allOrderData.value = [...allOrderData.value, ...orders]
|
||||
|
||||
@@ -154,8 +157,10 @@ async function fetchPageData(startDate: string, endDate: string) {
|
||||
progressPercentage.value = 100
|
||||
finishFetching()
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.name !== 'AbortError') {
|
||||
console.error('获取订单数据失败:', e)
|
||||
}
|
||||
finishFetching()
|
||||
}
|
||||
}
|
||||
@@ -163,6 +168,7 @@ async function fetchPageData(startDate: string, endDate: string) {
|
||||
function finishFetching() {
|
||||
isFetching.value = false
|
||||
loading.value = false
|
||||
abortController = null
|
||||
// 确保进度条完全填满
|
||||
progressPercentage.value = 100
|
||||
currentPage.value = 1
|
||||
@@ -170,6 +176,8 @@ function finishFetching() {
|
||||
}
|
||||
|
||||
function stopFetch() {
|
||||
abortController?.abort()
|
||||
abortController = null
|
||||
isFetching.value = false
|
||||
loading.value = false
|
||||
// 进度条保留显示,不自动隐藏
|
||||
|
||||
@@ -1,63 +1,42 @@
|
||||
package com.tashow.erp.controller;
|
||||
import com.tashow.erp.entity.AmazonProductEntity;
|
||||
import com.tashow.erp.repository.AmazonProductRepository;
|
||||
import com.tashow.erp.service.IAmazonScrapingService;
|
||||
import com.tashow.erp.service.AmazonScrapingService;
|
||||
import com.tashow.erp.utils.ExcelParseUtil;
|
||||
import com.tashow.erp.utils.ExcelExportUtil;
|
||||
import com.tashow.erp.utils.JsonData;
|
||||
import com.tashow.erp.utils.LoggerUtil;
|
||||
import com.tashow.erp.fx.controller.JavaBridge;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/amazon")
|
||||
public class AmazonController {
|
||||
private static final Logger logger = LoggerUtil.getLogger(AmazonController.class);
|
||||
@Autowired
|
||||
private IAmazonScrapingService amazonScrapingService;
|
||||
private AmazonScrapingService amazonScrapingService;
|
||||
@Autowired
|
||||
private AmazonProductRepository amazonProductRepository;
|
||||
|
||||
/**
|
||||
* 批量获取亚马逊产品信息
|
||||
*/
|
||||
@PostMapping("/products/batch")
|
||||
public JsonData batchGetProducts(@RequestBody Object request) {
|
||||
public JsonData batchGetProducts(@RequestBody Map<String, Object> request) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> requestMap = (Map<String, Object>) request;
|
||||
List<String> asinList = (List<String>) requestMap.get("asinList");
|
||||
String batchId = (String) requestMap.get("batchId");
|
||||
String region = (String) requestMap.getOrDefault("region", "JP");
|
||||
List<String> asinList = (List<String>) request.get("asinList");
|
||||
String batchId = (String) request.get("batchId");
|
||||
String region = (String) request.getOrDefault("region", "JP");
|
||||
List<AmazonProductEntity> products = amazonScrapingService.batchGetProductInfo(asinList, batchId, region);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("products", products);
|
||||
result.put("total", products.size());
|
||||
return JsonData.buildSuccess(result);
|
||||
return JsonData.buildSuccess(Map.of("products", products, "total", products.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新产品数据
|
||||
*/
|
||||
@GetMapping("/products/latest")
|
||||
public JsonData getLatestProducts() {
|
||||
List<AmazonProductEntity> products = amazonProductRepository.findLatestProducts();
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("products", products);
|
||||
result.put("total", products.size());
|
||||
return JsonData.buildSuccess(result);
|
||||
return JsonData.buildSuccess(Map.of("products", products, "total", products.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析Excel文件获取ASIN列表
|
||||
*/
|
||||
@PostMapping("/import/asin")
|
||||
public JsonData importAsinFromExcel(@RequestParam("file") MultipartFile file) {
|
||||
try {
|
||||
@@ -65,16 +44,10 @@ public class AmazonController {
|
||||
if (asinList.isEmpty()) {
|
||||
return JsonData.buildError("未从文件中解析到ASIN数据");
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("asinList", asinList);
|
||||
result.put("total", asinList.size());
|
||||
return JsonData.buildSuccess(result);
|
||||
|
||||
return JsonData.buildSuccess(Map.of("asinList", asinList, "total", asinList.size()));
|
||||
} catch (Exception e) {
|
||||
logger.error("解析文件失败: {}", e.getMessage(), e);
|
||||
return JsonData.buildError("解析失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,57 +1,45 @@
|
||||
package com.tashow.erp.controller;
|
||||
import com.tashow.erp.fx.controller.JavaBridge;
|
||||
import com.tashow.erp.repository.BanmaOrderRepository;
|
||||
import com.tashow.erp.service.IBanmaOrderService;
|
||||
import com.tashow.erp.utils.ExcelExportUtil;
|
||||
import com.tashow.erp.service.BanmaOrderService;
|
||||
import com.tashow.erp.utils.JsonData;
|
||||
import com.tashow.erp.utils.LoggerUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/banma")
|
||||
public class BanmaOrderController {
|
||||
private static final Logger logger = LoggerUtil.getLogger(BanmaOrderController.class);
|
||||
@Autowired
|
||||
IBanmaOrderService banmaOrderService;
|
||||
BanmaOrderService banmaOrderService;
|
||||
@Autowired
|
||||
BanmaOrderRepository banmaOrderRepository;
|
||||
|
||||
@GetMapping("/orders")
|
||||
public ResponseEntity<Map<String, Object>> getOrders(
|
||||
public JsonData getOrders(
|
||||
@RequestParam(required = false, name = "accountId") Long accountId,
|
||||
@RequestParam(required = false, name = "startDate") String startDate,
|
||||
@RequestParam(required = false, name = "endDate") String endDate,
|
||||
@RequestParam(defaultValue = "1", name = "page") int page,
|
||||
@RequestParam(defaultValue = "10", name = "pageSize") int pageSize,
|
||||
@RequestParam( "batchId") String batchId,
|
||||
@RequestParam("batchId") String batchId,
|
||||
@RequestParam(required = false, name = "shopIds") String shopIds) {
|
||||
List<String> shopIdList = shopIds != null ? java.util.Arrays.asList(shopIds.split(",")) : null;
|
||||
Map<String, Object> result = banmaOrderService.getOrdersByPage(accountId, startDate, endDate, page, pageSize, batchId, shopIdList);
|
||||
return ResponseEntity.ok(result);
|
||||
return result.containsKey("success") && !(Boolean)result.get("success")
|
||||
? JsonData.buildError((String)result.get("message"))
|
||||
: JsonData.buildSuccess(result);
|
||||
}
|
||||
/**
|
||||
* 获取店铺列表
|
||||
*/
|
||||
@GetMapping("/shops")
|
||||
public JsonData getShops(@RequestParam(required = false, name = "accountId") Long accountId) {
|
||||
try {
|
||||
Map<String, Object> response = banmaOrderService.getShops(accountId);
|
||||
return JsonData.buildSuccess(response);
|
||||
} catch (Exception e) {
|
||||
logger.error("获取店铺列表失败: {}", e.getMessage(), e);
|
||||
return JsonData.buildError("获取店铺列表失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新订单数据
|
||||
*/
|
||||
@GetMapping("/orders/latest")
|
||||
public JsonData getLatestOrders() {
|
||||
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
|
||||
@@ -68,8 +56,6 @@ public class BanmaOrderController {
|
||||
})
|
||||
.filter(order -> !order.isEmpty())
|
||||
.toList();
|
||||
|
||||
return JsonData.buildSuccess(Map.of("orders", orders, "total", orders.size()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,31 +2,19 @@ package com.tashow.erp.controller;
|
||||
|
||||
import com.tashow.erp.model.RakutenProduct;
|
||||
import com.tashow.erp.model.SearchResult;
|
||||
import com.tashow.erp.repository.RakutenProductRepository;
|
||||
import com.tashow.erp.service.Alibaba1688Service;
|
||||
import com.tashow.erp.service.IRakutenCacheService;
|
||||
import com.tashow.erp.service.RakutenCacheService;
|
||||
import com.tashow.erp.service.RakutenScrapingService;
|
||||
import com.tashow.erp.service.impl.Alibaba1688ServiceImpl;
|
||||
import com.tashow.erp.utils.DataReportUtil;
|
||||
import com.tashow.erp.utils.ExcelParseUtil;
|
||||
import com.tashow.erp.utils.JsonData;
|
||||
import com.tashow.erp.utils.QiniuUtil;
|
||||
import com.tashow.erp.fx.controller.JavaBridge;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Base64;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/rakuten")
|
||||
@@ -37,19 +25,10 @@ public class RakutenController {
|
||||
@Autowired
|
||||
private Alibaba1688Service alibaba1688Service;
|
||||
@Autowired
|
||||
private IRakutenCacheService rakutenCacheService;
|
||||
@Autowired
|
||||
private JavaBridge javaBridge;
|
||||
private RakutenCacheService rakutenCacheService;
|
||||
@Autowired
|
||||
private DataReportUtil dataReportUtil;
|
||||
|
||||
/**
|
||||
* 获取乐天商品数据
|
||||
*
|
||||
* @param file Excel文件(首列为店铺名)
|
||||
* @param batchId 可选,批次号
|
||||
* @return JsonData 响应
|
||||
*/
|
||||
@PostMapping(value = "/products")
|
||||
public JsonData getProducts(@RequestParam("file") MultipartFile file, @RequestParam(value = "batchId", required = false) String batchId) {
|
||||
try {
|
||||
@@ -80,21 +59,23 @@ public class RakutenController {
|
||||
if (!newProducts.isEmpty()) {
|
||||
rakutenCacheService.saveProductsWithSessionId(newProducts, batchId);
|
||||
}
|
||||
// 4. 上报缓存数据使用情况
|
||||
int cachedCount = allProducts.size() - newProducts.size();
|
||||
if (cachedCount > 0) {
|
||||
dataReportUtil.reportDataCollection("RAKUTEN_CACHE", cachedCount, "0");
|
||||
}
|
||||
return JsonData.buildSuccess(Map.of("products", allProducts, "total", allProducts.size(), "sessionId", batchId, "skippedShops", skippedShops, "newProductsCount", newProducts.size()));
|
||||
return JsonData.buildSuccess(Map.of(
|
||||
"products", allProducts,
|
||||
"total", allProducts.size(),
|
||||
"sessionId", batchId,
|
||||
"skippedShops", skippedShops,
|
||||
"newProductsCount", newProducts.size()
|
||||
));
|
||||
} catch (Exception e) {
|
||||
log.error("获取乐天商品失败", e);
|
||||
return JsonData.buildError("获取乐天商品失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 1688识图搜索API - 自动保存1688搜索结果
|
||||
*/
|
||||
@PostMapping("/search1688")
|
||||
public JsonData search1688(@RequestBody Map<String, Object> params) {
|
||||
String imageUrl = (String) params.get("imageUrl");
|
||||
@@ -109,21 +90,14 @@ public class RakutenController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/products/latest")
|
||||
public JsonData getLatestProducts() {
|
||||
try {
|
||||
List<Map<String, Object>> products = rakutenScrapingService.getLatestProductsForDisplay();
|
||||
return JsonData.buildSuccess(Map.of("products", products, "total", products.size()));
|
||||
} catch (Exception e) {
|
||||
|
||||
e.printStackTrace();
|
||||
log.info("获取最新商品数据失败", e);
|
||||
log.error("获取最新商品数据失败", e);
|
||||
return JsonData.buildError("获取最新数据失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -2,49 +2,36 @@ package com.tashow.erp.controller;
|
||||
|
||||
import com.tashow.erp.entity.AuthTokenEntity;
|
||||
import com.tashow.erp.repository.AuthTokenRepository;
|
||||
import com.tashow.erp.service.impl.CacheManagementServiceImpl;
|
||||
import com.tashow.erp.service.CacheService;
|
||||
import com.tashow.erp.service.impl.GenmaiServiceImpl;
|
||||
import com.tashow.erp.utils.JsonData;
|
||||
import com.tashow.erp.utils.LoggerUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 系统级接口控制器
|
||||
* 整合:认证、配置、版本、工具、代理等功能
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/system")
|
||||
public class SystemController {
|
||||
|
||||
private static final Logger logger = LoggerUtil.getLogger(SystemController.class);
|
||||
@Autowired
|
||||
private AuthTokenRepository authTokenRepository;
|
||||
|
||||
@Autowired
|
||||
private GenmaiServiceImpl genmaiService;
|
||||
|
||||
@Autowired
|
||||
private CacheManagementServiceImpl cacheManagementService;
|
||||
|
||||
private CacheService cacheService;
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Value("${project.version:2.3.6}")
|
||||
private String currentVersion;
|
||||
|
||||
@Value("${project.build.time:}")
|
||||
private String buildTime;
|
||||
|
||||
@Value("${api.server.base-url}")
|
||||
private String serverBaseUrl;
|
||||
/**
|
||||
* 保存认证密钥
|
||||
*/
|
||||
@PostMapping("/auth/save")
|
||||
public JsonData saveAuth(@RequestBody Map<String, Object> data) {
|
||||
String serviceName = (String) data.get("serviceName");
|
||||
@@ -52,17 +39,13 @@ public class SystemController {
|
||||
if (serviceName == null || authKey == null) {
|
||||
return JsonData.buildError("serviceName和authKey不能为空");
|
||||
}
|
||||
AuthTokenEntity entity = authTokenRepository.findByServiceName(serviceName)
|
||||
.orElse(new AuthTokenEntity());
|
||||
AuthTokenEntity entity = authTokenRepository.findByServiceName(serviceName).orElse(new AuthTokenEntity());
|
||||
entity.setServiceName(serviceName);
|
||||
entity.setToken(authKey);
|
||||
authTokenRepository.save(entity);
|
||||
return JsonData.buildSuccess("认证信息保存成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取认证密钥
|
||||
*/
|
||||
@GetMapping("/auth/get")
|
||||
public JsonData getAuth(@RequestParam String serviceName) {
|
||||
return JsonData.buildSuccess(authTokenRepository.findByServiceName(serviceName)
|
||||
@@ -70,82 +53,41 @@ public class SystemController {
|
||||
.orElse(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除认证密钥
|
||||
*/
|
||||
@DeleteMapping("/auth/remove")
|
||||
public JsonData removeAuth(@RequestParam String serviceName) {
|
||||
authTokenRepository.findByServiceName(serviceName)
|
||||
.ifPresent(authTokenRepository::delete);
|
||||
authTokenRepository.findByServiceName(serviceName).ifPresent(authTokenRepository::delete);
|
||||
return JsonData.buildSuccess("认证信息删除成功");
|
||||
}
|
||||
|
||||
// ==================== 设备管理 ====================
|
||||
|
||||
/**
|
||||
* 获取设备ID
|
||||
*/
|
||||
@GetMapping("/device-id")
|
||||
public JsonData getDeviceId() {
|
||||
String deviceId = com.tashow.erp.utils.DeviceUtils.generateDeviceId();
|
||||
return JsonData.buildSuccess(deviceId);
|
||||
return JsonData.buildSuccess(com.tashow.erp.utils.DeviceUtils.generateDeviceId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本机内网IP地址
|
||||
*/
|
||||
@GetMapping("/local-ip")
|
||||
public JsonData getLocalIp() {
|
||||
try {
|
||||
java.net.InetAddress localHost = java.net.InetAddress.getLocalHost();
|
||||
return JsonData.buildSuccess(localHost.getHostAddress());
|
||||
return JsonData.buildSuccess(java.net.InetAddress.getLocalHost().getHostAddress());
|
||||
} catch (Exception e) {
|
||||
return JsonData.buildSuccess("127.0.0.1");
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 版本信息 ====================
|
||||
|
||||
/**
|
||||
* 获取当前版本号
|
||||
*/
|
||||
@GetMapping("/version")
|
||||
public Map<String, Object> getVersion() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("success", true);
|
||||
result.put("currentVersion", currentVersion);
|
||||
result.put("buildTime", buildTime);
|
||||
return result;
|
||||
return Map.of("success", true, "currentVersion", currentVersion, "buildTime", buildTime);
|
||||
}
|
||||
|
||||
// ==================== 配置信息 ====================
|
||||
|
||||
/**
|
||||
* 获取服务器配置
|
||||
*/
|
||||
@GetMapping("/config/server")
|
||||
public Map<String, Object> getServerConfig() {
|
||||
return Map.of(
|
||||
"baseUrl", serverBaseUrl,
|
||||
"sseUrl", serverBaseUrl + "/monitor/account/events"
|
||||
);
|
||||
return Map.of("baseUrl", serverBaseUrl, "sseUrl", serverBaseUrl + "/monitor/account/events");
|
||||
}
|
||||
|
||||
// ==================== 工具功能 ====================
|
||||
|
||||
/**
|
||||
* 打开跟卖精灵网页
|
||||
*/
|
||||
@PostMapping("/genmai/open")
|
||||
public void openGenmaiWebsite() {
|
||||
genmaiService.openGenmaiWebsite();
|
||||
}
|
||||
|
||||
// ==================== 图片代理 ====================
|
||||
|
||||
/**
|
||||
* 代理获取图片(解决CORS跨域问题)
|
||||
*/
|
||||
@GetMapping("/proxy/image")
|
||||
public ResponseEntity<byte[]> proxyImage(@RequestParam("url") String imageUrl) {
|
||||
if (imageUrl == null || imageUrl.isEmpty()) {
|
||||
@@ -178,24 +120,15 @@ public class SystemController {
|
||||
|
||||
return new ResponseEntity<>(response.getBody(), responseHeaders, HttpStatus.OK);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logger.error("代理图片失败: {}", imageUrl, e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 缓存管理 ====================
|
||||
|
||||
/**
|
||||
* 清理缓存
|
||||
*/
|
||||
@PostMapping("/cache/clear")
|
||||
public JsonData clearCache() {
|
||||
try {
|
||||
cacheManagementService.clearCache();
|
||||
cacheService.clearCache();
|
||||
return JsonData.buildSuccess("缓存清理成功");
|
||||
} catch (Exception e) {
|
||||
return JsonData.buildError("清理缓存失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.tashow.erp.security;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.tashow.erp.service.IAuthService;
|
||||
import com.tashow.erp.service.impl.AuthServiceImpl;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -10,16 +10,13 @@ import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* 本地拦截器
|
||||
*/
|
||||
@Component
|
||||
public class LocalJwtAuthInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final IAuthService authService;
|
||||
private final AuthServiceImpl authService;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public LocalJwtAuthInterceptor(IAuthService authService) {
|
||||
public LocalJwtAuthInterceptor(AuthServiceImpl authService) {
|
||||
this.authService = authService;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,7 @@ package com.tashow.erp.service;
|
||||
import com.tashow.erp.entity.AmazonProductEntity;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 亚马逊数据采集服务接口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface IAmazonScrapingService {
|
||||
public interface AmazonScrapingService {
|
||||
|
||||
/**
|
||||
* 批量获取亚马逊产品信息
|
||||
@@ -19,10 +14,5 @@ public interface IAmazonScrapingService {
|
||||
* @return 产品信息列表
|
||||
*/
|
||||
List<AmazonProductEntity> batchGetProductInfo(List<String> asinList, String batchId, String region);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,12 +3,7 @@ package com.tashow.erp.service;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 斑马订单服务接口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface IBanmaOrderService {
|
||||
public interface BanmaOrderService {
|
||||
|
||||
// 客户端不再暴露刷新认证Token
|
||||
|
||||
@@ -30,3 +25,4 @@ public interface IBanmaOrderService {
|
||||
*/
|
||||
Map<String, Object> getOrdersByPage(Long accountId, String startDate, String endDate, int page, int pageSize, String batchId, List<String> shopIds);
|
||||
}
|
||||
|
||||
@@ -1,39 +1,49 @@
|
||||
package com.tashow.erp.service.impl;
|
||||
package com.tashow.erp.service;
|
||||
|
||||
import com.tashow.erp.entity.AuthTokenEntity;
|
||||
import com.tashow.erp.repository.*;
|
||||
import com.tashow.erp.service.ICacheManagementService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 缓存管理服务实现
|
||||
*/
|
||||
@Service
|
||||
public class CacheManagementServiceImpl implements ICacheManagementService {
|
||||
public class CacheService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CacheService.class);
|
||||
|
||||
@Autowired
|
||||
private AuthTokenRepository authTokenRepository;
|
||||
@Autowired
|
||||
private RakutenProductRepository rakutenProductRepository;
|
||||
|
||||
@Autowired
|
||||
private AmazonProductRepository amazonProductRepository;
|
||||
|
||||
@Autowired
|
||||
private Alibaba1688ProductRepository alibaba1688ProductRepository;
|
||||
|
||||
@Autowired
|
||||
private ZebraOrderRepository zebraOrderRepository;
|
||||
|
||||
@Autowired
|
||||
private BanmaOrderRepository banmaOrderRepository;
|
||||
|
||||
@Autowired
|
||||
private CacheDataRepository cacheDataRepository;
|
||||
|
||||
@Autowired
|
||||
private UpdateStatusRepository updateStatusRepository;
|
||||
|
||||
@Override
|
||||
public void saveAuthToken(String service, String token, long expireTimeMillis) {
|
||||
try {
|
||||
Optional<AuthTokenEntity> existing = authTokenRepository.findByServiceName(service);
|
||||
AuthTokenEntity entity = existing.orElse(new AuthTokenEntity());
|
||||
entity.setServiceName(service);
|
||||
entity.setToken(token);
|
||||
entity.setExpireTime(LocalDateTime.now().plusSeconds(expireTimeMillis / 1000));
|
||||
authTokenRepository.save(entity);
|
||||
} catch (Exception e) {
|
||||
logger.error("保存认证令牌失败: {}", service, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void clearCache() {
|
||||
rakutenProductRepository.deleteAll();
|
||||
@@ -1,52 +0,0 @@
|
||||
package com.tashow.erp.service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 认证服务接口
|
||||
*/
|
||||
public interface IAuthService {
|
||||
|
||||
/**
|
||||
* 客户端登录认证
|
||||
*/
|
||||
Map<String, Object> login(String username, String password);
|
||||
|
||||
/**
|
||||
* 获取客户端信息
|
||||
*/
|
||||
Map<String, Object> getClientInfo();
|
||||
|
||||
/**
|
||||
* 上报错误
|
||||
*/
|
||||
void reportError(String errorType, String errorMessage, Exception e);
|
||||
|
||||
/**
|
||||
* 检查版本更新
|
||||
*/
|
||||
String checkVersion(String currentVersion);
|
||||
|
||||
/**
|
||||
* 获取客户端ID
|
||||
*/
|
||||
String getClientId();
|
||||
|
||||
void logout();
|
||||
|
||||
/**
|
||||
* 验证token
|
||||
*/
|
||||
Map<String, Object> verifyToken(String token);
|
||||
|
||||
|
||||
/**
|
||||
* 注册新账号
|
||||
*/
|
||||
Map<String, Object> register(String username, String password);
|
||||
|
||||
/**
|
||||
* 检查用户名是否可用
|
||||
*/
|
||||
boolean checkUsername(String username);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.tashow.erp.service;
|
||||
|
||||
/**
|
||||
* 缓存服务接口
|
||||
*/
|
||||
public interface ICacheService {
|
||||
|
||||
/**
|
||||
* 保存认证令牌
|
||||
*/
|
||||
void saveAuthToken(String service, String token, long expireTimeMillis);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.tashow.erp.service;
|
||||
|
||||
/**
|
||||
* 跟卖精灵服务接口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface IGenmaiService {
|
||||
|
||||
/**
|
||||
* 使用Playwright打开跟卖精灵网页
|
||||
*
|
||||
* @return 是否成功打开
|
||||
*/
|
||||
void openGenmaiWebsite();
|
||||
|
||||
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
package com.tashow.erp.service;
|
||||
|
||||
import com.tashow.erp.model.RakutenProduct;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 乐天产品缓存服务接口
|
||||
*/
|
||||
public interface IRakutenCacheService {
|
||||
public interface RakutenCacheService {
|
||||
|
||||
/**
|
||||
* 保存产品数据
|
||||
@@ -19,8 +15,6 @@ public interface IRakutenCacheService {
|
||||
*/
|
||||
void saveProductsWithSessionId(List<RakutenProduct> products, String sessionId);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 检查店铺是否有最近的数据(12小时内)
|
||||
*/
|
||||
@@ -45,6 +39,5 @@ public interface IRakutenCacheService {
|
||||
* 清理指定店铺12小时内的重复数据,为新采集做准备
|
||||
*/
|
||||
void cleanRecentDuplicateData(String shopName);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.tashow.erp.service.impl;
|
||||
import com.tashow.erp.entity.AmazonProductEntity;
|
||||
import com.tashow.erp.repository.AmazonProductRepository;
|
||||
import com.tashow.erp.service.AmazonScrapingService;
|
||||
import com.tashow.erp.utils.DataReportUtil;
|
||||
import com.tashow.erp.utils.ErrorReporter;
|
||||
import com.tashow.erp.utils.RakutenProxyUtil;
|
||||
@@ -20,7 +21,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class AmazonScrapingServiceImpl implements IAmazonScrapingService, PageProcessor {
|
||||
public class AmazonScrapingServiceImpl implements AmazonScrapingService, PageProcessor {
|
||||
@Autowired
|
||||
private AmazonProductRepository amazonProductRepository;
|
||||
@Autowired
|
||||
@@ -68,8 +69,9 @@ public class AmazonScrapingServiceImpl implements IAmazonScrapingService, PagePr
|
||||
|
||||
if (isEmpty(price)) errorReporter.reportDataEmpty("amazon", asin, price);
|
||||
if (isEmpty(seller)) errorReporter.reportDataEmpty("amazon", asin, seller);
|
||||
|
||||
AmazonProductEntity entity = new AmazonProductEntity();
|
||||
entity.setAsin(asin != null ? asin : "");
|
||||
entity.setAsin(asin == null ? "" : asin);
|
||||
entity.setPrice(price);
|
||||
entity.setSeller(seller);
|
||||
resultCache.put(asin, entity);
|
||||
|
||||
@@ -1,24 +1,17 @@
|
||||
package com.tashow.erp.service.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.tashow.erp.service.IAuthService;
|
||||
import com.tashow.erp.utils.ApiForwarder;
|
||||
import com.tashow.erp.utils.DeviceUtils;
|
||||
import lombok.Getter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 认证服务实现类 - 简化版
|
||||
* 仅提供错误上报和客户端信息获取功能
|
||||
*/
|
||||
@Service
|
||||
public class AuthServiceImpl implements IAuthService {
|
||||
public class AuthServiceImpl {
|
||||
|
||||
@Value("${project.version:2.1.0}")
|
||||
private String appVersion;
|
||||
@@ -29,10 +22,6 @@ public class AuthServiceImpl implements IAuthService {
|
||||
@Getter
|
||||
private String clientId = DeviceUtils.generateDeviceId();
|
||||
|
||||
/**
|
||||
* 获取客户端基本信息
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getClientInfo() {
|
||||
Map<String, Object> info = new HashMap<>();
|
||||
info.put("clientId", clientId);
|
||||
@@ -41,10 +30,6 @@ public class AuthServiceImpl implements IAuthService {
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上报错误信息
|
||||
*/
|
||||
@Override
|
||||
public void reportError(String errorType, String errorMessage, Exception e) {
|
||||
try {
|
||||
Map<String, Object> errorData = new HashMap<>();
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.tashow.erp.service.impl;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.tashow.erp.entity.BanmaOrderEntity;
|
||||
import com.tashow.erp.repository.BanmaOrderRepository;
|
||||
import com.tashow.erp.service.BanmaOrderService;
|
||||
import com.tashow.erp.service.CacheService;
|
||||
import com.tashow.erp.utils.DataReportUtil;
|
||||
import com.tashow.erp.utils.ErrorReporter;
|
||||
import com.tashow.erp.utils.LoggerUtil;
|
||||
@@ -24,7 +26,7 @@ import java.util.stream.Collectors;
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class BanmaOrderServiceImpl {
|
||||
public class BanmaOrderServiceImpl implements BanmaOrderService {
|
||||
private static final Logger logger = LoggerUtil.getLogger(BanmaOrderServiceImpl.class);
|
||||
private static final String API_URL = "https://banma365.cn/api/order/list?%srecipientName=&page=%d&size=%d&markFlag=0&state=4&_t=%d";
|
||||
private static final String API_URL_WITH_TIME = "https://banma365.cn/api/order/list?%srecipientName=&page=%d&size=%d&markFlag=0&state=4&orderedAtStart=%s&orderedAtEnd=%s&_t=%d";
|
||||
@@ -34,7 +36,7 @@ public class BanmaOrderServiceImpl {
|
||||
private String ruoyiAdminBase;
|
||||
private RestTemplate restTemplate;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final CacheServiceImpl cacheService;
|
||||
private final CacheService cacheService;
|
||||
private final BanmaOrderRepository banmaOrderRepository;
|
||||
private final DataReportUtil dataReportUtil;
|
||||
private final ErrorReporter errorReporter;
|
||||
@@ -44,7 +46,7 @@ public class BanmaOrderServiceImpl {
|
||||
private String currentBatchSessionId = null;
|
||||
// 物流信息缓存,避免重复查询
|
||||
private final Map<String, String> trackingInfoCache = new ConcurrentHashMap<>();
|
||||
public BanmaOrderServiceImpl(BanmaOrderRepository banmaOrderRepository, CacheServiceImpl cacheService, DataReportUtil dataReportUtil, ErrorReporter errorReporter) {
|
||||
public BanmaOrderServiceImpl(BanmaOrderRepository banmaOrderRepository, CacheService cacheService, DataReportUtil dataReportUtil, ErrorReporter errorReporter) {
|
||||
this.banmaOrderRepository = banmaOrderRepository;
|
||||
this.cacheService = cacheService;
|
||||
this.dataReportUtil = dataReportUtil;
|
||||
@@ -233,9 +235,6 @@ public class BanmaOrderServiceImpl {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取子订单字段
|
||||
*/
|
||||
private void extractSubOrderFields(Map<String, Object> simplifiedOrder, Map<String, Object> subOrder) {
|
||||
String[] basicFields = {"orderedAt", "timeSinceOrder", "createdAt", "poTrackingNumber"};
|
||||
String[] productFields = {"productTitle", "shopOrderNumber", "priceJpy", "productQuantity", "shippingFeeJpy", "productNumber", "serviceFee", "productImage"};
|
||||
@@ -245,20 +244,11 @@ public class BanmaOrderServiceImpl {
|
||||
Arrays.stream(purchaseFields).forEach(field -> simplifiedOrder.put(field, subOrder.get(field)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 从API获取物流信息
|
||||
*/
|
||||
private String fetchTrackingInfo(String trackingNumber) {
|
||||
// 优先尝试佐川物流
|
||||
Map<String, Object> trackInfoMap = (Map<String, Object>) new SagawaExpressSdk().getTrackingInfo(trackingNumber).get("trackInfo");
|
||||
if (trackInfoMap != null) {
|
||||
return trackInfoMap.get("dateTime") + " " + trackInfoMap.get("office") + " " + trackInfoMap.get("status");
|
||||
}
|
||||
|
||||
// 斑马API
|
||||
ResponseEntity<Map> response = restTemplate.getForEntity(String.format(TRACKING_URL, trackingNumber), Map.class);
|
||||
return Optional.ofNullable(response.getBody())
|
||||
.filter(body -> Integer.valueOf(0).equals(body.get("code")))
|
||||
@@ -268,9 +258,4 @@ public class BanmaOrderServiceImpl {
|
||||
.map(track -> (String) track.get("track"))
|
||||
.orElse("暂无物流信息");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package com.tashow.erp.service.impl;
|
||||
|
||||
import com.tashow.erp.entity.AuthTokenEntity;
|
||||
import com.tashow.erp.repository.AuthTokenRepository;
|
||||
import com.tashow.erp.service.ICacheService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class CacheServiceImpl implements ICacheService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CacheServiceImpl.class);
|
||||
|
||||
@Autowired
|
||||
private AuthTokenRepository authTokenRepository;
|
||||
|
||||
@Override
|
||||
public void saveAuthToken(String service, String token, long expireTimeMillis) {
|
||||
try {
|
||||
Optional<AuthTokenEntity> existing = authTokenRepository.findByServiceName(service);
|
||||
AuthTokenEntity entity = existing.orElse(new AuthTokenEntity());
|
||||
entity.setServiceName(service);
|
||||
entity.setToken(token);
|
||||
entity.setExpireTime(LocalDateTime.now().plusSeconds(expireTimeMillis / 1000));
|
||||
authTokenRepository.save(entity);
|
||||
} catch (Exception e) {
|
||||
logger.error("保存认证令牌失败: {}", service, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,20 +8,15 @@ import org.openqa.selenium.JavascriptExecutor;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
import com.tashow.erp.service.IGenmaiService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
/**
|
||||
* 跟卖精灵服务实现类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class GenmaiServiceImpl implements IGenmaiService {
|
||||
public class GenmaiServiceImpl {
|
||||
@Value("${api.server.base-url}")
|
||||
private String serverApiUrl;
|
||||
@Value("${api.server.paths.getGenmaijlToken}")
|
||||
@@ -30,7 +25,6 @@ public class GenmaiServiceImpl implements IGenmaiService {
|
||||
private String updateGenmaijlToken;
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void openGenmaiWebsite() {
|
||||
// 先关闭所有Chrome进程
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.tashow.erp.service.impl;
|
||||
import com.tashow.erp.entity.RakutenProductEntity;
|
||||
import com.tashow.erp.model.RakutenProduct;
|
||||
import com.tashow.erp.repository.RakutenProductRepository;
|
||||
import com.tashow.erp.service.IRakutenCacheService;
|
||||
import com.tashow.erp.service.RakutenCacheService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -20,7 +20,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class RakutenCacheServiceImpl implements IRakutenCacheService {
|
||||
public class RakutenCacheServiceImpl implements RakutenCacheService {
|
||||
|
||||
@Autowired
|
||||
private RakutenProductRepository repository;
|
||||
|
||||
@@ -132,30 +132,24 @@ public class RakutenScrapingServiceImpl implements RakutenScrapingService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新的产品数据用于前端展示
|
||||
*/
|
||||
@Override
|
||||
public List<Map<String, Object>> getLatestProductsForDisplay() {
|
||||
return rakutenProductRepository.findLatestProducts().stream().map(entity -> {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("originalShopName", Optional.ofNullable(entity.getOriginalShopName()).orElse(""));
|
||||
result.put("productUrl", Optional.ofNullable(entity.getProductUrl()).orElse(""));
|
||||
result.put("imgUrl", Optional.ofNullable(entity.getImgUrl()).orElse(""));
|
||||
result.put("productTitle", Optional.ofNullable(entity.getProductTitle()).orElse(""));
|
||||
result.put("price", Optional.ofNullable(entity.getPrice()).orElse(""));
|
||||
result.put("ranking", Optional.ofNullable(entity.getRanking()).orElse(""));
|
||||
result.put("image1688Url", Optional.ofNullable(entity.getImage1688Url()).orElse(""));
|
||||
result.put("detailUrl1688", Optional.ofNullable(entity.getDetailUrl1688()).orElse(""));
|
||||
// 使用正确的实体字段
|
||||
result.put("mapRecognitionLink", Optional.ofNullable(entity.getMapRecognitionLink()).orElse(""));
|
||||
result.put("originalShopName", entity.getOriginalShopName());
|
||||
result.put("productUrl", entity.getProductUrl());
|
||||
result.put("imgUrl", entity.getImgUrl());
|
||||
result.put("productTitle", entity.getProductTitle());
|
||||
result.put("price", entity.getPrice());
|
||||
result.put("ranking", entity.getRanking());
|
||||
result.put("image1688Url", entity.getImage1688Url());
|
||||
result.put("detailUrl1688", entity.getDetailUrl1688());
|
||||
result.put("mapRecognitionLink", entity.getMapRecognitionLink());
|
||||
result.put("freight", entity.getFreight());
|
||||
result.put("median", entity.getMedian());
|
||||
result.put("weight", Optional.ofNullable(entity.getWeight()).orElse(""));
|
||||
result.put("skuPrice",entity.getSkuPriceJson());
|
||||
result.put("weight", entity.getWeight());
|
||||
result.put("skuPrice", entity.getSkuPriceJson());
|
||||
return result;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -8,12 +8,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import com.tashow.erp.service.IAuthService;
|
||||
/**
|
||||
* 错误上报工具类 - 立即上报所有错误
|
||||
*
|
||||
* @author ERP
|
||||
*/
|
||||
import com.tashow.erp.service.impl.AuthServiceImpl;
|
||||
|
||||
@Component
|
||||
public class ErrorReporter {
|
||||
|
||||
@@ -21,7 +17,7 @@ public class ErrorReporter {
|
||||
private String serverUrl;
|
||||
|
||||
@Autowired
|
||||
private IAuthService authService;
|
||||
private AuthServiceImpl authService;
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.ruoyi.web.controller.monitor;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -58,6 +57,17 @@ public class ClientAccountController extends BaseController {
|
||||
@Autowired
|
||||
private ClientDeviceMapper clientDeviceMapper;
|
||||
|
||||
private AjaxResult checkDeviceLimit(String username, String deviceId, int deviceLimit) {
|
||||
List<ClientDevice> userDevices = clientDeviceMapper.selectByUsername(username);
|
||||
int userDevice = userDevices.size();
|
||||
boolean exists = userDevices.stream().anyMatch(d -> deviceId.equals(d.getDeviceId()));
|
||||
if (exists) userDevice--;
|
||||
if (userDevice >= deviceLimit) {
|
||||
return AjaxResult.error("设备数量已达上限(" + deviceLimit + "个),请先移除其他设备");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询账号列表
|
||||
*/
|
||||
@@ -140,15 +150,8 @@ public class ClientAccountController extends BaseController {
|
||||
return AjaxResult.error("账号已被停用");
|
||||
}
|
||||
|
||||
// 检查设备数量限制
|
||||
int deviceLimit = account.getDeviceLimit();
|
||||
List<ClientDevice> userDevices = clientDeviceMapper.selectByUsername(username);
|
||||
int userDevice = userDevices.size();
|
||||
boolean exists = userDevices.stream().anyMatch(d -> clientId.equals(d.getDeviceId()));
|
||||
if (exists) userDevice--;
|
||||
if (userDevice >= deviceLimit) {
|
||||
return AjaxResult.error("设备数量已达上限(" + deviceLimit + "个),请先移除其他设备");
|
||||
}
|
||||
AjaxResult limitCheck = checkDeviceLimit(username, clientId, account.getDeviceLimit());
|
||||
if (limitCheck != null) return limitCheck;
|
||||
String token = Jwts.builder()
|
||||
.setHeaderParam("kid", jwtRsaKeyService.getKeyId())
|
||||
.setSubject(username)
|
||||
@@ -160,7 +163,6 @@ public class ClientAccountController extends BaseController {
|
||||
.signWith(SignatureAlgorithm.RS256, jwtRsaKeyService.getPrivateKey())
|
||||
.compact();
|
||||
|
||||
// 检查设备试用期(仅对trial账号生效)
|
||||
boolean deviceTrialExpired = false;
|
||||
if ("trial".equals(account.getAccountType())) {
|
||||
ClientDevice device = clientDeviceMapper.selectByDeviceIdAndUsername(clientId, username);
|
||||
@@ -169,14 +171,14 @@ public class ClientAccountController extends BaseController {
|
||||
&& new Date().after(device.getTrialExpireTime());
|
||||
}
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("token", token);
|
||||
data.put("permissions", account.getPermissions());
|
||||
data.put("accountName", account.getAccountName());
|
||||
data.put("expireTime", account.getExpireTime());
|
||||
data.put("accountType", account.getAccountType());
|
||||
data.put("deviceTrialExpired", deviceTrialExpired);
|
||||
return AjaxResult.success(data);
|
||||
return AjaxResult.success(Map.of(
|
||||
"token", token,
|
||||
"permissions", account.getPermissions(),
|
||||
"accountName", account.getAccountName(),
|
||||
"expireTime", account.getExpireTime(),
|
||||
"accountType", account.getAccountType(),
|
||||
"deviceTrialExpired", deviceTrialExpired
|
||||
));
|
||||
}
|
||||
/**
|
||||
* 验证token
|
||||
@@ -202,7 +204,6 @@ public class ClientAccountController extends BaseController {
|
||||
clientAccountService.updateClientAccount(account);
|
||||
}
|
||||
|
||||
// 检查设备试用期(仅对trial账号生效)
|
||||
boolean deviceTrialExpired = false;
|
||||
if ("trial".equals(account.getAccountType())) {
|
||||
ClientDevice device = clientDeviceMapper.selectByDeviceIdAndUsername(clientId, username);
|
||||
@@ -211,14 +212,14 @@ public class ClientAccountController extends BaseController {
|
||||
&& new Date().after(device.getTrialExpireTime());
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("username", username);
|
||||
result.put("permissions", account.getPermissions());
|
||||
result.put("accountName", account.getAccountName());
|
||||
result.put("expireTime", account.getExpireTime());
|
||||
result.put("accountType", account.getAccountType());
|
||||
result.put("deviceTrialExpired", deviceTrialExpired);
|
||||
return AjaxResult.success(result);
|
||||
return AjaxResult.success(Map.of(
|
||||
"username", username,
|
||||
"permissions", account.getPermissions(),
|
||||
"accountName", account.getAccountName(),
|
||||
"expireTime", account.getExpireTime(),
|
||||
"accountType", account.getAccountType(),
|
||||
"deviceTrialExpired", deviceTrialExpired
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,14 +277,14 @@ public class ClientAccountController extends BaseController {
|
||||
.signWith(SignatureAlgorithm.RS256, jwtRsaKeyService.getPrivateKey())
|
||||
.compact();
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("token", token);
|
||||
data.put("permissions", clientAccount.getPermissions());
|
||||
data.put("accountName", clientAccount.getAccountName());
|
||||
data.put("expireTime", clientAccount.getExpireTime());
|
||||
data.put("accountType", clientAccount.getAccountType());
|
||||
data.put("deviceTrialExpired", false);
|
||||
return AjaxResult.success(data);
|
||||
return AjaxResult.success(Map.of(
|
||||
"token", token,
|
||||
"permissions", clientAccount.getPermissions(),
|
||||
"accountName", clientAccount.getAccountName(),
|
||||
"expireTime", clientAccount.getExpireTime(),
|
||||
"accountType", clientAccount.getAccountType(),
|
||||
"deviceTrialExpired", false
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -324,13 +325,10 @@ public class ClientAccountController extends BaseController {
|
||||
account.setUpdateBy(getUsername());
|
||||
clientAccountService.updateClientAccount(account);
|
||||
|
||||
// 推送续费通知
|
||||
sseHubService.sendEventToAllDevices(account.getUsername(), "VIP_RENEWED",
|
||||
"{\"expireTime\":\"" + newExpireTime + "\"}");
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("expireTime", newExpireTime);
|
||||
return AjaxResult.success(result);
|
||||
return AjaxResult.success(Map.of("expireTime", newExpireTime));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.ruoyi.web.controller.system;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.ip.IpUtils;
|
||||
import com.ruoyi.system.domain.ClientDevice;
|
||||
import com.ruoyi.system.mapper.ClientDeviceMapper;
|
||||
import com.ruoyi.system.mapper.ClientAccountMapper;
|
||||
@@ -10,7 +9,6 @@ import com.ruoyi.web.sse.SseHubService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -24,13 +22,19 @@ public class ClientDeviceController {
|
||||
private ClientAccountMapper clientAccountMapper;
|
||||
@Autowired
|
||||
private SseHubService sseHubService;
|
||||
private AjaxResult checkDeviceLimit(String username, String deviceId) {
|
||||
ClientAccount account = clientAccountMapper.selectClientAccountByUsername(username);
|
||||
int deviceLimit = (account != null && account.getDeviceLimit() != null) ? account.getDeviceLimit() : 3;
|
||||
List<ClientDevice> userDevices = clientDeviceMapper.selectByUsername(username);
|
||||
int userDevice = userDevices.size();
|
||||
boolean deviceExists = userDevices.stream().anyMatch(d -> deviceId.equals(d.getDeviceId()));
|
||||
if (deviceExists) userDevice--;
|
||||
if (userDevice >= deviceLimit) {
|
||||
return AjaxResult.error("设备数量已达上限(" + deviceLimit + "个),请先移除其他设备");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询设备配额与已使用数量
|
||||
*
|
||||
* @param username 用户名,为空时返回0
|
||||
* @return 配额信息
|
||||
*/
|
||||
@GetMapping("/quota")
|
||||
public AjaxResult quota(@RequestParam(value = "username", required = false) String username) {
|
||||
List<ClientDevice> all = clientDeviceMapper.selectByUsername(username);
|
||||
@@ -40,10 +44,7 @@ public class ClientDeviceController {
|
||||
}
|
||||
ClientAccount account = clientAccountMapper.selectClientAccountByUsername(username);
|
||||
int limit = (account != null && account.getDeviceLimit() != null) ? account.getDeviceLimit() : 3;
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("limit", limit);
|
||||
map.put("used", used);
|
||||
return AjaxResult.success(map);
|
||||
return AjaxResult.success(Map.of("limit", limit, "used", used));
|
||||
}
|
||||
/**
|
||||
* 按用户名查询设备列表(最近活动优先)
|
||||
@@ -70,16 +71,8 @@ public class ClientDeviceController {
|
||||
String os = device.getOs();
|
||||
String deviceName = username + "@" + ip + " (" + os + ")";
|
||||
|
||||
// 检查设备数量限制
|
||||
ClientAccount account = clientAccountMapper.selectClientAccountByUsername(username);
|
||||
int deviceLimit = (account != null && account.getDeviceLimit() != null) ? account.getDeviceLimit() : 3;
|
||||
List<ClientDevice> userDevices = clientDeviceMapper.selectByUsername(username);
|
||||
int userDevice = userDevices.size();
|
||||
boolean deviceExists = userDevices.stream().anyMatch(d -> deviceId.equals(d.getDeviceId()));
|
||||
if (deviceExists) userDevice--;
|
||||
if (userDevice >= deviceLimit) {
|
||||
return AjaxResult.error("设备数量已达上限(" + deviceLimit + "个),请先移除其他设备");
|
||||
}
|
||||
AjaxResult limitCheck = checkDeviceLimit(username, deviceId);
|
||||
if (limitCheck != null) return limitCheck;
|
||||
|
||||
ClientDevice exists = clientDeviceMapper.selectByDeviceIdAndUsername(deviceId, username);
|
||||
if (exists == null) {
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.ruoyi.web.controller.tool;
|
||||
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@Anonymous
|
||||
public class GenmaijlController {
|
||||
@Autowired
|
||||
RedisCache redisCache;
|
||||
@GetMapping("/getToken")
|
||||
public String getToken(){
|
||||
return redisCache.getCacheObject("genmaijlToken");
|
||||
}
|
||||
|
||||
@PostMapping("/saveToken")
|
||||
public int saveToken(@RequestBody String token){
|
||||
redisCache.setCacheObject("genmaijlToken", token);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user