From 3c6175d95952c6f0e2d55e7e0064cbc1cd297fdd Mon Sep 17 00:00:00 2001 From: nenohi <kimutipartylove@gmail.com> Date: Sat, 8 Jul 2023 08:56:11 +0900 Subject: [PATCH] =?UTF-8?q?=E5=BA=83=E5=91=8A=E3=81=AE=E6=9B=9C=E6=97=A5?= =?UTF-8?q?=E3=82=92=E8=A8=AD=E5=AE=9A=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=20(#10095)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 曜日é¸æŠžã§ãるよã†ã« * ラベルé¸æŠžã§ã‚‚ãƒã‚§ãƒƒã‚¯ãŒå¤‰æ›´ã•ã‚Œã‚‹ã‚ˆã†ã« * 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> --- locales/ja-JP.yml | 1 + .../backend/migration/1677054292210-ad4.js | 9 +++++++++ packages/backend/src/models/entities/Ad.ts | 5 ++++- .../server/api/endpoints/admin/ad/create.ts | 4 +++- .../server/api/endpoints/admin/ad/update.ts | 4 +++- .../backend/src/server/api/endpoints/meta.ts | 20 +++++++++++-------- packages/frontend/src/pages/admin/ads.vue | 19 ++++++++++++++++++ 7 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 packages/backend/migration/1677054292210-ad4.js diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 0b2817e1ad..51122655b5 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1451,6 +1451,7 @@ _ad: back: "戻る" reduceFrequencyOfThisAd: "ã“ã®åºƒå‘Šã®è¡¨ç¤ºé »åº¦ã‚’下ã’ã‚‹" hide: "表示ã—ãªã„" + timezoneinfo: "曜日ã¯ã‚µãƒ¼ãƒãƒ¼ã®ã‚¿ã‚¤ãƒ ゾーンを元ã«æŒ‡å®šã•ã‚Œã¾ã™ã€‚" _forgotPassword: enterEmail: "アカウントã«ç™»éŒ²ã—ãŸãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’入力ã—ã¦ãã ã•ã„。ãã®ã‚¢ãƒ‰ãƒ¬ã‚¹å®›ã¦ã«ã€ãƒ‘スワードリセット用ã®ãƒªãƒ³ã‚¯ãŒé€ä¿¡ã•ã‚Œã¾ã™ã€‚" 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, }); -- GitLab