<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { jsonClone } from '@sa/utils';
import { fetchGetSchoolDetailBySchoolId } from '@/service/api/art/school-detail';
import { fetchCreateSchool, fetchGetSchoolInfo, fetchUpdateSchool } from '@/service/api/art/school';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales';

defineOptions({
  name: 'SchoolOperateDrawer'
});

interface Props {
  /** the type of operation */
  operateType: NaiveUI.TableOperateType;
  /** the edit row data */
  rowData?: Api.Art.School | null;
}

const props = withDefaults(defineProps<Props>(), {
  rowData: null
});

interface Emits {
  (e: 'submitted'): void;
}

const emit = defineEmits<Emits>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const { formRef, validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const submitLoading = ref(false);
const detailLoading = ref(false);
const enrollCodeInputValue = ref('');
const enrollCodeList = ref<string[]>([]);
const schoolTagInputValue = ref('');
const schoolTagList = ref<string[]>([]);
const detailTagInputValue = ref('');
const detailTagList = ref<string[]>([]);

const title = computed(() => {
  const titles: Record<NaiveUI.TableOperateType, string> = {
    add: '新增院校（基础信息 + 详情信息）',
    edit: '编辑院校（基础信息 + 详情信息）'
  };
  return titles[props.operateType];
});

const booleanOptions = [
  { value: 1, label: '是' },
  { value: 0, label: '否' }
];

type Model = Api.Art.SchoolWithDetailOperateParams;

const model = ref<Model>(createDefaultModel());

function createDefaultModel(): Model {
  return {
    school: {
      schoolId: null,
      mainCode: '',
      mainName: '',
      shortName: '',
      province: '',
      city: '',
      district: '',
      universityType: '',
      educationLevel: '',
      schoolNature: '',
      supervisorDept: '',
      remark: ''
    },
    detail: {
      detailId: null,
      schoolId: null,
      introduction: '',
      schoolIcon: '',
      backGround: '',
      address: '',
      contact: '',
      email: '',
      website: '',
      postcode: '',
      establishYear: null,
      campusAreaMu: null,
      libraryCollection: null,
      maleRatio: null,
      femaleRatio: null,
      is985: null,
      is211: null,
      isDoubleFirstClass: null,
      isKeyUniversity: null,
      isPublic: null,
      tags: [],
      studentCount: null,
      teacherCount: null,
      masterPoint: null,
      doctorPoint: null,
      keyMajorCount: null,
      employmentRate: null,
      satisfactionRate: null,
      univId: null,
      masterProportionRate: null,
      abroadProportionRate: null,
      hasRegular: null,
      hasJunior: null,
      hasMaster: null,
      isDoubleHighPlan: null,
      isStrongPlan: null,
      twsdlRank: null,
      xyhRank: null,
      wslRank: null,
      usdaluRank: null,
      qsdaluRank: null,
      combinedScore: null,
      overallRank: null,
      envSatisfaction: null,
      envVote: null,
      liveSatisfaction: null,
      liveVote: null,
      combinedSatisfaction: null,
      combinedVote: null,
      teachers: '',
      scholarship: '',
      grantDesc: '',
      canteen: '',
      dormitory: '',
      masterExplain: '',
      doctorExplain: '',
      remark: ''
    },
    enrollCodes: [],
    schoolTags: []
  };
}

type RuleKey = 'school.mainCode' | 'school.mainName' | 'detail.address' | 'detail.contact';

const rules: Record<RuleKey, App.Global.FormRule> = {
  'school.mainCode': createRequiredRule('学校编码不能为空'),
  'school.mainName': createRequiredRule('学校主名称不能为空'),
  'detail.address': createRequiredRule('学校地址不能为空'),
  'detail.contact': createRequiredRule('联系电话不能为空')
};

function normalizeStringList(values?: string[] | null) {
  if (!values?.length) return [];

  const uniqueValues = new Set<string>();

  values.forEach(value => {
    const normalizedValue = String(value).trim();
    if (normalizedValue) {
      uniqueValues.add(normalizedValue);
    }
  });

  return Array.from(uniqueValues);
}

function isSameStringList(source: string[], target: string[]) {
  if (source.length !== target.length) return false;
  return source.every((value, index) => value === target[index]);
}

function appendValues(inputValue: string, target: string[]) {
  const values = inputValue
    .split(/[,，]/)
    .map(item => item.trim())
    .filter(Boolean);

  if (!values.length) return target;

  return normalizeStringList([...target, ...values]);
}

function addEnrollCodes() {
  enrollCodeList.value = appendValues(enrollCodeInputValue.value, enrollCodeList.value);
  enrollCodeInputValue.value = '';
}

function addSchoolTags() {
  schoolTagList.value = appendValues(schoolTagInputValue.value, schoolTagList.value);
  schoolTagInputValue.value = '';
}

function addDetailTags() {
  detailTagList.value = appendValues(detailTagInputValue.value, detailTagList.value);
  detailTagInputValue.value = '';
}

function syncEnrollCodesToModel() {
  model.value.enrollCodes = normalizeStringList(enrollCodeList.value);
}

function syncSchoolTagsToModel() {
  model.value.schoolTags = normalizeStringList(schoolTagList.value);
}

function syncDetailTagsToModel() {
  model.value.detail.tags = normalizeStringList(detailTagList.value);
}

async function loadEditFormData(schoolId: CommonType.IdType) {
  detailLoading.value = true;

  const [schoolRes, detailRes] = await Promise.all([
    fetchGetSchoolInfo(schoolId),
    fetchGetSchoolDetailBySchoolId(schoolId)
  ]);

  if (!schoolRes.error) {
    const schoolData = jsonClone(schoolRes.data);
    const { enrollCodes = [], schoolTags = [], ...schoolFields } = schoolData;
    Object.assign(model.value.school, schoolFields);
    enrollCodeList.value = normalizeStringList(enrollCodes);
    schoolTagList.value = normalizeStringList(schoolTags);
  } else if (props.rowData) {
    const schoolData = jsonClone(props.rowData);
    const { enrollCodes = [], schoolTags = [], ...schoolFields } = schoolData;
    Object.assign(model.value.school, schoolFields);
    enrollCodeList.value = normalizeStringList(enrollCodes);
    schoolTagList.value = normalizeStringList(schoolTags);
  }

  if (!detailRes.error && detailRes.data) {
    const detailData = jsonClone(detailRes.data);
    Object.assign(model.value.detail, detailData);
    detailTagList.value = normalizeStringList(detailData.tags);
  }

  syncEnrollCodesToModel();
  syncSchoolTagsToModel();
  syncDetailTagsToModel();
  model.value.detail.schoolId = model.value.school.schoolId;
  detailLoading.value = false;
}

async function handleUpdateModelWhenOpen() {
  model.value = createDefaultModel();
  enrollCodeInputValue.value = '';
  enrollCodeList.value = [];
  schoolTagInputValue.value = '';
  schoolTagList.value = [];
  detailTagInputValue.value = '';
  detailTagList.value = [];

  if (props.operateType === 'edit' && props.rowData?.schoolId !== null && props.rowData?.schoolId !== undefined) {
    await loadEditFormData(props.rowData.schoolId);
  } else {
    syncEnrollCodesToModel();
    syncSchoolTagsToModel();
    syncDetailTagsToModel();
  }
}

function closeDrawer() {
  visible.value = false;
}

function getStatusMessage(data: boolean | Api.Art.SchoolWithDetailSubmitStatus) {
  if (typeof data === 'boolean') return null;

  const schoolMsg = data.schoolMessage || data.schoolStatus;
  const detailMsg = data.detailMessage || data.detailStatus;

  if (!schoolMsg && !detailMsg) return null;

  return `基础信息：${schoolMsg || '处理完成'}；详情信息：${detailMsg || '处理完成'}`;
}

async function handleSubmit() {
  await validate();

  submitLoading.value = true;

  const {
    schoolId,
    mainCode,
    mainName,
    shortName,
    province,
    city,
    district,
    universityType,
    educationLevel,
    schoolNature,
    supervisorDept,
    remark: schoolRemark
  } = model.value.school;

  const {
    detailId,
    introduction,
    schoolIcon,
    backGround,
    address,
    contact,
    email,
    website,
    postcode,
    establishYear,
    campusAreaMu,
    libraryCollection,
    maleRatio,
    femaleRatio,
    is985,
    is211,
    isDoubleFirstClass,
    isKeyUniversity,
    isPublic,
    studentCount,
    teacherCount,
    masterPoint,
    doctorPoint,
    keyMajorCount,
    employmentRate,
    satisfactionRate,
    univId,
    masterProportionRate,
    abroadProportionRate,
    hasRegular,
    hasJunior,
    hasMaster,
    isDoubleHighPlan,
    isStrongPlan,
    twsdlRank,
    xyhRank,
    wslRank,
    usdaluRank,
    qsdaluRank,
    combinedScore,
    overallRank,
    envSatisfaction,
    envVote,
    liveSatisfaction,
    liveVote,
    combinedSatisfaction,
    combinedVote,
    teachers,
    scholarship,
    grantDesc,
    canteen,
    dormitory,
    masterExplain,
    doctorExplain,
    remark: detailRemark
  } = model.value.detail;

  const payload: Api.Art.SchoolWithDetailOperateParams = {
    school: {
      schoolId,
      mainCode,
      mainName,
      shortName,
      province,
      city,
      district,
      universityType,
      educationLevel,
      schoolNature,
      supervisorDept,
      remark: schoolRemark
    },
    detail: {
      detailId,
      schoolId,
      introduction,
      schoolIcon,
      backGround,
      address,
      contact,
      email,
      website,
      postcode,
      establishYear,
      campusAreaMu,
      libraryCollection,
      maleRatio,
      femaleRatio,
      is985,
      is211,
      isDoubleFirstClass,
      isKeyUniversity,
      isPublic,
      tags: normalizeStringList(detailTagList.value),
      studentCount,
      teacherCount,
      masterPoint,
      doctorPoint,
      keyMajorCount,
      employmentRate,
      satisfactionRate,
      univId,
      masterProportionRate,
      abroadProportionRate,
      hasRegular,
      hasJunior,
      hasMaster,
      isDoubleHighPlan,
      isStrongPlan,
      twsdlRank,
      xyhRank,
      wslRank,
      usdaluRank,
      qsdaluRank,
      combinedScore,
      overallRank,
      envSatisfaction,
      envVote,
      liveSatisfaction,
      liveVote,
      combinedSatisfaction,
      combinedVote,
      teachers,
      scholarship,
      grantDesc,
      canteen,
      dormitory,
      masterExplain,
      doctorExplain,
      remark: detailRemark
    },
    enrollCodes: normalizeStringList(enrollCodeList.value),
    schoolTags: normalizeStringList(schoolTagList.value)
  };

  let responseData: boolean | Api.Art.SchoolWithDetailSubmitStatus = true;

  if (props.operateType === 'add') {
    const { data, error } = await fetchCreateSchool(payload);
    submitLoading.value = false;
    if (error) return;
    responseData = data ?? true;
  }

  if (props.operateType === 'edit') {
    const { data, error } = await fetchUpdateSchool(payload);
    submitLoading.value = false;
    if (error) return;
    responseData = data ?? true;
  }

  const statusMessage = getStatusMessage(responseData);
  window.$message?.success(
    statusMessage || (props.operateType === 'add' ? $t('common.addSuccess') : $t('common.updateSuccess'))
  );
  closeDrawer();
  emit('submitted');
}

watch(visible, async show => {
  if (show) {
    await handleUpdateModelWhenOpen();
    restoreValidation();
  }
});

watch(
  enrollCodeList,
  codes => {
    const normalizedCodes = normalizeStringList(codes);

    if (!isSameStringList(codes, normalizedCodes)) {
      enrollCodeList.value = normalizedCodes;
      return;
    }

    syncEnrollCodesToModel();
  },
  { deep: true }
);

watch(
  schoolTagList,
  tags => {
    const normalizedTags = normalizeStringList(tags);

    if (!isSameStringList(tags, normalizedTags)) {
      schoolTagList.value = normalizedTags;
      return;
    }

    syncSchoolTagsToModel();
  },
  { deep: true }
);

watch(
  detailTagList,
  tags => {
    const normalizedTags = normalizeStringList(tags);

    if (!isSameStringList(tags, normalizedTags)) {
      detailTagList.value = normalizedTags;
      return;
    }

    syncDetailTagsToModel();
  },
  { deep: true }
);
</script>

<template>
  <NDrawer v-model:show="visible" :title="title" display-directive="show" :width="1120" class="max-w-96%">
    <NDrawerContent :title="title" :native-scrollbar="false" closable>
      <NForm ref="formRef" :model="model" :rules="rules" label-placement="left">
        <NCard title="院校基础信息" size="small" :bordered="true" class="mb-16px">
          <NGrid :cols="24" :x-gap="16">
            <NGi :span="12">
              <NFormItem label="学校编码" path="school.mainCode">
                <NInput v-model:value="model.school.mainCode" placeholder="请输入学校编码（唯一标识，如国标代码）" />
              </NFormItem>
            </NGi>
            <NGi :span="12">
              <NFormItem label="学校主名称" path="school.mainName">
                <NInput v-model:value="model.school.mainName" placeholder="请输入学校主名称（官方全称）" />
              </NFormItem>
            </NGi>
            <NGi :span="12">
              <NFormItem label="学校简称" path="school.shortName">
                <NInput v-model:value="model.school.shortName" placeholder="请输入学校简称（备用）" />
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="院校招生代码" path="enrollCodes">
                <NSpace vertical class="w-full">
                  <NSpace class="w-full" :wrap-item="false">
                    <NInput
                      v-model:value="enrollCodeInputValue"
                      class="flex-1"
                      placeholder="输入招生代码后回车或点击确认，可用逗号一次输入多个"
                      @keydown.enter.prevent="addEnrollCodes"
                    />
                    <NButton type="primary" ghost @click="addEnrollCodes">确认</NButton>
                  </NSpace>
                  <NDynamicTags v-model:value="enrollCodeList" />
                </NSpace>
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="学校标签" path="schoolTags">
                <NSpace vertical class="w-full">
                  <NSpace class="w-full" :wrap-item="false">
                    <NInput
                      v-model:value="schoolTagInputValue"
                      class="flex-1"
                      placeholder="输入学校标签后回车或点击确认，可用逗号一次输入多个"
                      @keydown.enter.prevent="addSchoolTags"
                    />
                    <NButton type="primary" ghost @click="addSchoolTags">确认</NButton>
                  </NSpace>
                  <NDynamicTags v-model:value="schoolTagList" />
                </NSpace>
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="省份" path="school.province">
                <NInput v-model:value="model.school.province" placeholder="请输入省份" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="城市" path="school.city">
                <NInput v-model:value="model.school.city" placeholder="请输入城市" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="区县" path="school.district">
                <NInput v-model:value="model.school.district" placeholder="请输入区县" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="大学类型" path="school.universityType">
                <NInput v-model:value="model.school.universityType" placeholder="请输入大学类型，如综合/工科/艺术" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="学历层次" path="school.educationLevel">
                <NSelect
                  v-model:value="model.school.educationLevel"
                  placeholder="请选择学历层次"
                  :options="[
                    { value: '本科', label: '本科' },
                    { value: '专科', label: '专科' }
                  ]"
                  clearable
                />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="办学性质" path="school.schoolNature">
                <NSelect
                  v-model:value="model.school.schoolNature"
                  placeholder="请选择办学性质"
                  :options="[
                    { value: '公办', label: '公办' },
                    { value: '民办', label: '民办' },
                    { value: '中外合作', label: '中外合作' }
                  ]"
                  clearable
                />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="主管部门" path="school.supervisorDept">
                <NInput v-model:value="model.school.supervisorDept" placeholder="请输入主管部门" />
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="备注" path="school.remark">
                <NInput v-model:value="model.school.remark" :rows="2" type="textarea" placeholder="请输入备注" />
              </NFormItem>
            </NGi>
          </NGrid>
        </NCard>

        <NCard title="院校详情信息" size="small" :bordered="true" :loading="detailLoading">
          <NGrid :cols="24" :x-gap="16">
            <NGi :span="24">
              <NFormItem label="学校详细介绍" path="detail.introduction">
                <NInput
                  v-model:value="model.detail.introduction"
                  :rows="4"
                  type="textarea"
                  placeholder="请输入学校详细介绍"
                />
              </NFormItem>
            </NGi>
            <NGi :span="12">
              <NFormItem label="院校图标" path="detail.schoolIcon">
                <NInput v-model:value="model.detail.schoolIcon" placeholder="请输入院校图标地址" />
              </NFormItem>
            </NGi>
            <NGi :span="12">
              <NFormItem label="学校背景图" path="detail.backGround">
                <NInput v-model:value="model.detail.backGround" placeholder="请输入学校背景图地址" />
              </NFormItem>
            </NGi>
            <NGi :span="12">
              <NFormItem label="官网地址" path="detail.website">
                <NInput v-model:value="model.detail.website" placeholder="请输入官网地址" />
              </NFormItem>
            </NGi>
            <NGi :span="12">
              <NFormItem label="学校地址" path="detail.address">
                <NInput v-model:value="model.detail.address" placeholder="请输入学校地址" />
              </NFormItem>
            </NGi>
            <NGi :span="12">
              <NFormItem label="联系电话" path="detail.contact">
                <NInput v-model:value="model.detail.contact" placeholder="请输入联系电话" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="邮箱" path="detail.email">
                <NInput v-model:value="model.detail.email" placeholder="请输入邮箱" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="邮编" path="detail.postcode">
                <NInput v-model:value="model.detail.postcode" placeholder="请输入邮编" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="外部学校ID" path="detail.univId">
                <NInputNumber v-model:value="model.detail.univId" class="w-full" clearable placeholder="请输入外部学校ID" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="建校年份" path="detail.establishYear">
                <NInputNumber v-model:value="model.detail.establishYear" class="w-full" clearable placeholder="请输入建校年份" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="占地面积(亩)" path="detail.campusAreaMu">
                <NInputNumber
                  v-model:value="model.detail.campusAreaMu"
                  class="w-full"
                  clearable
                  placeholder="请输入占地面积(亩)"
                />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="图书馆藏书量" path="detail.libraryCollection">
                <NInputNumber
                  v-model:value="model.detail.libraryCollection"
                  class="w-full"
                  clearable
                  placeholder="请输入图书馆藏书量"
                />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="男生比例(%)" path="detail.maleRatio">
                <NInputNumber v-model:value="model.detail.maleRatio" class="w-full" clearable placeholder="请输入男生比例" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="女生比例(%)" path="detail.femaleRatio">
                <NInputNumber v-model:value="model.detail.femaleRatio" class="w-full" clearable placeholder="请输入女生比例" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="就业率(%)" path="detail.employmentRate">
                <NInputNumber
                  v-model:value="model.detail.employmentRate"
                  class="w-full"
                  clearable
                  placeholder="请输入就业率"
                />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="满意度(%)" path="detail.satisfactionRate">
                <NInputNumber
                  v-model:value="model.detail.satisfactionRate"
                  class="w-full"
                  clearable
                  placeholder="请输入满意度"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="是否985" path="detail.is985">
                <NSelect v-model:value="model.detail.is985" :options="booleanOptions" clearable placeholder="请选择" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="是否211" path="detail.is211">
                <NSelect v-model:value="model.detail.is211" :options="booleanOptions" clearable placeholder="请选择" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="是否双一流" path="detail.isDoubleFirstClass">
                <NSelect
                  v-model:value="model.detail.isDoubleFirstClass"
                  :options="booleanOptions"
                  clearable
                  placeholder="请选择"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="是否重点大学" path="detail.isKeyUniversity">
                <NSelect
                  v-model:value="model.detail.isKeyUniversity"
                  :options="booleanOptions"
                  clearable
                  placeholder="请选择"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="是否公办" path="detail.isPublic">
                <NSelect v-model:value="model.detail.isPublic" :options="booleanOptions" clearable placeholder="请选择" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="考研率(%)" path="detail.masterProportionRate">
                <NInputNumber
                  v-model:value="model.detail.masterProportionRate"
                  class="w-full"
                  clearable
                  placeholder="请输入考研率"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="出国率(%)" path="detail.abroadProportionRate">
                <NInputNumber
                  v-model:value="model.detail.abroadProportionRate"
                  class="w-full"
                  clearable
                  placeholder="请输入出国率"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="普通本科" path="detail.hasRegular">
                <NSelect v-model:value="model.detail.hasRegular" :options="booleanOptions" clearable placeholder="请选择" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="专科" path="detail.hasJunior">
                <NSelect v-model:value="model.detail.hasJunior" :options="booleanOptions" clearable placeholder="请选择" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="硕士点" path="detail.hasMaster">
                <NSelect v-model:value="model.detail.hasMaster" :options="booleanOptions" clearable placeholder="请选择" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="双高计划" path="detail.isDoubleHighPlan">
                <NSelect
                  v-model:value="model.detail.isDoubleHighPlan"
                  :options="booleanOptions"
                  clearable
                  placeholder="请选择"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="强基计划" path="detail.isStrongPlan">
                <NSelect v-model:value="model.detail.isStrongPlan" :options="booleanOptions" clearable placeholder="请选择" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="泰晤士排名" path="detail.twsdlRank">
                <NInputNumber
                  v-model:value="model.detail.twsdlRank"
                  class="w-full"
                  clearable
                  placeholder="请输入泰晤士排名"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="校友会排名" path="detail.xyhRank">
                <NInputNumber v-model:value="model.detail.xyhRank" class="w-full" clearable placeholder="请输入校友会排名" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="武书连排名" path="detail.wslRank">
                <NInputNumber v-model:value="model.detail.wslRank" class="w-full" clearable placeholder="请输入武书连排名" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="US排名" path="detail.usdaluRank">
                <NInputNumber v-model:value="model.detail.usdaluRank" class="w-full" clearable placeholder="请输入US排名" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="QS排名" path="detail.qsdaluRank">
                <NInputNumber v-model:value="model.detail.qsdaluRank" class="w-full" clearable placeholder="请输入QS排名" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="综合评分" path="detail.combinedScore">
                <NInputNumber
                  v-model:value="model.detail.combinedScore"
                  class="w-full"
                  clearable
                  placeholder="请输入综合评分"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="综合排名" path="detail.overallRank">
                <NInputNumber v-model:value="model.detail.overallRank" class="w-full" clearable placeholder="请输入综合排名" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="环境满意度" path="detail.envSatisfaction">
                <NInputNumber
                  v-model:value="model.detail.envSatisfaction"
                  class="w-full"
                  clearable
                  placeholder="请输入环境满意度"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="环境投票数" path="detail.envVote">
                <NInputNumber v-model:value="model.detail.envVote" class="w-full" clearable placeholder="请输入环境投票数" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="生活满意度" path="detail.liveSatisfaction">
                <NInputNumber
                  v-model:value="model.detail.liveSatisfaction"
                  class="w-full"
                  clearable
                  placeholder="请输入生活满意度"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="生活投票数" path="detail.liveVote">
                <NInputNumber v-model:value="model.detail.liveVote" class="w-full" clearable placeholder="请输入生活投票数" />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="综合满意度" path="detail.combinedSatisfaction">
                <NInputNumber
                  v-model:value="model.detail.combinedSatisfaction"
                  class="w-full"
                  clearable
                  placeholder="请输入综合满意度"
                />
              </NFormItem>
            </NGi>
            <NGi :span="6">
              <NFormItem label="综合投票数" path="detail.combinedVote">
                <NInputNumber
                  v-model:value="model.detail.combinedVote"
                  class="w-full"
                  clearable
                  placeholder="请输入综合投票数"
                />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="学生人数" path="detail.studentCount">
                <NInputNumber v-model:value="model.detail.studentCount" class="w-full" clearable placeholder="请输入学生人数" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="教师人数" path="detail.teacherCount">
                <NInputNumber v-model:value="model.detail.teacherCount" class="w-full" clearable placeholder="请输入教师人数" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="重点专业数" path="detail.keyMajorCount">
                <NInputNumber
                  v-model:value="model.detail.keyMajorCount"
                  class="w-full"
                  clearable
                  placeholder="请输入重点专业数"
                />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="硕士点数量" path="detail.masterPoint">
                <NInputNumber v-model:value="model.detail.masterPoint" class="w-full" clearable placeholder="请输入硕士点数量" />
              </NFormItem>
            </NGi>
            <NGi :span="8">
              <NFormItem label="博士点数量" path="detail.doctorPoint">
                <NInputNumber v-model:value="model.detail.doctorPoint" class="w-full" clearable placeholder="请输入博士点数量" />
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="详情标签" path="detail.tags">
                <NSpace vertical class="w-full">
                  <NSpace class="w-full" :wrap-item="false">
                    <NInput
                      v-model:value="detailTagInputValue"
                      class="flex-1"
                      placeholder="输入详情标签后回车或点击确认，可用逗号一次输入多个"
                      @keydown.enter.prevent="addDetailTags"
                    />
                    <NButton type="primary" ghost @click="addDetailTags">确认</NButton>
                  </NSpace>
                  <NDynamicTags v-model:value="detailTagList" />
                </NSpace>
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="师资力量" path="detail.teachers">
                <NInput v-model:value="model.detail.teachers" :rows="3" type="textarea" placeholder="请输入师资力量描述" />
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="奖学金说明" path="detail.scholarship">
                <NInput v-model:value="model.detail.scholarship" :rows="3" type="textarea" placeholder="请输入奖学金说明" />
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="助学金说明" path="detail.grantDesc">
                <NInput v-model:value="model.detail.grantDesc" :rows="3" type="textarea" placeholder="请输入助学金说明" />
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="食堂说明" path="detail.canteen">
                <NInput v-model:value="model.detail.canteen" :rows="3" type="textarea" placeholder="请输入食堂说明" />
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="宿舍说明" path="detail.dormitory">
                <NInput v-model:value="model.detail.dormitory" :rows="3" type="textarea" placeholder="请输入宿舍说明" />
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="硕士点说明" path="detail.masterExplain">
                <NInput v-model:value="model.detail.masterExplain" :rows="3" type="textarea" placeholder="请输入硕士点说明" />
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="博士点说明" path="detail.doctorExplain">
                <NInput v-model:value="model.detail.doctorExplain" :rows="3" type="textarea" placeholder="请输入博士点说明" />
              </NFormItem>
            </NGi>
            <NGi :span="24">
              <NFormItem label="详情备注" path="detail.remark">
                <NInput v-model:value="model.detail.remark" :rows="2" type="textarea" placeholder="请输入详情备注" />
              </NFormItem>
            </NGi>
          </NGrid>
        </NCard>
      </NForm>
      <template #footer>
        <NSpace :size="16">
          <NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
          <NButton type="primary" :loading="submitLoading" @click="handleSubmit">{{ $t('common.confirm') }}</NButton>
        </NSpace>
      </template>
    </NDrawerContent>
  </NDrawer>
</template>

<style scoped></style>
