mirror of
https://github.com/certd/certd.git
synced 2026-08-08 15:39:32 +08:00
Compare commits
3
Commits
9c7b419e8f
...
cd23ee2055
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd23ee2055 | ||
|
|
e00830bebc | ||
|
|
00e6d580c2 |
@@ -156,10 +156,11 @@ export function createAxiosService({ logger }: { logger: ILogger }) {
|
||||
|
||||
config.retry = merge(
|
||||
{
|
||||
status: [421],
|
||||
status: [421, 524],
|
||||
count: 0,
|
||||
max: 3,
|
||||
delay: 1000,
|
||||
delay: 2000,
|
||||
includes: ["[524]"],
|
||||
},
|
||||
config.retry
|
||||
);
|
||||
@@ -278,7 +279,19 @@ export function createAxiosService({ logger }: { logger: ILogger }) {
|
||||
const originalRequest = error.config || {};
|
||||
// logger.info(`config`, originalRequest);
|
||||
const retry = originalRequest.retry || {};
|
||||
if (retry.status && retry.status.includes(status)) {
|
||||
|
||||
const isRetryStatus = retry.status && retry.status.includes(status);
|
||||
let isRetryMessage = false;
|
||||
if (retry.includes) {
|
||||
for (const item of retry.includes) {
|
||||
if (error.message?.includes(item)) {
|
||||
isRetryMessage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isRetryStatus || isRetryMessage) {
|
||||
if (retry.max > 0 && retry.count < retry.max) {
|
||||
// 重试次数增加
|
||||
retry.count++;
|
||||
|
||||
@@ -23,6 +23,7 @@ export type ExecutorOptions = {
|
||||
pipeline: Pipeline;
|
||||
storage: IStorage;
|
||||
onChanged: (history: RunHistory) => Promise<void>;
|
||||
onFinished: (history: RunHistory) => Promise<void>;
|
||||
accessService: IAccessService;
|
||||
emailService: IEmailService;
|
||||
notificationService: INotificationService;
|
||||
@@ -47,16 +48,19 @@ export class Executor {
|
||||
lastRuntime!: RunHistory;
|
||||
options: ExecutorOptions;
|
||||
abort: AbortController = new AbortController();
|
||||
|
||||
_inited = false;
|
||||
|
||||
onChanged: (history: RunHistory) => Promise<void>;
|
||||
onFinished: (history: RunHistory) => Promise<void>;
|
||||
constructor(options: ExecutorOptions) {
|
||||
this.options = options;
|
||||
this.pipeline = cloneDeep(options.pipeline);
|
||||
this.onChanged = async (history: RunHistory) => {
|
||||
await options.onChanged(history);
|
||||
};
|
||||
this.onFinished = async (history: RunHistory) => {
|
||||
await options.onFinished(history);
|
||||
};
|
||||
this.pipeline.userId = options.user.id;
|
||||
this.contextFactory = new ContextFactory(options.storage);
|
||||
this.logger = logger;
|
||||
@@ -77,7 +81,7 @@ export class Executor {
|
||||
async cancel() {
|
||||
this.abort.abort();
|
||||
this.runtime?.cancel(this.pipeline);
|
||||
await this.onChanged(this.runtime);
|
||||
await this.onFinished(this.runtime);
|
||||
}
|
||||
|
||||
async run(runtimeId: any = 0, triggerType: string) {
|
||||
@@ -111,7 +115,7 @@ export class Executor {
|
||||
this.logger.error("pipeline 执行失败", e);
|
||||
} finally {
|
||||
clearInterval(intervalFlushLogId);
|
||||
await this.onChanged(this.runtime);
|
||||
await this.onFinished(this.runtime);
|
||||
//保存之前移除logs
|
||||
const lastRuntime: any = {
|
||||
...this.runtime,
|
||||
|
||||
@@ -87,6 +87,7 @@ export type Notification = {
|
||||
options?: EmailOptions;
|
||||
notificationId: number;
|
||||
title: string;
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type Pipeline = Runnable & {
|
||||
|
||||
@@ -20,5 +20,6 @@ export async function getTodayVipOrderCount() {
|
||||
return await request({
|
||||
url: "/sys/plus/getTodayVipOrderCount",
|
||||
method: "post",
|
||||
showErrorNotify: false,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,31 +1,5 @@
|
||||
<template>
|
||||
<div class="mt-10 vip-active-modal">
|
||||
<div v-if="todayOrderCount.enabled" class="order-count hidden md:flex">
|
||||
<div v-for="(stage, index) in todayOrderCount.stages" :key="index" class="status-item" :class="{ 'status-show': TodayVipOrderCountRef.current === index }">
|
||||
<div class="background">
|
||||
<img :src="stage.bg" alt="" />
|
||||
</div>
|
||||
<div class="flex flex-col order-count-text weight-bold">
|
||||
<div class="count-text ml-4 flex items-center">
|
||||
<fs-icon icon="noto:fire" class="fs-20 mr-2"></fs-icon>
|
||||
<template v-if="stage.vipTotal > 0">
|
||||
<span> 已有 </span>
|
||||
<span class="count-number color-red font-bold text-2xl ml-1 mr-1"> {{ stage.vipTotal }} </span> 位小伙伴赞助,
|
||||
<span>
|
||||
{{ stage.title }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span> 今日赞助 </span>
|
||||
<span class="count-number color-red font-bold text-2xl ml-1 mr-1"> {{ stage.orderCount }} </span> 人,
|
||||
<span>
|
||||
{{ stage.title }}
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="productInfo.notice" class="mt-10">
|
||||
<a-alert type="error" :message="productInfo.notice"></a-alert>
|
||||
</div>
|
||||
@@ -248,73 +222,35 @@ const vipTypeDefine: any = {
|
||||
const TodayVipOrderCountRef: Ref = ref({ enabled: false, current: 0, stages: [] });
|
||||
|
||||
async function getTodayVipOrderCount() {
|
||||
const res = await api.getTodayVipOrderCount();
|
||||
if (res) {
|
||||
TodayVipOrderCountRef.value = res;
|
||||
TodayVipOrderCountRef.value.current = 0;
|
||||
try {
|
||||
const res = await api.getTodayVipOrderCount();
|
||||
if (res) {
|
||||
TodayVipOrderCountRef.value = res;
|
||||
TodayVipOrderCountRef.value.current = 0;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
const todayOrderCount = computed(() => {
|
||||
const countInfo = TodayVipOrderCountRef.value;
|
||||
const enabled = countInfo?.enabled || false;
|
||||
const orderCount = countInfo?.orderCount || 0;
|
||||
for (const stage of countInfo?.stages) {
|
||||
stage.orderCount = stage.countGe || 0;
|
||||
}
|
||||
const lastStage = countInfo?.stages?.[countInfo?.stages?.length - 1] || {};
|
||||
lastStage.orderCount = orderCount;
|
||||
|
||||
const vipTotal = countInfo?.vipTotal || 0;
|
||||
const showVipTotal = countInfo?.showVipTotal || false;
|
||||
const userTotal = countInfo?.userTotal || 0;
|
||||
const stages: any = [];
|
||||
stages.push({
|
||||
title: countInfo.title,
|
||||
vipTotal: countInfo?.vipTotal || 0,
|
||||
orderCount: orderCount,
|
||||
bg: lastStage.bg,
|
||||
showVipTotal: showVipTotal,
|
||||
});
|
||||
if (lastStage.orderCount > 0) {
|
||||
stages.push(lastStage);
|
||||
}
|
||||
return {
|
||||
enabled: enabled,
|
||||
stages: stages,
|
||||
showVipTotal: showVipTotal,
|
||||
vipTotal: vipTotal,
|
||||
userTotal: userTotal,
|
||||
};
|
||||
});
|
||||
|
||||
async function scrollOrderCount() {
|
||||
const stages = todayOrderCount.value.stages;
|
||||
if (stages.length === 0) {
|
||||
return;
|
||||
}
|
||||
let index = 0;
|
||||
const doScroll = () => {
|
||||
TodayVipOrderCountRef.value.current = index;
|
||||
index++;
|
||||
if (index >= stages.length) {
|
||||
index = 0;
|
||||
}
|
||||
};
|
||||
doScroll();
|
||||
scrollOrderCountIntervalRef.value = setInterval(doScroll, 7000);
|
||||
}
|
||||
|
||||
const scrollOrderCountIntervalRef: Ref = ref(null);
|
||||
onMounted(async () => {
|
||||
await getTodayVipOrderCount();
|
||||
await nextTick();
|
||||
await scrollOrderCount();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(scrollOrderCountIntervalRef.value);
|
||||
});
|
||||
onUnmounted(() => {});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
||||
@@ -80,7 +80,7 @@ const development = {
|
||||
type: 'better-sqlite3',
|
||||
database: './data/db.sqlite',
|
||||
synchronize: false, // 如果第一次使用,不存在表,有同步的需求可以写 true
|
||||
logging: true,
|
||||
logging: false,
|
||||
highlightSql: false,
|
||||
|
||||
// 配置实体模型 或者 entities: '/entity',
|
||||
|
||||
@@ -674,8 +674,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const onChanged = async (history: RunHistory) => {
|
||||
|
||||
const doSaveHistory = async (history: RunHistory) => {
|
||||
//保存执行历史
|
||||
try {
|
||||
logger.info("保存执行历史:", history.id);
|
||||
@@ -690,6 +690,46 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
class HistorySaver {
|
||||
latest: RunHistory = null;
|
||||
interval: any = null;
|
||||
started: boolean = false;
|
||||
async save(){
|
||||
const latest = this.latest;
|
||||
this.latest = null;
|
||||
if (latest == null) {
|
||||
return;
|
||||
}
|
||||
await doSaveHistory(latest);
|
||||
}
|
||||
|
||||
async start(){
|
||||
this.started = true
|
||||
await this.save();
|
||||
this.interval = setInterval(()=>{
|
||||
this.save();
|
||||
}, 1000 * 5);
|
||||
}
|
||||
async push(history: RunHistory){
|
||||
this.latest = history;
|
||||
if(!this.started){
|
||||
await this.start();
|
||||
}
|
||||
}
|
||||
async done(){
|
||||
clearInterval(this.interval);
|
||||
await this.save();
|
||||
}
|
||||
}
|
||||
|
||||
const historySaver = new HistorySaver();
|
||||
const onChanged = async (history: RunHistory)=>{
|
||||
await historySaver.push(history);
|
||||
}
|
||||
const onFinished = async (history: RunHistory)=>{
|
||||
await onChanged(history);
|
||||
await historySaver.done();
|
||||
}
|
||||
|
||||
const userId = entity.userId;
|
||||
const projectId = entity.projectId;
|
||||
@@ -723,6 +763,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
user,
|
||||
pipeline,
|
||||
onChanged,
|
||||
onFinished,
|
||||
accessService: accessGetter,
|
||||
cnameProxyService,
|
||||
pluginConfigService: this.pluginConfigGetter,
|
||||
@@ -762,15 +803,15 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
if (executor) {
|
||||
await executor.cancel();
|
||||
}
|
||||
const entity = await this.historyService.info(historyId);
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
const pipeline: Pipeline = JSON.parse(entity.pipeline);
|
||||
pipeline.status.status = ResultType.canceled;
|
||||
pipeline.status.result = ResultType.canceled;
|
||||
const runtime = new RunHistory(historyId, null, pipeline);
|
||||
await this.saveHistory(runtime);
|
||||
// const entity = await this.historyService.info(historyId);
|
||||
// if (entity == null) {
|
||||
// return;
|
||||
// }
|
||||
// const pipeline: Pipeline = JSON.parse(entity.pipeline);
|
||||
// pipeline.status.status = ResultType.canceled;
|
||||
// pipeline.status.result = ResultType.canceled;
|
||||
// const runtime = new RunHistory(historyId, null, pipeline);
|
||||
// await this.saveHistory(runtime);
|
||||
}
|
||||
|
||||
private getTriggerType(triggerId, pipeline) {
|
||||
|
||||
@@ -93,6 +93,9 @@ export class OnePanelClient {
|
||||
if (res.code === 200) {
|
||||
return res.data;
|
||||
}
|
||||
if (res?.message?.includes("record not found")){
|
||||
throw new Error("没有找到证书,请确认证书在1panel上是否已被删除,如果被删除请重新选择新的证书id:"+ config.url);
|
||||
}
|
||||
throw new Error(res.message);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,3 +40,4 @@ function randomStr(length, options?) {
|
||||
}
|
||||
|
||||
export const RandomUtil = { randomStr };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user