排课优化 #3

Merged
biss merged 12 commits from codex/timetable-soft-constraints into master 2026-08-17 19:36:49 +08:00
4 changed files with 65 additions and 15 deletions
Showing only changes of commit 3f685ca068 - Show all commits

No files matched your search

+5 -4
View File
@@ -3,6 +3,7 @@ import { computed, ref, watch } from 'vue'
import { nativePlaceRows } from '../data/nativePlaces.generated'
const model = defineModel<string>({ default: '' })
defineProps<{ disabled?: boolean }>()
type Place = {
id: number
@@ -85,16 +86,16 @@ watch(model, (value) => {
<template>
<div class="native-place-cascader">
<el-select :model-value="selectedIds[0]" :placeholder="levelLabels[0]" filterable clearable @update:model-value="(value) => changeLevel(0, value)">
<el-select :model-value="selectedIds[0]" :placeholder="levelLabels[0]" filterable clearable :disabled="disabled" @update:model-value="(value) => changeLevel(0, value)">
<el-option v-for="option in provinceOptions" :key="option.id" :label="option.name" :value="option.id" />
</el-select>
<el-select :model-value="selectedIds[1]" :placeholder="levelLabels[1]" filterable clearable :disabled="!selectedIds[0]" @update:model-value="(value) => changeLevel(1, value)">
<el-select :model-value="selectedIds[1]" :placeholder="levelLabels[1]" filterable clearable :disabled="disabled || !selectedIds[0]" @update:model-value="(value) => changeLevel(1, value)">
<el-option v-for="option in cityOptions" :key="option.id" :label="option.name" :value="option.id" />
</el-select>
<el-select :model-value="selectedIds[2]" :placeholder="levelLabels[2]" filterable clearable :disabled="!selectedIds[1]" @update:model-value="(value) => changeLevel(2, value)">
<el-select :model-value="selectedIds[2]" :placeholder="levelLabels[2]" filterable clearable :disabled="disabled || !selectedIds[1]" @update:model-value="(value) => changeLevel(2, value)">
<el-option v-for="option in districtOptions" :key="option.id" :label="option.name" :value="option.id" />
</el-select>
<el-select :model-value="selectedIds[3]" :placeholder="levelLabels[3]" filterable clearable :disabled="!selectedIds[2]" @update:model-value="(value) => changeLevel(3, value)">
<el-select :model-value="selectedIds[3]" :placeholder="levelLabels[3]" filterable clearable :disabled="disabled || !selectedIds[2]" @update:model-value="(value) => changeLevel(3, value)">
<el-option v-for="option in townOptions" :key="option.id" :label="option.name" :value="option.id" />
</el-select>
</div>
+15
View File
@@ -0,0 +1,15 @@
export const nationalityOptions = [
'中国', '阿富汗', '阿尔巴尼亚', '阿尔及利亚', '安道尔', '安哥拉', '安提瓜和巴布达', '阿根廷', '亚美尼亚', '澳大利亚', '奥地利', '阿塞拜疆', '巴哈马', '巴林', '孟加拉国', '巴巴多斯', '白俄罗斯', '比利时', '伯利兹', '贝宁', '不丹', '玻利维亚', '波斯尼亚和黑塞哥维那', '博茨瓦纳', '巴西', '文莱', '保加利亚', '布基纳法索', '布隆迪', '佛得角', '柬埔寨', '喀麦隆', '加拿大', '中非', '乍得', '智利', '哥伦比亚', '科摩罗', '刚果共和国', '刚果民主共和国', '哥斯达黎加', '科特迪瓦', '克罗地亚', '古巴', '塞浦路斯', '捷克', '丹麦', '吉布提', '多米尼克', '多米尼加', '厄瓜多尔', '埃及', '萨尔瓦多', '赤道几内亚', '厄立特里亚', '爱沙尼亚', '斯威士兰', '埃塞俄比亚', '斐济', '芬兰', '法国', '加蓬', '冈比亚', '格鲁吉亚', '德国', '加纳', '希腊', '格林纳达', '危地马拉', '几内亚', '几内亚比绍', '圭亚那', '海地', '洪都拉斯', '匈牙利', '冰岛', '印度', '印度尼西亚', '伊朗', '伊拉克', '爱尔兰', '以色列', '意大利', '牙买加', '日本', '约旦', '哈萨克斯坦', '肯尼亚', '基里巴斯', '朝鲜', '韩国', '科威特', '吉尔吉斯斯坦', '老挝', '拉脱维亚', '黎巴嫩', '莱索托', '利比里亚', '利比亚', '列支敦士登', '立陶宛', '卢森堡', '马达加斯加', '马拉维', '马来西亚', '马尔代夫', '马里', '马耳他', '马绍尔群岛', '毛里塔尼亚', '毛里求斯', '墨西哥', '密克罗尼西亚联邦', '摩尔多瓦', '摩纳哥', '蒙古', '黑山', '摩洛哥', '莫桑比克', '缅甸', '纳米比亚', '瑙鲁', '尼泊尔', '荷兰', '新西兰', '尼加拉瓜', '尼日尔', '尼日利亚', '北马其顿', '挪威', '阿曼', '巴基斯坦', '帕劳', '巴拿马', '巴布亚新几内亚', '巴拉圭', '秘鲁', '菲律宾', '波兰', '葡萄牙', '卡塔尔', '罗马尼亚', '俄罗斯', '卢旺达', '圣基茨和尼维斯', '圣卢西亚', '圣文森特和格林纳丁斯', '萨摩亚', '圣马力诺', '圣多美和普林西比', '沙特阿拉伯', '塞内加尔', '塞尔维亚', '塞舌尔', '塞拉利昂', '新加坡', '斯洛伐克', '斯洛文尼亚', '所罗门群岛', '索马里', '南非', '南苏丹', '西班牙', '斯里兰卡', '苏丹', '苏里南', '瑞典', '瑞士', '叙利亚', '塔吉克斯坦', '坦桑尼亚', '泰国', '东帝汶', '多哥', '汤加', '特立尼达和多巴哥', '突尼斯', '土耳其', '土库曼斯坦', '图瓦卢', '乌干达', '乌克兰', '阿联酋', '英国', '美国', '乌拉圭', '乌兹别克斯坦', '瓦努阿图', '梵蒂冈', '委内瑞拉', '越南', '也门', '赞比亚', '津巴布韦', '巴勒斯坦国', '其他',
] as const
export const ethnicityOptions = [
'汉族', '蒙古族', '回族', '藏族', '维吾尔族', '苗族', '彝族', '壮族', '布依族', '朝鲜族', '满族', '侗族', '瑶族', '白族', '土家族', '哈尼族', '哈萨克族', '傣族', '黎族', '傈僳族', '佤族', '畲族', '高山族', '拉祜族', '水族', '东乡族', '纳西族', '景颇族', '柯尔克孜族', '土族', '达斡尔族', '仫佬族', '羌族', '布朗族', '撒拉族', '毛南族', '仡佬族', '锡伯族', '阿昌族', '普米族', '塔吉克族', '怒族', '乌孜别克族', '俄罗斯族', '鄂温克族', '德昂族', '保安族', '裕固族', '京族', '塔塔尔族', '独龙族', '鄂伦春族', '赫哲族', '门巴族', '珞巴族', '基诺族',
] as const
export const politicalStatusOptions = [
'中共党员', '中共预备党员', '共青团员', '民革党员', '民盟盟员', '民建会员', '民进会员', '农工党党员', '致公党党员', '九三学社社员', '台盟盟员', '无党派人士', '群众',
] as const
export function isChineseNationality(nationality: unknown) {
return nationality === '中国'
}
+22 -5
View File
@@ -6,6 +6,7 @@ import http, { apiErrorMessage } from '../api/http'
import { downloadApiFile, importExcel } from '../api/excel'
import { useAuthStore } from '../stores/auth'
import NativePlaceCascader from '../components/NativePlaceCascader.vue'
import { ethnicityOptions, isChineseNationality, nationalityOptions, politicalStatusOptions } from '../data/studentIdentityOptions'
type Registry = 'teachers' | 'students'
interface PageResult {
@@ -151,7 +152,7 @@ function resetForm(row?: any) {
dateOfBirth: '',
englishName: '',
idCardNumber: '',
nationality: '',
nationality: '中国',
ethnicity: '',
politicalStatus: '',
nativePlace: '',
@@ -170,10 +171,26 @@ function resetForm(row?: any) {
biography: '',
notes: '',
}, row ?? {})
form.nationality ||= '中国'
form.specialTags = splitSpecialTags(form.specialTags)
clearChinaOnlyFields()
}
}
const isChinese = () => isChineseNationality(form.nationality)
function clearChinaOnlyFields() {
if (active.value !== 'students') return
if (isChineseNationality(form.nationality)) return
form.ethnicity = ''
form.politicalStatus = ''
form.nativePlace = ''
}
watch(() => form.nationality, () => {
clearChinaOnlyFields()
})
async function load() {
loading.value = true
try {
@@ -632,12 +649,12 @@ watch(active, async () => {
<el-form-item label="证件号码"><el-input v-model="form.idCardNumber" /></el-form-item>
</div>
<div class="form-grid">
<el-form-item label="国籍"><el-input v-model="form.nationality" /></el-form-item>
<el-form-item label="民族"><el-input v-model="form.ethnicity" /></el-form-item>
<el-form-item label="国籍"><el-select v-model="form.nationality" filterable placeholder="请选择国籍"><el-option v-for="option in nationalityOptions" :key="option" :label="option" :value="option" /></el-select></el-form-item>
<el-form-item label="民族"><el-select v-model="form.ethnicity" filterable clearable :disabled="!isChinese()" placeholder="请选择民族"><el-option v-for="option in ethnicityOptions" :key="option" :label="option" :value="option" /></el-select></el-form-item>
</div>
<div class="form-grid">
<el-form-item label="政治面貌"><el-input v-model="form.politicalStatus" /></el-form-item>
<el-form-item label="籍贯"><NativePlaceCascader v-model="form.nativePlace" /></el-form-item>
<el-form-item label="政治面貌"><el-select v-model="form.politicalStatus" filterable clearable :disabled="!isChinese()" placeholder="请选择政治面貌"><el-option v-for="option in politicalStatusOptions" :key="option" :label="option" :value="option" /></el-select></el-form-item>
<el-form-item label="籍贯"><NativePlaceCascader v-model="form.nativePlace" :disabled="!isChinese()" /></el-form-item>
</div>
<div class="form-grid">
<el-form-item label="户籍地址"><el-input v-model="form.householdAddress" /></el-form-item>
Loaded 3 of 4 files, more files were not shown because too many files have changed in this diff. Show more