feat(organization): 添加组织相关API并实现助力功能
实现组织搜索、查询已助力和助力功能API 替换原家庭相关接口为组织接口 移除mock数据,使用真实API调用 添加错误处理和状态管理
Showing
2 changed files
with
134 additions
and
79 deletions
src/api/organization.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2025-09-18 17:42:18 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2025-09-18 17:46:03 | ||
| 5 | + * @FilePath: /lls_program/src/api/organization.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +import { fn, fetch } from './fn'; | ||
| 9 | + | ||
| 10 | +const Api = { | ||
| 11 | + SEARCH_INSTITUTION: '/srv/?a=institution&t=search_by_passphrase', | ||
| 12 | + GET_SUPPORTED_INSTITUTION: '/srv/?a=institution&t=get_supported', | ||
| 13 | + SUPPORT_INSTITUTION: '/srv/?a=institution&t=support', | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +/** | ||
| 17 | + * @description: 根据助力码搜索单位 | ||
| 18 | + * @param {*} params | ||
| 19 | + * @param {string} params.passphrase - 助力码 | ||
| 20 | + * @returns {Object} response - 响应对象 | ||
| 21 | + * @returns {string} response.code - 响应状态码 | ||
| 22 | + * @returns {string} response.msg - 响应消息 | ||
| 23 | + * @returns {Object} response.data - 响应数据 | ||
| 24 | + * @returns {number} response.data.id - 单位ID | ||
| 25 | + * @returns {string} response.data.name - 单位名称 | ||
| 26 | + * @returns {string} response.data.avatar_url - 单位头像 | ||
| 27 | + */ | ||
| 28 | + | ||
| 29 | +export const searchInstitutionAPI = (params) => fn(fetch.get(Api.SEARCH_INSTITUTION, params)); | ||
| 30 | + | ||
| 31 | +/** | ||
| 32 | + * @description: 查询我助力的单位 | ||
| 33 | + * @param {*} params | ||
| 34 | + * @returns {Object} response - 响应对象 | ||
| 35 | + * @returns {string} response.code - 响应状态码 | ||
| 36 | + * @returns {string} response.msg - 响应消息 | ||
| 37 | + * @returns {Object} response.data - 响应数据 | ||
| 38 | + * @returns {number} response.data.id - 单位ID | ||
| 39 | + * @returns {string} response.data.name - 单位名称 | ||
| 40 | + * @returns {string} response.data.avatar_url - 单位头像 | ||
| 41 | + */ | ||
| 42 | +export const getSupportedInstitutionAPI = (params) => fn(fetch.get(Api.GET_SUPPORTED_INSTITUTION, params)); | ||
| 43 | + | ||
| 44 | +/** | ||
| 45 | + * @description: 助力单位 | ||
| 46 | + * @param {*} params | ||
| 47 | + * @param {number} params.family_id - 家庭ID | ||
| 48 | + * @returns {Object} response - 响应对象 | ||
| 49 | + * @returns {string} response.code - 响应状态码 | ||
| 50 | + * @returns {string} response.msg - 响应消息 | ||
| 51 | + * @returns {Object} response.data - 响应数据 | ||
| 52 | + */ | ||
| 53 | +export const supportInstitutionAPI = (params) => fn(fetch.post(Api.SUPPORT_INSTITUTION, params)); |
| ... | @@ -91,7 +91,7 @@ import { ref, computed, nextTick, onMounted, watch } from 'vue'; | ... | @@ -91,7 +91,7 @@ import { ref, computed, nextTick, onMounted, watch } from 'vue'; |
| 91 | import Taro from '@tarojs/taro'; | 91 | import Taro from '@tarojs/taro'; |
| 92 | import { My, Check, IconFont } from '@nutui/icons-vue-taro'; | 92 | import { My, Check, IconFont } from '@nutui/icons-vue-taro'; |
| 93 | // 获取接口信息 | 93 | // 获取接口信息 |
| 94 | -import { searchFamilyByPassphraseAPI, joinFamilyAPI } from '@/api/family'; | 94 | +import { searchInstitutionAPI, getSupportedInstitutionAPI, supportInstitutionAPI } from '@/api/organization'; |
| 95 | // 导入主题颜色 | 95 | // 导入主题颜色 |
| 96 | import { THEME_COLORS } from '@/utils/config'; | 96 | import { THEME_COLORS } from '@/utils/config'; |
| 97 | // 默认幼儿园Logo | 97 | // 默认幼儿园Logo |
| ... | @@ -105,75 +105,84 @@ const focusedIndex = ref(-1); | ... | @@ -105,75 +105,84 @@ const focusedIndex = ref(-1); |
| 105 | const matchedKindergarten = ref(null); | 105 | const matchedKindergarten = ref(null); |
| 106 | const isAlreadyJoined = ref(false); | 106 | const isAlreadyJoined = ref(false); |
| 107 | 107 | ||
| 108 | -// Mock 幼儿园数据 | ||
| 109 | -const mockKindergartenData = { | ||
| 110 | - '1234': { | ||
| 111 | - id: 1, | ||
| 112 | - name: '阳光幼儿园', | ||
| 113 | - address: '北京市朝阳区阳光街123号', | ||
| 114 | - logo: 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' | ||
| 115 | - }, | ||
| 116 | - '5678': { | ||
| 117 | - id: 2, | ||
| 118 | - name: '彩虹幼儿园', | ||
| 119 | - address: '北京市海淀区彩虹路456号', | ||
| 120 | - logo: 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' | ||
| 121 | - } | ||
| 122 | -}; | ||
| 123 | - | ||
| 124 | -// Mock 已参与助力榜的数据(模拟用户已经参与的幼儿园) | ||
| 125 | -const mockJoinedKindergarten = { | ||
| 126 | - id: 1, | ||
| 127 | - name: '阳光幼儿园', | ||
| 128 | - address: '北京市朝阳区阳光街123号', | ||
| 129 | - logo: 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' | ||
| 130 | -}; | ||
| 131 | - | ||
| 132 | // 页面加载时检查是否已参与助力榜 | 108 | // 页面加载时检查是否已参与助力榜 |
| 133 | onMounted(() => { | 109 | onMounted(() => { |
| 134 | checkExistingJoinStatus(); | 110 | checkExistingJoinStatus(); |
| 135 | }); | 111 | }); |
| 136 | 112 | ||
| 137 | -// 检查现有参与状态 | 113 | +/** |
| 138 | -const checkExistingJoinStatus = () => { | 114 | + * 检查现有参与状态 |
| 139 | - // 模拟检查用户是否已经参与助力榜 | 115 | + */ |
| 140 | - // 实际应该调用API检查 | 116 | +const checkExistingJoinStatus = async () => { |
| 141 | - const hasJoined = true; // 模拟已参与状态 | 117 | + try { |
| 142 | - | 118 | + const response = await getSupportedInstitutionAPI(); |
| 143 | - if (hasJoined && mockJoinedKindergarten) { | 119 | + if (response.code && response.data) { |
| 144 | - matchedKindergarten.value = mockJoinedKindergarten; | 120 | + // 用户已经助力了某个单位 |
| 121 | + matchedKindergarten.value = { | ||
| 122 | + id: response.data.id, | ||
| 123 | + name: response.data.name, | ||
| 124 | + address: '', // API返回中没有地址字段,使用空字符串 | ||
| 125 | + logo: response.data.avatar_url | ||
| 126 | + }; | ||
| 145 | isAlreadyJoined.value = true; | 127 | isAlreadyJoined.value = true; |
| 146 | // 清空输入框,因为已经参与了 | 128 | // 清空输入框,因为已经参与了 |
| 147 | mottoChars.value = ['', '', '', '']; | 129 | mottoChars.value = ['', '', '', '']; |
| 130 | + } else { | ||
| 131 | + // 用户还没有助力任何单位 | ||
| 132 | + matchedKindergarten.value = null; | ||
| 133 | + isAlreadyJoined.value = false; | ||
| 134 | + } | ||
| 135 | + } catch (error) { | ||
| 136 | + console.error('检查助力状态失败:', error); | ||
| 137 | + // 出错时重置状态 | ||
| 138 | + matchedKindergarten.value = null; | ||
| 139 | + isAlreadyJoined.value = false; | ||
| 148 | } | 140 | } |
| 149 | }; | 141 | }; |
| 150 | 142 | ||
| 151 | -// 检查并匹配幼儿园 | 143 | +/** |
| 152 | -const checkAndMatchKindergarten = () => { | 144 | + * 检查并匹配单位 |
| 145 | + */ | ||
| 146 | +const checkAndMatchKindergarten = async () => { | ||
| 153 | const motto = mottoChars.value.join(''); | 147 | const motto = mottoChars.value.join(''); |
| 154 | 148 | ||
| 155 | if (motto.length === 4) { | 149 | if (motto.length === 4) { |
| 156 | - // 输入完成,查找匹配的幼儿园 | 150 | + try { |
| 157 | - const kindergarten = mockKindergartenData[motto]; | 151 | + // 调用API搜索单位 |
| 158 | - if (kindergarten) { | 152 | + const response = await searchInstitutionAPI({ passphrase: motto }); |
| 159 | - // 检查是否要更换幼儿园 | 153 | + |
| 160 | - if (isAlreadyJoined.value && matchedKindergarten.value && kindergarten.id !== matchedKindergarten.value.id) { | 154 | + if (response.code && response.data) { |
| 161 | - // 用户要更换幼儿园,显示确认提示 | 155 | + const institution = { |
| 162 | - showChangeConfirmation(kindergarten); | 156 | + id: response.data.id, |
| 157 | + name: response.data.name, | ||
| 158 | + address: '', // API返回中没有地址字段,使用空字符串 | ||
| 159 | + logo: response.data.avatar_url | ||
| 160 | + }; | ||
| 161 | + | ||
| 162 | + // 检查是否要更换单位 | ||
| 163 | + if (isAlreadyJoined.value && matchedKindergarten.value && institution.id !== matchedKindergarten.value.id) { | ||
| 164 | + // 用户要更换单位,显示确认提示 | ||
| 165 | + showChangeConfirmation(institution); | ||
| 163 | return; | 166 | return; |
| 164 | } | 167 | } |
| 165 | 168 | ||
| 166 | - matchedKindergarten.value = kindergarten; | 169 | + matchedKindergarten.value = institution; |
| 167 | // 如果之前已经参与,保持已参与状态;否则设为未参与 | 170 | // 如果之前已经参与,保持已参与状态;否则设为未参与 |
| 168 | if (!isAlreadyJoined.value) { | 171 | if (!isAlreadyJoined.value) { |
| 169 | isAlreadyJoined.value = false; | 172 | isAlreadyJoined.value = false; |
| 170 | } | 173 | } |
| 171 | } else { | 174 | } else { |
| 175 | + // 没有找到匹配的单位 | ||
| 176 | + matchedKindergarten.value = null; | ||
| 177 | + isAlreadyJoined.value = false; | ||
| 178 | + } | ||
| 179 | + } catch (error) { | ||
| 180 | + console.error('搜索单位失败:', error); | ||
| 172 | matchedKindergarten.value = null; | 181 | matchedKindergarten.value = null; |
| 173 | isAlreadyJoined.value = false; | 182 | isAlreadyJoined.value = false; |
| 174 | } | 183 | } |
| 175 | } else { | 184 | } else { |
| 176 | - // 输入未完成,如果之前已参与,保持显示已参与的幼儿园 | 185 | + // 输入未完成,如果之前已参与,保持显示已参与的单位 |
| 177 | if (!isAlreadyJoined.value) { | 186 | if (!isAlreadyJoined.value) { |
| 178 | matchedKindergarten.value = null; | 187 | matchedKindergarten.value = null; |
| 179 | } | 188 | } |
| ... | @@ -254,57 +263,50 @@ const handleBlur = (index) => { | ... | @@ -254,57 +263,50 @@ const handleBlur = (index) => { |
| 254 | const isComplete = computed(() => { | 263 | const isComplete = computed(() => { |
| 255 | return mottoChars.value.every((char) => char) && matchedKindergarten.value; | 264 | return mottoChars.value.every((char) => char) && matchedKindergarten.value; |
| 256 | }); | 265 | }); |
| 257 | -const handleConfirmJoin = async () => { | ||
| 258 | - if (!isComplete.value) return; | ||
| 259 | - | ||
| 260 | - // 如果已经参与助力榜,检查是否是更换操作 | ||
| 261 | - if (isAlreadyJoined.value) { | ||
| 262 | - // 检查当前匹配的幼儿园是否与之前参与的不同 | ||
| 263 | - const currentMotto = mottoChars.value.join(''); | ||
| 264 | - const currentKindergarten = mockKindergartenData[currentMotto]; | ||
| 265 | 266 | ||
| 266 | - if (currentKindergarten && mockJoinedKindergarten && currentKindergarten.id === mockJoinedKindergarten.id) { | 267 | +/** |
| 267 | - // 相同的幼儿园,提示已参与 | 268 | + * 处理确认加入 |
| 268 | - Taro.showToast({ | 269 | + */ |
| 269 | - title: '您已经参与该助力榜', | 270 | +const handleConfirmJoin = async () => { |
| 270 | - icon: 'none' | 271 | + if (!matchedKindergarten.value) return; |
| 271 | - }); | ||
| 272 | - return; | ||
| 273 | - } | ||
| 274 | - } | ||
| 275 | 272 | ||
| 276 | try { | 273 | try { |
| 277 | - // 这里应该调用加入助力榜的API | 274 | + // 调用助力API |
| 278 | - // 暂时使用模拟逻辑 | 275 | + const response = await supportInstitutionAPI({ |
| 279 | - console.log('加入助力榜:', { | 276 | + family_id: matchedKindergarten.value.id |
| 280 | - kindergarten: matchedKindergarten.value, | ||
| 281 | - motto: mottoChars.value.join('') | ||
| 282 | }); | 277 | }); |
| 283 | 278 | ||
| 284 | - // 模拟API调用成功 | 279 | + if (response.code) { |
| 280 | + // 助力成功 | ||
| 285 | isAlreadyJoined.value = true; | 281 | isAlreadyJoined.value = true; |
| 286 | - // 更新已参与的幼儿园信息 | ||
| 287 | - mockJoinedKindergarten.id = matchedKindergarten.value.id; | ||
| 288 | - mockJoinedKindergarten.name = matchedKindergarten.value.name; | ||
| 289 | - mockJoinedKindergarten.address = matchedKindergarten.value.address; | ||
| 290 | - mockJoinedKindergarten.logo = matchedKindergarten.value.logo; | ||
| 291 | 282 | ||
| 283 | + // 显示成功提示 | ||
| 292 | Taro.showToast({ | 284 | Taro.showToast({ |
| 293 | - title: '加入成功', | 285 | + title: '助力成功!', |
| 294 | - icon: 'success' | 286 | + icon: 'success', |
| 287 | + duration: 2000 | ||
| 295 | }); | 288 | }); |
| 296 | 289 | ||
| 290 | + // 延迟跳转到排行榜页面 | ||
| 297 | setTimeout(() => { | 291 | setTimeout(() => { |
| 298 | - // 返回上一页 | ||
| 299 | Taro.navigateBack({ | 292 | Taro.navigateBack({ |
| 300 | delta: 1 | 293 | delta: 1 |
| 301 | }); | 294 | }); |
| 302 | - }, 1500); | 295 | + }, 2000); |
| 296 | + } else { | ||
| 297 | + // 助力失败 | ||
| 298 | + Taro.showToast({ | ||
| 299 | + title: response.message || '助力失败,请重试', | ||
| 300 | + icon: 'none', | ||
| 301 | + duration: 2000 | ||
| 302 | + }); | ||
| 303 | + } | ||
| 303 | } catch (error) { | 304 | } catch (error) { |
| 304 | - console.error('加入助力榜失败:', error); | 305 | + console.error('助力操作失败:', error); |
| 305 | Taro.showToast({ | 306 | Taro.showToast({ |
| 306 | - title: '加入失败,请重试', | 307 | + title: '网络错误,请重试', |
| 307 | - icon: 'none' | 308 | + icon: 'none', |
| 309 | + duration: 2000 | ||
| 308 | }); | 310 | }); |
| 309 | } | 311 | } |
| 310 | }; | 312 | }; | ... | ... |
-
Please register or login to post a comment