2025/9/26/1:02
This commit is contained in:
@@ -5,7 +5,8 @@
|
|||||||
"pages/home/home",
|
"pages/home/home",
|
||||||
"pages/chat/chat",
|
"pages/chat/chat",
|
||||||
"pages/user/user",
|
"pages/user/user",
|
||||||
"pages/user-login/user-login"
|
"pages/user-login/user-login",
|
||||||
|
"pages/articledetail/articledetail"
|
||||||
],
|
],
|
||||||
"window": {
|
"window": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
// app.ts
|
// app.ts
|
||||||
|
|
||||||
|
import { CardData, Comment, IAppOption } from "../typings";
|
||||||
|
import envConfig from "./env";
|
||||||
|
|
||||||
App<IAppOption>({
|
App<IAppOption>({
|
||||||
globalData: {
|
globalData: {
|
||||||
token: "",
|
token: "",
|
||||||
userInfo: null
|
userInfo: null,
|
||||||
|
rawCardData: [
|
||||||
|
] ,
|
||||||
|
processedCardsData: []
|
||||||
},
|
},
|
||||||
onLaunch() {
|
onLaunch() {
|
||||||
const token = wx.getStorageSync("token");
|
const token = wx.getStorageSync("token");
|
||||||
@@ -11,6 +17,82 @@ App<IAppOption>({
|
|||||||
this.globalData.token = token;
|
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) {
|
setToken(token: string) {
|
||||||
this.globalData.token = token;
|
this.globalData.token = token;
|
||||||
wx.setStorageSync("token", token); // 同步到缓存,持久化存储
|
wx.setStorageSync("token", token); // 同步到缓存,持久化存储
|
||||||
|
|||||||
4
miniprogram/pages/articledetail/articledetail.json
Normal file
4
miniprogram/pages/articledetail/articledetail.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"component": true,
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
||||||
26
miniprogram/pages/articledetail/articledetail.ts
Normal file
26
miniprogram/pages/articledetail/articledetail.ts
Normal 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){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
3
miniprogram/pages/articledetail/articledetail.wxml
Normal file
3
miniprogram/pages/articledetail/articledetail.wxml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<view>
|
||||||
|
<a></a>
|
||||||
|
</view>
|
||||||
0
miniprogram/pages/articledetail/articledetail.wxss
Normal file
0
miniprogram/pages/articledetail/articledetail.wxss
Normal file
@@ -1,50 +1,17 @@
|
|||||||
Component({
|
Component({
|
||||||
data: {
|
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[]
|
processedCardsData: [] as any[]
|
||||||
},
|
},
|
||||||
lifetimes: {
|
lifetimes: {
|
||||||
attached() {
|
attached() {
|
||||||
const processedData = this.processVoteData(this.data.rawCardData);
|
// 从全局获取处理后的卡片数据
|
||||||
this.setData({
|
const app = getApp();
|
||||||
processedCardsData: processedData
|
app.fetchRawCardData().then(cards => {
|
||||||
|
this.setData({ processedCardsData: cards });
|
||||||
|
}).catch(err => {
|
||||||
|
wx.showToast({ title: '加载失败', icon: 'none' });
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
processVoteData(cards: any[]): any[] {
|
processVoteData(cards: any[]): any[] {
|
||||||
@@ -152,6 +119,13 @@ Component({
|
|||||||
icon: 'success',
|
icon: 'success',
|
||||||
duration: 2000
|
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}`,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -9,8 +9,12 @@
|
|||||||
>
|
>
|
||||||
<view class="cards-container">
|
<view class="cards-container">
|
||||||
<block wx:for="{{processedCardsData}}" wx:for-item="card" wx:key="article_id">
|
<block wx:for="{{processedCardsData}}" wx:for-item="card" wx:key="article_id">
|
||||||
<view class="voting-card">
|
<view class="voting-card"
|
||||||
<view class="card-header">
|
>
|
||||||
|
<view class="card-header"
|
||||||
|
bindtap="goToDetail"
|
||||||
|
data-id="{{card.article_id}}"
|
||||||
|
>
|
||||||
<view class="user-info">
|
<view class="user-info">
|
||||||
<image src="https://picsum.photos/id/100/200/200" mode="widthFix" class="avatar" alt="用户头像"></image>
|
<image src="https://picsum.photos/id/100/200/200" mode="widthFix" class="avatar" alt="用户头像"></image>
|
||||||
<view class="user-details">
|
<view class="user-details">
|
||||||
@@ -23,7 +27,8 @@
|
|||||||
|
|
||||||
<view class="divider"></view>
|
<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-title">{{card.article_title}} ({{card.vote_type === 'single' ? '单选' : '多选'}})</text>
|
||||||
<text class="vote-desc"></text>
|
<text class="vote-desc"></text>
|
||||||
</view>
|
</view>
|
||||||
@@ -63,7 +68,10 @@
|
|||||||
</block>
|
</block>
|
||||||
</view>
|
</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.total_voters}} 人参与投票</text>
|
||||||
<text class="stats-text">{{card.is_ended ? '已结束' : '剩余 ' + card.end_time}}</text>
|
<text class="stats-text">{{card.is_ended ? '已结束' : '剩余 ' + card.end_time}}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
// index.ts
|
// index.ts
|
||||||
|
|
||||||
|
import { IAppOption } from "../../../typings";
|
||||||
|
|
||||||
// 获取应用实例
|
// 获取应用实例
|
||||||
const app = getApp<IAppOption>()
|
const app = getApp<IAppOption>()
|
||||||
Component({
|
Component({
|
||||||
|
|||||||
51
typings/index.d.ts
vendored
51
typings/index.d.ts
vendored
@@ -1,9 +1,58 @@
|
|||||||
/// <reference path="./types/index.d.ts" />
|
/// <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 {
|
interface IAppOption {
|
||||||
globalData: {
|
globalData: {
|
||||||
userInfo?: WechatMiniprogram.CustomUserInfo | null,
|
userInfo?: WechatMiniprogram.CustomUserInfo | null,
|
||||||
token: string
|
token: string,
|
||||||
|
rawCardData:CardData[],
|
||||||
|
processedCardsData:CardData[]
|
||||||
}
|
}
|
||||||
userInfoReadyCallback?: WechatMiniprogram.GetUserInfoSuccessCallback,
|
userInfoReadyCallback?: WechatMiniprogram.GetUserInfoSuccessCallback,
|
||||||
|
processVoteData(rawData: CardData[]): CardData[],
|
||||||
|
fetchRawCardData():void,
|
||||||
|
getComments(articleId: number):Comment[]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user