|
@@ -0,0 +1,448 @@
|
|
|
+<template>
|
|
|
+
|
|
|
+ <!-- 地理資訊-學校選單-->
|
|
|
+ <el-row style="background-color: #FFFFFF;">
|
|
|
+ <!-- 第一列:父级菜单 -->
|
|
|
+ <el-col :span="8">
|
|
|
+ <div class="list">
|
|
|
+ <div v-for="(item, index) in items"
|
|
|
+ :key="index"
|
|
|
+ :class="{'active': activeIndex === index}"
|
|
|
+ class="list-item"
|
|
|
+ @click="setProvinceActive(index)">
|
|
|
+ {{ item.name }}
|
|
|
+ {{ item.scCnt }} 校
|
|
|
+ {{ item.tchCnt }} 人
|
|
|
+ <el-button size="small" @click.stop="addToColumn3(item, 0)" type="success">加入</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <!-- 第二列:City 菜单 -->
|
|
|
+ <el-col :span="8">
|
|
|
+ <div v-if="activeIndex !== null" class="list">
|
|
|
+ <div v-for="(item, index) in cityItems"
|
|
|
+ :key="index"
|
|
|
+ :class="{'active': activeIndex2 === index}"
|
|
|
+ class="list-item"
|
|
|
+ @click="setCityActive(index)">
|
|
|
+ {{ item.name }}
|
|
|
+ {{ item.scCnt }} 校
|
|
|
+ {{ item.tchCnt }} 人
|
|
|
+ <el-button size="small" @click.stop="addToColumn3(item, 0)" type="success">加入</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <!-- 第三列:子级菜单 -->
|
|
|
+ <el-col :span="8">
|
|
|
+ <div v-if="activeIndex2 !== null" class="list2">
|
|
|
+
|
|
|
+ <!-- 搜尋框 -->
|
|
|
+ <el-input v-model="searchQuery"
|
|
|
+ placeholder="搜尋字串..."
|
|
|
+ size="medium"
|
|
|
+ clearable
|
|
|
+ style="margin-bottom: 10px;"></el-input>
|
|
|
+
|
|
|
+ <!-- 学校列表 -->
|
|
|
+ <div class="list" style="height: 450px;">
|
|
|
+
|
|
|
+ <div v-for="(subItem, subIndex) in filteredSubItems"
|
|
|
+ :key="subIndex"
|
|
|
+ :class="{'active': activeIndex3 === subIndex}"
|
|
|
+ class="list-item"
|
|
|
+ @click="setSchoolActive(subIndex)">
|
|
|
+ {{ subItem.name }}
|
|
|
+ {{ subItem.tchCnt }} 人
|
|
|
+ <el-button size="small" @click.stop="addToColumn3(subItem)" type="success">加入</el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <!-- 第三列:展示加入的项 -->
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-card v-if="false" style="height:600px;">
|
|
|
+ <template #header>
|
|
|
+ <span class="head-text">接收名單</span>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <el-scrollbar style="height: 300px; width:100% ;">
|
|
|
+ <el-list style="display: flex; flex-direction: column;">
|
|
|
+ <el-list-item v-for="(item, index) in column3Items"
|
|
|
+ :key="index"
|
|
|
+ class="el-list-item">
|
|
|
+ {{ item.name }}
|
|
|
+ {{ item.tchCnt }} 人
|
|
|
+
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <!-- 标签部分 -->
|
|
|
+ <el-tag style="background-color: #409eff; color: white;">
|
|
|
+ {{ item.receiveType === 3 ? 'ID' : '学校' }}
|
|
|
+ </el-tag>
|
|
|
+
|
|
|
+ <el-button size="small" @click.stop="removeFromColumn3(index)">
|
|
|
+ <el-icon>
|
|
|
+ <CloseBold />
|
|
|
+ </el-icon>
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </el-list-item>
|
|
|
+ </el-list>
|
|
|
+ </el-scrollbar>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+ import { ref, computed, onMounted, provide, inject, getCurrentInstance } from "vue";
|
|
|
+ import { ElMessage } from "element-plus";
|
|
|
+ import axios from "axios";
|
|
|
+ import { CloseBold } from "@element-plus/icons-vue";
|
|
|
+ import Geos_Info_ID from './geos_info_id.vue'; // 引入组件
|
|
|
+ let { proxy } = getCurrentInstance()
|
|
|
+
|
|
|
+ // 动态获取的地理資訊和学校数据
|
|
|
+ const items = ref([]); // 地理列表(父级菜单)
|
|
|
+ const cityItems = ref([]); // 地理列表2(父级菜单)
|
|
|
+ const subItems = ref([]); // 对应的学校列表(子级菜单)
|
|
|
+
|
|
|
+ // 选中状态
|
|
|
+ const activeIndex = ref(null); // 当前选中的学区
|
|
|
+ const activeIndex2 = ref(null); // 当前选中的City
|
|
|
+ const activeIndex3 = ref(null); // 当前选中的学校
|
|
|
+ const searchQuery = ref(""); // 搜索框内容
|
|
|
+
|
|
|
+ // 从父组件注入的接收名单和更新方法
|
|
|
+ const column3Items = inject("column3Items", ref([])); // 接收名單
|
|
|
+
|
|
|
+ // 取得服務 url
|
|
|
+ const new_msg_host = inject('new_msg_host');
|
|
|
+
|
|
|
+ const selectedValue2 = ref([]);
|
|
|
+
|
|
|
+ const value = ref('School')
|
|
|
+
|
|
|
+ // 選項列表
|
|
|
+ const options = [
|
|
|
+ { value: 'School', label: '學校' },
|
|
|
+ { value: 'ID', label: 'ID' }
|
|
|
+ ]
|
|
|
+
|
|
|
+ // 过滤子级菜单项(学校)
|
|
|
+ const filteredSubItems = computed(() => {
|
|
|
+
|
|
|
+ //由於所有關連到的 ref() 變數,都會觸發,要特別小心別呆
|
|
|
+
|
|
|
+ // 如果正在加载或 subItems 为空,则返回空数组
|
|
|
+ if (isLoading.value || subItems.value.length === 0) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 要由 city id,取得學校資料
|
|
|
+ if (activeIndex2.value === null) return [];
|
|
|
+
|
|
|
+ // 確保 school list 項目有資料
|
|
|
+ if (subItems.value === null) return [];
|
|
|
+
|
|
|
+ const query = searchQuery.value.toLowerCase(); // 获取搜索关键字(小写)
|
|
|
+
|
|
|
+ let filteredItems = []; // 初始化一个空的数组
|
|
|
+ // 过滤学校列表
|
|
|
+ filteredItems = subItems.value.filter((item) => {
|
|
|
+
|
|
|
+ // 打印当前项的信息
|
|
|
+ console.log("当前项:", item);
|
|
|
+
|
|
|
+ return item.name.toLowerCase().includes(query); // 判断 name 是否包含关键字
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ return filteredItems; // 返回筛选后的数组
|
|
|
+ });
|
|
|
+ // 點擊後,取得地理資訊(City)
|
|
|
+ const setProvinceActive = (index) => {
|
|
|
+
|
|
|
+ if (index === null) return;
|
|
|
+
|
|
|
+ activeIndex.value = index; // 设置当前选中的父清單索引
|
|
|
+ activeIndex2.value = null; // 重置第二级子菜单的选中状态
|
|
|
+ searchQuery.value = ""; // 清空子菜单的搜索框
|
|
|
+ //const selectedProvinceId = items.value[index].id; // 获取当前选中省的ID
|
|
|
+
|
|
|
+ const SelectParentId = items.value[index].id; // 获取当前选中的父清單ID
|
|
|
+
|
|
|
+ // 根据选中的父ID取得City List
|
|
|
+ //fetchCityDataByProvince(selectedProvinceId);
|
|
|
+ fetchCityDataByParentId(SelectParentId);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 點擊 City 後, 取得所屬 City 的學校列表
|
|
|
+ const setCityActive = (index) => {
|
|
|
+
|
|
|
+ // 設置當前選中的 City Index
|
|
|
+ activeIndex2.value = index;
|
|
|
+
|
|
|
+ // 取得地理資訊中的 City ID
|
|
|
+ const selectedCityId = cityItems.value[index].id;
|
|
|
+
|
|
|
+ // 取得地理資訊中的 ParentId
|
|
|
+ //const selectProvinceId = items.value[activeIndex.value].id;
|
|
|
+ const ParentId = items.value[activeIndex.value].id;
|
|
|
+
|
|
|
+ // 由地理資訊的 City ID, 取得學校數據
|
|
|
+ //fetchSchoolDataByCity(selectProvinceId, selectedCityId); // 获取学校数据
|
|
|
+ fetchSchoolDataByCity(ParentId, selectedCityId); // 获取学校数据
|
|
|
+ };
|
|
|
+
|
|
|
+ const setSchoolActive = (index) => {
|
|
|
+
|
|
|
+ activeIndex3.value = index;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ const addToColumn3 = (item) => {
|
|
|
+
|
|
|
+ if (!column3Items.value.includes(item)) {
|
|
|
+ column3Items.value.push(item);
|
|
|
+ ElMessage.success(`已加入接收名單`);
|
|
|
+ } else {
|
|
|
+ ElMessage.warning(`已存在接收名單中`);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const removeFromColumn3 = (index) => {
|
|
|
+ column3Items.value.splice(index, 1);
|
|
|
+ };
|
|
|
+
|
|
|
+ let new_msg_station = "";
|
|
|
+ // 一開始加載時,获取地理资讯数据
|
|
|
+ const fetchData = async () => {
|
|
|
+
|
|
|
+ // 設定站台別 (國際站,大陸站) 下面國際站
|
|
|
+ //new_msg_station = ['localhost:5001', 'bi.teammodel.cn', 'bitest.teammodel.cn'].includes(window.location.host) ? 'CN' : 'ORG';
|
|
|
+ new_msg_station = ['bi.teammodel.cn', 'bitest.teammodel.cn'].includes(window.location.host) ? 'CN' : 'ORG';
|
|
|
+ // 記錄站台別
|
|
|
+ provide("new_msg_station", new_msg_station);
|
|
|
+
|
|
|
+ // 預設 type":"school"
|
|
|
+
|
|
|
+ //泛型的設計,最重要的是,一開始的 Request 參數
|
|
|
+
|
|
|
+ // 先取得站台別 (new_msg_station)
|
|
|
+
|
|
|
+ // 依站台別,決定 Resuest 的參數
|
|
|
+
|
|
|
+ const requestData = { showSchool: false }; // 其實不需要輸入參數
|
|
|
+ //const requestData = { showSchool: false }; // 國際站,不需要輸入特定參數,就可以取得國碼
|
|
|
+ //const requestData = { showSchool: false, countryId: "CN" }; // 大陸站,不需要輸入特定參數,就可以取得省分
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+ const response = await proxy.$api.getGeos(requestData);
|
|
|
+ console.log(response, '发送消息返回');
|
|
|
+
|
|
|
+ if (response.state === 200) {
|
|
|
+ //ElMessage.success('消息发送成功');
|
|
|
+ // 在这里执行后续操作,确保数据已获取
|
|
|
+ const data = response.data; // 假设返回的数据在 `response.data` 中
|
|
|
+ console.log(data, '地理資訊');
|
|
|
+ // 后续逻辑处理
|
|
|
+ } else {
|
|
|
+ ElMessage.error('取得資訊失败,状态码错误');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 父清單,在這裡做泛型的區分(站台別不用分,因為皆不需要Request 參數)
|
|
|
+
|
|
|
+ const { state, data } = response;
|
|
|
+ if (state === 200) {
|
|
|
+ items.value = data.map((area) => ({
|
|
|
+ id: area.id,
|
|
|
+ name: area.name,
|
|
|
+ scCnt: area.scCnt,
|
|
|
+ tchCnt: area.tchCnt,
|
|
|
+ countryId: area.id, // 國碼
|
|
|
+ type: "school", //類型 tmid、school
|
|
|
+ receiveType: 2, // receiveType: 0, //1 .學區: area 2 .地理資訊: geo 3 .教育機構類型: unit 4 .學校ID: school 5 .醍摩豆ID: tmid
|
|
|
+ showID_Tag: false,
|
|
|
+ }));
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error("请求失败:", error);
|
|
|
+ ElMessage.error("网络错误,请检查后重试!");
|
|
|
+ }
|
|
|
+ };
|
|
|
+ // 根据选中的父ID取得 City List
|
|
|
+ //const fetchCityDataByProvince = async (provinceId) => {
|
|
|
+ const fetchCityDataByParentId = async (SelectParentId) => {
|
|
|
+
|
|
|
+ // 設定 Request 參數,provinceId (大陸站),先不考慮
|
|
|
+ //const requestData = { showSchool: false, provinceId: provinceId };
|
|
|
+ //const requestData = { showSchool: false, countryId: "CN", provinceId };
|
|
|
+
|
|
|
+ // 設定 Request 參數,countryId (國際站)
|
|
|
+ const requestData = { showSchool: false, countryId: SelectParentId };
|
|
|
+
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+ const response = await proxy.$api.getGeos(requestData);
|
|
|
+ console.log(response, '发送消息返回');
|
|
|
+
|
|
|
+ if (response.state === 200) {
|
|
|
+ //ElMessage.success('消息发送成功');
|
|
|
+ // 在这里执行后续操作,确保数据已获取
|
|
|
+ const data = response.data; // 假设返回的数据在 `response.data` 中
|
|
|
+ console.log(data, '地理資訊');
|
|
|
+ // 后续逻辑处理
|
|
|
+ } else {
|
|
|
+ ElMessage.error('取得資訊失败,状态码错误');
|
|
|
+ }
|
|
|
+
|
|
|
+ //const response = await axios.post("https://localhost:5001/notice/get-geos", requestData);
|
|
|
+
|
|
|
+ const { state, data } = response;
|
|
|
+
|
|
|
+ // 成功取得資料的話,進行資料的 Mapping, 組成 City list
|
|
|
+ if (state === 200) {
|
|
|
+ cityItems.value = data.map((area) => ({
|
|
|
+ id: area.id,
|
|
|
+ name: area.name,
|
|
|
+ scCnt: area.scCnt,
|
|
|
+ tchCnt: area.tchCnt,
|
|
|
+ countryId: SelectParentId,
|
|
|
+ cityId: area.id,
|
|
|
+ type: "school", //類型 tmid、school
|
|
|
+ receiveType: 2, // receiveType: 0, //1 .學區: area 2 .地理資訊: geo 3 .教育機構類型: unit 4 .學校ID: school 5 .醍摩豆ID: tmid
|
|
|
+ showID_Tag: false,
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("请求失败:", error);
|
|
|
+ ElMessage.error("网络错误,请检查后重试!");
|
|
|
+ }
|
|
|
+ };
|
|
|
+ // 取得學校資訊 school list
|
|
|
+ const isLoading = ref(false); // 加载状态
|
|
|
+ //const fetchSchoolDataByCity = async (provinceId, cityId) => {
|
|
|
+ const fetchSchoolDataByCity = async (parentId, cityId) => {
|
|
|
+
|
|
|
+ isLoading.value = true; // 开始加载
|
|
|
+
|
|
|
+ //const requestData = { showSchool: false, countryId: "CN", provinceId, cityId };
|
|
|
+
|
|
|
+ // 國際站 // 參數要填 CountryId : TW,"cityId": "01"
|
|
|
+ const requestData = { countryId: parentId, cityId, cityId };
|
|
|
+
|
|
|
+ //调用 fetchSchoolDataByCity 时,isLoading 置为 true
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+ const response = await proxy.$api.getGeos(requestData);
|
|
|
+ console.log(response, '发送消息返回');
|
|
|
+
|
|
|
+ if (response.state === 200) {
|
|
|
+ //ElMessage.success('消息发送成功');
|
|
|
+ // 在这里执行后续操作,确保数据已获取
|
|
|
+ const data = response.data; // 假设返回的数据在 `response.data` 中
|
|
|
+ console.log(data, '地理資訊');
|
|
|
+ // 后续逻辑处理
|
|
|
+ } else {
|
|
|
+ ElMessage.error('取得資訊失败,状态码错误');
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //const response = await axios.post("https://localhost:5001/notice/get-geos", requestData);
|
|
|
+
|
|
|
+ const { state, data } = response;
|
|
|
+
|
|
|
+ if (state === 200) {
|
|
|
+ subItems.value = data.map((area) => ({
|
|
|
+ id: area.id,
|
|
|
+ name: area.name,
|
|
|
+ scCnt: area.scCnt,
|
|
|
+ tchCnt: area.tchCnt,
|
|
|
+ receiveType: 2, // receiveType: 0, //1 .學區: area 2 .地理資訊: geo 3 .教育機構類型: unit 4 .學校ID: school 5 .醍摩豆ID: tmid
|
|
|
+ showID_Tag: false,
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("请求失败:", error);
|
|
|
+ ElMessage.error("网络错误,请检查后重试!");
|
|
|
+ }
|
|
|
+ finally {
|
|
|
+ isLoading.value = false; // 加载结束
|
|
|
+ //debugger;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 页面加载时自动获取数据
|
|
|
+ onMounted(fetchData);
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+ /* 样式与原程序保持一致 */
|
|
|
+ .list {
|
|
|
+ width: 100%;
|
|
|
+ height: 63vh;
|
|
|
+ border: 1px solid #ccc;
|
|
|
+ padding: 10px;
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .list2 {
|
|
|
+ width: 100%;
|
|
|
+ height: 630px;
|
|
|
+ border: 1px solid #ccc;
|
|
|
+ padding: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .list-item {
|
|
|
+ min-height: 50px;
|
|
|
+ max-height: 100px;
|
|
|
+ line-height: 50px;
|
|
|
+ padding: 0 10px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: background-color 0.3s ease;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .list-item:hover {
|
|
|
+ background-color: #f0f0f0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .list-item.active {
|
|
|
+ background-color: #409eff;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+
|
|
|
+ .head-text {
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-list-item {
|
|
|
+ padding: 5px 10px !important;
|
|
|
+ line-height: 1.5 !important;
|
|
|
+ height: auto !important;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 自定義 select 高度 */
|
|
|
+ .custom-select {
|
|
|
+ line-height: 1; /* 調整外部行高,避免過多空間 */
|
|
|
+ margin: 0; /* 移除外部間距 */
|
|
|
+ }
|
|
|
+</style>
|