hookehuyr

feat(organization): 添加组织相关API并实现助力功能

实现组织搜索、查询已助力和助力功能API
替换原家庭相关接口为组织接口
移除mock数据,使用真实API调用
添加错误处理和状态管理
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 };
......