import { Provide, Inject } from '@midwayjs/core';
|
import { BaseService } from '@cool-midway/core';
|
import axios from 'axios';
|
import { BaseSysParamEntity } from '../../base/entity/sys/param';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
import { Repository } from 'typeorm';
|
|
interface Ys7TokenData {
|
accessToken: string;
|
/** 萤石返回的毫秒级过期时间戳 */
|
expireTime: number;
|
}
|
|
@Provide()
|
export class Ys7Service extends BaseService {
|
@InjectEntityModel(BaseSysParamEntity)
|
baseSysParamEntity: Repository<BaseSysParamEntity>;
|
|
/** 内存并发锁 */
|
private refreshing: Promise<Ys7TokenData> | null = null;
|
|
/**
|
* 对外暴露:拿 token(自动读缓存 / 续签)
|
*/
|
async getAccessToken() {
|
const token = await this.baseSysParamEntity.findOneBy({ keyName: 'ys7.accessToken' });
|
if (
|
!token ||
|
!token.updateTime ||
|
Date.now() - new Date(token.updateTime).getTime() > 6 * 24 * 60 * 60 * 1000
|
) {
|
await this.fetchAndSaveRemote();
|
}
|
}
|
|
/** 真正调萤石 */
|
private async fetchAndSaveRemote(): Promise<Ys7TokenData> {
|
const appKey_result = await this.baseSysParamEntity.findOneBy({ keyName: 'ys7.appKey' });
|
const appSecret_result = await this.baseSysParamEntity.findOneBy({ keyName: 'ys7.appSecret' });
|
|
if (!appKey_result || !appSecret_result) {
|
throw new Error(
|
'萤石云 appKey/appSecret 未配置,请在【系统参数】中维护 ys7.appKey / ys7.appSecret'
|
);
|
}
|
|
const { data: res } = await axios.post(
|
'https://open.ys7.com/api/lapp/token/get',
|
new URLSearchParams({ appKey: appKey_result.data, appSecret: appSecret_result.data }),
|
{
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
timeout: 8000,
|
}
|
);
|
|
if (String(res.code) !== '200') {
|
throw new Error(`萤石云获取 Token 失败:${res.msg}(code: ${res.code})`);
|
}
|
|
const tokenData: Ys7TokenData = {
|
accessToken: res.data.accessToken,
|
expireTime: res.data.expireTime,
|
};
|
|
// 写回系统参数表(Cool-Admin 自带 upsert)
|
const token = await this.baseSysParamEntity.findOneBy({ keyName: 'ys7.accessToken' });
|
this.baseSysParamEntity.save({
|
...token,
|
data: tokenData.accessToken,
|
updateTime: new Date(),
|
}).catch(() => {
|
// 忽略写回失败
|
});
|
return tokenData;
|
}
|
}
|