summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authornenohi <kimutipartylove@gmail.com>2023-07-08 08:56:11 +0900
committerGitHub <noreply@github.com>2023-07-08 08:56:11 +0900
commit3c6175d95952c6f0e2d55e7e0064cbc1cd297fdd (patch)
treebae4b84ba3e7e56650641428050a05d0d3c3a3ad /packages
parentuse engines (diff)
downloadsharkey-3c6175d95952c6f0e2d55e7e0064cbc1cd297fdd.tar.gz
sharkey-3c6175d95952c6f0e2d55e7e0064cbc1cd297fdd.tar.bz2
sharkey-3c6175d95952c6f0e2d55e7e0064cbc1cd297fdd.zip
広告の曜日を設定できるように (#10095)
* 曜日選択できるように * ラベル選択でもチェックが変更されるように * adを参照しないといけないかも * smallint -> integer * 異物混入だったので取りだし * タイムゾーン指定(Date2つ使うのなんか違和感 * 未テスト * これにすると出てこないかも * UIチョット変更 * UI変更 fix bug * 畳むように修正 * dayofweek->dayOfWeek * マイグレ時にnot null,default設定してるのでnullable:falseでよさそう * コメントの記載 * Update packages/backend/src/server/api/endpoints/meta.ts Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> --------- Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
Diffstat (limited to 'packages')
-rw-r--r--packages/backend/migration/1677054292210-ad4.js9
-rw-r--r--packages/backend/src/models/entities/Ad.ts5
-rw-r--r--packages/backend/src/server/api/endpoints/admin/ad/create.ts4
-rw-r--r--packages/backend/src/server/api/endpoints/admin/ad/update.ts4
-rw-r--r--packages/backend/src/server/api/endpoints/meta.ts20
-rw-r--r--packages/frontend/src/pages/admin/ads.vue19
6 files changed, 50 insertions, 11 deletions
diff --git a/packages/backend/migration/1677054292210-ad4.js b/packages/backend/migration/1677054292210-ad4.js
new file mode 100644
index 0000000000..48499319b4
--- /dev/null
+++ b/packages/backend/migration/1677054292210-ad4.js
@@ -0,0 +1,9 @@
+export class ad1677054292210 {
+ name = 'ad1677054292210';
+ async up(queryRunner) {
+ await queryRunner.query(`ALTER TABLE "ad" ADD "dayOfWeek" integer NOT NULL Default 0`);
+ }
+ async down(queryRunner) {
+ await queryRunner.query(`ALTER TABLE "ad" DROP COLUMN "dayOfWeek"`);
+ }
+}
diff --git a/packages/backend/src/models/entities/Ad.ts b/packages/backend/src/models/entities/Ad.ts
index 56baf863ca..a496a6d276 100644
--- a/packages/backend/src/models/entities/Ad.ts
+++ b/packages/backend/src/models/entities/Ad.ts
@@ -55,7 +55,10 @@ export class Ad {
length: 8192, nullable: false,
})
public memo: string;
-
+ @Column('integer', {
+ default: 0, nullable: false,
+ })
+ public dayOfWeek: number;
constructor(data: Partial<Ad>) {
if (data == null) return;
diff --git a/packages/backend/src/server/api/endpoints/admin/ad/create.ts b/packages/backend/src/server/api/endpoints/admin/ad/create.ts
index 917242db3f..757030839e 100644
--- a/packages/backend/src/server/api/endpoints/admin/ad/create.ts
+++ b/packages/backend/src/server/api/endpoints/admin/ad/create.ts
@@ -22,8 +22,9 @@ export const paramDef = {
expiresAt: { type: 'integer' },
startsAt: { type: 'integer' },
imageUrl: { type: 'string', minLength: 1 },
+ dayOfWeek: { type: 'integer' },
},
- required: ['url', 'memo', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'imageUrl'],
+ required: ['url', 'memo', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'imageUrl', 'dayOfWeek'],
} as const;
// eslint-disable-next-line import/no-default-export
@@ -41,6 +42,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
createdAt: new Date(),
expiresAt: new Date(ps.expiresAt),
startsAt: new Date(ps.startsAt),
+ dayOfWeek: ps.dayOfWeek,
url: ps.url,
imageUrl: ps.imageUrl,
priority: ps.priority,
diff --git a/packages/backend/src/server/api/endpoints/admin/ad/update.ts b/packages/backend/src/server/api/endpoints/admin/ad/update.ts
index dbab7e9d4f..70082290ba 100644
--- a/packages/backend/src/server/api/endpoints/admin/ad/update.ts
+++ b/packages/backend/src/server/api/endpoints/admin/ad/update.ts
@@ -31,8 +31,9 @@ export const paramDef = {
ratio: { type: 'integer' },
expiresAt: { type: 'integer' },
startsAt: { type: 'integer' },
+ dayOfWeek: { type: 'integer' },
},
- required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt'],
+ required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'dayOfWeek'],
} as const;
// eslint-disable-next-line import/no-default-export
@@ -56,6 +57,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
imageUrl: ps.imageUrl,
expiresAt: new Date(ps.expiresAt),
startsAt: new Date(ps.startsAt),
+ dayOfWeek: ps.dayOfWeek,
});
});
}
diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts
index 6ef5f0d5c8..915a1e54f8 100644
--- a/packages/backend/src/server/api/endpoints/meta.ts
+++ b/packages/backend/src/server/api/endpoints/meta.ts
@@ -1,4 +1,4 @@
-import { IsNull, LessThanOrEqual, MoreThan } from 'typeorm';
+import { IsNull, LessThanOrEqual, MoreThan, Brackets } from 'typeorm';
import { Inject, Injectable } from '@nestjs/common';
import JSON5 from 'json5';
import type { AdsRepository, UsersRepository } from '@/models/index.js';
@@ -263,13 +263,16 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
super(meta, paramDef, async (ps, me) => {
const instance = await this.metaService.fetch(true);
- const ads = await this.adsRepository.find({
- where: {
- expiresAt: MoreThan(new Date()),
- startsAt: LessThanOrEqual(new Date()),
- },
- });
-
+ const ads = await this.adsRepository.createQueryBuilder("ads")
+ .where('ads.expiresAt > :now', { now: new Date() })
+ .andWhere('ads.startsAt <= :now', { now: new Date() })
+ .andWhere(new Brackets(qb => {
+ // 曜日のビットフラグを確認する
+ qb.where('ads.dayOfWeek & :dayOfWeek > 0', { dayOfWeek: 1 << new Date().getDay() })
+ .orWhere('ads.dayOfWeek = 0');
+ }))
+ .getMany();
+
const response: any = {
maintainerName: instance.maintainerName,
maintainerEmail: instance.maintainerEmail,
@@ -311,6 +314,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
place: ad.place,
ratio: ad.ratio,
imageUrl: ad.imageUrl,
+ dayOfWeek: ad.dayOfWeek,
})),
enableEmail: instance.enableEmail,
enableServiceWorker: instance.enableServiceWorker,
diff --git a/packages/frontend/src/pages/admin/ads.vue b/packages/frontend/src/pages/admin/ads.vue
index 2c9e18b0bf..9a5bd88b2e 100644
--- a/packages/frontend/src/pages/admin/ads.vue
+++ b/packages/frontend/src/pages/admin/ads.vue
@@ -36,6 +36,16 @@
<template #label>{{ i18n.ts.expiration }}</template>
</MkInput>
</FormSplit>
+ <MkFolder>
+ <template #label>{{ i18n.ts.advancedSettings }}</template>
+ <span>
+ {{ i18n.ts._ad.timezoneinfo }}
+ <div v-for="(day, index) in daysOfWeek" :key="index">
+ <input :id="`ad${ad.id}-${index}`" type="checkbox" :checked="(ad.dayOfWeek & (1 << index)) !== 0" @change="toggleDayOfWeek(ad, index)">
+ <label :for="`ad${ad.id}-${index}`">{{ day }}</label>
+ </div>
+ </span>
+ </MkFolder>
<MkTextarea v-model="ad.memo">
<template #label>{{ i18n.ts.memo }}</template>
</MkTextarea>
@@ -59,6 +69,7 @@ import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
import MkTextarea from '@/components/MkTextarea.vue';
import MkRadios from '@/components/MkRadios.vue';
+import MkFolder from '@/components/MkFolder.vue';
import FormSplit from '@/components/form/split.vue';
import * as os from '@/os';
import { i18n } from '@/i18n';
@@ -69,6 +80,7 @@ let ads: any[] = $ref([]);
// ISO形式はTZがUTCになってしまうので、TZ分ずらして時間を初期化
const localTime = new Date();
const localTimeDiff = localTime.getTimezoneOffset() * 60 * 1000;
+const daysOfWeek: string[] = [i18n.ts._weekday.sunday, i18n.ts._weekday.monday, i18n.ts._weekday.tuesday, i18n.ts._weekday.wednesday, i18n.ts._weekday.thursday, i18n.ts._weekday.friday, i18n.ts._weekday.saturday];
os.api('admin/ad/list').then(adsResponse => {
ads = adsResponse.map(r => {
@@ -84,6 +96,11 @@ os.api('admin/ad/list').then(adsResponse => {
});
});
+// 選択された曜日(index)のビットフラグを操作する
+function toggleDayOfWeek(ad, index) {
+ ad.dayOfWeek ^= 1 << index;
+}
+
function add() {
ads.unshift({
id: null,
@@ -95,6 +112,7 @@ function add() {
imageUrl: null,
expiresAt: null,
startsAt: null,
+ dayOfWeek: 0,
});
}
@@ -105,6 +123,7 @@ function remove(ad) {
}).then(({ canceled }) => {
if (canceled) return;
ads = ads.filter(x => x !== ad);
+ if (ad.id == null) return;
os.apiWithDialog('admin/ad/delete', {
id: ad.id,
});