広告開始時期の設定 (#9944)

* 広告開始時期の設定

* 過去のものも表示するように
This commit is contained in:
nenohi 2023-02-15 14:29:40 +09:00 committed by GitHub
parent 8caf288ac1
commit 71c42bef9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 36 additions and 8 deletions

View File

@ -777,6 +777,7 @@ popularPosts: "人気の投稿"
shareWithNote: "ノートで共有" shareWithNote: "ノートで共有"
ads: "広告" ads: "広告"
expiration: "期限" expiration: "期限"
startingperiod: "開始期間"
memo: "メモ" memo: "メモ"
priority: "優先度" priority: "優先度"
high: "高" high: "高"

View File

@ -0,0 +1,9 @@
export class ad1676438468213 {
name = 'ad1676438468213';
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "ad" ADD "startAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "startAt"`);
}
}

View File

@ -18,6 +18,12 @@ export class Ad {
}) })
public expiresAt: Date; public expiresAt: Date;
@Index()
@Column('timestamp with time zone', {
comment: 'The expired date of the Ad.',
})
public startAt: Date;
@Column('varchar', { @Column('varchar', {
length: 32, nullable: false, length: 32, nullable: false,
}) })

View File

@ -20,9 +20,10 @@ export const paramDef = {
priority: { type: 'string' }, priority: { type: 'string' },
ratio: { type: 'integer' }, ratio: { type: 'integer' },
expiresAt: { type: 'integer' }, expiresAt: { type: 'integer' },
startAt: { type: 'integer' },
imageUrl: { type: 'string', minLength: 1 }, imageUrl: { type: 'string', minLength: 1 },
}, },
required: ['url', 'memo', 'place', 'priority', 'ratio', 'expiresAt', 'imageUrl'], required: ['url', 'memo', 'place', 'priority', 'ratio', 'expiresAt', 'startAt', 'imageUrl'],
} as const; } as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@ -39,6 +40,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
id: this.idService.genId(), id: this.idService.genId(),
createdAt: new Date(), createdAt: new Date(),
expiresAt: new Date(ps.expiresAt), expiresAt: new Date(ps.expiresAt),
startAt: new Date(ps.startAt),
url: ps.url, url: ps.url,
imageUrl: ps.imageUrl, imageUrl: ps.imageUrl,
priority: ps.priority, priority: ps.priority,

View File

@ -32,8 +32,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.adsRepository.createQueryBuilder('ad'), ps.sinceId, ps.untilId) const query = this.queryService.makePaginationQuery(this.adsRepository.createQueryBuilder('ad'), ps.sinceId, ps.untilId)
.andWhere('ad.expiresAt > :now', { now: new Date() });
const ads = await query.take(ps.limit).getMany(); const ads = await query.take(ps.limit).getMany();
return ads; return ads;

View File

@ -30,8 +30,9 @@ export const paramDef = {
priority: { type: 'string' }, priority: { type: 'string' },
ratio: { type: 'integer' }, ratio: { type: 'integer' },
expiresAt: { type: 'integer' }, expiresAt: { type: 'integer' },
startAt: { type: 'integer' },
}, },
required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt'], required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startAt'],
} as const; } as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@ -54,6 +55,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
memo: ps.memo, memo: ps.memo,
imageUrl: ps.imageUrl, imageUrl: ps.imageUrl,
expiresAt: new Date(ps.expiresAt), expiresAt: new Date(ps.expiresAt),
startAt: new Date(ps.startAt),
}); });
}); });
} }

View File

@ -1,4 +1,4 @@
import { IsNull, MoreThan } from 'typeorm'; import { IsNull, LessThanOrEqual, MoreThan } from 'typeorm';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import type { AdsRepository, EmojisRepository, UsersRepository } from '@/models/index.js'; import type { AdsRepository, EmojisRepository, UsersRepository } from '@/models/index.js';
import { MAX_NOTE_TEXT_LENGTH, DB_MAX_NOTE_TEXT_LENGTH } from '@/const.js'; import { MAX_NOTE_TEXT_LENGTH, DB_MAX_NOTE_TEXT_LENGTH } from '@/const.js';
@ -262,6 +262,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const ads = await this.adsRepository.find({ const ads = await this.adsRepository.find({
where: { where: {
expiresAt: MoreThan(new Date()), expiresAt: MoreThan(new Date()),
startAt: LessThanOrEqual(new Date()),
}, },
}); });

View File

@ -29,6 +29,9 @@
<MkInput v-model="ad.ratio" type="number"> <MkInput v-model="ad.ratio" type="number">
<template #label>{{ i18n.ts.ratio }}</template> <template #label>{{ i18n.ts.ratio }}</template>
</MkInput> </MkInput>
<MkInput v-model="ad.startAt" type="datetime-local">
<template #label>{{ i18n.ts.startingperiod }}</template>
</MkInput>
<MkInput v-model="ad.expiresAt" type="datetime-local"> <MkInput v-model="ad.expiresAt" type="datetime-local">
<template #label>{{ i18n.ts.expiration }}</template> <template #label>{{ i18n.ts.expiration }}</template>
</MkInput> </MkInput>
@ -66,11 +69,14 @@ const localTimeDiff = localTime.getTimezoneOffset() * 60 * 1000;
os.api('admin/ad/list').then(adsResponse => { os.api('admin/ad/list').then(adsResponse => {
ads = adsResponse.map(r => { ads = adsResponse.map(r => {
const date = new Date(r.expiresAt); const exdate = new Date(r.expiresAt);
date.setMilliseconds(date.getMilliseconds() - localTimeDiff); const stdate = new Date(r.startAt);
exdate.setMilliseconds(exdate.getMilliseconds() - localTimeDiff);
stdate.setMilliseconds(stdate.getMilliseconds() - localTimeDiff);
return { return {
...r, ...r,
expiresAt: date.toISOString().slice(0, 16), expiresAt: exdate.toISOString().slice(0, 16),
startAt: stdate.toISOString().slice(0, 16),
}; };
}); });
}); });
@ -85,6 +91,7 @@ function add() {
url: '', url: '',
imageUrl: null, imageUrl: null,
expiresAt: null, expiresAt: null,
startAt: null,
}); });
} }
@ -106,11 +113,13 @@ function save(ad) {
os.apiWithDialog('admin/ad/create', { os.apiWithDialog('admin/ad/create', {
...ad, ...ad,
expiresAt: new Date(ad.expiresAt).getTime(), expiresAt: new Date(ad.expiresAt).getTime(),
startAt: new Date(ad.startAt).getTime(),
}); });
} else { } else {
os.apiWithDialog('admin/ad/update', { os.apiWithDialog('admin/ad/update', {
...ad, ...ad,
expiresAt: new Date(ad.expiresAt).getTime(), expiresAt: new Date(ad.expiresAt).getTime(),
startAt: new Date(ad.startAt).getTime(),
}); });
} }
} }