入力できる文字数チェック

本文介绍了两种用于检查用户输入字符串长度及格式的JavaScript函数:checkLen用于验证输入是否超出指定的最大长度,同时考虑了全角字符占两字符空间的情况;checkLenAndFormat则进一步确保所有字符均为半角。
 
// 入力できる文字数チェック
// string : 入力した文字、maxLength : 入力できる文字最大数
function checkLen(string, maxLength){
	if(!string || !string.length){return true;}
	var a = 0; 
	for (i = 0; i < string.length; i++) { 
		a += string.charCodeAt(i) > 255 ? 2 : 1; 
	} 
	return a <= maxLength;
}

// 入力できる文字数チェックと半角チェック
// string : 入力した文字、maxLength : 入力できる文字最大数
function checkLenAndFormat(string, maxLength){
	if(!string || !string.length){return true;}
	var a = 0; 
	for (i = 0; i < string.length; i++) { 
		var temp = string.charCodeAt(i);
		if(temp > 255){
			return false;
		}
		a += 1; 
	} 
	return a <= maxLength;
}

下面的代码中【override fun onEvent(event: JafEvent)】报错, 【Conflicting overloads: fun onEvent(event: JafEvent): Unit fun onEvent(event: JafEvent): Unit】,请问应该怎么解决? package jp.or.jaf.syg.feature.jafrsho01.jafrsho01020 import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import dagger.hilt.android.lifecycle.HiltViewModel import jp.or.jaf.syg.core.common.base.JafViewModel import jp.or.jaf.syg.core.common.event.JafAction import jp.or.jaf.syg.core.common.event.JafEvent import jp.or.jaf.syg.core.common.util.JsonUtils import jp.or.jaf.syg.core.designsystem.theme.resources import jp.or.jaf.syg.domain.exception.StandardBusinessException.BusinessException import jp.or.jaf.syg.domain.message.Message import jp.or.jaf.syg.domain.model.jafrshs99.SendIFInfo import jp.or.jaf.syg.domain.model.jafrshs99.SendResultModel import jp.or.jaf.syg.domain.model.request.JAFRSJS05580IF01Req import jp.or.jaf.syg.domain.repository.jafrsho01.IJAFRSHO01020Repository import jp.or.jaf.syg.domain.usecase.jafrsho01.jafrsho01020.IJAFRSHO01020E004UseCase import jp.or.jaf.syg.domain.usecase.jafrshs99.jafrshs99020.IJAFRSHS99020P001UseCase import jp.or.jaf.syg.feature.jafrsho01.jafrsho01020.mappers.toPwModifyInfoInModel import javax.inject.Inject /** * 【画面仕様: JAFRSHO01020】パスワード変更ポップアップのViewModel実装 */ @HiltViewModel class JAFRSHO01020ViewModel @Inject constructor( /** IF送信処理UseCase */ private val jAFRSHS99020P001UseCase: IJAFRSHS99020P001UseCase, /** 確定 - 押下UseCase */ private val jAFRSHO01020E004UseCase: IJAFRSHO01020E004UseCase, /** JAFRSHO01020 パスワード変更リポジトリ */ private val jAFRSHO01020Repository: IJAFRSHO01020Repository, ) : JafViewModel<JAFRSHO01020UiStateData>() { /** * 定数(設計書準拠) */ companion object { /** 最小パスワード桁数 */ private const val MIN_INPUT_LENGTH = 8 /** 最大パスワード桁数 */ private const val MAX_INPUT_LENGTH = 20 /** 連続字制限 */ private const val RENZOKU_SEIGEN_LENGTH: Int = 3 } /** * パスワード表示モード列挙型 * 設計書の定数に対応 */ enum class PasswordDisplayMode { /** マスク表示 */ MASK_DSP, /** パスワード表示 */ PW_DSP } /** * システムイベント処理 * @param event 基本イベントクラス */ @Composable override fun onEvent(event: JafEvent) { when (event) { is JafEvent.Companion.InitializeWithParameters<*> -> { // パラメータ付き初期化(編集画面等) // 画面設計書記載のパラメータ付き初期表示処理 val params = event.params as? JAFRSHO01020Model onPopupDisplay( params?.userCdParam ?: "", params?.henkouMaePwParam ?: "", params?.pwValidKigenDaysParam ?: 0, ) } } } /** * アクション処理 * * @param action 基本アクションクラス */ override fun onAction(action: JafAction) { when (action) { // JAFRSHO01020E002 ×(閉じる) - 押下 is JAFRSHO01020Action.WindowClose -> { onWindowClose() } // JAFRSHO01020E003 閉じる - 押下 is JAFRSHO01020Action.Close -> { onClose() } // JAFRSHO01020E004 確定 - 押下 is JAFRSHO01020Action.Confirm -> { launchWithLoading { onConfirm( action.userCdParam, action.henkouMaePwParam, action.pwValidKigenDaysParam, ) } } // JAFRSHO01020E005 新パスワード表示切替アイコン - 押下 is JAFRSHO01020Action.NewPwDspSwitch -> { onNewPwDspSwitch() } // JAFRSHO01020E006 確認用パスワード表示切替アイコン - 押下 is JAFRSHO01020Action.ConfirmPwDspSwitch -> { onConfirmPwDspSwitch() } // JAFRSHO01020E007 - 新パスワード - is JAFRSHO01020Action.UpdateNewPassword -> { val currentData: JAFRSHO01020UiStateData = getCurrentData() ?: JAFRSHO01020UiStateData() onNewPasswordUpdate(currentData.txtboxNewPw) } // JAFRSHO01020E008 - 確認用パスワード - is JAFRSHO01020Action.UpdateConfirmPassword -> { val currentData: JAFRSHO01020UiStateData = getCurrentData() ?: JAFRSHO01020UiStateData() onConfirmPasswordUpdate(currentData.txtboxConfirmPw) } } } /** * 【処理仕様: JAFRSHO01020E001】画面表示処理 * @param userCdParam ユーザーコード * @param henkouMaePwParam 変更前パスワード * @param pwValidKigenDaysParam パスワード有効期限日数 */ @Composable private fun onPopupDisplay( userCdParam: String, henkouMaePwParam: String, pwValidKigenDaysParam: Int ) { val currentData: JAFRSHO01020UiStateData = getCurrentData() ?: JAFRSHO01020UiStateData() // パラメータ付き初期化を実行 setSuccess( currentData.copy( txtboxNewPw = "", txtboxConfirmPw = "", newPwDspSwitch = PasswordDisplayMode.MASK_DSP, confirmPwDspSwitch = PasswordDisplayMode.MASK_DSP, newPwDspSwitchIcon = MaterialTheme.resources.pwDspButton().toString(), txtboxNewPwDspInfo = VisualTransformation.None, confirmPwDspSwitchIcon = MaterialTheme.resources.pwDspButton().toString(), txtboxConfirmPwDspInfo = VisualTransformation.None ) ) } /** * 【処理仕様: JAFRSHO01020E002】×(閉じる) - 押下処理 */ private fun onWindowClose() { // パスワード変更ポップアップを閉じる navigateBack() } /** * 【処理仕様: JAFRSHO01020E003】閉じる - 押下処理 */ private fun onClose() { // パスワード変更ポップアップを閉じる navigateBack() } /** * 【処理仕様: JAFRSHO01020E004】確定 - 押下処理 * * @param userCdParam ユーザーコード * @param henkouMaePwParam 変更前パスワード * @param pwValidKigenDaysParam パスワード有効期限日数 */ private suspend fun onConfirm( userCdParam: String, henkouMaePwParam: String, pwValidKigenDaysParam: Int ) { // チェックを実施する。 val currentData: JAFRSHO01020UiStateData = getCurrentData() ?: JAFRSHO01020UiStateData() val txtboxNewPw = currentData.txtboxNewPw val txtboxConfirmPw = currentData.txtboxConfirmPw val userCdParam = userCdParam val henkouMaePwParam = henkouMaePwParam // 新パスワード未チェック if (txtboxNewPw.isNullOrEmpty()) { showMessage( Message.JAFRSHO99010WC00005.id, listOf("新パスワード"), onOk = { // 「OK」ボタンを押下した場合、処理を終了する。 } ) return } // 新パスワード桁数チェック if (txtboxNewPw.length < MIN_INPUT_LENGTH || txtboxNewPw.length > MAX_INPUT_LENGTH) { showMessage( Message.JAFRSHO99010WC00110.id, listOf(""), onOk = { // 「OK」ボタンを押下した場合、処理を終了する。 } ) return } // 新パスワード強度チェック // 項目定義.txtboxNewPw(新パスワード)に 引数.userCdParam(ユーザーコード)の連続する3字以上が含まれる var isConsecutiveCharactersFlg = false if (userCdParam.length < RENZOKU_SEIGEN_LENGTH) { isConsecutiveCharactersFlg = false } for (i in 0..userCdParam.length - RENZOKU_SEIGEN_LENGTH) { val sequence = userCdParam.substring(i, i + RENZOKU_SEIGEN_LENGTH) if (txtboxNewPw.contains(sequence, ignoreCase = true)) { isConsecutiveCharactersFlg = true } } // 項目定義.txtboxNewPw(新パスワード).matches(Regex("^[^a-zA-Z0-9]+$")) || // ※(英小字 OR 英大字 OR 数字)が含まれていない // 項目定義.txtboxNewPw(新パスワード)に 引数.userCdParam(ユーザーコード)の連続する3字以上が含まれる // 項目定義.txtboxNewPw(新パスワード) == 引数.henkouMaePwParam(変更前パスワード) if ((txtboxNewPw.matches(Regex("^[^a-zA-Z0-9]+$"))) || isConsecutiveCharactersFlg || txtboxNewPw == henkouMaePwParam ) { showMessage( Message.JAFRSHO99010WC00111.id, listOf(""), onOk = { // 「OK」ボタンを押下した場合、処理を終了する。 } ) return } // 確認用パスワード未チェック if (txtboxConfirmPw.isEmpty()) { showMessage( Message.JAFRSHO99010WC00005.id, listOf("確認用パスワード"), onOk = { // 「OK」ボタンを押下した場合、処理を終了する。 } ) return } // 新パスワードと一致するかチェック if (txtboxNewPw != txtboxConfirmPw) { showMessage( Message.JAFRSHO99010WC00112.id, listOf(""), onOk = { // 「OK」ボタンを押下した場合、処理を終了する。 } ) return } try { val currentData: JAFRSHO01020UiStateData = getCurrentData() ?: JAFRSHO01020UiStateData() val txtboxNewPw = currentData.txtboxNewPw val userCdParam = userCdParam // 車載連携アプリにパスワード世代確認処理を送信する。 val sendIFInfoTmp1: SendIFInfo<JAFRSJS05580IF01Req> = SendIFInfo( cdIf = "JAFRSJS05580IF01", JSON = JAFRSJS05580IF01Req( // ユーザーコード cdUser = userCdParam, // パスワード password = txtboxNewPw, ), serializer = JAFRSJS05580IF01Req.serializer() ) // IF送信処理を実施する。 // TODO IF送信処理に問題がありますので、一旦送信処理コメント val sendResultModelTmp1: SendResultModel = invoke { jAFRSHS99020P001UseCase(sendIFInfoTmp1) } if (sendResultModelTmp1.isIfSendSuccess) { if (JsonUtils.getJsonValue( sendResultModelTmp1.resultJSON, "searchResult", ) == "0" ) { // 何もしない } else { // 業務共通部品(メッセージダイアログ)を呼び出す showMessage( Message.JAFRSHO99010WC00111.id, listOf(""), onOk = { // 「OK」ボタンを押下した場合、処理を終了する。 } ) return } } else { throw BusinessException( messageId = sendResultModelTmp1.messageID, params = listOf(sendResultModelTmp1.errCd), operator = "IF送信処理失敗" ) } // 有効なユーザーか確認用件数を取得する。 // 有効なユーザーであるか確認する。 // 有効なユーザーか確認用件数を取得する。 val validUserCntTmp: Int = jAFRSHO01020Repository.getValidUserCnt(userCdParam) if (validUserCntTmp < 1) { // 業務共通部品(メッセージダイアログ)を呼び出す showMessage( Message.JAFRSHO99010WC00113.id, listOf(""), onOk = { // 「OK」ボタンを押下した場合、処理を終了する。 } ) } else { // 業務共通部品(メッセージダイアログ)を呼び出す showMessage( Message.JAFRSHO99010IC00228.id, // 「いいえ」ボタンを押下した場合 onNo = { // その他操作ボタンポップアップを閉じる。 }, // 「はい」ボタンを押下した場合 onYes = { launchWithLoading("") { val currentData: JAFRSHO01020UiStateData = getCurrentData() ?: JAFRSHO01020UiStateData() val txtboxNewPw = currentData.txtboxNewPw // JAFRSHO01020E004UseCaseに渡す引数を設定する。 val pwModifyInfoInModel = currentData.toPwModifyInfoInModel( userCdParam, txtboxNewPw, pwValidKigenDaysParam ) // パスワード更新処理を行う。 invoke { jAFRSHO01020E004UseCase(pwModifyInfoInModel) } } } ) } // パスワード更新処理を行う。 val pwModifyInfoInModel = currentData.toPwModifyInfoInModel( userCdParam, txtboxNewPw, pwValidKigenDaysParam ) invoke { jAFRSHO01020E004UseCase(pwModifyInfoInModel) } // パスワード変更ポップアップを閉じる navigateBack() } catch (ex: BusinessException) { showMessage( ex.messageId, ex.message?.let { listOf(it) } ?: emptyList() ) return } } /** * 【処理仕様: JAFRSHO01020E005】新パスワード表示切替アイコン - 押下処理 */ private fun onNewPwDspSwitch() { val currentData: JAFRSHO01020UiStateData = getCurrentData() ?: JAFRSHO01020UiStateData() // インスタンス変数.新パスワード表示切替が定数.マスク表示の場合 if (currentData.newPwDspSwitch == PasswordDisplayMode.MASK_DSP) { updateSuccess { currentData -> currentData.copy( newPwDspSwitch = PasswordDisplayMode.PW_DSP, newPwDspSwitchIcon = MaterialTheme.resources.pwDspButton().toString(), txtboxNewPwDspInfo = VisualTransformation.None ) } // インスタンス変数.新パスワード表示切替が定数.パスワード表示の場合 } else if (currentData.newPwDspSwitch == PasswordDisplayMode.PW_DSP) { updateSuccess { currentData -> currentData.copy( newPwDspSwitch = PasswordDisplayMode.MASK_DSP, newPwDspSwitchIcon = MaterialTheme.resources.maskDspButton().toString(), txtboxNewPwDspInfo = PasswordVisualTransformation('※') ) } } else { // 何もしない } } /** * 【処理仕様: JAFRSHO01020E006】確認用パスワード表示切替アイコン - 押下処理 */ private fun onConfirmPwDspSwitch() { val currentData: JAFRSHO01020UiStateData = getCurrentData() ?: JAFRSHO01020UiStateData() // インスタンス変数.確認用パスワード表示切替が定数.マスク表示の場合 if (currentData.confirmPwDspSwitch == PasswordDisplayMode.MASK_DSP) { updateSuccess { currentData -> currentData.copy( confirmPwDspSwitch = PasswordDisplayMode.PW_DSP, confirmPwDspSwitchIcon = MaterialTheme.resources.pwDspButton().toString(), txtboxConfirmPwDspInfo = VisualTransformation.None ) } // インスタンス変数.確認用パスワード表示切替が定数.パスワード表示の場合 } else if (currentData.confirmPwDspSwitch == PasswordDisplayMode.PW_DSP) { updateSuccess { currentData -> currentData.copy( confirmPwDspSwitch = PasswordDisplayMode.MASK_DSP, confirmPwDspSwitchIcon = MaterialTheme.resources.maskDspButton().toString(), txtboxConfirmPwDspInfo = PasswordVisualTransformation('※') ) } } else { // 何もしない } } /** * 新パスワード更新 * @param newPassword 新パスワード */ private fun onNewPasswordUpdate(newPassword: String) { val currentData = getCurrentData() if (currentData != null) { setSuccess(currentData.copy(txtboxNewPw = newPassword)) } } /** * 確認用パスワード更新 * @param confirmPassword 確認用パスワード */ private fun onConfirmPasswordUpdate(confirmPassword: String) { val currentData = getCurrentData() if (currentData != null) { setSuccess(currentData.copy(txtboxConfirmPw = confirmPassword)) } } }
09-30
翻译:### 3.2 Model: `JAFRSAS02010Model.cs` #### **クラス概要** - **行数**: **7,146行** ⚠️ **極めて大きい** - **役割**: ビジネスロジックの実装 - **メソッド数**: 4 (公開メソッド) + 多数のプライベートヘルパーメソッド #### **✅ 良好な点** 1. **処理フロー**: 処理仕様書に忠実に実装されている 2. **定数定義**: マジックナンバーを定数化(例: `CONST_COMMAND_METHOD_0`, `CONST_UPDATEMODE_ADD`) 3. **トランザクション管理**: `using` による DB 接続の確実なクローズ 4. **コメント**: 処理ステップごとにコメントが記載され、仕様書との対応が明確 #### **⚠️ 指摘事項(重要)** 1. **ファイルサイズの肥大化**: 7,146行は保守性を著しく低下させる - **影響範囲**: 変更時の影響範囲が把握困難、マージコンフリクトが頻発する可能性 - **推奨**: 以下のように分割 - `JAFRSAS02010P001_Service.cs` (JAFアプリ受付依頼受信処理) - `JAFRSAS02010P002_Service.cs` (JAFアプリチャット受信処理) - `JAFRSAS02010P003_Service.cs` (JAFアプリチャット対応要求受信処理) - `JAFRSAS02010P004_Service.cs` (JAFアプリチャット対応終了通知受信処理) - `JAFRSAS02010_ValidationService.cs` (共通バリデーション処理) - `JAFRSAS02010_MappingService.cs` (Entity マッピング処理) 2. **メソッドの長大化**: `JafAppUketsukeReceive` メソッドが約4,800行 - **影響範囲**: 単体テストが困難、デバッグ時の可読性低下 - **推奨**: 以下のようにメソッド分割 - `ValidateInputData()` (検証処理) - `ResolveAddressCode()` (住所解析処理) - `CreateUketsukeEntity()` (受付Entity構築) - `RegisterAlertIfNeeded()` (アラート登録処理) - `ExecuteDelayQuery()` (遅延照会処理) 3. **複雑な条件分岐のネスト**: 最大8階層の if ネストが存在 ```csharp if (...) { if (...) { if (...) { if (...) { if (...) { if (...) { if (...) { if (...) { // 処理 } } } } } } } } ``` **推奨**: Early Return パターンの適用 4. **字列リテラルの直接使用**: 定数化されていない字列が多数存在 ```csharp if (value == "0") { ... } // "0" の意味が不明 ``` **推奨**: 定数クラスへの移動 or Enum の使用 5. **Null 安全性**: 800+ プロパティを持つ Entity へのアクセス時、Null チェックが不十分 ```csharp var value = entity.SomeProperty; // entity が null の場合 NullReferenceException ``` **推奨**: Null 条件演算子 `?.` の使用、または C# 8.0 以降の Nullable Reference Types の有効化 #### **❌ 問題** 1. **ログ出の不統一**: 一部の処理でログ出が欠落している可能性 - **影響範囲**: トラブルシューティング時に問題箇所の特定が困難 - **推奨**: 全処理ステップで開始・終了・エラーログを出 2. **エラーメッセージの多言語対応**: 英語のエラーメッセージが一部ハードコーディングされている ```csharp throw new Exception("Invalid parameter"); ``` **推奨**: `JAFCommonMessage.Get()` を使用してメッセージIDから取得
11-18
【概要】 Bitbucketに登録したPKGについてJenkinsにてビルドし、登録元のソフトとリリースするファイルが一致することを確認する。 ① JenkinsビルドJOB作成 ② CHKファイル生成 ③ ビルド後PKG比較 ④ TAG設定 【前提】 ■ベースビルド検証 制御ソフトコードおよび意匠ソフトコードのブランチが作成済みであること ■各イベントでのPKG作成 制御、意匠ともにmasterブランチに対応要件のコードが反映されていること 【手順】 ① JenkinsビルドJOB作成 対象車両のビルドJOBを作成するため、新規ジョブ作成を選択する フォルダを選択し、JOB名をする 作成したJOBフォルダの中で、さらにJOBを作成する 名前をし、フリースタイル・プロジェクトのビルドを選択する 作成されたことを確認 作成したJenkinsJOBを選択、各種項目を設定したのちパラメータ付きビルドを実行する 設定内容については、JenkinsJOB_作成参考資料シート参照 ② CHKファイル生成 ビルド完了後ワークスペースを選択し、PKGをダウンロードする PKGダウンロード後は以下のシートの530-667行目を参照 ビルド手順補足 ③ ビルド後PKG比較 →初回PKG登録時のみ実施する ダウンロード後、SVNからベースにした登録PKGを取得し比較する レポート生成を選択後、ファイル生成場所と形式(CSV)を選択する 以下のような比較結果を作成し、PKG構成ファイルおよび生成物に問題ないことを確認する Box\bxd-meter_develop_honda\01_開発\TZAA\ISB(33FA)\XX_Jenkins立ち上げ\02_PKG作成\ア大 33FA_A332_before_vs_after.xlsx 差分箇所抽出シート:PKG全体を比較し、差分および片方のみ存在するファイルについて確認する dst_配下比較結果シート:リリースしたソフト(CHKファイルや暗号化ファイル)を比較し一致することを確認する ④ TAG設定 ビルド完了後、制御ソフトおよび意匠ソフトのmasterブランチに対してTAGを設定しプッシュする タグを設定したいコミットの上で右クリックし、タグを作成を選択する 黄色の枠でTAGが生成されていることを確認する 設定したTAGをBitbucketへ反映させる ▼を選択し、タグをプッシュを選択する Bitbucketに設定したタグが反映されていることを確認する END
11-18
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值