排课优化 #3
No files matched your search
@@ -0,0 +1,17 @@
|
||||
import { readFile, writeFile } from 'node:fs/promises'
|
||||
import { resolve } from 'node:path'
|
||||
|
||||
const [inputFile, outputFile] = process.argv.slice(2)
|
||||
|
||||
if (!inputFile || !outputFile) {
|
||||
throw new Error('用法:node scripts/generate-china-postcode-data.mjs <china_zipcode_adcode.json> <输出文件>')
|
||||
}
|
||||
|
||||
const sourceData = JSON.parse(await readFile(resolve(inputFile), 'utf8'))
|
||||
const rows = sourceData
|
||||
.filter((row) => /^\d{6}$/.test(row.code) && /^\d{6}$/.test(row.zipCode))
|
||||
.map((row) => [row.code, row.zipCode])
|
||||
|
||||
const source = `// 由 tombcato/china-zipcode-data 的 china_zipcode_adcode.json 生成。\n// 上游项目采用 MIT License:https://github.com/tombcato/china-zipcode-data\nexport type ChinaPostcodeRow = readonly [districtCode: string, postcode: string]\n\nexport const chinaPostcodeRows: readonly ChinaPostcodeRow[] = ${JSON.stringify(rows)} as const\n`
|
||||
|
||||
await writeFile(resolve(outputFile), source, 'utf8')
|
||||
Vendored
+1
@@ -12,6 +12,7 @@ export {}
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
AppUpdateManagementPanel: typeof import('./components/AppUpdateManagementPanel.vue')['default']
|
||||
ChinesePostalCodeInput: typeof import('./components/ChinesePostalCodeInput.vue')['default']
|
||||
ElAlert: typeof import('element-plus/es')['ElAlert']
|
||||
ElBadge: typeof import('element-plus/es')['ElBadge']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { nativePlaceCandidatesForPostcode, postcodeForNativePlace } from '../data/nativePlaceLookup'
|
||||
|
||||
const postcode = defineModel<string>({ default: '' })
|
||||
const nativePlace = defineModel<string>('nativePlace', { default: '' })
|
||||
const props = defineProps<{ linked?: boolean }>()
|
||||
|
||||
const candidates = ref<string[]>([])
|
||||
const suggestedPostcode = computed(() => props.linked === false ? undefined : postcodeForNativePlace(nativePlace.value))
|
||||
const lockedPrefix = computed(() => suggestedPostcode.value?.slice(0, 4) ?? '')
|
||||
const suffix = computed({
|
||||
get: () => lockedPrefix.value && postcode.value.startsWith(lockedPrefix.value) ? postcode.value.slice(4, 6) : '',
|
||||
set: (value: string) => { postcode.value = `${lockedPrefix.value}${value.replace(/\D/g, '').slice(0, 2)}` },
|
||||
})
|
||||
|
||||
function normalize(value: string) {
|
||||
return value.replace(/\D/g, '').slice(0, 6)
|
||||
}
|
||||
|
||||
function updatePostcode(value: string) {
|
||||
postcode.value = normalize(value)
|
||||
}
|
||||
|
||||
function selectCandidate(value: string) {
|
||||
nativePlace.value = value
|
||||
candidates.value = []
|
||||
}
|
||||
|
||||
watch(suggestedPostcode, (suggested) => {
|
||||
if (!suggested || props.linked === false) return
|
||||
if (!postcode.value.startsWith(suggested.slice(0, 4))) postcode.value = suggested
|
||||
}, { immediate: true })
|
||||
|
||||
watch(postcode, (value) => {
|
||||
if (props.linked === false || nativePlace.value || lockedPrefix.value) return
|
||||
const matches = nativePlaceCandidatesForPostcode(value)
|
||||
candidates.value = matches
|
||||
if (matches.length === 1) selectCandidate(matches[0])
|
||||
})
|
||||
|
||||
watch(() => props.linked, (linked) => {
|
||||
if (linked === false) candidates.value = []
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="postcode-control">
|
||||
<template v-if="linked !== false && lockedPrefix">
|
||||
<el-input :model-value="lockedPrefix" disabled class="postcode-prefix" aria-label="邮政编码前四位" />
|
||||
<el-input v-model="suffix" inputmode="numeric" maxlength="2" placeholder="后两位" aria-label="邮政编码后两位" />
|
||||
</template>
|
||||
<el-input v-else-if="linked !== false" :model-value="postcode" inputmode="numeric" maxlength="6" placeholder="6位邮政编码" @update:model-value="updatePostcode" />
|
||||
<el-input v-else v-model="postcode" maxlength="20" placeholder="邮政编码" />
|
||||
<el-select v-if="linked !== false && candidates.length > 1" placeholder="请选择匹配的区县" @update:model-value="selectCandidate">
|
||||
<el-option v-for="candidate in candidates" :key="candidate" :label="candidate" :value="candidate" />
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.postcode-control { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; width: 100%; }
|
||||
.postcode-prefix { width: 100%; }
|
||||
.postcode-control:has(.postcode-prefix) { grid-template-columns: 1fr 1fr; }
|
||||
@media (max-width: 480px) { .postcode-control:has(.postcode-prefix) { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
Loaded 3 of 8 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user