2025/9/26/1:02

This commit is contained in:
2025-09-26 01:02:43 +08:00
parent c1b7a1174d
commit 578d49826b
10 changed files with 199 additions and 49 deletions

View File

@@ -5,7 +5,8 @@
"pages/home/home",
"pages/chat/chat",
"pages/user/user",
"pages/user-login/user-login"
"pages/user-login/user-login",
"pages/articledetail/articledetail"
],
"window": {
"navigationBarTextStyle": "black",

View File

@@ -1,9 +1,15 @@
// app.ts
import { CardData, Comment, IAppOption } from "../typings";
import envConfig from "./env";
App<IAppOption>({
globalData: {
token: "",
userInfo: null
userInfo: null,
rawCardData: [
] ,
processedCardsData: []
},
onLaunch() {
const token = wx.getStorageSync("token");
@@ -11,6 +17,82 @@ App<IAppOption>({
this.globalData.token = token;
}
},
fetchRawCardData(): Promise<CardData[]> {
return new Promise((resolve, reject) => {
wx.request({
url: `${envConfig.apiBaseUrl}/article/get`,
method: "POST",
data: {
uid: "1c3e5a7d-9b1f-4c3a-8e5f-7d9b1c3e5a7d"
},
success: (res) => {
if (res.data && res.data.success && Array.isArray(res.data.data)) {
const rawData = res.data.data as CardData[];
this.globalData.rawCardData = rawData;
const processedData = this.processVoteData(rawData);
this.globalData.processedCardsData = processedData;
console.log("成功获取文评列表:", processedData);
resolve(processedData);
} else {
const error = new Error("接口返回格式不正确");
console.error(error, res);
reject(error);
}
},
fail: (err) => {
console.error("拉取投票数据失败", err);
reject(err);
}
});
});
},
getComments(articleId: number): Promise<Comment[]> {
return new Promise((resolve, reject) => {
wx.request({
url: `${envConfig.apiBaseUrl}/comment/get`,
method: "POST",
data: {
articleId: articleId // int 类型
},
success: (res) => {
const response = res.data as CommentResponse;
if (response.success && Array.isArray(response.data)) {
resolve(response.data);
} else {
reject(new Error(response.message || "获取评论失败"));
}
},
fail: (err) => {
reject(new Error("网络请求失败"));
}
});
});
},
// 处理投票数据的方法
processVoteData(rawData: CardData[]): CardData[] {
return rawData.map(card => {
// 计算每个选项的百分比
const optionsWithPercentage = card.options.map(option => {
const percentage = card.total_voters > 0
? Math.round((option.votes / card.total_voters) * 100)
: 0;
return {
...option,
percentage,
isSelected: false // 初始化选中状态
};
});
return {
...card,
options: optionsWithPercentage
};
});
},
setToken(token: string) {
this.globalData.token = token;
wx.setStorageSync("token", token); // 同步到缓存,持久化存储

View File

@@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

View File

@@ -0,0 +1,26 @@
Component({
data: {
},
lifetimes: {
attached() {
// 组件被挂载时执行
const id = this.properties.id; // 从 properties 获取
this.getCardDetail(id);
}
},
properties: {
id: {
type: String,
value: ''
}
},
methods: {
getCardDetail(id: string) {
console.log("切换到:", id);
},
getArticleComments(id:string){
}
}
})

View File

@@ -0,0 +1,3 @@
<view>
<a></a>
</view>

View File

@@ -1,50 +1,17 @@
Component({
data: {
rawCardData: [
{
"article_id": 123123148,
"article_title": "多选测试",
"vote_type": "multiple",
"total_voters": 3,
"end_time": "2025-10-22 00:59:59",
"is_ended": false,
"publisher_id": "xlsisanasifknfdg",
"create_time": "2025-09-24 23:10:22",
"options": [
{ "id": 69, "name": "Go", "votes": 1, "is_voted": false },
{ "id": 70, "name": "Python", "votes": 1, "is_voted": false },
{ "id": 71, "name": "Rust", "votes": 1, "is_voted": false }
],
"user_has_voted": false,
"user_voted_option_ids": null
},
{
"article_id": 123123149,
"article_title": "单选测试",
"vote_type": "single",
"total_voters": 5,
"end_time": "2025-10-25 12:00:00",
"is_ended": false,
"publisher_id": "another_user_id",
"create_time": "2025-09-25 10:00:00",
"options": [
{ "id": 72, "name": "JavaScript", "votes": 3, "is_voted": false },
{ "id": 73, "name": "TypeScript", "votes": 2, "is_voted": false },
{ "id": 74, "name": "Java", "votes": 0, "is_voted": false }
],
"user_has_voted": false,
"user_voted_option_ids": null
}
],
processedCardsData: [] as any[]
},
lifetimes: {
attached() {
const processedData = this.processVoteData(this.data.rawCardData);
this.setData({
processedCardsData: processedData
// 从全局获取处理后的卡片数据
const app = getApp();
app.fetchRawCardData().then(cards => {
this.setData({ processedCardsData: cards });
}).catch(err => {
wx.showToast({ title: '加载失败', icon: 'none' });
});
}
},
},
methods: {
processVoteData(cards: any[]): any[] {
@@ -152,6 +119,13 @@ Component({
icon: 'success',
duration: 2000
});
},
goToDetail(e: { currentTarget: { dataset: { id: any; }; }; }) {
const id = e.currentTarget.dataset.id;
console.log(id)
wx.navigateTo({
url: `/pages/articledetail/articledetail?id=${id}`,
});
}
}
});

View File

@@ -9,8 +9,12 @@
>
<view class="cards-container">
<block wx:for="{{processedCardsData}}" wx:for-item="card" wx:key="article_id">
<view class="voting-card">
<view class="card-header">
<view class="voting-card"
>
<view class="card-header"
bindtap="goToDetail"
data-id="{{card.article_id}}"
>
<view class="user-info">
<image src="https://picsum.photos/id/100/200/200" mode="widthFix" class="avatar" alt="用户头像"></image>
<view class="user-details">
@@ -23,7 +27,8 @@
<view class="divider"></view>
<view class="vote-title-section">
<view class="vote-title-section" bindtap="goToDetail"
data-id="{{card.article_id}}">
<text class="vote-title">{{card.article_title}} ({{card.vote_type === 'single' ? '单选' : '多选'}})</text>
<text class="vote-desc"></text>
</view>
@@ -63,7 +68,10 @@
</block>
</view>
<view class="vote-stats">
<view class="vote-stats"
bindtap="goToDetail"
data-id="{{card.article_id}}"
>
<text class="stats-text">已有 {{card.total_voters}} 人参与投票</text>
<text class="stats-text">{{card.is_ended ? '已结束' : '剩余 ' + card.end_time}}</text>
</view>

View File

@@ -1,4 +1,7 @@
// index.ts
import { IAppOption } from "../../../typings";
// 获取应用实例
const app = getApp<IAppOption>()
Component({

51
typings/index.d.ts vendored
View File

@@ -1,9 +1,58 @@
/// <reference path="./types/index.d.ts" />
export interface VoteOption {
id: number;
name: string;
votes: number;
is_voted: boolean;
percentage?: number;
isSelected?: boolean;
}
export interface CardData {
article_id: number;
article_title: string;
vote_type: 'single' | 'multiple';
total_voters: number;
end_time: string;
is_ended: boolean;
publisher_id: string;
create_time: string;
options: VoteOption[];
user_has_voted: boolean;
user_voted_option_ids: number[] | null;
}
export interface Comment {
id: number;
article_id: number;
parent_id: number;
content: string;
likes_count: number;
created_at: string;
updated_at: string;
username: string;
avatar_url: string;
replies?: Comment[]; // 子评论可选
}
export interface CommentResponse {
data: Comment[];
message: string;
success: boolean;
}
interface IAppOption {
globalData: {
userInfo?: WechatMiniprogram.CustomUserInfo | null,
token: string
token: string,
rawCardData:CardData[],
processedCardsData:CardData[]
}
userInfoReadyCallback?: WechatMiniprogram.GetUserInfoSuccessCallback,
processVoteData(rawData: CardData[]): CardData[],
fetchRawCardData():void,
getComments(articleId: number):Comment[]
}