From 4e39a1a6806f91f8146e2a3c7d607767c36ed691 Mon Sep 17 00:00:00 2001 From: xue jiahao Date: Wed, 12 Feb 2025 14:42:54 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E5=9C=92=E5=85=90=E5=8F=B0=E5=B8=B3?= =?UTF-8?q?=20for=20update=20vlookup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/env.js | 6 ++ src/main.css | 18 +++++- src/utils.js | 58 ++++++++++++++++++ src/園児別出欠簿入力/BatchCreateHandler.js | 68 ++++++++++++++++++++-- src/園児別出欠簿入力/ExtractHandler.js | 10 ++-- src/園児別出欠簿入力/Link1Handler.js | 8 +-- src/園児別出欠簿入力/Link2Handler.js | 8 +-- src/園児別出欠簿入力/clock-btn-desktop.js | 12 ++-- src/園児別出欠簿入力/main.js | 8 +-- src/園児台帳/main.js | 42 +++++++++++++ 10 files changed, 209 insertions(+), 29 deletions(-) create mode 100644 src/園児台帳/main.js diff --git a/src/env.js b/src/env.js index 500ebb8..d746ee1 100644 --- a/src/env.js +++ b/src/env.js @@ -23,5 +23,11 @@ const env = { }, "園児台帳": { appId: 16, + uniqueKeyFieldCode: 'ユニークキー' }, }; + +const warekiStartYear = { + "平成": 1989, + "令和": 2019, +} \ No newline at end of file diff --git a/src/main.css b/src/main.css index 30cb4ae..4fc782d 100644 --- a/src/main.css +++ b/src/main.css @@ -75,4 +75,20 @@ --kuc-button-height: 42px; margin-top: 32px; margin-left: -8px; -} \ No newline at end of file +} + +.kuc--has-spinner { + position: relative; +} +div[class^='kuc-spinner'][class$='__spinner'] { + margin-top: 89px; + height: calc(100% - 89px); + position: absolute; + --kuc-spinner-text-color: #3498db; + --kuc-spinner-loader-color: #3498db; +} +div[class^='kuc-spinner'][class$='mask'] { + top: 89px; + position: absolute; + background-color: white; +} diff --git a/src/utils.js b/src/utils.js index 1ed66d6..1297238 100644 --- a/src/utils.js +++ b/src/utils.js @@ -21,6 +21,7 @@ const classItems = [ const errorEl = new Kuc.Notification({ type: 'danger', }); +let loadingEl; function getHeaderSpace(className, isDetailPage) { const headerSpace = (isDetailPage ? kintone.app.record : kintone.app).getHeaderMenuSpaceElement(); @@ -191,4 +192,61 @@ function hideSpaceField(ids) { function getExcelName({ excelName }, nameSuffix = '', suffix = '.xlsx') { return excelName + (nameSuffix ? (nameSuffix.startsWith('_') ? nameSuffix : ('_' + nameSuffix)) : '') + suffix; +} + +function getJapaneseEraDate(date = new Date()) { + const formatter = new Intl.DateTimeFormat('ja-JP-u-ca-japanese', { + era: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }); + const japaneseDate = formatter.format(date); + + const match = japaneseDate.match(/(.+?)(元|\d+)年(\d+)月(\d+)日/); + + if (!match) { + throw new Error("日付の解析に失敗しました。"); + } + + const era = match[1]; + const year = match[2] === "元" ? 1 : parseInt(match[2], 10); + const month = parseInt(match[3], 10); + const day = parseInt(match[4], 10); + + return { + japaneseDate, + era, + year, + month, + day, + westernYear: date.getFullYear() + }; +} + +function convertToWesternYear(year, era) { + return warekiStartYear[era] + year - 1; +} + +function getFormatDateString(date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + + return `${year}-${month}-${day}`; +} + +function loading(show, text) { + if (!loadingEl) { + loadingEl = new Kuc.Spinner({ + container: document.querySelector('.container-gaia'), + text + }); + } else { + loadingEl.close(); + loadingEl.text = text; + } + if (show) { + loadingEl.open(); + } } \ No newline at end of file diff --git a/src/園児別出欠簿入力/BatchCreateHandler.js b/src/園児別出欠簿入力/BatchCreateHandler.js index bd5e6d4..12df43f 100644 --- a/src/園児別出欠簿入力/BatchCreateHandler.js +++ b/src/園児別出欠簿入力/BatchCreateHandler.js @@ -1,8 +1,6 @@ class BatchCreateHandler { - constructor(env, headerSpace) { - BatchCreateHandler.APP_ENV = env; - + constructor(headerSpace) { const elements = createBtnGroupArea('batch-action-area', '出欠簿一括作成', this.handleCreateDate, { btnElId: 'batch-btn', }) @@ -12,7 +10,69 @@ class BatchCreateHandler { headerSpace.appendChild(elements['batch-action-area']); } - handleCreateDate(e) { + handleCreateDate = async (e) => { + loading(true, '出欠簿一括作成中...'); + const api = new KintoneRestAPIClient(); + let result = []; + + try { + result = await api.record.getAllRecordsWithId({ + app: env["園児台帳"].appId, + fields: ["$id", "ユニークキー", "和暦_退園年月日", "年_退園年月日", "月_退園年月日", "日_退園年月日"], + }); + } catch (error) { + // TODO + loading(false); + return; + } + + const today = new Date(); + const todayString = getFormatDateString(today) + const records = []; + for (const record of result) { + if (!this.needCreateData(record, today)) { + continue; + } + records.push(this.createRecord(record, todayString)) + } + console.log(records); + + try { + const addResult = await api.record.addAllRecords({ + app: env["園児別出欠簿入力"].appId, + records + }); + location.reload(); + } catch (error) { + // TODO + } finally { + loading(false); + } + } + + needCreateData = (record, today) => { + const era = record["和暦_退園年月日"].value; + const lastYear = record["年_退園年月日"].value; + const lastMonth = record["月_退園年月日"].value; + const lastDate = record["日_退園年月日"].value; + if (!era || !lastYear || !lastMonth || !lastDate) { + return true; + } + const todayObj = new Date(today); + todayObj.setHours(0, 0, 0, 0); + const lastDateObj = new Date(convertToWesternYear(Number(lastYear), era), Number(lastMonth) - 1, Number(lastDate)); + lastDateObj.setHours(0, 0, 0, 0); + return todayObj.getTime() <= lastDateObj.getTime(); + } + + createRecord = (record, todayString) => { + return { + '登園日': { 'value': todayString }, + '園児ユニークキー': { 'value': record["ユニークキー"].value }, + // '学年': { 'value': record["学年"].value }, + // 'クラス': { 'value': record["クラス"].value }, + // '出席番号': { 'value': record["出席番号"].value }, + } } static getInstance(env, headerSpace) { diff --git a/src/園児別出欠簿入力/ExtractHandler.js b/src/園児別出欠簿入力/ExtractHandler.js index 91a255b..a83076f 100644 --- a/src/園児別出欠簿入力/ExtractHandler.js +++ b/src/園児別出欠簿入力/ExtractHandler.js @@ -1,7 +1,5 @@ class ExtractHandler { - constructor(env, headerSpace) { - ExtractHandler.APP_ENV = env; - + constructor(headerSpace) { const elements = createBtnGroupArea('extract-action-area', '出欠集計表出力', this.handleExtractData, { btnElId: 'extract-btn', yearElId: 'extract-year', @@ -15,13 +13,13 @@ class ExtractHandler { } handleExtractData(e, { year, month, className }) { - const fileName = getExcelName(ExtractHandler.APP_ENV, year + month + '_' + className + '組'); + const fileName = getExcelName(env["園児別出欠簿入力"], year + month + '_' + className + '組'); console.log(fileName); } - static getInstance(env, headerSpace) { + static getInstance(headerSpace) { if (!ExtractHandler.instance) { - ExtractHandler.instance = new ExtractHandler(env, headerSpace); + ExtractHandler.instance = new ExtractHandler(headerSpace); } return ExtractHandler.instance; } diff --git a/src/園児別出欠簿入力/Link1Handler.js b/src/園児別出欠簿入力/Link1Handler.js index c6e0afe..1a41dea 100644 --- a/src/園児別出欠簿入力/Link1Handler.js +++ b/src/園児別出欠簿入力/Link1Handler.js @@ -1,8 +1,6 @@ class Link1Handler { - constructor(env, headerSpace) { - Link1Handler.APP_ENV = env; - + constructor(headerSpace) { const elements = createBtnGroupArea('link-1-action-area', '0,1歳日誌データ連携', this.handleLink, { btnElId: 'link-1-btn', yearElId: 'link-1-year', @@ -17,9 +15,9 @@ class Link1Handler { handleLink(e, { year, month }) { } - static getInstance(env, headerSpace) { + static getInstance(headerSpace) { if (!Link1Handler.instance) { - Link1Handler.instance = new Link1Handler(env, headerSpace); + Link1Handler.instance = new Link1Handler(headerSpace); } return Link1Handler.instance; } diff --git a/src/園児別出欠簿入力/Link2Handler.js b/src/園児別出欠簿入力/Link2Handler.js index 7d8d209..766b87b 100644 --- a/src/園児別出欠簿入力/Link2Handler.js +++ b/src/園児別出欠簿入力/Link2Handler.js @@ -1,8 +1,6 @@ class Link2Handler { - constructor(env, headerSpace) { - Link2Handler.APP_ENV = env; - + constructor(headerSpace) { const elements = createBtnGroupArea('link-2-action-area', '2歳以上日誌データ連携', this.handleLink, { btnElId: 'link-2-btn', yearElId: 'link-2-year', @@ -20,9 +18,9 @@ class Link2Handler { handleLink(e, { year, month, date }) { } - static getInstance(env, headerSpace) { + static getInstance(headerSpace) { if (!Link2Handler.instance) { - Link2Handler.instance = new Link2Handler(env, headerSpace); + Link2Handler.instance = new Link2Handler(headerSpace); } return Link2Handler.instance; } diff --git a/src/園児別出欠簿入力/clock-btn-desktop.js b/src/園児別出欠簿入力/clock-btn-desktop.js index 7a28644..40069fc 100644 --- a/src/園児別出欠簿入力/clock-btn-desktop.js +++ b/src/園児別出欠簿入力/clock-btn-desktop.js @@ -12,10 +12,7 @@ area.appendChild(clockOut); hideSpaceField(['clock-in-btn-area', 'clock-out-btn-area']); - }); - - kintone.events.on('app.record.print.show', (event) => { - hideSpaceField(['clock-in-btn-area', 'clock-out-btn-area']); + return event; }); function dateToFieldInDetail(fieldCode) { @@ -33,12 +30,19 @@ } } + // ------------------- 印刷画面表示時の処理 ------------------- + kintone.events.on('app.record.print.show', (event) => { + hideSpaceField(['clock-in-btn-area', 'clock-out-btn-area']); + return event; + }); + // ------------------- 編集画面表示時の処理 ------------------- kintone.events.on(['app.record.create.show', 'app.record.edit.show'], function (event) { const clockIn = createBtn('clock-in', '登園', dateToFieldInEdit('登園時刻')); kintone.app.record.getSpaceElement('clock-in-btn-area').appendChild(clockIn); const clockOut = createBtn('clock-out', '帰園', dateToFieldInEdit('帰園時刻')); kintone.app.record.getSpaceElement('clock-out-btn-area').appendChild(clockOut); + return event; }); function dateToFieldInEdit(fieldCode) { diff --git a/src/園児別出欠簿入力/main.js b/src/園児別出欠簿入力/main.js index 40f2213..77798c1 100644 --- a/src/園児別出欠簿入力/main.js +++ b/src/園児別出欠簿入力/main.js @@ -6,17 +6,17 @@ const headerSpace = getHeaderSpace('single-label-line'); if (event.viewId === APP_ENV.view["0,1歳日誌データ連携用途"]) { - Link1Handler.getInstance(APP_ENV, headerSpace); + Link1Handler.getInstance(headerSpace); return event; } if (event.viewId === APP_ENV.view["2歳以上日誌データ連携用途"]) { - Link2Handler.getInstance(APP_ENV, headerSpace); + Link2Handler.getInstance(headerSpace); return event; } - BatchCreateHandler.getInstance(APP_ENV, headerSpace); - ExtractHandler.getInstance(APP_ENV, headerSpace); + BatchCreateHandler.getInstance(headerSpace); + ExtractHandler.getInstance(headerSpace); }); })(); \ No newline at end of file diff --git a/src/園児台帳/main.js b/src/園児台帳/main.js new file mode 100644 index 0000000..15a4afd --- /dev/null +++ b/src/園児台帳/main.js @@ -0,0 +1,42 @@ + +(function () { + "use strict"; + const APP_ENV = env["園児台帳"]; + const FIELD_CODE = APP_ENV.uniqueKeyFieldCode; + + // ------------------- 詳細/印刷/編集画面表示時の処理 ------------------- + kintone.events.on(['app.record.detail.show', 'app.record.print.show'], function (event) { + hideField(FIELD_CODE); + return event; + }); + + // ------------------- 編集画面表示時の処理 ------------------- + kintone.events.on(['app.record.edit.show', 'app.record.create.show'], function (event) { + const targetFieldEl = kintone.app.record.getSpaceElement("before-unique-key").parentElement.nextSibling; + targetFieldEl.querySelector('.input-constraints-cybozu').style.display = 'none'; + + event.record[FIELD_CODE]['value'] = "<自動計算:出席番号+学年+クラス+名前>"; + disableField(event.record, FIELD_CODE); + return event; + }); + + + function hideField(fieldCode) { + kintone.app.record.setFieldShown(fieldCode, false); + } + + function disableField(record, fieldCode) { + record[fieldCode]['disabled'] = true; + } + + // ------------------- 編集画面保存時の処理 ------------------- + kintone.events.on(['app.record.create.submit', 'app.record.edit.submit'], function (event) { + event.record[FIELD_CODE]['value'] = getUniqueKey(event.record); + return event; + }); + + function getUniqueKey(record) { + return (record['出席番号']['value'] + '_' + record['学年']['value'] + '_' + record['クラス']['value'] + '_' + record['名前']['value']).substring(0, 64); + } + +})(); \ No newline at end of file