commit
aff4457858
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Eslint config file
|
||||||
|
* Documentation: https://eslint.org/docs/user-guide/configuring/
|
||||||
|
* Install the Eslint extension before using this feature.
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
es6: true,
|
||||||
|
browser: true,
|
||||||
|
node: true,
|
||||||
|
},
|
||||||
|
ecmaFeatures: {
|
||||||
|
modules: true,
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2018,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
globals: {
|
||||||
|
wx: true,
|
||||||
|
App: true,
|
||||||
|
Page: true,
|
||||||
|
getCurrentPages: true,
|
||||||
|
getApp: true,
|
||||||
|
Component: true,
|
||||||
|
requirePlugin: true,
|
||||||
|
requireMiniProgram: true,
|
||||||
|
},
|
||||||
|
// extends: 'eslint:recommended',
|
||||||
|
rules: {},
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
// app.js
|
||||||
|
App({
|
||||||
|
onLaunch() {
|
||||||
|
// 监听页面不存在的情况
|
||||||
|
wx.onPageNotFound(function(res) {
|
||||||
|
console.error('Page not found:', res);
|
||||||
|
wx.redirectTo({
|
||||||
|
url: 'pages/participated/participated'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取本地存储的用户信息
|
||||||
|
const userInfo = wx.getStorageSync('userInfo')
|
||||||
|
if (userInfo) {
|
||||||
|
this.globalData.userInfo = userInfo
|
||||||
|
this.globalData.isLoggedIn = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取本地存储的积分
|
||||||
|
const score = wx.getStorageSync('score')
|
||||||
|
if (score) {
|
||||||
|
this.globalData.score = score
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow(options) {
|
||||||
|
// 小程序从后台进入前台时触发
|
||||||
|
console.log('小程序显示', options)
|
||||||
|
},
|
||||||
|
|
||||||
|
onHide() {
|
||||||
|
// 小程序从前台进入后台时触发
|
||||||
|
console.log('小程序隐藏')
|
||||||
|
},
|
||||||
|
|
||||||
|
globalData: {
|
||||||
|
userInfo: null,
|
||||||
|
isLoggedIn: false,
|
||||||
|
token: '',
|
||||||
|
score: 0,
|
||||||
|
activities: [],
|
||||||
|
participatedActivities: []
|
||||||
|
},
|
||||||
|
|
||||||
|
// 全局方法
|
||||||
|
setUserInfo(userInfo) {
|
||||||
|
this.globalData.userInfo = userInfo
|
||||||
|
this.globalData.isLoggedIn = true
|
||||||
|
wx.setStorageSync('userInfo', userInfo)
|
||||||
|
},
|
||||||
|
|
||||||
|
clearUserInfo() {
|
||||||
|
this.globalData.userInfo = null
|
||||||
|
this.globalData.isLoggedIn = false
|
||||||
|
this.globalData.token = ''
|
||||||
|
wx.removeStorageSync('userInfo')
|
||||||
|
},
|
||||||
|
|
||||||
|
updateScore(delta) {
|
||||||
|
this.globalData.score += delta
|
||||||
|
wx.setStorageSync('score', this.globalData.score)
|
||||||
|
},
|
||||||
|
|
||||||
|
addActivity(activity) {
|
||||||
|
this.globalData.activities.push(activity)
|
||||||
|
},
|
||||||
|
|
||||||
|
addParticipatedActivity(activity) {
|
||||||
|
this.globalData.participatedActivities.push(activity)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 模拟随机点名
|
||||||
|
randomNameCall(activityId) {
|
||||||
|
// 这里应该根据 activityId 获取对应活动的参与者列表
|
||||||
|
// 为了演示,我们使用一个固定的名单
|
||||||
|
const participants = ['张三', '李四', '王五', '赵六', '钱七']
|
||||||
|
const randomIndex = Math.floor(Math.random() * participants.length)
|
||||||
|
return participants[randomIndex]
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"pages": [
|
||||||
|
"pages/login/login",
|
||||||
|
"pages/created/created",
|
||||||
|
"pages/participated/participated",
|
||||||
|
"pages/store/store",
|
||||||
|
"pages/createActivity/createActivity",
|
||||||
|
"pages/participatedDetail/participatedDetail",
|
||||||
|
"pages/test/test"
|
||||||
|
],
|
||||||
|
"window": {
|
||||||
|
"backgroundTextStyle": "light",
|
||||||
|
"navigationBarBackgroundColor": "#fff",
|
||||||
|
"navigationBarTitleText": "点名小程序",
|
||||||
|
"navigationBarTextStyle": "black"
|
||||||
|
},
|
||||||
|
"tabBar": {
|
||||||
|
"color": "#999999",
|
||||||
|
"selectedColor": "#0d94ff",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"pagePath": "pages/created/created",
|
||||||
|
"text": "我创建的",
|
||||||
|
"iconPath": "assets/icon-created.png",
|
||||||
|
"selectedIconPath": "assets/icon-created-active.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/participated/participated",
|
||||||
|
"text": "我参与的",
|
||||||
|
"iconPath": "assets/icon-participated.png",
|
||||||
|
"selectedIconPath": "assets/icon-participated-active.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/store/store",
|
||||||
|
"text": "商店",
|
||||||
|
"iconPath": "assets/icon-store.png",
|
||||||
|
"selectedIconPath": "assets/icon-store-active.png"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"style": "v2",
|
||||||
|
"sitemapLocation": "sitemap.json",
|
||||||
|
"networkTimeout": {
|
||||||
|
"request": 10000
|
||||||
|
},
|
||||||
|
"permission": {
|
||||||
|
"scope.userLocation": {
|
||||||
|
"desc": "你的位置信息将用于小程序位置接口的效果展示"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
/**app.wxss**/
|
||||||
|
.container {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 200rpx 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1,39 @@
|
|||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
activity: null,
|
||||||
|
selectedUser: null
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad(options) {
|
||||||
|
const activityId = options.id;
|
||||||
|
this.fetchActivityDetails(activityId);
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchActivityDetails(id) {
|
||||||
|
// 这里应该从后端 API 获取活动详情
|
||||||
|
const mockActivity = { id: 1, name: '软件工程课程', participants: 50 };
|
||||||
|
this.setData({ activity: mockActivity });
|
||||||
|
},
|
||||||
|
|
||||||
|
randomNameCall() {
|
||||||
|
// 这里应该从后端 API 获取随机用户
|
||||||
|
const randomUser = '张三';
|
||||||
|
this.setData({ selectedUser: randomUser });
|
||||||
|
},
|
||||||
|
|
||||||
|
randomQuestion() {
|
||||||
|
// 这里应该从后端 API 获取随机用户
|
||||||
|
const randomUser = '李四';
|
||||||
|
this.setData({ selectedUser: randomUser });
|
||||||
|
},
|
||||||
|
|
||||||
|
addScore() {
|
||||||
|
// 这里应该调用后端 API 增加用户积分
|
||||||
|
wx.showToast({ title: '积分已增加', icon: 'success' });
|
||||||
|
},
|
||||||
|
|
||||||
|
minusScore() {
|
||||||
|
// 这里应该调用后端 API 减少用户积分
|
||||||
|
wx.showToast({ title: '积分已减少', icon: 'success' });
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,17 @@
|
|||||||
|
<view class="container">
|
||||||
|
<view class="activity-info">
|
||||||
|
<text class="activity-name">活动名称</text>
|
||||||
|
<text class="activity-participants">参与人数: 50</text>
|
||||||
|
</view>
|
||||||
|
<view class="action-buttons">
|
||||||
|
<button class="btn-action" bindtap="randomNameCall">随机点名</button>
|
||||||
|
<button class="btn-action" bindtap="randomQuestion">回答问题</button>
|
||||||
|
</view>
|
||||||
|
<view class="selected-user" wx:if="{{selectedUser}}">
|
||||||
|
<text class="selected-user-name">{{selectedUser}}</text>
|
||||||
|
<view class="score-buttons">
|
||||||
|
<button class="btn-score" bindtap="addScore">+1分</button>
|
||||||
|
<button class="btn-score" bindtap="minusScore">-1分</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
@ -0,0 +1,63 @@
|
|||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f4f3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-info {
|
||||||
|
background-color: white;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-name {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-participants {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-action {
|
||||||
|
width: 48%;
|
||||||
|
height: 40px;
|
||||||
|
background-color: #0d94ff;
|
||||||
|
color: white;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-user {
|
||||||
|
background-color: white;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-user-name {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.score-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-score {
|
||||||
|
width: 80px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #0d94ff;
|
||||||
|
color: white;
|
||||||
|
border-radius: 15px;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
fileName: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
onUpload() {
|
||||||
|
wx.chooseMessageFile({
|
||||||
|
count: 1,
|
||||||
|
type: 'file',
|
||||||
|
extension: ['xlsx'],
|
||||||
|
success: (res) => {
|
||||||
|
const file = res.tempFiles[0];
|
||||||
|
this.setData({
|
||||||
|
fileName: file.name
|
||||||
|
});
|
||||||
|
// 这里可以处理文件上传逻辑
|
||||||
|
console.log('选择的文件:', file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onSubmit(e) {
|
||||||
|
const { activityName, activityDescription } = e.detail.value;
|
||||||
|
if (activityName && activityDescription) {
|
||||||
|
if (!this.data.fileName) {
|
||||||
|
wx.showToast({
|
||||||
|
title: '请上传 XLSX 文件',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 这里应该添加创建活动的逻辑,比如调用后端 API
|
||||||
|
console.log('创建活动:', activityName, activityDescription, this.data.fileName);
|
||||||
|
wx.showToast({
|
||||||
|
title: '创建成功',
|
||||||
|
icon: 'success',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
wx.navigateBack();
|
||||||
|
}, 2000);
|
||||||
|
} else {
|
||||||
|
wx.showToast({
|
||||||
|
title: '请填写完整信息',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,27 @@
|
|||||||
|
<view class="container">
|
||||||
|
<form bindsubmit="onSubmit">
|
||||||
|
<view class="form-group">
|
||||||
|
<text class="label">活动名称</text>
|
||||||
|
<view class="input-container">
|
||||||
|
<input name="activityName" placeholder="请输入活动名称" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="form-group">
|
||||||
|
<text class="label">活动描述</text>
|
||||||
|
<view class="input-container">
|
||||||
|
<textarea name="activityDescription" placeholder="请输入活动描述"></textarea>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="form-group">
|
||||||
|
<text class="label">上传文件</text>
|
||||||
|
<button class="upload-btn" bindtap="onUpload">上传 XLSX 文件</button>
|
||||||
|
<text class="file-name" wx:if="{{fileName}}">{{fileName}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="submit-container">
|
||||||
|
<button class="submit-btn" form-type="submit">创建活动</button>
|
||||||
|
</view>
|
||||||
|
</form>
|
||||||
|
</view>
|
@ -0,0 +1,70 @@
|
|||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f4f3f3;
|
||||||
|
min-height: 100vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
border: none;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-btn {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
color: #333;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 8px 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: auto;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-name {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-container {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
|
background-color: #0d94ff;
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
activities: [
|
||||||
|
{ id: 1, name: "活动1", participants: 10 },
|
||||||
|
{ id: 2, name: "活动2", participants: 20 },
|
||||||
|
{ id: 3, name: "活动3", participants: 15 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
onSearchInput(e) {
|
||||||
|
// 实现搜索功能
|
||||||
|
console.log("搜索:", e.detail.value);
|
||||||
|
},
|
||||||
|
|
||||||
|
onActivityTap(e) {
|
||||||
|
const activityId = e.currentTarget.dataset.id;
|
||||||
|
wx.navigateTo({
|
||||||
|
url: `/pages/activityDetail/activityDetail?id=${activityId}`
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onCreateActivity() {
|
||||||
|
wx.navigateTo({
|
||||||
|
url: '/pages/createActivity/createActivity'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<view class="container">
|
||||||
|
<view class="search-bar">
|
||||||
|
<input type="text" placeholder="搜索活动" bindinput="onSearchInput" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="activity-list">
|
||||||
|
<block wx:for="{{activities}}" wx:key="id">
|
||||||
|
<button class="activity-item" bindtap="onActivityTap" data-id="{{item.id}}">
|
||||||
|
<view class="activity-info">
|
||||||
|
<text class="activity-name">{{item.name}}</text>
|
||||||
|
<text class="activity-participants">参与人数:{{item.participants}}</text>
|
||||||
|
</view>
|
||||||
|
</button>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<button class="create-btn" bindtap="onCreateActivity">创建自定义</button>
|
||||||
|
</view>
|
@ -0,0 +1,64 @@
|
|||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f4f3f3;
|
||||||
|
min-height: 100vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: #f4f3f3;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar input {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 15px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 20px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-list {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-participants {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.create-btn {
|
||||||
|
background-color: #0d94ff;
|
||||||
|
color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<!--index.wxml-->
|
||||||
|
<scroll-view class="scrollarea" scroll-y type="list">
|
||||||
|
<view class="container">
|
||||||
|
<view class="userinfo">
|
||||||
|
<block wx:if="{{canIUseNicknameComp && !hasUserInfo}}">
|
||||||
|
<button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
|
||||||
|
<image class="avatar" src="{{userInfo.avatarUrl}}"></image>
|
||||||
|
</button>
|
||||||
|
<view class="nickname-wrapper">
|
||||||
|
<text class="nickname-label">昵称</text>
|
||||||
|
<input type="nickname" class="nickname-input" placeholder="请输入昵称" bind:change="onInputChange" />
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<block wx:elif="{{!hasUserInfo}}">
|
||||||
|
<button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button>
|
||||||
|
<view wx:else> 请使用2.10.4及以上版本基础库 </view>
|
||||||
|
</block>
|
||||||
|
<block wx:else>
|
||||||
|
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
|
||||||
|
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
<view class="usermotto">
|
||||||
|
<text class="user-motto">{{motto}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
@ -0,0 +1,62 @@
|
|||||||
|
/**index.wxss**/
|
||||||
|
page {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.scrollarea {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.userinfo {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
color: #aaa;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.userinfo-avatar {
|
||||||
|
overflow: hidden;
|
||||||
|
width: 128rpx;
|
||||||
|
height: 128rpx;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.usermotto {
|
||||||
|
margin-top: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
width: 56px !important;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 40px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
display: block;
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nickname-wrapper {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-top: .5px solid rgba(0, 0, 0, 0.1);
|
||||||
|
border-bottom: .5px solid rgba(0, 0, 0, 0.1);
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nickname-label {
|
||||||
|
width: 105px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nickname-input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
account: '',
|
||||||
|
password: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
onAccountInput(e) {
|
||||||
|
this.setData({
|
||||||
|
account: e.detail.value
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onPasswordInput(e) {
|
||||||
|
this.setData({
|
||||||
|
password: e.detail.value
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onLogin() {
|
||||||
|
const { account, password } = this.data
|
||||||
|
if (account && password) {
|
||||||
|
// 这里应该添加实际的登录逻辑,比如调用后端 API
|
||||||
|
// 现在我们只是模拟登录成功
|
||||||
|
wx.showToast({
|
||||||
|
title: '登录成功',
|
||||||
|
icon: 'success',
|
||||||
|
duration: 2000
|
||||||
|
})
|
||||||
|
// 登录成功后跳转到"我创建的"页面
|
||||||
|
wx.switchTab({
|
||||||
|
url: '/pages/created/created'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
wx.showToast({
|
||||||
|
title: '请输入账号和密码',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,7 @@
|
|||||||
|
<view class="container">
|
||||||
|
<view class="login-form">
|
||||||
|
<input type="text" placeholder="请输入账号" bindinput="onAccountInput" />
|
||||||
|
<input type="password" placeholder="请输入密码" bindinput="onPasswordInput" />
|
||||||
|
<button bindtap="onLogin" style="background-color: #0d94ff; color: white; border-radius: 5px;">登录</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
@ -0,0 +1,30 @@
|
|||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #f4f3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form {
|
||||||
|
width: 80%;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
// logs.js
|
||||||
|
const util = require('../../utils/util.js')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
logs: []
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
this.setData({
|
||||||
|
logs: (wx.getStorageSync('logs') || []).map(log => {
|
||||||
|
return {
|
||||||
|
date: util.formatTime(new Date(log)),
|
||||||
|
timeStamp: log
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
<!--logs.wxml-->
|
||||||
|
<scroll-view class="scrollarea" scroll-y type="list">
|
||||||
|
<block wx:for="{{logs}}" wx:key="timeStamp" wx:for-item="log">
|
||||||
|
<view class="log-item">{{index + 1}}. {{log.date}}</view>
|
||||||
|
</block>
|
||||||
|
</scroll-view>
|
@ -0,0 +1,16 @@
|
|||||||
|
page {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.scrollarea {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
.log-item {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.log-item:last-child {
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
activities: []
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.fetchActivities();
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchActivities() {
|
||||||
|
// 这里应该从后端 API 获取活动列表
|
||||||
|
const mockActivities = [
|
||||||
|
{ id: 1, name: '软件工程课程', participants: 50 },
|
||||||
|
{ id: 2, name: '数据结构讨论', participants: 30 }
|
||||||
|
];
|
||||||
|
this.setData({ activities: mockActivities });
|
||||||
|
},
|
||||||
|
|
||||||
|
onSearch(e) {
|
||||||
|
const keyword = e.detail.value;
|
||||||
|
// 实现搜索逻辑
|
||||||
|
},
|
||||||
|
|
||||||
|
goToCreateActivity() {
|
||||||
|
wx.navigateTo({ url: '/pages/createActivity/createActivity' });
|
||||||
|
},
|
||||||
|
|
||||||
|
goToActivityDetail(e) {
|
||||||
|
const activityId = e.currentTarget.dataset.id;
|
||||||
|
wx.navigateTo({ url: `/pages/activityDetail/activityDetail?id=${activityId}` });
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,12 @@
|
|||||||
|
<view class="container">
|
||||||
|
<view class="search-bar">
|
||||||
|
<input type="text" placeholder="搜索活动" />
|
||||||
|
</view>
|
||||||
|
<button class="btn-create">创建自定义</button>
|
||||||
|
<view class="activity-list">
|
||||||
|
<view class="activity-item" bindtap="goToActivityDetail">
|
||||||
|
<text class="activity-name">活动名称</text>
|
||||||
|
<text class="activity-participants">参与人数: 50</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
@ -0,0 +1,40 @@
|
|||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f4f3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 0 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-create {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
background-color: #0d94ff;
|
||||||
|
color: white;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item {
|
||||||
|
background-color: white;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-participants {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
activities: []
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.fetchParticipatedActivities();
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchParticipatedActivities() {
|
||||||
|
// 这里应该从后端 API 获取参与的活动列表
|
||||||
|
const mockActivities = [
|
||||||
|
{ id: 1, name: '2024软件工程K班', participants: 104 }
|
||||||
|
];
|
||||||
|
this.setData({ activities: mockActivities });
|
||||||
|
},
|
||||||
|
|
||||||
|
goToParticipatedDetail(e) {
|
||||||
|
const activityId = e.currentTarget.dataset.id;
|
||||||
|
wx.navigateTo({ url: `/pages/participatedDetail/participatedDetail?id=${activityId}` });
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,8 @@
|
|||||||
|
<view class="container">
|
||||||
|
<view class="activity-list">
|
||||||
|
<view class="activity-item" bindtap="goToParticipatedDetail">
|
||||||
|
<text class="activity-name">2024软件工程K班</text>
|
||||||
|
<text class="activity-participants">参与人数: 104</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
@ -0,0 +1,21 @@
|
|||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f4f3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item {
|
||||||
|
background-color: white;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-participants {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
activities: [
|
||||||
|
{ id: 1, name: "2024软件工程K班", participants: 104 }
|
||||||
|
// 可以添加更多活动
|
||||||
|
],
|
||||||
|
filteredActivities: []
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad: function() {
|
||||||
|
this.setData({
|
||||||
|
filteredActivities: this.data.activities.slice(1) // 除了第一个活动外的所有活动
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onSearchInput(e) {
|
||||||
|
const searchText = e.detail.value.toLowerCase();
|
||||||
|
const filtered = this.data.activities.filter(activity =>
|
||||||
|
activity.name.toLowerCase().includes(searchText)
|
||||||
|
);
|
||||||
|
this.setData({
|
||||||
|
filteredActivities: filtered
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onActivitySummaryTap() {
|
||||||
|
wx.navigateTo({
|
||||||
|
url: '/pages/participatedDetail/participatedDetail?id=1',
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('Navigation failed:', err);
|
||||||
|
wx.showToast({
|
||||||
|
title: '页面跳转失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onActivityTap(e) {
|
||||||
|
const activityId = e.currentTarget.dataset.id;
|
||||||
|
wx.navigateTo({
|
||||||
|
url: `/pages/participatedDetail/participatedDetail?id=${activityId}`,
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('Navigation failed:', err);
|
||||||
|
wx.showToast({
|
||||||
|
title: '页面跳转失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
.container {
|
||||||
|
background-color: #f4f3f3;
|
||||||
|
min-height: 100vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-section {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 5px 15px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar icon {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar input {
|
||||||
|
flex: 1;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
height: 30px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-summary {
|
||||||
|
background-color: #0d94ff;
|
||||||
|
color: white;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-participants {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-list {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-participants {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-activities {
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 50px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
const app = getApp()
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
activity: null,
|
||||||
|
luckyStudent: null,
|
||||||
|
isLoading: false,
|
||||||
|
studentId: null,
|
||||||
|
showAnswerModal: false
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad: function(options) {
|
||||||
|
const activityId = options.id;
|
||||||
|
// 这里应该根据 activityId 从服务器或本地存储加载活动详情
|
||||||
|
// 现在我们只是模拟一下
|
||||||
|
this.setData({
|
||||||
|
activity: { id: activityId, name: "2024软件工程K班", participants: 104 }
|
||||||
|
});
|
||||||
|
// 这里应该从全局状态或本地存储获取当前用户的 student_id
|
||||||
|
this.setData({
|
||||||
|
studentId: app.globalData.studentId || '12345' // 假设的学生ID
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onSignIn: function() {
|
||||||
|
wx.request({
|
||||||
|
url: 'http://10.133.7.205:3000/update_attendance_score',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
student_id: this.data.studentId
|
||||||
|
},
|
||||||
|
success: (res) => {
|
||||||
|
if (res.statusCode === 200) {
|
||||||
|
wx.showToast({
|
||||||
|
title: '签到成功',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
wx.showToast({
|
||||||
|
title: '签到失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('API request failed:', err);
|
||||||
|
wx.showToast({
|
||||||
|
title: '网络错误',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onDrawLuckyStudent: function() {
|
||||||
|
if (this.data.isLoading) return; // 防止重复点击
|
||||||
|
|
||||||
|
this.setData({ isLoading: true });
|
||||||
|
|
||||||
|
this.drawLuckyStudentWithRetry(3); // 最多重试3次
|
||||||
|
},
|
||||||
|
|
||||||
|
drawLuckyStudentWithRetry: function(retryCount) {
|
||||||
|
wx.request({
|
||||||
|
url: 'http://10.133.7.205:3000/get_random_student',
|
||||||
|
method: 'GET',
|
||||||
|
timeout: 15000, // 增加超时时间到15秒
|
||||||
|
success: (res) => {
|
||||||
|
if (res.statusCode === 200) {
|
||||||
|
this.setData({
|
||||||
|
luckyStudent: res.data.name,
|
||||||
|
studentId: res.data.id,
|
||||||
|
isLoading: false,
|
||||||
|
showAnswerModal: true
|
||||||
|
});
|
||||||
|
wx.showToast({
|
||||||
|
title: '已抽取幸运儿',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.handleDrawError('服务器返回错误', retryCount);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('API request failed:', err);
|
||||||
|
this.handleDrawError('网络请求失败', retryCount);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
handleDrawError: function(errorMsg, retryCount) {
|
||||||
|
if (retryCount > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.drawLuckyStudentWithRetry(retryCount - 1);
|
||||||
|
}, 1000); // 1秒后重试
|
||||||
|
} else {
|
||||||
|
this.setData({ isLoading: false });
|
||||||
|
wx.showModal({
|
||||||
|
title: '抽取失败',
|
||||||
|
content: `${errorMsg},请稍后再试。`,
|
||||||
|
showCancel: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onAnswerCorrect: function() {
|
||||||
|
this.updateAnswerScore(true, 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
onAnswerIncorrect: function() {
|
||||||
|
this.updateAnswerScore(false, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateAnswerScore: function(repeatedCorrectly, answerScore) {
|
||||||
|
wx.request({
|
||||||
|
url: 'http://10.133.7.205:3000/update_answer_score',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
student_id: this.data.studentId,
|
||||||
|
repeated_correctly: repeatedCorrectly,
|
||||||
|
answer_score: answerScore
|
||||||
|
},
|
||||||
|
success: (res) => {
|
||||||
|
if (res.statusCode === 200) {
|
||||||
|
wx.showToast({
|
||||||
|
title: '回答已记录',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
wx.showToast({
|
||||||
|
title: '记录失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.setData({ showAnswerModal: false });
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('API request failed:', err);
|
||||||
|
wx.showToast({
|
||||||
|
title: '网络错误',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
this.setData({ showAnswerModal: false });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<view class="container">
|
||||||
|
<view class="activity-info">
|
||||||
|
<text class="activity-name">{{activity.name}}</text>
|
||||||
|
<text class="activity-participants">参与人数:{{activity.participants}}人</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="lucky-student" wx:if="{{luckyStudent}}">
|
||||||
|
<text>幸运儿:{{luckyStudent}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="action-buttons">
|
||||||
|
<button class="action-btn" bindtap="onSignIn">签到</button>
|
||||||
|
<button class="action-btn" bindtap="onDrawLuckyStudent" disabled="{{isLoading}}">
|
||||||
|
{{isLoading ? '抽取中...' : '抽取幸运儿'}}
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="answer-modal" wx:if="{{showAnswerModal}}">
|
||||||
|
<view class="modal-content">
|
||||||
|
<text>{{luckyStudent}} 回答问题:</text>
|
||||||
|
<view class="answer-buttons">
|
||||||
|
<button class="answer-btn correct" bindtap="onAnswerCorrect">回答正确</button>
|
||||||
|
<button class="answer-btn incorrect" bindtap="onAnswerIncorrect">回答错误</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
@ -0,0 +1,95 @@
|
|||||||
|
.container {
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #f4f3f3;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-info {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
box-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-name {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-participants {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lucky-student {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
box-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #0d94ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
background-color: #0d94ff;
|
||||||
|
color: #ffffff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 10rpx 20rpx;
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
width: 80%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-btn {
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 10rpx 20rpx;
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.correct {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.incorrect {
|
||||||
|
background-color: #F44336;
|
||||||
|
color: white;
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
<view class="container">
|
||||||
|
<view class="user-points">
|
||||||
|
<text class="points-text">当前积分:{{userPoints}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="card-list">
|
||||||
|
<view class="card-item" wx:for="{{cards}}" wx:key="id">
|
||||||
|
<text class="card-name">{{item.name}}</text>
|
||||||
|
<image class="card-image" src="{{item.image}}" mode="aspectFit"></image>
|
||||||
|
<view class="card-info">
|
||||||
|
<text class="card-price">{{item.price}} 积分</text>
|
||||||
|
<button class="buy-btn" bindtap="onBuy" data-id="{{item.id}}">
|
||||||
|
购买
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="bottom-section">
|
||||||
|
<button class="guess-btn" bindtap="onGuess">
|
||||||
|
猜题赢积分
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
@ -0,0 +1,71 @@
|
|||||||
|
.container {
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #f4f3f3;
|
||||||
|
min-height: 100vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-points {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-item {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
box-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-name {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-image {
|
||||||
|
width: 300rpx;
|
||||||
|
height: 300rpx;
|
||||||
|
object-fit: cover;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-info {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-price {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buy-btn, .guess-btn {
|
||||||
|
background-color: #0d94ff;
|
||||||
|
color: #ffffff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 10rpx 20rpx;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guess-btn {
|
||||||
|
width: 100%;
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
Page({
|
||||||
|
data: {} ,
|
||||||
|
onLoad: function() {
|
||||||
|
console.log('Test page loaded');
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
<view>This is a test page</view>
|
@ -0,0 +1,3 @@
|
|||||||
|
view {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"compileType": "miniprogram",
|
||||||
|
"libVersion": "trial",
|
||||||
|
"packOptions": {
|
||||||
|
"ignore": [],
|
||||||
|
"include": []
|
||||||
|
},
|
||||||
|
"setting": {
|
||||||
|
"coverView": true,
|
||||||
|
"es6": true,
|
||||||
|
"postcss": true,
|
||||||
|
"minified": true,
|
||||||
|
"enhance": true,
|
||||||
|
"showShadowRootInWxmlPanel": true,
|
||||||
|
"packNpmRelationList": [],
|
||||||
|
"babelSetting": {
|
||||||
|
"ignore": [],
|
||||||
|
"disablePlugins": [],
|
||||||
|
"outputPath": ""
|
||||||
|
},
|
||||||
|
"urlCheck": false
|
||||||
|
},
|
||||||
|
"condition": {},
|
||||||
|
"editorSetting": {
|
||||||
|
"tabIndent": "auto",
|
||||||
|
"tabSize": 2
|
||||||
|
},
|
||||||
|
"appid": "wxcbc61201213ab639"
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||||
|
"rules": [{
|
||||||
|
"action": "allow",
|
||||||
|
"page": "*"
|
||||||
|
}]
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
const formatTime = date => {
|
||||||
|
const year = date.getFullYear()
|
||||||
|
const month = date.getMonth() + 1
|
||||||
|
const day = date.getDate()
|
||||||
|
const hour = date.getHours()
|
||||||
|
const minute = date.getMinutes()
|
||||||
|
const second = date.getSeconds()
|
||||||
|
|
||||||
|
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatNumber = n => {
|
||||||
|
n = n.toString()
|
||||||
|
return n[1] ? n : `0${n}`
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
formatTime
|
||||||
|
}
|
Loading…
Reference in new issue