diff --git a/hwe/b_processing.php b/hwe/b_processing.php index 5a398fab..3ca90ab5 100644 --- a/hwe/b_processing.php +++ b/hwe/b_processing.php @@ -77,55 +77,30 @@ $cssList = $commandObj->getCSSFiles(); + DB::prefix(), + 'serverID' => UniqueConst::$serverID, + 'commandName' => $commandObj->getName(), + 'turnList' => $turnList, + 'currentCity' => $general->getCityID(), + 'currentNation' => $general->getNationID(), + 'entryInfo' => [$isChiefTurn?'Nation':'General', $commandType] + ])?> + exportJSVars(), false) ?> - - - - - - - + - - - - - - - -
getName() ?>
-
-
- -
- getForm() ?> -
- - - - - -
-
- -
- - +
\ No newline at end of file diff --git a/hwe/css/processing.css b/hwe/css/processing.css deleted file mode 100644 index 00f5ccb7..00000000 --- a/hwe/css/processing.css +++ /dev/null @@ -1,11 +0,0 @@ -#amount { - width: 100px; -} - -#colorType { - width: 150px; -} - -.no-padding .select2-results__option { - padding: 0; -} \ No newline at end of file diff --git a/hwe/func_legacy.php b/hwe/func_legacy.php index a5ac76e2..cb8e750c 100644 --- a/hwe/func_legacy.php +++ b/hwe/func_legacy.php @@ -52,6 +52,18 @@ function bar($per, $h = 7) return $str; } +function JSOptionsForCities(callable $infoCall = null){ + $result = []; + foreach (CityConst::all() as $city) { + $item = [$city->id, $city->name]; + + if($infoCall){ + $item[2] = $infoCall($city); + } + $result[] = $item; + } + return $result; +} function optionsForCities(callable $infoCall = null) { @@ -116,6 +128,15 @@ function closeButton() return "
"; } +function JSCitiesBasedOnDistance(int $cityNo, int $maxDistance = 1): array{ + $distanceList = searchDistance($cityNo, $maxDistance, true); + $result = []; + for ($dist = 1; $dist <= $maxDistance; $dist++) { + $result[$dist] = Util::array_get($distanceList[$dist], []); + } + return $result; +} + function printCitiesBasedOnDistance(int $cityNo, int $maxDistance = 1): string { diff --git a/hwe/func_template.php b/hwe/func_template.php index 8b029dba..6f264148 100644 --- a/hwe/func_template.php +++ b/hwe/func_template.php @@ -225,6 +225,14 @@ function formatName(string $name, int $npc): string return $name; } +function getMapTheme(): string +{ + $db = DB::db(); + $gameStor = KVStorage::getStorage($db, 'game_env'); + $mapTheme = $gameStor->map_theme ?? 'che'; + return $mapTheme; +} + function getMapHtml(?string $mapTheme = null) { $templates = new \League\Plates\Engine(__DIR__ . '/templates'); diff --git a/hwe/sammo/Command/BaseCommand.php b/hwe/sammo/Command/BaseCommand.php index 6a8a2996..b7ce2565 100644 --- a/hwe/sammo/Command/BaseCommand.php +++ b/hwe/sammo/Command/BaseCommand.php @@ -478,6 +478,9 @@ abstract class BaseCommand{ public function getJSPlugins():array { return []; } + public function exportJSVars():array { + return []; + } public function getCSSFiles():array { return []; } diff --git a/hwe/sammo/Command/General/che_강행.php b/hwe/sammo/Command/General/che_강행.php index 392698f0..602f05ef 100644 --- a/hwe/sammo/Command/General/che_강행.php +++ b/hwe/sammo/Command/General/che_강행.php @@ -12,6 +12,7 @@ use \sammo\GameUnitConst; use \sammo\LastTurn; use \sammo\Command; +use function sammo\getMapTheme; use function \sammo\printCitiesBasedOnDistance; use function sammo\tryUniqueItemLottery; @@ -176,6 +177,15 @@ class che_강행 extends Command\GeneralCommand ]; } + public function exportJSVars(): array + { + return [ + 'cities' => \sammo\JSOptionsForCities(), + 'mapTheme' => getMapTheme(), + 'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 3), + ]; + } + public function getForm(): string { $currentCityID = $this->generalObj->getCityID(); @@ -187,7 +197,7 @@ class che_강행 extends Command\GeneralCommand 선택된 도시로 강행합니다.
최대 3칸내 도시로만 강행이 가능합니다.
목록을 선택하거나 도시를 클릭하세요.
- =>

diff --git a/hwe/sammo/Command/General/che_이동.php b/hwe/sammo/Command/General/che_이동.php index db4fc213..acb02e98 100644 --- a/hwe/sammo/Command/General/che_이동.php +++ b/hwe/sammo/Command/General/che_이동.php @@ -184,6 +184,13 @@ class che_이동 extends Command\GeneralCommand ]; } + public function exportJSVars(): array + { + return [ + 'cities' => \sammo\JSOptionsForCities() + ]; + } + public function getForm(): string { $currentCityID = $this->generalObj->getCityID(); diff --git a/hwe/scss/processing.scss b/hwe/scss/processing.scss new file mode 100644 index 00000000..d97ababa --- /dev/null +++ b/hwe/scss/processing.scss @@ -0,0 +1,37 @@ +@import "./common/break_500px.scss"; +@import "./common/bootstrap5.scss"; +@import "./editor_component.scss"; +@import "./common_legacy.scss"; + +#amount { + width: 100px; +} + +#colorType { + width: 150px; +} + +.no-padding .select2-results__option { + padding: 0; +} + + +@include media-breakpoint-up(md) { + #container { + width: 1000px; + margin: 0 auto; + } +} + + +@include media-breakpoint-down(md) { + body { + overflow-x: hidden; + } + + #container { + width: 500px; + margin: 0 auto; + margin-bottom: 100px; + } +} diff --git a/hwe/ts/build_exports.json b/hwe/ts/build_exports.json index d681655e..00a3bd8a 100644 --- a/hwe/ts/build_exports.json +++ b/hwe/ts/build_exports.json @@ -7,7 +7,6 @@ "install": "install.ts", "battle_simulator": "battle_simulator.ts", "recent_map": "recent_map.ts", - "processing": "processing.ts", "select_npc": "select_npc.ts", "betting": "betting.ts", "bossInfo": "bossInfo.ts", @@ -27,7 +26,7 @@ "v_NPCControl": "v_NPCControl.ts", "v_join": "v_join.ts", "v_main": "v_main.ts", - "v_dipcenter": "v_dipcenter.ts" - + "v_dipcenter": "v_dipcenter.ts", + "v_processing": "v_processing.ts" } } \ No newline at end of file diff --git a/hwe/ts/components/MapLegacyTemplate.vue b/hwe/ts/components/MapLegacyTemplate.vue new file mode 100644 index 00000000..762351ff --- /dev/null +++ b/hwe/ts/components/MapLegacyTemplate.vue @@ -0,0 +1,130 @@ + + diff --git a/hwe/ts/defaultSelectCityByMap.ts b/hwe/ts/defaultSelectCityByMap.ts index 15facc51..a3f5078e 100644 --- a/hwe/ts/defaultSelectCityByMap.ts +++ b/hwe/ts/defaultSelectCityByMap.ts @@ -1,21 +1,19 @@ import { reloadWorldMap } from "@/map"; -import { unwrap_any } from "@util/unwrap_any"; + +declare let vueReactive_destCityID: number|undefined; export function defaultSelectCityByMap(): void { - const $target = $("#destCityID"); - console.log('city', $target); void reloadWorldMap({ isDetailMap: false, clickableAll: true, neutralView: true, useCachedMap: true, selectCallback: function (city) { - const currVal = unwrap_any($target.val()); - $target.val(city.id); - $target.trigger("change"); - if ($target.val() === null) { - $target.val(currVal).trigger("change").blur(); + if(vueReactive_destCityID === undefined){ + console.error('아직 초기화 되지 않음'); + return false; } + vueReactive_destCityID = city.id; return false; } }); diff --git a/hwe/ts/defaultSelectNationByMap.ts b/hwe/ts/defaultSelectNationByMap.ts index 21ed28d3..0a3c953a 100644 --- a/hwe/ts/defaultSelectNationByMap.ts +++ b/hwe/ts/defaultSelectNationByMap.ts @@ -1,5 +1,6 @@ import { reloadWorldMap } from "@/map"; -import { unwrap_any } from "@util/unwrap_any"; + +declare let vueReactive_destNationID: number|undefined; export function defaultSelectNationByMap(): void{ const $target = $("#destNationID"); @@ -9,15 +10,12 @@ export function defaultSelectNationByMap(): void{ clickableAll: true, neutralView: true, useCachedMap: true, - selectCallback: (city)=>{ - const currVal = unwrap_any($target.val()); - if(!city.nationID){ + selectCallback: function (city) { + if(typeof vueReactive_destNationID === 'undefined'){ + console.error('아직 초기화 되지 않음'); return false; } - $target.val(city.nationID).trigger("change"); - if ($target.val() === null) { - $target.val(currVal).trigger("change"); - } + vueReactive_destNationID = city.nationID; return false; } }); diff --git a/hwe/ts/map.ts b/hwe/ts/map.ts index 751fbde7..d89eb76d 100644 --- a/hwe/ts/map.ts +++ b/hwe/ts/map.ts @@ -1,11 +1,12 @@ import axios from 'axios'; import $ from 'jquery'; -import { extend, isNumber } from 'lodash'; +import { extend, isNumber, merge } from 'lodash'; import { convColorValue, convertDictById, stringFormat } from '@/common_legacy'; import { InvalidResponse } from '@/defs'; import { unwrap } from "@util/unwrap"; import { convertFormData } from '@util/convertFormData'; import { exportWindow } from '@util/exportWindow'; +import { htmlReady } from './util/htmlReady'; declare const serverNick: string; declare const serverID: string; @@ -57,7 +58,7 @@ type MapCityParsedRegionLevelText = MapCityParsedClickable & { text: string, } -type MapCityParsed = MapCityParsedRegionLevelText; +export type MapCityParsed = MapCityParsedRegionLevelText; type MapCityDrawable = { cityList: MapCityParsed[], @@ -107,7 +108,7 @@ function is_touch_device(): boolean { return mq(query); } -type loadMapOption = { +export type loadMapOption = { isDetailMap?: boolean, //복잡 지도, 단순 지도 clickableAll?: boolean, //어떤 경우든 클릭을 가능하게 함. 해당 동작의 동작 가능성 여부와는 별도. selectCallback?: (city: MapCityParsed) => void, //callback을 지정시 clickable과 관계 없이 해당 함수를 실행. @@ -160,7 +161,7 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world startYear: undefined, }; - option = extend({}, defaultOption, option); + option = merge({}, defaultOption, option); const useCachedMap = option.useCachedMap; const isDetailMap = option.isDetailMap; @@ -671,7 +672,6 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world const $hideCityNameBtn = $world_map.find('.map_toggle_cityname'); if (localStorage.getItem('sam.hideMapCityName') == 'yes') { - console.log('tryHide!'); $world_map.addClass('hide_cityname'); $hideCityNameBtn.addClass('active').attr('aria-pressed', 'true'); } @@ -680,7 +680,6 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world //이전 상태 확인 const state = localStorage.getItem('sam.hideMapCityName') == 'no'; if (state) { - console.log('tryHide!'); $world_map.addClass('hide_cityname'); localStorage.setItem('sam.hideMapCityName', 'yes'); } else { @@ -789,8 +788,12 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world } exportWindow(reloadWorldMap, 'reloadWorldMap'); -$(function ($) { - if (is_touch_device()) { - $('.map_body .map_toggle_single_tap').show(); +htmlReady(function(){ + if( is_touch_device()){ + const target = document.querySelector('.map_body .map_toggle_single_tap') as HTMLElement | null; + if(!target){ + return; + } + target.style.display = 'block'; } -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/hwe/ts/processing.ts b/hwe/ts/processing.ts deleted file mode 100644 index a43a0b50..00000000 --- a/hwe/ts/processing.ts +++ /dev/null @@ -1,300 +0,0 @@ -import $ from 'jquery'; -exportWindow($, '$'); -import { exportWindow } from '@util/exportWindow'; -import axios from 'axios'; -import 'bootstrap'; -import 'select2/dist/js/select2.full.js' -import { setAxiosXMLHttpRequest } from '@util/setAxiosXMLHttpRequest'; -import { convertFormData } from '@util/convertFormData'; -import { InvalidResponse } from '@/defs'; -import { unwrap_any } from '@util/unwrap_any'; -import { DataFormat, IdTextPair, OptionData } from 'select2'; -import { unwrap } from "@util/unwrap"; -import { defaultSelectCityByMap } from '@/defaultSelectCityByMap'; -import { defaultSelectNationByMap } from '@/defaultSelectNationByMap'; -import { colorSelect } from '@/colorSelect'; -import { recruitCrewForm } from '@/recruitCrewForm'; - -declare const isChiefTurn: boolean; -declare const jsPlugins: string[]; - -declare global { - interface Window { - submitAction: () => Promise; - turnList: number[], - command: string, - } -} - -async function reserveTurn(turnList: number[], command: string, arg: Record) { - const target = isChiefTurn ? 'j_set_chief_command.php' : 'j_set_general_command.php'; - - let data: InvalidResponse; - try { - const response = await axios({ - url: target, - responseType: 'json', - method: 'post', - data: convertFormData({ - action: command, - turnList: turnList, - arg: JSON.stringify(arg) - }) - }); - data = response.data; - } - catch (e) { - console.error(e); - alert(`에러가 발생했습니다: ${e}`); - return; - } - - if (!data.result) { - alert(data.reason); - return; - } - - if (!isChiefTurn) { - window.location.href = './'; - } else { - window.location.href = 'b_chiefcenter.php'; - } -} - -$(function ($) { - setAxiosXMLHttpRequest(); - //checkCommandArg 참고 - const availableArgumentList = { - 'string': [ - 'nationName', 'optionText', 'itemType', 'nationType', 'itemCode', 'commandType', - ], - 'int': [ - 'crewType', 'destGeneralID', 'destCityID', 'destNationID', - 'amount', 'colorType', - 'year', 'month', - 'srcArmType', 'destArmType', //숙련전환 전용 - ], - 'boolean': [ - 'isGold', 'buyRice', - ], - 'integerArray': [ - 'destNationIDList', 'destGeneralIDList', 'amountList' - ] - } - - type argTypes = keyof typeof availableArgumentList; - type argValues = string | number | boolean | number[]; - - const handlerList: Record) => argValues> = { - 'string': function ($obj: JQuery) { - return $.trim(unwrap_any($obj.eq(0).val())); - }, - 'int': function ($obj: JQuery) { - return parseInt(unwrap_any($obj.eq(0).val())); - }, - 'boolean': function ($obj: JQuery) { - switch (unwrap_any($obj.eq(0).val()).toLowerCase()) { - case "true": - case "yes": - case "1": - return true; - case "false": - case "no": - case "0": - return false; - default: - throw new Error("Boolean.parse: Cannot convert string to boolean."); - } - }, - 'integerArray': function ($obj: JQuery) { - const result: number[] = []; - $obj.each(function () { - result.push(parseInt(unwrap_any($(this).val()))); - }); - return result; - } - } - - window.submitAction = async function (): Promise { - const argument: Record = {}; - for (const typeName of Object.keys(availableArgumentList) as argTypes[]) { - const typeKeys = availableArgumentList[typeName]; - for (const typeKey of typeKeys) { - let $obj = $('#' + typeKey) as JQuery; - if ($obj.length == 0) { - $obj = $('.' + typeKey); - if ($obj.length == 0) { - continue; - } - } - - argument[typeKey] = handlerList[typeName]($obj); - } - } - - console.log(argument); - await reserveTurn(window.turnList, window.command, argument); - }; - - $('#commonSubmit').on('click', window.submitAction); - - const $colorType = $('#colorType'); - if ($colorType.length) { - $colorType.select2({ - theme: 'bootstrap4', - placeholder: "색상을 선택해 주세요.", - language: "ko", - containerCss: { - display: "inline-block !important", - color: 'white !important', - }, - templateSelection: function (item) { - if ((item as DataFormat).disabled) { - return item.text; - } - const element = (item as OptionData).element; - if (!element) { - throw 'invalid type'; - } - const bgcolor = unwrap(element.dataset.color); - const fgcolor = unwrap(element.dataset.fontColor); - // eslint-disable-next-line no-irregular-whitespace - return $(`  ${item.text}`); - }, - templateResult: function (item) { - if ((item as DataFormat).disabled) { - return item.text; - } - const element = (item as OptionData).element; - if (!element) { - throw 'invalid type'; - } - const bgcolor = unwrap(element.dataset.color); - const fgcolor = unwrap(element.dataset.fontColor); - return $(`
${item.text}
`); - }, - containerCssClass: 'simple-select2-align-center bg-secondary text-secondary', - dropdownCssClass: 'no-padding simple-select2-align-center bg-secondary text-secondary', - }); - } - - const $nationType = $('#nationType'); - if ($nationType.length) { - $nationType.select2({ - theme: 'bootstrap4', - language: "ko", - containerCss: { - display: "inline-block !important", - color: 'white !important', - }, - containerCssClass: 'simple-select2-align-center bg-secondary text-secondary', - dropdownCssClass: 'simple-select2-align-center bg-secondary text-secondary', - }); - } - - const $destCityID = $('#destCityID'); - if ($destCityID.length) { - $destCityID.select2({ - theme: 'bootstrap4', - placeholder: "도시를 선택해 주세요.", - language: "ko", - containerCss: { - display: "inline-block !important", - color: 'white !important', - }, - containerCssClass: 'simple-select2-align-center bg-secondary text-secondary', - dropdownCssClass: 'simple-select2-align-center bg-secondary text-secondary', - }); - } - - const $destNationID = $('#destNationID'); - if ($destNationID.length) { - $destNationID.select2({ - theme: 'bootstrap4', - placeholder: "국가를 선택해 주세요.", - language: "ko", - containerCss: { - display: "inline-block !important", - color: 'white !important', - }, - containerCssClass: 'simple-select2-align-center bg-secondary text-secondary', - dropdownCssClass: 'simple-select2-align-center bg-secondary text-secondary', - }); - } - - const $destGeneralID = $('#destGeneralID'); - if ($destGeneralID.length) { - $destGeneralID.select2({ - theme: 'bootstrap4', - placeholder: "장수를 선택해 주세요.", - language: "ko", - containerCss: { - display: "inline-block !important", - color: 'white !important', - }, - containerCssClass: 'simple-select2-align-center bg-secondary text-secondary', - dropdownCssClass: 'simple-select2-align-center bg-secondary text-secondary', - }); - } - - const $isGold = $('#isGold'); - if ($isGold.length) { - $isGold.select2({ - theme: 'bootstrap4', - placeholder: "분량을 지정해 주세요.", - language: "ko", - containerCss: { - display: "inline-block !important", - color: 'white !important', - }, - minimumResultsForSearch: -1, - containerCssClass: 'simple-select2-align-center bg-secondary text-secondary', - dropdownCssClass: 'simple-select2-align-center bg-secondary text-secondary', - }); - } - - const $amount = $('#amount:not([type=hidden])'); - if ($amount.length) { - $amount.select2({ - theme: 'bootstrap4', - placeholder: "분량을 지정해 주세요.", - allowClear: false, - language: "ko", - containerCss: { - display: "inline-block !important", - color: 'white !important', - }, - tags: true, - sorter: function (items) { - (items as IdTextPair[]).sort(function (lhs, rhs) { - return parseInt(lhs.id) - parseInt(rhs.id); - }) - return items; - }, - containerCssClass: 'simple-select2-align-center bg-secondary text-secondary', - dropdownCssClass: 'select2-only-number simple-select2-align-center bg-secondary text-secondary', - }) - } - - $(document).on('keypress', '.select2-only-number .select2-search__field', function (e) { - $(this).val(unwrap_any($(this).val()).replace(/[^\d].+/, "")); - if ((e.which < 48 || e.which > 57)) { - e.preventDefault(); - } - }); - - const pluginMap:Recordvoid> = { - 'defaultSelectCityByMap': defaultSelectCityByMap, - 'defaultSelectNationByMap': defaultSelectNationByMap, - 'colorSelect': colorSelect, - 'recruitCrewForm': recruitCrewForm, - }; - for (const jsPlugin of jsPlugins) { - if (jsPlugin in pluginMap) { - pluginMap[jsPlugin]() - } - else{ - console.error(`'${jsPlugin}' is not supported`); - } - } -}); \ No newline at end of file diff --git a/hwe/ts/processing/CitiesBasedOnDistance.vue b/hwe/ts/processing/CitiesBasedOnDistance.vue new file mode 100644 index 00000000..89a52a13 --- /dev/null +++ b/hwe/ts/processing/CitiesBasedOnDistance.vue @@ -0,0 +1,37 @@ + + diff --git a/hwe/ts/processing/CitySelect.vue b/hwe/ts/processing/CitySelect.vue new file mode 100644 index 00000000..3f6e62fe --- /dev/null +++ b/hwe/ts/processing/CitySelect.vue @@ -0,0 +1,89 @@ + + diff --git a/hwe/ts/processing/General/che_강행.vue b/hwe/ts/processing/General/che_강행.vue new file mode 100644 index 00000000..ff83253e --- /dev/null +++ b/hwe/ts/processing/General/che_강행.vue @@ -0,0 +1,98 @@ + + + diff --git a/hwe/ts/processing/General/index.ts b/hwe/ts/processing/General/index.ts new file mode 100644 index 00000000..03de46d6 --- /dev/null +++ b/hwe/ts/processing/General/index.ts @@ -0,0 +1 @@ +export { default as che_강행 } from "./che_강행.vue"; \ No newline at end of file diff --git a/hwe/ts/processing/Nation/che_발령.vue b/hwe/ts/processing/Nation/che_발령.vue new file mode 100644 index 00000000..f236d0f0 --- /dev/null +++ b/hwe/ts/processing/Nation/che_발령.vue @@ -0,0 +1,7 @@ + diff --git a/hwe/ts/processing/Nation/che_포상.vue b/hwe/ts/processing/Nation/che_포상.vue new file mode 100644 index 00000000..f236d0f0 --- /dev/null +++ b/hwe/ts/processing/Nation/che_포상.vue @@ -0,0 +1,7 @@ + diff --git a/hwe/ts/processing/Nation/index.ts b/hwe/ts/processing/Nation/index.ts new file mode 100644 index 00000000..19805c88 --- /dev/null +++ b/hwe/ts/processing/Nation/index.ts @@ -0,0 +1,2 @@ +export * as che_발령 from "./che_발령.vue"; +export * as che_포상 from "./che_포상.vue"; \ No newline at end of file diff --git a/hwe/ts/processing/args.ts b/hwe/ts/processing/args.ts new file mode 100644 index 00000000..782e29bc --- /dev/null +++ b/hwe/ts/processing/args.ts @@ -0,0 +1,83 @@ +import { isArray, isBoolean, isInteger, isString } from "lodash"; + + +const stringArgs = [ + 'nationName', 'optionText', 'itemType', 'nationType', 'itemCode', 'commandType', +] as const; +const intArgs = [ + 'crewType', 'destGeneralID', 'destCityID', 'destNationID', + 'amount', 'colorType', + 'year', 'month', + 'srcArmType', 'destArmType', //숙련전환 전용 +] as const; + +const booleanArgs = [ + 'isGold', 'buyRice', +] as const; + +const integerArrayArgs = [ + 'destNationIDList', 'destGeneralIDList', 'amountList' +] as const; + +type StringKeys = typeof stringArgs[number]; +type IntKeys = typeof intArgs[number]; +type BooleanKeys = typeof booleanArgs[number]; +type IntegerArrayKeys = typeof integerArrayArgs[number]; + + +export type Args = { + [key in StringKeys]?: string; +} & { + [key in IntKeys]?: number; + } & { + [key in BooleanKeys]?: boolean; + } & { + [key in IntegerArrayKeys]?: number[] + }; + + + +export function testSubmitArgs(args: Args): true | ['int' | 'string' | 'boolean' | 'int[]', keyof Args, number | string | boolean | number[]] { + for (const intKey of intArgs) { + const testVal = args[intKey]; + if (testVal === undefined) { + continue; + } + if (!isInteger(testVal)) { + return ['int', intKey, testVal]; + } + } + for (const stringKey of stringArgs) { + const testVal = args[stringKey]; + if (testVal === undefined) { + continue; + } + if (!isString(testVal)) { + return ['string', stringKey, testVal]; + } + } + for (const booleanKey of booleanArgs) { + const testVal = args[booleanKey]; + if (testVal === undefined) { + continue; + } + if (!isBoolean(testVal)) { + return ['boolean', booleanKey, testVal]; + } + } + for (const integerArrayKey of integerArrayArgs) { + const testVal = args[integerArrayKey]; + if (testVal === undefined) { + continue; + } + if (!isArray(args[integerArrayKey])) { + return ['int[]', integerArrayKey, testVal]; + } + for (const value of testVal) { + if (!isInteger(value)) { + return ['int[]', integerArrayKey, testVal]; + } + } + } + return true; +} diff --git a/hwe/ts/v_main.ts b/hwe/ts/v_main.ts index 83b6f15a..6496f677 100644 --- a/hwe/ts/v_main.ts +++ b/hwe/ts/v_main.ts @@ -15,7 +15,5 @@ import "@/legacy/main"; import { auto500px } from './util/auto500px'; setAxiosXMLHttpRequest(); - +auto500px(); createApp(PartialReservedCommand).use(BootstrapVue3).component('v-multiselect', Multiselect).mount('#reservedCommandList'); - -auto500px(); \ No newline at end of file diff --git a/hwe/ts/v_processing.ts b/hwe/ts/v_processing.ts new file mode 100644 index 00000000..2cbe54e2 --- /dev/null +++ b/hwe/ts/v_processing.ts @@ -0,0 +1,112 @@ +import '@scss/processing.scss'; + +import $ from 'jquery'; +exportWindow($, '$'); +import { exportWindow } from '@util/exportWindow'; +import axios from 'axios'; +import { setAxiosXMLHttpRequest } from '@util/setAxiosXMLHttpRequest'; +import { convertFormData } from '@util/convertFormData'; +import { InvalidResponse } from '@/defs'; +import { unwrap } from "@util/unwrap"; +import { defaultSelectCityByMap } from '@/defaultSelectCityByMap'; +import { defaultSelectNationByMap } from '@/defaultSelectNationByMap'; +import { colorSelect } from '@/colorSelect'; +import { recruitCrewForm } from '@/recruitCrewForm'; +import BootstrapVue3 from 'bootstrap-vue-3' +import Multiselect from 'vue-multiselect'; +import * as GeneralActions from "@/processing/General"; +import * as NationActions from "@/processing/Nation"; +import { App, createApp } from 'vue'; +import { auto500px } from './util/auto500px'; +import { isString } from 'lodash'; +import { Args, testSubmitArgs } from './processing/args'; + +declare const turnList: number[]; + +setAxiosXMLHttpRequest(); + +async function submitCommand(isChiefTurn: boolean, turnList: number[], command: string, args: Args): Promise { + + + const target = isChiefTurn ? 'j_set_chief_command.php' : 'j_set_general_command.php'; + + try { + const testResult = testSubmitArgs(args); + if (testResult !== true) { + throw new TypeError(`Invalied Type ${testResult[0]}, ${testResult[2]} should be ${testResult[1]}`); + } + console.log('trySubmit', args); + const response = await axios({ + url: target, + responseType: 'json', + method: 'post', + data: convertFormData({ + action: command, + turnList: turnList, + arg: JSON.stringify(args) + }) + }); + const data = response.data as InvalidResponse; + if (!data.result) { + throw data.reason; + } + + if (!isChiefTurn) { + window.location.href = './'; + } else { + window.location.href = 'b_chiefcenter.php'; + } + + return data as unknown as T; + } + catch (e) { + console.error(e); + if (isString(e)) { + alert(e); + } + throw e; + } +} + + + +declare const entryInfo: ['General', keyof typeof GeneralActions] | ['Nation', keyof typeof NationActions]; + +console.log('entry', entryInfo); + +auto500px(); +const app: App | undefined = (function () { + //NOTE: route를 쓴다? + const groupName = entryInfo[0]; + if (groupName == 'General') { + const moduleName = entryInfo[1]; + if (!(moduleName in GeneralActions)) { + console.error(`${moduleName}이 ${groupName}에 없음`); + } + return createApp(GeneralActions[moduleName]); + } + if (groupName == 'Nation') { + const moduleName = entryInfo[1]; + if (!(moduleName in GeneralActions)) { + console.error(`${moduleName}이 ${groupName}에 없음`); + } + return createApp(NationActions[moduleName]); + } + + console.error('알수') + return undefined; +}()); +console.log(app); +if (app === undefined) { + console.error(`모듈이 지정되지 않음`, entryInfo); +} +else { + + const div = unwrap(document.querySelector('#container')); + div.addEventListener('customSubmit', (e: Event) => { + const {detail} = e as unknown as CustomEvent; + void submitCommand(entryInfo[0] == 'Nation', turnList, entryInfo[1], detail); + }, true); + + app.use(BootstrapVue3).component('v-multiselect', Multiselect).mount('#container'); +}