New Huajishe Check ChaoXing
This commit is contained in:
275
HuajisheCheckChaoXing/pages/home/home.js
Normal file
275
HuajisheCheckChaoXing/pages/home/home.js
Normal file
@@ -0,0 +1,275 @@
|
||||
import config from '@utils/config';
|
||||
import util from '@utils/util';
|
||||
import API from '@utils/api';
|
||||
import log from '@utils/log';
|
||||
|
||||
let api = null;
|
||||
|
||||
Page({
|
||||
data: {
|
||||
tab: 'login', // login / courses / activities / signin
|
||||
typeDefine: ["拍照签到", "普通签到", "二维码签到", "手势签到", "位置签到", "签到码签到"],
|
||||
swiperList: (config.swiperList || [
|
||||
"/swiper/1.png",
|
||||
"/swiper/2.png",
|
||||
"/swiper/3.png",
|
||||
"/swiper/4.png",
|
||||
]).map(item => `https://testingcf.jsdelivr.net/gh/${config.repository}@main/resource${item}`),
|
||||
repository: config.repository,
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
this.setData({
|
||||
'username': util.getStorage('username'),
|
||||
'password': util.getStorage('password'),
|
||||
}, () => {
|
||||
this.setData(Object.assign(this.data, options))
|
||||
})
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
util.setStorage('username', this.data.username);
|
||||
util.setStorage('password', this.data.password);
|
||||
},
|
||||
|
||||
input(e) { // 输入绑定
|
||||
this.setData({
|
||||
[e.currentTarget.dataset.input]: e.detail.value.trim(),
|
||||
})
|
||||
},
|
||||
|
||||
login() { // 账号登录
|
||||
const username = this.data.username;
|
||||
const password = this.data.password;
|
||||
if (!username || !password) {
|
||||
util.showInfo("帐号或密码不能为空!")
|
||||
return;
|
||||
}
|
||||
api = new API(username, password);
|
||||
api.login()
|
||||
.then(res => {
|
||||
util.showInfo(res.mes);
|
||||
if (res.status) {
|
||||
api.getUserInfo()
|
||||
.then(userinfo => {
|
||||
util.showInfo("登录成功")
|
||||
this.setData({
|
||||
'userinfo': userinfo,
|
||||
'tab': 'courses',
|
||||
})
|
||||
this.options.username = username;
|
||||
this.options.password = password;
|
||||
this.onUnload(); // 缓存
|
||||
this.get_courses(); // 获取课程
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
util.showInfo("网络不稳定 请稍后再试");
|
||||
log.error("登录失败", e)
|
||||
})
|
||||
},
|
||||
|
||||
get_courses() { // 获取课程列表
|
||||
api.getCourse()
|
||||
.then(courses => {
|
||||
this.setData({
|
||||
'courses': courses,
|
||||
})
|
||||
util.showInfo("获取课程成功")
|
||||
})
|
||||
.catch(e => {
|
||||
util.showInfo("获取课程失败,请重试")
|
||||
log.error("获取课程失败", e)
|
||||
})
|
||||
},
|
||||
|
||||
get_activities(e) { // 获取签到列表
|
||||
const item = e.currentTarget.dataset.item;
|
||||
api.getActivity(item.courseId, item.classId)
|
||||
.then(activities => {
|
||||
this.setData({
|
||||
'activities': activities.slice(0, 20),
|
||||
'tab': 'activities',
|
||||
})
|
||||
util.showInfo("获取活动成功");
|
||||
})
|
||||
.catch(e => {
|
||||
util.showInfo("获取活动失败,请重试")
|
||||
log.error("获取活动失败", e)
|
||||
})
|
||||
},
|
||||
|
||||
async to_signin(e) { // 进入签到页
|
||||
const item = e.currentTarget.dataset.item;
|
||||
this.getUserLocation()
|
||||
api = new API(this.data.username, this.data.password);
|
||||
api.beforeSign(item.activeId, item.courseId, item.classId);
|
||||
this.data.hasValidate = await api.hasValidate(item.activeId); // 是否有滑块验证码
|
||||
this.data.token = ([0, 1].includes(item.type)) ? await api.getToken() : ''; // 超星云盘token
|
||||
api.getActivityInfo(item.activeId) // 获取签到活动信息
|
||||
.then(info => this.setData({
|
||||
'info': Object.assign(info, item),
|
||||
'info.type': info.otherId || (1 - info.ifphoto), // 是否为拍照签到
|
||||
'tab': 'signin',
|
||||
}))
|
||||
},
|
||||
|
||||
getUserLocation() { // 获取用户位置
|
||||
wx.getLocation({
|
||||
'type': 'gcj02',
|
||||
})
|
||||
.then(gcj02 => {
|
||||
log.info("获取用户位置", gcj02)
|
||||
API.allToBaidu(gcj02.longitude, gcj02.latitude)
|
||||
.then(bd09ll => this.setData({
|
||||
'location.longitude': bd09ll.x,
|
||||
'location.latitude': bd09ll.y,
|
||||
}))
|
||||
API.getAddressText(gcj02.longitude, gcj02.latitude)
|
||||
.then(text => this.setData({
|
||||
'location.name': text,
|
||||
}))
|
||||
})
|
||||
.catch(e => {
|
||||
util.showInfo("用户拒绝定位")
|
||||
log.debug("用户拒绝定位", e)
|
||||
})
|
||||
},
|
||||
|
||||
chooseLocation() { // 选择位置
|
||||
wx.chooseLocation(this.data.location) // 国测局坐标系 gcj02
|
||||
.then(gcj02 => {
|
||||
log.info("用户选择位置", gcj02)
|
||||
API.allToBaidu(gcj02.longitude, gcj02.latitude)
|
||||
.then(bd09ll => this.setData({
|
||||
'location.latitude': bd09ll.y,
|
||||
'location.longitude': bd09ll.x,
|
||||
'location.name': gcj02.name || gcj02.address,
|
||||
}))
|
||||
})
|
||||
.catch(e => {
|
||||
util.showInfo("取消位置选择")
|
||||
log.debug("取消位置选择", e)
|
||||
})
|
||||
},
|
||||
|
||||
async signin(e) { // 提交签到
|
||||
const objectId = (this.data.srcList || []).length ? this.data.srcList[0] : "";
|
||||
const location = this.data.location;
|
||||
const info = this.data.info;
|
||||
const userinfo = this.data.userinfo;
|
||||
|
||||
let res = "";
|
||||
if (this.data.hasValidate)
|
||||
this.data.validate = ""; // 课后作业:此处请自行实现 GET请求 https://cx.micono.eu.org/api/validate
|
||||
|
||||
if (info.type == 0 || info.type == 1) { // 图片/普通
|
||||
if (objectId == 0 && info.type == 0) {
|
||||
const ok = await wx.showModal({
|
||||
title: '确认直接签到吗?',
|
||||
content: '你还没有上传图片',
|
||||
})
|
||||
if (ok.confirm != true)
|
||||
return;
|
||||
}
|
||||
res = await api.defaultSign(info.activeId, objectId, null, null, null, null, null, null, userinfo.name, this.data.validate);
|
||||
}
|
||||
|
||||
if (info.type == 3 || info.type == 5) { // 签到码/手势
|
||||
res = await api.defaultSign(info.activeId, null, null, null, null, this.data.signCode, null, null, userinfo.name, this.data.validate);
|
||||
}
|
||||
|
||||
if (info.type == 4) { // 位置
|
||||
res = await api.defaultSign(info.activeId, null, location.longitude, location.latitude, location.name, null, null, null, userinfo.name, this.data.validate);
|
||||
}
|
||||
|
||||
if (info.type == 2) { // 二维码
|
||||
const qrcode = await wx.scanCode();
|
||||
log.debug("扫码结果", qrcode)
|
||||
let params = {};
|
||||
qrcode.result.split('?')[1].split('&').forEach(param => {
|
||||
const parts = param.split('=');
|
||||
const key = decodeURIComponent(parts[0]);
|
||||
const value = decodeURIComponent(parts[1]);
|
||||
params[key] = value;
|
||||
});
|
||||
const enc = params.enc;
|
||||
res = await this.data.api.defaultSign(info.activeId, null, location.longitude, location.latitude, location.name, null, null, enc, userinfo.name, this.data.validate);
|
||||
}
|
||||
|
||||
const msg = API.getResult(res);
|
||||
util.showInfo(msg, 'none', true);
|
||||
this.setData({
|
||||
'result': msg,
|
||||
})
|
||||
},
|
||||
|
||||
handleAdd(e) { // 上传图片
|
||||
const files = e.detail.files;
|
||||
const token = this.data.token;
|
||||
const fileList = this.data.fileList || [];
|
||||
files.forEach(file => {
|
||||
this.setData({
|
||||
'fileList': [...fileList, {
|
||||
...file,
|
||||
'status': 'loading'
|
||||
}],
|
||||
'srcList': this.data.srcList || [],
|
||||
});
|
||||
const length = fileList.length;
|
||||
|
||||
const task = wx.uploadFile({
|
||||
url: `https://pan-yz.chaoxing.com/upload?_token=${token}`,
|
||||
filePath: file.url,
|
||||
name: 'file',
|
||||
formData: {
|
||||
'puid': this.data.userinfo.uid
|
||||
},
|
||||
success: res => {
|
||||
const data = JSON.parse(res.data);
|
||||
if (data.result) {
|
||||
log.debug("图片上传结果", data)
|
||||
util.showInfo("图片上传成功")
|
||||
this.setData({
|
||||
[`fileList[${length}].status`]: 'done',
|
||||
[`srcList[${length}]`]: data.objectId,
|
||||
});
|
||||
} else {
|
||||
util.showInfo(data.msg)
|
||||
this.handleRemove()
|
||||
}
|
||||
|
||||
},
|
||||
});
|
||||
task.onProgressUpdate((res) => {
|
||||
this.setData({
|
||||
[`fileList[${length}].percent`]: Math.floor(res.progress * 0.99),
|
||||
});
|
||||
});
|
||||
})
|
||||
},
|
||||
handleRemove(e) { // 删除图片
|
||||
const index = e?.detail?.index || this.data.fileList.length - 1;
|
||||
this.data.fileList.splice(index, 1);
|
||||
this.data.srcList.splice(index, 1);
|
||||
this.setData({
|
||||
'fileList': this.data.fileList,
|
||||
'srcList': this.data.srcList,
|
||||
});
|
||||
},
|
||||
|
||||
back() { // 返回
|
||||
const tabs = ["login", "courses", "activities", "signin"];
|
||||
this.setData({
|
||||
'tab': tabs[(tabs.indexOf(this.data.tab) || 1) - 1],
|
||||
})
|
||||
},
|
||||
|
||||
onShareAppMessage() { // 分享
|
||||
return {
|
||||
'title': '学习通签到助手',
|
||||
'imageUrl': '/static/image/share.png',
|
||||
}
|
||||
}
|
||||
})
|
||||
28
HuajisheCheckChaoXing/pages/home/home.json
Normal file
28
HuajisheCheckChaoXing/pages/home/home.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"t-swiper": "tdesign-miniprogram/swiper/swiper",
|
||||
"t-dialog": "tdesign-miniprogram/dialog/dialog",
|
||||
"t-switch": "tdesign-miniprogram/switch/switch",
|
||||
"t-icon": "tdesign-miniprogram/icon/icon",
|
||||
"t-upload": "tdesign-miniprogram/upload/upload",
|
||||
"t-notice-bar": "tdesign-miniprogram/notice-bar/notice-bar",
|
||||
"t-button": "tdesign-miniprogram/button/button",
|
||||
"t-radio": "tdesign-miniprogram/radio/radio",
|
||||
"t-navbar": "tdesign-miniprogram/navbar/navbar",
|
||||
"t-radio-group": "tdesign-miniprogram/radio-group/radio-group",
|
||||
"t-cell": "tdesign-miniprogram/cell/cell",
|
||||
"t-picker": "tdesign-miniprogram/picker/picker",
|
||||
"t-picker-item": "tdesign-miniprogram/picker-item/picker-item",
|
||||
"t-popup": "tdesign-miniprogram/popup/popup",
|
||||
"t-checkbox": "tdesign-miniprogram/checkbox/checkbox",
|
||||
"t-checkbox-group": "tdesign-miniprogram/checkbox-group/checkbox-group",
|
||||
"t-fab": "tdesign-miniprogram/fab/fab",
|
||||
"t-input": "tdesign-miniprogram/input/input",
|
||||
"t-image": "tdesign-miniprogram/image/image",
|
||||
"t-search": "tdesign-miniprogram/search/search",
|
||||
"t-divider": "tdesign-miniprogram/divider/divider",
|
||||
"t-dropdown-menu": "tdesign-miniprogram/dropdown-menu/dropdown-menu",
|
||||
"t-dropdown-item": "tdesign-miniprogram/dropdown-item/dropdown-item",
|
||||
"no-data": "/components/no-data/no-data"
|
||||
}
|
||||
}
|
||||
156
HuajisheCheckChaoXing/pages/home/home.wxml
Normal file
156
HuajisheCheckChaoXing/pages/home/home.wxml
Normal file
@@ -0,0 +1,156 @@
|
||||
|
||||
<t-navbar title="学习助手" t-class-title="nav-title"></t-navbar>
|
||||
|
||||
<!-- 登录页 -->
|
||||
<view wx:if="{{tab=='login'}}">
|
||||
<view class="swiper shadow-radius">
|
||||
<t-swiper duration="1000" height="300rpx" interval="3000" list="{{swiperList}}" navigation="{{ {type: 'dots-bar'} }}"></t-swiper>
|
||||
</view>
|
||||
<view class="container shadow-radius">
|
||||
<view class="input">
|
||||
<image class="input-icon" src="/static/svg/icon/username.svg" mode="aspectFill"></image>
|
||||
<input class="input-value" value="{{username}}" type="number" placeholder="帐号 (手机号)" bindinput="input" data-input="username"></input>
|
||||
</view>
|
||||
<view class="input">
|
||||
<image class="input-icon" src="/static/svg/icon/password.svg" mode="aspectFill"></image>
|
||||
<input class="input-value" value="{{password}}" type="text" placeholder="密码" bindinput="input" data-input="password" bindconfirm="login"></input>
|
||||
</view>
|
||||
<view class="login-button">
|
||||
<t-button block theme="primary" size="large" variant="outline" open-type="share">分享</t-button>
|
||||
<t-button block theme="primary" size="large" bindtap="login">登录</t-button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="license">
|
||||
<view>本小程序使用 AGPLv3 协议</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 课程列表页 -->
|
||||
<view wx:if="{{tab=='courses'}}">
|
||||
<view class="container shadow-radius">
|
||||
<view class="course-item" wx:for="{{courses}}" wx:key="index" bindtap="get_activities" data-item="{{item}}">
|
||||
<view class="course-item-image">
|
||||
<t-image src="{{item.img}}" width="60" height="60" shape="round" mode="aspectFill"></t-image>
|
||||
</view>
|
||||
<view class="course-item-info {{item.folder?'inside':''}}">
|
||||
<text class="course-item-title">{{item.courseName}}</text>
|
||||
<text class="course-item-other">教师:{{item.teacherName}}</text>
|
||||
<text class="course-item-other">班级:{{item.className}}</text>
|
||||
<text class="course-item-other" wx:if="{{item.folder}}">文件夹:{{item.folder}}</text>
|
||||
<text class="course-item-other" wx:if="{{item.isTeach}}">身份:教师/助教</text>
|
||||
</view>
|
||||
<t-divider></t-divider>
|
||||
</view>
|
||||
<view wx:if="{{!courses || courses.length==0}}">
|
||||
<no-data text="暂无签到/活动"></no-data>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 签到列表页 -->
|
||||
<view wx:if="{{tab=='activities'}}">
|
||||
<view class="container shadow-radius">
|
||||
<view class="course-item" wx:for="{{activities}}" wx:key="index" bindtap="to_signin" data-item="{{item}}">
|
||||
<view class="course-item-image">
|
||||
<t-image src="{{item.img}}" width="60" height="60" shape="round" mode="aspectFill"></t-image>
|
||||
</view>
|
||||
<view class="course-item-info {{item.folder?'inside':''}}">
|
||||
<text class="course-item-title">{{typeDefine[item.type]}}</text>
|
||||
<text class="course-item-other">截止时间:{{item.time}}</text>
|
||||
<text class="course-item-other">签到名称:{{item.name}}</text>
|
||||
</view>
|
||||
<t-divider></t-divider>
|
||||
</view>
|
||||
<view wx:if="{{!courses || courses.length==0}}">
|
||||
<no-data text="暂无签到/活动"></no-data>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 签到页 -->
|
||||
<view wx:if="{{tab=='signin'}}">
|
||||
<view class="container shadow-radius">
|
||||
<view class="container-text">
|
||||
<view class="title">
|
||||
<text class="title-text">{{typeDefine[info.type]}}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="info-tag">签到名</view>
|
||||
<view class="info-content">{{info.name}}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="info-tag">已签人数</view>
|
||||
<view class="info-content">{{info.attendNum}}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="info-tag">活动ID</view>
|
||||
<view class="info-content">{{info.activeId}}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="info-tag">结束时间</view>
|
||||
<view class="info-content">{{info.endtimeStr}}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="info-tag">签到结果</view>
|
||||
<view class="info-content result">{{result}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 普通 -->
|
||||
<view wx:if="{{info.type==1}}">
|
||||
<view class="button-box">
|
||||
<t-button block t-class="shadow-radius" theme="primary" size="large" bindtap="signin">一键签到</t-button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 拍照 -->
|
||||
<view wx:if="{{info.type==0}}">
|
||||
<view class="image-box shadow-radius">
|
||||
<t-upload grid-config="{{ {width: 110, height: 110, column: 5} }}" mediaType="{{['image']}}" source="{{uploadMode}}" max="1" files="{{fileList}}" bind:add="handleAdd" bind:remove="handleRemove"></t-upload>
|
||||
</view>
|
||||
<view class="button-box">
|
||||
<t-button block t-class="shadow-radius" theme="primary" size="large" bindtap="signin">立即签到</t-button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 签到码/手势 -->
|
||||
<view wx:if="{{info.type==3 || info.type==5}}">
|
||||
<view class="input-box shadow-radius">
|
||||
<view class="signcode-info"><text space="emsp">提示:签到码与手势签到的区别,请参考数字9键</text></view>
|
||||
<t-input type="number" label="签到码" value="{{signCode}}" placeholder="签到码/手势" bind:change="input" data-input="signCode" bind:blur="checkSignCode" suffixIcon="{{signCodeIcon}}"></t-input>
|
||||
</view>
|
||||
<view class="button-box">
|
||||
<t-button block t-class="shadow-radius" theme="primary" size="large" bindtap="signin" disabled="{{signCodeIcon!='check-circle'}}">{{signCodeIcon!='check-circle'?'请先输入':'立即签到'}}</t-button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 位置 -->
|
||||
<view wx:if="{{info.type==4}}">
|
||||
<view class="input-box shadow-radius">
|
||||
<t-input type="digit" label="纬度" value="{{location.latitude}}" placeholder="点击下方地图选点" bind:change="input" data-input="location.latitude"></t-input>
|
||||
<t-input type="digit" label="经度" value="{{location.longitude}}" placeholder="点击下方地图选点" bind:change="input" data-input="location.longitude"></t-input>
|
||||
<t-input label="位置" value="{{location.name}}" placeholder="教师端可见,留空时不上传位置" bind:change="input" data-input="location.name"></t-input>
|
||||
</view>
|
||||
<view class="button-box">
|
||||
<t-button block t-class="shadow-radius" theme="light" size="large" bindtap="chooseLocation">地图选点</t-button>
|
||||
<t-button block t-class="shadow-radius" theme="primary" size="large" bindtap="signin">立即签到</t-button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 二维码 -->
|
||||
<view wx:if="{{info.type==2}}">
|
||||
<view class="input-box shadow-radius">
|
||||
<t-input type="digit" label="纬度" value="{{location.latitude}}" placeholder="点击下方地图选点" bind:change="input" data-input="location.latitude"></t-input>
|
||||
<t-input type="digit" label="经度" value="{{location.longitude}}" placeholder="点击下方地图选点" bind:change="input" data-input="location.longitude"></t-input>
|
||||
<t-input label="位置" value="{{location.name}}" placeholder="教师端可见,留空时不上传位置" bind:change="input" data-input="location.name"></t-input>
|
||||
</view>
|
||||
<view class="button-box">
|
||||
<t-button block t-class="shadow-radius" theme="light" size="large" bindtap="chooseLocation">地图选点</t-button>
|
||||
<t-button block t-class="shadow-radius" theme="primary" size="large" bindtap="signin">扫码签到</t-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 页尾 -->
|
||||
<t-fab icon="rollback" bind:click="back" aria-label="返回" wx:if="{{tab!='login'}}"></t-fab>
|
||||
<view style="height: 200rpx"></view>
|
||||
172
HuajisheCheckChaoXing/pages/home/home.wxss
Normal file
172
HuajisheCheckChaoXing/pages/home/home.wxss
Normal file
@@ -0,0 +1,172 @@
|
||||
/* 公用样式 */
|
||||
|
||||
.container {
|
||||
margin: 30rpx;
|
||||
min-height: 100rpx;
|
||||
padding: 20rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* 登录页 */
|
||||
.license {
|
||||
text-align: center;
|
||||
color: gray;
|
||||
position: fixed;
|
||||
bottom: 30rpx;
|
||||
width: 100vw;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
margin: 30rpx;
|
||||
height: 300rpx;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 600rpx;
|
||||
height: 100rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
align-items: center;
|
||||
padding: 0px 0px 0px 32rpx;
|
||||
gap: 16px;
|
||||
background: #f6f6f6;
|
||||
border: 0.5px solid #e4e4e4;
|
||||
border-radius: 15rpx;
|
||||
margin: 25rpx auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.input-value {
|
||||
width: 340rpx;
|
||||
text-align: left;
|
||||
font-size: 30rpx;
|
||||
margin: 0rpx 50rpx;
|
||||
background-color: rgb(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.login-button {
|
||||
width: 600rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 20rpx auto;
|
||||
gap: 40rpx;
|
||||
}
|
||||
|
||||
/* 课程列表页 */
|
||||
|
||||
.course-item {
|
||||
min-height: 100rpx;
|
||||
background: white;
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inside {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.course-item-image {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.course-item-info {
|
||||
margin: 0rpx 20rpx;
|
||||
max-width: 480rpx;
|
||||
}
|
||||
|
||||
.course-item-title {
|
||||
font-size: 30rpx;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.course-item-other {
|
||||
color: #535353;
|
||||
font-size: 24rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 签到页 */
|
||||
|
||||
.container-text {
|
||||
margin: 30rpx 45rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.title {
|
||||
position: relative;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
margin: 15rpx auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
float: right;
|
||||
font-size: 26rpx;
|
||||
margin: 1rpx 0;
|
||||
}
|
||||
|
||||
.info-tag {
|
||||
position: absolute;
|
||||
color: black;
|
||||
left: -10rpx;
|
||||
width: 4em;
|
||||
display: inline-block;
|
||||
text-align: justify;
|
||||
text-align-last: justify;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
width: 450rpx;
|
||||
height: 50rpx;
|
||||
color: gray;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.image-box {
|
||||
margin: 30rpx;
|
||||
background: none;
|
||||
align-items: left;
|
||||
padding: 20rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.signcode-info {
|
||||
color: gray;
|
||||
margin: 20rpx 30rpx 10rpx;
|
||||
font-size: 25rpx;
|
||||
}
|
||||
|
||||
.input-box {
|
||||
width: 660rpx;
|
||||
margin: 0 auto 30rpx;
|
||||
padding-right: 30rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.button-box {
|
||||
width: 690rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 15rpx;
|
||||
margin: 30rpx auto;
|
||||
}
|
||||
Reference in New Issue
Block a user