Commit 4293f451 by 穆启卓

第一版

parents
> 1%
last 2 versions
not ie <= 8
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
# read_daka
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Run your tests
```
npm run test
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
module.exports = {
presets: [
'@vue/app'
]
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "read_daka",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"axios": "^0.18.0",
"vue": "^2.6.6",
"vue-calendar-component": "^2.8.2",
"vue-router": "^3.0.1",
"vuex": "^3.0.1",
"weixin-js-sdk": "^1.4.0-test"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.4.0",
"@vue/cli-service": "^3.4.0",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"vue-template-compiler": "^2.5.21"
}
}
module.exports = {
plugins: {
autoprefixer: {}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" />
<title>每天读书打卡</title>
</head>
<body>
<noscript>
<strong>We're sorry but read_daka doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div id="app">
<router-view/>
<HelloWorld></HelloWorld>
</div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
components: {
HelloWorld
},
mounted() {
(function (win) {
var doc = win.document;
var html = doc.documentElement;
// 基于750px方案的设计稿
////////////////////////////////////////////////////
// 通用的做法是将设计稿中的100px换算为1rem
// 因此,当我们已知设计稿的宽度baseWidth,还有屏幕的实际宽度clientWidth时,1rem对于屏幕的实际宽度为:
// html-font-size = clientWidth / (baseWidth/100) px
///////////////////////////////////////////////////
var baseWidth = 750,
grids = baseWidth / 100,
resizeEvt = "orientationchange" in win ? "orientationchange" : "resize",
recalc = function () {
// 默认尺寸为320px
var clientWidth = html.clientWidth || 640;
// 如果屏幕尺寸大于750,则按750宽度进行计算
if (clientWidth > 750) {
clientWidth = 750;
}
html.style.fontSize = clientWidth / grids + "px";
// document.querySelector(".content").style.display = "block";
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener(
"DOMContentLoaded",
function () {
setTimeout(recalc);
},
false
);
})(window);
}
};
</script>
<style lang="stylus">
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: "";
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
body,html,#app
margin 0
width 100%
height 100%
</style>
\ No newline at end of file
<template>
<div class="DakaSuccess">
<div class="content">
<img
src="../assets/ic_close.png"
class="close_icon"
@click="closeModal"
>
<div class="title_container">
<div class="title">早起打卡成功</div>
<div class="sub_title">请继续保持早起习惯哦~</div>
</div>
<img
src="../assets/pop_hand.png"
class="main_pic"
>
<div class="desc">奖励金预计当日13点前到账</div>
<div
class="DakaSuccess_button"
@click="nextSign"
>报名下一期</div>
</div>
</div>
</template>
<style>
div.DakaSuccess {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.3);
border: 1px solid transparent;
text-align: center;
}
div.DakaSuccess .close_icon {
display: block;
position: absolute;
top: 0.2rem;
right: 0.2rem;
width: 0.3rem;
}
div.DakaSuccess .content {
width: 6.4rem;
height: 6.85rem;
background: #ffffff;
border-radius: 0.06rem;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
border: 1px solid transparent;
}
div.DakaSuccess .content .title_container {
height: 1rem;
}
div.DakaSuccess .content .title {
font-size: 0.4rem;
color: #282828;
margin-top: 0.6rem;
font-weight: bold;
}
div.DakaSuccess .content .sub_title {
margin-top: 0.18rem;
font-size: 0.4rem;
color: #282828;
}
div.DakaSuccess .content img.main_pic {
width: 3.2rem;
margin-top: 0.2rem;
}
div.DakaSuccess .content .desc {
margin-top: 0.24rem;
color: #5a5a5a;
font-size: 0.28rem;
}
div.DakaSuccess .content .desc span {
font-size: 0.36rem;
color: #282828;
font-weight: bold;
}
div.DakaSuccess .content .sub_desc {
margin-top: 0.3rem;
color: #5a5a5a;
font-size: 0.24rem;
}
div.DakaSuccess .content .DakaSuccess_button {
width: 5rem;
height: 0.88rem;
margin-top: 0.4rem;
margin-left: calc((6.4rem - 5rem) / 2);
background: #ffbb34;
border-radius: 0.44rem;
font-size: 0.38rem;
font-weight: bold;
color: #ffffff;
line-height: calc(0.88 / 0.38);
}
</style>
<script>
export default {
name: "DakaSuccess",
components: {},
data() {
return {
can_get: false,
invite_num: 4
};
},
methods: {
// 关闭弹窗
closeModal() {
this.$emit("close", true);
},
// 邀请好友
nextSign() {
this.$emit("nextSign", true);
this.$emit("close", true);
},
// 立即报名
joinDakaSuccess() {}
}
};
</script>
<template>
<div class="example_modal">
<div class="example_img">
<img src="../assets/daka_example_modal.png" alt="">
</div>
<div class="example_btn" @click="closeDialog">
我知道了
</div>
</div>
</template>
<script>
export default {
name: "ExampleModal",
methods: {
closeDialog() {
this.$emit("close")
}
}
}
</script>
<style scoped>
.example_modal{
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
border: 1px solid transparent;
z-index: 100;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.example_img{
width: 6.4rem;
}
.example_img img{
width: 100%;
}
.example_btn{
width: 2.8rem;
height: .8rem;
display: flex;
justify-content: center;
align-items: center;
color: rgba(255,255,255,1);
font-size: .36rem;
border-radius: .4rem;
border: .01rem solid rgba(255,255,255,1);
margin-top: .5rem;
}
</style>
<template>
<div class="follow_dialog">
<div class="follow_img" v-if="isKefu==1">
<img src="https://cos-minigame.wxatech.com/common/study_contact_kefu.jpg" alt="">
</div>
<div class="follow_img" v-else>
<img src="https://cos-minigame.wxatech.com/common/study_follow_account1.jpg" alt="">
</div>
<div class="close_btn" @click="closeDialog">
<img src="../assets/ic_close3.png" alt="">
</div>
</div>
</template>
<script>
export default {
name: "FollowDialog",
props: ["isKefu"],
methods: {
closeDialog() {
this.$emit("close")
}
}
}
</script>
<style scoped>
.follow_dialog {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
border: 1px solid transparent;
z-index: 100;
text-align: center;
}
.follow_img {
position: absolute;
left: 50%;
top: 50%;
width: 6.4rem;
margin-top: -4.5rem;
margin-left: -3.2rem;
}
.follow_img img {
width: 100%;
}
.close_btn {
width: .7rem;
position: absolute;
top: 50%;
left: 50%;
margin-top: 4rem;
margin-left: -.35rem;
}
.close_btn img {
width: 100%;
}
</style>
<template>
<div class="Free">
<div class="content">
<img
src="../assets/ic_close.png"
class="close_icon"
@click="closeModal"
>
<div class="title">邀请1位好友报名成功</div>
<div class="sub_title">可获取免押金1次</div>
<img
src="../assets/pic_coin.png"
class="main_pic"
>
<div class="desc">
成功邀请<span class="invite_num"> {{invite_num}} </span>位好友
</div>
<div class="sub_desc">注:每位好友仅可被邀请一次</div>
<div class="btn_container">
<div class="share_btn">
<!--<div-->
<!--class="free_button"-->
<!--v-if="can_get"-->
<!--@click="joinFree"-->
<!--&gt;立即报名-->
<!--</div>-->
<div
class="free_button"
@click="inviteFriend"
>邀请好友获取
</div>
</div>
<!--<div-->
<!--class="free_button2"-->
<!--@click="showImg"-->
<!--&gt;获取邀请卡-->
<!--</div>-->
</div>
<div v-if="invite_num>0" @click="joinFree">
<div class="text_btn">
<span>立即免押金报名</span>
<img class="free_arrow" src="../assets/free_arrow.png" alt="">
</div>
<div class="sub_desc" style="margin-top: .15rem">须当日23:50前完成报名, 如已报名可次日使用</div>
</div>
</div>
<ShareModal
v-on:close="closeShareModal"
v-if="showShareModal"
></ShareModal>
</div>
</template>
<style>
div.Free {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
border: 1px solid transparent;
text-align: center;
}
div.Free .close_icon {
display: block;
position: absolute;
top: 0.2rem;
right: 0.2rem;
width: 0.3rem;
}
div.Free .content {
width: 6.4rem;
height: 7.6rem;
background: #ffffff;
border-radius: 0.06rem;
margin: auto;
position: absolute;
top: -1rem;
left: 0;
bottom: 0;
right: 0;
border: 1px solid transparent;
}
div.Free .content .title {
font-size: 0.4rem;
color: #282828;
margin-top: 0.6rem;
font-weight: bold;
}
div.Free .content .sub_title {
margin-top: 0.18rem;
font-size: 0.4rem;
color: #282828;
}
div.Free .content img.main_pic {
width: 3.2rem;
margin-top: 0.2rem;
}
div.Free .content .desc {
margin-top: 0.14rem;
color: #5a5a5a;
font-size: 0.28rem;
}
div.Free .content .desc span {
font-size: 0.36rem;
color: #282828;
font-weight: bold;
}
div.Free .content .sub_desc {
margin-top: 0.3rem;
color: #a5a5a5;
font-size: 0.24rem;
}
div.Free .content .free_button {
width: 5rem;
height: 0.88rem;
/*margin-top: 0.4rem;*/
/*margin-left: calc((6.4rem - 5rem) / 2);*/
background: #6eb5f5;
border-radius: 0.44rem;
font-size: 0.38rem;
font-weight: bold;
color: #ffffff;
line-height: calc(0.88 / 0.38);
}
div.Free .content .free_button2 {
width: 2.6rem;
height: 0.88rem;
/*margin-top: 0.4rem;*/
/*margin-left: calc((6.4rem - 5rem) / 2);*/
background: #ffbb34;
border-radius: 0.44rem;
font-size: 0.38rem;
font-weight: bold;
color: #ffffff;
line-height: calc(0.88 / 0.38);
margin-left: 0.3rem;
}
</style>
<style scoped>
.btn_container {
display: flex;
justify-content: center;
margin-top: .3rem;
}
.text_btn {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
margin-top: .25rem;
font-size: .3rem;
font-weight: bold;
color: #5a5a5a;
}
.free_arrow {
margin-left: .1rem;
width: .26rem;
}
</style>
<script>
import ShareModal from "@/components/ShareModal.vue";
import {dakaPay, shareContent, track, liinShare} from "@/components/axios/api";
export default {
name: "Free",
components: {
ShareModal
},
data() {
return {
showShareModal: false,
userData: null
// can_get: false,
// invite_num: 4
};
},
methods: {
//打开分享图
showImg() {
// this.$emit("showShareImg", "code_contract")
},
// 关闭弹窗
closeModal() {
shareContent("").then(res => {
let result = res.data;
let links = `${location.href.split("#")[0].split("?")[0]}`;
wx.updateAppMessageShareData({
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接
imgUrl: result.img_url, // 分享图标
success: function () {
}
});
wx.onMenuShareAppMessage({
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: result.img_url, // 分享图标
success: function () {
// 用户点击了分享后执行的回调函数
}
});
// wx.onMenuShareTimeline({
// title: result.title, // 分享标题
// link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
// imgUrl: result.img_url, // 分享图标
// success: function () {
// }
// });
});
this.$emit("close", true);
},
closeShareModal() {
this.showShareModal = false;
},
// 邀请好友
inviteFriend() {
this.showShareModal = true;
let id = this.userData.id;
track("free_contract_share");
let links = `${
location.href.split("#")[0].split("?")[0]
}?inviter=${id}&from_type=free_contract&`;
shareContent("free_contract").then(res => {
let result = res.data;
console.log("分享内容", result, links);
let option1 = {
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接
imgUrl: result.img_url, // 分享图标
success: function (res) {
track("free_contract_share_act");
console.log("option1Success", res)
}
}
wx.updateAppMessageShareData(option1);
//微信分享菜单测试
let option2 = {
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接
imgUrl: result.img_url, // 分享图标
success: function (res) {
console.log("option2Success", res)
}
}
let option3 = {
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: result.img_url, // 分享图标
success: function (res) {
// 用户点击了分享后执行的回调函数
track("free_contract_share_act");
console.log("option3Success", res)
},
fail: (err) => {
console.log("option3error", err)
}
}
wx.onMenuShareAppMessage(option3);
let option4 = {
title: result.title, // 分享标题
link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: result.img_url, // 分享图标
success: function (res) {
console.log("option4Success", res)
},
fail: (err) => {
console.log("option4error", err)
}
}
// wx.onMenuShareTimeline(option4);
console.log("option", option1, option2, option3, option4)
});
},
queryPayImage() {
liinShare().then(res => {
if (res.code == 0) {
console.log("open_platform2", res)
localStorage.setItem("is_follow", res.data.is_follow);
localStorage.setItem("liin_share_image", res.data.image);
localStorage.setItem("hb_url", res.data.hb_url);
localStorage.setItem("open_platform", res.data.open_platform);
}
});
},
showModal(title, desc) {
this.$emit("showModal", title, desc);
},
// 立即报名
joinFree() {
let days = this.days || 0
// this.queryPayImage();
dakaPay(days, 1).then(response => {
console.log("报名状态", response);
if (response.code == 1) {
this.showModal("温馨提示", response.msg);
return;
}
if (response.code == 0) {
this.$emit("close", true);
this.$emit("success")
// localStorage.setItem("is_every", 0)
// location.replace("#/Success");
}
});
},
getPlatform() {
var u = navigator.userAgent,
app = navigator.appVersion;
var isAndroid = u.indexOf("Android") > -1 || u.indexOf("Linux") > -1; //g
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if (isAndroid) {
return "android";
}
if (isIOS) {
return "ios";
}
return "other";
}
},
mounted() {
console.log("this.pageType", this.page_type)
if (window["userData"]) {
this.userData = window["userData"];
} else {
let localUserData = localStorage.getItem("read_userData");
if (localUserData) {
window["userData"] = JSON.parse(localUserData);
this.userData = window["userData"];
}
}
console.log("userData", this.userData)
},
props: ["v_data", "page_type", "days"],
computed: {
can_get() {
console.log("是否可以免单", this.v_data);
return this.v_data.can_get;
},
invite_num() {
console.log("邀请人数", this.v_data);
return this.v_data.cnt;
}
}
};
</script>
<template>
<div class="hello">
</div>
</template>
<script>
import {jssdk, shareContent} from "@/components/axios/api";
export default {
name: "HelloWorld",
props: {
msg: String
},
mounted() {
this.getConfig();
},
methods: {
// 微信分参数
getConfig() {
// if (sessionStorage.getItem("jssdk_ready") || !window["userData"]) {
// return;
// }
let url = location.href.split("#")[0]; //获取锚点之前的链接
// url = url.split("?")[0];
console.log("jssdk注入1", url);
jssdk(url).then(response => {
let res = response.data;
this.wxInit(res);
});
},
wxConfig() {
// console.log(wx);
// wx.config({
// debug: false,
// appId: "",
// timestamp: "",
// nonceStr: "",
// signature: "",
// jsApiList: [
// "onMenuShareTimeline",
// "onMenuShareAppMessage",
// "onMenuShareQQ",
// "onMenuShareWeibo",
// "onMenuShareQZone",
// "updateTimelineShareData"
// ]
// });
},
// 微信分享
wxInit(res) {
let url = location.href.split("#")[0]; //获取锚点之前的链接
// url = url.split("?")[0];
let links = url + "#/SignUp";
let title = "测试标题";
let desc = "测试描述";
let imgUrl = "";
console.log("获取jssdk数据", res);
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: "wx9af64967a0d40159", // 必填,公众号的唯一标识
timestamp: res.timestamp, // 必填,生成签名的时间戳
nonceStr: res.nonceStr, // 必填,生成签名的随机串
signature: res.signature, // 必填,签名
jsApiList: [
"onMenuShareTimeline",
"updateTimelineShareData",
"updateAppMessageShareData",
"chooseWXPay",
"onMenuShareAppMessage",
] // 必填,需要使用的JS接口列表
});
wx.ready( ()=> {
console.log("jssdk注入成功");
let links = `${
location.href.split("#")[0].split("?")[0]
}?test=1&`;
shareContent("free_contract").then(res => {
let result = res.data;
console.log("分享内容", result, links);
let option1 = {
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接
imgUrl: result.img_url, // 分享图标
success: function (res) {
console.log("option1Success", res)
}
}
wx.updateAppMessageShareData(option1);
//微信分享菜单测试
let option3 = {
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接
imgUrl: result.img_url, // 分享图标
success: function (res) {
console.log("option3Success", res)
}
}
wx.onMenuShareAppMessage(option3);
let option4 = {
title: result.title, // 分享标题
link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: result.img_url, // 分享图标
success: function (res) {
console.log("option4Success", res)
},
fail: (err) => {
console.log("option4error", err)
}
}
// wx.onMenuShareTimeline(option4);
});
console.log("this.$router.history.current.name",this.$router)
if (this.$router.history.current.name != "Daka") {
shareContent("pyq").then(result => {
console.log("pyq2", result)
wx.onMenuShareTimeline({
title: result.data.title, // 分享标题
link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: result.data.img_url, // 分享图标
success: (res) => {
// setTimeout(function(){
//回调要执行的代码
// alert(33)
// }, 500);
},
cancel: (res) => {
// alert(55)
},
fail: (res) => {
// alert(44)
}
})
})
}
// wx.updateAppMessageShareData({
// title: title, // 分享标题
// desc: desc, // 分享描述
// link: links, // 分享链接
// imgUrl: imgUrl, // 分享图标
// success: function() {}
// });
// //微信分享菜单测试
// wx.updateTimelineShareData({
// title: title, // 分享标题
// desc: desc, // 分享描述
// link: links, // 分享链接
// imgUrl: imgUrl, // 分享图标
// success: function() {}
// });
sessionStorage.setItem("jssdk_ready", 1);
});
wx.error(function (err) {
alert(JSON.stringify(err));
});
// 1秒后,如果还没有jssdk注入,则重新调用注入请求方法
// setTimeout(() => {
// if (!sessionStorage.getItem("jssdk_ready")) {
// this.getConfig();
// }
// }, 1000);
}
}
};
</script>
<style scoped>
</style>
<template>
<div class="Loading">
<div class="mask"></div>
<div class="loadingDialog">
<div class="loadEffect">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="loadingText">加载中,请稍等</div>
</div>
</div>
</template>
<script>
export default {
name: "Loading"
}
</script>
<style scoped>
.loadingText{
color: #ffffff;
margin-top: 0.3rem;
opacity: 0.9;
font-size: .18rem;
}
.Loading {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.mask {
width: 100%;
height: 100%;
background: #000000;
opacity: 0.7;
}
.loadingDialog {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.loadEffect{
width: 1rem;
height: 1rem;
position: relative;
}
.loadEffect span{
display: inline-block;
width: 0.16rem;
height: 0.16rem;
border-radius: 50%;
background: #ffffff;
position: absolute;
-webkit-animation: load 1.04s ease infinite;
}
@-webkit-keyframes load{
0%{
opacity: 1;
}
100%{
opacity: 0.2;
}
}
.loadEffect span:nth-child(1){
left: 0;
top: 50%;
margin-top:-0.08rem;
-webkit-animation-delay:0.13s;
}
.loadEffect span:nth-child(2){
left: 0.14rem;
top: 0.14rem;
-webkit-animation-delay:0.26s;
}
.loadEffect span:nth-child(3){
left: 50%;
top: 0;
margin-left: -0.08rem;
-webkit-animation-delay:0.39s;
}
.loadEffect span:nth-child(4){
top: 0.14rem;
right:0.14rem;
-webkit-animation-delay:0.52s;
}
.loadEffect span:nth-child(5){
right: 0;
top: 50%;
margin-top:-0.08rem;
-webkit-animation-delay:0.65s;
}
.loadEffect span:nth-child(6){
right: 0.14rem;
bottom:0.14rem;
-webkit-animation-delay:0.78s;
}
.loadEffect span:nth-child(7){
bottom: 0;
left: 50%;
margin-left: -0.08rem;
-webkit-animation-delay:0.91s;
}
.loadEffect span:nth-child(8){
bottom: 0.14rem;
left: 0.14rem;
-webkit-animation-delay:1.04s;
}
</style>
<template>
<div class="Modal">
<div class="content">
<div v-if="!option.showIcon" :class="option.changeImportant?'modal_desc':'modal_title'">
{{title_text}}
</div>
<div v-else>
<img class="icon" src="../assets/ic_fri.png" alt="">
</div>
<div :class="option.changeImportant?'modal_title':'modal_desc'" :style="option.showIcon?'margin-top:.2rem':''">
{{title_desc}}
</div>
<div v-if="option.subDesc" :class="option.changeImportant?'modal_title':'modal_desc'" style="margin-top: .1rem">
{{option.subDesc}}
</div>
<div class="btn_container">
<div class="cancel_btn" @click="closeModal" v-if="option.showCancel">
取消
</div>
<div class="confirm_btn" @click="confirmModal">
{{option.btnText?option.btnText:'确定'}}
</div>
</div>
</div>
</div>
</template>
<style scoped>
.icon {
width: 1.07rem;
margin-top: .4rem;
}
div.Modal {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
border: 1px solid transparent;
text-align: center;
}
div.Modal .content {
width: 5.8rem;
height: 3.7rem;
background: #ffffff;
border-radius: 0.2rem;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
border: 1px solid transparent;
}
div.Modal .content .modal_title {
font-size: 0.36rem;
color: #282828;
margin-top: 0.6rem;
font-weight: bold;
}
div.Modal .content .modal_desc {
margin-top: 0.6rem;
font-size: 0.3rem;
padding: 0 0.5rem;
color: #8a8a8a;
line-height: 1.2;
}
.btn_container {
width: 100%;
display: flex;
position: absolute;
bottom: 0;
}
div.Modal .content .cancel_btn {
flex: 1;
border-top: 1px solid #e8e8e8;
border-right: 1px solid #e8e8e8;
padding: 0.36rem 0;
color: rgba(136, 136, 136, 1);
font-weight: bold;
/*height: 1.02rem;*/
font-size: 0.3rem;
}
div.Modal .content .confirm_btn {
flex: 1;
border-top: 1px solid #e8e8e8;
padding: 0.36rem 0;
color: rgba(26, 211, 212, 1);
font-weight: bold;
/*height: 1.02rem;*/
font-size: 0.3rem;
}
</style>
<script>
export default {
name: "Modal",
components: {},
data() {
return {};
},
methods: {
// 关闭弹窗
confirmModal() {
this.$emit("confirmModal", this.option.scb)
},
closeModal() {
this.$emit("close", true);
},
// 邀请好友
inviteFriend() {
},
// 立即报名
joinModal() {
}
},
props: ["title", "desc", "option"],
computed: {
title_text() {
return this.title;
},
title_desc() {
return this.desc;
}
}
};
</script>
<template>
<div class="notice_bonus" v-if="isShowNotice">
<img class="icon_container" src="../images/components/NoticeBonus/sy_guangbo.png" alt="">
<div ref="container" class="msg_container">
<!--<div class="notice_msg" v-for='item in notice_list'>-->
<!--{{item}}-->
<!--</div>-->
<div ref="msg1" :class="['notice_msg', startAnimate?'msg1':'']">{{msg1}}</div>
<div :class="['notice_msg', startAnimate?'msg2':'']">{{msg2}}</div>
</div>
</div>
</template>
<style>
.notice_bonus {
width: 3.6rem;
height: .32rem;
border-radius: .06rem;
background: rgba(255, 255, 255, .2);
display: flex;
align-items: center;
padding: 0 .14rem;
box-sizing: border-box;
}
.icon_container {
width: .22rem;
height: .2rem;
flex-shrink: 0;
margin-right: .1rem;
}
.msg_container {
flex: 1;
height: .32rem;
transform-style: preserve-3d;
overflow: hidden;
}
.notice_msg {
font-size: .2rem;
color: #fff;
line-height: .32rem;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
}
.msg1 {
transform: translate3d(0, 0.32rem, 0);
animation: rowUp 10s infinite;
/* transform: translateZ(35rpx); */
}
.msg2 {
transform: translate3d(0, 0, 0);
animation: rowUp2 10s infinite;
/* transform: rotateX(90deg) translateZ(35rpx); */
}
/* .rotate-animation {
animation: rotate .3s linear 0s 1 normal forwards;
}
@keyframes rotate {
0% {
transform: rotateX(0deg);
}
100% {
transform: rotateX(-90deg);
}
} */
@keyframes rowUp {
0% {
-webkit-transform: translate3d(0, 0.32rem, 0);
transform: translate3d(0, 0.32rem, 0);
}
10% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
40% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
50% {
-webkit-transform: translate3d(0, -0.32rem, 0);
transform: translate3d(0, -0.32rem, 0);
}
100% {
-webkit-transform: translate3d(0, -0.32rem, 0);
transform: translate3d(0, -0.32rem, 0);
}
}
@keyframes rowUp2 {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
50% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
60% {
-webkit-transform: translate3d(0, -0.32rem, 0);
transform: translate3d(0, -0.32rem, 0);
}
90% {
-webkit-transform: translate3d(0, -0.32rem, 0);
transform: translate3d(0, -0.32rem, 0);
}
100% {
-webkit-transform: translate3d(0, -0.96rem, 0);
transform: translate3d(0, -0.96rem, 0);
}
}
</style>
<script>
import {gameInfo} from "@/components/axios/api";
export default {
name: "NoticeBonus",
data() {
return {
isShowNotice:false,
notice_list: [],
gameInfo: {
"fly_top": [],
"fly_bot": []
},
canScroll: true,
curIndex: 0,
startAnimate: false,
msg1: "",
msg2: "",
};
},
// props: ["notice_list"],
// computed: {
// notice() {
// return this.notice_list;
// }
// },
methods: {
stopScroll(e) {
console.log(e)
e.preventDefault();
},
getGameInfo(nonRefresh) {
gameInfo().then(result => {
console.log("result", result)
if (result.code == 0) {
let fly_bot = result.data.fly_bot
let fly_top = result.data.fly_top
let len = Math.max(fly_bot.length, fly_top.length)
let list = []
for (let i = 0; i < len; i++) {
fly_bot[i] && (list.push(fly_bot[i]))
fly_top[i] && (list.push(fly_top[i]))
}
this.notice_list = list
this.canScroll = true
this.msg1 = this.notice_list[0]
this.msg2 = this.notice_list[1]
console.log("this.notice_list", this.notice_list)
this.isShowNotice=true
}
})
},
msgAnimate() {
setTimeout(() => {
this.startAnimate = true
}, 100)
let timer = sessionStorage.getItem("timer")
if (timer) {
clearInterval(Number(timer))
}
let newTimer = setInterval(() => {
if (Math.abs(this.notice_list.length - this.curIndex) <= 2) {
this.curIndex = 0
if (window.location.hash == "#/Daka") {
this.getGameInfo()
}
} else {
this.curIndex += 2
}
this.msg1 = this.notice_list[this.curIndex]
this.msg2 = this.notice_list[this.curIndex + 1]
}, 10000)
sessionStorage.setItem("timer", newTimer + "")
}
},
created() {
this.getGameInfo()
},
mounted() {
this.msgAnimate()
}
};
</script>
<template>
<div class="pay_fail_modal">
<div class="content">
<img class="closeBtn" src="../assets/ic_close.png" alt="" @click="closeModal">
<div class="title">支付遇到问题?</div>
<div class="modal_tip">可长按识别下方二维码</div>
<div class="modal_tip">联系客服小姐姐立即为你解决哦~</div>
<div class="qrcode">
<img src="../assets/qrcode.jpg" alt="">
</div>
</div>
</div>
</template>
<script>
export default {
name: "PayFailModal",
methods:{
closeModal() {
this.$emit("close")
}
}
}
</script>
<style scoped>
.pay_fail_modal {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
border: 1px solid transparent;
z-index: 100;
text-align: center;
}
.content {
width: 6.4rem;
height: 7.5rem;
background: #ffffff;
position: absolute;
left: 50%;
top: 50%;
margin-left: -3.2rem;
margin-top: -3.75rem;
}
.closeBtn{
width: .3rem;
position: absolute;
right: .2rem;
top: .2rem;
}
.title {
font-size: .4rem;
font-weight: bold;
margin: .6rem 0;
}
.modal_tip {
font-size: .28rem;
color: rgba(90, 90, 90, 1);
margin-bottom: .2rem;
}
.qrcode{
display: flex;
justify-content: center;
align-items: center;
}
.qrcode img {
width: 3.86rem;
display: block;
}
</style>
<template>
<div class="Rank">
<div class="mask"></div>
<div class="rank_container">
<div class="rank_banner">
<img class="banner_bg" src="../assets/img_top.png" alt="">
<div class="banner_container">
<div class="banner_top">
<div class="banner_top_title">{{period}}期 总奖金(元)</div>
<div class="banner_top_data">{{detailData.total.total_money?Number(detailData.total.total_money).toFixed(2):0}}</div>
</div>
<div class="banner_bottom">
<div class="banner_bottom_item">
<div class="banner_bottom_title">参与人数</div>
<div class="banner_bottom_data">{{Number(detailData.total.join_num)}}</div>
</div>
<div class="banner_bottom_item">
<div class="banner_bottom_title">平均奖金(元)</div>
<div class="banner_bottom_data">{{Number(detailData.total.avg_bonus).toFixed(2)}}</div>
</div>
<div class="banner_bottom_item">
<div class="banner_bottom_title">最高奖金(元)</div>
<div class="banner_bottom_data">{{Number(higtest_bonus).toFixed(2)}}</div>
</div>
</div>
</div>
</div>
<div class="rank_list">
<div class="list_header">
<div class="header_item">排名</div>
<div class="header_item">头像昵称</div>
<div class="header_item">获得奖金(元)</div>
<div class="header_item">打卡时间</div>
</div>
<div class="list_container" @scroll="onScroll" @touchend="startStopScroll" @touchstart="endStopScroll">
<div class="record_item"
v-for="(item,index) in this.detailData.records">
<div class="rank_num">
<div v-if="(index+1)>3">
{{index+1}}
</div>
<img v-else :src="rankImg[index].src" alt="">
</div>
<div class="record_user">
<img
:src="item.user_info.avatar"
alt=""
class="record_avatar"
>
<div class="record_nickname">
{{item.user_info.nickname?item.user_info.nickname.substr(0,6):""}}
</div>
</div>
<div class="record_money">{{item.money |moneyFormatter}}({{item.number?item.number:0}}份)</div>
<div class="record_time">{{item.daka_time?item.daka_time.substr(11, 8):""}}</div>
</div>
<div class="full_tips"
v-if="this.detailData.records.length>95">
只显示前100人
</div>
</div>
<!--<div class="list_footer">-->
<!--<div class="sign_btn" @touchstart="doSign" @touchend="startStopScroll">{{buttonText}}</div>-->
<!--</div>-->
</div>
<img class="rank_close" src="../assets/ic_close2.png" alt="" @touchend="closeRank">
</div>
</div>
</template>
<script>
import {
dakaRank
} from "@/components/axios/api";
export default {
name: "Rank",
data() {
return {
period: "",
page: 1,
canScroll: true,
higtest_bonus: 0,
detailData: {
total: {},
records: [],
next_page: true,
higtest_bonus: ""
},
isTouchingScoller: false,
rankImg: [
{
src: require("../assets/ic_record_1.png")
},
{
src: require("../assets/ic_record_2.png")
},
{
src: require("../assets/ic_record_3.png")
}
],
};
},
props: ["rankStatus", "isShowRank"],
methods: {
emitTouching() {
this.$emit("rankTouching", this.isTouchingScoller);
},
startStopScroll() {
console.log("startStopScroll")
this.isTouchingScoller = false
this.emitTouching()
},
endStopScroll() {
console.log("endStopScroll")
this.isTouchingScoller = true
this.emitTouching()
},
doSign() {
this.isTouchingScoller = true
this.emitTouching()
console.log("doSign", this.rankStatus)
if (this.rankStatus != 2) {
this.$emit("doSign", this.rankStatus);
this.$emit("closeRank");
}
},
closeRank(e) {
e.stopPropagation()
// this.isTouchingScoller = true
this.emitTouching()
this.$emit("closeRank");
},
getTodayPeriod() {
let today = new Date()
return `${today.getFullYear()}${this.fillzero(today.getMonth() + 1)}${this.fillzero(today.getDate())}`
},
fillzero(num) {
return num < 10 ? `0${num}` : num
},
getRecordDetail(notRefresh) {
dakaRank(this.page, 10, "")
.then(result => {
this.canScroll = true;
console.log(result);
if (result.code == 0) {
let data = JSON.parse(JSON.stringify(result.data));
data.records = data.records.filter(item => {
return !!item.user_info;
});
console.log("过滤后数据", data);
if (!notRefresh) {
this.detailData = data;
this.period = this.detailData.period
this.detailData.higtest_bonus && (this.higtest_bonus = this.detailData.higtest_bonus)
} else {
this.detailData.next_page = data.next_page;
this.detailData.total = data.total;
this.detailData.records = this.detailData.records.concat(
data.records
);
}
}
})
.catch(e => {
this.canScroll = true;
console.log("dakaRecordDetail err", e);
});
},
onScroll(event) {
if (this.detailData.next_page && this.canScroll) {
let offsetHeight = event.currentTarget.offsetHeight,
scrollHeight = event.target.scrollHeight,
scrollTop = event.target.scrollTop,
scrollBottom = offsetHeight + scrollTop;
if (Math.abs(scrollHeight - scrollBottom) < 50) {
this.canScroll = false;
console.log("onScroll", "到底部");
if (this.page < 10) {
this.page += 1;
this.getRecordDetail(true);
}
}
}
}
},
filters: {
moneyFormatter(val) {
if (val && !isNaN(val)) {
return Number(val).toFixed(2);
} else {
return "0.00";
}
}
},
created() {
console.log("this.rankStatus", this.rankStatus)
this.getRecordDetail();
},
computed: {
buttonText() {
if (this.rankStatus == 0) {
return "立即报名"
} else if (this.rankStatus == 1) {
return "已报名"
} else {
return "报名已满"
}
}
}
}
</script>
<style scoped>
.Rank {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
text-align: center;
}
.mask {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: #000;
opacity: 0.7;
}
.rank_container {
width: 6.9rem;
height: 11.08rem;
position: fixed;
top: 50%;
left: 50%;
margin-top: -5.54rem;
margin-left: -3.45rem;
display: flex;
flex-direction: column;
}
.rank_close {
position: absolute;
width: 0.3rem;
height: 0.3rem;
top: 0.2rem;
right: 0.2rem;
}
.rank_banner {
position: relative;
}
.banner_bg {
display: block;
width: 100%;
}
.banner_container {
position: absolute;
left: 0;
top: 0;
width: 100%;
color: #ffffff;
}
.banner_bottom {
display: flex;
}
.banner_bottom_item {
flex: 1;
}
.banner_top_title {
margin: 0.3rem 0 0.3rem;
font-size: 0.26rem;
color: #fff;
}
.banner_bottom_title {
margin: 0.6rem 0 0.3rem;
font-size: 0.26rem;
color: #fff;
}
.banner_top_data {
font-size: 0.72rem;
color: #ffffff;
font-weight: bold;
}
.banner_bottom_data {
font-size: 0.34rem;
color: #ffffff;
font-weight: bold;
}
.rank_list {
flex: 1;
background: #fff;
display: flex;
flex-direction: column;
}
.list_header {
display: flex;
font-size: 0.24rem;
color: #97d7e7;
margin: 0.26rem 0 0.16rem;
}
.header_item {
flex: 1;
font-size: 0.24rem;
}
.header_item:nth-child(2) {
flex: 2;
text-align: left;
}
.list_container {
flex: 1;
overflow-y: scroll;
-webkit-overflow-scrolling: touch
}
.list_container::-webkit-scrollbar {
display: none;
}
.record_item {
display: flex;
align-items: center;
padding: 0.2rem 0;
border-bottom: 0.01rem solid #e8e8e8;
}
.rank_num,
.record_user,
.record_money,
.record_time {
flex: 1;
font-size: 0.24rem;
color: #000000;
}
.record_money {
text-align: left;
}
.rank_num img {
width: 0.6rem;
}
.record_nickname {
font-size: 0.24rem;
}
.record_user {
display: flex;
justify-content: flex-start;
align-items: center;
flex: 2;
text-align: left;
}
.record_avatar {
background: #000;
width: 0.58rem;
height: 0.58rem;
border-radius: 50%;
margin-right: 0.1rem;
flex-shrink: 0;
}
.full_tips {
font-size: 0.28rem;
color: #bbbbbb;
height: 0.9rem;
line-height: calc(0.9 / 0.28);
}
.list_footer {
width: 100%;
height: 1.4rem;
display: flex;
justify-content: center;
align-items: center;
}
.sign_btn {
width: 4.2rem;
height: .88rem;
display: flex;
justify-content: center;
align-items: center;
background: #FFBB34;
font-size: 0.38rem;
color: #fff;
font-weight: bold;
border-radius: 0.44rem;
}
</style>
<template>
<div class="Reborn">
<div class="content">
<img
src="../assets/ic_close.png"
class="close_icon"
@click="closeModal"
>
<div
class="title_container"
v-if="!can_get"
>
<div class="title">邀请1位好友报名成功</div>
<div class="sub_title">可获得1次复活机会</div>
</div>
<div
class="title_container"
v-if="can_get"
>
<div class="title">已有好友帮你获得1次复活机会</div>
</div>
<img
src="../assets/pic_fh.png"
class="main_pic"
>
<div class="desc">已获得<span class="invite_num"> {{invite_num}} </span>张复活卡</div>
<div class="sub_desc">当日未完成打卡,可在24:00前使用复活卡复活</div>
<div class="btn_container">
<div class="share_btn">
<div
class="Reborn_button"
v-if="can_get"
@click="joinReborn"
>复活打卡
</div>
<div
class="Reborn_button"
v-if="!can_get"
@click="inviteFriend"
>邀请好友
</div>
</div>
<!--<div-->
<!--class="Reborn_button2"-->
<!--@click="showImg"-->
<!--&gt;获取邀请卡-->
<!--</div>-->
</div>
</div>
<ShareModal
v-on:close="closeShareModal"
v-if="showShareModal"
></ShareModal>
</div>
</template>
<style>
div.Reborn {
text-align: center;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
border: 1px solid transparent;
}
div.Reborn .close_icon {
display: block;
position: absolute;
top: 0.2rem;
right: 0.2rem;
width: 0.3rem;
}
div.Reborn .content {
width: 6.4rem;
height: 7.25rem;
background: #ffffff;
border-radius: 0.06rem;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
border: 1px solid transparent;
}
div.Reborn .title_container {
height: 1.6rem;
padding-top: 0;
border: 1px solid transparent;
}
div.Reborn .content .title {
font-size: 0.4rem;
color: #282828;
margin-top: 0.6rem;
font-weight: bold;
}
div.Reborn .content .sub_title {
margin-top: 0.18rem;
font-size: 0.4rem;
color: #282828;
}
div.Reborn .content img.main_pic {
width: 3.2rem;
margin-top: 0.2rem;
}
div.Reborn .content .desc {
margin-top: 0.24rem;
color: #5a5a5a;
font-size: 0.28rem;
}
div.Reborn .content .desc span {
font-size: 0.36rem;
color: #282828;
font-weight: bold;
}
div.Reborn .content .sub_desc {
margin-top: 0.3rem;
color: #5a5a5a;
font-size: 0.24rem;
}
div.Reborn .content .Reborn_button {
width: 5rem;
height: 0.88rem;
background: #6eb5f5;
border-radius: 0.44rem;
font-size: 0.38rem;
font-weight: bold;
color: #ffffff;
line-height: calc(0.88 / 0.38);
}
div.Reborn .content .Reborn_button2 {
width: 2.6rem;
height: 0.88rem;
margin-left: 0.3rem;
background: #ffbb34;
border-radius: 0.44rem;
font-size: 0.38rem;
font-weight: bold;
color: #ffffff;
line-height: calc(0.88 / 0.38);
}
</style>
<style scoped>
.btn_container {
display: flex;
justify-content: center;
margin-top: .4rem;
}
</style>
<script>
import ShareModal from "@/components/ShareModal.vue";
import {shareContent, track} from "@/components/axios/api";
export default {
name: "Reborn",
components: {ShareModal},
data() {
return {
showShareModal: false,
userData: null
// can_get: false,
// invite_num: 4
};
},
methods: {
//打开分享图
showImg() {
this.$emit("showShareImg", "code_rebirth")
},
// 关闭弹窗
closeModal() {
shareContent("").then(res => {
let result = res.data;
let links = `${location.href.split("#")[0].split("?")[0]}`;
wx.updateAppMessageShareData({
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接
imgUrl: result.img_url, // 分享图标
success: function () {
}
});
wx.onMenuShareAppMessage({
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: result.img_url, // 分享图标
success: function () {
// 用户点击了分享后执行的回调函数
}
});
// wx.onMenuShareTimeline({
// title: result.title, // 分享标题
// link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
// imgUrl: result.img_url, // 分享图标
// success: function () {
// }
// });
});
this.$emit("close", true);
},
closeShareModal() {
this.showShareModal = false;
},
// 邀请好友
inviteFriend() {
this.showShareModal = true;
let id = this.userData.id;
track("rebitrh_share");
console.log("处理前连接", location.href);
let links = `${
location.href.split("#")[0].split("?")[0]
}?inviter=${id}&from_type=rebirth&`;
console.log("处理后的连接", links);
shareContent("rebirth").then(res => {
let result = res.data;
wx.updateAppMessageShareData({
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接
imgUrl: result.img_url, // 分享图标
success: function () {
}
});
wx.onMenuShareAppMessage({
title: result.title, // 分享标题
desc: result.desc, // 分享描述
link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: result.img_url, // 分享图标
success: function () {
// 用户点击了分享后执行的回调函数
track("rebitrh_share_act");
}
});
// wx.onMenuShareTimeline({
// title: result.title, // 分享标题
// link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
// imgUrl: result.img_url, // 分享图标
// success: function () {
// }
// });
});
},
// 立即报名
joinReborn() {
this.$emit("rebirth", true);
}
},
mounted() {
if (window["userData"]) {
this.userData = window["userData"];
} else {
let localUserData = localStorage.getItem("read_userData");
if (localUserData) {
window["userData"] = JSON.parse(localUserData);
this.userData = window["userData"];
}
}
},
props: ["v_data"],
computed: {
can_get() {
return this.v_data.can_get;
},
invite_num() {
return this.v_data.cnt;
}
}
};
</script>
<template>
<div class="redpack_dialog">
<div class="redpack_img" v-if="type==1">
<img :src="withdrawData.task_url" alt="">
</div>
<div class="redpack_img" v-else>
<img :src="withdrawData.withdraw_url_1" alt="">
</div>
<div class="redpack_tip">长按识别小程序码领取</div>
<div class="close_btn" @click="closeDialog">
<img src="../assets/ic_close3.png" alt="">
</div>
</div>
</template>
<script>
export default {
name: "RedpackDialog",
props:["withdrawData","type"],
methods: {
closeDialog() {
this.$emit("close")
}
}
}
</script>
<style scoped>
.redpack_tip {
position: absolute;
left: 50%;
top: 50%;
margin-left: -1.2rem;
margin-top: 3.35rem;
color: #fff;
font-size: 0.34rem;
animation: redpack_tip_animate 1.5s infinite;
}
@keyframes redpack_tip_animate {
0% {
transform: scale(1, 1)
}
50% {
transform: scale(1.2, 1.2)
}
100% {
transform: scale(1, 1)
}
}
.redpack_dialog {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
border: 1px solid transparent;
z-index: 100;
text-align: center;
}
.redpack_img {
position: absolute;
left: 50%;
top: 50%;
width: 6.4rem;
margin-top: -4.5rem;
margin-left: -3.2rem;
}
.redpack_img img {
width: 100%;
}
.close_btn {
width: .7rem;
position: absolute;
top: .3rem;
right: .5rem;
}
.close_btn img{
width: 100%;
height: 100%;
}
</style>
<template>
<div
class="ShareModal"
@click="closeModal"
>
<img class="arrow"
src="../assets/share_tip_arrow.png"
alt=""
>
<img class="tip"
src="../assets/share_tip.png"
alt=""
>
</div>
</template>
<style>
div.ShareModal {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
border: 1px solid transparent;
z-index: 100;
}
.tip {
position: absolute;
width: 3rem;
height: 1.55rem;
top: 1.2rem;
right: 1.2rem;
}
.arrow{
position: absolute;
width: 1.2rem;
height: 0.95rem;
top: 0.1rem;
right: 0.3rem;
animation: arrowMove 1s infinite;
}
@keyframes arrowMove {
0%{
top: 0.1rem;
right: 0.3rem;
}
50%{
top: 0.3rem;
right: 0.5rem;
}
0%{
top: 0.1rem;
right: 0.3rem;
}
}
</style>
<script>
export default {
name: "ShareModal",
data() {
return {};
},
methods: {
// 关闭弹窗
closeModal() {
this.$emit("close", true);
}
}
};
</script>
<template>
<div class="title_container">
<img class="back" :src="arrowSrc" @click="goBack" v-if="show_back">
<div class="title_text" :style="'color:'+thisTitleColor">{{title_text}}</div>
<div class="my_data" v-if="show_my_data">
<router-link to="/MyData" replace>个人信息</router-link>
</div>
<div class="my_data" v-if="show_blame">
<router-link to="/Blame" replace>投诉</router-link>
</div>
</div>
</template>
<script>
export default {
name: "Title",
data() {
return {
blackArrow: require('../images/components/Title/ic_back_black.png'),
whiteArrow: require('../images/components/Title/ic_back_white.png'),
};
},
props: ["title", "show_back", "show_my_data", "show_blame", "arrowColor", "titleColor"],
methods: {
goBack() {
this.$emit("goback", true);
}
},
computed: {
title_text() {
return this.title;
},
thisTitleColor() {
let titleColor = '#fff';
if (this.titleColor) {
titleColor = this.titleColor;
}
return titleColor;
},
arrowSrc() {
let arrowSrc = this.whiteArrow;
if (this.arrowColor === 'black') {
arrowSrc = this.blackArrow;
} else if (this.arrowColor === 'white') {
arrowSrc = this.whiteArrow;
}
return arrowSrc;
}
}
};
</script>
<style>
.title_container {
font-size: 0.36rem;
color: #ffffff;
}
.title_container > div {
font-size: 0.36rem;
}
.title_container > div > a {
font-size: 0.32rem;
color: #ffffff;
text-decoration: none;
}
.back {
width: 0.24rem;
height: 0.42rem;
left: 0.2rem;
top: 0.26rem;
position: absolute;
}
.my_data {
position: absolute;
top: 0.32rem;
right: 0.2rem;
font-size: 0.32rem;
}
.big .title_container {
padding-top: 0.3rem;
}
.big .my_data {
top: 0.32rem;
font-size: 0.32rem;
}
.title_text {
height: .36rem;
font-size: 0.36rem;
line-height: 1;
text-align: center;
padding: .3rem 0;
}
</style>
\ No newline at end of file
import {fetch} from "./fetch"; //引用fetch.js
import api from './url'; //引用url.js
function getPlatform() {
var u = navigator.userAgent,
app = navigator.appVersion;
var isAndroid = u.indexOf("Android") > -1 || u.indexOf("Linux") > -1; //g
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if (isAndroid) {
return "android";
}
if (isIOS) {
return "ios";
}
}
//打卡查询
export function dakaStatus() { //lookOption是你要调用接口的名字,issuer,userId是传进来的参数
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.dakaStatusPath,
method: 'GET',//请求方法
params: {
//传过去的参数
}
})
}
// 打卡操作
export function daka(use_rebirth) { //lookOption是你要调用接口的名字,issuer,userId是传进来的参数
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.dakaPath,
method: 'GET',//请求方法
params: {
//传过去的参数
use_rebirth: use_rebirth || 0,
}
})
}
// 打卡总计
export function dakaRecordTotal() {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.dakaRecordsTotalPath,
method: 'GET',//请求方法
params: {
//传过去的参数
}
})
}
// 打卡记录列表
export function dakaRecordList(page, perpage) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.dakaRecordsListPath,
method: 'GET',//请求方法
params: {
//传过去的参数
// 第几页(从1开始)
page: page,
// 每页多少(默认为10)
per_page: perpage
}
})
}
// 打卡总计
export function dakaRecordDetail(page, perpage, period, daka) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.dakaRecordsDetailPath,
method: 'GET',//请求方法
params: {
//传过去的参数
// 第几页(从1开始)
page: page,
// 每页多少(默认为10)
perpage: perpage,
period: period,
daka: daka
}
})
}
// 走马灯,玩法
export function gameInfo() {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.gameInfoPath,
method: 'GET',//请求方法
params: {
//传过去的参数
}
})
}
// 余额查询
export function balanceQuery() {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.balanceQueryPath,
method: 'GET',//请求方法
params: {
//传过去的参数
}
})
}
// 余额提现
export function balanceWithdraw(money, code) {
let params = {}
if (code) {
params["js_code"] = code
} else {
params["money"] = money
}
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.balanceWithdrawPath,
method: 'GET',//请求方法
params: params
})
}
// 常见问题
export function faq() { //lookOption是你要调用接口的名字,issuer,userId是传进来的参数
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.faqPath,
method: 'GET',//请求方法
params: {
//传过去的参数
}
})
}
// 客服
export function kefu() { //lookOption是你要调用接口的名字,issuer,userId是传进来的参数
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.kefuPath,
method: 'GET',//请求方法
params: {
//传过去的参数
}
})
}
// 关注公众号
export function ocFollow() { //lookOption是你要调用接口的名字,issuer,userId是传进来的参数
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.ocFollowPath,
method: 'GET',//请求方法
params: {
//传过去的参数
}
})
}
// 报名支付
export function dakaPay(days,use_contract) {
let now = new Date();
let year = now.getFullYear();
let month = now.getMonth() + 1;
let day = now.getDate();
let date_time = new Date(`${year}/${month}/${day}`).getTime();
let inviter = "";
let from_type = "";
if (Number(localStorage.getItem('last_share_time') || 0) >= date_time && !use_contract) {
inviter = localStorage.getItem('inviter');
from_type = localStorage.getItem('from_type');
}
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.dakaPayPath,
method: 'GET',//请求方法
params: {
//传过去的参数
// platform: ios, android, other
platform: getPlatform(),
use_contract: use_contract || 0,
inviter_id: inviter || '',
from_type: from_type || '',
days: days || 0
}
})
}
// jssdk注入
export function jssdk(url) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.jssdkPath,
method: 'GET',//请求方法
params: {
//传过去的参数
// platform: ios, android, other
url: url
}
})
}
// 用户复活卡,免契约金卡信息
export function userCards() {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.userCardPath,
method: 'GET',//请求方法
params: {
//传过去的参数
}
})
}
// 获取分享内容
export function shareContent(from_type) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.shareContentPath,
method: 'GET',//请求方法
params: {
//传过去的参数
from_type: from_type || ''
}
})
}
// 获取规则内容
export function getRule() {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.getRulePath,
method: 'GET',//请求方法
params: {
//传过去的参数
from_type: from_type || ''
}
})
}
// 数据埋点
export function track(key) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.trackingPath,
method: 'GET',//请求方法
params: {
//传过去的参数
p: `study`,
k: `${key}`,
u: window['userData'] ? window['userData'].id : ''
}
})
}
// 立应关注分享图
export function liinShare(key) {
var new_user = sessionStorage.getItem('new_user') ? 1 : 0;
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.liinShareImagePath,
method: 'GET',//请求方法
params: {
//传过去的参数
new_user: new_user
}
})
}
// 每日分享图
export function dailyShare(from_type) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.dailyShareImagePath,
method: 'GET',//请求方法
params: {
//传过去的参数
from_type: from_type || "daily_share"
}
})
}
// 打卡排行榜
export function dakaRank(page, per_page, period) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.dakaRankPath,
method: 'GET',//请求方法
params: {
//传过去的参数
page: page || 1,
per_page: per_page || 10,
period: period || "",
}
})
}
// 新用户
export function firstDaka() {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.firstDakaPath,
method: 'GET',//请求方法
params: {}
})
}
// 个人排名
export function personRank(period) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.personRankInfoPath,
method: 'GET',//请求方法
params: {
period: period
}
})
}
// 用户当月打卡状态查询
export function daka_status_list(year_month) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.daka_status_list,
method: 'GET',//请求方法
params: {
year_month: year_month || ""
}
})
}
// 每日故事详情
export function story_detail(story_id, story_index) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.story_detail,
method: 'GET',//请求方法
params: {
story_id: story_id,
story_index: story_index,
}
})
}
// 每日故事列表
export function story_list() {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.story_list,
method: 'GET',//请求方法
params: {}
})
}
// 记录详情
export function daka_records_detail(course_id) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.daka_records_detail,
method: 'GET',//请求方法
params: {
//传过去的参数
course_id: course_id,
}
})
}
// 记录详情
export function daka_rule() {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.daka_rule,
method: 'GET',//请求方法
params: {
//传过去的参数
}
})
}
// 红包图片
export function withdraw_img(position) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.withdraw_img,
method: 'GET',//请求方法
params: {
position: position || ""
}
})
}
// 资金明细
export function withdraw_log(page) {
return fetch({
//api.Hallowmas 引用url.js里面的数据
url: api.withdraw_log,
method: 'GET',//请求方法
params: {
page: page,
per_page: 10
}
})
}
// 首页数据
export function daka_index(grade) {
return fetch({
url: api.daka_index,
method: 'GET',//请求方法
params: {
grade: grade
}
})
}
//有新接口的时候像上面那样再来一次
// //修改昵称接口
// export function userID(name){
// return fetch({
// url:api.myself_name,
// method:"put",
// data:{
// nickname:name
// }
// })
// }
//
//
// //取消转发赞踩接口
// export function cancelForward(articleId,type){
// return fetch({
// url:api.detail_article+articleId+"/forwarded_impress",
// method:"delete",
// params:{
// type:type
// }
// })
// }
import axios from 'axios';//引入axios
export function fetch(options) {
// if (!window['userData']) {
// let user_data_str = localStorage.getItem('read_userData');
// if (user_data_str) {
// window['userData'] = JSON.parse(user_data_str);
// }
// }
// if (!window['userData']) {
// localStorage.setItem('last_url', location.hash.slice(1));
// location.replace('#/Author');
// // this.$router.push({name:"Author"})
// }
return new Promise((resolve, reject) => {
const instance = axios.create({ //instance创建一个axios实例,可以自定义配置,可在 axios文档中查看详情
//所有的请求都会带上这些配置,比如全局都要用的身份信息等。
headers: {
'Content-Type': 'application/json',
// 'Authorization': window['userData']?window['userData'].token:''
'Authorization':"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLCJvcGVuX2lkIjoiMTExMTExMTExMTExMTExMTExMTExMTExMTExMSIsImV4cCI6MTU1Mzk3MTExOX0.KZhzLx6y6t_wDHU35DWNGVIp9M1tZLKzhaW8kMoeBoU"
// 'token_in_header': global_.token,//token从全局变量那里传过来
},
timeout: 30 * 1000 // 30秒超时
});
instance(options)
.then(response => { //then 请求成功之后进行什么操作
console.log('raw response',response);
response.data['date'] = response.headers.date;
resolve(response.data);//把请求到的数据发到引用请求的地方
})
.catch(error => {
console.log('请求异常信息:', error);
// console.log(error);
// if (error.response.status == 401) {
// localStorage.setItem('last_url', location.hash.slice(1));
// localStorage.setItem('read_userData', '');
// location.replace('#/Author');
// // this.$router.push({name:"Author"})
// } else {
// reject(error);
// }
});
});
}
//也可以像下面这样,区分环境或者区分服务器等等
let service = 'dev';
// let service = 'prod';
let api = '';
if (service === 'dev') {
/**dev开发**/
api = '';
} else if (service === 'prod') {
/**prod部署**/
api = 'https://miniapp-api.wxatech.com/game-bsdk';
}
let trackApi = '';
if (service === 'dev') {
/**dev开发**/
trackApi = 'https://test-api.wxagame.com/game-track';
} else if (service === 'prod') {
/**prod部署**/
trackApi = 'https://minigame.api.wxagame.com/game-track';
}
export default {
/**个人中心start**/
//1 打卡查询 GET /api/v1/daka_status
dakaStatusPath: `${api}/api/v1/daka_status`,
//2 打卡操作 POST /api/v1/daka
dakaPath: `${api}/api/v1/daka`,
//3 打卡记录 GET /api/v1/daka_records
dakaRecordsTotalPath: `${api}/api/v1/daka_records/total`,
dakaRecordsListPath: `${api}/api/v1/daka_records/list`,
dakaRecordsDetailPath: `${api}/api/v1/daka_records/detail`,
//4 走马灯、玩法 GET /api/v1/game_info
gameInfoPath: `${api}/api/v1/game_info`,
//5 余额查询 GET /api/v1/balance_query
balanceQueryPath: `${api}/api/v1/balance_query`,
//6 余额提现 GET /api/v1/balance_withdraw
balanceWithdrawPath: `${api}/api/v1/balance_withdraw`,
//7 常见问题 GET /api/v1/faq
faqPath: `${api}/api/v1/faq`,
//8 客服 GET /api/v1/kefu
kefuPath: `${api}/api/v1/kefu`,
//9 关注公众号 GET /api/v1/oc_follow
ocFollowPath: `${api}/api/v1/oc_follow`,
//10 报名支付 GET /api/v1/daka_pay
dakaPayPath: `${api}/api/v1/daka_pay`,
//11 jssdk注入 GET /api/v1/daka_pay
jssdkPath: `${api}/api/v1/config/jssdk`,
// 12 提现banner GET /api/v1/config/withdraw_banner
withdrawBannerPath: `${api}/api/v1/config/withdraw_banner`,
// 13 用户复活卡,免契约金卡信息 GET /api/v1/user_cards
userCardPath: `${api}/api/v1/user_cards`,
// 14 分享内容 /api/v1/config/share_content
shareContentPath: `${api}/api/v1/config/share_content`,
// 15 获取规则文本 /api/v1/get_rule
getRulePath: `${api}/api/v1/get_rule`,
// 16 数据埋点 /api/v1/tracking
trackingPath: `${api}/api/v1/tracking`,
// 17 关注公众号图片 /api/v1/liin_share_image
liinShareImagePath: `${api}/api/v1/liin_share_image`,
// 18 每日分享图 /api/v1/daily_share_image
dailyShareImagePath: `${api}/api/v1/qrcode_url`,
// 19 每日排行榜 /api/v1/daka_rank
dakaRankPath: `${api}/api/v1/daka_rank`,
// 20 新用户 /api/v1/first_daka
firstDakaPath: `${api}/api/v1/first_daka`,
// 21 个人排名 /api/v1/person_rank_info
personRankInfoPath: `${api}/api/v1/person_rank_info`,
// 22 用户当月打卡状态查询
daka_status_list: `${api}/api/v1/daka_status/list`,
// 23 每日故事详情
story_detail: `${api}/api/v1/story/detail`,
// 24 每日故事列表
story_list: `${api}/api/v1/story/list`,
// 25 记录详情
daka_records_detail: `${api}/api/v1/daka_records/detail`,
// 25 规则详情
daka_rule: `${api}/api/v1/daka_rule`,
// 26 红包 /api/v1/withdraw_img
withdraw_img: `${api}/api/v1/withdraw_img`,
// 27 提现明细 /api/v1/withdraw_log
withdraw_log: `${api}/api/v1/withdraw_log`,
// 首页数据
daka_index: `${api}/api/v1/daka_index`,
}
/**
* @1900-2100区间内的公历、农历互转
* @charset UTF-8
* @Author Jea杨(JJonline@JJonline.Cn)
* @Time 2014-7-21
* @Time 2016-8-13 Fixed 2033hex、Attribution Annals
* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug
* @Version 1.0.2
* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
*/
var calendar = {
/**
* 农历1900-2100的润大小信息表
* @Array Of Property
* @return Hex
*/
lunarInfo:[0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909
0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919
0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929
0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939
0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949
0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959
0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969
0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979
0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989
0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,//1990-1999
0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009
0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019
0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029
0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039
0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049
/**Add By JJonline@JJonline.Cn**/
0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50, 0x06b20,0x1a6c4,0x0aae0,//2050-2059
0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069
0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079
0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089
0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099
0x0d520],//2100
/**
* 公历每个月份的天数普通表
* @Array Of Property
* @return Number
*/
solarMonth:[31,28,31,30,31,30,31,31,30,31,30,31],
/**
* 天干地支之天干速查表
* @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
* @return Cn string
*/
Gan:["\u7532","\u4e59","\u4e19","\u4e01","\u620a","\u5df1","\u5e9a","\u8f9b","\u58ec","\u7678"],
/**
* 天干地支之地支速查表
* @Array Of Property
* @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
* @return Cn string
*/
Zhi:["\u5b50","\u4e11","\u5bc5","\u536f","\u8fb0","\u5df3","\u5348","\u672a","\u7533","\u9149","\u620c","\u4ea5"],
/**
* 天干地支之地支速查表<=>生肖
* @Array Of Property
* @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
* @return Cn string
*/
Animals:["\u9f20","\u725b","\u864e","\u5154","\u9f99","\u86c7","\u9a6c","\u7f8a","\u7334","\u9e21","\u72d7","\u732a"],
/**
* 24节气速查表
* @Array Of Property
* @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
* @return Cn string
*/
solarTerm:["\u5c0f\u5bd2","\u5927\u5bd2","\u7acb\u6625","\u96e8\u6c34","\u60ca\u86f0","\u6625\u5206","\u6e05\u660e","\u8c37\u96e8","\u7acb\u590f","\u5c0f\u6ee1","\u8292\u79cd","\u590f\u81f3","\u5c0f\u6691","\u5927\u6691","\u7acb\u79cb","\u5904\u6691","\u767d\u9732","\u79cb\u5206","\u5bd2\u9732","\u971c\u964d","\u7acb\u51ac","\u5c0f\u96ea","\u5927\u96ea","\u51ac\u81f3"],
/**
* 1900-2100各年的24节气日期速查表
* @Array Of Property
* @return 0x string For splice
*/
sTermInfo:['9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f',
'97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f',
'b027097bd097c36b0b6fc9274c91aa','9778397bd19801ec9210c965cc920e','97b6b97bd19801ec95f8c965cc920f',
'97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd197c36c9210c9274c91aa',
'97b6b97bd19801ec95f8c965cc920e','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bcf97c3598082c95f8e1cfcc920f',
'97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f',
'97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd07f595b0b6fc920fb0722',
'9778397bd097c36b0b6fc9210c8dc2','9778397bd19801ec9210c9274c920e','97b6b97bd19801ec95f8c965cc920f',
'97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',
'97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bd07f1487f595b0b0bc920fb0722',
'7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa','97b6b97bd197c36c9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',
'97b6b7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36b0b70c9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa','97b6b7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','977837f0e37f149b0723b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c35b0b6fc9210c8dc2',
'977837f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'977837f0e37f14998082b0723b06bd','7f07e7f0e37f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f595b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f531b0b0bb0b6fb0722',
'7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35',
'7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd',
'7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35',
'7ec967f0e37f14998082b0723b06bd','7f07e7f0e37f14998083b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14898082b0723b02d5','7f07e7f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66aa89801e9808297c35','665f67f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66a449801e9808297c35',
'665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e26665b66a449801e9808297c35','665f67f0e37f1489801eb072297c35',
'7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722'],
/**
* 数字转中文速查表
* @Array Of Property
* @trans ['日','一','二','三','四','五','六','七','八','九','十']
* @return Cn string
*/
nStr1:["\u65e5","\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341"],
/**
* 日期转农历称呼速查表
* @Array Of Property
* @trans ['初','十','廿','卅']
* @return Cn string
*/
nStr2:["\u521d","\u5341","\u5eff","\u5345"],
/**
* 月份转农历称呼速查表
* @Array Of Property
* @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
* @return Cn string
*/
nStr3:["\u6b63","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341","\u51ac","\u814a"],
/**
* 返回农历y年一整年的总天数
* @param lunar Year
* @return Number
* @eg:var count = calendar.lYearDays(1987) ;//count=387
*/
lYearDays:function(y) {
var i, sum = 348;
for(i=0x8000; i>0x8; i>>=1) { sum += (calendar.lunarInfo[y-1900] & i)? 1: 0; }
return(sum+calendar.leapDays(y));
},
/**
* 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
* @param lunar Year
* @return Number (0-12)
* @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
*/
leapMonth:function(y) { //闰字编码 \u95f0
return(calendar.lunarInfo[y-1900] & 0xf);
},
/**
* 返回农历y年闰月的天数 若该年没有闰月则返回0
* @param lunar Year
* @return Number (0、29、30)
* @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
*/
leapDays:function(y) {
if(calendar.leapMonth(y)) {
return((calendar.lunarInfo[y-1900] & 0x10000)? 30: 29);
}
return(0);
},
/**
* 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
* @param lunar Year
* @return Number (-1、29、30)
* @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
*/
monthDays:function(y,m) {
if(m>12 || m<1) {return -1}//月份参数从1至12,参数错误返回-1
return( (calendar.lunarInfo[y-1900] & (0x10000>>m))? 30: 29 );
},
/**
* 返回公历(!)y年m月的天数
* @param solar Year
* @return Number (-1、28、29、30、31)
* @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
*/
solarDays:function(y,m) {
if(m>12 || m<1) {return -1} //若参数错误 返回-1
var ms = m-1;
if(ms==1) { //2月份的闰平规律测算后确认返回28或29
return(((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29: 28);
}else {
return(calendar.solarMonth[ms]);
}
},
/**
* 农历年份转换为干支纪年
* @param lYear 农历年的年份数
* @return Cn string
*/
toGanZhiYear:function(lYear) {
var ganKey = (lYear - 3) % 10;
var zhiKey = (lYear - 3) % 12;
if(ganKey == 0) ganKey = 10;//如果余数为0则为最后一个天干
if(zhiKey == 0) zhiKey = 12;//如果余数为0则为最后一个地支
return calendar.Gan[ganKey-1] + calendar.Zhi[zhiKey-1];
},
/**
* 公历月、日判断所属星座
* @param cMonth [description]
* @param cDay [description]
* @return Cn string
*/
toAstro:function(cMonth,cDay) {
var s = "\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf";
var arr = [20,19,21,21,21,22,23,23,23,23,22,22];
return s.substr(cMonth*2 - (cDay < arr[cMonth-1] ? 2 : 0),2) + "\u5ea7";//座
},
/**
* 传入offset偏移量返回干支
* @param offset 相对甲子的偏移量
* @return Cn string
*/
toGanZhi:function(offset) {
return calendar.Gan[offset%10] + calendar.Zhi[offset%12];
},
/**
* 传入公历(!)y年获得该年第n个节气的公历日期
* @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
* @return day Number
* @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
*/
getTerm:function(y,n) {
if(y<1900 || y>2100) {return -1;}
if(n<1 || n>24) {return -1;}
var _table = calendar.sTermInfo[y-1900];
var _info = [
parseInt('0x'+_table.substr(0,5)).toString() ,
parseInt('0x'+_table.substr(5,5)).toString(),
parseInt('0x'+_table.substr(10,5)).toString(),
parseInt('0x'+_table.substr(15,5)).toString(),
parseInt('0x'+_table.substr(20,5)).toString(),
parseInt('0x'+_table.substr(25,5)).toString()
];
var _calday = [
_info[0].substr(0,1),
_info[0].substr(1,2),
_info[0].substr(3,1),
_info[0].substr(4,2),
_info[1].substr(0,1),
_info[1].substr(1,2),
_info[1].substr(3,1),
_info[1].substr(4,2),
_info[2].substr(0,1),
_info[2].substr(1,2),
_info[2].substr(3,1),
_info[2].substr(4,2),
_info[3].substr(0,1),
_info[3].substr(1,2),
_info[3].substr(3,1),
_info[3].substr(4,2),
_info[4].substr(0,1),
_info[4].substr(1,2),
_info[4].substr(3,1),
_info[4].substr(4,2),
_info[5].substr(0,1),
_info[5].substr(1,2),
_info[5].substr(3,1),
_info[5].substr(4,2),
];
return parseInt(_calday[n-1]);
},
/**
* 传入农历数字月份返回汉语通俗表示法
* @param lunar month
* @return Cn string
* @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
*/
toChinaMonth:function(m) { // 月 => \u6708
if(m>12 || m<1) {return -1} //若参数错误 返回-1
var s = calendar.nStr3[m-1];
s+= "\u6708";//加上月字
return s;
},
/**
* 传入农历日期数字返回汉字表示法
* @param lunar day
* @return Cn string
* @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
*/
toChinaDay:function(d){ //日 => \u65e5
var s;
switch (d) {
case 10:
s = '\u521d\u5341'; break;
case 20:
s = '\u4e8c\u5341'; break;
break;
case 30:
s = '\u4e09\u5341'; break;
break;
default :
s = calendar.nStr2[Math.floor(d/10)];
s += calendar.nStr1[d%10];
}
return(s);
},
/**
* 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
* @param y year
* @return Cn string
* @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
*/
getAnimal: function(y) {
return calendar.Animals[(y - 4) % 12]
},
/**
* 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
* @param y solar year
* @param m solar month
* @param d solar day
* @return JSON object
* @eg:console.log(calendar.solar2lunar(1987,11,01));
*/
solar2lunar:function (y,m,d) { //参数区间1900.1.31~2100.12.31
if(y<1900 || y>2100) {return -1;}//年份限定、上限
if(y==1900&&m==1&&d<31) {return -1;}//下限
if(!y) { //未传参 获得当天
var objDate = new Date();
}else {
var objDate = new Date(y,parseInt(m)-1,d)
}
var i, leap=0, temp=0;
//修正ymd参数
var y = objDate.getFullYear(),m = objDate.getMonth()+1,d = objDate.getDate();
var offset = (Date.UTC(objDate.getFullYear(),objDate.getMonth(),objDate.getDate()) - Date.UTC(1900,0,31))/86400000;
for(i=1900; i<2101 && offset>0; i++) { temp=calendar.lYearDays(i); offset-=temp; }
if(offset<0) { offset+=temp; i--; }
//是否今天
var isTodayObj = new Date(),isToday=false;
if(isTodayObj.getFullYear()==y && isTodayObj.getMonth()+1==m && isTodayObj.getDate()==d) {
isToday = true;
}
//星期几
var nWeek = objDate.getDay(),cWeek = calendar.nStr1[nWeek];
if(nWeek==0) {nWeek =7;}//数字表示周几顺应天朝周一开始的惯例
//农历年
var year = i;
var leap = calendar.leapMonth(i); //闰哪个月
var isLeap = false;
//效验闰月
for(i=1; i<13 && offset>0; i++) {
//闰月
if(leap>0 && i==(leap+1) && isLeap==false){
--i;
isLeap = true; temp = calendar.leapDays(year); //计算农历闰月天数
}
else{
temp = calendar.monthDays(year, i);//计算农历普通月天数
}
//解除闰月
if(isLeap==true && i==(leap+1)) { isLeap = false; }
offset -= temp;
}
if(offset==0 && leap>0 && i==leap+1)
if(isLeap){
isLeap = false;
}else{
isLeap = true; --i;
}
if(offset<0){ offset += temp; --i; }
//农历月
var month = i;
//农历日
var day = offset + 1;
//天干地支处理
var sm = m-1;
var gzY = calendar.toGanZhiYear(year);
//月柱 1900年1月小寒以前为 丙子月(60进制12)
var firstNode = calendar.getTerm(year,(m*2-1));//返回当月「节」为几日开始
var secondNode = calendar.getTerm(year,(m*2));//返回当月「节」为几日开始
//依据12节气修正干支月
var gzM = calendar.toGanZhi((y-1900)*12+m+11);
if(d>=firstNode) {
gzM = calendar.toGanZhi((y-1900)*12+m+12);
}
//传入的日期的节气与否
var isTerm = false;
var Term = null;
if(firstNode==d) {
isTerm = true;
Term = calendar.solarTerm[m*2-2];
}
if(secondNode==d) {
isTerm = true;
Term = calendar.solarTerm[m*2-1];
}
//日柱 当月一日与 1900/1/1 相差天数
var dayCyclical = Date.UTC(y,sm,1,0,0,0,0)/86400000+25567+10;
var gzD = calendar.toGanZhi(dayCyclical+d-1);
//该日期所属的星座
var astro = calendar.toAstro(m,d);
return {'lYear':year,'lMonth':month,'lDay':day,'Animal':calendar.getAnimal(year),'IMonthCn':(isLeap?"\u95f0":'')+calendar.toChinaMonth(month),'IDayCn':calendar.toChinaDay(day),'cYear':y,'cMonth':m,'cDay':d,'gzYear':gzY,'gzMonth':gzM,'gzDay':gzD,'isToday':isToday,'isLeap':isLeap,'nWeek':nWeek,'ncWeek':"\u661f\u671f"+cWeek,'isTerm':isTerm,'Term':Term,'astro':astro};
},
/**
* 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
* @param y lunar year
* @param m lunar month
* @param d lunar day
* @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
* @return JSON object
* @eg:console.log(calendar.lunar2solar(1987,9,10));
*/
lunar2solar:function(y,m,d,isLeapMonth) { //参数区间1900.1.31~2100.12.1
var isLeapMonth = !!isLeapMonth;
var leapOffset = 0;
var leapMonth = calendar.leapMonth(y);
var leapDay = calendar.leapDays(y);
if(isLeapMonth&&(leapMonth!=m)) {return -1;}//传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
if(y==2100&&m==12&&d>1 || y==1900&&m==1&&d<31) {return -1;}//超出了最大极限值
var day = calendar.monthDays(y,m);
var _day = day;
//bugFix 2016-9-25
//if month is leap, _day use leapDays method
if(isLeapMonth) {
_day = calendar.leapDays(y,m);
}
if(y < 1900 || y > 2100 || d > _day) {return -1;}//参数合法性效验
//计算农历的时间差
var offset = 0;
for(var i=1900;i<y;i++) {
offset+=calendar.lYearDays(i);
}
var leap = 0,isAdd= false;
for(var i=1;i<m;i++) {
leap = calendar.leapMonth(y);
if(!isAdd) {//处理闰月
if(leap<=i && leap>0) {
offset+=calendar.leapDays(y);isAdd = true;
}
}
offset+=calendar.monthDays(y,i);
}
//转换闰月农历 需补充该年闰月的前一个月的时差
if(isLeapMonth) {offset+=day;}
//1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
var stmap = Date.UTC(1900,1,30,0,0,0);
var calObj = new Date((offset+d-31)*86400000+stmap);
var cY = calObj.getUTCFullYear();
var cM = calObj.getUTCMonth()+1;
var cD = calObj.getUTCDate();
return calendar.solar2lunar(cY,cM,cD);
}
};
export default calendar
\ No newline at end of file
<template>
<div class="calendar">
<div class="calendar-tools">
<span class="calendar-prev" @click="prev">
<svg width="20" height="20" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g class="transform-group">
<g transform="scale(0.015625, 0.015625)">
<path
d="M671.968 912c-12.288 0-24.576-4.672-33.952-14.048L286.048 545.984c-18.752-18.72-18.752-49.12 0-67.872l351.968-352c18.752-18.752 49.12-18.752 67.872 0 18.752 18.72 18.752 49.12 0 67.872l-318.016 318.048 318.016 318.016c18.752 18.752 18.752 49.12 0 67.872C696.544 907.328 684.256 912 671.968 912z"
fill="#5e7a88"></path>
</g>
</g>
</svg>
</span>
<div class="calendar-info">
<!-- {{monthString}} -->
{{year}}{{zeroPad(month+1)}}
</div>
<span class="calendar-next" @click="next">
<svg width="20" height="20" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g class="transform-group">
<g transform="scale(0.015625, 0.015625)">
<path
d="M761.056 532.128c0.512-0.992 1.344-1.824 1.792-2.848 8.8-18.304 5.92-40.704-9.664-55.424L399.936 139.744c-19.264-18.208-49.632-17.344-67.872 1.888-18.208 19.264-17.376 49.632 1.888 67.872l316.96 299.84-315.712 304.288c-19.072 18.4-19.648 48.768-1.248 67.872 9.408 9.792 21.984 14.688 34.56 14.688 12 0 24-4.48 33.312-13.44l350.048-337.376c0.672-0.672 0.928-1.6 1.6-2.304 0.512-0.48 1.056-0.832 1.568-1.344C757.76 538.88 759.2 535.392 761.056 532.128z"
fill="#5e7a88"></path>
</g>
</g>
</svg>
</span>
</div>
<!--<table cellpadding="5">-->
<!--<thead>-->
<!--<tr>-->
<!--<td v-for="week in weeks" class="week">{{week}}</td>-->
<!--</tr>-->
<!--</thead>-->
<!--<tbody>-->
<!--<tr v-for="(day,k1) in days" style="{'animation-delay',(k1*30)+'ms'}">-->
<!--<td v-for="(child,k2) in day" :class="{'selected':child.selected,'disabled':child.disabled}"-->
<!--@click="select(k1,k2,$event)">-->
<!--<span :class="{'red':k2==0||k2==6||((child.isLunarFestival||child.isGregorianFestival) && lunar)}">{{child.day}}</span>-->
<!--</td>-->
<!--</tr>-->
<!--</tbody>-->
<!--</table>-->
<div class="calendar_table">
<div class="thead">
<div class="tr">
<div class="td" v-for="week in weeks">{{week}}</div>
</div>
</div>
<div class="tbody">
<div class="tr" v-for="(day,k1) in days">
<div :class="child.disabled?'disabled td':'td'" v-for="(child,k2) in day" @click="clickDay(child)">
<div :class="getDayType(child.day)==1?'day_bg':getDayType(child.day)==2?'day_bg class':'day_bg active'">
{{getDayText(child.day)}}
</div>
</div>
</div>
</div>
</div>
<div class="calendar_bar">
<div class="bar_item">
<div class="left_bar_ball"></div>
<div class="bar_text">已打卡</div>
</div>
<div class="bar_item">
<div class="right_bar_ball"></div>
<div class="bar_text">未打卡</div>
</div>
</div>
</div>
</template>
<style scoped>
.calendar {
margin: .2rem auto 0;
width: 6.9rem;
background: #fff;
user-select: none;
box-shadow: 0 0.02rem 0.14rem 0 rgba(180, 197, 200, 0.5);
}
.calendar-tools {
height: .86rem;
font-size: .28rem;
line-height: 40px;
color: #55B7B7;
display: flex;
align-items: center;
justify-content: space-between;
background: #EBFFFF;
}
.calendar-tools span {
cursor: pointer;
}
.calendar-prev {
width: 14.28571429%;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
.calendar-info {
font-size: .28rem;
line-height: 1.3;
text-align: center;
}
.calendar-info > div.month {
margin: auto;
height: 20px;
width: 100px;
text-align: center;
color: #5e7a88;
overflow: hidden;
position: relative;
}
.calendar-info > div.month .month-inner {
position: absolute;
left: 0;
top: 0;
height: 240px;
transition: top .5s cubic-bezier(0.075, 0.82, 0.165, 1);
}
.calendar-info > div.month .month-inner > span {
display: block;
font-size: 14px;
height: 20px;
width: 100px;
overflow: hidden;
text-align: center;
}
.calendar-info > div.year {
font-size: 10px;
line-height: 1;
color: #999;
}
.calendar-next {
width: 14.28571429%;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
.tr {
display: flex;
}
.tr .td {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
margin: 0.12rem 0;
}
.thead {
border-bottom: 0.01rem solid #F2F2F5;
}
.thead .td {
font-size: 0.26rem;
color: #888888;
}
.tbody .td {
height: 0.52rem;
color: #888888;
}
.td.disabled {
opacity: 0.3;
}
.day_bg {
/*background: #F2F2F5;*/
width: 0.52rem;
height: 0.52rem;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 0.26rem;
}
.day_bg.class {
background: rgba(242, 242, 245, 1);
}
.day_bg.active {
background: rgba(26, 211, 211, 1);
color: #fff;
}
.calendar_bar {
display: flex;
align-items: center;
padding: 0.3rem 0;
font-size: .26rem;
}
.left_bar_ball, .right_bar_ball {
width: .16rem;
height: .16rem;
border-radius: 50%;
background: rgba(26, 211, 211, 1);
margin: 0 .07rem 0 .3rem;
}
.right_bar_ball {
background: rgba(242, 242, 245, 1);
}
.bar_text {
color: #A5A5A5;
}
.bar_item {
display: flex;
align-items: center;
}
</style>
<script>
import calendar from './calendar.js'
import {
daka_status_list,
} from "@/components/axios/api";
export default {
props: {
// 多选模式
multi: {
type: Boolean,
default: false
},
// 范围模式
range: {
type: Boolean,
default: false
},
// 默认日期
value: {
type: Array,
default: function () {
return []
}
},
// 开始选择日期
begin: {
type: Array,
default: function () {
return []
}
},
// 结束选择日期
end: {
type: Array,
default: function () {
return []
}
},
// 是否小于10补零
zero: {
type: Boolean,
default: false
},
// 屏蔽的日期
disabled: {
type: Array,
default: function () {
return []
}
},
// 是否显示农历
lunar: {
type: Boolean,
default: false
},
// 自定义星期名称
weeks: {
type: Array,
default: function () {
return window.navigator.language.toLowerCase() == "zh-cn" ? ['日', '一', '二', '三', '四', '五', '六'] : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
}
},
// 自定义月份
months: {
type: Array,
default: function () {
return window.navigator.language.toLowerCase() == "zh-cn" ? ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'] : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
}
},
// 自定义事件
events: {
type: Object,
default: function () {
return {}
}
},
},
data() {
return {
now: 0,
years: [],
yearsShow: false,
year: 0,
month: 0,
day: 0,
days: [],
multiDays: [],
today: [],
festival: {
lunar: {
"1-1": "春节",
"1-15": "元宵节",
"2-2": "龙头节",
"5-5": "端午节",
"7-7": "七夕节",
"7-15": "中元节",
"8-15": "中秋节",
"9-9": "重阳节",
"10-1": "寒衣节",
"10-15": "下元节",
"12-8": "腊八节",
"12-23": "祭灶节",
},
gregorian: {
"1-1": "元旦",
"2-14": "情人节",
"3-8": "妇女节",
"3-12": "植树节",
"4-5": "清明节",
"5-1": "劳动节",
"5-4": "青年节",
"6-1": "儿童节",
"7-1": "建党节",
"8-1": "建军节",
"9-10": "教师节",
"10-1": "国庆节",
"12-24": "平安夜",
"12-25": "圣诞节",
},
},
rangeBegin: [],
rangeEnd: [],
dakaList: [],
classDayList: [],
yearMonth: ""
}
},
watch: {
events() {
this.render(this.year, this.month)
},
value() {
this.init();
}
},
mounted() {
this.init()
this.getList()
},
methods: {
clickDay(item) {
let type = this.getDayType(item.day)
let index = this.classDayList.indexOf(item.day)
let now = new Date().getDate()
let nowIndex = this.classDayList.indexOf(now)
console.log("index", this.classDayList, index, nowIndex)
if (type == 1) {
return
}
if ((index > nowIndex)) {
type = 4
}
let day = this.dakaList[index]
this.$emit("clickDay", type, day)
},
getList() {
console.log("year", this.year, this.month)
this.classDayList = []
let ym = `${this.year}${this.zeroPad(this.month + 1)}`
daka_status_list(ym).then(res => {
console.log("res", res)
if (res.code == 0) {
this.dakaList = res.data
for (let i = 0; i < this.dakaList.length; i++) {
let item = this.dakaList[i]
this.classDayList.push(Number(item.day))
}
}
})
},
getDayType(day) {
let index = this.classDayList.indexOf(day)
if (index == -1) {
return "1"
} else {
if (this.dakaList[index].daka_done) {
return "3"
} else {
return "2"
}
}
},
getDayText(day) {
if (this.month != this.now.getMonth() || this.year != this.now.getFullYear()) {
return day
} else {
if (day == this.now.getDate()) {
return "今"
}
return day
}
},
init() {
let now = new Date();
this.now = now
this.year = now.getFullYear()
this.month = now.getMonth()
this.day = now.getDate()
if (this.value.length > 0) {
if (this.range) { //范围
this.year = parseInt(this.value[0][0])
this.month = parseInt(this.value[0][1]) - 1
this.day = parseInt(this.value[0][2])
let year2 = parseInt(this.value[1][0])
let month2 = parseInt(this.value[1][1]) - 1
let day2 = parseInt(this.value[1][2])
this.rangeBegin = [this.year, this.month, this.day]
this.rangeEnd = [year2, month2, day2]
} else if (this.multi) {//多选
this.multiDays = this.value;
this.year = parseInt(this.value[0][0])
this.month = parseInt(this.value[0][1]) - 1
this.day = parseInt(this.value[0][2])
} else { //单选
this.year = parseInt(this.value[0])
this.month = parseInt(this.value[1]) - 1
this.day = parseInt(this.value[2])
}
}
this.render(this.year, this.month)
},
// 渲染日期
render(y, m) {
let firstDayOfMonth = new Date(y, m, 1).getDay() //当月第一天
let lastDateOfMonth = new Date(y, m + 1, 0).getDate() //当月最后一天
let lastDayOfLastMonth = new Date(y, m, 0).getDate() //最后一月的最后一天
this.year = y
let seletSplit = this.value
let i, line = 0, temp = [], nextMonthPushDays = 1
for (i = 1; i <= lastDateOfMonth; i++) {
let day = new Date(y, m, i).getDay() //返回星期几(0~6)
let k
// 第一行
if (day == 0) {
temp[line] = []
} else if (i == 1) {
temp[line] = []
k = lastDayOfLastMonth - firstDayOfMonth + 1
for (let j = 0; j < firstDayOfMonth; j++) {
// console.log("第一行",lunarYear,lunarMonth,lunarValue,lunarInfo)
temp[line].push(Object.assign(
{day: k, disabled: true},
this.getLunarInfo(this.computedPrevYear(), this.computedPrevMonth(true), k),
this.getEvents(this.computedPrevYear(), this.computedPrevMonth(true), k),
))
k++;
}
}
if (this.range) { // 范围
// console.log("日期范围",this.getLunarInfo(this.year,this.month+1,i))
let options = Object.assign(
{day: i},
this.getLunarInfo(this.year, this.month + 1, i),
this.getEvents(this.year, this.month + 1, i),
)
if (this.rangeBegin.length > 0) {
let beginTime = Number(new Date(this.rangeBegin[0], this.rangeBegin[1], this.rangeBegin[2]))
let endTime = Number(new Date(this.rangeEnd[0], this.rangeEnd[1], this.rangeEnd[2]))
let stepTime = Number(new Date(this.year, this.month, i))
if (beginTime <= stepTime && endTime >= stepTime) {
options.selected = true
}
}
if (this.begin.length > 0) {
let beginTime = Number(new Date(parseInt(this.begin[0]), parseInt(this.begin[1]) - 1, parseInt(this.begin[2])))
if (beginTime > Number(new Date(this.year, this.month, i))) options.disabled = true
}
if (this.end.length > 0) {
let endTime = Number(new Date(parseInt(this.end[0]), parseInt(this.end[1]) - 1, parseInt(this.end[2])))
if (endTime < Number(new Date(this.year, this.month, i))) options.disabled = true
}
if (this.disabled.length > 0) {
if (this.disabled.filter(v => {
return this.year === v[0] && this.month === v[1] - 1 && i === v[2]
}).length > 0) {
options.disabled = true
}
}
temp[line].push(options)
} else if (this.multi) {//多选
let options
// 判断是否选中
if (this.value.filter(v => {
return this.year === v[0] && this.month === v[1] - 1 && i === v[2]
}).length > 0) {
options = Object.assign({
day: i,
selected: true
}, this.getLunarInfo(this.year, this.month + 1, i), this.getEvents(this.year, this.month + 1, i))
} else {
options = Object.assign({
day: i,
selected: false
}, this.getLunarInfo(this.year, this.month + 1, i), this.getEvents(this.year, this.month + 1, i))
if (this.begin.length > 0) {
let beginTime = Number(new Date(parseInt(this.begin[0]), parseInt(this.begin[1]) - 1, parseInt(this.begin[2])))
if (beginTime > Number(new Date(this.year, this.month, i))) options.disabled = true
}
if (this.end.length > 0) {
let endTime = Number(new Date(parseInt(this.end[0]), parseInt(this.end[1]) - 1, parseInt(this.end[2])))
if (endTime < Number(new Date(this.year, this.month, i))) options.disabled = true
}
if (this.disabled.length > 0) {
if (this.disabled.filter(v => {
return this.year === v[0] && this.month === v[1] - 1 && i === v[2]
}).length > 0) {
options.disabled = true
}
}
}
temp[line].push(options)
} else { // 单选
// console.log(this.lunar(this.year,this.month,i));
let chk = new Date()
let chkY = chk.getFullYear()
let chkM = chk.getMonth()
// 匹配上次选中的日期
if (parseInt(seletSplit[0]) == this.year && parseInt(seletSplit[1]) - 1 == this.month && parseInt(seletSplit[2]) == i) {
// console.log("匹配上次选中的日期",lunarYear,lunarMonth,lunarValue,lunarInfo)
temp[line].push(Object.assign(
{day: i, selected: true},
this.getLunarInfo(this.year, this.month + 1, i),
this.getEvents(this.year, this.month + 1, i),
))
this.today = [line, temp[line].length - 1]
}
// 没有默认值的时候显示选中今天日期
else if (chkY == this.year && chkM == this.month && i == this.day && this.value == "") {
// console.log("今天",lunarYear,lunarMonth,lunarValue,lunarInfo)
temp[line].push(Object.assign(
{day: i, selected: true},
this.getLunarInfo(this.year, this.month + 1, i),
this.getEvents(this.year, this.month + 1, i),
))
this.today = [line, temp[line].length - 1]
} else {
// 普通日期
// console.log("设置可选范围",i,lunarYear,lunarMonth,lunarValue,lunarInfo)
let options = Object.assign(
{day: i, selected: false},
this.getLunarInfo(this.year, this.month + 1, i),
this.getEvents(this.year, this.month + 1, i),
)
if (this.begin.length > 0) {
let beginTime = Number(new Date(parseInt(this.begin[0]), parseInt(this.begin[1]) - 1, parseInt(this.begin[2])))
if (beginTime > Number(new Date(this.year, this.month, i))) options.disabled = true
}
if (this.end.length > 0) {
let endTime = Number(new Date(parseInt(this.end[0]), parseInt(this.end[1]) - 1, parseInt(this.end[2])))
if (endTime < Number(new Date(this.year, this.month, i))) options.disabled = true
}
if (this.disabled.length > 0) {
if (this.disabled.filter(v => {
return this.year === v[0] && this.month === v[1] - 1 && i === v[2]
}).length > 0) {
options.disabled = true
}
}
temp[line].push(options)
}
}
// 到周六换行
if (day == 6 && i < lastDateOfMonth) {
line++
} else if (i == lastDateOfMonth) {
// line++
let k = 1
for (let d = day; d < 6; d++) {
// console.log(this.computedNextYear()+"-"+this.computedNextMonth(true)+"-"+k)
temp[line].push(Object.assign(
{day: k, disabled: true},
this.getLunarInfo(this.computedNextYear(), this.computedNextMonth(true), k),
this.getEvents(this.computedNextYear(), this.computedNextMonth(true), k),
))
k++
}
// 下个月除了补充的前几天开始的日期
nextMonthPushDays = k
}
} //end for
// console.log(this.year+"/"+this.month+"/"+this.day+":"+line)
// 补充第六行让视觉稳定
if (line <= 5 && nextMonthPushDays > 0) {
// console.log({nextMonthPushDays:nextMonthPushDays,line:line})
for (let i = line + 1; i <= 5; i++) {
temp[i] = []
let start = nextMonthPushDays + (i - line - 1) * 7
for (let d = start; d <= start + 6; d++) {
temp[i].push(Object.assign(
{day: d, disabled: true},
this.getLunarInfo(this.computedNextYear(), this.computedNextMonth(true), d),
this.getEvents(this.computedNextYear(), this.computedNextMonth(true), d),
))
}
}
}
this.days = temp
},
computedPrevYear() {
let value = this.year
if (this.month - 1 < 0) {
value--
}
return value
},
computedPrevMonth(isString) {
let value = this.month
if (this.month - 1 < 0) {
value = 11
} else {
value--
}
// 用于显示目的(一般月份是从0开始的)
if (isString) {
return value + 1
}
return value
},
computedNextYear() {
let value = this.year
if (this.month + 1 > 11) {
value++
}
return value
},
computedNextMonth(isString) {
let value = this.month
if (this.month + 1 > 11) {
value = 0
} else {
value++
}
// 用于显示目的(一般月份是从0开始的)
if (isString) {
return value + 1
}
return value
},
// 获取农历信息
getLunarInfo(y, m, d) {
let lunarInfo = calendar.solar2lunar(y, m, d)
let lunarValue = lunarInfo.IDayCn
// console.log(lunarInfo)
let isLunarFestival = false
let isGregorianFestival = false
if (this.festival.lunar[lunarInfo.lMonth + "-" + lunarInfo.lDay] != undefined) {
lunarValue = this.festival.lunar[lunarInfo.lMonth + "-" + lunarInfo.lDay]
isLunarFestival = true
} else if (this.festival.gregorian[m + "-" + d] != undefined) {
lunarValue = this.festival.gregorian[m + "-" + d]
isGregorianFestival = true
}
return {
lunar: lunarValue,
isLunarFestival: isLunarFestival,
isGregorianFestival: isGregorianFestival,
}
},
// 获取自定义事件
getEvents(y, m, d) {
if (Object.keys(this.events).length == 0) return false;
let eventName = this.events[y + "-" + m + "-" + d]
let data = {}
if (eventName != undefined) {
data.eventName = eventName
}
return data
},
// 上月
prev(e) {
e.stopPropagation()
if (this.month == 0) {
this.month = 11
this.year = parseInt(this.year) - 1
} else {
this.month = parseInt(this.month) - 1
}
this.render(this.year, this.month)
this.$emit('selectMonth', this.month + 1, this.year)
this.$emit('prev', this.month + 1, this.year)
this.getList()
},
// 下月
next(e) {
e.stopPropagation()
if (this.month == 11) {
this.month = 0
this.year = parseInt(this.year) + 1
} else {
this.month = parseInt(this.month) + 1
}
this.render(this.year, this.month)
this.$emit('selectMonth', this.month + 1, this.year)
this.$emit('next', this.month + 1, this.year)
this.getList()
},
// 选中日期
select(k1, k2, e) {
if (e != undefined) e.stopPropagation()
// 日期范围
if (this.range) {
if (this.rangeBegin.length == 0 || this.rangeEndTemp != 0) {
this.rangeBegin = [this.year, this.month, this.days[k1][k2].day]
this.rangeBeginTemp = this.rangeBegin
this.rangeEnd = [this.year, this.month, this.days[k1][k2].day]
this.rangeEndTemp = 0
} else {
this.rangeEnd = [this.year, this.month, this.days[k1][k2].day]
this.rangeEndTemp = 1
// 判断结束日期小于开始日期则自动颠倒过来
if (+new Date(this.rangeEnd[0], this.rangeEnd[1], this.rangeEnd[2]) < +new Date(this.rangeBegin[0], this.rangeBegin[1], this.rangeBegin[2])) {
this.rangeBegin = this.rangeEnd
this.rangeEnd = this.rangeBeginTemp
}
// 小于10左边打补丁
let begin = []
let end = []
if (this.zero) {
this.rangeBegin.forEach((v, k) => {
if (k == 1) v = v + 1
begin.push(this.zeroPad(v))
})
this.rangeEnd.forEach((v, k) => {
if (k == 1) v = v + 1
end.push(this.zeroPad(v))
})
} else {
begin = this.rangeBegin
end = this.rangeEnd
}
// console.log("选中日期",begin,end)
this.$emit('select', begin, end)
}
this.render(this.year, this.month)
} else if (this.multi) {
// 如果已经选过则过滤掉
let filterDay = this.multiDays.filter(v => {
return this.year === v[0] && this.month === v[1] - 1 && this.days[k1][k2].day === v[2]
})
if (filterDay.length > 0) {
this.multiDays = this.multiDays.filter(v => {
return this.year !== v[0] || this.month !== v[1] - 1 || this.days[k1][k2].day !== v[2]
})
} else {
this.multiDays.push([this.year, this.month + 1, this.days[k1][k2].day]);
}
this.days[k1][k2].selected = !this.days[k1][k2].selected
this.$emit('select', this.multiDays)
} else {
// 取消上次选中
if (this.today.length > 0) {
this.days.forEach(v => {
v.forEach(vv => {
vv.selected = false
})
})
}
// 设置当前选中天
this.days[k1][k2].selected = true
this.day = this.days[k1][k2].day
this.today = [k1, k2]
this.$emit('select', [this.year, this.zero ? this.zeroPad(this.month + 1) : this.month + 1, this.zero ? this.zeroPad(this.days[k1][k2].day) : this.days[k1][k2].day])
}
},
changeYear() {
if (this.yearsShow) {
this.yearsShow = false
return false
}
this.yearsShow = true
this.years = [];
for (let i = ~~this.year - 10; i < ~~this.year + 10; i++) {
this.years.push(i)
}
},
selectYear(value) {
this.yearsShow = false
this.year = value
this.render(this.year, this.month)
this.$emit('selectYear', value)
},
// 返回今天
setToday() {
let now = new Date();
this.year = now.getFullYear()
this.month = now.getMonth()
this.day = now.getDate()
this.render(this.year, this.month)
// 遍历当前日找到选中
this.days.forEach(v => {
let day = v.find(vv => {
return vv.day == this.day && !vv.disabled
})
if (day != undefined) {
day.selected = true
}
})
},
// 日期补零
zeroPad(n) {
return String(n < 10 ? '0' + n : n)
},
}
}
</script>
<template>
<div class="share_friend_model" @click="closeModal">
<img class="arrow" src="../assets/img_arrow.png" alt="">
<div class="share_content">
<div class="share_tip tip1">点击右上角三个点选项</div>
<div class="tip_img">
<img src="../assets/ic_fri.png" alt="">
</div>
<div class="img_title">分享朋友圈</div>
<div class="share_tip tip2">分享到朋友圈即为打卡成功</div>
<div class="share_tip tip3">还可邀请更多好友一起学习!</div>
</div>
</div>
</template>
<style scoped>
.share_friend_model {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
border: 1px solid transparent;
z-index: 100;
text-align: center;
}
.arrow {
position: absolute;
width: 1.5rem;
height: 1.11rem;
top: 0.1rem;
right: 0.3rem;
animation: arrowMove 1s infinite;
}
.share_tip{
font-size: .36rem;
color: #ffffff;
}
.tip1{
margin: 1.8rem 0 .8rem;
}
.tip2{
margin-bottom: .2rem;
}
.img_title{
font-size: .30rem;
color: #ffffff;
margin: .2rem 0 .8rem;
}
.tip_img{
margin: 0 auto;
width: 2rem;
height: 2rem;
border-radius: .2rem;
background: #ffffff;
display: flex;
justify-content: center;
align-items: center;
}
.tip_img img{
width: 1.07rem;
height: 1.07rem;
}
@keyframes arrowMove {
0% {
top: 0.1rem;
right: 0.3rem;
}
50% {
top: 0.3rem;
right: 0.5rem;
}
0% {
top: 0.1rem;
right: 0.3rem;
}
}
</style>
<script>
export default {
name: "shareFriendModel",
data() {
return {};
},
methods: {
// 关闭弹窗
closeModal() {
this.$emit("close", true);
}
}
}
</script>
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from 'axios'
import wx from 'weixin-js-sdk'
import api from "@/components/axios/api"
// import VConsole from 'vconsole/dist/vconsole.min.js' //import vconsole
// let vConsole = new VConsole() // 初始化
Vue.config.productionTip = false
Vue.prototype.$http = axios;
window.wx = wx;
router.beforeEach((to, from, next) => {
// document.title = to.meta.title //修改各个页面的title
var uid = localStorage.getItem('read_userData');
if (location.search.match(/inviter/)) {
let searchs = location.search.split('&');
let search_obj = {};
searchs.map((item, index) => {
if (index == 0) {
let str = item.slice(1);
let key_pair = str.split('=');
search_obj[key_pair[0]] = key_pair[1];
} else {
let str = item;
let key_pair = str.split('=');
search_obj[key_pair[0]] = key_pair[1];
}
})
let inviter_matchs = search_obj.inviter;
let from_type_matchs = search_obj.from_type;
let now = new Date();
let year = now.getFullYear();
let month = now.getMonth() + 1;
let day = now.getDate();
let date_time = new Date(`${year}/${month}/${day}`).getTime();
// alert("test3:" + localStorage.getItem('last_share_time'))
if (Number(localStorage.getItem('last_share_time') || 0) < date_time) {
now && (localStorage.setItem('last_share_time', `${now.getTime()}`));
inviter_matchs && (localStorage.setItem('inviter', inviter_matchs))
from_type_matchs && (localStorage.setItem('from_type', from_type_matchs));
// alert(inviter_matchs + "test1")
}
}
console.log(to);
to.params.replace = true;
if (!uid && location.href.match(/\.wxatech\.com/)) {
if (to.path === '/author') {
next()
// location.replace('#/author')
} else {
localStorage.setItem('last_url', to.path);
next('/author')
// location.replace('#/author')
}
} else {
next()
// location.replace(`#${to.path}`)
}
})
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
import Vue from 'vue'
import Router from 'vue-router'
import Courses from './views/Courses.vue'
import Daka from './views/Daka.vue'
import Read from './views/Read.vue'
import Reading from './views/Reading.vue'
import SignUp from './views/SignUp.vue'
import UserCenter from './views/UserCenter.vue'
import MainPage from './views/MainPage.vue'
import Question from './views/Question.vue'
import Wallet from './views/Wallet.vue'
import Author from './views/Author.vue'
import Record from './views/Record.vue'
import Success from './views/Success.vue'
import RecordDetail from './views/RecordDetail.vue'
import Rule from './views/Rule.vue'
import RedpackLog from './views/RedpackLog.vue'
import AmountDetail from './views/AmountDetail.vue'
import PartakeChallenge from './views/PartakeChallenge.vue'
import ChallengeDetail from './views/ChallengeDetail.vue'
import HaveJoinedGame from './views/HaveJoinedGame.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path:"/",
redirect:"/MainPage/SignUp"
},
{
path: '/Author',
name: 'Author',
component: Author
},
{
path: '/Success',
name: 'Success',
component: Success
},
{
path: '/Daka',
name: 'Daka',
component: Daka
},
{
path: '/Record',
name: 'Record',
component: Record
},
{
path: '/RecordDetail',
name: 'RecordDetail',
component: RecordDetail
},
{
path: '/AmountDetail',
name: 'AmountDetail',
component: AmountDetail
},
{
path: '/MainPage/Reading',
name: 'Reading',
component: Reading
},
{
path: '/Question',
name: 'Question',
component: Question
},
{
path: '/Wallet',
name: 'Wallet',
component: Wallet
},
{
path: '/RedpackLog',
name: 'RedpackLog',
component: RedpackLog
},
{
path: '/PartakeChallenge',
name: 'PartakeChallenge',
component: PartakeChallenge
},
{
path: '/ChallengeDetail',
name: 'ChallengeDetail',
component: ChallengeDetail
},
{
path: '/Rule',
name: 'Rule',
component: Rule
},
{
path: '/HaveJoinedGame',
name: 'HaveJoinedGame',
component: HaveJoinedGame
},
{
path: '/MainPage',
name: 'MainPage',
component: MainPage,
children:[
{
path:"/",
redirect: "/MainPage/SignUp"
},
{
path: '/MainPage/SignUp',
name: 'SignUp',
component: SignUp
},
{
path: '/MainPage/PartakeChallenge',
name: 'MainPagePartakeChallenge',
component: PartakeChallenge
},
{
path: '/MainPage/HaveJoinedGame',
name: 'MainPageHaveJoinedGame',
component: HaveJoinedGame
},
{
path: '/UserCenter',
name: 'UserCenter',
component: UserCenter
},
]
},
]
})
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
}
})
<template>
<div class="about">
</div>
</template>
<template>
<div class="amount-detail-page">
<Title class="page-title" title="资金明细" titleColor="#000" @goback="goback" show_back="true" arrowColor="black"></Title>
<div class="amount-container-list" @scroll="onScroll">
<div class="amount-item" v-for="(item,index) in moneyLog" @click="toRecordDetail(item)">
<div class="left-item">
<div class="left-title">{{item.week}}期-{{item.step}}{{item.days}}日耐力赛</div>
<div class="left-content">{{item.created_at}}</div>
</div>
<div class="right-item">
<div class="right-title">{{item.change_type === 2 ? '奖金' : item.change_type === 5 ? '押金' : '金额'}}(元)</div>
<div class="right-content">+{{item.value}}</div>
</div>
</div>
<div class="no-more-list">没有更多数据啦~</div>
</div>
</div>
</template>
<script>
import Title from "@/components/Title.vue";
import {withdraw_log} from "@/components/axios/api";
export default {
name: "AmountDetail",
components: {
Title
},
data() {
return {
moneyLog: [],
next_page: false,
page: 1,
canScroll: true
};
},
created() {
this.getList();
},
methods: {
goback() {
history.go(-1);
},
getList(notRefresh) {
withdraw_log(this.page).then(res => {
this.canScroll = true;
if (res.code == 0) {
if (!notRefresh) {
this.next_page = res.data.next_page;
this.moneyLog = res.data.logs;
} else {
this.next_page = res.data.next_page;
this.moneyLog = this.moneyLog.concat(res.data.logs);
}
}
}).catch(e=>{
this.canScroll = true;
})
},
onScroll(event) {
if (this.next_page && this.canScroll) {
let offsetHeight = event.currentTarget.offsetHeight,
scrollHeight = event.target.scrollHeight,
scrollTop = event.target.scrollTop,
scrollBottom = offsetHeight + scrollTop;
if (Math.abs(scrollHeight - scrollBottom) < 5) {
this.canScroll = false;
console.log("onScroll", "到底部");
this.page += 1;
this.getList(true);
}
}
},
},
};
</script>
<style lang="less" scoped>
#app {
background: #fff;
}
.amount-detail-page {
width: 100%;
height: 100vh;
padding-top: .96rem;
box-sizing: border-box;
display: flex;
flex-direction: column;
.page-title {
width: 100%;
position: fixed;
left: 0;
top: 0;
}
.amount-container-list {
width: 100%;
height: 100vh;
padding-bottom: .2rem;
border-top: .01rem solid #e5e5e5;
box-sizing: border-box;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
&::-webkit-scrollbar {
display: none;
}
.amount-item {
width: 100%;
height: 1.38rem;
border-bottom: .01rem solid #e5e5e5;
padding: 0 .3rem;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
.left-item {
flex: 1;
flex-shrink: 0;
.left-title {
font-size: .3rem;
line-height: 1;
color: #333;
}
.left-content {
font-size: .26rem;
line-height: 1;
color: #888;
margin-top: .28rem;
}
}
.right-item {
flex-shrink: 0;
text-align: right;
.right-title {
font-size: .3rem;
line-height: 1;
color: #333;
}
.right-content {
font-size: .36rem;
line-height: .8;
color: #FFBB33;
margin-top: .21rem;
}
}
}
.no-more-list {
font-size: .26rem;
line-height: 1;
color: #999;
text-align: center;
margin: .8rem 0 .3rem;
}
}
}
</style>
\ No newline at end of file
<template>
<div></div>
</template>
<script>
// import { getToUrl, setToken, setUid } from "../assets/lib/util"; // 封装的缓存方法
// var url = getToUrl();
export default {
name: "Author",
created() {
document.title = "微信授权中";
var code = this.GetUrlParame("code"); // 截取code
console.log(code);
if (!code) {
let local_hash = location.hash;
window.localStorage.setItem("local_hash", local_hash);
let redirect_uri = encodeURIComponent(
`${location.origin}${location.pathname}`
);
location.replace(
`https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9af64967a0d40159&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
);
} else {
console.log("拿到code", code);
console.log("请求登录");
let inviter = localStorage.getItem("inviter");
var uid = localStorage.getItem('read_userData');
if (uid && inviter == JSON.parse(uid).id) {
inviter = "";
}
let from_type = localStorage.getItem("from_type");
// alert(inviter + "test2")
this.$http
.post("/game-bsdk/api/v1/auth_login", {
js_code: code,
inviter_id: inviter || "",
from_type: from_type || ""
}) //如果有code,说明用户点击了授权 将获取到的code传递给后台
.then(res => {
// 返回状态和UId
console.log("返回的数据", res);
if (!res) {
return;
}
let result = res.data;
if (result.code == 0) {
localStorage.setItem("read_userData", JSON.stringify(result.data));
sessionStorage.setItem("new_user", result.data.new_user);
let last_url = localStorage.getItem("last_url") || "/";
let url = location.href.split("#")[0];
// setTimeout(() => {
// // this.$router.go("/MyData");
location.replace(
`https://miniapp-api.wxatech.com/app_pages/read_daka.html?#${last_url}`
);
// }, 60000);
}
// this.uid = res.data.UId;
// setUid(this.uid);
// if (res.data.status && this.uid) {
// window.location.replace("http://wenlian.cct.work/dist/#" + url);
// }
});
}
},
data() {
return {
uid: ""
};
},
methods: {
// 截取code
GetUrlParame(parameName) {
/// 获取地址栏指定参数的值
/// <param name="parameName">参数名</param>
// 获取url中跟在问号后面的部分
var parames = window.location.search;
// 检测参数是否存在
if (parames.indexOf(parameName) > -1) {
var parameValue = "";
parameValue = parames.substring(
parames.indexOf(parameName),
parames.length
);
// 检测后面是否还有参数
if (parameValue.indexOf("&") > -1) {
// 去除后面多余的参数, 得到最终 parameName=parameValue 形式的值
parameValue = parameValue.substring(0, parameValue.indexOf("&"));
// 去掉参数名, 得到最终纯值字符串
parameValue = parameValue.replace(parameName + "=", "");
return parameValue;
}
return "";
}
}
}
};
</script>
<template>
<div class="partake-challenge-page">
<Title class="page-title" title=" " v-on:goback="goback" show_back="true"></Title>
<div class="game-rule-container">
<img src="../images/ChallengeDetail/ic_que.png">
活动规则
</div>
<div class="game-bonus-container">
<div class="bonus-title">本期累计奖励金(元)</div>
<div class="bonus-amount">6.86</div>
</div>
<div class="game-title">5000步七日耐力赛</div>
<div class="game-time">开赛时间:3月11日 00:00-3月17日24:00</div>
<div class="hr"></div>
<div class="game-info-container">
<div class="game-info-section">
<div class="section-item">
<div class="item-value">5636.26</div>
<div class="item-key">总奖励金(元)</div>
</div>
<div class="section-item">
<div class="item-value">26.8%</div>
<div class="item-key">收益率</div>
</div>
</div>
<div class="game-info-section">
<div class="section-item">
<div class="item-value">70964</div>
<div class="item-key">达标人数</div>
</div>
<div class="section-item">
<div class="item-value">111858</div>
<div class="item-key">参赛人数</div>
</div>
</div>
</div>
<div class="share-btn">邀请好友来参赛</div>
</div>
</template>
<script>
import Title from "@/components/Title.vue";
export default {
name: "ChallengeDetail",
components: {
Title
},
data() {
return {
}
},
created() {
},
methods: {
goback() {
history.go(-1);
},
}
}
</script>
<style lang="less" scoped>
.partake-challenge-page {
width: 100%;
min-height: 100vh;
background-color: rgb(70, 88, 149);
background-image: url(../images/SignUp/sy_beijing.png);
background-repeat: no-repeat;
background-size: 100%;
background-position: center top;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
position: relative;
.page-title {
position: fixed;
left: 0;
top: 0;
}
.game-rule-container {
display: flex;
align-items: center;
position: absolute;
top: .3rem;
right: .22rem;
font-size: .26rem;
line-height: 1;
color: #465895;
img {
width: .3rem;
height: .3rem;
margin-right: .1rem;
}
}
.game-bonus-container {
width: 6.4rem;
padding: .3rem 0;
box-sizing: border-box;
background: linear-gradient(90deg, rgba(255, 255, 255, 0), #1A285A, rgba(255, 255, 255, 0));
margin-top: 2.38rem;
.bonus-title {
font-size: .3rem;
line-height: 1;
color: #fff;
text-align: center;
}
.bonus-amount {
font-size: .64rem;
line-height: .8;
color: #FFE253;
text-align: center;
margin-top: .26rem;
}
}
.game-title {
font-size: .36rem;
line-height: 1;
color: #fff;
font-weight: bold;
margin-top: .4rem;
}
.game-time {
font-size: .24rem;
line-height: 1;
color: #D6DFFF;
padding: .12rem .38rem;
border-radius: .48rem;
background: #556CB6;
margin-top: .14rem;
}
.hr {
width: 3rem;
height: .01rem;
background: #6F82C3;
margin-top: .5rem;
}
.game-info-container {
width: 6rem;
background: #3D4F8F;
margin-top: .5rem;
.game-info-section {
width: 100%;
height: 1.34rem;
display: flex;
align-items: center;
.section-item {
flex: 1;
position: relative;
&:last-child:after {
content: '';
width: .02rem;
height: .4rem;
background: #A2B4EE;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
.item-value {
font-size: .4rem;
line-height: .8;
color: #fff;
text-align: center;
}
.item-key {
font-size: .26rem;
line-height: 1;
color: #fff;
text-align: center;
margin-top: .18rem;
}
}
}
}
.share-btn {
width: 5.6rem;
border-radius: .92rem;
background: #1FDBB1;
font-size: .4rem;
line-height: .92rem;
color: #fff;
font-weight: bold;
text-align: center;
margin-top: 2.24rem;
}
}
</style>
<template>
<div class="courses">
<div class="courses_list" v-if="isSignUp">
<div class="list_item" v-for="item in storyList" @click="toReading(item)">
<img class="book_img" :src="item.story_thumbnail" alt="">
<div class="book_msg">
<div class="book_title">{{item.story_title}}</div>
<div class="book_author">来自:{{item.story_author}}</div>
</div>
<div class="user_msg">
<div class="msg_time">
<div class="msg_date">{{item.date}}</div>
<div class="msg_day">{{item.what_day}}</div>
</div>
<div :class="item.showStatus?'msg_status':'msg_status hidden'">
<div class="daka_done" v-if="item.daka_signup&&item.daka_done">已打卡</div>
<div class="daka_not" v-if="item.daka_signup&&!item.daka_done">漏打卡</div>
</div>
</div>
</div>
</div>
<div class="not_sign_page" v-else>
<div class="book_title" style="margin: 2rem 0 .2rem;font-size: .36rem">新的一期读书打卡开始了哦~</div>
<div class="book_author" style="font-size: .28rem">点击下方按钮去报名</div>
<div class="study_btn" @click="toDaka" style="margin-top: 1rem">立即报名</div>
</div>
<div class="modal" v-if="modalShown">
<Modal v-on:close="closeModal"
v-on:confirmModal="confirmModal"
v-bind:title="modalTitle"
v-bind:option="modalOption"
v-bind:desc="modalDesc">
</Modal>
</div>
</div>
</template>
<script>
import Modal from "@/components/Modal.vue";
import {
story_list,
} from "@/components/axios/api";
export default {
name: "Courses",
components: {
Modal,
},
data() {
return {
modalTitle: "",
modalDesc: "",
modalOption: "",
modalShown: false,
storyList: [],
targetDate: "",
isSignUp: true
}
},
methods: {
toDaka(){
this.$router.push({name:"Daka"})
},
showModal(title, desc, option) {
this.modalTitle = title || "";
this.modalDesc = desc || "";
this.modalOption = option || {}
this.modalShown = true;
},
closeModal() {
this.modalShown = false;
},
confirmModal(scb) {
scb && scb()
this.modalShown = false;
},
toReading(item) {
let period = item.period
let now = new Date()
let date = new Date(this.insertStr(this.insertStr(period, 4, "-"), 7, "-"))
if (item.showStatus || (date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate())) {
if ((date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate())) {
this.$router.push({name: "Reading", query: {storyId: item.story_id, days: item.days, canDaka: "1"}})
} else {
this.$router.push({name: "Reading", query: {storyId: item.story_id, days: item.days}})
}
} else {
this.showModal("未开放课程", "别着急哦,每天开放一节课!", {
btnText: "我知道了",
})
}
},
formatData() {
for (let item of this.storyList) {
let period = item.period
let now = new Date()
let date = new Date(this.insertStr(this.insertStr(period, 4, "-"), 7, "-"))
if (date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate()) {
item.date = `今`
if (now >= this.targetDate || item.daka_done) {
item.showStatus = true
}
} else {
item.date = `${date.getMonth() + 1}.${this.fillZero(date.getDate())}`
if (date < now) {
item.showStatus = true
}
}
}
},
fillZero(num) {
return num < 10 ? `0${num}` : num
},
insertStr(soure, start, newStr) {
return soure.slice(0, start) + newStr + soure.slice(start);
},
getList() {
story_list().then(res => {
if (res.code === 0) {
this.storyList = res.data.data
this.isSignUp = res.data.is_signup
console.log("this.storyList",res.data)
if(this.isSignUp){
this.formatData()
}
}
})
},
setTargetDate() {
let targetDate = new Date()
targetDate.setHours(22)
targetDate.setMinutes(0)
targetDate.setSeconds(59)
this.targetDate = targetDate
}
},
created() {
this.setTargetDate()
this.getList()
}
}
</script>
<style scoped>
.courses {
min-height: 0;
margin-top: .2rem;
}
.courses_list {
height: 100%;
overflow-y: scroll;
/*-webkit-overflow-scrolling: touch;*/
padding: 0 .3rem;
}
.not_sign_page{
display: flex;
flex-direction: column;
align-items: center;
}
.list_item {
display: flex;
align-items: center;
padding: .14rem 0;
border-bottom: .01rem solid rgba(230, 230, 230, 1);
}
.book_img {
width: .88rem;
height: .88rem;
flex-shrink: 0;
}
.book_msg {
margin-left: .1rem;
flex: 1;
}
.book_title {
font-size: .28rem;
margin-bottom: .13rem;
}
.book_author {
font-size: .24rem;
color: rgba(165, 165, 165, 1);
}
.msg_time {
display: flex;
justify-content: flex-end;
}
.msg_date {
font-size: .46rem;
color: rgba(26, 211, 211, 1);
margin-right: .12rem;
}
.msg_day {
display: flex;
align-items: center;
font-size: .2rem;
color: rgba(136, 136, 136, 1);
}
.msg_status {
display: flex;
justify-content: flex-end;
}
.msg_status.hidden {
opacity: 0;
}
.daka_done, .daka_not {
width: 1rem;
height: .34rem;
border: .02rem solid rgba(255, 195, 15, 1);
border-radius: .17rem;
color: rgba(255, 195, 15, 1);
display: flex;
justify-content: center;
align-items: center;
font-size: .24rem;
}
.daka_not {
border: .02rem solid rgba(255, 146, 134, 1);
color: rgba(255, 146, 134, 1);
}
.study_btn {
width: 4rem;
height: .88rem;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
font-size: .36rem;
border-radius: .44rem;
background: rgba(255, 195, 15, 1);
/*margin: 0 auto;*/
}
</style>
<template>
<div class="daka" :style="isTouchingScoller?'overflow-y:hidden':'overflow-y:scroll'" @touchstart="stopDefault"
@touchmove="stopDefault" @touchend="stopDefault">
<img class="banner" src="../assets/daka_top_banner.jpg" alt="">
<div class="daka_container">
<div class="top_container">
<NoticeBonus></NoticeBonus>
<div class="time_tip">每日 <span>{{dakaStatus.daka_start}}-{{dakaStatus.daka_end}}</span> 打卡赢取奖金</div>
<calendar ref="calendar" @clickDay="clickDay"></calendar>
<div class="money_container"
v-if="(!not_signup&&!userStatus.daka_signup)||(userStatus.days==7&&userStatus.daka_done)">
<!--<div class="money_tip">今日激励金100元,成功报名人数2000人</div>-->
<div class="money_content">
<div class="money_content_left">
<div class="money_left_title">
赢取奖金
</div>
<div class="money_left_text">
<span>{{dakaStatus.bet_bonus}}</span>
</div>
</div>
<div class="money_content_right">
<div class="money_right_title">
收益率
</div>
<div class="money_right_text">
<span>{{dakaStatus.bet_rate}}</span> %
</div>
</div>
</div>
</div>
<div class="btn_container">
<div class="rank_btn" @click="toggleRank" v-if="!pageStatus.largeBtnStatus">
<img class="btn_icon" src="../assets/daka_ic_record.png" alt="">
<div class="btn_text">我的记录</div>
</div>
<div class="rank_btn" @click="showFree" v-else>
<img class="btn_icon" src="../assets/daka_ic_free.png" alt="">
<div class="btn_text">免押金报名</div>
</div>
<div class="main_msg_container">
<div class="main_msg" v-if="pageStatus.mainBtnStatus==1">
<div class="main_msg_time" v-if="pageStatus.mainMsgTitleStatus==0">{{userStatus.daka_time|dakaFilter}}
完成打卡
</div>
<div class="main_msg_title" v-else>{{pageStatus.mainMsgTitleStatus==1?'打卡失败':'本期未报名'}}</div>
<div class="main_msg_tip">{{getMainMsgTipText()}}</div>
</div>
<div class="main_btn" @click="toggleShareFriendModel" v-else>
立即打卡
</div>
</div>
<div class="reborn_btn" @click="showReborn">
<img class="btn_icon" src="../assets/daka_ic_heart.png" alt="">
<div class="btn_text">复活卡</div>
</div>
</div>
<div class="large_btn" @click="payToSign" v-if="pageStatus.largeBtnStatus">报名下一期</div>
<div class="daka_num"><img src="../assets/people_num_ic.png" alt="">已有{{dakaStatus.daka_num}}人成功打卡</div>
<!--<div class="large_btn" @click="dakaAction">立即打卡</div>-->
<!--<div class="large_reborn_btn" @click="doReborn">立即复活</div>-->
</div>
<div class="line"></div>
<div class="bottom_container">
<div class="bottom_title">
<div class="bottom_title_left"><img src="../assets/daka_ic_know.png" alt=""> 打卡须知</div>
<div class="bottom_title_right" @click="toggleExample">打卡案例 <img src="../assets/daka_example.png" alt="">
</div>
</div>
<div class="bottom_content">
<div class="rule_item" v-for="(item,index) in ruleList">
{{item}}
<span class="link" v-if="index==ruleList.length-1" @click="jumpToRule">《每天读书打卡规则》</span>
</div>
</div>
</div>
</div>
<div class="user_msg">
<img class="ic_user_msg" @click="toUserCenter" src="../assets/daka_ic_my.png" alt="">
我的
</div>
<Rank v-if="isShowRank" @rankTouching="rankTouching" @closeRank="toggleRank" :rankStatus="rankStatus"
@doSign="payToSign" :isShowRank="isShowRank"></Rank>
<div class="modal" v-if="showDakaSuccessModal">
<DakaSuccess v-on:close="closeDakaSuccess" v-on:nextSign="payToSign"></DakaSuccess>
</div>
<div class="modal" v-if="showRebornModal">
<Reborn
v-on:close="closeReborn"
v-bind:v_data="rebirth_data"
v-on:rebirth="rebirthAction"
v-on:showShareImg="showShareImg"
></Reborn>
</div>
<div class="shareImgDialog" v-if="isShowShareImg">
<div class="shareImgMass"></div>
<div class="shareImgContent" @click="showShareImg">
<img class="shareImg" :src="shareImgUrl" @click="stopPop" @load="imgLoaded"/>
<div class="shareTip" v-if="isImgLoaded">长按上方图片发送给好友</div>
<div class="shareTip" style="margin-top: 0" v-if="isImgLoaded">注:关注公众号后报名才有效</div>
</div>
</div>
<div class="modal" v-if="showFreeModal">
<Free
v-bind:page_type="1"
v-on:close="closeFree"
v-bind:v_data="contract_data"
@showModal="showModal"
@success="showSuccess"
:days="userStatus.days||0"
></Free>
</div>
<PayFailModal v-if="isShowPayFail" @close="togglePayFail"></PayFailModal>
<shareFriendModel v-if="isShowShareFriend" @close="toggleShareFriendModel"></shareFriendModel>
<ExampleModal v-if="isShowExample" @close="toggleExample"></ExampleModal>
<div class="modal" v-if="modalShown">
<Modal v-on:close="closeModal"
v-on:confirmModal="confirmModal"
v-bind:title="modalTitle"
v-bind:option="modalOption"
v-bind:desc="modalDesc">
</Modal>
</div>
</div>
</template>
<script>
import NoticeBonus from "@/components/NoticeBonus.vue";
import shareFriendModel from "@/components/shareFriendModel.vue";
import DakaSuccess from "@/components/DakaSuccess.vue";
import calendar from "@/components/calendar.vue";
import Rank from "@/components/Rank.vue";
import Modal from "@/components/Modal.vue";
import Reborn from "@/components/Reborn.vue";
import Free from "@/components/Free.vue";
import PayFailModal from "@/components/PayFailModal.vue";
import ExampleModal from "@/components/ExampleModal.vue";
import {
shareContent,
dakaStatus,
daka,
userCards,
track,
dailyShare,
dakaPay,
liinShare
} from "@/components/axios/api";
export default {
name: "Daka",
components: {
ExampleModal,
shareFriendModel,
NoticeBonus,
Free,
Rank,
Modal,
calendar,
DakaSuccess,
Reborn,
PayFailModal
},
data() {
return {
isShowExample: false,
isFollow: false,
isShowPayFail: false,
not_signup: true,
next_signup: false,
contract_data: {},
showFreeModal: false,
isShowShareFriend: false,
ruleList: [],
dakaStatus: {},
userStatus: {},
isShowRank: false,
rankStatus: 0,
isTouchingScoller: false,
showDakaSuccessModal: false,
showRebornModal: false,
rebirth_data: null,
modalTitle: "",
modalDesc: "",
modalOption: "",
modalShown: false,
isShowShareImg: false,
isImgLoaded: false,
shareImgUrl: "",
current_date: "",
pageStatus: {
mainBtnStatus: 0,//主按钮状态 0:立即打卡 1:不显示按钮,显示主打卡信息
mainMsgTitleStatus: 0,//主信息标题状态 0:显示打卡成功时间 1:显示打卡失败 2:显示本期未报名
mainMsgTipStatus: 0,//主信息提示状态 0:显示预计到账时间 1.等待复活 2.已复活 3.报名下一期
largeBtnStatus: 0//大按钮状态 0:不显示 1:报名下一期
}
}
},
methods: {
toggleExample() {
this.isShowExample = !this.isShowExample
},
jumpToRule() {
this.$router.push({name: "Rule"})
},
queryPayImage() {
liinShare().then(res => {
if (res.code == 0) {
localStorage.setItem("is_follow", res.data.is_follow);
this.isFollow = res.data.is_follow
}
});
},
togglePayFail() {
this.isShowPayFail = !this.isShowPayFail
},
showSuccess() {
this.showModal("温馨提示", "报名成功", {
scb: () => {
if (this.isFollow == 1) {
this.$router.push({name: "Read"})
} else {
this.$router.push({name: "Success"})
}
}
});
},
showFree(e) {
e.stopPropagation();
track("free_contract_show");
if (localStorage.getItem("first_show_free") == 1) {
localStorage.setItem("first_show_free", 2);
this.canShowFree = false;
} else {
this.canCheckShowFree = false;
this.canShowFree = false;
}
userCards().then(res => {
console.log("获取免契约金数据", res);
let data = {
card: res.data.contract_card,
cnt: res.data.contract_cnt
};
this.current_date = new Date(res.date);
// if (
// // 如果明天没报名,而且还有免契约金卡,则可以使用
// !this.date_status[1].user_status.daka_signup &&
// res.data.contract_card > 0
// ) {
// data.can_get = true;
// // 其他情况,显示报名下期比赛
// } else {
// data.can_get = false;
// }
this.contract_data = JSON.parse(JSON.stringify(data));
this.showFreeModal = true;
});
},
closeFree() {
this.showFreeModal = false;
},
showFriendTip() {
this.showModal("恭喜你打卡成功", "需分享至朋友圈才能成功打卡",
{
showIcon: true,
btnText: "我知道了",
changeImportant: true
})
},
toggleShareFriendModel(e) {
this.isShowShareFriend = !this.isShowShareFriend
if (e && !this.isShowShareFriend) {
this.showFriendTip()
}
},
clickDay(type, day) {
console.log(type, day)
if (type == 3) {
this.showModal("太棒了!当日打卡已完成~", "查看当日学习课程", {
btnText: "去查看",
showCancel: true,
changeImportant: true,
scb: () => {
this.$router.push({name: "Courses"})
}
})
} else if (type == 2) {
let today = new Date().getDate()
if (today == day.day) {
this.showModal("今天还没打卡!", "点击下方黄色按钮进入打卡噢!", {
btnText: "我知道了",
})
} else {
this.showModal("很遗憾,打卡失败!", "这一天你可能太忙忘记打卡了噢", {
btnText: "继续努力",
})
}
} else if (type == 4) {
this.showModal("未开放课程", "别着急哦,每天开放一节课!", {
btnText: "我知道了",
})
}
},
payToSign() {
let days = this.userStatus.days || 0
dakaPay(days).then(response => {
this.current_date = new Date(response.date);
if (response.code == 1) {
this.showModal("温馨提示", response.msg);
return;
}
let result = response.data;
console.log("请求打卡支付数据", result);
if (result) {
WeixinJSBridge.invoke(
"getBrandWCPayRequest",
{
appId: result.appId, //公众号名称,由商户传入
timeStamp: `${result.timeStamp}`, //时间戳,自1970年以来的秒数
nonceStr: result.nonceStr, //随机串
package: result.package,
signType: result.signType, //微信签名方式:
paySign: result.paySign //微信签名
},
// result,
res => {
console.log("支付调用结果", res);
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
// 支付成功后的回调函数
console.log("支付成功");
this.showModal("温馨提示", "报名成功", {
scb: () => {
if (this.isFollow == 1) {
this.$router.push({name: "Read"})
} else {
this.$router.push({name: "Success"})
}
}
});
// this.dateSelect(2);
// localStorage.setItem("is_every", 0)
// location.replace("#/Success");
}
if (res.err_msg == "get_brand_wcpay_request:fail") {
this.togglePayFail()
// this.showModal("温馨提示", "支付服务繁忙,请稍后重试");
}
if (res.err_msg == "get_brand_wcpay_request:cancel") {
this.togglePayFail()
console.log("支付取消");
}
}
);
}
});
},
stopPop(e) {
e.stopPropagation()
},
imgLoaded() {
console.log("图片加载完成")
this.isLoading = false
this.isImgLoaded = true
},
showReborn() {
window.event.stopPropagation();
// track("rebirth_show");
if (localStorage.getItem("first_show_reborn") == 1) {
localStorage.setItem("first_show_reborn", 2);
this.canShowReborn = false;
} else {
this.canCheckShowReborn = false;
this.canShowReborn = false;
}
userCards().then(res => {
console.log("获取复活卡数据", res);
let data = {
card: res.data.rebirth_card,
cnt: res.data.rebirth_cnt
};
this.current_date = new Date(res.date);
let deadline = new Date()
deadline.setHours(21)
deadline.setMinutes(0)
deadline.setSeconds(59)
// console.log("复活测试", this.date_status[1].user_status.daka_signup, !this.date_status[1].user_status.daka_done, this.current_date.getHours(), this.current_date.getHours())
if (
// 如果今天报名了,在8点-12点之间,还没打卡,而且有复活卡,则可以用
// this.date_status[0].user_status.daka_signup &&
// !this.date_status[0].user_status.daka_done &&
this.current_date.getHours() >= 21 &&
this.current_date.getHours() < 24 &&
this.userStatus.daka_signup && !this.userStatus.daka_done &&
res.data.rebirth_card > 0
) {
data.can_get = true;
} else {
data.can_get = false;
}
this.rebirth_data = JSON.parse(JSON.stringify(data));
this.showRebornModal = true;
});
},
showShareImg(type) {
console.log("分享图点击", type)
this.shareImgUrl = ""
this.isShowShareImg = !this.isShowShareImg
if (this.isShowShareImg) {
this.isLoading = true
dailyShare(type).then(res => {
if (res.code === 0) {
this.shareImgUrl = res.data.img_url
console.log(this.shareImgUrl)
} else {
this.isLoading = false
}
}).catch(err => {
this.isLoading = false
})
}
},
closeReborn() {
this.showRebornModal = false;
},
dakaSuccessHandle() {
this.refreshCalendar()
this.getDakaStatus()
this.showModal("恭喜你打卡成功", "坚持学习,向七日总奖金迈进", {
btnText: "继续努力"
})
},
dakaAction() {
if (this.userStatus.daka_done) {
return
}
daka(0)
.then(res => {
console.log("打卡数据", res);
if (res.code == 1) {
this.showModal("温馨提示", res.msg, {btnText: "我知道了"});
return;
}
this.dakaSuccessHandle()
})
.catch(err => {
console.log("打卡请求报错", err);
this.showModal("温馨提示", "服务器繁忙,请稍后重试");
});
},
rebirthAction() {
daka(1)
.then(res => {
if (res.code == 1) {
this.showModal("温馨提示", res.msg);
return;
}
this.closeReborn();
this.dakaSuccessHandle()
// this.showDakaSuccess();
// this.dateSelect(1)
// this.dateSelect(1);
})
.catch(() => {
});
},
showDakaSuccess() {
this.showDakaSuccessModal = true;
},
closeDakaSuccess() {
this.showDakaSuccessModal = false;
this.button_state_num = 0
},
rankTouching(e) {
this.isTouchingScoller = e
},
stopDefault(e) {
if (!this.isTouchingScoller && this.isShowRank) {
e.preventDefault()
}
},
refreshCalendar() {
let calendar = this.$refs.calendar
calendar.getList()
},
showModal(title, desc, option) {
this.modalTitle = title || "";
this.modalDesc = desc || "";
this.modalOption = option || {}
this.modalShown = true;
},
closeModal() {
this.modalShown = false;
},
confirmModal(scb) {
scb && scb()
this.modalShown = false;
},
doReborn() {
},
toggleRank() {
this.$router.push({name: "Record"})
// this.isShowRank = !this.isShowRank
},
toUserCenter() {
this.$router.push({name: "UserCenter"})
},
getDakaStatus() {
dakaStatus().then(res => {
if (res.code === 0) {
this.ruleList = res.data.daka_faq2
this.not_signup = res.data.not_signup
this.next_signup = res.data.next_signup
this.dakaStatus = res.data.daka_info
this.userStatus = res.data.daka_info.user_status
this.statusHandle()
}
})
},
getMainMsgTipText() {
switch (this.pageStatus.mainMsgTipStatus) {
case 0:
return '押金预计今日24点前返还'
case 1:
return '点击复活卡按钮立即复活'
case 2:
return '点击复活卡按钮立即复活'
case 3:
return '点击下方按钮报名下一期'
}
},
statusHandle() {
let tds = this.userStatus.daka_signup//今日报名状态
let tdd = this.userStatus.daka_done//今日打卡状态
let mainBtnStatus = 0//主按钮状态 0:立即打卡 1:不显示按钮,显示主打卡信息
let mainMsgTitleStatus = 0//主信息标题状态 0:显示打卡成功时间 1:显示打卡失败 2:显示本期未报名
let mainMsgTipStatus = 0//主信息提示状态 0:显示预计到账时间 1.等待复活 2.已复活 3.报名下一期
let largeBtnStatus = 0//大按钮状态 0:不显示 1:报名下一期
let now = new Date()
let deadline = new Date()
deadline.setHours(22)
deadline.setMinutes(0)
deadline.setSeconds(59)
if (!tds) {
//未报名,显示未报名页
mainBtnStatus = 1
mainMsgTitleStatus = 2
mainMsgTipStatus = 3
largeBtnStatus = 1
} else {
// 报了名
if (tdd) {
//今天已打卡
mainBtnStatus = 1
} else {
//今天未打卡
if (now <= deadline) {
//打卡时间
} else {
//非打卡时间
mainBtnStatus = 1
mainMsgTitleStatus = 1
mainMsgTipStatus = 1
}
}
}
//大按钮状态
if ((this.userStatus.days == 7 && !this.next_signup && mainBtnStatus == 1) || !tds) {
largeBtnStatus = 1
}
this.pageStatus = {
mainBtnStatus: mainBtnStatus,//主按钮状态 0:立即打卡 1:不显示按钮,显示主打卡信息
mainMsgTitleStatus: mainMsgTitleStatus,//主信息标题状态 0:显示打卡成功时间 1:显示打卡失败 2:显示本期未报名
mainMsgTipStatus: mainMsgTipStatus,//主信息提示状态 0:显示预计到账时间 1.等待复活 2.已复活 3.报名下一期
largeBtnStatus: largeBtnStatus//大按钮状态 0:不显示 1:报名下一期
}
console.log("this.pageStatus", this.pageStatus)
},
initFriendLine() {
let url = location.href.split("#")[0]; //获取锚点之前的链接
// url = url.split("?")[0];
let links = url + "#/SignUp";
shareContent("pyq").then(result => {
console.log("pyq", result)
wx.onMenuShareTimeline({
title: result.data.title, // 分享标题
link: links, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: result.data.img_url, // 分享图标
success: (res) => {
setTimeout(() => {
//回调要执行的代码
// alert(3)
if (this.$router.history.current.name != "Daka") {
return
}
console.log("pyq sc", res)
// 用户点击了分享后执行的回调函数
if (this.isShowShareFriend) {
this.toggleShareFriendModel()
}
this.dakaAction()
}, 500);
// console.log("分享朋友圈")
// alert(123123)
},
cancel: (res) => {
// alert(5)
},
fail: (res) => {
// alert(4)
console.log("pyq fail", res)
}
})
})
},
},
mounted() {
setTimeout(() => {
this.initFriendLine()
}, 500)
},
created() {
this.queryPayImage()
// this.showDakaSuccess();
this.getDakaStatus()
},
filters: {
periodFillter(period) {
if (period) {
return period;
} else {
return "";
}
},
dakaFilter(date) {
if (date) {
return date.substr(11, 10)
} else {
return ""
}
}
}
}
</script>
<style lang="stylus" scoped>
.link {
color #3399ea
}
.modal {
position: fixed;
}
.shareImgDialog {
text-align center
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.shareImgMass {
background: #000;
opacity: 0.7;
width: 100%;
height: 100%;
}
.shareImgContent {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.shareImgContent img {
width: 6.4rem;
}
.shareTip {
font-size: .36rem;
color: #fff;
margin-top: .3rem;
font-weight: 700;
width: 100%;
padding: 0.13rem 0;
background: #5ab640;
}
.daka {
width 100%
height 100%
background #ffffff
position relative
/*-webkit-overflow-scrolling: touch*/
}
.daka_container {
width 100%;
height 100%
position absolute
left 0
top 0
}
.banner {
width 100%;
}
.user_msg {
position absolute;
top .7rem
right .2rem
text-align center
font-size .28rem
color #ffffff
}
.ic_user_msg {
width 0.32rem
margin: 0 auto .1rem;
display block
}
.btn_icon {
width .64rem
margin-bottom .1rem
}
.time_tip {
margin-top .8rem
font-size .28rem
color #ffffff
text-align center
}
.time_tip span {
border-bottom 0.01rem solid #ffe53d
color #ffe53d
}
.money_container {
margin .1rem auto 0
width 6.9rem
box-shadow 0px 2px 14px 0px rgba(180, 197, 200, 0.5);
}
.money_tip {
font-size: 0.26rem;
font-family: Microsoft YaHei;
color: rgba(165, 165, 165, 1);
text-align center
padding .3rem 0
}
.money_content {
display flex
text-align center
font-size .28rem
justify-content center
padding-bottom .2rem
padding-top .3rem
}
.money_content_left, .money_content_right {
margin: 0 0.6rem;
}
.money_left_text, .money_right_text {
margin-top .2rem
color #1AD3D3
font-weight bold
}
.money_left_text span, .money_right_text span {
font-size .6rem
}
.btn_container {
display flex
justify-content space-between
font-size .24rem
padding .3rem 0 0.2rem
}
.rank_btn, .reborn_btn {
flex 1
display flex
flex-direction column
align-items center
font-size .24rem
color rgba(90, 90, 90, 1)
}
.main_btn {
width 4rem
height .88rem
display flex
justify-content center
align-items center
background #FFC30F
font-size .36rem
font-weight bold
color #ffffff
border-radius .44rem
margin: 0.15rem 0 .2rem;
}
.main_msg_container {
text-align center
}
.main_msg_time {
font-size .36rem
color rgba(255, 195, 15, 1)
font-weight bold
margin-top .05rem
}
.main_msg_title {
font-size .36rem
color rgba(136, 136, 136, 1)
font-weight bold
margin-top .05rem
}
.main_msg_tip {
font-size .24rem
color rgba(165, 165, 165, 1)
margin-top .2rem
}
.large_btn, .large_reborn_btn {
width 6.9rem
height .88rem
display flex
justify-content center
align-items center
background #FFC30F
font-size .36rem
font-weight bold
color #ffffff
border-radius .44rem
margin: 0.1rem auto .4rem;
}
.daka_num {
display flex
justify-content center
align-items center
font-size .24rem
color rgba(191, 191, 191, 1)
margin .2rem 0 .3rem
}
.daka_num img {
width .28rem
display block
margin-right .1rem
}
.large_reborn_btn {
background #ff9186
}
.line {
height .2rem
background #F2F2F2
}
.bottom_container {
padding 0 0.4rem
}
.bottom_title {
padding .2rem 0
color #1ad3d3
font-size .28rem
border-bottom .01rem solid rgba(240, 240, 240, 1)
display flex
justify-content space-between
align-items center
}
.bottom_title_left {
display flex
justify-content center
align-items center
}
.bottom_title_left img {
width .28rem
display block
margin-right .1rem
}
.bottom_title_right {
color #1AD3D3
display flex
justify-content center
align-items center
}
.bottom_title_right img {
width .32rem
display block
margin-left .1rem
}
.rule_item {
font-size: .26rem;
color: #5a5a5a;
/* margin: .0rem 0; */
line-height: 2;
letter-spacing: .005rem;
}
</style>
<template>
<div class="have-joined-game-page">
<Title class="page-title" @goback="goback" show_back="true" v-if="currentPage()==='HaveJoinedGame'"></Title>
<div class="game-bonus-container">
<div class="bonus-title">本期累计奖励金(元)</div>
<div class="bonus-amount">6.86</div>
</div>
<div class="game-title">5000步七日耐力赛</div>
<div class="game-time">开赛时间:3月11日 00:00-3月17日24:00</div>
<div class="target-people-container">
<img class="target-img" src="../images/ChallengeDetail/ic_shoes.png">
<div class="target-people-text">每日5000步达标</div>
<img class="people-img" src="../images/ChallengeDetail/ic_people.png">
<div class="target-people-text">已有2468人参赛</div>
</div>
<div class="hr"></div>
<div class="game-scroll-container">
<div class="game-scroll-item">
<div class="item-title-status">
<div class="item-title">第一天</div>
<div class="item-status0">未开始</div>
</div>
<div class="item-income" style="visibility: hidden;">
<div class="item-amount">2.56</div>
<div class="item-text">(元) 预计收益</div>
</div>
<div class="item-progress-num">
<div class="item-num" v-if="true">还有01天03小时56秒开始</div>
<template v-else>
<div class="item-progress" :style="'width: '+rate/100*2.46+'rem;'"></div>
<div class="item-num">2635/5000步</div>
</template>
</div>
</div>
<div class="game-scroll-item">
<div class="item-title-status">
<div class="item-title">第一天</div>
<div class="item-status1">比赛中</div>
</div>
<div class="item-income">
<div class="item-amount">2.56</div>
<div class="item-text">(元) 预计收益</div>
</div>
<div class="item-progress-num">
<div class="item-num" v-if="false">还有01天03小时56秒开始</div>
<template v-else>
<div class="item-progress" :style="'width: '+rate/100*2.46+'rem;'"></div>
<div class="item-num">2635/5000步</div>
</template>
</div>
</div>
<div class="game-scroll-item">
<div class="item-title-status">
<div class="item-title">第一天</div>
<div class="item-status2">已淘汰</div>
</div>
<div class="item-income" style="visibility: hidden;">
<div class="item-amount">2.56</div>
<div class="item-text">(元) 预计收益</div>
</div>
<div class="item-progress-num">
<div class="item-num" v-if="false">还有01天03小时56秒开始</div>
<template v-else>
<div class="item-progress" :style="'width: '+rate/100*2.46+'rem;'"></div>
<div class="item-num">2635/5000步</div>
</template>
</div>
</div>
</div>
<div class="func-btn">提交今日步数</div>
</div>
</template>
<script>
import Title from "@/components/Title.vue";
export default {
name: "HaveJoinedGame",
components: {
Title
},
data() {
return {
rate: 50
}
},
created() {
},
methods: {
goback() {
history.go(-1);
},
goOtherPage(pageName) {
this.$router.push({name: pageName});
},
currentPage() {
return this.$router.history.current.name;
}
}
}
</script>
<style lang="less" scoped>
.have-joined-game-page {
width: 100%;
min-height: 100vh;
background-color: rgb(70, 88, 149);
background-image: url(../images/SignUp/sy_beijing.png);
background-repeat: no-repeat;
background-size: 100%;
background-position: center top;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
position: relative;
.page-title {
width: 100%;
position: fixed;
left: 0;
top: 0;
}
.game-bonus-container {
width: 6.4rem;
padding: .3rem 0;
box-sizing: border-box;
background: linear-gradient(90deg, rgba(255, 255, 255, 0), #1A285A, rgba(255, 255, 255, 0));
margin-top: 2.38rem;
.bonus-title {
font-size: .3rem;
line-height: 1;
color: #fff;
text-align: center;
}
.bonus-amount {
font-size: .64rem;
line-height: .8;
color: #FFE253;
text-align: center;
margin-top: .26rem;
}
}
.game-title {
font-size: .36rem;
line-height: 1;
color: #fff;
font-weight: bold;
margin-top: .4rem;
}
.game-time {
font-size: .24rem;
line-height: 1;
color: #D6DFFF;
padding: .12rem .38rem;
border-radius: .48rem;
background: #556CB6;
margin-top: .14rem;
}
.target-people-container {
display: flex;
margin-top: .34rem;
.target-img {
width: .3rem;
height: .26rem;
}
.people-img {
width: .28rem;
height: .24rem;
margin-left: .5rem;
}
.target-people-text {
font-size: .26rem;
line-height: 1;
color: #fff;
margin-left: .08rem;
}
}
.hr {
width: 3rem;
height: .01rem;
background: #6F82C3;
margin-top: .5rem;
}
.game-scroll-container {
width: 100%;
height: 2.68rem;
margin-top: .4rem;
padding: 0 .3rem;
box-sizing: border-box;
overflow-x: scroll;
white-space: nowrap;
&::-webkit-scrollbar {
display: none;
}
.game-scroll-item {
width: 5.1rem;
height: 2.68rem;
background-image: url(../images/ChallengeDetail/img_card.png);
background-repeat: no-repeat;
background-size: 100% 100%;
padding-top: .24rem;
box-sizing: border-box;
margin-left: .2rem;
display: inline-block;
vertical-align: top;
&:first-child {
margin-left: 0;
}
.item-title-status {
width: 100%;
padding: 0 .24rem 0 .3rem;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
.item-title {
font-size: .3rem;
line-height: 1;
color: #fff;
}
.item-status0 {
padding: 0 .16rem;
box-sizing: border-box;
background: rgba(255, 255, 255, .4);
font-size: .26rem;
line-height: .42rem;
color: #fff;
}
.item-status1 {
padding: 0 .16rem;
box-sizing: border-box;
background: #FCF776;
font-size: .26rem;
line-height: .42rem;
color: #703E0B;
}
.item-status2 {
padding: 0 .16rem;
box-sizing: border-box;
background: #A5A5A5;
font-size: .26rem;
line-height: .42rem;
color: #fff;
}
}
.item-income {
width: 100%;
padding-left: .3rem;
box-sizing: border-box;
margin-top: .4rem;
display: flex;
align-items: flex-end;
.item-amount {
font-size: .48rem;
line-height: .8;
color: #FCF776;
}
.item-text {
font-size: .26rem;
line-height: 1;
color: #DBF3FF;
margin-left: .1rem;
}
}
.item-progress-num {
width: 100%;
padding: 0 .3rem;
box-sizing: border-box;
margin-top: .58rem;
display: flex;
align-items: center;
justify-content: space-between;
.item-progress {
height: .06rem;
background: #fff;
position: relative;
&:after {
content: '';
width: 2.46rem;
height: .06rem;
background: rgba(255, 255, 255, .5);
position: absolute;
}
}
.item-num {
font-size: .26rem;
line-height: 1;
color: #fff;
}
}
}
}
.func-btn {
width: 5.6rem;
border-radius: .92rem;
background: #FABD21;
font-size: .4rem;
line-height: .92rem;
color: #fff;
font-weight: bold;
text-align: center;
margin-top: 1.2rem;
}
}
</style>
<template>
<div class="home">
</div>
</template>
<script>
// @ is an alias to /src
export default {
name: 'home',
components: {
}
}
</script>
<template>
<div class="main-page">
<router-view class="main-page-child"/>
<div class="bottom-bar">
<div class="bottom-tab" @click="selectTab('SignUp')">
<div :class="['text', currentPage()==='SignUp'?'active':'']">7天健步挑战赛</div>
</div>
<div class="bottom-tab" @click="selectTab('nowGame')">
<div :class="['text', (currentPage()==='MainPagePartakeChallenge'||currentPage()==='MainPageHaveJoinedGame')?'active':'']">当前比赛</div>
</div>
<div class="bottom-tab" @click="selectTab('UserCenter')">
<div :class="['text', currentPage()==='UserCenter'?'active':'']">我的</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "MainPage",
data() {
return {
}
},
created(){
},
methods: {
selectTab(item) {
if (item === 'nowGame') {
if (true) {
this.$router.push({name: 'MainPagePartakeChallenge'});
} else {
this.$router.push({name: 'MainPageHaveJoinedGame'});
}
} else {
this.$router.push({name: item});
}
},
currentPage() {
return this.$router.history.current.name;
}
},
}
</script>
<style lang="less" scoped>
.main-page {
height: 100vh;
padding-bottom: .9rem;
box-sizing: border-box;
.main-page-child {
height: 100%;
}
.bottom-bar {
width: 100%;
height: .9rem;
background: #fff;
display: flex;
align-items: center;
position: fixed;
bottom: 0;
left: 0;
z-index: 999;
.bottom-tab {
flex: 1;
height: 100%;
display: flex;
justify-content: center;
.text {
height: 100%;
font-size: .3rem;
line-height: .9rem;
color: #333;
&.active {
color: #07C9D1;
position: relative;
&:after {
content: '';
width: 100%;
height: .08rem;
background: #07C9D1;
position: absolute;
bottom: 0;
left: 0;
}
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="partake-challenge-page">
<Title class="page-title" title=" " v-on:goback="goback" show_back="true"></Title>
<div class="game-title">5000步七日耐力赛</div>
<div class="game-time">开赛时间:3月11日 00:00-3月17日24:00</div>
<div class="game-cost">本期运动契约金:<span>21.00元/人</span></div>
<div class="game-introduce-container">
<div class="game-introduce-title">
<img src="../images/PartakeChallenge/ic_3.png">
步赚取运动奖励金
</div>
<div class="game-introduce-section">
<img class="section-icon" src="../images/PartakeChallenge/ic_join.png">
<div class="section-content">
<div class="content-title">报名参赛</div>
<div class="content-text">支付7.00元运动契约金,即可加入5000步日耐力赛,契约金平均分配到每个比赛日,每日结算1次。</div>
</div>
</div>
<div class="game-introduce-section">
<img class="section-icon" src="../images/PartakeChallenge/ic_suc.png">
<div class="section-content">
<div class="content-title">运动达标</div>
<div class="content-text">每日走满5000步即可达标,获得当日奖励资格;未达标用户将失去后续比赛的参赛资格,其契约金将继续作为奖励金奖励达标用户。</div>
</div>
</div>
<div class="game-introduce-section">
<img class="section-icon" src="../images/PartakeChallenge/ic_money.png">
<div class="section-content">
<div class="content-title">获得奖励</div>
<div class="content-text">次日结算前日比赛,达标者获得对应奖励金;总奖励金为用户每日达标奖金之和。</div>
</div>
</div>
</div>
<div class="footer-container">
<div class="auth-container">
<img class="auth-checked" src="../images/PartakeChallenge/ic_choose.png" v-if="true">
<div class="auth-uncheck" v-else></div>
<div class="text1">我同意</div>
<div class="text2" @click="goOtherPage('Rule')">《步数打卡的挑战规则协议》</div>
</div>
<div class="partake-btn">立即报名</div>
</div>
</div>
</template>
<script>
import Title from "@/components/Title.vue";
export default {
name: "PartakeChallenge",
components: {
Title
},
data() {
return {
}
},
created() {
},
methods: {
goback() {
history.go(-1);
},
goOtherPage(pageName) {
this.$router.push({name: pageName});
},
}
}
</script>
<style lang="less" scoped>
.partake-challenge-page {
min-height: 100vh;
background-color: rgb(70, 88, 149);
background-image: url(../images/SignUp/sy_beijing.png);
background-repeat: no-repeat;
background-size: 100%;
background-position: center top;
display: flex;
flex-direction: column;
align-items: center;
.page-title {
position: fixed;
left: 0;
top: 0;
}
.game-title {
font-size: .36rem;
line-height: 1;
color: #fff;
font-weight: bold;
margin-top: 4.4rem;
}
.game-time {
font-size: .24rem;
line-height: 1;
color: #D6DFFF;
padding: .12rem .38rem;
border-radius: .48rem;
background: #556CB6;
margin-top: .14rem;
}
.game-cost {
font-size: .26rem;
line-height: 1;
color: #fff;
margin-top: .34rem;
span {
color: #FFE253;
}
}
.game-introduce-container {
width: 7.1rem;
border-radius: .08rem;
padding: .36rem .28rem .2rem;
box-sizing: border-box;
background: #fff;
margin-top: .34rem;
margin-bottom: 1.6rem;
display: flex;
flex-direction: column;
align-items: center;
.game-introduce-title {
display: flex;
align-items: flex-end;
font-size: .3rem;
line-height: 1;
color: #333;
margin-bottom: .24rem;
img {
width: .26rem;
height: .35rem;
margin-right: .08rem;
}
}
.game-introduce-section {
width: 100%;
margin-top: .34rem;
display: flex;
align-items: flex-start;
&:last-of-type .section-content {
border-bottom: none;
}
.section-icon {
width: .8rem;
height: .8rem;
flex-shrink: 0;
margin-right: .3rem;
}
.section-content {
flex: 1;
border-bottom: .01rem solid #e5e5e5;
.content-title {
font-size: .3rem;
line-height: 1;
color: #333;
}
.content-text {
font-size: .24rem;
line-height: .36rem;
color: #999;
margin: .16rem 0 .14rem;
}
}
}
}
.footer-container {
width: 100%;
position: fixed;
left: 0;
bottom: 0;
.auth-container {
width: 100%;
height: .52rem;
background: #F2F2F2;
display: flex;
align-items: center;
justify-content: center;
.auth-checked {
width: .24rem;
height: .24rem;
}
.auth-uncheck {
width: .24rem;
height: .24rem;
border: .01rem solid #BFBFBF;
box-sizing: border-box;
border-radius: 50%;
}
.text1 {
font-size: .24rem;
line-height: 1;
color: #999;
margin: 0 .1rem;
}
.text2 {
font-size: .24rem;
line-height: 1;
color: #576B95;
}
}
.partake-btn {
width: 100%;
background: #FABD21;
font-size: .36rem;
line-height: .88rem;
color: #fff;
font-weight: bold;
text-align: center;
}
}
}
</style>
<template>
<div class="Question">
<Title class="page-title" title="常见问题" titleColor="#000" @goback="goback" show_back="true" arrowColor="black"></Title>
<ul style="padding-top: .9rem">
<li
v-for="item,index in data_list"
@click="switchQuestion(index)"
>
<div class="que_title">
<div
class="active"
v-if="item.active"
> {{item.title}}
<img src="../assets/ic_zk.png">
</div>
<div v-if="!item.active"> {{item.title}} <img src="../assets/ic_zk.png"></div>
</div>
<div
class="que_desc"
v-if="item.active"
>
{{item.desc}}
</div>
</li>
</ul>
<div class="button_container">
<div
class="kefu_button"
@click="jumpToKeFu"
>联系客服
</div>
</div>
<FollowDialog :isKefu="isKefu" v-if="isShowFollow" @close="toggleFollowDialog"></FollowDialog>
</div>
</template>
<style>
.Question {
width: 100%;
height: 100%;
background: #f1f1f1;
/*padding-top: 0.9rem;*/
overflow-x: hidden;
}
.Question .title_container {
color: #282828;
background: #ffffff;
/*height: 0.9rem;*/
position: fixed;
top: 0;
width: 100%;
}
.big .Question {
padding-top: 0.9rem;
}
.big .Question .title_container {
height: 0.9rem;
}
.Question li {
margin-top: 0.2rem;
}
.Question li > div {
background: #ffffff;
text-align: left;
color: #282828;
font-size: 0.3rem;
border-bottom: 1px solid #e8e8e8;
padding-right: 0.3rem;
padding-left: 0.3rem;
}
.Question li > div.que_title {
height: 1rem;
line-height: calc(1 / 0.3);
}
.Question li > div.que_title div {
font-size: 0.3rem;
}
.Question li > div.que_title .active {
color: #8a8a8a;
}
.Question li > div.que_title img {
display: block;
float: right;
/* margin-right:0.3rem; */
width: 0.36rem;
margin-top: 0.33rem;
}
.Question li > div.que_desc {
padding: 0.3rem;
line-height: 1.2;
}
.Question .button_container {
width: 100%;
height: 1.78rem;
border: 1px solid transparent;
background: #f1f1f1;
}
.Question .kefu_button {
width: 5rem;
height: 0.88rem;
margin-top: 0.4rem;
margin-left: calc((100% - 5rem) / 2);
margin-bottom: 0.5rem;
background: #ffbb34;
border-radius: 0.44rem;
font-size: 0.38rem;
font-weight: bold;
color: #ffffff;
line-height: calc(0.88 / 0.38);
text-align: center;
}
</style>
<script>
// 常见问题
import Title from "@/components/Title.vue";
import FollowDialog from "@/components/FollowDialog.vue";
import {faq} from "@/components/axios/api";
export default {
name: "Question",
components: {
Title,
FollowDialog
},
data() {
return {
data_list: [],
isShowFollow: false,
isKefu: 1
};
},
methods: {
toggleFollowDialog() {
this.isShowFollow = !this.isShowFollow
},
switchQuestion(index) {
this.data_list = this.data_list.map(item => {
item.active = false;
return item;
});
this.data_list[index].active = true;
},
jumpToKeFu() {
this.toggleFollowDialog()
// window.location.href = "https://mp.weixin.qq.com/s/YFO5CA_iKSBdnXbxJZAC-Q"
},
goback() {
this.$router.push({name: "UserCenter"})
// location.replace("#/MyData");
}
},
created() {
faq()
.then(res => {
if (res.code == 0) {
console.log("获取常见问题列表", res, res.data);
this.data_list = res.data.map(item => {
return {
active: false,
title: item[0],
desc: item[1]
};
});
}
})
.catch(() => {
});
},
mounted() {
}
};
</script>
<template>
<div class="read_page">
<div class="read" v-if="!isReading&&isSignUp">
<div class="top_container">
<div class="day">{{userStatus.days}}</div>
<div class="book_msg">
<div class="book_img">
<img :src="bookMsg.story_img" alt="">
</div>
<div class="book_title">{{bookMsg.story_title}}</div>
<div class="book_author">来自:{{bookMsg.story_author}}</div>
</div>
</div>
<div class="bottom_container">
<div class="study_btn" @click="toReading">开始学习</div>
</div>
</div>
<div class="not_sign_page" v-else>
<div class="book_title" style="margin: 2rem 0 .2rem">新的一期读书打卡开始了哦~</div>
<div class="book_author">点击下方按钮去报名</div>
<div class="study_btn" @click="toDaka" style="margin-top: 1rem">立即报名</div>
</div>
<!--<div class="reading" v-if="isReading">-->
<!--<div class="top_container">-->
<!--<div class="book_icon">-->
<!--<img src="../assets/read_img.png" alt="">-->
<!--</div>-->
<!--<div class="book_msg">-->
<!--<div class="book_title">{{bookMsg.story_title}}</div>-->
<!--<div class="book_author">来自:{{bookMsg.story_author}}</div>-->
<!--</div>-->
<!--<div class="book_content" v-html="bookMsg.content"></div>-->
<!--</div>-->
<!--<div class="bottom_container">-->
<!--<div class="study_btn">进入打卡</div>-->
<!--</div>-->
<!--</div>-->
</div>
</template>
<script>
import {
dakaStatus,
story_detail,
} from "@/components/axios/api";
export default {
name: "Read",
data() {
return {
dakaInfo: {},
userStatus: {},
bookMsg: {},
isReading: false,
isSignUp: true
}
},
methods: {
toDaka(){
this.$router.push({name:"Daka"})
},
toReading() {
this.$router.push({name: "Reading", query: {canDaka: "1"}})
},
getStatus() {
dakaStatus().then(res => {
if (res.code == 0) {
this.dakaInfo = res.data.daka_info
this.userStatus = this.dakaInfo.user_status
this.getList()
}
})
},
getList() {
story_detail(this.userStatus.course_id, this.userStatus.days).then(res => {
if (res.code == 0) {
this.bookMsg = res.data.data
this.isSignUp = res.data.is_signup
}
}).catch(err => [
this.isSignUp = false
])
}
},
created() {
console.log("$router", this.$router)
this.getStatus()
}
}
</script>
<style scoped>
.not_sign_page{
display: flex;
flex-direction: column;
align-items: center;
}
.read_page {
}
.read {
height: 100%;
text-align: center;
display: flex;
flex-direction: column;
}
.reading {
height: 100%;
text-align: center;
display: flex;
flex-direction: column;
}
.bottom_container {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.day {
font-size: .32rem;
color: #A5A5A5;
margin-bottom: .3rem;
}
.book_img {
text-align: center;
margin-bottom: .2rem;
}
.book_img img {
width: 5rem;
}
.book_title {
font-size: .36rem;
color: #333333;
margin-bottom: .3rem;
}
.book_author {
font-size: .28rem;
color: #A5A5A5;
}
.study_btn {
width: 4rem;
height: .88rem;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
font-size: .36rem;
border-radius: .44rem;
background: rgba(255, 195, 15, 1);
/*margin: 0 auto;*/
}
.reading .book_icon img {
width: 4.6rem;
margin-top: .2rem;
}
.book_content {
width: 6.23rem;
margin: .3rem auto 0;
font-size: .28rem;
text-align: left;
}
.book_content p {
margin: 0;
}
</style>
<style>
.book_content p {
margin: .1rem 0;
text-indent: .5rem;
}
</style>
<template>
<div class="reading">
<div class="close_btn" @click="goBack"></div>
<div class="top_container">
<div class="book_icon">
<img src="../assets/read_img.png" alt="">
</div>
<div class="book_msg">
<div class="book_title">{{bookMsg.story_title}}</div>
<div class="book_author">来自:{{bookMsg.story_author}}</div>
</div>
<div class="book_content" v-html="bookMsg.content"></div>
</div>
<div class="bottom_container" v-if="canDaka">
<div class="study_btn" @click="toDaka">进入打卡</div>
</div>
</div>
</template>
<script>
import {
dakaStatus,
story_detail,
} from "@/components/axios/api";
export default {
name: "Read",
data() {
return {
dakaInfo: {},
userStatus: {},
bookMsg: {},
isReading: false,
storyId: "",
days: "",
canDaka: false
}
},
methods: {
goBack(){
history.go(-1)
},
getStatus() {
dakaStatus().then(res => {
if (res.code == 0) {
this.dakaInfo = res.data.daka_info
this.userStatus = this.dakaInfo.user_status
this.getList()
}
})
},
getList() {
let id = this.storyId ? this.storyId : this.userStatus.course_id
let days = this.days ? this.days : this.userStatus.days
story_detail(id, days).then(res => {
if (res.code == 0) {
this.bookMsg = res.data.data
}
})
},
toDaka() {
this.$router.push({name: "Daka"})
}
},
created() {
this.storyId = this.$route.query.storyId
this.days = this.$route.query.days
this.$route.query.canDaka && (this.canDaka = this.$route.query.canDaka)
this.getStatus()
}
}
</script>
<style scoped>
.close_btn{
position: absolute;
background: url("../assets/ic_back_black.png") 0 0 no-repeat;
background-size: contain;
width: 0.24rem;
height: 0.42rem;
left: 0.2rem;
top: 0.26rem;
}
.reading {
height: 100%;
text-align: center;
display: flex;
flex-direction: column;
}
.bottom_container {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.book_img img {
width: 3.8rem;
}
.book_title {
font-size: .38rem;
color: #333;
margin-bottom: .3rem;
font-weight: bold;
}
.book_author {
font-size: .28rem;
color: #A5A5A5
}
.study_btn {
width: 4rem;
height: .88rem;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
font-size: .36rem;
border-radius: .44rem;
background: rgba(255, 195, 15, 1);
/*margin: 0 auto;*/
}
.reading .book_icon img {
width: 4.6rem;
margin-top: .2rem;
margin-bottom: .2rem;
}
.book_content {
width: 6.23rem;
margin: .3rem auto 0;
font-size: .3rem;
text-align: left;
}
.book_content p {
margin: 0;
}
</style>
<style>
.book_content p {
margin: .1rem 0;
text-indent: .5rem;
letter-spacing: .03rem;
line-height: 1.6;
}
</style>
<template>
<div class="record-page">
<div class="banner">
<Title title="挑战明细" v-on:goback="goback" show_back="true" arrowColor="white"></Title>
<div class="amount-detail" @click="goOtherPage('AmountDetail')">资金明细</div>
<div class="total-amount-container">
<div class="title">总奖励金(元)</div>
<div class="amount">{{recordTotal.money | moneyFormatter }}</div>
</div>
<div class="other-info-container">
<div class="other-info-item">
<div class="title">参赛次数</div>
<div class="content">{{recordTotal.total}}</div>
</div>
<div class="other-info-item">
<div class="title">达标率</div>
<div class="content">{{recordTotal.rach_rate}}%</div>
</div>
<div class="other-info-item">
<div class="title">达标次数</div>
<div class="content">{{recordTotal.daka_count}}</div>
</div>
</div>
</div>
<div class="card-container-list" @scroll="onScroll">
<div class="card-item" v-for="(item,index) in recordList.records" @click="toRecordDetail(item)">
<div class="card-title">{{item.period}}期-{{item.grade}}{{item.total_days}}日耐力赛(第{{item.days}}天)</div>
<div class="card-detail-container">
<div class="detail-item">
<div class="item-title">累计奖励金(元)</div>
<div class="item-content-point">{{item.money | moneyFormatter}}</div>
</div>
<div class="detail-item">
<div class="item-title">当前步数</div>
<div class="item-content">{{item.steps || 0}}</div>
</div>
<div class="detail-item">
<div class="item-title">打卡次数</div>
<div class="item-content">{{item.daka_count || 0}}</div>
</div>
</div>
<img class="corner-marker" src="../images/Record/status0.png" v-if="item.at_present === 2">
<img class="corner-marker" src="../images/Record/status1.png" v-else-if="item.at_present === 1">
<img class="corner-marker" src="../images/Record/status2.png" v-else-if="item.at_present === 3">
<img class="corner-marker" src="../images/Record/status3.png" v-else-if="item.at_present === 0">
</div>
<div class="no-more-list">没有更多数据啦~</div>
</div>
</div>
</template>
<script>
import Title from "@/components/Title.vue";
import {dakaRecordTotal, dakaRecordList} from "@/components/axios/api";
export default {
name: "Record",
components: {
Title
},
data() {
return {
recordTotal: {
daka_count: 0,
money: 0,
rach_rate: 0,
total: 0
},
page: 1,
canScroll: true,
recordList: {
next_page: false,
records: []
}
};
},
methods: {
goOtherPage(pageName) {
this.$router.push({name: pageName});
},
goback() {
history.go(-1);
},
toRecordDetail(item) {
// location.replace("#/RecordDetail");
sessionStorage.setItem("selectedRecord", JSON.stringify(item));
this.$router.push({name: "RecordDetail"})
},
onScroll(event) {
if (this.recordList.next_page && this.canScroll) {
let offsetHeight = event.currentTarget.offsetHeight,
scrollHeight = event.target.scrollHeight,
scrollTop = event.target.scrollTop,
scrollBottom = offsetHeight + scrollTop;
if (Math.abs(scrollHeight - scrollBottom) < 5) {
this.canScroll = false;
console.log("onScroll", "到底部");
this.page += 1;
this.getRecordList(true);
}
}
},
getRecordTotal() {
dakaRecordTotal().then(result => {
if (result.code == 0) {
this.recordTotal = result.data;
}
}).catch(e => {
console.log("dakaRecordTotal err", e);
});
},
getRecordList(notRefresh) {
dakaRecordList(this.page, 10).then(result => {
this.canScroll = true;
if (result.code == 0) {
if (!notRefresh) {
this.recordList = result.data;
} else {
this.recordList.next_page = result.data.next_page;
this.recordList.records = this.recordList.records.concat(result.data.records);
}
}
}).catch(e => {
this.canScroll = true;
console.log("dakaRecordList err", e);
});
}
},
created() {
this.getRecordTotal();
this.getRecordList();
},
filters: {
moneyFormatter(val) {
if (val && !isNaN(val)) {
return Number(val).toFixed(2);
} else {
return "0.00";
}
}
}
};
</script>
<style lang="less" scoped>
.record-page {
min-height: 100vh;
background: #F2F4F5;
display: flex;
flex-direction: column;
.banner {
height: 4rem;
background: linear-gradient(0, #07C9D1, #2AD6A6);
text-align: center;
position: relative;
.amount-detail {
font-size: .3rem;
line-height: .94rem;
color: #fff;
position: absolute;
top: 0;
right: .32rem;
}
.total-amount-container {
margin-top: .2rem;
.title {
font-size: .26rem;
color: #fff;
line-height: 1;
}
.amount {
font-size: .64rem;
color: #fff;
line-height: .8;
margin-top: .24rem;
}
}
.other-info-container {
display: flex;
margin-top: .6rem;
.other-info-item {
flex: 1;
.title {
font-size: .26rem;
color: #fff;
line-height: 1;
}
.content {
font-size: .48rem;
color: #fff;
line-height: .8;
margin-top: .24rem;
}
}
}
}
.card-container-list {
width: 100%;
overflow-y: scroll;
padding-bottom: .2rem;
-webkit-overflow-scrolling: touch;
&::-webkit-scrollbar {
display: none;
}
.card-item {
width: 100%;
height: 2.44rem;
background: #ffffff;
margin-top: .14rem;
position: relative;
.card-title {
font-size: .3rem;
line-height: 1;
color: #333;
font-weight: bold;
padding: .3rem .3rem .5rem;
}
.card-detail-container {
display: flex;
padding-left: .3rem;
.detail-item {
flex: 1;
.item-title {
font-size: .26rem;
line-height: .8;
color: #888;
text-align: left;
}
.item-content {
font-size: .48rem;
line-height: .8;
color: #333;
text-align: left;
margin-top: .24rem;
}
.item-content-point {
font-size: .48rem;
line-height: .8;
color: #ffbb33;
text-align: left;
margin-top: .24rem;
}
}
}
.corner-marker {
width: 1.39rem;
height: 1.39rem;
position: absolute;
top: 0;
right: 0;
}
}
.no-more-list {
font-size: .26rem;
line-height: 1;
color: #999;
text-align: center;
margin: .8rem 0 .3rem;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="RecordDetail">
<div class="banner">
<!--<img class="banner_bg" src="../assets/img_top2.png" alt="">-->
<div class="banner_container">
<Title
v-bind:title="title"
v-on:goback="goback"
show_back="true"
></Title>
<div class="banner_top">
<div class="banner_top_title">{{recordData.period}}期 获得奖金(元)</div>
<div class="banner_top_data">{{recordData.money?Number(recordData.money).toFixed(2):0}}</div>
</div>
<div class="banner_bottom">
<div class="banner_bottom_item">
<div class="banner_bottom_title">收益率</div>
<div class="banner_bottom_data">{{recordData.rate?Number(recordData.rate):0}}%</div>
</div>
<div class="banner_bottom_item">
<div class="banner_bottom_title">成功打卡天数</div>
<div class="banner_bottom_data">{{recordData.daka_count?Number(recordData.daka_count):0}}</div>
</div>
</div>
</div>
</div>
<div class="card_container">
<div class="record_container">
<div class="record_header">
<div class="header_item">日期</div>
<div class="header_item">打卡时间</div>
<div class="header_item">课程</div>
</div>
<div class="record_scroller" @scroll="onScroll">
<div class="record_item" v-for="(item,index) in this.detailData" @click="toReading(item)">
<div class="record_date">{{item.day_date}}</div>
<div class="record_time" v-if="item.daka_done">{{item.daka_time?item.daka_time.substr(11, 5):""}}</div>
<div class="record_time fail" v-else-if="item.showStatus">漏打卡</div>
<div class="record_time" v-else></div>
<div class="record_course">{{item.story_title}}</div>
</div>
</div>
</div>
</div>
<div class="modal" v-if="modalShown">
<Modal v-on:close="closeModal"
v-on:confirmModal="confirmModal"
v-bind:title="modalTitle"
v-bind:option="modalOption"
v-bind:desc="modalDesc">
</Modal>
</div>
</div>
</template>
<style>
.RecordDetail .title_text {
color: black;
}
.RecordDetail .back {
background: url("../assets/ic_back_black.png") 0 0 no-repeat;
background-size: contain;
width: 0.24rem;
height: 0.42rem;
left: 0.2rem;
top: 0.26rem;
}
</style>
<style scoped>
.banner_bg {
display: block;
width: 100%;
}
.banner_container {
/*position: absolute;*/
/*left: 0;*/
/*top: 0;*/
width: 100%;
color: #ffffff;
}
.RecordDetail {
background: rgba(241, 241, 241, 1);
height: 100%;
display: flex;
flex-direction: column;
text-align: center;
}
.banner {
background: #fff;
border: 0;
height: auto;
padding-bottom: .5rem;
margin-bottom: .2rem;
/*height: 4.8rem;*/
}
.banner_top_title {
margin: 0.3rem 0 0.3rem;
font-size: 0.26rem;
color: rgba(254, 169, 0, 1);
}
.banner_bottom_title {
margin: 0.8rem 0 0.3rem;
font-size: 0.26rem;
color: rgba(90, 90, 90, 1);
}
.banner_top_data {
font-size: 0.72rem;
color: rgba(254, 169, 0, 1);
font-weight: bold;
}
.banner_bottom_data {
font-size: 0.36rem;
color: rgba(90, 90, 90, 1);
font-weight: bold;
}
.banner_bottom {
display: flex;
}
.banner_bottom_item {
flex: 1;
}
.card_container {
flex: 1;
background: #fff;
display: flex;
flex-direction: column;
}
.container_title {
text-align: left;
display: flex;
align-items: center;
padding-top: 0.25rem;
margin-left: 0.3rem;
margin-bottom: 0.1rem;
}
.container_title div {
font-size: 0.26rem;
color: #282828;
}
.container_title img {
width: 0.28rem;
margin-right: 0.1rem;
}
.container_tab {
display: flex;
justify-content: space-around;
border-bottom: 0.01rem solid #e8e8e8;
}
.container_tab img {
width: 0.73rem;
}
.tabItem {
display: flex;
color: #8a8a8a;
flex-direction: column;
}
.tabItem div {
font-size: 0.3rem;
margin-bottom: 0.15rem;
}
.tabItem.active {
color: #282828;
}
.record_container {
flex: 1;
display: flex;
flex-direction: column;
padding: 0 .3rem;
}
.record_header {
display: flex;
font-size: 0.24rem;
color: #97d7e7;
padding: 0.3rem 0;
border-bottom: 0.01rem solid #e8e8e8;
}
.header_item {
flex: 1;
font-size: 0.3rem;
}
.record_scroller {
flex: 1;
overflow-y: scroll;
-webkit-overflow-scrolling: touch
}
.record_scroller::-webkit-scrollbar {
display: none;
}
.record_item {
display: flex;
align-items: center;
padding: 0.3rem 0;
border-bottom: 0.01rem solid #e8e8e8;
background: #fff;
}
.record_course,
.record_date,
.record_time {
flex: 1;
font-size: 0.3rem;
color: #000000;
}
.record_time.fail {
color: rgba(255, 146, 134, 1);
}
.record_course {
color: #576B95;
}
.rank_num img {
width: 0.6rem;
}
</style>
<script>
// 打卡记录
import Title from "@/components/Title.vue";
import {dakaRecordDetail, dakaRank, personRank, daka_records_detail} from "@/components/axios/api";
import Modal from "@/components/Modal.vue";
export default {
name: "RecordDetail",
components: {
Title,
Modal
},
data() {
return {
modalTitle: "",
modalDesc: "",
modalOption: "",
modalShown: false,
title: "每日读书奖金赛详情",
tab: 1,
recordData: {
period: "",
daka_done: false
},
page: 1,
canScroll: true,
detailData: [],
selfData: {},
targetDate: {},
rankImg: [
{
src: require("../assets/ic_record_1.png")
},
{
src: require("../assets/ic_record_2.png")
},
{
src: require("../assets/ic_record_3.png")
}
]
};
},
methods: {
showModal(title, desc, option) {
this.modalTitle = title || "";
this.modalDesc = desc || "";
this.modalOption = option || {}
this.modalShown = true;
},
closeModal() {
this.modalShown = false;
},
confirmModal(scb) {
scb && scb()
this.modalShown = false;
},
toReading(item) {
let now = new Date()
let date = new Date(item.day_date)
if (date < now || (date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate())) {
if ((date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate())) {
this.$router.push({name: "Reading", query: {storyId: item.story_id, days: item.days, canDaka: "1"}})
} else {
this.$router.push({name: "Reading", query: {storyId: item.story_id, days: item.days}})
}
} else {
this.showModal("未开放课程", "别着急哦,每天开放一节课!", {
btnText: "我知道了",
})
}
},
goback() {
history.go(-1)
// this.$router.push({name:"Record"})
},
changeTab(tab) {
this.tab = tab;
this.page = 1;
this.getRecordDetail();
},
setTargetDate() {
let targetDate = new Date()
targetDate.setHours(22)
targetDate.setMinutes(0)
targetDate.setSeconds(59)
this.targetDate = targetDate
},
getRecordDetail(notRefresh) {
console.log(this.recordData)
daka_records_detail(this.recordData.period).then(res => {
if (res.code == 0) {
this.detailData = res.data;
for (let item of this.detailData) {
let now = new Date()
let date = new Date(item.day_date)
if (date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate()) {
if (now >= this.targetDate || item.daka_done) {
item.showStatus = true
}
} else {
if (date < now) {
item.showStatus = true
}
}
}
}
})
// let period = this.recordData.period;
// personRank(period).then(res => {
// if (res.code == 0) {
// this.selfData = res.data
// }
// })
// dakaRank(this.page, 10, period)
// .then(result => {
// this.canScroll = true;
// console.log(result);
// if (result.code == 0) {
// let data = JSON.parse(JSON.stringify(result.data));
// data.records = data.records.filter(item => {
// return !!item.user_info;
// });
// console.log("过滤后数据", data);
// if (!notRefresh) {
// this.detailData = data;
// this.detailData.higtest_bonus = this.detailData.records[0].money
// } else {
// this.detailData.next_page = data.next_page;
// this.detailData.total = data.total;
// this.detailData.records = this.detailData.records.concat(
// data.records
// );
// }
// }
// })
// .catch(e => {
// this.canScroll = true;
// console.log("dakaRecordDetail err", e);
// });
},
onScroll(event) {
if (this.detailData.next_page && this.canScroll) {
let offsetHeight = event.currentTarget.offsetHeight,
scrollHeight = event.target.scrollHeight,
scrollTop = event.target.scrollTop,
scrollBottom = offsetHeight + scrollTop;
if (Math.abs(scrollHeight - scrollBottom) < 5) {
this.canScroll = false;
console.log("onScroll", "到底部");
if (this.page < 10) {
this.page += 1;
this.getRecordDetail(true);
}
}
}
},
},
created() {
this.setTargetDate()
let recordData = sessionStorage.getItem("selectedRecord");
if (recordData) {
this.recordData = JSON.parse(recordData);
}
this.getRecordDetail();
},
filters: {
moneyFormatter(val) {
if (val && !isNaN(val)) {
return Number(val).toFixed(2);
} else {
return "0.00";
}
}
}
};
</script>
<template>
<div class="redpack_log">
<Title
v-bind:title="title"
v-on:goback="goback"
show_back="true"
show_blame=""
></Title>
<div class="list_container" @scroll="onScroll">
<div class="list_item" v-for="item in moneyLog">
<div class="item_left">
<div class="item_title">提现</div>
<div class="item_date">{{item.created_at}}</div>
</div>
<div class="item_right">
<div class="item_title">{{item.value}}</div>
<div class="item_tip item_tip1" v-if="item.valid">已到账</div>
<div class="item_tip item_tip2" v-else>提现中</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Title from "@/components/Title.vue";
import {withdraw_log} from "@/components/axios/api";
export default {
name: "RedpackLog",
components: {
Title,
},
data() {
return {
title: "提现明细",
moneyLog: [],
next_page: false,
page: 1,
canScroll:true
}
},
methods: {
goback() {
location.replace("#/Wallet");
},
getList(notRefresh) {
withdraw_log(this.page).then(res => {
this.canScroll = true;
if (res.code == 0) {
if (!notRefresh) {
this.next_page = res.data.next_page
this.moneyLog = res.data.logs
} else {
this.next_page = res.data.next_page
this.moneyLog = this.moneyLog.concat(
res.data.logs
);
// this.detailData.records = this.detailData.records.concat(
// data.records
// );
}
}
}).catch(e=>{
this.canScroll = true;
})
},
onScroll(event) {
console.log("onScroll")
if (this.next_page && this.canScroll) {
let offsetHeight = event.currentTarget.offsetHeight,
scrollHeight = event.target.scrollHeight,
scrollTop = event.target.scrollTop,
scrollBottom = offsetHeight + scrollTop;
if (Math.abs(scrollHeight - scrollBottom) < 5) {
this.canScroll = false;
console.log("onScroll", "到底部");
this.page += 1;
this.getList(true);
}
}
},
},
created() {
this.getList()
}
}
</script>
<style scoped>
.redpack_log{
width: 100%;
height: 100%;
display: flex;
}
.list_container {
width: 100%;
flex: 1;
/*height: 100%;*/
padding-top: 1rem;
overflow-y: scroll;
}
.list_item {
display: flex;
padding: .36rem .4rem;
border-top: .02rem solid rgba(224, 224, 224, 1);
}
.item_left {
flex: 1;
text-align: left;
}
.item_right {
flex: 1;
text-align: right;
}
.item_title {
font-size: .32rem;
color: rgba(40, 40, 40, 1);
margin-bottom: .2rem;
}
.item_date {
font-size: .28rem;
color: rgba(165, 165, 165, 1);
}
.item_tip {
font-size: .28rem;
}
.item_tip1 {
color: rgba(165, 165, 165, 1);;
}
.item_tip2 {
color: rgba(199, 167, 93, 1);;
}
</style>
<style>
.redpack_log .back {
background-image: url("../assets/ic_back_black.png");
}
.redpack_log .title_container {
color: #282828;
background: #ffffff;
height: 0.9rem;
position: fixed;
top: 0;
width: 100%;
}
.redpack_log .title_container > div > a {
color: #282828;
}
</style>
<template>
<div class="rule-page">
<Title class="page-title" title="活动规则与协议" titleColor="#000" @goback="goback" show_back="true" arrowColor="black"></Title>
<div class="section-title">挑战玩法:</div>
<img class="game-way-img" src="../images/Rule/img_rule.png">
<div class="section-title">参赛须知:</div>
<div class="content1-container">
<div class="content1-item">• 为督促大家运动,每位用户报名均需提供契约金</div>
<div class="content1-item">• 当期比赛结束后不达标的用户将被扣除契约金,作为达标奖金</div>
<div class="content1-item">• 当期比赛结束后达标用户将平分达标奖金的30%,作为激励</div>
<div class="content1-item">• 奖金赛中每个账号只能接受一台设备上报的步数</div>
<div class="content1-item">• 由于微信对网页暂不支持时时步数同步,所以最终结算步数为用户在小程序页面中“提交今日步数”为准。</div>
</div>
<div class="section2-title">参赛须知详情:</div>
<div class="content2-title">一、比赛规则</div>
<div class="content2-item">每期比赛于比赛日00:00:00正式开始统计,到比赛日23: 59:59正式结束;用户缴纳当期比赛契约金后即可成功报名;比赛结束后达标用户将收到运动奖励金(奖励金等于达标用户本人运动契约金,加上均分未达标用户契约金的30%);</div>
<div class="content2-item">运动达标奖励金将于比赛结束后24小时内发放到达标用户账户中;</div>
<div class="content2-title">二、用户确认报名即认可平台判定结果,不再对该结果进行任何 形式抗辩</div>
<div class="content2-item">每场比赛的判定结果,由平台根据比赛结束时(当期比赛最后一曰的23:59:59)的服务器后台获取的用户步数来判定,该步数会显示在当期比赛结束后的比赛详情页;用户报名成功即表示对平台 的判定结果表示认可,不再对该结果进行任何形式抗辩;</div>
<div class="content2-title">三、用户应保证设备的可靠性,以保证运动数据准确性</div>
<div class="content2-item">报名赛事的用户应保证自己设备的可靠性,例如保证电源电量充 足,保证计步服务在设备系统的运行白名单内,网络链接正常 等;为了更好的保证运动数据的可靠性,比赛期间请保证一定频次的手机微信登录;由于用户个人设备缺乏可靠性导致的投诉,平台不予处理;</div>
<div class="content2-title">四、其他说明</div>
<div class="content2-item">奖金派发时’仅派发到小数点后两位,由此可能造成的奖金结余 将在合并至本组下期比赛奖金中一并派发;</div>
<div class="content2-item">由于不可抗力因素导致当期比赛因故无法进行的,平台有权取消 当期比赛’并将在指定时间内将运动契约金原路退还给报名成功 用户;</div>
<div class="ps">注:Apple不是本赛事赞助者</div>
</div>
</template>
<script>
import Title from "@/components/Title.vue";
export default {
name: "Rule",
components: {
Title,
},
data() {
return {
};
},
methods: {
goback() {
history.go(-1);
},
}
}
</script>
<style lang="less" scoped>
.rule-page {
width: 100%;
background: #fff;
display: flex;
flex-direction: column;
align-items: center;
padding-top: .96rem;
.page-title {
font-weight: bold;
width: 100%;
background: #fff;
position: fixed;
left: 0;
top: 0;
}
.section-title {
width: 6.72rem;
font-size: .3rem;
line-height: 1;
color: #333;
font-weight: bold;
text-align: left;
margin-top: .44rem;
}
.game-way-img {
width: 6.15rem;
height: 1.09rem;
margin-top: .3rem;
margin-bottom: .14rem;
}
.content1-container {
width: 6.7rem;
margin-top: .2rem;
.content1-item {
font-size: .26rem;
line-height: .44rem;
color: #5a5a5a;
}
}
.section2-title {
width: 6.72rem;
font-size: .26rem;
line-height: 1;
color: #333;
margin-top: .4rem;
}
.content2-title {
width: 6.72rem;
font-size: .26rem;
line-height: .44rem;
color: #333;
margin-top: .2rem;
}
.content2-item {
width: 6.72rem;
font-size: .26rem;
line-height: .44rem;
color: #5a5a5a;
margin-top: .14rem;
}
.ps {
width: 6.72rem;
font-size: .26rem;
line-height: 1;
color: #A5A5A5;
margin: .4rem 0 .26rem;
}
}
</style>
\ No newline at end of file
<template>
<div class="sign-up-page">
<!-- <PayFailModal v-if="isShowPayFail" @close="togglePayFail"></PayFailModal>
<div class="modal" v-if="modalShown">
<Modal v-on:close="closeModal" v-on:confirmModal="confirmModal" v-bind:title="modalTitle" v-bind:desc="modalDesc"
:option="modalOption"></Modal>
</div>
<div class="modal" v-if="showFreeModal">
<Free
v-bind:page_type="1"
v-on:close="closeFree"
v-bind:v_data="contract_data"
@showModal="showModal"
@success="showSuccess"
:days="0"
></Free>
</div> -->
<!-- 顶部步数级别选择 -->
<div class="top-nav-level">
<div :class="['level-item', choosedLevel===0?'active':'']" @click="chooseGameLevel(0)">3000步赛</div>
<div :class="['level-item', choosedLevel===1?'active':'']" @click="chooseGameLevel(1)">5000步赛</div>
<div :class="['level-item', choosedLevel===2?'active':'']" @click="chooseGameLevel(2)">8000步赛</div>
</div>
<!-- 左上角查看步数按钮 -->
<img class="view-steps-btn" src="../images/SignUp/sy_bushu.png">
<!-- 信息广播 -->
<NoticeBonus class="notice-broadcast"></NoticeBonus>
<!-- 挑战赛卡片 -->
<div class="challenge-card" v-for="item in gameList">
<img class="corner-marker" src="../images/SignUp/home_tag_bsz.png" v-if="item.status===0">
<img class="corner-marker" src="../images/SignUp/home_tag_zmz.png" v-if="item.status===1">
<img class="corner-marker" src="../images/SignUp/home_tag_yjs.png" v-if="item.status===2">
<div class="card-title">3天健步挑战赛</div>
<div class="card-time"><{{item.already_join===1?'已参赛':'未参赛'}} {{item.period_start}}——{{item.period_end}}></div>
<div class="card-info">
<div class="info-item" v-if="item.status===0||item.status===2">
<div class="item-title">达标人数</div>
<div class="item-content">{{item.people_cnt || 0}}</div>
</div>
<div class="info-item">
<div class="item-title">参与人数</div>
<div class="item-content">{{item.total_signup || 0}}</div>
</div>
<div class="info-item">
<div class="item-title">总奖励金</div>
<div class="item-money">{{item.total_money || '0.00'}}</div>
</div>
</div>
<div class="card-btn" v-if="item.status===1" @click="goOtherPage('PartakeChallenge')">
<div>参与挑战</div>
<div class="card-btn-tip">(每日目标{{item.target_step}}步)</div>
</div>
<div class="card-btn" style="background:#32A1F6;" v-else @click="goOtherPage('HaveJoinedGame')">查看详情</div>
</div>
</div>
</template>
<script>
import NoticeBonus from "@/components/NoticeBonus.vue";
import Free from "@/components/Free.vue";
import Modal from "@/components/Modal.vue";
import PayFailModal from "@/components/PayFailModal.vue";
import {
dakaPay,
track,
userCards,
daka_index
} from "@/components/axios/api";
export default {
name: "SignUp",
components: {
NoticeBonus,
Modal,
Free,
PayFailModal
},
data() {
return {
contract_data: {},
showFreeModal: false,
modalTitle: "",
modalDesc: "",
modalShown: false,
current_date: {},
isShowPayFail: false,
isFollow: false,
gameList: [],
choosedLevel: 0
}
},
created() {
this.getPageData();
},
methods: {
chooseGameLevel(level) {
this.choosedLevel = level;
},
goOtherPage(pageName) {
this.$router.push({name: pageName});
},
getPageData(grade = 1) {
daka_index(grade).then(res => {
if (res.code === 0) {
this.gameList = res.data;
console.log(this.gameList)
}
})
},
togglePayFail() {
this.isShowPayFail = !this.isShowPayFail
},
showSuccess() {
this.showModal("温馨提示", "报名成功", {
scb: () => {
if (this.isFollow == 1) {
this.$router.push({name: "Read"})
} else {
this.$router.push({name: "Success"})
}
}
});
},
confirmModal(scb) {
scb && scb()
this.modalShown = false;
},
showFree(e) {
e.stopPropagation();
track("free_contract_show");
if (localStorage.getItem("first_show_free") == 1) {
localStorage.setItem("first_show_free", 2);
this.canShowFree = false;
} else {
this.canCheckShowFree = false;
this.canShowFree = false;
}
userCards().then(res => {
console.log("获取免契约金数据", res);
let data = {
card: res.data.contract_card,
cnt: res.data.contract_cnt
};
this.current_date = new Date(res.date);
// if (
// // 如果明天没报名,而且还有免契约金卡,则可以使用
// !this.date_status[1].user_status.daka_signup &&
// res.data.contract_card > 0
// ) {
// data.can_get = true;
// // 其他情况,显示报名下期比赛
// } else {
// data.can_get = false;
// }
this.contract_data = JSON.parse(JSON.stringify(data));
this.showFreeModal = true;
});
},
closeFree() {
this.showFreeModal = false;
},
showModal(title, desc, option) {
this.modalTitle = title || "";
this.modalDesc = desc || "";
this.modalOption = option || {}
this.modalShown = true;
},
closeModal() {
this.modalShown = false;
},
payToSign() {
dakaPay().then(response => {
this.current_date = new Date(response.date);
if (response.code == 1) {
this.showModal("温馨提示", response.msg);
return;
}
let result = response.data;
console.log("请求打卡支付数据", result);
if (result) {
WeixinJSBridge.invoke(
"getBrandWCPayRequest",
{
appId: result.appId, //公众号名称,由商户传入
timeStamp: `${result.timeStamp}`, //时间戳,自1970年以来的秒数
nonceStr: result.nonceStr, //随机串
package: result.package,
signType: result.signType, //微信签名方式:
paySign: result.paySign //微信签名
},
// result,
res => {
console.log("支付调用结果", res);
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
// 支付成功后的回调函数
console.log("支付成功");
this.showModal("温馨提示", "报名成功", {
scb: () => {
if (this.isFollow == 1) {
this.$router.push({name: "Read"})
} else {
this.$router.push({name: "Success"})
}
}
});
// this.dateSelect(2);
// localStorage.setItem("is_every", 0)
// location.replace("#/Success");
}
if (res.err_msg == "get_brand_wcpay_request:fail") {
// this.showModal("温馨提示", "支付服务繁忙,请稍后重试");
this.togglePayFail()
}
if (res.err_msg == "get_brand_wcpay_request:cancel") {
// console.log("支付取消");
this.togglePayFail()
}
}
);
}
});
},
}
}
</script>
<style lang="less" scoped>
.sign-up-page {
width: 100%;
height: 100%;
overflow-y: scroll;
background-color: rgb(70, 88, 149);
background-image: url(../images/SignUp/sy_beijing.png);
background-repeat: no-repeat;
background-size: contain;
background-attachment: scroll;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
.top-nav-level {
flex-shrink: 0;
margin-top: .3rem;
border: .02rem solid #fff;
border-radius: .1rem;
overflow: hidden;
background: #fff;
box-sizing: border-box;
display: flex;
.level-item {
width: 1.76rem;
font-size: .3rem;
line-height: .54rem;
color: #465895;
text-align: center;
position: relative;
&:after {
content: '';
height: .26rem;
width: .02rem;
background: #465895;
position: absolute;
left: -.02rem;
top: 50%;
transform: translateY(-50%);
}
&:first-child:after {
display: none;
}
&.active {
background: #465895;
color: #fff;
border-radius: .1rem;
font-weight: bold;
}
&.active:after {
display: none;
}
}
}
.view-steps-btn {
flex-shrink: 0;
width: 1.11rem;
height: .84rem;
display: block;
position: absolute;
left: 0;
top: 1.22rem;
}
.notice-broadcast {
flex-shrink: 0;
margin: 3.68rem 0 .18rem;
}
.challenge-card {
flex-shrink: 0;
width: 6.9rem;
height: 4.4rem;
background-image: url(../images/SignUp/sy_dikuang.png);
background-size: 100% 100%;
margin-bottom: .4rem;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
.corner-marker {
width: 1.39rem;
height: 1.39rem;
position: absolute;
top: -.02rem;
right: -.02rem;
}
.card-title {
font-size: .36rem;
line-height: 1;
color: #fff;
margin-top: .28rem;
}
.card-time {
font-size: .22rem;
line-height: 1;
color: #fff;
margin-top: .16rem;
}
.card-info {
width: 100%;
margin-top: .56rem;
display: flex;
align-items: center;
justify-content: space-between;
.info-item {
flex: 1;
border-left: .02rem solid #fff;
display: flex;
flex-direction: column;
align-items: center;
&:first-child {
border-left: none;
}
.item-title {
font-size: .28rem;
line-height: .8;
color: #fff;
}
.item-content {
font-size: .48rem;
line-height: .8;
color: #fff;
margin-top: .12rem;
}
.item-money {
font-size: .48rem;
line-height: .8;
color: #fcf776;
margin-top: .12rem;
}
}
}
.card-btn {
width: 4rem;
height: .8rem;
background: #fabd21;
border-radius: .74rem;
box-shadow: 0 .02rem .04rem 0 rgba(0, 0, 0, .2);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: .3rem;
line-height: 1;
color: #fff;
position: absolute;
bottom: .38rem;
left: 50%;
transform: translateX(-50%);
.card-btn-tip {
font-size: .22rem;
margin-top: .06rem;
}
}
}
}
</style>
<template>
<div class="success">
<Title
v-bind:title="title"
v-on:goback="goback"
show_back="true"
></Title>
<div class="share_img">
<img :src="liin_share_image" alt="">
</div>
</div>
</template>
<script>
import Title from "@/components/Title.vue";
import {
liinShare
} from "@/components/axios/api";
export default {
name: "Success",
components: {
Title,
},
data() {
return {
shareImgUrl: "",
title: "每天读书打卡",
if_follow: false,
liin_share_image: "",
is_every: false,
dailyShare: "",
isImgLoaded: false,
isLoading: false,
isShowRedpack: false
};
},
methods: {
goback() {
this.$router.push({name: "Read"})
},
queryPayImage() {
liinShare().then(res => {
if (res.code == 0) {
localStorage.setItem("is_follow", res.data.is_follow);
localStorage.setItem("liin_share_image", res.data.image);
localStorage.setItem("hb_url", res.data.hb_url);
localStorage.setItem("open_platform", res.data.open_platform);
this.liin_share_image = localStorage.getItem("liin_share_image") || "";
}
});
},
},
created() {
this.queryPayImage()
}
}
</script>
<style scoped>
.share_img img {
width: 100%;
}
</style>
<style>
.success .back {
background-image: url("../assets/ic_back_black.png");
}
.success .title_container {
color: #282828;
background: #ffffff;
height: 0.9rem;
position: fixed;
top: 0;
width: 100%;
}
</style>
<template>
<div class="user-center-page">
<div class="banner"></div>
<div class="user-container">
<img class="user-avatar" :src="userData.avatar">
<div class="user_msg">
<div class="user_nickname">{{userData.nickname|textFormatter}}</div>
<div class="user_number">昵称:{{userData.student_num|textFormatter}}</div>
</div>
<div class="btn_container">
<div class="btn_item" v-for="item in btnList" @click="jumpTo(item)">
<div class="btn_icon">
<img :src="item.icon" alt="">
</div>
<div class="btn_text">{{item.text}}</div>
<div class="btn_right" v-if="item.money||item.money===0">{{item.money|moneyFormatter}}</div>
<div class="btn_right" v-else>
<img src="../assets/ic_next.png" alt="">
</div>
</div>
</div>
</div>
<FollowDialog :isKefu="isKefu" v-if="isShowFollow" @close="toggleFollowDialog"></FollowDialog>
</div>
</template>
<script>
import {balanceQuery} from "@/components/axios/api";
import FollowDialog from "@/components/FollowDialog.vue";
import Title from "@/components/Title.vue";
export default {
name: "UserCenter",
components: {
FollowDialog,
Title
},
created() {
let userData = localStorage.getItem("read_userData")
if (userData) {
this.userData = JSON.parse(userData)
}
this.getBalanceQuery()
},
methods: {
toggleFollowDialog(isKefu) {
isKefu && (this.isKefu = isKefu)
this.isShowFollow = !this.isShowFollow
},
jumpTo(item) {
console.log("item", item)
if (item.to) {
window.location.href = item.to
}
if (item.router) {
this.$router.push({name: item.router})
}
if (item.isKefu) {
this.toggleFollowDialog(item.isKefu)
}
},
getBalanceQuery() {
balanceQuery().then(result => {
if (result.code == 0) {
this.btnList[0].money = result.data.balance;
console.log(this.btnList)
if (result.data.withdraw_auth) {
this.appid = result.data.withdraw_appid;
// this.getOpenId();
}
}
});
},
},
data() {
return {
isKefu: false,
isShowFollow: false,
userData: {},
btnList: [
{
icon: require("../assets/ic_my_wallet.png"),
text: "钱包",
money: "0",
router: "Wallet"
},
{
icon: require("../assets/ic_my_record.png"),
text: "我的打卡记录",
router: "Record"
},
{
icon: require("../assets/ic_my_que.png"),
text: "常见问题",
router: "Question"
},
{
icon: require("../assets/ic_my_connect.png"),
text: "联系我们",
isKefu: 1
},
{
icon: require("../assets/ic_my_code.png"),
text: "关注公众号",
isKefu: 2
},
]
}
},
filters: {
moneyFormatter(val) {
if (val && !isNaN(val)) {
return Number(val).toFixed(2);
} else {
return "0.00";
}
},
textFormatter(val) {
if (val) {
return val
} else {
return ""
}
}
}
}
</script>
<style lang="less" scoped>
.user-center-page {
width: 100%;
position: relative;
overflow-y: scroll;
background: #f8f8f8;
.banner {
width: 100%;
height: 2.6rem;
background: linear-gradient(0, #07C9D1, #2AD6A6);
position: absolute;
left: 0;
top: 0;
}
.user-container {
width: 6.9rem;
margin: 1.76rem auto 0;
background: rgba(255, 255, 255, 1);
box-shadow: 0 .02rem .14rem 0 rgba(180, 197, 200, 0.5);
position: relative;
.user-avatar {
overflow: hidden;
width: 1.48rem;
height: 1.48rem;
border-radius: 50%;
border: .07rem solid #fff;
background: black;
display: block;
position: absolute;
left: 50%;
top: 0;
transform: translate(-50%, -50%);
}
}
}
.user_msg {
padding-top: .9rem;
padding-bottom: .4rem;
text-align: center;
}
.user_nickname {
font-size: .32rem;
color: rgba(51, 51, 51, 1);
margin-bottom: .1rem;
}
.user_number {
font-size: .28rem;
color: rgba(165, 165, 165, 1);
}
.btn_container {
padding: 0 .4rem;
}
.btn_item {
display: flex;
align-items: center;
padding: .3rem 0;
border-top: .01rem solid rgba(232, 232, 232, 1);
}
.btn_icon {
flex-shrink: 0;
}
.btn_icon img {
display: block;
width: .44rem;
}
.btn_text {
font-size: .3rem;
color: rgba(40, 40, 40, 1);
flex: 1;
margin-left: .3rem;
}
.btn_right {
font-size: .3rem;
color: rgba(138, 138, 138, 1);
}
.btn_right img {
width: .2rem;
}
</style>
<template>
<div class="Wallet">
<Title class="page-title" title="余额提现" titleColor="#000" @goback="goback" show_back="true" arrowColor="black"></Title>
<div class="wallet_container">
<div class="wallet_content">
<div class="wallet_money">
账户余额<span class="money_num">{{this.money_num|moneyFormatter}}</span><span
style="color:#8a8a8a;"></span>
</div>
<div
class="wallet_money"
style="margin-top:0.6rem">
提现金额
</div>
<div class="money_input">
<span class="dollar"></span>
<input
type="text"
v-bind:placeholder="`可提现到微信钱包${MoneyNum}元`"
v-model="cash_money_num"
@input="checkMoney"
@blur="refreshPage"
>
<span
class="get_all"
@click="cashAll"
>全部</span>
</div>
<div class="seprate_line"></div>
<div class="desc">
单次提现金额至少0.3元,最多100元
</div>
<div class="cash_button" @click="cashMoney"></div>
</div>
<div class="wallet_text_btn">
<div class="kefu_btn" @click="concatCustom">联系客服</div>
<div class="line"></div>
<div class="cash_list_btn" @click="toRedpackLog">提现明细</div>
</div>
<div class="ad_banner" @click="toggleRedpack" v-if="!open_platform">
<div class="ad_avatar">
<img :src="userData.avatar" alt="">
</div>
<div class="ad_msg">
<div class="ad_title">恭喜你获得一个红包</div>
<div class="ad_desc">点击立即领取!</div>
</div>
<div class="ad_btn">
领取
</div>
</div>
</div>
<!--<div class="concat_custom">-->
<!--<span-->
<!--class="concat"-->
<!--@click="concatCustom"-->
<!--&gt;联系客服</span>-->
<!--</div>-->
<div class="promote">
</div>
<div class="modal" v-if="modalShown">
<Modal v-on:close="closeModal" v-on:confirmModal="closeModal" v-bind:title="modalTitle" v-bind:desc="modalDesc"
:option="modalOption"></Modal>
</div>
<Loading v-if="isLoading"></Loading>
<FollowDialog :isKefu="isKefu" v-if="isShowFollow" @close="toggleFollowDialog"></FollowDialog>
<RedpackDialog v-if="isShowRedpack" @close="toggleRedpack" :withdrawData="withdrawData"
:type="redpackType"></RedpackDialog>
</div>
</template>
<style scoped>
.ad_banner {
width: 6.9rem;
height: 1.4rem;
display: flex;
align-items: center;
background: #fff;
padding: .2rem;
position: absolute;
bottom: .5rem;
left: 50%;
margin-left: -3.65rem;
}
.ad_avatar {
width: 1rem;
height: 1rem;
margin-right: .2rem;
}
.ad_avatar img {
width: 100%;
height: 100%;
}
.ad_msg {
flex: 1;
}
.ad_title {
font-size: .32rem;
color: rgba(51, 51, 51, 1);
margin-bottom: .16rem;
text-align: left;
}
.ad_desc {
font-size: .28rem;
color: rgba(165, 165, 165, 1);
text-align: left;
}
.ad_btn {
width: 1.3rem;
height: .72rem;
border: .02rem solid rgba(237, 195, 101, 1);
border-radius: .12rem;
display: flex;
justify-content: center;
align-items: center;
color: rgba(237, 195, 101, 1);
font-size: .32rem;
}
.wallet_text_btn {
display: flex;
justify-content: center;
align-items: center;
margin-top: .5rem;
}
.kefu_btn, .cash_list_btn {
color: rgba(87, 107, 149, 1);
font-size: 0.3rem;
margin: 0 .25rem;
}
.line {
width: .02rem;
height: .22rem;
background: rgba(204, 204, 204, 1);
}
</style>
<style>
.Wallet {
width: 100%;
height: 100%;
background: #f1f1f1;
}
.Wallet .title_container {
color: #282828;
background: #ffffff;
height: 0.9rem;
position: fixed;
top: 0;
width: 100%;
}
.Wallet .title_container > div > a {
color: #282828;
}
.big .Wallet {
padding-top: 0.9rem;
}
.big .Wallet .title_container {
height: 0.9rem;
}
.wallet_container{
width: 100%;
padding-top: 1.5rem;
}
.wallet_content {
width: 6.9rem;
/*height: 6.04rem;*/
margin: 0 auto 0;
padding: .8rem 0;
/*margin-left: calc((100% - 6.9rem) / 2);*/
background: #ffffff;
/*padding: 0.5rem 0.4rem 0.6rem 0.4rem;*/
}
.wallet_content div {
margin-left: .4rem;
}
.wallet_money {
font-size: 0.28rem;
color: #282828;
text-align: left;
}
.wallet_content span.money_num {
font-size: 0.48rem;
color: #8a8a8a;
display: inline-block;
margin-left: 1rem;
}
.Wallet .money_input {
height: 0.5rem;
width: 6.1rem;
margin-top: 0.6rem;
text-align: left;
display: flex;
align-items: center;
justify-content: space-between;
}
.Wallet .money_input span.dollar {
font-size: 0.48rem;
color: #282828;
margin-bottom: .2rem;
}
.Wallet .money_input input {
border: 0;
outline: 0;
font-size: 0.28rem;
color: #282828;
display: inline-block;
/*margin-left: 0.4rem;*/
width: 4rem;
}
.Wallet .money_input .get_all {
float: right;
color: #52526e;
font-size: 0.3rem;
}
.Wallet .concat_custom {
/*width: 100%;*/
padding-top: .5rem;
padding-right: 0.3rem;
/*padding: 0.2rem;*/
text-align: right;
/*padding-bottom: 0;*/
}
.Wallet .concat_custom .concat {
width: 100%;
text-align: right;
color: #52526e;
font-size: 0.3rem;
}
::-webkit-input-placeholder {
color: #cccccc;
font-size: 0.28rem;
}
.seprate_line {
width: 6.1rem;
border-bottom: 1px solid #e8e8e8;
margin: 0.2rem 0;
}
.Wallet .desc {
color: #8a8a8a;
font-size: 0.24rem;
text-align: left;
}
.Wallet .cash_button {
width: 6.1rem;
height: 0.8rem;
background: url("../assets/btn_tx.png") 0 0 no-repeat;
background-size: contain;
margin-top: 0.4rem;
}
</style>
<script>
// 钱包
import Title from "@/components/Title.vue";
import Modal from "@/components/Modal.vue";
import Loading from "@/components/Loading.vue";
import FollowDialog from "@/components/FollowDialog.vue";
import RedpackDialog from "@/components/RedpackDialog.vue";
import {balanceQuery, balanceWithdraw, withdraw_img} from "@/components/axios/api";
export default {
name: "Wallet",
components: {
Title,
Modal,
Loading,
FollowDialog,
RedpackDialog
},
data() {
return {
isShowRedpack: false,
isShowFollow: false,
isKefu: 1,
money_num: 0,
cash_money_num: null,
modalShown: false,
appid: "",
code: "",
uid: "",
loginFail: false,
isLoading: false,
userData: {},
withdrawData: {},
open_platform: true,
redpackType: 1
};
},
methods: {
toRedpackLog() {
this.$router.push({name: "RedpackLog"});
},
toggleRedpack() {
this.isShowRedpack = !this.isShowRedpack
if (!this.isShowRedpack) {
if (this.redpackType == 1) {
this.redpackType = 2
this.getRedpackImg("task")
}
}
},
getRedpackImg(position) {
withdraw_img(position).then(res => {
if (res.code == 0) {
this.withdrawData = res.data
this.open_platform = res.data.open_platform
if (this.redpackType == 1 && !this.open_platform) {
this.toggleRedpack()
}
}
})
},
toggleFollowDialog() {
this.isShowFollow = !this.isShowFollow
},
refreshPage() {
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
window.scrollTo(0, Math.max(scrollHeight - 1, 0));
}, 100);
},
goback() {
this.$router.push({name: "UserCenter"})
},
cashAll() {
// console.log('触发赋值',this.money_num);
if (this.money_num > 100) {
this.cash_money_num = 100;
} else {
this.cash_money_num = this.money_num;
}
},
cashMoney() {
console.log("提现操作");
if (this.cash_money_num != 0 && !this.cash_money_num) {
this.showModal("温馨提示", "请输入提现金额");
return;
}
if (this.cash_money_num < 0.3) {
this.showModal("温馨提示", "金额不足0.3元,无法提现");
return;
}
this.isLoading = true;
balanceWithdraw(this.cash_money_num)
.then(result => {
console.log(result);
this.isLoading = false;
if (result.code == 0) {
this.cash_money_num = null;
this.getBalanceQuery();
this.showModal(
"温馨提示",
"提现申请成功,预计1-5个工作日内提到微信钱包"
);
} else {
this.showModal("温馨提示", "提现失败,请稍后重试或联系客服");
}
})
.catch(e => {
this.showModal("温馨提示", "提现失败,请稍后重试或联系客服");
this.isLoading = false;
});
},
getBalanceQuery() {
balanceQuery().then(result => {
console.log(result);
if (result.code == 0) {
this.money_num = result.data.balance;
if (result.data.withdraw_auth) {
this.appid = result.data.withdraw_appid;
// this.getOpenId();
}
}
});
},
checkMoney(e) {
console.log(e)
let judge = this.money_num > 100 ? 100 : this.money_num;
if (e.inputType != "deleteContentBackward") {
this.cash_money_num = (this.cash_money_num + '').replace(/[^\d.]/g, "");
this.cash_money_num = (this.cash_money_num + '').replace(/^\./g, "");
this.cash_money_num = (this.cash_money_num + '').replace(/\.{2,}/g, ".");
this.cash_money_num = (this.cash_money_num + '').replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
}
if (this.cash_money_num > judge) {
this.cash_money_num = judge;
}
console.log("checkMoney", this.cash_money_num);
},
showModal(title, desc, option) {
this.modalTitle = title || "";
this.modalDesc = desc || "";
this.modalOption = option || {}
this.modalShown = true;
},
closeModal() {
this.modalShown = false;
if (this.loginFail) {
this.loginFail = false;
let oldHref = window.location.href;
let newHref = oldHref.replace(window.location.search, "");
newHref = newHref.replace(window.location.hash, "#/MyData");
location.replace(newHref);
}
},
getOpenId() {
document.title = "微信授权中";
var code = this.GetUrlParame("code"); // 截取code
console.log(code);
let local_hash = location.hash;
window.localStorage.setItem("local_hash", local_hash);
let redirect_uri = encodeURIComponent(
`${location.origin}${location.pathname}${local_hash}`
);
let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${
this.appid
}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`;
console.log("url", url);
if (!code) {
location.replace(url);
} else {
console.log("拿到code", code);
console.log("请求登录");
balanceWithdraw("", code).then(result => {
console.log(result);
if (result.code != 0) {
this.showModal("温馨提示", "服务器繁忙,请稍后重试");
this.loginFail = true;
}
});
}
},
// 截取code
GetUrlParame(parameName) {
/// 获取地址栏指定参数的值
/// <param name="parameName">参数名</param>
// 获取url中跟在问号后面的部分
var parames = window.location.search;
// 检测参数是否存在
if (parames.indexOf(parameName) > -1) {
var parameValue = "";
parameValue = parames.substring(
parames.indexOf(parameName),
parames.length
);
// 检测后面是否还有参数
if (parameValue.indexOf("&") > -1) {
// 去除后面多余的参数, 得到最终 parameName=parameValue 形式的值
parameValue = parameValue.substring(0, parameValue.indexOf("&"));
// 去掉参数名, 得到最终纯值字符串
parameValue = parameValue.replace(parameName + "=", "");
return parameValue;
}
return "";
}
},
concatCustom() {
this.toggleFollowDialog()
// window.location.href = "https://mp.weixin.qq.com/s/YFO5CA_iKSBdnXbxJZAC-Q"
}
},
props: ["money"],
computed: {
MoneyNum() {
let moneyNum = 0;
if (this.money_num > 100) {
moneyNum = 100;
} else {
if (this.money_num < 0.3) {
moneyNum = 0;
} else {
moneyNum = this.money_num;
}
}
return moneyNum;
}
},
created() {
this.getRedpackImg()
this.getBalanceQuery();
if (window["userData"]) {
this.userData = window["userData"];
} else {
let localUserData = localStorage.getItem("userData");
if (localUserData) {
window["userData"] = JSON.parse(localUserData);
this.userData = window["userData"];
}
}
},
filters: {
moneyFormatter(val) {
if (val && !isNaN(val)) {
return Number(val).toFixed(2);
} else {
return "0.00";
}
}
}
};
</script>
//vue.config.js
module.exports = {
// 选项...
// publicPath: 'https://miniapp-api.wxatech.com/app_pages',
// indexPath: "read_daka.html",
// assetsDir: "read_static",
devServer: {
proxy: {
'/api': {
target: "https://miniapp-api.wxatech.com/game-bsdk/",
changeOrigin: true,
pathRewrite: {
"^/api": "/api"
}
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment