Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac2b1b3d10 | ||
|
|
cba8253f32 | ||
|
|
7a7cf54dc7 | ||
|
|
000b73c476 | ||
|
|
d371d016f7 | ||
|
|
64ace657ac | ||
|
|
245a04aedc | ||
|
|
33ac3cf2e6 | ||
|
|
73de49527d | ||
|
|
b5fc0068b1 | ||
|
|
85af097207 | ||
|
|
24c3709c95 | ||
|
|
0b3882256e | ||
|
|
e99f8d485c | ||
|
|
1aa198fd85 | ||
|
|
2aeebb3245 | ||
|
|
cc94ee7aff | ||
|
|
86b92e6f2a | ||
|
|
f41874765a | ||
|
|
8d1cb7c4de | ||
|
|
52b8033e2d | ||
|
|
7e55249b79 | ||
|
|
c36415fcda | ||
|
|
7ce062229f | ||
|
|
ae95b0def7 | ||
|
|
cab431c25e | ||
|
|
563533ba19 | ||
|
|
42e9129f8a | ||
|
|
6a6f022eac | ||
|
|
6f2d9f1014 | ||
|
|
7be4e398f3 | ||
|
|
d5592cbd48 | ||
|
|
1256956825 | ||
|
|
d3c114325b | ||
|
|
40ae9ca1c4 | ||
|
|
1ff0b665b6 | ||
|
|
06f7bd5f68 | ||
|
|
03ceb0bcf3 | ||
|
|
5981432ff7 | ||
|
|
e513fff4c0 | ||
|
|
78da791d4c | ||
|
|
810f311a13 | ||
|
|
1f7824b0d7 | ||
|
|
2bf4f1fa56 | ||
|
|
52f8e217f3 | ||
|
|
380b47e371 | ||
|
|
5d319b3f37 | ||
|
|
b076f61c58 | ||
|
|
7b35a39618 | ||
|
|
f9253f9e56 | ||
|
|
681535e94b | ||
|
|
fc50e78bec | ||
|
|
d07f823326 | ||
|
|
787d115e5a | ||
|
|
4f219f2551 | ||
|
|
a91b09a5fc | ||
|
|
a2f0aa31fd | ||
|
|
1e01a404ba | ||
|
|
b34a1ec397 | ||
|
|
f26acabda2 | ||
|
|
ca316b10ae | ||
|
|
6ea3a8aa69 | ||
|
|
7e7248ef97 | ||
|
|
4e40a69f61 | ||
|
|
99a6ff2d77 | ||
|
|
e8573f42bb | ||
|
|
0bd831fe35 | ||
|
|
54c6e483a4 | ||
|
|
3c7db828db | ||
|
|
b71fed3782 | ||
|
|
31970ceda9 | ||
|
|
ad4eb04f49 | ||
|
|
15b7e3d94c | ||
|
|
e9019e9d39 | ||
|
|
81c8285016 | ||
|
|
50fcef07ee | ||
|
|
34d222dc36 | ||
|
|
25538f7a82 | ||
|
|
27321bda16 | ||
|
|
b15fb02ecf | ||
|
|
5b8b91356f | ||
|
|
17ae7587cb | ||
|
|
c8db068547 | ||
|
|
9acaf3c27c | ||
|
|
32e108ca2f | ||
|
|
e45372d4b6 | ||
|
|
6bdbebe2a0 | ||
|
|
92cb6252ae | ||
|
|
f579101f7c | ||
|
|
31f8897d6e | ||
|
|
182cb8efdb | ||
|
|
85f91fa570 | ||
|
|
02ce643f57 | ||
|
|
84e9e44b22 | ||
|
|
a7f96df500 | ||
|
|
09496a038b | ||
|
|
3ec70daafc | ||
|
|
475a681300 | ||
|
|
592827bc3d | ||
|
|
ea89482012 | ||
|
|
5e4a9f8cc2 | ||
|
|
e42f376bc2 | ||
|
|
330e508900 | ||
|
|
e452f7cb19 | ||
|
|
a4846939dd | ||
|
|
40883fda3b | ||
|
|
7d512ef9a6 | ||
|
|
e629285b51 | ||
|
|
0bc8344505 | ||
|
|
c83c98b598 | ||
|
|
5a25680bf7 | ||
|
|
83d81031e3 | ||
|
|
c7323c1900 | ||
|
|
cf73be8270 | ||
|
|
d68b24445a | ||
|
|
1279ba6b5d | ||
|
|
04ccd6d704 | ||
|
|
644b458969 | ||
|
|
2afae4f007 | ||
|
|
6316405712 | ||
|
|
bff8bd8dd0 | ||
|
|
a7e784555d | ||
|
|
965d6683bf | ||
|
|
be43aaafd8 | ||
|
|
00ed94c762 | ||
|
|
2aef6a4fe5 | ||
|
|
62644ddb56 | ||
|
|
6a1b442c3c | ||
|
|
d175b3dd26 | ||
|
|
224e4f4772 | ||
|
|
8d6d8a25fd | ||
|
|
1a8c321ca7 | ||
|
|
fe955e9fb1 | ||
|
|
3ae38b6626 | ||
|
|
3d4400f198 | ||
|
|
ec0e0ee234 | ||
|
|
39873a9e3c | ||
|
|
afad547b14 | ||
|
|
b1da35a040 | ||
|
|
dcae130b4a | ||
|
|
828505c2dd | ||
|
|
8e2d28d27a | ||
|
|
72385f8ed8 | ||
|
|
c23e1922a3 | ||
|
|
e08f65b4cb | ||
|
|
6442fc5c11 | ||
|
|
21461991ac | ||
|
|
e58e910951 | ||
|
|
4c0704b5cd | ||
|
|
87bd79b8ee | ||
|
|
576d0874ad | ||
|
|
a08e05ea8b | ||
|
|
202ee764ba | ||
|
|
0d723b1f28 | ||
|
|
10ee3965df | ||
|
|
13769114d2 | ||
|
|
335146ed94 | ||
|
|
0a575e92d0 | ||
|
|
7f0870a34a | ||
|
|
3746fe27bb | ||
|
|
edabd0c29f | ||
|
|
5d9be29f04 | ||
|
|
8718927bb1 | ||
|
|
e67fdf510c | ||
|
|
4dd71968a5 | ||
|
|
e763dce12b | ||
|
|
4aed2a78e0 | ||
|
|
9199f20de0 | ||
|
|
220b21b6b6 | ||
|
|
725a37eae5 | ||
|
|
f256bb904d | ||
|
|
b88b260ac2 | ||
|
|
7f976681e4 | ||
|
|
cf23ffbbfe | ||
|
|
a89d014836 | ||
|
|
987e90f80a | ||
|
|
70fe080f57 | ||
|
|
b8e61cf7a0 | ||
|
|
96db421a2a | ||
|
|
31ead800b1 | ||
|
|
31c96a5c76 | ||
|
|
868901739c | ||
|
|
04350dc5c2 | ||
|
|
cb01b3d6c1 | ||
|
|
6fcb8196c3 | ||
|
|
4e756482ce | ||
|
|
0ceb18b823 | ||
|
|
ddf9aa6d8a | ||
|
|
02aa4756fd | ||
|
|
80c5617d52 | ||
|
|
7bc30ba3eb | ||
|
|
07b9521a63 | ||
|
|
eab00bf2a6 | ||
|
|
9e74d2a704 | ||
|
|
992321be2a | ||
|
|
b6fd22c8fb | ||
|
|
d89f64f80f | ||
|
|
33311ae19c | ||
|
|
8fbdec3738 | ||
|
|
e68d39c99c | ||
|
|
6320bb3453 | ||
|
|
83a6955778 | ||
|
|
8b2291d8b4 | ||
|
|
16b6a37074 | ||
|
|
ed2ea5876c | ||
|
|
dcbe6241f0 | ||
|
|
c9f3f7f6ff | ||
|
|
9fca18b350 | ||
|
|
c8fdda0bb0 | ||
|
|
4e465b7e72 | ||
|
|
4a9c829d6f | ||
|
|
8ccaa633ff | ||
|
|
ce1472d09c | ||
|
|
e93170f25a | ||
|
|
f1c8338981 | ||
|
|
6397287238 | ||
|
|
fc25cdfa02 | ||
|
|
f4e2327095 | ||
|
|
955ea2fdee | ||
|
|
c42aab28a1 | ||
|
|
39c4716fc1 | ||
|
|
ddf354921b | ||
|
|
96cbe9d7e3 | ||
|
|
df945fc609 | ||
|
|
829babf74a | ||
|
|
95031bc483 | ||
|
|
5e6d4b5a77 | ||
|
|
bd5e8f1aea | ||
|
|
d4f2aae8f9 | ||
|
|
f3c1bcb6c5 | ||
|
|
621819b067 | ||
|
|
a6f622572a | ||
|
|
3c0b73f100 | ||
|
|
9b39c27876 | ||
|
|
6fe074baaa | ||
|
|
1d816d6b06 | ||
|
|
8c67e73d43 | ||
|
|
6685425ae0 | ||
|
|
6a7437f068 | ||
|
|
deabefd64f | ||
|
|
d1682fba15 |
No files matched your search
@@ -1,40 +0,0 @@
|
||||
# 支付目标
|
||||
# H5 - 强制使用 H5/WAP 支付渠道
|
||||
# APP - 非微信小程序端跳转到微信小程序支付
|
||||
# SHOPRO_BUILD_TARGET 为兼容旧配置的默认值,下面两项可分别覆盖支付宝和微信支付
|
||||
SHOPRO_BUILD_TARGET=APP
|
||||
SHOPRO_ALIPAY_BUILD_TARGET=APP
|
||||
SHOPRO_WECHAT_BUILD_TARGET=APP
|
||||
|
||||
# 版本号
|
||||
SHOPRO_VERSION=v2.4.1
|
||||
|
||||
# 后端接口前缀(一般不建议调整)
|
||||
SHOPRO_API_PATH=/app-api
|
||||
|
||||
# 后端接口 - 测试环境(通过 process.env.NODE_ENV == development)
|
||||
# SHOPRO_DEV_BASE_URL = https://api.htysapp.com
|
||||
SHOPRO_DEV_BASE_URL=https://324e01b5211c41c7a8fc9f7854195f30.hn.takin.cc
|
||||
# SHOPRO_DEV_BASE_URL=http://localhost:48083
|
||||
|
||||
# 后端接口 - 正式环境(通过 process.env.NODE_ENV != development)
|
||||
SHOPRO_BASE_URL=https://api.htysapp.com
|
||||
|
||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
|
||||
SHOPRO_UPLOAD_TYPE=server
|
||||
|
||||
# 后端 websocket 接口前缀
|
||||
SHOPRO_WEBSOCKET_PATH=/infra/ws
|
||||
|
||||
# 客户端静态资源地址 空=默认使用服务端指定的CDN资源地址前缀 | local=本地 | http(s)://xxx.xxx=自定义静态资源地址前缀
|
||||
SHOPRO_STATIC_URL=http://test.yudao.iocoder.cn
|
||||
### SHOPRO_STATIC_URL = https://file.sheepjs.com
|
||||
|
||||
# 前端 H5 访问域名(App 调起 H5 支付时作为支付完成后的回跳地址)
|
||||
SHOPRO_H5_URL=http://127.0.0.1:3000
|
||||
|
||||
# 是否开启直播 1 开启直播 | 0 关闭直播
|
||||
SHOPRO_MPLIVE_ON=0
|
||||
|
||||
# 租户ID 默认 1
|
||||
SHOPRO_TENANT_ID=1
|
||||
@@ -1,23 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
.hbuilderx
|
||||
build.sh
|
||||
.idea
|
||||
unpackage
|
||||
@@ -0,0 +1,20 @@
|
||||
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
|
||||
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
|
||||
"version": "0.0",
|
||||
"configurations": [{
|
||||
"default" :
|
||||
{
|
||||
"launchtype" : "remote"
|
||||
},
|
||||
"h5" :
|
||||
{
|
||||
"launchtype" : "remote"
|
||||
},
|
||||
"mp-weixin" :
|
||||
{
|
||||
"launchtype" : "remote"
|
||||
},
|
||||
"type" : "uniCloud"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 238 KiB |
|
After Width: | Height: | Size: 139 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 201 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 168 KiB |
|
After Width: | Height: | Size: 294 KiB |
|
After Width: | Height: | Size: 177 KiB |
@@ -1,6 +0,0 @@
|
||||
/unpackage/*
|
||||
/node_modules/**
|
||||
/uni_modules/**
|
||||
/public/*
|
||||
**/*.svg
|
||||
**/*.sh
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"semi": true,
|
||||
"vueIndentScriptAndStyle": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"proseWrap": "never",
|
||||
"htmlWhitespaceSensitivity": "strict",
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
@@ -1,326 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="font-size:50px">
|
||||
|
||||
<head>
|
||||
<title>荷塘月色 - app下载</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta http-equiv="pragma" content="no-cache">
|
||||
<meta http-equiv="cache-control" content="no-cache">
|
||||
<meta http-equiv="expires" content="0">
|
||||
<meta name="description" content="高端私密真实可靠的聊天交友APP。平台通过人工审核和会员制度,保证用户质量。快来邂逅附近的女神吧!">
|
||||
<meta name="keywords" content="荷塘月色,聊天,交友">
|
||||
<script src="./device-fingerprint.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
<style type="text/css">
|
||||
a,
|
||||
abbr,
|
||||
acronym,
|
||||
address,
|
||||
applet,
|
||||
article,
|
||||
aside,
|
||||
audio,
|
||||
b,
|
||||
big,
|
||||
blockquote,
|
||||
body,
|
||||
canvas,
|
||||
caption,
|
||||
center,
|
||||
cite,
|
||||
code,
|
||||
dd,
|
||||
del,
|
||||
details,
|
||||
dfn,
|
||||
div,
|
||||
dl,
|
||||
dt,
|
||||
em,
|
||||
embed,
|
||||
fieldset,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
form,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
header,
|
||||
html,
|
||||
i,
|
||||
iframe,
|
||||
img,
|
||||
input,
|
||||
ins,
|
||||
kbd,
|
||||
label,
|
||||
legend,
|
||||
li,
|
||||
mark,
|
||||
menu,
|
||||
nav,
|
||||
object,
|
||||
ol,
|
||||
output,
|
||||
p,
|
||||
pre,
|
||||
q,
|
||||
ruby,
|
||||
s,
|
||||
samp,
|
||||
section,
|
||||
small,
|
||||
span,
|
||||
strike,
|
||||
strong,
|
||||
sub,
|
||||
summary,
|
||||
sup,
|
||||
table,
|
||||
tbody,
|
||||
td,
|
||||
tfoot,
|
||||
th,
|
||||
thead,
|
||||
time,
|
||||
tr,
|
||||
tt,
|
||||
u,
|
||||
ul,
|
||||
var,
|
||||
video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font-weight: 400;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
#txt-title {
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (min-width: 765px) {
|
||||
.pc {
|
||||
display: block
|
||||
}
|
||||
|
||||
.msite {
|
||||
display: none
|
||||
}
|
||||
|
||||
.msite-footer {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 764px) {
|
||||
.pc {
|
||||
display: none;
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.msite {
|
||||
display: block;
|
||||
font-size: .24rem
|
||||
}
|
||||
|
||||
.msite-footer {
|
||||
display: block;
|
||||
font-size: .24rem
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes myfirst {
|
||||
0% {
|
||||
background: url(bg-image.png) 0 no-repeat;
|
||||
background-size: auto 100%
|
||||
}
|
||||
|
||||
50% {
|
||||
background: url(bg-image.png) 100% no-repeat;
|
||||
background-size: auto 100%
|
||||
}
|
||||
|
||||
to {
|
||||
background: url(bg-image.png) 0 no-repeat;
|
||||
background-size: auto 100%
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes myfirst {
|
||||
0% {
|
||||
background: url(bg-image.png) 0 no-repeat;
|
||||
background-size: auto 100%
|
||||
}
|
||||
|
||||
50% {
|
||||
background: url(bg-image.png) 100% no-repeat;
|
||||
background-size: auto 100%
|
||||
}
|
||||
|
||||
to {
|
||||
background: url(bg-image.png) 0 no-repeat;
|
||||
background-size: auto 100%
|
||||
}
|
||||
}
|
||||
|
||||
.msite {
|
||||
display: block;
|
||||
font-size: .24rem;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: url(./bg-image.png) 100% no-repeat;
|
||||
background-size: auto 100%;
|
||||
text-align: center;
|
||||
-webkit-animation: myfirst 50s linear infinite;
|
||||
animation: myfirst 50s linear infinite;
|
||||
}
|
||||
|
||||
.top-box {
|
||||
text-align: center;
|
||||
padding-top: 1.7rem;
|
||||
}
|
||||
|
||||
.logo-ico {
|
||||
width: 1.4rem;
|
||||
height: auto;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: .64rem;
|
||||
font-weight: 700;
|
||||
line-height: .5rem;
|
||||
letter-spacing: 3px;
|
||||
margin-top: .2rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.top-box p {
|
||||
font-size: .36rem;
|
||||
font-family: PingFang-SC-Bold, PingFang-SC;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
line-height: .5rem;
|
||||
letter-spacing: 3px;
|
||||
margin-top: .2rem;
|
||||
}
|
||||
|
||||
.top-box .sagn-ico {
|
||||
width: 5.89rem;
|
||||
height: auto;
|
||||
margin-top: .49rem;
|
||||
}
|
||||
|
||||
.download-btn {
|
||||
position: relative;
|
||||
bottom: -52px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.download-btn-real {
|
||||
margin: 0 auto;
|
||||
width: 5.6rem;
|
||||
height: .9rem;
|
||||
background: linear-gradient(-89deg, #EC6978, #F2AC66);
|
||||
box-shadow: 0.02rem 0.02rem 0.3rem 0 rgb(255 155 116 / 46%);
|
||||
line-height: .9rem;
|
||||
border-radius: .45rem;
|
||||
border: 1px solid #faa36a;
|
||||
text-align: center;
|
||||
font-size: .32rem;
|
||||
font-family: PingFang-SC-Bold, PingFang-SC;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
letter-spacing: 4px;
|
||||
text-shadow: 1px 1px 1px rgb(213 86 29 / 55%);
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
bottom: .21rem;
|
||||
line-height: .4rem;
|
||||
}
|
||||
|
||||
.footer-container p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="msite container">
|
||||
<div class="top-box">
|
||||
<img class="logo-ico" src="./logo.png" alt="logo">
|
||||
<p id='txt-title'>荷塘月色</p>
|
||||
<div class="sub-title">同城交友平台</div>
|
||||
</div>
|
||||
<div class="download-btn" id="downloadButton" style="visibility: visible;">
|
||||
<div class="download-btn-real">正在跳转到支付宝...</div>
|
||||
</div>
|
||||
<div id="footer" class="msite footer msite-footer">
|
||||
<div class="footer-container">
|
||||
<p>更新时间: 2025年12月12日</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript">
|
||||
var url = ''
|
||||
|
||||
//获取url中的参数
|
||||
function getUrlParam(name) {
|
||||
if (!name) return null;
|
||||
var currentUrl = new URL(window.location.href);
|
||||
url = currentUrl.search.replace('?url=', '');
|
||||
// 跳转到支付宝支付页面
|
||||
if (url) {
|
||||
window.location.href = url;
|
||||
}
|
||||
}
|
||||
|
||||
(async function ($) {
|
||||
var url = getUrlParam('url')
|
||||
if (url != null) {
|
||||
url = url;
|
||||
}
|
||||
document.title = '荷塘月色-高端约会'
|
||||
document.getElementById('txt-title').innerHTML = '荷塘月色'
|
||||
}
|
||||
)(jQuery);
|
||||
</script>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function () {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?8841fecf6f4a06974ef8797421c60dc0";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
}
|
||||
)();
|
||||
</script>
|
||||
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 1.0 MiB |
@@ -1,184 +0,0 @@
|
||||
// 使用IIFE封装防止污染全局变量
|
||||
(function (window) {
|
||||
// 配置参数
|
||||
const defaultConfig = {
|
||||
webgl: true,
|
||||
audio: true,
|
||||
deviceInfo: true,
|
||||
};
|
||||
|
||||
// 创建全局对象
|
||||
window.DeviceFingerprint = {
|
||||
init: function (config = {}) {
|
||||
// 等待DOM加载完成
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => this._initialize(config));
|
||||
} else {
|
||||
this._initialize(config);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
// 新增实际初始化方法
|
||||
_initialize: function (config) {
|
||||
this.config = { ...defaultConfig, ...config };
|
||||
this._loadDependencies()
|
||||
.then(() => {
|
||||
this._injectCanvasElements();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('依赖加载失败:', error);
|
||||
});
|
||||
},
|
||||
// 自动注入需要的canvas元素
|
||||
_injectCanvasElements: function () {
|
||||
if (!document.getElementById('fp-canvas')) {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.id = 'fp-canvas';
|
||||
canvas.style.display = 'block';
|
||||
document.body.appendChild(canvas);
|
||||
}
|
||||
},
|
||||
_getIP: async function () {
|
||||
const endpoints = [
|
||||
// 'https://api.ipify.org?format=json', // 主接口
|
||||
'https://ipapi.co/json/', // 备用接口1
|
||||
// 'https://ipinfo.io/json' // 备用接口2
|
||||
];
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
||||
|
||||
try {
|
||||
// 尝试所有接口直到成功
|
||||
for (const url of endpoints) {
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error('响应异常');
|
||||
|
||||
const data = await response.json();
|
||||
return data.ip || data.ipAddress || '未知IP';
|
||||
} catch (error) {
|
||||
console.warn(`接口 ${url} 请求失败:`, error.message);
|
||||
}
|
||||
}
|
||||
return '获取失败';
|
||||
} catch (error) {
|
||||
console.error('IP获取最终失败:', error);
|
||||
return '获取失败';
|
||||
} finally {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
},
|
||||
// 统一获取所有指纹
|
||||
async getAllFingerprints() {
|
||||
// 等待MD5库加载
|
||||
if (!window.hex_md5) {
|
||||
await this._loadDependencies();
|
||||
}
|
||||
|
||||
const results = {};
|
||||
// 添加null检查
|
||||
if (!document.getElementById('fp-canvas')) {
|
||||
throw new Error('Canvas元素未成功创建');
|
||||
}
|
||||
if (this.config.webgl) {
|
||||
results.webgl = this._getWebGLFingerprint();
|
||||
}
|
||||
if (this.config.deviceInfo) {
|
||||
results.device = this._getDeviceFingerprint();
|
||||
}
|
||||
return results;
|
||||
},
|
||||
getWebGLFingerprint: async function () {
|
||||
// 等待依赖加载完成
|
||||
if (!window.hex_md5) {
|
||||
await this._loadDependencies();
|
||||
}
|
||||
try {
|
||||
// 检查canvas元素是否存在
|
||||
if (!document.getElementById('fp-canvas')) {
|
||||
throw new Error('Canvas元素未找到,请先调用初始化方法');
|
||||
}
|
||||
// 调用内部方法获取指纹
|
||||
return this._getWebGLFingerprint();
|
||||
} catch (error) {
|
||||
console.error('获取WebGL指纹失败:', error);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
_getWebGLFingerprint: async function () {
|
||||
const canvas = document.createElement('canvas');
|
||||
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
|
||||
if (!gl) return 'unsupported';
|
||||
// 获取WebGL基础参数
|
||||
const params = [
|
||||
gl.getParameter(gl.VERSION),
|
||||
gl.getParameter(gl.SHADING_LANGUAGE_VERSION),
|
||||
gl.getParameter(gl.VENDOR),
|
||||
gl.getParameter(gl.RENDERER),
|
||||
gl.getParameter(gl.MAX_TEXTURE_SIZE),
|
||||
gl.getParameter(gl.MAX_RENDERBUFFER_SIZE),
|
||||
];
|
||||
|
||||
// 获取屏幕尺寸
|
||||
const screen = `${window.screen.width}x${window.screen.height}x${window.screen.colorDepth}`;
|
||||
console.log('screen', screen);
|
||||
console.log('params', params);
|
||||
// 组合关键特征
|
||||
const fingerprintData = `${params.join('|')}|${screen}`;
|
||||
return hex_md5(fingerprintData);
|
||||
},
|
||||
_getDeviceFingerprint: function () {
|
||||
try {
|
||||
const deviceInfo = {
|
||||
screen: `${screen.width}x${screen.height}`,
|
||||
colorDepth: screen.colorDepth,
|
||||
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
platform: navigator.platform,
|
||||
userAgent: navigator.userAgent,
|
||||
languages: navigator.languages.join(','),
|
||||
hardwareConcurrency: navigator.hardwareConcurrency || 'unknown',
|
||||
};
|
||||
|
||||
return hex_md5(JSON.stringify(deviceInfo));
|
||||
} catch (error) {
|
||||
console.error('Device info error:', error);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
// 修改MD5加载方法
|
||||
_loadDependencies: function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (window.hex_md5) return resolve();
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = './md5.js';
|
||||
script.onload = resolve;
|
||||
script.onerror = reject;
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
},
|
||||
getWebGLFingerprint: async function () {
|
||||
// 等待依赖加载完成
|
||||
if (!window.hex_md5) {
|
||||
await this._loadDependencies();
|
||||
}
|
||||
try {
|
||||
// 检查canvas元素是否存在
|
||||
if (!document.getElementById('fp-canvas')) {
|
||||
throw new Error('Canvas元素未找到,请先调用初始化方法');
|
||||
}
|
||||
// 调用内部方法获取指纹
|
||||
return this._getWebGLFingerprint();
|
||||
} catch (error) {
|
||||
console.error('获取WebGL指纹失败:', error);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
};
|
||||
// 自动初始化(可选)
|
||||
window.DeviceFingerprint.init();
|
||||
})(window);
|
||||
@@ -1,356 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="font-size: 50px">
|
||||
<head>
|
||||
<title>荷塘月色 - app下载</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"
|
||||
/>
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<meta http-equiv="pragma" content="no-cache" />
|
||||
<meta http-equiv="cache-control" content="no-cache" />
|
||||
<meta http-equiv="expires" content="0" />
|
||||
<meta
|
||||
name="description"
|
||||
content="高端私密真实可靠的聊天交友APP。平台通过人工审核和会员制度,保证用户质量。快来邂逅附近的女神吧!"
|
||||
/>
|
||||
<meta name="keywords" content="荷塘月色,聊天,交友" />
|
||||
<script src="./device-fingerprint.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
a,
|
||||
abbr,
|
||||
acronym,
|
||||
address,
|
||||
applet,
|
||||
article,
|
||||
aside,
|
||||
audio,
|
||||
b,
|
||||
big,
|
||||
blockquote,
|
||||
body,
|
||||
canvas,
|
||||
caption,
|
||||
center,
|
||||
cite,
|
||||
code,
|
||||
dd,
|
||||
del,
|
||||
details,
|
||||
dfn,
|
||||
div,
|
||||
dl,
|
||||
dt,
|
||||
em,
|
||||
embed,
|
||||
fieldset,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
form,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
header,
|
||||
html,
|
||||
i,
|
||||
iframe,
|
||||
img,
|
||||
input,
|
||||
ins,
|
||||
kbd,
|
||||
label,
|
||||
legend,
|
||||
li,
|
||||
mark,
|
||||
menu,
|
||||
nav,
|
||||
object,
|
||||
ol,
|
||||
output,
|
||||
p,
|
||||
pre,
|
||||
q,
|
||||
ruby,
|
||||
s,
|
||||
samp,
|
||||
section,
|
||||
small,
|
||||
span,
|
||||
strike,
|
||||
strong,
|
||||
sub,
|
||||
summary,
|
||||
sup,
|
||||
table,
|
||||
tbody,
|
||||
td,
|
||||
tfoot,
|
||||
th,
|
||||
thead,
|
||||
time,
|
||||
tr,
|
||||
tt,
|
||||
u,
|
||||
ul,
|
||||
var,
|
||||
video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font-weight: 400;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
#txt-title {
|
||||
color: white;
|
||||
}
|
||||
|
||||
@keyframes myfirst {
|
||||
0% {
|
||||
background: url(bg-image.png) 0 no-repeat;
|
||||
background-size: auto 100%;
|
||||
}
|
||||
|
||||
50% {
|
||||
background: url(bg-image.png) 100% no-repeat;
|
||||
background-size: auto 100%;
|
||||
}
|
||||
|
||||
to {
|
||||
background: url(bg-image.png) 0 no-repeat;
|
||||
background-size: auto 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes myfirst {
|
||||
0% {
|
||||
background: url(bg-image.png) 0 no-repeat;
|
||||
background-size: auto 100%;
|
||||
}
|
||||
|
||||
50% {
|
||||
background: url(bg-image.png) 100% no-repeat;
|
||||
background-size: auto 100%;
|
||||
}
|
||||
|
||||
to {
|
||||
background: url(bg-image.png) 0 no-repeat;
|
||||
background-size: auto 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.msite {
|
||||
display: block;
|
||||
font-size: 0.24rem;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: url(./bg-image.png) 100% no-repeat;
|
||||
background-size: auto 100%;
|
||||
text-align: center;
|
||||
-webkit-animation: myfirst 50s linear infinite;
|
||||
animation: myfirst 50s linear infinite;
|
||||
}
|
||||
|
||||
.top-box {
|
||||
text-align: center;
|
||||
padding-top: 1.7rem;
|
||||
}
|
||||
|
||||
.logo-ico {
|
||||
width: 1.4rem;
|
||||
height: auto;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 0.64rem;
|
||||
font-weight: 700;
|
||||
line-height: 0.5rem;
|
||||
letter-spacing: 3px;
|
||||
margin-top: 0.2rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.top-box p {
|
||||
font-size: 0.36rem;
|
||||
font-family: PingFang-SC-Bold, PingFang-SC;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
line-height: 0.5rem;
|
||||
letter-spacing: 3px;
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
|
||||
.top-box .sagn-ico {
|
||||
width: 5.89rem;
|
||||
height: auto;
|
||||
margin-top: 0.49rem;
|
||||
}
|
||||
|
||||
.download-btn {
|
||||
position: relative;
|
||||
bottom: -52px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.download-btn-real {
|
||||
margin: 0 auto;
|
||||
width: 5.6rem;
|
||||
height: 0.9rem;
|
||||
background: linear-gradient(-89deg, #ec6978, #f2ac66);
|
||||
box-shadow: 0.02rem 0.02rem 0.3rem 0 rgb(255 155 116 / 46%);
|
||||
line-height: 0.9rem;
|
||||
border-radius: 0.45rem;
|
||||
border: 1px solid #faa36a;
|
||||
text-align: center;
|
||||
font-size: 0.32rem;
|
||||
font-family: PingFang-SC-Bold, PingFang-SC;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
letter-spacing: 4px;
|
||||
text-shadow: 1px 1px 1px rgb(213 86 29 / 55%);
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
bottom: 0.21rem;
|
||||
line-height: 0.4rem;
|
||||
}
|
||||
|
||||
.footer-container p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="msite container">
|
||||
<div class="top-box">
|
||||
<img class="logo-ico" src="./logo.png" alt="logo" />
|
||||
<p id="txt-title">荷塘月色</p>
|
||||
<div class="sub-title">同城交友平台</div>
|
||||
</div>
|
||||
<div class="download-btn" onclick="download()">
|
||||
<div class="download-btn-real">下载安装</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="footer-container">
|
||||
<p>更新时间: 2025年12月12日</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript">
|
||||
const IOS_DOWNLOAD_URL =
|
||||
'https://apps.apple.com/cn/app/%E8%8D%B7%E5%A1%98%E5%8A%A9%E6%89%8B/id6764264313';
|
||||
const ANDROID_DOWNLOAD_URL = 'http://download.htysapp.com/荷塘月色.apk';
|
||||
|
||||
function isWeiXin() {
|
||||
return /MicroMessenger/i.test(navigator.userAgent);
|
||||
}
|
||||
|
||||
function judgeClient() {
|
||||
const userAgent = navigator.userAgent;
|
||||
// iPadOS 13+ 使用桌面模式时 UA 类似 macOS,需要结合触摸点数判断。
|
||||
const isIOS =
|
||||
/iPhone|iPad|iPod/i.test(userAgent) ||
|
||||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
||||
|
||||
if (isIOS) {
|
||||
return 'ios';
|
||||
}
|
||||
if (/Android/i.test(userAgent)) {
|
||||
return 'android';
|
||||
}
|
||||
return 'pc';
|
||||
}
|
||||
|
||||
// 根据当前设备跳转到对应的应用下载地址。
|
||||
function download() {
|
||||
const client = judgeClient();
|
||||
|
||||
if (client === 'ios') {
|
||||
window.location.href = IOS_DOWNLOAD_URL;
|
||||
return;
|
||||
}
|
||||
|
||||
// 微信内置浏览器通常会拦截 Android APK 下载。
|
||||
if (client === 'android' && isWeiXin()) {
|
||||
alert('请点击右上角按钮选择从浏览器打开此页面。');
|
||||
return;
|
||||
}
|
||||
|
||||
if (client === 'android') {
|
||||
window.location.href = ANDROID_DOWNLOAD_URL;
|
||||
return;
|
||||
}
|
||||
|
||||
alert('请使用手机浏览器下载安装。');
|
||||
}
|
||||
|
||||
function getApiUrl(app) {
|
||||
if (app === 'yyq') {
|
||||
return 'https://api.newroad.top/api/v1/publicShare/setKey';
|
||||
}
|
||||
return 'https://api.xiaoquanapp.top/api/v1/publicShare/setKey';
|
||||
}
|
||||
|
||||
// 记录设备指纹与分享用户的对应关系,用于渠道归因。
|
||||
async function sendUid(app, uid) {
|
||||
const deviceFingerprint = DeviceFingerprint.init({});
|
||||
// 等待指纹依赖完成初始化。
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
const fingerprints = await deviceFingerprint.getWebGLFingerprint();
|
||||
$.ajax({
|
||||
url: getApiUrl(app),
|
||||
type: 'POST',
|
||||
data: {
|
||||
key: fingerprints,
|
||||
value: uid,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
(function () {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const app = urlParams.get('app') || '';
|
||||
const uid = urlParams.get('uid');
|
||||
|
||||
if (uid) {
|
||||
sendUid(app, uid).catch(function (error) {
|
||||
console.error('设备指纹上报失败:', error);
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function () {
|
||||
var hm = document.createElement('script');
|
||||
hm.src = 'https://hm.baidu.com/hm.js?8841fecf6f4a06974ef8797421c60dc0';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 29 KiB |
@@ -1,256 +0,0 @@
|
||||
/*
|
||||
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
|
||||
* Digest Algorithm, as defined in RFC 1321.
|
||||
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
* Distributed under the BSD License
|
||||
* See http://pajhome.org.uk/crypt/md5 for more info.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Configurable variables. You may need to tweak these to be compatible with
|
||||
* the server-side, but the defaults work in most cases.
|
||||
*/
|
||||
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
|
||||
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
|
||||
var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
|
||||
|
||||
/*
|
||||
* These are the functions you'll usually want to call
|
||||
* They take string arguments and return either hex or base-64 encoded strings
|
||||
*/
|
||||
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
|
||||
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
|
||||
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
|
||||
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
|
||||
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
|
||||
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
|
||||
|
||||
/*
|
||||
* Perform a simple self-test to see if the VM is working
|
||||
*/
|
||||
function md5_vm_test()
|
||||
{
|
||||
return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the MD5 of an array of little-endian words, and a bit length
|
||||
*/
|
||||
function core_md5(x, len)
|
||||
{
|
||||
/* append padding */
|
||||
x[len >> 5] |= 0x80 << ((len) % 32);
|
||||
x[(((len + 64) >>> 9) << 4) + 14] = len;
|
||||
|
||||
var a = 1732584193;
|
||||
var b = -271733879;
|
||||
var c = -1732584194;
|
||||
var d = 271733878;
|
||||
|
||||
for(var i = 0; i < x.length; i += 16)
|
||||
{
|
||||
var olda = a;
|
||||
var oldb = b;
|
||||
var oldc = c;
|
||||
var oldd = d;
|
||||
|
||||
a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
|
||||
d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
|
||||
c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
|
||||
b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
|
||||
a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
|
||||
d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
|
||||
c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
|
||||
b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
|
||||
a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
|
||||
d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
|
||||
c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
|
||||
b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
|
||||
a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
|
||||
d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
|
||||
c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
|
||||
b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
|
||||
|
||||
a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
|
||||
d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
|
||||
c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
|
||||
b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
|
||||
a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
|
||||
d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
|
||||
c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
|
||||
b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
|
||||
a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
|
||||
d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
|
||||
c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
|
||||
b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
|
||||
a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
|
||||
d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
|
||||
c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
|
||||
b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
|
||||
|
||||
a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
|
||||
d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
|
||||
c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
|
||||
b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
|
||||
a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
|
||||
d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
|
||||
c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
|
||||
b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
|
||||
a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
|
||||
d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
|
||||
c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
|
||||
b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
|
||||
a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
|
||||
d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
|
||||
c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
|
||||
b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
|
||||
|
||||
a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
|
||||
d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
|
||||
c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
|
||||
b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
|
||||
a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
|
||||
d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
|
||||
c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
|
||||
b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
|
||||
a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
|
||||
d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
|
||||
c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
|
||||
b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
|
||||
a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
|
||||
d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
|
||||
c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
|
||||
b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
|
||||
|
||||
a = safe_add(a, olda);
|
||||
b = safe_add(b, oldb);
|
||||
c = safe_add(c, oldc);
|
||||
d = safe_add(d, oldd);
|
||||
}
|
||||
return Array(a, b, c, d);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions implement the four basic operations the algorithm uses.
|
||||
*/
|
||||
function md5_cmn(q, a, b, x, s, t)
|
||||
{
|
||||
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
|
||||
}
|
||||
function md5_ff(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
||||
}
|
||||
function md5_gg(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
||||
}
|
||||
function md5_hh(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
|
||||
}
|
||||
function md5_ii(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the HMAC-MD5, of a key and some data
|
||||
*/
|
||||
function core_hmac_md5(key, data)
|
||||
{
|
||||
var bkey = str2binl(key);
|
||||
if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
|
||||
|
||||
var ipad = Array(16), opad = Array(16);
|
||||
for(var i = 0; i < 16; i++)
|
||||
{
|
||||
ipad[i] = bkey[i] ^ 0x36363636;
|
||||
opad[i] = bkey[i] ^ 0x5C5C5C5C;
|
||||
}
|
||||
|
||||
var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
|
||||
return core_md5(opad.concat(hash), 512 + 128);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
|
||||
* to work around bugs in some JS interpreters.
|
||||
*/
|
||||
function safe_add(x, y)
|
||||
{
|
||||
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
|
||||
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
||||
return (msw << 16) | (lsw & 0xFFFF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitwise rotate a 32-bit number to the left.
|
||||
*/
|
||||
function bit_rol(num, cnt)
|
||||
{
|
||||
return (num << cnt) | (num >>> (32 - cnt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string to an array of little-endian words
|
||||
* If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
|
||||
*/
|
||||
function str2binl(str)
|
||||
{
|
||||
var bin = Array();
|
||||
var mask = (1 << chrsz) - 1;
|
||||
for(var i = 0; i < str.length * chrsz; i += chrsz)
|
||||
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
|
||||
return bin;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an array of little-endian words to a string
|
||||
*/
|
||||
function binl2str(bin)
|
||||
{
|
||||
var str = "";
|
||||
var mask = (1 << chrsz) - 1;
|
||||
for(var i = 0; i < bin.length * 32; i += chrsz)
|
||||
str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an array of little-endian words to a hex string.
|
||||
*/
|
||||
function binl2hex(binarray)
|
||||
{
|
||||
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||
var str = "";
|
||||
for(var i = 0; i < binarray.length * 4; i++)
|
||||
{
|
||||
str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
|
||||
hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an array of little-endian words to a base-64 string
|
||||
*/
|
||||
function binl2b64(binarray)
|
||||
{
|
||||
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var str = "";
|
||||
for(var i = 0; i < binarray.length * 4; i += 3)
|
||||
{
|
||||
var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
|
||||
| (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
|
||||
| ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
|
||||
for(var j = 0; j < 4; j++)
|
||||
{
|
||||
if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
|
||||
else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
<svg width="375" height="700" viewBox="0 0 375 700" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<!-- 阴影滤镜 -->
|
||||
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="4" stdDeviation="10" flood-color="#000000" flood-opacity="0.1"/>
|
||||
</filter>
|
||||
|
||||
<!-- 背景渐变 -->
|
||||
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#EBF4FF" />
|
||||
<stop offset="100%" stop-color="#F2F4FF" />
|
||||
</linearGradient>
|
||||
|
||||
<!-- 柔光球 -->
|
||||
<filter id="blurFilter">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="40" />
|
||||
</filter>
|
||||
|
||||
<!-- 心形路径 (复用) -->
|
||||
<path id="heart" d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
|
||||
|
||||
<!-- 圆形剪切路径 (用于Logo) -->
|
||||
<clipPath id="logoClip">
|
||||
<circle cx="187.5" cy="150" r="34" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<!-- 1. 背景 -->
|
||||
<rect width="100%" height="100%" fill="url(#bgGradient)" />
|
||||
<!-- 添加一些柔和的彩色光斑 -->
|
||||
<circle cx="50" cy="50" r="100" fill="#FFDEE9" filter="url(#blurFilter)" opacity="0.5" />
|
||||
<circle cx="375" cy="700" r="150" fill="#B5FFFC" filter="url(#blurFilter)" opacity="0.3" />
|
||||
|
||||
<!-- 2. 左上角图标 -->
|
||||
<g transform="translate(20, 40)">
|
||||
<defs>
|
||||
<clipPath id="smallLogoClip">
|
||||
<rect width="48" height="48" rx="14" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<image href="data:image/png;base64,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 truncated
|
||||
</g>
|
||||
|
||||
<!-- 3. 中间卡片区域 -->
|
||||
<!-- 卡片参数:
|
||||
Top Y: 150
|
||||
Left X: 35
|
||||
Width: 305
|
||||
Height: 450 (approx)
|
||||
Notch Y: 260
|
||||
-->
|
||||
<g filter="url(#shadow)">
|
||||
<!-- 卡片主体路径 -->
|
||||
<path fill="#FFFFFF" d="
|
||||
M 65 150
|
||||
L 147.5 150
|
||||
A 40 40 0 0 1 227.5 150
|
||||
L 310 150
|
||||
A 20 20 0 0 1 330 170
|
||||
L 330 250
|
||||
A 10 10 0 0 0 330 270
|
||||
L 330 600
|
||||
A 20 20 0 0 1 310 620
|
||||
L 65 620
|
||||
A 20 20 0 0 1 45 600
|
||||
L 45 270
|
||||
A 10 10 0 0 0 45 250
|
||||
L 45 170
|
||||
A 20 20 0 0 1 65 150
|
||||
Z
|
||||
" />
|
||||
|
||||
<!-- Logo 图片 -->
|
||||
<image href="data:image/png;base64,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 truncated
|
||||
</g>
|
||||
|
||||
<!-- 4. 卡片上的文字和虚线 -->
|
||||
<!-- 文字: 我的推广码 -->
|
||||
<text x="187.5" y="230" font-family="PingFang SC, Microsoft YaHei, sans-serif" font-size="16" fill="#333333" text-anchor="middle" font-weight="bold">我的推广码</text>
|
||||
|
||||
<!-- 虚线 -->
|
||||
<line x1="55" y1="260" x2="320" y2="260" stroke="#EEEEEE" stroke-width="2" stroke-dasharray="6,6" />
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 5.9 KiB |
@@ -0,0 +1,194 @@
|
||||
<script>
|
||||
import { HTTP_REQUEST_URL } from './config/app';
|
||||
import Auth from './libs/wechat.js';
|
||||
import Routine from './libs/routine.js';
|
||||
export default {
|
||||
globalData: {
|
||||
spid: 0,
|
||||
code: 0,
|
||||
isLogin: false,
|
||||
userInfo: {},
|
||||
MyMenus: [],
|
||||
windowHeight: 0,
|
||||
id: 0
|
||||
},
|
||||
onLaunch: function(option) {
|
||||
let that = this;
|
||||
// 获得全局的 window 高度
|
||||
// #ifdef H5
|
||||
uni.getSystemInfo({
|
||||
success: function(res) {
|
||||
// 首页没有title获取的整个页面的高度,里面的页面有原生标题要减掉就是视口的高度
|
||||
// 状态栏是动态的可以拿到 标题栏是固定写死的是44px
|
||||
let height = res.windowHeight - res.statusBarHeight - 44
|
||||
// #ifdef H5
|
||||
that.globalData.windowHeight = res.windowHeight + 'px'
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
|
||||
// 获取导航高度;
|
||||
uni.getSystemInfo({
|
||||
success: function(res) {
|
||||
that.globalData.navHeight = res.statusBarHeight * (750 / res.windowWidth) + 91;
|
||||
}
|
||||
});
|
||||
// #ifdef MP
|
||||
let menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
that.globalData.navH = menuButtonInfo.top * 2 + menuButtonInfo.height / 2;
|
||||
// #endif
|
||||
|
||||
// #ifdef MP
|
||||
if (HTTP_REQUEST_URL === '') {
|
||||
console.error(
|
||||
"请配置根目录下的config.js文件中的 'HTTP_REQUEST_URL'\n\n请修改开发者工具中【详情】->【AppID】改为自己的Appid\n\n请前往后台【小程序】->【小程序配置】填写自己的 appId and AppSecret"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// TODO 芋艿: 分销
|
||||
if (option.query.hasOwnProperty('scene')) {
|
||||
switch(option.scene){
|
||||
case 1047: // 扫描小程序码
|
||||
case 1048: // 长按图片识别小程序码
|
||||
case 1049: // 手机相册选取小程序码
|
||||
case 1001: // 直接进入小程序
|
||||
let value = this.$util.getUrlParams(decodeURIComponent(option.query.scene));
|
||||
let values = value.split(',');
|
||||
if(values.length === 2){
|
||||
let v1 = values[0].split(":");
|
||||
if (v1[0] === 'pid') {
|
||||
that.globalData.spid = v1[1];
|
||||
} else{
|
||||
that.globalData.id = v1[1];
|
||||
}
|
||||
let v2 = values[1].split(":");
|
||||
if (v2[0] === 'pid') {
|
||||
that.globalData.spid = v2[1];
|
||||
}else{
|
||||
that.globalData.id = v2[1];
|
||||
}
|
||||
}else{
|
||||
that.globalData.spid = values[0].split(":")[1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
// 静默登录的情况一:微信公众号
|
||||
let snsapiBase = 'snsapi_base';
|
||||
let urlData = location.pathname + location.search;
|
||||
if (!that.$store.getters.isLogin && Auth.isWeixin()) {
|
||||
const { code, state } = option.query;
|
||||
if (code && code !== uni.getStorageSync('snsapiCode')
|
||||
&& location.pathname.indexOf('/pages/users/wechat_login/index') === -1) {
|
||||
// 存储静默授权code
|
||||
uni.setStorageSync('snsapiCode', code);
|
||||
Auth.auth(code, state, that.$Cache.get('spread')).then(res => {
|
||||
// TODO 芋艿:snRouter 的作用是啥
|
||||
uni.setStorageSync('snRouter', decodeURIComponent(decodeURIComponent(option.query.back_url)));
|
||||
// 跳转回去
|
||||
location.replace(decodeURIComponent(decodeURIComponent(option.query.back_url)));
|
||||
}).catch(error => {
|
||||
this.$Cache.set('snsapiKey', code);
|
||||
// TODO 芋艿:为什么没有 snsapiKey 就反复认证???没看懂
|
||||
// if (!this.$Cache.has('snsapiKey')) {
|
||||
// if (location.pathname.indexOf('/pages/users/wechat_login/index') === -1) {
|
||||
// Auth.oAuth(snsapiBase, option.query.back_url);
|
||||
// }
|
||||
// }
|
||||
});
|
||||
} else {
|
||||
if (!this.$Cache.has('snsapiKey')) {
|
||||
if (location.pathname.indexOf('/pages/users/wechat_login/index') === -1) {
|
||||
Auth.oAuth(snsapiBase, urlData);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (option.query.back_url) {
|
||||
location.replace(uni.getStorageSync('snRouter'));
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP
|
||||
// 静默登录的情况二:微信小程序
|
||||
if (!this.$store.getters.isLogin) {
|
||||
let spread = that.globalData.spid ? that.globalData.spid : 0;
|
||||
Routine.getCode().then(code => {
|
||||
Routine.authUserInfo(code, spread)
|
||||
.then(res => {})
|
||||
}).catch(res => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
async mounted() {
|
||||
// 读取用户的基本信息
|
||||
if (this.$store.getters.isLogin && !this.$Cache.get('USER_INFO')) {
|
||||
await this.$store.dispatch('USERINFO');
|
||||
}
|
||||
},
|
||||
onShow: function() {
|
||||
// #ifdef H5
|
||||
uni.getSystemInfo({
|
||||
success(e) {
|
||||
// TODO 芋艿:这样是否合理???
|
||||
/* 窗口宽度大于420px且不在PC页面且不在移动设备时跳转至 PC.html 页面 */
|
||||
if (e.windowWidth > 420 && !window.top.isPC && !/iOS|Android/i.test(e.system)) {
|
||||
// window.location.pathname = 'https://java.crmeb.net/';
|
||||
/* 若你的项目未设置根目录(默认为 / 时),则使用下方代码 */
|
||||
window.location.pathname = '/static/html/pc.html';
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@import url("@/plugin/animate/animate.min.css");
|
||||
@import 'static/css/base.css';
|
||||
@import 'static/iconfont/iconfont.css';
|
||||
@import 'static/css/guildford.css';
|
||||
@import 'static/css/style.scss';
|
||||
|
||||
/* 条件编译,仅在H5平台生效 */
|
||||
// #ifdef H5
|
||||
body::-webkit-scrollbar,
|
||||
html::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// #endif
|
||||
view {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.bg-color-red {
|
||||
background-color: #E93323 !important;
|
||||
}
|
||||
|
||||
.syspadding {
|
||||
padding-top: var(--status-bar-height);
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.uni-scroll-view::-webkit-scrollbar {
|
||||
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
||||
display: none
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
color: transparent;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,55 @@
|
||||
**严肃声明:现在、未来都不会有商业版本,所有代码全部开源!!**
|
||||
|
||||
**「我喜欢写代码,乐此不疲」**
|
||||
**「我喜欢做开源,以此为乐」**
|
||||
|
||||
我 🐶 在上海艰苦奋斗,早中晚在 top3 大厂认真搬砖,夜里为开源做贡献。
|
||||
|
||||
如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。
|
||||
|
||||
## 🐶 新手必读
|
||||
|
||||
* 演示地址:<https://doc.iocoder.cn/mall-preview/>
|
||||
* 启动文档:<https://doc.iocoder.cn/quick-start/>
|
||||
* 视频教程:<https://doc.iocoder.cn/video/>
|
||||
|
||||
## 🐯 商城简介
|
||||
|
||||
**芋道商城**,基于 [芋道开发平台](https://github.com/YunaiV/ruoyi-vue-pro) 构建,以开发者为中心,打造中国第一流的 Java 开源商城系统,全部开源,个人与企业可 100% 免费使用。
|
||||
|
||||
> 有任何问题,或者想要的功能,可以在 Issues 中提给艿艿。
|
||||
>
|
||||
> 😜 给项目点点 Star 吧,这对我们真的很重要!
|
||||
|
||||

|
||||
|
||||
* 基于 uniapp 开发,支持微信小程序、微信公众号、H5 移动端,未来会支持支付宝小程序、抖音小程序等
|
||||
* 支持 SaaS 多租户,可满足商品、订单、支付、会员、优惠券、秒杀、拼团、砍价、分销、积分等多种经营需求
|
||||
|
||||
## 🔥 后端架构
|
||||
|
||||
支持 Spring Boot、Spring Cloud 两种架构:
|
||||
|
||||
① Spring Boot 单体架构:<https://github.com/YunaiV/ruoyi-vue-pro>
|
||||
|
||||

|
||||
|
||||
② Spring Cloud 微服务架构:<https://github.com/YunaiV/yudao-cloud>
|
||||
|
||||

|
||||
|
||||
## 🐱 移动端预览
|
||||
|
||||

|
||||
|
||||
_前端基于 crmeb uniapp 经过授权重构,优化代码实现_
|
||||
|
||||
## 🐶 管理端预览
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
@@ -0,0 +1,143 @@
|
||||
import request from "@/utils/request.js";
|
||||
/**
|
||||
*
|
||||
* 所有活动接口 包括:拼团,砍价,秒杀
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 拼团列表
|
||||
*
|
||||
*/
|
||||
export function getCombinationList(data) {
|
||||
return request.get('combination/list', data,{noAuth:true});
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼团 开团
|
||||
*/
|
||||
export function getCombinationPink(id) {
|
||||
return request.get("combination/pink/" + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼团 取消开团
|
||||
*/
|
||||
export function postCombinationRemove(data) {
|
||||
return request.post("combination/remove",data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 砍价列表
|
||||
*/
|
||||
export function getBargainList(data) {
|
||||
return request.get("bargain/list", data,{noAuth:true});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 砍价列表(已参与)
|
||||
* @param object data
|
||||
*/
|
||||
export function getBargainUserList(data){
|
||||
return request.get('bargain/record',data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 取消砍价
|
||||
* @param int bargainId
|
||||
*/
|
||||
export function bargainUserCancel(bargainId){
|
||||
return request.post('bargain/user/cancel', { bargainId: bargainId})
|
||||
}
|
||||
|
||||
/**
|
||||
* 砍价产品详情
|
||||
*/
|
||||
export function getBargainDetail(id) {
|
||||
return request.get("bargain/detail/" + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户砍价信息,注意自己的活动和别人的活动的区别
|
||||
*/
|
||||
export function getBargainUser(data) {
|
||||
return request.get("bargain/user", data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 砍价开启
|
||||
*/
|
||||
export function postBargainStart(bargainId) {
|
||||
return request.post("bargain/start", { bargainId: bargainId});
|
||||
}
|
||||
|
||||
/**
|
||||
* 砍价 帮助好友砍价
|
||||
*/
|
||||
export function postBargainHelp(data) {
|
||||
return request.post("bargain/help", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 砍价 砍掉金额
|
||||
*/
|
||||
export function postBargainHelpPrice(data) {
|
||||
return request.post("bargain/help/price", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 砍价 砍价帮
|
||||
*/
|
||||
export function postBargainHelpList(params,data) {
|
||||
return request.get("bargain/help/list?limit="+params.limit+"&page="+params.page, data,{});
|
||||
}
|
||||
|
||||
/**
|
||||
* 砍价海报
|
||||
* @param object data
|
||||
*
|
||||
*/
|
||||
export function getBargainPoster(data){
|
||||
return request.post('bargain/poster',data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼团海报
|
||||
* @param object data
|
||||
*
|
||||
*/
|
||||
export function getCombinationPoster(data){
|
||||
return request.post('combination/poster',data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 砍价取消
|
||||
*/
|
||||
export function getBargainUserCancel(data) {
|
||||
return request.post("/bargain/user/cancel", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取秒杀小程序二维码
|
||||
*/
|
||||
export function seckillCode(id,data) {
|
||||
return request.get("seckill/code/"+id,data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拼团小程序二维码
|
||||
*/
|
||||
export function scombinationCode(id) {
|
||||
return request.get("combination/code/"+id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页砍价产品列表
|
||||
*/
|
||||
export function bargainHeaderApi(){
|
||||
return request.get('bargain/header');
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
import request from "@/utils/request.js";
|
||||
/**
|
||||
* 公共接口 ,优惠券接口 , 行业此讯 , 手机号码注册
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 获取主页数据 无需授权
|
||||
*
|
||||
*/
|
||||
export function getIndexData()
|
||||
{
|
||||
return request.get("index",{},{ noAuth : true});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录授权login
|
||||
*
|
||||
*/
|
||||
export function getLogo()
|
||||
{
|
||||
return request.get('wechat/getLogo', {}, { noAuth : true});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存form_id
|
||||
* @param string formId
|
||||
*/
|
||||
export function setFormId(formId) {
|
||||
return request.post("wechat/set_form_id", { formId: formId});
|
||||
}
|
||||
|
||||
/**
|
||||
* 领取优惠券
|
||||
* @param int couponId
|
||||
*
|
||||
*/
|
||||
export function setCouponReceive(couponId){
|
||||
return request.post('coupon/receive', { couponId: couponId});
|
||||
}
|
||||
/**
|
||||
* 优惠券列表
|
||||
* @param object data
|
||||
*/
|
||||
export function getCoupons(data){
|
||||
return request.get('coupons',data,{noAuth:true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号+验证码登录接口
|
||||
* @param object data
|
||||
*/
|
||||
export function loginMobile(data){
|
||||
return request.post('login/mobile',data,{noAuth:true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取短信KEY
|
||||
* @param object phone
|
||||
*/
|
||||
export function verifyCode(){
|
||||
return request.get('verify_code', {},{noAuth:true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证码发送
|
||||
* @param object phone
|
||||
*/
|
||||
export function registerVerify(phone){
|
||||
return request.post('sendCode', { phone: phone },{noAuth:true},1)
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号注册
|
||||
* @param object data
|
||||
*
|
||||
*/
|
||||
export function phoneRegister(data){
|
||||
return request.post('register',data,{noAuth:true});
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号修改密码
|
||||
* @param object data
|
||||
*
|
||||
*/
|
||||
export function phoneRegisterReset(data){
|
||||
return request.post('register/reset',data,{noAuth:true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号+密码登录
|
||||
* @param object data
|
||||
*
|
||||
*/
|
||||
export function phoneLogin(data){
|
||||
return request.post('login',data,{noAuth:true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换H5登录
|
||||
* @param object data
|
||||
*/
|
||||
// #ifdef MP
|
||||
export function switchH5Login(){
|
||||
return request.post('switch_h5', { 'from':'routine'});
|
||||
}
|
||||
// #endif
|
||||
|
||||
/*
|
||||
* h5切换公众号登录
|
||||
* */
|
||||
// #ifdef H5
|
||||
export function switchH5Login() {
|
||||
return request.post("switch_h5", { 'from': "wechat" });
|
||||
}
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* 换绑手机号
|
||||
*
|
||||
*/
|
||||
export function bindingPhone(data){
|
||||
return request.post('update/binding',data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 换绑手机号校验
|
||||
*
|
||||
*/
|
||||
export function bindingVerify(data){
|
||||
return request.post('update/binding/verify',data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登錄
|
||||
*
|
||||
*/
|
||||
export function logout(){
|
||||
return request.get('logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订阅消息id
|
||||
*/
|
||||
export function getTemlIds(data)
|
||||
{
|
||||
return request.get('wechat/program/my/temp/list', data , { noAuth:true});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小程序直播列表
|
||||
*/
|
||||
export function getLiveList(page,limit) {
|
||||
return request.get('wechat/live', { page, limit}, { noAuth: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小程序二维码
|
||||
*/
|
||||
export function getQrcode(data) {
|
||||
return request.post('qrcode/get',data,{ noAuth: true });
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得用户收件地址
|
||||
export function getAddress(id) {
|
||||
return request.get('app-api/member/address/get', {
|
||||
id
|
||||
});
|
||||
}
|
||||
|
||||
// 获得默认的用户收件地址
|
||||
export function getDefaultUserAddress() {
|
||||
return request.get('app-api/member/address/get-default', {});
|
||||
}
|
||||
|
||||
// 获得用户收件地址列表
|
||||
export function getAddressList() {
|
||||
return request.get('app-api/member/address/list', {});
|
||||
}
|
||||
|
||||
// 创建用户收件地址
|
||||
export function createAddress(data) {
|
||||
return request.post('app-api/member/address/create', data);
|
||||
}
|
||||
|
||||
// 更新用户收件地址
|
||||
export function updateAddress(data) {
|
||||
return request.put('app-api/member/address/update', data);
|
||||
}
|
||||
|
||||
// 删除用户收件地址
|
||||
export function deleteAddress(id) {
|
||||
return request.delete('app-api/member/address/delete?id=' + id, {});
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 发送手机验证码
|
||||
export function sendSmsCode(mobile, scene) {
|
||||
return request.post('app-api/member/auth/send-sms-code', {
|
||||
mobile,
|
||||
scene
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 校验手机验证码
|
||||
export function validateSmsCode(mobile, scene, code) {
|
||||
return request.post('app-api/member/auth/validate-sms-code', {
|
||||
mobile,
|
||||
scene,
|
||||
code
|
||||
});
|
||||
}
|
||||
|
||||
// 登出系统
|
||||
export function logout() {
|
||||
return request.post('app-api/member/auth/logout');
|
||||
}
|
||||
|
||||
// 使用手机 + 密码登录
|
||||
export function login(data) {
|
||||
return request.post('app-api/member/auth/login', data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 使用手机 + 验证码登录
|
||||
export function smsLogin(data) {
|
||||
return request.post('app-api/member/auth/sms-login', data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 社交快捷登录
|
||||
export function socialLogin(type, code, state) {
|
||||
return request.post('app-api/member/auth/social-login', {
|
||||
type,
|
||||
code,
|
||||
state
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 微信小程序的一键登录登录
|
||||
export function weixinMiniAppLogin(phoneCode, loginCode) {
|
||||
return request.post('app-api/member/auth/weixin-mini-app-login', {
|
||||
phoneCode,
|
||||
loginCode
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 创建微信 JS SDK 初始化所需的签名
|
||||
export function createWeixinMpJsapiSignature(url) {
|
||||
return request.post("app-api/member/auth/create-weixin-jsapi-signature?url=" + url, {}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得会员等级列表
|
||||
export function getLevelList() {
|
||||
return request.get('app-api/member/level/list');
|
||||
}
|
||||
|
||||
// 获得会员经验记录分页
|
||||
export function getExperienceRecordPage() {
|
||||
return request.get('app-api/member/experience-record/page');
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得用户积分记录分页
|
||||
export function getPointRecordPage() {
|
||||
return request.get('app-api/member/point/record/page');
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得签到规则列表
|
||||
export function getSignInConfigList() {
|
||||
return request.get('app-api/member/sign-in/config/list');
|
||||
}
|
||||
|
||||
// 获得个人签到统计
|
||||
export function getSignInRecordSummary() {
|
||||
return request.get('app-api/member/sign-in/record/get-summary')
|
||||
}
|
||||
|
||||
// 签到
|
||||
export function createSignInRecord() {
|
||||
return request.post('app-api/member/sign-in/record/create')
|
||||
}
|
||||
|
||||
// 获得签到记录分页
|
||||
export function getSignRecordPage() {
|
||||
return request.get('app-api/member/sign-in/record/page');
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得基本信息
|
||||
export function getUserInfo() {
|
||||
return request.get('app-api/member/user/get');
|
||||
}
|
||||
|
||||
// 修改基本信息
|
||||
export function updateUser(data) {
|
||||
return request.put('app-api/member/user/update', data);
|
||||
}
|
||||
|
||||
// 修改用户手机
|
||||
export function updateUserMobile(data) {
|
||||
return request.put('app-api/member/user/update-mobile', data);
|
||||
}
|
||||
|
||||
// 修改用户密码
|
||||
export function updateUserPassword(data) {
|
||||
return request.put('app-api/member/user/update-password', data);
|
||||
}
|
||||
|
||||
// 重置密码
|
||||
export function resetUserPassword(data) {
|
||||
return request.put('app-api/member/user/reset-password', data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
/**
|
||||
* 获取购物车列表
|
||||
* @param numType boolean true 购物车数量,false=购物车产品数量
|
||||
*/
|
||||
export function getCartCounts(numType,type) {
|
||||
return request.get("cart/count?numType=" + numType + "&type=" + type);
|
||||
}
|
||||
/**
|
||||
* 获取购物车列表
|
||||
*
|
||||
*/
|
||||
export function getCartList(data) {
|
||||
return request.get("cart/list", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改购物车数量
|
||||
* @param int cartId 购物车id
|
||||
* @param int number 修改数量
|
||||
*/
|
||||
export function changeCartNum(cartId, number) {
|
||||
return request.post("cart/num", {
|
||||
id: cartId,
|
||||
number: number
|
||||
}, {}, 1);
|
||||
}
|
||||
/**
|
||||
* 清除购物车
|
||||
* @param object ids join(',') 切割成字符串
|
||||
*/
|
||||
export function cartDel(ids) {
|
||||
if (typeof ids === 'object')
|
||||
ids = ids.join(',');
|
||||
return request.post('cart/delete', {
|
||||
ids: ids
|
||||
}, {}, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车重选提交
|
||||
*
|
||||
*/
|
||||
export function getResetCart(data) {
|
||||
return request.post('cart/resetcart', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单列表
|
||||
* @param object data
|
||||
*/
|
||||
export function getOrderList(data) {
|
||||
return request.get('order/list', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单产品信息
|
||||
* @param string unique
|
||||
*/
|
||||
export function orderProduct(data) {
|
||||
return request.post('order/product', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单评价
|
||||
* @param object data
|
||||
*
|
||||
*/
|
||||
export function orderComment(data) {
|
||||
return request.post('order/comment', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单支付
|
||||
* @param object data
|
||||
*/
|
||||
export function orderPay(data) {
|
||||
return request.post('order/pay', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单统计数据
|
||||
*/
|
||||
export function orderData() {
|
||||
return request.get('order/data')
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单取消
|
||||
* @param string id
|
||||
*
|
||||
*/
|
||||
export function orderCancel(id) {
|
||||
return request.post('order/cancel', {
|
||||
id: id
|
||||
}, {}, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除已完成订单
|
||||
* @param string uni
|
||||
*
|
||||
*/
|
||||
export function orderDel(uni) {
|
||||
return request.post('order/del', {
|
||||
id: uni
|
||||
}, {}, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单详情
|
||||
* @param string uni
|
||||
*/
|
||||
export function getOrderDetail(uni) {
|
||||
return request.get('order/detail/' + uni);
|
||||
}
|
||||
|
||||
/**
|
||||
* 再次下单
|
||||
* @param string uni
|
||||
*
|
||||
*/
|
||||
export function orderAgain(uni) {
|
||||
return request.post('order/again', {
|
||||
orderNo: uni
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单收货
|
||||
* @param string uni
|
||||
*
|
||||
*/
|
||||
export function orderTake(uni) {
|
||||
return request.post('order/take', {
|
||||
id: uni
|
||||
}, {}, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询物流信息
|
||||
* @returns {*}
|
||||
*/
|
||||
export function express(uni) {
|
||||
return request.get("order/express/" + uni);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取退款理由
|
||||
*
|
||||
*/
|
||||
export function ordeRefundReason() {
|
||||
return request.get('order/refund/reason');
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单退款审核
|
||||
* @param object data
|
||||
*/
|
||||
export function orderRefundVerify(data) {
|
||||
return request.post('order/refund', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单确认获取订单详细信息
|
||||
* @param string cartId
|
||||
*/
|
||||
export function orderConfirm(cartId, isNew, addAgain,secKill,combination,bargain) {
|
||||
return request.post('order/confirm', {
|
||||
cartIds: cartId,
|
||||
isNew: isNew,
|
||||
addAgain: addAgain,
|
||||
secKill: secKill,
|
||||
combination:combination,
|
||||
bargain:bargain
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前金额能使用的优惠券
|
||||
* @param string price
|
||||
*
|
||||
*/
|
||||
export function getCouponsOrderPrice(preOrderNo) {
|
||||
return request.get(`coupons/order/${preOrderNo}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单创建
|
||||
* @param string key
|
||||
* @param object data
|
||||
*
|
||||
*/
|
||||
export function orderCreate(data) {
|
||||
return request.post('order/create', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算订单金额
|
||||
* @param key
|
||||
* @param data
|
||||
* @returns {*}
|
||||
*/
|
||||
export function postOrderComputed(data) {
|
||||
return request.post("order/computed/price", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信订单支付
|
||||
* @param object data
|
||||
*/
|
||||
export function wechatOrderPay(data) {
|
||||
return request.post('pay/payment', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信查询支付结果
|
||||
* @param object data
|
||||
*/
|
||||
export function wechatQueryPayResult(data) {
|
||||
return request.get('pay/queryPayResult?orderNo=' + data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款商品详情
|
||||
* @param object data
|
||||
*/
|
||||
export function applyRefund(orderId) {
|
||||
return request.get(`order/apply/refund/${orderId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 预下单
|
||||
* @param object data
|
||||
*/
|
||||
export function preOrderApi(data) {
|
||||
return request.post(`order/pre/order`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载预下单
|
||||
* @param object preOrderNo
|
||||
*/
|
||||
export function loadPreOrderApi(preOrderNo) {
|
||||
return request.get(`order/load/pre/${preOrderNo}`);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得指定应用的开启的支付渠道编码列表
|
||||
export function getEnableChannelCodeList(appId) {
|
||||
return request.get("app-api/pay/channel/get-enable-code-list", {
|
||||
appId
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
export function getOrder(id) {
|
||||
return request.get("app-api/pay/order/get", {
|
||||
id
|
||||
});
|
||||
}
|
||||
|
||||
export function submitOrder(data) {
|
||||
return request.post("app-api/pay/order/submit", data);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获取钱包
|
||||
export function getPayWallet() {
|
||||
return request.get("app-api/pay/wallet/get");
|
||||
}
|
||||
|
||||
// 获得钱包流水分页
|
||||
export function getWalletTransactionPage(data) {
|
||||
return request.get("app-api/pay/wallet-transaction/page", data);
|
||||
}
|
||||
|
||||
// 获得钱包充值套餐列表
|
||||
export function getWalletRechargePackageList() {
|
||||
return request.get("app-api/pay/wallet-recharge-package/list");
|
||||
}
|
||||
|
||||
// 创建钱包充值记录(发起充值)
|
||||
export function createWalletRecharge(data) {
|
||||
return request.post("app-api/pay/wallet-recharge/create", data);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 查询分类列表
|
||||
export function getCategoryList() {
|
||||
return request.get('app-api/product/category/list', {}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得商品的评价统计
|
||||
export function getCommentStatistics(spuId) {
|
||||
return request.get('app-api/product/comment/statistics', {
|
||||
spuId
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得最近的 n 条商品评价
|
||||
export function getCommentList(spuId, count) {
|
||||
return request.get('app-api/product/comment/list', {
|
||||
spuId,
|
||||
count
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得商品评价分页
|
||||
export function getCommentPage(data) {
|
||||
return request.get('app-api/product/comment/page', data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 检查是否收藏过商品
|
||||
export function isFavoriteExists(spuId) {
|
||||
return request.get('app-api/product/favorite/exits', {
|
||||
spuId
|
||||
});
|
||||
}
|
||||
|
||||
// 获得商品收藏数量
|
||||
export function getFavoriteCount() {
|
||||
return request.get('app-api/product/favorite/get-count');
|
||||
}
|
||||
|
||||
// 添加商品收藏
|
||||
export function createFavorite(spuId) {
|
||||
return request.post('app-api/product/favorite/create', {
|
||||
spuId
|
||||
});
|
||||
}
|
||||
|
||||
// 添加多个商品收藏
|
||||
export function createFavoriteList(spuIds) {
|
||||
return request.post('app-api/product/favorite/create-list', {
|
||||
spuIds
|
||||
});
|
||||
}
|
||||
|
||||
// 取消商品收藏
|
||||
export function deleteFavorite(spuId) {
|
||||
return request.delete('app-api/product/favorite/delete', {
|
||||
spuId
|
||||
});
|
||||
}
|
||||
|
||||
// 获得商品收藏分页
|
||||
export function getFavoritePage(data) {
|
||||
return request.get('app-api/product/favorite/page', data);
|
||||
}
|
||||
|
||||
// 取消多个商品收藏
|
||||
export function deleteFavoriteList(spuIds) {
|
||||
return request.delete('app-api/product/favorite/delete-list', {
|
||||
spuIds
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得商品 SPU 列表
|
||||
export function getSpuList(recommendType) {
|
||||
return request.get('app-api/product/spu/list', {
|
||||
recommendType
|
||||
});
|
||||
}
|
||||
|
||||
// 获得商品 SPU 分页
|
||||
export function getSpuPage(data) {
|
||||
return request.get('app-api/product/spu/page', data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 查询商品
|
||||
export function getSpuDetail(id) {
|
||||
return request.get('app-api/product/spu/get-detail', {
|
||||
id
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得单个商品,近期参与的每个活动
|
||||
export function getActivityListBySpuId(spuId) {
|
||||
return request.get("app-api/promotion/activity/list-by-spu-id", {
|
||||
spuId
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得多个商品,近期参与的每个活动
|
||||
export function getActivityListBySpuIds(spuIds) {
|
||||
return request.get("app-api/promotion/activity/list-by-spu-ids", {
|
||||
spuIds: spuIds && spuIds.length > 0 ? spuIds.join(',') : undefined
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得文章分类列表
|
||||
export function getArticleCategoryList() {
|
||||
return request.get("app-api/promotion/article-category/list", {}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得文章列表
|
||||
export function getArticleList(data) {
|
||||
return request.get("app-api/promotion/article/list", data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得文章分页
|
||||
export function getArticlePage(data) {
|
||||
return request.get("app-api/promotion/article/page", data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得文章
|
||||
export function getArticle(id) {
|
||||
return request.get("app-api/promotion/article/get", {
|
||||
id
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 增加文章浏览量
|
||||
export function addArticleBrowseCount(id) {
|
||||
return request.put("app-api/promotion/article/add-browse-count?id=" + id, {}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
export function getBannerList(position) {
|
||||
return request.get("app-api/promotion/banner/list", {
|
||||
position
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得砍价活动列表
|
||||
export function getBargainActivityList(count) {
|
||||
return request.get("app-api/promotion/bargain-activity/list", {
|
||||
count
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得砍价活动详情
|
||||
export function getBargainActivityDetail(id) {
|
||||
return request.get("app-api/promotion/bargain-activity/get-detail", {
|
||||
id
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得砍价活动分页
|
||||
export function getBargainActivityPage(count) {
|
||||
return request.get("app-api/promotion/bargain-activity/page", {
|
||||
count
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得砍价记录的概要信息
|
||||
export function getBargainRecordSummary() {
|
||||
return request.get("app-api/promotion/bargain-record/get-summary", {}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得砍价记录的分页
|
||||
export function getBargainRecordPage(data) {
|
||||
return request.get("app-api/promotion/bargain-record/page", data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得砍价活动详情
|
||||
export function getBargainRecordDetail(id, activityId) {
|
||||
return request.get("app-api/promotion/bargain-record/get-detail", {
|
||||
id: id > 0 ? id : undefined,
|
||||
activityId: activityId > 0 ? activityId : undefined
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 创建砍价记录(参与拼团活动)
|
||||
export function createBargainRecord(activityId) {
|
||||
return request.post("app-api/promotion/bargain-record/create", {
|
||||
activityId
|
||||
});
|
||||
}
|
||||
|
||||
// 创建砍价助力(给拼团记录砍一刀)
|
||||
export function createBargainHelp(recordId) {
|
||||
return request.post("app-api/promotion/bargain-help/create", {
|
||||
recordId: recordId
|
||||
});
|
||||
}
|
||||
|
||||
// 获得砍价助力列表
|
||||
export function getBargainHelpList(recordId) {
|
||||
return request.get("app-api/promotion/bargain-help/list", {
|
||||
recordId: recordId
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得拼团活动列表
|
||||
export function getCombinationActivityList(count) {
|
||||
return request.get("app-api/promotion/combination-activity/list", {
|
||||
count
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得拼团活动分页
|
||||
export function getCombinationActivityPage(data) {
|
||||
return request.get("app-api/promotion/combination-activity/page", data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得拼团活动明细
|
||||
export function getCombinationActivity(id) {
|
||||
return request.get("app-api/promotion/combination-activity/get-detail", {
|
||||
id
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得最近 n 条拼团记录(团长发起的)
|
||||
export function getHeadCombinationRecordList(activityId, status, count) {
|
||||
return request.get("app-api/promotion/combination-record/get-head-list", {
|
||||
activityId,
|
||||
status,
|
||||
count
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得拼团记录明细
|
||||
export function getCombinationRecordDetail(id) {
|
||||
return request.get("app-api/promotion/combination-record/get-detail", {
|
||||
id
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得拼团记录的概要信息
|
||||
export function getCombinationRecordSummary() {
|
||||
return request.get("app-api/promotion/combination-record/get-summary", {}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 领取优惠券
|
||||
export function takeCoupon(templateId) {
|
||||
return request.post("app-api/promotion/coupon/take", {
|
||||
templateId
|
||||
});
|
||||
}
|
||||
|
||||
// 获得匹配指定商品的优惠劵列表
|
||||
export function getMatchCouponList(data) {
|
||||
return request.get("app-api/promotion/coupon/match-list", data);
|
||||
}
|
||||
|
||||
// 获得用户优惠劵列表
|
||||
export function getCouponPage(data) {
|
||||
return request.get("app-api/promotion/coupon/page", data);
|
||||
}
|
||||
|
||||
// 获得优惠劵模板分页
|
||||
export function getCouponTemplatePage(data) {
|
||||
return request.get("app-api/promotion/coupon-template/page", data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得优惠劵模板列表
|
||||
export function getCouponTemplateList(data) {
|
||||
return request.get("app-api/promotion/coupon-template/list", data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得未使用的优惠劵数量
|
||||
export function getUnusedCouponCount() {
|
||||
return request.get("app-api/promotion/coupon/get-unused-count");
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
export function getDecorateComponentListByPage(page) {
|
||||
return request.get("app-api/promotion/decorate/list", {
|
||||
page
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得秒杀时间段列表
|
||||
export function getSeckillConfigList() {
|
||||
return request.get("app-api/promotion/seckill-config/list", {}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得当前秒杀活动
|
||||
export function getNowSeckillActivity() {
|
||||
return request.get("app-api/promotion/seckill-activity/get-now", {}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得秒杀活动分页
|
||||
export function getSeckillActivityPage(data) {
|
||||
return request.get("app-api/promotion/seckill-activity/page", data, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
|
||||
// 获得秒杀活动明细
|
||||
export function getSeckillActivity(id) {
|
||||
return request.get("app-api/promotion/seckill-activity/get-detail", {
|
||||
id
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import request from "@/utils/request.js";
|
||||
import wechat from "@/libs/wechat.js";
|
||||
import {
|
||||
toLogin,
|
||||
checkLogin
|
||||
} from '../libs/login';
|
||||
/**
|
||||
* 获取微信公众号js配置
|
||||
* @returns {*}
|
||||
*/
|
||||
export function getWechatConfig() {
|
||||
return request.get("wechat/config",{ url: encodeURIComponent(wechat.signLink()) },{ noAuth: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信sdk配置
|
||||
* @returns {*}
|
||||
*/
|
||||
export function wechatAuth(code, spread) {
|
||||
var reg=/^[0-9]+.?[0-9]*$/; //判断字符串是否为数字 ,判断正整数用/^[1-9]+[0-9]*]*$/
|
||||
spread = reg.test(spread) ? spread : 0;
|
||||
return request.get(
|
||||
"wechat/authorize/login?code=" + code + "&spread_spid=" + spread, {},
|
||||
{ noAuth: true }
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录授权login
|
||||
*
|
||||
*/
|
||||
export function getLogo()
|
||||
{
|
||||
// wechat/get_logo
|
||||
return request.get('wechat/getLogo', {}, { noAuth : true});
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序用户登录
|
||||
* @param data object 小程序用户登录信息
|
||||
*/
|
||||
export function login(code,data) {
|
||||
return request.post("wechat/authorize/program/login?code="+code, data, { noAuth : true });
|
||||
}
|
||||
/**
|
||||
* 分享
|
||||
* @returns {*}
|
||||
*/
|
||||
export function getShare() {
|
||||
return request.get("share", {}, { noAuth: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取关注海报
|
||||
* @returns {*}
|
||||
*/
|
||||
export function follow() {
|
||||
return request.get("wechat/follow", {}, { noAuth: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图片base64
|
||||
* @retins {*}
|
||||
* */
|
||||
export function imageBase64(image) {
|
||||
return request.post("qrcode/base64",image,{ noAuth: true },1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动复制口令功能
|
||||
* @returns {*}
|
||||
*/
|
||||
export function copyWords() {
|
||||
return request.get("copy_words", {}, { noAuth: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页 获取客服地址
|
||||
* @returns {*}
|
||||
*/
|
||||
export function kefuConfig() {
|
||||
return request.get("config", {}, { noAuth: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信(公众号,小程序)绑定手机号
|
||||
* @param {Object} data
|
||||
*/
|
||||
export function getUserPhone(data){
|
||||
return request.post('wechat/register/binding/phone',data,{noAuth : true});
|
||||
}
|
||||
|
||||
/**
|
||||
* APP微信登录
|
||||
* @param {Object} data
|
||||
*/
|
||||
export function appAuth(data) {
|
||||
return request.post("wechat/authorize/app/login", data, { noAuth : true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 苹果登录
|
||||
* @param {Object} data
|
||||
*/
|
||||
export function appleLogin(data) {
|
||||
return request.post("ios/login", data, { noAuth : true });
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 苹果绑定手机号
|
||||
* @param {Object} data
|
||||
*/
|
||||
export function iosBinding(data) {
|
||||
return request.post("ios/binding/phone", data, { noAuth : true });
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
/**
|
||||
* 获取产品详情
|
||||
* @param int id
|
||||
*
|
||||
*/
|
||||
export function getProductDetail(id, type) {
|
||||
return request.get('product/detail/' + id + '?type=' + type, {}, {
|
||||
noAuth: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 产品分享二维码 推广员
|
||||
* @param int id
|
||||
*/
|
||||
// #ifndef MP
|
||||
export function getProductCode(id) {
|
||||
return request.get('product/code/' + id, {});
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
export function getProductCode(id) {
|
||||
return request.get('product/code/' + id, {
|
||||
user_type: 'routine'
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* 添加收藏
|
||||
* @param int id
|
||||
* @param string category product=普通产品,product_seckill=秒杀产品
|
||||
*/
|
||||
export function collectAdd(id, category) {
|
||||
return request.post('collect/add', {
|
||||
id: id,
|
||||
'category': category === undefined ? 'product' : category
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收藏产品
|
||||
* @param int id
|
||||
*/
|
||||
export function collectDel(proId) {
|
||||
return request.post(`collect/cancel/${proId}`);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除收藏产品
|
||||
* @param string id
|
||||
*/
|
||||
export function collectDelete(ids) {
|
||||
return request.post(`collect/delete`,ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 购车添加
|
||||
*
|
||||
*/
|
||||
export function postCartAdd(data) {
|
||||
return request.post('cart/save', data, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类列表
|
||||
*
|
||||
*/
|
||||
export function getCategoryList() {
|
||||
return request.get('category', {}, {
|
||||
noAuth: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取产品列表
|
||||
* @param object data
|
||||
*/
|
||||
export function getProductslist(data) {
|
||||
return request.get('products', data, {
|
||||
noAuth: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取推荐产品
|
||||
*
|
||||
*/
|
||||
export function getProductHot(page, limit) {
|
||||
return request.get("product/hot", {
|
||||
page: page === undefined ? 1 : page,
|
||||
limit: limit === undefined ? 4 : limit
|
||||
}, {
|
||||
noAuth: true
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量收藏
|
||||
*
|
||||
* @param object id 产品编号 join(',') 切割成字符串
|
||||
* @param string category
|
||||
*/
|
||||
export function collectAll(id, category) {
|
||||
return request.post('collect/all', {
|
||||
id: id,
|
||||
category: category === undefined ? 'product' : category
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页产品的轮播图和产品信息
|
||||
* @param int type
|
||||
*
|
||||
*/
|
||||
export function getGroomList(type, data) {
|
||||
return request.get('index/product/' + type, data, {
|
||||
noAuth: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收藏列表
|
||||
* @param object data
|
||||
*/
|
||||
export function getCollectUserList(data) {
|
||||
return request.get('collect/user', data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取产品评论
|
||||
* @param int id
|
||||
* @param object data
|
||||
*
|
||||
*/
|
||||
export function getReplyList(id, data) {
|
||||
return request.get('reply/list/' + id, data,{
|
||||
noAuth: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 产品评价数量和好评度
|
||||
* @param int id
|
||||
*/
|
||||
export function getReplyConfig(id) {
|
||||
return request.get('reply/config/' + id,{},{
|
||||
noAuth: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取搜索关键字获取
|
||||
*
|
||||
*/
|
||||
export function getSearchKeyword() {
|
||||
return request.get('search/keyword', {}, {
|
||||
noAuth: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 门店列表
|
||||
* @returns {*}
|
||||
*/
|
||||
export function storeListApi(data) {
|
||||
return request.post("store/list", data, {}, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 优品推荐
|
||||
* @param object data
|
||||
*/
|
||||
export function getProductGood() {
|
||||
return request.get('product/good');
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情页产品评论
|
||||
* @param int id
|
||||
* @param object data
|
||||
*
|
||||
*/
|
||||
export function getReplyProduct(id) {
|
||||
return request.get('reply/product/' + id, {
|
||||
noAuth: true
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得地区树
|
||||
export function getAreaTree() {
|
||||
return request.get("app-api/system/area/tree", {}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 根据字典类型查询字典数据信息
|
||||
export function getDicts(dictType) {
|
||||
return request.get('app-api/system/dict-data/type?type=' + dictType);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
export function getAfterSale(id) {
|
||||
return request.get("app-api/trade/after-sale/get", {
|
||||
id
|
||||
});
|
||||
}
|
||||
|
||||
export function getApplyingAfterSaleCount() {
|
||||
return request.get("app-api/trade/after-sale/get-applying-count");
|
||||
}
|
||||
|
||||
export function getAfterSalePage(data) {
|
||||
return request.get("app-api/trade/after-sale/page", data);
|
||||
}
|
||||
|
||||
export function createAfterSale(data) {
|
||||
return request.post("app-api/trade/after-sale/create", data);
|
||||
}
|
||||
|
||||
export function cancelAfterSale(id) {
|
||||
return request.delete("app-api/trade/after-sale/cancel?id=" + id);
|
||||
}
|
||||
|
||||
export function deliveryAfterSale(data) {
|
||||
return request.put("app-api/trade/after-sale/delivery", data);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得个人分销信息
|
||||
export function getBrokerageUser() {
|
||||
return request.get('app-api/trade/brokerage-user/get');
|
||||
}
|
||||
|
||||
// 获得个人分销信息
|
||||
export function bindBrokerageUser(bindUserId) {
|
||||
return request.put('app-api/trade/brokerage-user/bind', {
|
||||
bindUserId
|
||||
});
|
||||
}
|
||||
|
||||
// 获得个人分销统计
|
||||
export function getBrokerageUserSummary() {
|
||||
return request.get('app-api/trade/brokerage-user/get-summary');
|
||||
}
|
||||
|
||||
// 获得下级分销统计分页
|
||||
export function getBrokerageUserChildSummaryPage(data) {
|
||||
return request.get('app-api/trade/brokerage-user/child-summary-page', data);
|
||||
}
|
||||
|
||||
// 获得分销用户排行分页(基于用户量)
|
||||
export function getBrokerageUserRankPageByUserCount(data) {
|
||||
return request.get('app-api/trade/brokerage-user/rank-page-by-user-count', data);
|
||||
}
|
||||
|
||||
// 获得分销用户排行(基于佣金)
|
||||
export function getBrokerageUserRankByPrice(data) {
|
||||
return request.get('app-api/trade/brokerage-user/get-rank-by-price', data);
|
||||
}
|
||||
|
||||
// 获得分销用户排行分页(基于佣金)
|
||||
export function getBrokerageUserRankPageByPrice(data) {
|
||||
return request.get('app-api/trade/brokerage-user/rank-page-by-price', data);
|
||||
}
|
||||
|
||||
// 获得分销提现分页记录
|
||||
export function getBrokerageWithdrawPage(data) {
|
||||
return request.get('app-api/trade/brokerage-withdraw/page', data);
|
||||
}
|
||||
|
||||
// 创建分销提现
|
||||
export function createBrokerageWithdraw(data) {
|
||||
return request.post('app-api/trade/brokerage-withdraw/create', data);
|
||||
}
|
||||
|
||||
// 获得分销记录分页
|
||||
export function getBrokerageRecordPage(data) {
|
||||
return request.get('app-api/trade/brokerage-record/page', data);
|
||||
}
|
||||
|
||||
// 获得商品的分销金额
|
||||
export function getProductBrokeragePrice(spuId) {
|
||||
return request.get('app-api/trade/brokerage-record/get-product-brokerage-price', {
|
||||
spuId
|
||||
}, {
|
||||
noAuth: true // TODO 芋艿:后续要做调整
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
export function addCart(data) {
|
||||
return request.post("app-api/trade/cart/add", data);
|
||||
}
|
||||
|
||||
export function updateCartCount(data) {
|
||||
return request.put("app-api/trade/cart/update-count", data);
|
||||
}
|
||||
|
||||
export function updateCartSelected(data) {
|
||||
return request.put("app-api/trade/cart/update-selected", data);
|
||||
}
|
||||
|
||||
export function resetCart(data) {
|
||||
return request.put("app-api/trade/cart/reset", data);
|
||||
}
|
||||
|
||||
export function getCartCount() {
|
||||
return request.get("app-api/trade/cart/get-count");
|
||||
}
|
||||
|
||||
export function getCartCountMap() {
|
||||
return request.get("app-api/trade/cart/get-count-map");
|
||||
}
|
||||
|
||||
export function getCartList() {
|
||||
return request.get("app-api/trade/cart/list");
|
||||
}
|
||||
|
||||
export function deleteCart(ids) {
|
||||
return request.delete("app-api/trade/cart/delete?ids=" + ids.join(','));
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得交易配置
|
||||
export function getTradeConfig() {
|
||||
return request.get("app-api/trade/config/get");
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
// 获得配送配置
|
||||
export function getDeliveryConfig() {
|
||||
return request.get("app-api/trade/delivery/config/get", {});
|
||||
}
|
||||
|
||||
// 获得自提门店列表
|
||||
export function getDeliveryPickUpStoreList(data) {
|
||||
return request.get("app-api/trade/delivery/pick-up-store/list", data);
|
||||
}
|
||||
|
||||
// 获得自提门店
|
||||
export function getDeliveryPickUpStore(id) {
|
||||
return request.get("app-api/trade/delivery/pick-up-store/get", {
|
||||
id
|
||||
});
|
||||
}
|
||||
|
||||
// 获得快递公司列表
|
||||
export function getDeliveryExpressList() {
|
||||
return request.get("app-api/trade/delivery/express/list");
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
export function settlementOrder(data) {
|
||||
const data2 = {
|
||||
...data,
|
||||
}
|
||||
// 解决 SpringMVC 接受 List<Item> 参数的问题
|
||||
delete data2.items
|
||||
for (let i = 0; i < data.items.length; i++) {
|
||||
data2['items[' + i + '].skuId'] = data.items[i].skuId;
|
||||
data2['items[' + i + '].count'] = data.items[i].count;
|
||||
data2['items[' + i + '].cartId'] = data.items[i].cartId;
|
||||
}
|
||||
return request.get("app-api/trade/order/settlement", data2);
|
||||
}
|
||||
|
||||
export function createOrder(data) {
|
||||
return request.post("app-api/trade/order/create", data);
|
||||
}
|
||||
|
||||
export function getOrderDetail(id) {
|
||||
return request.get("app-api/trade/order/get-detail", {
|
||||
id
|
||||
});
|
||||
}
|
||||
|
||||
export function getOrderCount() {
|
||||
return request.get("app-api/trade/order/get-count");
|
||||
}
|
||||
|
||||
export function getOrderPage(data) {
|
||||
return request.get("app-api/trade/order/page", data);
|
||||
}
|
||||
|
||||
export function receiveOrder(id) {
|
||||
return request.put("app-api/trade/order/receive?id=" + id, {});
|
||||
}
|
||||
|
||||
export function cancelOrder(id) {
|
||||
return request.delete("app-api/trade/order/cancel?id=" + id, {});
|
||||
}
|
||||
|
||||
export function deleteOrder(id) {
|
||||
return request.delete("app-api/trade/order/delete?id=" + id, {});
|
||||
}
|
||||
|
||||
export function getOrderItem(id) {
|
||||
return request.get("app-api/trade/order/item/get", {
|
||||
id
|
||||
});
|
||||
}
|
||||
|
||||
export function createOrderItemComment(data) {
|
||||
return request.post("app-api/trade/order/item/create-comment", data);
|
||||
}
|
||||
|
||||
export function getOrderExpressTrackList(id) {
|
||||
return request.get("app-api/trade/order/get-express-track-list", {
|
||||
id
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
import request from "@/utils/request.js";
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*/
|
||||
export function getUserInfo(){
|
||||
return request.get('user');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用户分享
|
||||
*/
|
||||
export function userShare(){
|
||||
return request.post('user/share');
|
||||
}
|
||||
|
||||
/**
|
||||
* h5用户登录
|
||||
* @param data object 用户账号密码
|
||||
*/
|
||||
export function loginH5(data) {
|
||||
return request.post("login", data, { noAuth : true });
|
||||
}
|
||||
|
||||
/**
|
||||
* h5用户手机号登录
|
||||
* @param data object 用户手机号 也只能
|
||||
*/
|
||||
export function loginMobile(data) {
|
||||
return request.post("login/mobile", data, { noAuth : true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证码key
|
||||
*/
|
||||
export function getCodeApi() {
|
||||
return request.get("verify_code", {}, { noAuth: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* h5用户发送验证码
|
||||
* @param data object 用户手机号
|
||||
*/
|
||||
export function registerVerify(phone){
|
||||
return request.post('sendCode', { phone: phone },{noAuth:true},1)
|
||||
}
|
||||
|
||||
/**
|
||||
* h5用户手机号注册
|
||||
* @param data object 用户手机号 验证码 密码
|
||||
*/
|
||||
export function register(data) {
|
||||
return request.post("register", data, { noAuth : true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户手机号修改密码
|
||||
* @param data object 用户手机号 验证码 密码
|
||||
*/
|
||||
export function registerReset(data) {
|
||||
return request.post("register/reset", data, { noAuth: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户中心菜单
|
||||
*
|
||||
*/
|
||||
export function getMenuList() {
|
||||
return request.get("menu/user");
|
||||
}
|
||||
|
||||
/*
|
||||
* 签到用户信息
|
||||
* */
|
||||
export function postSignUser(sign) {
|
||||
return request.post("user/sign/user", sign);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取签到配置
|
||||
*
|
||||
*/
|
||||
export function getSignConfig(){
|
||||
return request.get('user/sign/config')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取签到列表
|
||||
* @param object data
|
||||
*/
|
||||
export function getSignList(data){
|
||||
return request.get('user/sign/list',data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户签到
|
||||
*/
|
||||
export function setSignIntegral(){
|
||||
return request.get('user/sign/integral')
|
||||
}
|
||||
|
||||
/**
|
||||
* 签到列表(年月)
|
||||
* @param object data
|
||||
*
|
||||
*/
|
||||
export function getSignMonthList(data){
|
||||
return request.get('user/sign/month',data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 活动状态
|
||||
*
|
||||
*/
|
||||
export function userActivity(){
|
||||
return request.get('user/activity');
|
||||
}
|
||||
|
||||
/*
|
||||
* 余额明细(types|2=全部,1=支出,2=收入)
|
||||
* */
|
||||
export function getCommissionInfo(data) {
|
||||
return request.get("spread/commission/detail", data);
|
||||
}
|
||||
|
||||
/*
|
||||
* 提现记录 getCountApi
|
||||
* */
|
||||
export function getRecordApi(q) {
|
||||
return request.get("extract/record", q);
|
||||
}
|
||||
|
||||
/*
|
||||
* 提现总金额
|
||||
* */
|
||||
export function getCountApi() {
|
||||
return request.get("extract/totalMoney");
|
||||
}
|
||||
|
||||
/*
|
||||
* 积分记录
|
||||
* */
|
||||
export function getIntegralList(q) {
|
||||
return request.get("integral/list", q);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分销海报图片
|
||||
*
|
||||
*/
|
||||
export function spreadBanner(data){
|
||||
return request.get('user/spread/banner',data);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 获取推广用户一级和二级
|
||||
* @param object data
|
||||
*/
|
||||
export function spreadPeople(data){
|
||||
return request.get('spread/people',data);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 推广佣金/提现总和
|
||||
* @param int type
|
||||
*/
|
||||
export function spreadCount(type){
|
||||
return request.get('spread/count/'+type);
|
||||
}
|
||||
|
||||
/*
|
||||
* 推广数据 当前佣金 提现总金额
|
||||
* */
|
||||
export function getSpreadInfo() {
|
||||
return request.get("commission");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 推广订单
|
||||
* @param object data
|
||||
*/
|
||||
export function spreadOrder(data){
|
||||
return request.get('spread/order',data);
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取推广人排行
|
||||
* */
|
||||
export function getRankList(q) {
|
||||
return request.get("rank", q);
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取佣金排名
|
||||
* */
|
||||
export function getBrokerageRank(q) {
|
||||
return request.get("brokerage_rank", q);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提现申请
|
||||
* @param object data
|
||||
*/
|
||||
export function extractCash(data){
|
||||
return request.post('extract/cash',data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 会员等级列表
|
||||
*
|
||||
*/
|
||||
export function userLevelGrade(){
|
||||
return request.get('user/level/grade');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个等级任务
|
||||
* @param int id 任务id
|
||||
*/
|
||||
export function userLevelTask(id){
|
||||
return request.get('user/level/task/'+id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否可以成为会员
|
||||
*
|
||||
*/
|
||||
export function userLevelDetection(){
|
||||
return request.get('user/level/detection');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个地址
|
||||
* @param int id
|
||||
*/
|
||||
export function getAddressDetail(id){
|
||||
return request.get('address/detail/'+id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户信息
|
||||
* @param object
|
||||
*/
|
||||
export function userEdit(data){
|
||||
return request.post('user/edit',data);
|
||||
}
|
||||
|
||||
/*
|
||||
* 退出登录
|
||||
* */
|
||||
export function getLogout() {
|
||||
return request.get("logout");
|
||||
}
|
||||
/**
|
||||
* 小程序充值
|
||||
*
|
||||
*/
|
||||
export function rechargeRoutine(data){
|
||||
return request.post('recharge/routine',data)
|
||||
}
|
||||
/*
|
||||
* 公众号充值
|
||||
* */
|
||||
export function rechargeWechat(data) {
|
||||
return request.post("recharge/wechat", data);
|
||||
}
|
||||
|
||||
/*
|
||||
* app微信充值
|
||||
* */
|
||||
export function appWechat(data) {
|
||||
return request.post("recharge/wechat/app", data);
|
||||
}
|
||||
|
||||
/*
|
||||
* 余额充值
|
||||
* */
|
||||
export function transferIn(data) {
|
||||
return request.post("recharge/transferIn", data,{},1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认地址
|
||||
*
|
||||
*/
|
||||
export function getAddressDefault(){
|
||||
return request.get('address/default');
|
||||
}
|
||||
|
||||
/**
|
||||
* 充值金额选择
|
||||
*/
|
||||
export function getRechargeApi() {
|
||||
return request.get("recharge/index");
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录记录
|
||||
*/
|
||||
export function setVisit(data)
|
||||
{
|
||||
return request.post('user/set_visit', {...data}, { noAuth:true});
|
||||
}
|
||||
|
||||
/**
|
||||
* 客服列表
|
||||
*/
|
||||
export function serviceList() {
|
||||
return request.get("user/service/lst");
|
||||
}
|
||||
/**
|
||||
* 客服详情
|
||||
*/
|
||||
export function getChatRecord(to_uid, data) {
|
||||
return request.get("user/service/record/" + to_uid, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 静默绑定推广人
|
||||
* @param {Object} puid
|
||||
*/
|
||||
export function spread(puid)
|
||||
{
|
||||
return request.get("user/bindSpread?spreadPid="+ puid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前用户在佣金排行第几名
|
||||
*
|
||||
*/
|
||||
export function brokerageRankNumber(data)
|
||||
{
|
||||
return request.get("user/brokerageRankNumber",data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 会员等级经验值;
|
||||
*
|
||||
*/
|
||||
export function getlevelInfo()
|
||||
{
|
||||
return request.get("user/level/grade");
|
||||
}
|
||||
|
||||
/**
|
||||
* 经验值明细;
|
||||
*
|
||||
*/
|
||||
export function getlevelExpList(data)
|
||||
{
|
||||
return request.get("user/expList",data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 经验值明细;
|
||||
*
|
||||
*/
|
||||
export function getuserDalance()
|
||||
{
|
||||
return request.get("user/balance");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 账单记录;
|
||||
*
|
||||
*/
|
||||
export function getBillList(data)
|
||||
{
|
||||
return request.get("recharge/bill/record",data);
|
||||
}
|
||||
|
||||
/*
|
||||
* 积分中心详情
|
||||
* */
|
||||
export function postIntegralUser() {
|
||||
return request.get("integral/user");
|
||||
}
|
||||
|
||||
/*
|
||||
* 立即提现 冻结期、冻结佣金、可提现佣金、最低可提现金额
|
||||
* */
|
||||
export function extractUser() {
|
||||
return request.get("extract/user");
|
||||
}
|
||||
|
||||
/*
|
||||
* 推广人统计页 推广人数(一级+二级)、一级人数、二级人数
|
||||
* */
|
||||
export function spreadPeoCount() {
|
||||
return request.get("spread/people/count");
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class='Popup' v-if='isShowAuth'>
|
||||
<image :src='logoUrl'></image>
|
||||
<view class='title'>授权提醒</view>
|
||||
<view class='tip'>请授权头像等信息,以便为您提供更好的服务</view>
|
||||
<view class='bottom flex'>
|
||||
<view class='item' @click='close'>随便逛逛</view>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<button class='item grant' @click="setUserInfo">去授权</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP -->
|
||||
<button class='item grant' type="primary" open-type="getUserInfo" lang="zh_CN" @getuserinfo="setUserInfo">去授权</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
<view class='mask' v-if='isShowAuth' @click='close'></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const app = getApp();
|
||||
import Cache from '../utils/cache';
|
||||
import { getLogo } from '../api/public';
|
||||
import { LOGO_URL } from '../config/cache';
|
||||
import { mapGetters } from 'vuex';
|
||||
import Routine from '../libs/routine';
|
||||
|
||||
export default {
|
||||
name:'Authorize',
|
||||
props:{
|
||||
isAuto:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
isGoIndex:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
isShowAuth:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
logoUrl:''
|
||||
}
|
||||
},
|
||||
computed:mapGetters(['isLogin','userInfo']),
|
||||
watch:{
|
||||
isLogin(n){
|
||||
n === true && this.$emit('onLoadFun',this.userInfo);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getLogoUrl();
|
||||
this.setAuthStatus();
|
||||
},
|
||||
methods:{
|
||||
setAuthStatus(){
|
||||
Routine.authorize().then(res=>{
|
||||
if(res.islogin === false)
|
||||
this.setUserInfo();
|
||||
else
|
||||
this.$emit('onLoadFun',this.userInfo);
|
||||
}).catch(res=>{
|
||||
if (this.isAuto)
|
||||
this.$emit('authColse',true);
|
||||
})
|
||||
},
|
||||
getUserInfo(code){
|
||||
Routine.getUserInfo().then(res=>{
|
||||
let userInfo = res.userInfo
|
||||
userInfo.code = code;
|
||||
userInfo.spread_spid = app.globalData.spid;//获取推广人ID
|
||||
userInfo.spread_code = app.globalData.code;//获取推广人分享二维码ID
|
||||
userInfo.avatar = userInfo.userInfo.avatarUrl;
|
||||
userInfo.city = userInfo.userInfo.city;
|
||||
userInfo.country = userInfo.userInfo.country;
|
||||
userInfo.nickName = userInfo.userInfo.nickName;
|
||||
userInfo.province = userInfo.userInfo.province;
|
||||
userInfo.sex = userInfo.userInfo.gender;
|
||||
Routine.authUserInfo(code,userInfo).then(res=>{
|
||||
uni.hideLoading();
|
||||
this.$emit('authColse',false);
|
||||
this.$emit('onLoadFun',this.userInfo);
|
||||
}).catch(res=>{
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title:res.message,
|
||||
icon:'none',
|
||||
duration:2000
|
||||
});
|
||||
})
|
||||
}).catch(res =>{
|
||||
uni.hideLoading();
|
||||
})
|
||||
},
|
||||
setUserInfo(){
|
||||
uni.showLoading({title:'正在登录中'});
|
||||
Routine.getCode().then(code=>{
|
||||
this.getUserInfo(code);
|
||||
}).catch(res=>{
|
||||
uni.hideLoading();
|
||||
})
|
||||
},
|
||||
getLogoUrl(){
|
||||
let that = this;
|
||||
if (Cache.has(LOGO_URL)) {
|
||||
this.logoUrl = Cache.get(LOGO_URL);
|
||||
return;
|
||||
}
|
||||
getLogo().then(res=>{
|
||||
that.logoUrl = res.data.logoUrl
|
||||
Cache.set(LOGO_URL,that.logoUrl);
|
||||
})
|
||||
},
|
||||
close(){
|
||||
let pages = getCurrentPages(), currPage = pages[pages.length - 1];
|
||||
if(this.isGoIndex){
|
||||
uni.switchTab({url:'/pages/index/index'});
|
||||
} else {
|
||||
this.$emit('authColse',false);
|
||||
}
|
||||
// if (currPage && currPage.isShowAuth != undefined){
|
||||
// currPage.isShowAuth = true;
|
||||
// }
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.Popup{width:500rpx;background-color:#fff;position:fixed;top:50%;left:50%;margin-left:-250rpx;transform:translateY(-50%);z-index:320;}
|
||||
.Popup image{width:150rpx;height:150rpx;margin:-67rpx auto 0 auto;display:block;border: 8rpx solid #fff;border-radius: 50%}
|
||||
.Popup .title{font-size:28rpx;color:#000;text-align:center;margin-top: 30rpx}
|
||||
.Popup .tip{font-size:22rpx;color:#555;padding:0 24rpx;margin-top:25rpx;}
|
||||
.Popup .bottom .item{width:50%;height:80rpx;background-color:#eeeeee;text-align:center;line-height:80rpx;font-size:24rpx;color:#666;margin-top:54rpx;}
|
||||
.Popup .bottom .item.on{width: 100%}
|
||||
.flex{display:flex;}
|
||||
.Popup .bottom .item.grant{font-size:28rpx;color:#fff;font-weight:bold;background-color:$theme-color;border-radius:0;padding:0;}
|
||||
.mask{position:fixed;top:0;right:0;left:0;bottom:0;background-color:rgba(0,0,0,0.65);z-index:310;}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="Loads acea-row row-center-wrapper" v-if="loading && !loaded" style="margin-top: .2rem;">
|
||||
<view v-if="loading">
|
||||
<view class="iconfont icon-jiazai loading acea-row row-center-wrapper"></view>
|
||||
正在加载中
|
||||
</view>
|
||||
<view v-else>
|
||||
上拉加载更多
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Loading",
|
||||
props: {
|
||||
loaded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.Loads {
|
||||
height: 80upx;
|
||||
font-size: 25upx;
|
||||
color: #000;
|
||||
}
|
||||
.Loads .iconfont {
|
||||
font-size: 30upx;
|
||||
margin-right: 10upx;
|
||||
height: 32upx;
|
||||
line-height: 32upx;
|
||||
}
|
||||
/*加载动画*/
|
||||
@keyframes load {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.loadingpic {
|
||||
animation: load 3s linear 1s infinite;
|
||||
}
|
||||
.loading {
|
||||
animation: load linear 1s infinite;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="address-window" :class="address.address ? 'on' : ''">
|
||||
<view class='title'>选择地址<text class='iconfont icon-guanbi' @tap='close'></text></view>
|
||||
<view class='list'>
|
||||
<view class='item acea-row row-between-wrapper' :class='active === index?"font-color":""'
|
||||
v-for="(item,index) in addressList" @tap='tapAddress(index,item.id)' :key='index'>
|
||||
<text class='iconfont icon-ditu' :class='active===index?"font-color":""' />
|
||||
<view class='address'>
|
||||
<view class='name' :class='active==index?"font-color":""'>
|
||||
{{ item.name }}
|
||||
<text class='phone'>{{ item.mobile }}</text>
|
||||
</view>
|
||||
<view class='line1'>{{ item.areaName }} {{ item.detailAddress }}</view>
|
||||
</view>
|
||||
<text class='iconfont icon-complete' :class='active === index?"font-color":""' />
|
||||
</view>
|
||||
</view>
|
||||
<!-- 无地址 -->
|
||||
<view class='pictrue' v-if="!is_loading && !addressList.length">
|
||||
<image src='../../static/images/noAddress.png'></image>
|
||||
</view>
|
||||
<view class='addressBnt bg-color' @tap='goAddressPages'>选择其地址</view>
|
||||
</view>
|
||||
<view class='mask' catchtouchmove="true" :hidden='!address.address' @tap='close' />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as AddressApi from '@/api/member/address.js';
|
||||
export default {
|
||||
props: {
|
||||
pagesUrl: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
address: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
address: true, // 是否打开
|
||||
addressId: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
isLog: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: 0, // 激活的 addressList 下标
|
||||
is_loading: true,
|
||||
addressList: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 选中某个地址
|
||||
*/
|
||||
tapAddress: function(e, addressid) {
|
||||
this.active = e;
|
||||
for (let i = 0; i < this.addressList.length; i++) {
|
||||
if (this.addressList[i].id === addressid) {
|
||||
this.$emit('OnChangeAddress', this.addressList[i]);
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
close: function() {
|
||||
this.$emit('changeClose');
|
||||
},
|
||||
goAddressPages: function() {
|
||||
this.$emit('changeClose');
|
||||
uni.navigateTo({
|
||||
url: this.pagesUrl
|
||||
});
|
||||
},
|
||||
getAddressList: function() {
|
||||
AddressApi.getAddressList().then(res => {
|
||||
const addressList = res.data;
|
||||
this.$set(this, 'addressList', addressList);
|
||||
this.is_loading = false;
|
||||
// 处理默认选中项
|
||||
if (!this.address.addressId) {
|
||||
return;
|
||||
}
|
||||
let defaultAddress = {};
|
||||
for (let i = 0; i < addressList.length; i++) {
|
||||
if (addressList[i].id === this.address.addressId) {
|
||||
this.active = i;
|
||||
defaultAddress = this.addressList[i];
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.address-window {
|
||||
background-color: #fff;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 101;
|
||||
transform: translate3d(0, 100%, 0);
|
||||
transition: all .3s cubic-bezier(.25, .5, .5, .9);
|
||||
}
|
||||
|
||||
.address-window.on {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
.address-window .title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
height: 123rpx;
|
||||
line-height: 123rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.address-window .title .iconfont {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
color: #8a8a8a;
|
||||
font-size: 35rpx;
|
||||
}
|
||||
|
||||
.address-window .list .item {
|
||||
margin-left: 30rpx;
|
||||
padding-right: 30rpx;
|
||||
border-bottom: 1px solid #eee;
|
||||
height: 129rpx;
|
||||
font-size: 25rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.address-window .list .item .iconfont {
|
||||
font-size: 37rpx;
|
||||
color: #2c2c2c;
|
||||
}
|
||||
|
||||
.address-window .list .item .iconfont.icon-complete {
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.address-window .list .item .address {
|
||||
width: 560rpx;
|
||||
}
|
||||
|
||||
.address-window .list .item .address .name {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #282828;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.address-window .list .item .address .name .phone {
|
||||
margin-left: 18rpx;
|
||||
}
|
||||
|
||||
.address-window .addressBnt {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
width: 690rpx;
|
||||
height: 86rpx;
|
||||
border-radius: 43rpx;
|
||||
text-align: center;
|
||||
line-height: 86rpx;
|
||||
margin: 85rpx auto;
|
||||
}
|
||||
|
||||
.address-window .pictrue {
|
||||
width: 414rpx;
|
||||
height: 336rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.address-window .pictrue image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -1,20 +1,13 @@
|
||||
<template>
|
||||
<view class="time" :style="justifyLeft">
|
||||
<text class="" v-if="tipText">{{ tipText }}</text>
|
||||
<text class="styleAll p6" v-if="isDay === true"
|
||||
:style="{background:bgColor.bgColor,color:bgColor.Color}">{{ day }}{{bgColor.isDay?'天':''}}</text>
|
||||
<text class="timeTxt" v-if="dayText"
|
||||
:style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ dayText }}</text>
|
||||
<text class="styleAll" :class='isCol?"timeCol":""'
|
||||
:style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ hour }}</text>
|
||||
<text class="timeTxt" v-if="hourText" :class='isCol?"whit":""'
|
||||
:style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ hourText }}</text>
|
||||
<text class="styleAll" :class='isCol?"timeCol":""'
|
||||
:style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ minute }}</text>
|
||||
<text class="timeTxt" v-if="minuteText" :class='isCol?"whit":""'
|
||||
:style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ minuteText }}</text>
|
||||
<text class="styleAll" :class='isCol?"timeCol":""'
|
||||
:style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ second }}</text>
|
||||
<text class="styleAll p6" v-if="isDay === true" :style="{background:bgColor.bgColor,color:bgColor.Color}">{{ day }}{{bgColor.isDay?'天':''}}</text>
|
||||
<text class="timeTxt" v-if="dayText" :style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ dayText }}</text>
|
||||
<text class="styleAll" :class='isCol?"timeCol":""' :style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ hour }}</text>
|
||||
<text class="timeTxt" v-if="hourText" :class='isCol?"whit":""' :style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ hourText }}</text>
|
||||
<text class="styleAll" :class='isCol?"timeCol":""' :style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ minute }}</text>
|
||||
<text class="timeTxt" v-if="minuteText" :class='isCol?"whit":""' :style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ minuteText }}</text>
|
||||
<text class="styleAll" :class='isCol?"timeCol":""' :style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ second }}</text>
|
||||
<text class="timeTxt" v-if="secondText">{{ secondText }}</text>
|
||||
</view>
|
||||
</template>
|
||||
@@ -124,11 +117,10 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.p6 {
|
||||
.p6{
|
||||
padding: 0 8rpx;
|
||||
}
|
||||
|
||||
.styleAll {
|
||||
.styleAll{
|
||||
/* color: #fff; */
|
||||
font-size: 24rpx;
|
||||
height: 36rpx;
|
||||
@@ -137,19 +129,16 @@
|
||||
text-align: center;
|
||||
/* padding: 0 6rpx; */
|
||||
}
|
||||
|
||||
.timeTxt {
|
||||
text-align: center;
|
||||
/* width: 16rpx; */
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
display: inline-block;
|
||||
.timeTxt{
|
||||
text-align: center;
|
||||
/* width: 16rpx; */
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.whit {
|
||||
.whit{
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.time {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@@ -170,4 +159,4 @@
|
||||
font-size: 24rpx; */
|
||||
color: #E93323;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -0,0 +1,247 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class='coupon-list-window' :class='coupon.coupon === true?"on":""'>
|
||||
<view v-if="!orderShow" class="nav acea-row row-around">
|
||||
<view :class="['acea-row', 'row-middle', type === 1 ? 'on' : '']" @click="setType(1)">通用券</view>
|
||||
<view :class="['acea-row', 'row-middle', type === 2 ? 'on' : '']" @click="setType(2)">商品券</view>
|
||||
<view :class="['acea-row', 'row-middle', type === 3 ? 'on' : '']" @click="setType(3)">品类券</view>
|
||||
</view>
|
||||
<view class='coupon-list' :style="{'margin-top':!orderShow?'0':'50rpx'}">
|
||||
<block v-if="coupon.list.length">
|
||||
<view class='item acea-row row-center-wrapper' v-for="(item,index) in coupon.list"
|
||||
@click="getCouponUser(index, item.id)" :key='index'>
|
||||
<!-- 金额 -->
|
||||
<view class='money acea-row row-column row-center-wrapper' :class='item.canTake ? "" : "moneyGray"'>
|
||||
<view>¥
|
||||
<text v-if="item.discountType === 1" class='num'>{{ fen2yuan(item.discountPrice) }}</text>
|
||||
<text v-else class='num'>{{ (item.discountPercent / 10.0).toFixed(1) }} 折</text>
|
||||
</view>
|
||||
<view class="pic-num">满 {{ fen2yuan(item.usePrice) }} 元可用</view>
|
||||
</view>
|
||||
<view class='text'>
|
||||
<!-- 类型 -->
|
||||
<view class='condition line2'>
|
||||
<span class='line-title' :class='item.isUse?"gray":""' v-if='type === 1'>通用</span>
|
||||
<span class='line-title' :class='item.isUse?"gray":""'
|
||||
v-else-if='type === 3'>品类</span>
|
||||
<span class='line-title' :class='item.isUse?"gray":""' v-else>商品</span>
|
||||
<span>{{item.name}}</span>
|
||||
</view>
|
||||
<!-- 领取类型 -->
|
||||
<view class='data acea-row row-between-wrapper'>
|
||||
<view v-if="item.validityType > 1">领取后 {{ item.fixedEndTerm }} 天内可用</view>
|
||||
<view v-else>
|
||||
{{ formatDate(item.validStartTime) + " - " + formatDate(item.validEndTime) }}
|
||||
</view>
|
||||
<view class='bnt bg-color' v-if="item.canTake">{{coupon.statusTile || '立即领取'}}</view>
|
||||
<view class='bnt gray' v-else>{{item.use_title || '已领取'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 无优惠券 -->
|
||||
<view class='pictrue' v-else>
|
||||
<image src='../../static/images/noCoupon.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='mask' catchtouchmove="true" :hidden='!coupon.coupon' @click='close'></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Util from '@/utils/util.js';
|
||||
import dayjs from "@/plugin/dayjs/dayjs.min.js";
|
||||
import * as CouponApi from '@/api/promotion/coupon.js';
|
||||
export default {
|
||||
props: {
|
||||
openType: {
|
||||
type: Number, // 打开状态 0=领取优惠券, 1=使用优惠券
|
||||
default: 0,
|
||||
},
|
||||
coupon: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
orderShow: {
|
||||
type: String, // 下单页面使用优惠券组件不展示 tab 切换页
|
||||
default: function() {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
type: 1 // 使用类型
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
close: function() {
|
||||
this.type = 1
|
||||
this.$emit('ChangCouponsClose');
|
||||
},
|
||||
/**
|
||||
* 选择优惠劵
|
||||
*/
|
||||
getCouponUser: function(index, id) {
|
||||
// 领取优惠劵时,如果已经领取,则直接跳过
|
||||
let list = this.coupon.list;
|
||||
switch (this.openType) {
|
||||
case 0: // 领取优惠券
|
||||
if (!list[index].canTake) {
|
||||
return;
|
||||
}
|
||||
CouponApi.takeCoupon(id).then(res => {
|
||||
this.$util.Tips({
|
||||
title: "领取成功"
|
||||
});
|
||||
this.$emit('ChangCoupons', list[index]);
|
||||
})
|
||||
break;
|
||||
case 1: // 使用优惠劵
|
||||
// TODO 芋艿:需要额外把不可用优惠劵的样式做了;
|
||||
if (list[index].match === false) {
|
||||
alert('该优惠劵无法使用,原因:' + list[index].description);
|
||||
return;
|
||||
}
|
||||
this.$emit('ChangCoupons', index);
|
||||
break;
|
||||
}
|
||||
},
|
||||
setType: function(type) {
|
||||
this.type = type;
|
||||
this.$emit('tabCouponType', type);
|
||||
},
|
||||
|
||||
fen2yuan(price) {
|
||||
return Util.fen2yuan(price)
|
||||
},
|
||||
formatDate: function(date) {
|
||||
return dayjs(date).format("YYYY-MM-DD");
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.coupon-list-window {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
z-index: 555;
|
||||
transform: translate3d(0, 100%, 0);
|
||||
transition: all .3s cubic-bezier(.25, .5, .5, .9);
|
||||
}
|
||||
|
||||
.coupon-list-window.on {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
.coupon-list-window .title {
|
||||
height: 124rpx;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
line-height: 124rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.coupon-list-window .title .iconfont {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 35rpx;
|
||||
color: #8a8a8a;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.coupon-list-window .coupon-list {
|
||||
margin: 0 0 30rpx 0;
|
||||
height: 823rpx;
|
||||
overflow: auto;
|
||||
padding-top: 30rpx;
|
||||
}
|
||||
|
||||
.coupon-list-window .pictrue {
|
||||
width: 414rpx;
|
||||
height: 336rpx;
|
||||
margin: 208rpx auto;
|
||||
}
|
||||
|
||||
.coupon-list-window .pictrue image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.pic-num {
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.line-title {
|
||||
width: 90rpx;
|
||||
padding: 0 10rpx;
|
||||
box-sizing: border-box;
|
||||
background: rgba(255, 247, 247, 1);
|
||||
border: 1px solid rgba(232, 51, 35, 1);
|
||||
opacity: 1;
|
||||
border-radius: 20rpx;
|
||||
font-size: 20rpx;
|
||||
color: #E83323;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.line-title.gray {
|
||||
border-color: #BBB;
|
||||
color: #bbb;
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.nav {
|
||||
// position: absolute;
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
width: 100%;
|
||||
height: 96rpx;
|
||||
border-bottom: 2rpx solid #F5F5F5;
|
||||
border-top-left-radius: 16rpx;
|
||||
border-top-right-radius: 16rpx;
|
||||
background-color: #FFFFFF;
|
||||
font-size: 30rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.nav .acea-row {
|
||||
border-top: 5rpx solid transparent;
|
||||
border-bottom: 5rpx solid transparent;
|
||||
}
|
||||
|
||||
.nav .acea-row.on {
|
||||
border-bottom-color: #E93323;
|
||||
color: #282828;
|
||||
}
|
||||
|
||||
.nav .acea-row:only-child {
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
.occupy {
|
||||
height: 106rpx;
|
||||
}
|
||||
|
||||
.coupon-list .item {
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.coupon-list .item .money {
|
||||
font-weight: normal;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class='coupon-window' :class='window==true?"on":""'>
|
||||
<view class='couponWinList'>
|
||||
<view class='item acea-row row-between-wrapper' v-for="(item,index) in couponList" :key="index">
|
||||
<view class='money font-color'>¥<text class='num'>{{ item.money?Number(item.money):'' }}</text></view>
|
||||
<view class='text'>
|
||||
<view class='name'>购物买{{item.minPrice}}减{{item.money}}</view>
|
||||
<view v-if="item.day>0">领取后{{item.day}}天内可用</view>
|
||||
<view v-else>{{item.useStartTimeStr&&item.useEndTimeStr ? item.useStartTimeStr+'~'+item.useEndTimeStr : ''}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='lid'>
|
||||
<navigator hover-class='none' url='/pages/users/user_get_coupon/index' class='bnt font-color'>立即领取</navigator>
|
||||
<view class='iconfont icon-guanbi3' @click="close"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='mask' catchtouchmove="true" :hidden="window==false"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
props: {
|
||||
window: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
couponList: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return []
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
close:function(){
|
||||
this.$emit('onColse');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mask{
|
||||
z-index: 999;
|
||||
}
|
||||
.coupon-window {
|
||||
background-image: url('data:image/png;base64,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 truncated
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 630rpx;
|
||||
height: 649rpx;
|
||||
position: fixed;
|
||||
top: 20%;
|
||||
z-index: 1000;
|
||||
left: 50%;
|
||||
margin-left: -305rpx;
|
||||
transform: translate3d(0, -200%, 0);
|
||||
transition: all .3s cubic-bezier(.25, .5, .5, .9);
|
||||
}
|
||||
|
||||
.coupon-window.on {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
.coupon-window .couponWinList {
|
||||
width: 480rpx;
|
||||
margin: 157rpx 0 0 60rpx;
|
||||
height: 415rpx;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.coupon-window .couponWinList .item {
|
||||
width: 100%;
|
||||
height: 120rpx;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
margin-bottom: 17rpx;
|
||||
}
|
||||
|
||||
.coupon-window .couponWinList .item::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #f2443a;
|
||||
left: 25.5%;
|
||||
bottom: 0;
|
||||
margin-bottom: -9rpx;
|
||||
}
|
||||
|
||||
.coupon-window .couponWinList .item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #f2443a;
|
||||
left: 25.5%;
|
||||
top: 0;
|
||||
margin-top: -9rpx;
|
||||
}
|
||||
|
||||
.coupon-window .couponWinList .item .money {
|
||||
width: 130rpx;
|
||||
border-right: 1px dashed #ddd;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
line-height: 120rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.coupon-window .couponWinList .item .money .num {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.coupon-window .couponWinList .item .text {
|
||||
width: 349rpx;
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
padding: 0 29rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.coupon-window .couponWinList .item .text .name {
|
||||
font-size: 26rpx;
|
||||
color: #282828;
|
||||
font-weight: bold;
|
||||
margin-bottom: 9rpx;
|
||||
}
|
||||
|
||||
.coupon-window .lid {
|
||||
background-image: url('data:image/png;base64,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');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 573rpx;
|
||||
height: 224rpx;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 20%;
|
||||
margin: 424rpx 0 0 -296rpx;
|
||||
}
|
||||
|
||||
.coupon-window .lid .bnt {
|
||||
font-size: 29rpx;
|
||||
width: 440rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #f9f1d3;
|
||||
text-align: center;
|
||||
line-height: 80rpx;
|
||||
font-weight: bold;
|
||||
margin: 98rpx auto 0 auto;
|
||||
}
|
||||
|
||||
.coupon-window .lid .iconfont {
|
||||
color: #fff;
|
||||
font-size: 60rpx;
|
||||
text-align: center;
|
||||
margin-top: 87rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="upload">
|
||||
<block v-for="(upload,index) in uploads" :key="index">
|
||||
<view class="uplode-file">
|
||||
<image v-if="types == 'image'" class="uploade-img" :src="upload" :data-src="upload" @tap="previewImage"></image>
|
||||
<image v-if="types == 'image'" class="clear-one-icon" :src="clearIcon" @tap="delImage(index)"></image>
|
||||
<video v-if="types == 'video'" class="uploade-img" :src="upload" controls>
|
||||
<cover-image v-if="types == 'video'" class="clear-one-icon" :src="clearIcon" @tap="delImage(index)"></cover-image>
|
||||
</video>
|
||||
</view>
|
||||
</block>
|
||||
<view class="uploader-input-box" v-if="uploads.length < uploadCount">
|
||||
<view class="uploader-input" @tap="chooseUploads"></view>
|
||||
</view>
|
||||
</view>
|
||||
<button type="primary" v-if="types == 'image'" @tap="upload">上传</button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
props: {
|
||||
types: {
|
||||
type: String,
|
||||
default: 'image'
|
||||
},
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
clearIcon: {
|
||||
type: String,
|
||||
default: 'http://img1.imgtn.bdimg.com/it/u=451604666,2295832001&fm=26&gp=0.jpg'
|
||||
},
|
||||
uploadUrl: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
deleteUrl: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
uploadCount: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
//上传图片大小 默认3M
|
||||
upload_max: {
|
||||
type: Number,
|
||||
default: 3
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
//上传的图片地址
|
||||
uploadImages: [],
|
||||
//展示的图片地址
|
||||
uploads: [],
|
||||
// 超出限制数组
|
||||
exceeded_list: [],
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
dataList() {
|
||||
this.uploads = this.dataList
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
previewImage (e) {
|
||||
var current = e.target.dataset.src
|
||||
uni.previewImage({
|
||||
current: current,
|
||||
urls: this.dataList
|
||||
})
|
||||
},
|
||||
chooseUploads(){
|
||||
switch (this.types){
|
||||
case 'image':
|
||||
uni.chooseImage({
|
||||
count: this.uploadCount - this.uploads.length, //默认9
|
||||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], //从相册选择
|
||||
success: (res) => {
|
||||
for(let i = 0; i< res.tempFiles.length; i++){
|
||||
if(Math.ceil(res.tempFiles[i].size / 1024) < this.upload_max * 1024){
|
||||
this.uploads.push(res.tempFiles[i].path)
|
||||
this.uploadImages.push(res.tempFiles[i].path)
|
||||
}else {
|
||||
this.exceeded_list.push(i === 0 ? 1 : i + 1);
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: `第${[...new Set(this.exceeded_list)].join(',')}张图片超出限制${this.upload_max}MB,已过滤`
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(err)
|
||||
});
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'video' :
|
||||
uni.chooseVideo({
|
||||
sourceType: ['camera', 'album'],
|
||||
success: (res) => {
|
||||
if(Math.ceil(res.size / 1024) < this.upload_max * 1024){
|
||||
this.uploads.push(res.tempFilePath)
|
||||
uni.uploadFile({
|
||||
url: this.uploadUrl, //仅为示例,非真实的接口地址
|
||||
filePath: res.tempFilePath,
|
||||
name: 'file',
|
||||
//请求参数
|
||||
formData: {
|
||||
'user': 'test'
|
||||
},
|
||||
success: (uploadFileRes) => {
|
||||
this.$emit('successVideo',uploadFileRes)
|
||||
}
|
||||
});
|
||||
}else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: `第${[...new Set(this.exceeded_list)].join(',')}张视频超出限制${this.upload_max}MB,已过滤`
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(err)
|
||||
});
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
delImage(index){
|
||||
if(this.uploads[index].substring(0,4) !== 'http'){
|
||||
this.uploads.splice(index,1)
|
||||
return;
|
||||
};
|
||||
if(!this.deleteUrl) {
|
||||
uni.showModal({
|
||||
content: '请填写删除接口'
|
||||
});
|
||||
return;
|
||||
};
|
||||
uni.request({
|
||||
url: this.deleteUrl,
|
||||
method: 'DELETE',
|
||||
data: {
|
||||
image: this.dataList[index]
|
||||
},
|
||||
success: res => {
|
||||
this.uploads.splice(index,1)
|
||||
},
|
||||
});
|
||||
},
|
||||
upload(){
|
||||
if(!this.uploadUrl) {
|
||||
uni.showModal({
|
||||
content: '请填写上传接口'
|
||||
});
|
||||
return;
|
||||
};
|
||||
for (let i of this.uploadImages) {
|
||||
uni.uploadFile({
|
||||
url: this.uploadUrl, //仅为示例,非真实的接口地址
|
||||
filePath: i,
|
||||
name: 'file',
|
||||
//请求参数
|
||||
formData: {
|
||||
'user': 'test'
|
||||
},
|
||||
success: (uploadFileRes) => {
|
||||
this.$emit('successImage',uploadFileRes)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.upload {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.uplode-file {
|
||||
margin: 10upx;
|
||||
width: 210upx;
|
||||
height: 210upx;
|
||||
position: relative;
|
||||
}
|
||||
.uploade-img {
|
||||
display: block;
|
||||
width: 210upx;
|
||||
height: 210upx;
|
||||
}
|
||||
.clear-one{
|
||||
position: absolute;
|
||||
top: -10rpx;
|
||||
right: 0;
|
||||
}
|
||||
.clear-one-icon{
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
.uploader-input-box {
|
||||
position: relative;
|
||||
margin:10upx;
|
||||
width: 208upx;
|
||||
height: 208upx;
|
||||
border: 2upx solid #D9D9D9;
|
||||
}
|
||||
.uploader-input-box:before,
|
||||
.uploader-input-box:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: #D9D9D9;
|
||||
}
|
||||
.uploader-input-box:before {
|
||||
width: 4upx;
|
||||
height: 79upx;
|
||||
}
|
||||
.uploader-input-box:after {
|
||||
width: 79upx;
|
||||
height: 4upx;
|
||||
}
|
||||
.uploader-input-box:active {
|
||||
border-color: #999999;
|
||||
}
|
||||
.uploader-input-box:active:before,
|
||||
.uploader-input-box:active:after {
|
||||
background-color: #999999;
|
||||
}
|
||||
.uploader-input {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,40 @@
|
||||
### easy-upload 组件
|
||||
|
||||
使用方法
|
||||
```js
|
||||
<easy-upload
|
||||
:dataList="imageList" uploadUrl="http://localhost:3000/upload" :types="category"
|
||||
deleteUrl='http://localhost:3000/upload' :uploadCount="6"
|
||||
@successImage="successImage" @successVideo="successvideo"
|
||||
></easy-upload>
|
||||
|
||||
//先引入组件
|
||||
import easyUpload from '@/components/easy-upload/easy-upload.vue'
|
||||
//注册组件
|
||||
components:{
|
||||
easyUpload
|
||||
}
|
||||
|
||||
//使用 easycom 可以直接使用
|
||||
|
||||
```
|
||||
|
||||
| 参数 | 类型 | 是否必填 | 参数描述
|
||||
| ---- | ---- | ---- | ----
|
||||
| types | String | 否 | 上传类型 image/video
|
||||
| dataList | Array | 否 | 图片/视频数据展示
|
||||
| clearIcon | String | 否 | 删除图标(可以换成自己本地图片)
|
||||
| uploadUrl | String | 否 | 上传的接口
|
||||
| deleteUrl | String | 否 | 删除的接口
|
||||
| uploadCount | Number | 否 | 上传图片最大个数(默认为一张)
|
||||
| upload_max | Number | 否 | 上传大小(默认为3M)
|
||||
| upload_max | Number | 否 | 上传大小(默认为3M)
|
||||
| upload_max | Number | 否 | 上传大小(默认为3M)
|
||||
|
||||
| 事件 | 是否必填 | 参数描述
|
||||
| ---- | ---- | ----
|
||||
| successImage | 否 | 上传图片成功事件
|
||||
| successVideo | 否 | 上传视频成功回调
|
||||
|
||||
示例项目中有服务端代码 (node.js)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<view class="empty-box">
|
||||
<image src="../static/images/empty-box.png"></image>
|
||||
<view class="txt">{{title}}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '暂无记录',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.empty-box{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 200rpx;
|
||||
padding-bottom: 60rpx;
|
||||
image{
|
||||
width: 414rpx;
|
||||
height: 240rpx;
|
||||
}
|
||||
.txt{
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<view class='goodList'>
|
||||
<block v-for="(item,index) in bastList" :key="index">
|
||||
<view @click="goDetail(item)" class='item acea-row row-between-wrapper' hover-class="none">
|
||||
<view class='pictrue'>
|
||||
<image :src='item.picUrl'></image>
|
||||
<span class="pictrue_log pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 1">秒杀</span>
|
||||
<span class="pictrue_log pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 2">砍价</span>
|
||||
<span class="pictrue_log pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 3">拼团</span>
|
||||
</view>
|
||||
<view class='underline'>
|
||||
<view class='text'>
|
||||
<view class='line1'>{{ item.name }}</view>
|
||||
<view class='money font-color'>¥<text class='num'>{{ fen2yuan(item.price) }}</text></view>
|
||||
<view class='vip-money acea-row row-middle' v-if="item.vipPrice > 0">¥{{ fen2yuan(item.price - item.vipPrice) }}
|
||||
<image src='../../static/images/vip.png'></image><text class='num'>已售{{ item.salesCount }}{{item.unitName}}</text>
|
||||
</view>
|
||||
<view class='vip-money acea-row row-middle' v-else><text class='num'>已售{{ item.salesCount }}{{item.unitName}}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='iconfont icon-gouwuche cart-color acea-row row-center-wrapper'></view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import { goShopDetail } from '@/libs/order.js'
|
||||
import * as Util from '@/utils/util.js';
|
||||
export default {
|
||||
computed: mapGetters(['uid']),
|
||||
props: {
|
||||
status: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
bastList: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goDetail(item) {
|
||||
goShopDetail(item,this.uid).then(() =>{
|
||||
uni.navigateTo({
|
||||
url:`/pages/goods_details/index?id=${item.id}`
|
||||
})
|
||||
})
|
||||
},
|
||||
fen2yuan(price) {
|
||||
return Util.fen2yuan(price)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang='scss'>
|
||||
.goodList .item {
|
||||
position: relative;
|
||||
padding-left: 30rpx;
|
||||
}
|
||||
|
||||
.goodList .item .pictrue {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.goodList .item .pictrue image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
|
||||
.goodList .item .pictrue .numPic {
|
||||
position: absolute;
|
||||
left: 7rpx;
|
||||
top: 7rpx;
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.goodList .item .underline {
|
||||
padding: 30rpx 30rpx 30rpx 0;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
|
||||
.goodList .item:nth-last-child(1) .underline {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.goodList .item .text {
|
||||
font-size: 30rpx;
|
||||
color: #222;
|
||||
width: 489rpx;
|
||||
}
|
||||
|
||||
.goodList .item .text .money {
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
margin-top: 50rpx;
|
||||
}
|
||||
|
||||
.goodList .item .text .money .num {
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.goodList .item .text .vip-money {
|
||||
font-size: 24rpx;
|
||||
color: #282828;
|
||||
font-weight: bold;
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
|
||||
.goodList .item .text .vip-money image {
|
||||
width: 46rpx;
|
||||
height: 21rpx;
|
||||
margin: 0 22rpx 0 5rpx;
|
||||
}
|
||||
|
||||
.goodList .item .text .vip-money .num {
|
||||
font-size: 22rpx;
|
||||
color: #aaa;
|
||||
font-weight: normal;
|
||||
margin: -2rpx 0 0 0;
|
||||
}
|
||||
|
||||
.goodList .item .iconfont {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
border-radius: 50%;
|
||||
font-size: 30rpx;
|
||||
bottom: 38rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<view style="touch-action: none;">
|
||||
<view class="home" style="position:fixed;" :style="{ top: top + 'px'}" id="right-nav" @touchmove.stop.prevent="setTouchMove">
|
||||
<view class="homeCon bg-color-red" :class="homeActive === true ? 'on' : ''" v-if="homeActive">
|
||||
<navigator hover-class='none' url='/pages/index/index' open-type='switchTab'
|
||||
class='iconfont icon-shouye-xianxing' />
|
||||
<navigator hover-class='none' url='/pages/order_addcart/order_addcart' open-type='switchTab'
|
||||
class='iconfont icon-caigou-xianxing' />
|
||||
<navigator hover-class='none' url='/pages/user/index' open-type='switchTab'
|
||||
class='iconfont icon-yonghu1' />
|
||||
</view>
|
||||
<view @click="open" class="pictrueBox">
|
||||
<view class="pictrue">
|
||||
<image :src="homeActive === true ? '/static/images/close.gif' : '/static/images/open.gif'" class="image" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
export default {
|
||||
name: "Home",
|
||||
props: {},
|
||||
data: function() {
|
||||
return {
|
||||
top: "500"
|
||||
};
|
||||
},
|
||||
computed: mapGetters(["homeActive"]),
|
||||
methods: {
|
||||
setTouchMove(e) {
|
||||
if (e.touches[0].clientY < 545 && e.touches[0].clientY > 66) {
|
||||
this.top = e.touches[0].clientY
|
||||
}
|
||||
},
|
||||
open: function() {
|
||||
this.homeActive ?
|
||||
this.$store.commit("CLOSE_HOME") :
|
||||
this.$store.commit("OPEN_HOME");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.pictrueBox {
|
||||
width: 130rpx;
|
||||
height: 120rpx;
|
||||
}
|
||||
|
||||
/*返回主页按钮*/
|
||||
.home {
|
||||
position: fixed;
|
||||
color: white;
|
||||
text-align: center;
|
||||
z-index: 9999;
|
||||
right: 15rpx;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.home .homeCon {
|
||||
border-radius: 50rpx;
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
color: $theme-color;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.home .homeCon.on {
|
||||
opacity: 1;
|
||||
animation: bounceInRight 0.5s cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
width: 300rpx;
|
||||
height: 86rpx;
|
||||
margin-bottom: 20rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #f44939 !important;
|
||||
}
|
||||
|
||||
.home .homeCon .iconfont {
|
||||
font-size: 48rpx;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.home .pictrue {
|
||||
width: 86rpx;
|
||||
height: 86rpx;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.home .pictrue .image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
transform: rotate(90deg);
|
||||
ms-transform: rotate(90deg);
|
||||
moz-transform: rotate(90deg);
|
||||
webkit-transform: rotate(90deg);
|
||||
o-transform: rotate(90deg);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,814 @@
|
||||
<!--
|
||||
parser 主模块组件
|
||||
github:https://github.com/jin-yufeng/Parser
|
||||
docs:https://jin-yufeng.github.io/Parser
|
||||
插件市场:https://ext.dcloud.net.cn/plugin?id=805
|
||||
author:JinYufeng
|
||||
update:2020/04/14
|
||||
-->
|
||||
<template>
|
||||
<view>
|
||||
<slot v-if="!nodes.length" />
|
||||
<!--#ifdef APP-PLUS-NVUE-->
|
||||
<web-view id="top" ref="web" :src="src" :style="'margin-top:-2px;height:'+height+'px'" @onPostMessage="_message" />
|
||||
<!--#endif-->
|
||||
<!--#ifndef APP-PLUS-NVUE-->
|
||||
<view id="top" :style="showAm+(selectable?';user-select:text;-webkit-user-select:text':'')" :animation="scaleAm" @tap="_tap"
|
||||
@touchstart="_touchstart" @touchmove="_touchmove">
|
||||
<!--#ifdef H5-->
|
||||
<div :id="'rtf'+uid"></div>
|
||||
<!--#endif-->
|
||||
<!--#ifndef H5-->
|
||||
<trees :nodes="nodes" :lazy-load="lazyLoad" :loadVideo="loadVideo" />
|
||||
<image v-for="(item, index) in imgs" v-bind:key="index" :id="index" :src="item" hidden @load="_load" />
|
||||
<!--#endif-->
|
||||
</view>
|
||||
<!--#endif-->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifndef H5 || APP-PLUS-NVUE
|
||||
import trees from './libs/trees';
|
||||
var cache = {},
|
||||
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
||||
fs = uni.getFileSystemManager ? uni.getFileSystemManager() : null,
|
||||
// #endif
|
||||
Parser = require('./libs/MpHtmlParser.js');
|
||||
var document; // document 补丁包 https://jin-yufeng.github.io/Parser/#/instructions?id=document
|
||||
// 计算 cache 的 key
|
||||
function hash(str) {
|
||||
for (var i = str.length, val = 5381; i--;)
|
||||
val += (val << 5) + str.charCodeAt(i);
|
||||
return val;
|
||||
}
|
||||
// #endif
|
||||
// #ifdef H5 || APP-PLUS-NVUE
|
||||
var rpx = uni.getSystemInfoSync().screenWidth / 750,
|
||||
cfg = require('./libs/config.js');
|
||||
// #endif
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
var dom = weex.requireModule('dom');
|
||||
// #endif
|
||||
export default {
|
||||
name: 'parser',
|
||||
data() {
|
||||
return {
|
||||
// #ifdef APP-PLUS
|
||||
loadVideo: false,
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
uid: this._uid,
|
||||
// #endif
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
src: '',
|
||||
height: 1,
|
||||
// #endif
|
||||
// #ifndef APP-PLUS-NVUE
|
||||
scaleAm: '',
|
||||
showAm: '',
|
||||
imgs: [],
|
||||
// #endif
|
||||
nodes: []
|
||||
}
|
||||
},
|
||||
// #ifndef H5 || APP-PLUS-NVUE
|
||||
components: {
|
||||
trees
|
||||
},
|
||||
// #endif
|
||||
props: {
|
||||
'html': null,
|
||||
// #ifndef MP-ALIPAY
|
||||
'autopause': {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// #endif
|
||||
'autosetTitle': {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// #ifndef H5 || APP-PLUS-NVUE
|
||||
'compress': Number,
|
||||
'useCache': Boolean,
|
||||
'xml': Boolean,
|
||||
// #endif
|
||||
'domain': String,
|
||||
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||
'gestureZoom': Boolean,
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN || MP-QQ || H5 || APP-PLUS
|
||||
'lazyLoad': Boolean,
|
||||
// #endif
|
||||
'selectable': Boolean,
|
||||
'tagStyle': Object,
|
||||
'showWithAnimation': Boolean,
|
||||
'useAnchor': Boolean
|
||||
},
|
||||
watch: {
|
||||
html(html) {
|
||||
this.setContent(html);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 图片数组
|
||||
this.imgList = [];
|
||||
this.imgList.each = function(f) {
|
||||
for (var i = 0, len = this.length; i < len; i++)
|
||||
this.setItem(i, f(this[i], i, this));
|
||||
}
|
||||
this.imgList.setItem = function(i, src) {
|
||||
if (i == void 0 || !src) return;
|
||||
// #ifndef MP-ALIPAY || APP-PLUS
|
||||
// 去重
|
||||
if (src.indexOf('http') == 0 && this.includes(src)) {
|
||||
var newSrc = '';
|
||||
for (var j = 0, c; c = src[j]; j++) {
|
||||
if (c == '/' && src[j - 1] != '/' && src[j + 1] != '/') break;
|
||||
newSrc += Math.random() > 0.5 ? c.toUpperCase() : c;
|
||||
}
|
||||
newSrc += src.substr(j);
|
||||
return this[i] = newSrc;
|
||||
}
|
||||
// #endif
|
||||
this[i] = src;
|
||||
// 暂存 data src
|
||||
if (src.includes('data:image')) {
|
||||
var filePath, info = src.match(/data:image\/(\S+?);(\S+?),(.+)/);
|
||||
if (!info) return;
|
||||
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
||||
filePath = `${wx.env.USER_DATA_PATH}/${Date.now()}.${info[1]}`;
|
||||
fs && fs.writeFile({
|
||||
filePath,
|
||||
data: info[3],
|
||||
encoding: info[2],
|
||||
success: () => this[i] = filePath
|
||||
})
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
filePath = `_doc/parser_tmp/${Date.now()}.${info[1]}`;
|
||||
var bitmap = new plus.nativeObj.Bitmap();
|
||||
bitmap.loadBase64Data(src, () => {
|
||||
bitmap.save(filePath, {}, () => {
|
||||
bitmap.clear()
|
||||
this[i] = filePath;
|
||||
})
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
if (this.html) this.setContent(this.html);
|
||||
},
|
||||
beforeDestroy() {
|
||||
// #ifdef H5
|
||||
if (this._observer) this._observer.disconnect();
|
||||
// #endif
|
||||
this.imgList.each(src => {
|
||||
// #ifdef APP-PLUS
|
||||
if (src && src.includes('_doc')) {
|
||||
plus.io.resolveLocalFileSystemURL(src, entry => {
|
||||
entry.remove();
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
||||
if (src && src.includes(uni.env.USER_DATA_PATH))
|
||||
fs && fs.unlink({
|
||||
filePath: src
|
||||
})
|
||||
// #endif
|
||||
})
|
||||
clearInterval(this._timer);
|
||||
},
|
||||
methods: {
|
||||
// #ifdef H5 || APP-PLUS-NVUE
|
||||
_Dom2Str(nodes) {
|
||||
var str = '';
|
||||
for (var node of nodes) {
|
||||
if (node.type == 'text')
|
||||
str += node.text;
|
||||
else {
|
||||
str += ('<' + node.name);
|
||||
for (var attr in node.attrs || {})
|
||||
str += (' ' + attr + '="' + node.attrs[attr] + '"');
|
||||
if (!node.children || !node.children.length) str += '>';
|
||||
else str += ('>' + this._Dom2Str(node.children) + '</' + node.name + '>');
|
||||
}
|
||||
}
|
||||
return str;
|
||||
},
|
||||
_handleHtml(html, append) {
|
||||
if (typeof html != 'string') html = this._Dom2Str(html.nodes || html);
|
||||
// 处理 rpx
|
||||
if (html.includes('rpx'))
|
||||
html = html.replace(/[0-9.]+\s*rpx/g, $ => parseFloat($) * rpx + 'px');
|
||||
if (!append) {
|
||||
// 处理 tag-style 和 userAgentStyles
|
||||
var style = '<style>@keyframes show{0%{opacity:0}100%{opacity:1}}';
|
||||
for (var item in cfg.userAgentStyles)
|
||||
style += `${item}{${cfg.userAgentStyles[item]}}`;
|
||||
for (item in this.tagStyle)
|
||||
style += `${item}{${this.tagStyle[item]}}`;
|
||||
style += '</style>';
|
||||
html = style + html;
|
||||
}
|
||||
return html;
|
||||
},
|
||||
// #endif
|
||||
setContent(html, append) {
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
if (!html) {
|
||||
this.src = '';
|
||||
this.height = 1;
|
||||
return;
|
||||
}
|
||||
if (append) return;
|
||||
plus.io.resolveLocalFileSystemURL('_doc', entry => {
|
||||
entry.getDirectory('parser_tmp', {
|
||||
create: true
|
||||
}, entry => {
|
||||
var fileName = Date.now() + '.html';
|
||||
entry.getFile(fileName, {
|
||||
create: true
|
||||
}, entry => {
|
||||
entry.createWriter(writer => {
|
||||
writer.onwriteend = () => {
|
||||
this.nodes = [1];
|
||||
this.src = '_doc/parser_tmp/' + fileName;
|
||||
this.$nextTick(function() {
|
||||
entry.remove();
|
||||
})
|
||||
}
|
||||
html =
|
||||
'<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1' +
|
||||
(this.selectable ? '' : ',user-scalable=no') +
|
||||
'"><script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></' +
|
||||
'script><base href="' + this.domain + '">' + this._handleHtml(html) +
|
||||
'<script>"use strict";function post(t){uni.postMessage({data:t})}' +
|
||||
(this.showWithAnimation ? 'document.body.style.animation="show .5s",' : '') +
|
||||
'document.addEventListener("UniAppJSBridgeReady",function(){post({action:"load",text:document.body.innerText});var t=document.getElementsByTagName("title");t.length&&post({action:"getTitle",title:t[0].innerText});for(var e,o=document.getElementsByTagName("img"),n=[],i=0,r=0;e=o[i];i++)e.onerror=function(){post({action:"error",source:"img",target:this})},e.hasAttribute("ignore")||"A"==e.parentElement.nodeName||(e.i=r++,n.push(e.src),e.onclick=function(){post({action:"preview",img:{i:this.i,src:this.src}})});post({action:"getImgList",imgList:n});for(var a,s=document.getElementsByTagName("a"),c=0;a=s[c];c++)a.onclick=function(){var t,e=this.getAttribute("href");if("#"==e[0]){var r=document.getElementById(e.substr(1));r&&(t=r.offsetTop)}return post({action:"linkpress",href:e,offset:t}),!1};;for(var u,m=document.getElementsByTagName("video"),d=0;u=m[d];d++)u.style.maxWidth="100%",u.onerror=function(){post({action:"error",source:"video",target:this})}' +
|
||||
(this.autopause ? ',u.onplay=function(){for(var t,e=0;t=m[e];e++)t!=this&&t.pause()}' : '') +
|
||||
';for(var g,l=document.getElementsByTagName("audio"),p=0;g=l[p];p++)g.onerror=function(){post({action:"error",source:"audio",target:this})};window.onload=function(){post({action:"ready",height:document.body.scrollHeight})}});</' +
|
||||
'script>';
|
||||
writer.write(html);
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
if (!html) {
|
||||
if (this.rtf && !append) this.rtf.parentNode.removeChild(this.rtf);
|
||||
return;
|
||||
}
|
||||
var div = document.createElement('div');
|
||||
if (!append) {
|
||||
if (this.rtf) this.rtf.parentNode.removeChild(this.rtf);
|
||||
this.rtf = div;
|
||||
} else {
|
||||
if (!this.rtf) this.rtf = div;
|
||||
else this.rtf.appendChild(div);
|
||||
}
|
||||
div.innerHTML = this._handleHtml(html, append);
|
||||
for (var styles = this.rtf.getElementsByTagName('style'), i = 0, style; style = styles[i++];) {
|
||||
style.innerHTML = style.innerHTML.replace(/body/g, '#rtf' + this._uid);
|
||||
style.setAttribute('scoped', 'true');
|
||||
}
|
||||
// 懒加载
|
||||
if (!this._observer && this.lazyLoad && IntersectionObserver) {
|
||||
this._observer = new IntersectionObserver(changes => {
|
||||
for (let item, i = 0; item = changes[i++];) {
|
||||
if (item.isIntersecting) {
|
||||
item.target.src = item.target.getAttribute('data-src');
|
||||
item.target.removeAttribute('data-src');
|
||||
this._observer.unobserve(item.target);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
rootMargin: '900px 0px 900px 0px'
|
||||
})
|
||||
}
|
||||
var _ts = this;
|
||||
// 获取标题
|
||||
var title = this.rtf.getElementsByTagName('title');
|
||||
if (title.length && this.autosetTitle)
|
||||
uni.setNavigationBarTitle({
|
||||
title: title[0].innerText
|
||||
})
|
||||
// 图片处理
|
||||
this.imgList.length = 0;
|
||||
var imgs = this.rtf.getElementsByTagName('img');
|
||||
for (let i = 0, j = 0, img; img = imgs[i]; i++) {
|
||||
img.style.maxWidth = '100%';
|
||||
var src = img.getAttribute('src');
|
||||
if (this.domain && src) {
|
||||
if (src[0] == '/') {
|
||||
if (src[1] == '/')
|
||||
img.src = (this.domain.includes('://') ? this.domain.split('://')[0] : '') + ':' + src;
|
||||
else img.src = this.domain + src;
|
||||
} else if (!src.includes('://')) img.src = this.domain + '/' + src;
|
||||
}
|
||||
if (!img.hasAttribute('ignore') && img.parentElement.nodeName != 'A') {
|
||||
img.i = j++;
|
||||
_ts.imgList.push(img.src || img.getAttribute('data-src'));
|
||||
img.onclick = function() {
|
||||
var preview = true;
|
||||
this.ignore = () => preview = false;
|
||||
_ts.$emit('imgtap', this);
|
||||
if (preview) {
|
||||
uni.previewImage({
|
||||
current: this.i,
|
||||
urls: _ts.imgList
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
img.onerror = function() {
|
||||
_ts.$emit('error', {
|
||||
source: 'img',
|
||||
target: this
|
||||
});
|
||||
}
|
||||
if (_ts.lazyLoad && this._observer && img.src && img.i != 0) {
|
||||
img.setAttribute('data-src', img.src);
|
||||
img.removeAttribute('src');
|
||||
this._observer.observe(img);
|
||||
}
|
||||
}
|
||||
// 链接处理
|
||||
var links = this.rtf.getElementsByTagName('a');
|
||||
for (var link of links) {
|
||||
link.onclick = function() {
|
||||
var jump = true,
|
||||
href = this.getAttribute('href');
|
||||
_ts.$emit('linkpress', {
|
||||
href,
|
||||
ignore: () => jump = false
|
||||
});
|
||||
if (jump && href) {
|
||||
if (href[0] == '#') {
|
||||
if (_ts.useAnchor) {
|
||||
_ts.navigateTo({
|
||||
id: href.substr(1)
|
||||
})
|
||||
}
|
||||
} else if (href.indexOf('http') == 0 || href.indexOf('//') == 0)
|
||||
return true;
|
||||
else {
|
||||
uni.navigateTo({
|
||||
url: href
|
||||
})
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 视频处理
|
||||
var videos = this.rtf.getElementsByTagName('video');
|
||||
_ts.videoContexts = videos;
|
||||
for (let video, i = 0; video = videos[i++];) {
|
||||
video.style.maxWidth = '100%';
|
||||
video.onerror = function() {
|
||||
_ts.$emit('error', {
|
||||
source: 'video',
|
||||
target: this
|
||||
});
|
||||
}
|
||||
video.onplay = function() {
|
||||
if (_ts.autopause)
|
||||
for (let item, i = 0; item = _ts.videoContexts[i++];)
|
||||
if (item != this) item.pause();
|
||||
}
|
||||
}
|
||||
// 音频处理
|
||||
var audios = this.rtf.getElementsByTagName('audios');
|
||||
for (var audio of audios)
|
||||
audio.onerror = function() {
|
||||
_ts.$emit('error', {
|
||||
source: 'audio',
|
||||
target: this
|
||||
});
|
||||
}
|
||||
this.document = this.rtf;
|
||||
if (!append) document.getElementById('rtf' + this._uid).appendChild(this.rtf);
|
||||
this.$nextTick(() => {
|
||||
this.nodes = [1];
|
||||
this.$emit('load');
|
||||
})
|
||||
setTimeout(() => this.showAm = '', 500);
|
||||
// #endif
|
||||
// #ifndef H5 || APP-PLUS-NVUE
|
||||
var nodes;
|
||||
if (!html)
|
||||
return this.nodes = [];
|
||||
else if (typeof html == 'string') {
|
||||
let parser = new Parser(html, this);
|
||||
// 缓存读取
|
||||
if (this.useCache) {
|
||||
var hashVal = hash(html);
|
||||
if (cache[hashVal])
|
||||
nodes = cache[hashVal];
|
||||
else {
|
||||
nodes = parser.parse();
|
||||
cache[hashVal] = nodes;
|
||||
}
|
||||
} else nodes = parser.parse();
|
||||
this.$emit('parse', nodes);
|
||||
} else if (Object.prototype.toString.call(html) == '[object Array]') {
|
||||
// 非本插件产生的 array 需要进行一些转换
|
||||
if (html.length && html[0].PoweredBy != 'Parser') {
|
||||
let parser = new Parser(html, this);
|
||||
(function f(ns) {
|
||||
for (var i = 0, n; n = ns[i]; i++) {
|
||||
if (n.type == 'text') continue;
|
||||
n.attrs = n.attrs || {};
|
||||
for (var item in n.attrs)
|
||||
if (typeof n.attrs[item] != 'string') n.attrs[item] = n.attrs[item].toString();
|
||||
parser.matchAttr(n, parser);
|
||||
if (n.children && n.children.length) {
|
||||
parser.STACK.push(n);
|
||||
f(n.children);
|
||||
parser.popNode(parser.STACK.pop());
|
||||
} else n.children = void 0;
|
||||
}
|
||||
})(html);
|
||||
}
|
||||
nodes = html;
|
||||
} else if (typeof html == 'object' && html.nodes) {
|
||||
nodes = html.nodes;
|
||||
console.warn('错误的 html 类型:object 类型已废弃');
|
||||
} else
|
||||
return console.warn('错误的 html 类型:' + typeof html);
|
||||
// #ifdef APP-PLUS
|
||||
this.loadVideo = false;
|
||||
// #endif
|
||||
if (document) this.document = new document(this.nodes, 'nodes', this);
|
||||
if (append) this.nodes = this.nodes.concat(nodes);
|
||||
else this.nodes = nodes;
|
||||
if (nodes.length && nodes[0].title && this.autosetTitle)
|
||||
uni.setNavigationBarTitle({
|
||||
title: nodes[0].title
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.imgList.length = 0;
|
||||
this.videoContexts = [];
|
||||
// #ifdef MP-TOUTIAO
|
||||
setTimeout(() => {
|
||||
// #endif
|
||||
var f = (cs) => {
|
||||
for (let i = 0, c; c = cs[i++];) {
|
||||
if (c.$options.name == 'trees') {
|
||||
for (var j = c.nodes.length, item; item = c.nodes[--j];) {
|
||||
if (item.c) continue;
|
||||
if (item.name == 'img') {
|
||||
this.imgList.setItem(item.attrs.i, item.attrs.src);
|
||||
// #ifndef MP-ALIPAY
|
||||
if (!c.observer && !c.imgLoad && item.attrs.i != '0') {
|
||||
if (this.lazyLoad && uni.createIntersectionObserver) {
|
||||
c.observer = uni.createIntersectionObserver(c);
|
||||
c.observer.relativeToViewport({
|
||||
top: 900,
|
||||
bottom: 900
|
||||
}).observe('._img', () => {
|
||||
c.imgLoad = true;
|
||||
c.observer.disconnect();
|
||||
})
|
||||
} else
|
||||
c.imgLoad = true;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
// #ifndef MP-ALIPAY
|
||||
else if (item.name == 'video') {
|
||||
var ctx = uni.createVideoContext(item.attrs.id, c);
|
||||
ctx.id = item.attrs.id;
|
||||
this.videoContexts.push(ctx);
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||
if (item.attrs && item.attrs.id) {
|
||||
this.anchors = this.anchors || [];
|
||||
this.anchors.push({
|
||||
id: item.attrs.id,
|
||||
node: c
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
if (c.$children.length)
|
||||
f(c.$children)
|
||||
}
|
||||
}
|
||||
f(this.$children);
|
||||
// #ifdef MP-TOUTIAO
|
||||
}, 200)
|
||||
this.$emit('load');
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
setTimeout(() => {
|
||||
this.loadVideo = true;
|
||||
}, 3000);
|
||||
// #endif
|
||||
})
|
||||
// #endif
|
||||
// #ifndef APP-PLUS-NVUE
|
||||
var height;
|
||||
clearInterval(this._timer);
|
||||
this._timer = setInterval(() => {
|
||||
// #ifdef H5
|
||||
var res = [this.rtf.getBoundingClientRect()];
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
// #ifdef APP-PLUS
|
||||
uni.createSelectorQuery().in(this)
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
this.createSelectorQuery()
|
||||
// #endif
|
||||
.select('#top').boundingClientRect().exec(res => {
|
||||
// #endif
|
||||
this.width = res[0].width;
|
||||
if (res[0].height == height) {
|
||||
this.$emit('ready', res[0])
|
||||
clearInterval(this._timer);
|
||||
}
|
||||
height = res[0].height;
|
||||
// #ifndef H5
|
||||
});
|
||||
// #endif
|
||||
}, 350)
|
||||
if (this.showWithAnimation && !append) this.showAm = 'animation:show .5s';
|
||||
// #endif
|
||||
},
|
||||
getText(ns = this.nodes) {
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
return this._text;
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
return this.rtf.innerText;
|
||||
// #endif
|
||||
// #ifndef H5 || APP-PLUS-NVUE
|
||||
var txt = '';
|
||||
for (var i = 0, n; n = ns[i++];) {
|
||||
if (n.type == 'text') txt += n.text.replace(/ /g, '\u00A0').replace(/</g, '<').replace(/>/g, '>')
|
||||
.replace(/&/g, '&');
|
||||
else if (n.type == 'br') txt += '\n';
|
||||
else {
|
||||
// 块级标签前后加换行
|
||||
var block = n.name == 'p' || n.name == 'div' || n.name == 'tr' || n.name == 'li' || (n.name[0] == 'h' && n.name[1] >
|
||||
'0' && n.name[1] < '7');
|
||||
if (block && txt && txt[txt.length - 1] != '\n') txt += '\n';
|
||||
if (n.children) txt += this.getText(n.children);
|
||||
if (block && txt[txt.length - 1] != '\n') txt += '\n';
|
||||
else if (n.name == 'td' || n.name == 'th') txt += '\t';
|
||||
}
|
||||
}
|
||||
return txt;
|
||||
// #endif
|
||||
},
|
||||
navigateTo(obj) {
|
||||
if (!this.useAnchor)
|
||||
return obj.fail && obj.fail({
|
||||
errMsg: 'Anchor is disabled'
|
||||
})
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
if (!obj.id)
|
||||
dom.scrollToElement(this.$refs.web);
|
||||
else
|
||||
this.$refs.web.evalJs('var pos=document.getElementById("' + obj.id +
|
||||
'");if(pos)post({action:"linkpress",href:"#",offset:pos.offsetTop})');
|
||||
return obj.success && obj.success({
|
||||
errMsg: 'pageScrollTo:ok'
|
||||
});
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
if (!obj.id) {
|
||||
window.scrollTo(0, this.rtf.offsetTop);
|
||||
return obj.success && obj.success({
|
||||
errMsg: 'pageScrollTo:ok'
|
||||
});
|
||||
}
|
||||
var target = document.getElementById(obj.id);
|
||||
if (!target) return obj.fail && obj.fail({
|
||||
errMsg: 'Label not found'
|
||||
});
|
||||
obj.scrollTop = this.rtf.offsetTop + target.offsetTop;
|
||||
uni.pageScrollTo(obj);
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
var Scroll = (selector, component) => {
|
||||
uni.createSelectorQuery().in(component ? component : this).select(selector).boundingClientRect().selectViewport()
|
||||
.scrollOffset()
|
||||
.exec(res => {
|
||||
if (!res || !res[0])
|
||||
return obj.fail && obj.fail({
|
||||
errMsg: 'Label not found'
|
||||
});
|
||||
obj.scrollTop = res[1].scrollTop + res[0].top;
|
||||
uni.pageScrollTo(obj);
|
||||
})
|
||||
}
|
||||
if (!obj.id) Scroll('#top');
|
||||
else {
|
||||
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||
Scroll('#top >>> #' + obj.id + ', #top >>> .' + obj.id);
|
||||
// #endif
|
||||
// #ifdef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||
for (var anchor of this.anchors)
|
||||
if (anchor.id == obj.id)
|
||||
Scroll('#' + obj.id + ', .' + obj.id, anchor.node);
|
||||
// #endif
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
getVideoContext(id) {
|
||||
// #ifndef APP-PLUS-NVUE
|
||||
if (!id) return this.videoContexts;
|
||||
else
|
||||
for (var i = this.videoContexts.length; i--;)
|
||||
if (this.videoContexts[i].id == id) return this.videoContexts[i];
|
||||
// #endif
|
||||
},
|
||||
// 预加载
|
||||
preLoad(html, num) {
|
||||
// #ifdef H5 || APP-PLUS-NVUE
|
||||
if (html.constructor == Array)
|
||||
html = this._Dom2Str(html);
|
||||
var script = "var contain=document.createElement('div');contain.innerHTML='" + html.replace(/'/g, "\\'") +
|
||||
"';for(var imgs=contain.querySelectorAll('img'),i=imgs.length-1;i>=" + num +
|
||||
";i--)imgs[i].removeAttribute('src');";
|
||||
// #endif
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
this.$refs.web.evalJs(script);
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
eval(script);
|
||||
// #endif
|
||||
// #ifndef H5 || APP-PLUS-NVUE
|
||||
if (typeof html == 'string') {
|
||||
var id = hash(html);
|
||||
html = new Parser(html, this).parse();
|
||||
cache[id] = html;
|
||||
}
|
||||
var wait = [];
|
||||
(function f(ns) {
|
||||
for (var i = 0, n; n = ns[i++];) {
|
||||
if (n.name == 'img' && n.attrs.src && !wait.includes(n.attrs.src))
|
||||
wait.push(n.attrs.src);
|
||||
f(n.children || []);
|
||||
}
|
||||
})(html);
|
||||
if (num) wait = wait.slice(0, num);
|
||||
this._wait = (this._wait || []).concat(wait);
|
||||
if (!this.imgs) this.imgs = this._wait.splice(0, 15);
|
||||
else if (this.imgs.length < 15)
|
||||
this.imgs = this.imgs.concat(this._wait.splice(0, 15 - this.imgs.length));
|
||||
// #endif
|
||||
},
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
_message(e) {
|
||||
// 接收 web-view 消息
|
||||
var data = e.detail.data[0];
|
||||
if (data.action == 'load') {
|
||||
this.$emit('load');
|
||||
this._text = data.text;
|
||||
} else if (data.action == 'getTitle') {
|
||||
if (this.autosetTitle)
|
||||
uni.setNavigationBarTitle({
|
||||
title: data.title
|
||||
})
|
||||
} else if (data.action == 'getImgList') {
|
||||
this.imgList.length = 0;
|
||||
for (var i = data.imgList.length; i--;)
|
||||
this.imgList.setItem(i, data.imgList[i]);
|
||||
} else if (data.action == 'preview') {
|
||||
var preview = true;
|
||||
data.img.ignore = () => preview = false;
|
||||
this.$emit('imgtap', data.img);
|
||||
if (preview)
|
||||
uni.previewImage({
|
||||
current: data.img.i,
|
||||
urls: this.imgList
|
||||
})
|
||||
} else if (data.action == 'linkpress') {
|
||||
var jump = true,
|
||||
href = data.href;
|
||||
this.$emit('linkpress', {
|
||||
href,
|
||||
ignore: () => jump = false
|
||||
})
|
||||
if (jump && href) {
|
||||
if (href[0] == '#') {
|
||||
if (this.useAnchor)
|
||||
dom.scrollToElement(this.$refs.web, {
|
||||
offset: data.offset
|
||||
})
|
||||
} else if (href.includes('://'))
|
||||
plus.runtime.openWeb(href);
|
||||
else
|
||||
uni.navigateTo({
|
||||
url: href
|
||||
})
|
||||
}
|
||||
} else if (data.action == 'error')
|
||||
this.$emit('error', {
|
||||
source: data.source,
|
||||
target: data.target
|
||||
})
|
||||
else if (data.action == 'ready') {
|
||||
this.height = data.height;
|
||||
this.$nextTick(() => {
|
||||
uni.createSelectorQuery().in(this).select('#top').boundingClientRect().exec(res => {
|
||||
this.rect = res[0];
|
||||
this.$emit('ready', res[0]);
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
// #endif
|
||||
// #ifndef APP-PLUS-NVUE
|
||||
// #ifndef H5
|
||||
_load(e) {
|
||||
if (this._wait.length)
|
||||
this.$set(this.imgs, e.target.id, this._wait.shift());
|
||||
},
|
||||
// #endif
|
||||
_tap(e) {
|
||||
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||
if (this.gestureZoom && e.timeStamp - this._lastT < 300) {
|
||||
var initY = e.touches[0].pageY - e.currentTarget.offsetTop;
|
||||
if (this._zoom) {
|
||||
this._scaleAm.translateX(0).scale(1).step();
|
||||
uni.pageScrollTo({
|
||||
scrollTop: (initY + this._initY) / 2 - e.touches[0].clientY,
|
||||
duration: 400
|
||||
})
|
||||
} else {
|
||||
var initX = e.touches[0].pageX - e.currentTarget.offsetLeft;
|
||||
this._initY = initY;
|
||||
this._scaleAm = uni.createAnimation({
|
||||
transformOrigin: `${initX}px ${this._initY}px 0`,
|
||||
timingFunction: 'ease-in-out'
|
||||
});
|
||||
// #ifdef MP-TOUTIAO
|
||||
this._scaleAm.opacity(1);
|
||||
// #endif
|
||||
this._scaleAm.scale(2).step();
|
||||
this._tMax = initX / 2;
|
||||
this._tMin = (initX - this.width) / 2;
|
||||
this._tX = 0;
|
||||
}
|
||||
this._zoom = !this._zoom;
|
||||
this.scaleAm = this._scaleAm.export();
|
||||
}
|
||||
this._lastT = e.timeStamp;
|
||||
// #endif
|
||||
},
|
||||
_touchstart(e) {
|
||||
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||
if (e.touches.length == 1)
|
||||
this._initX = this._lastX = e.touches[0].pageX;
|
||||
// #endif
|
||||
},
|
||||
_touchmove(e) {
|
||||
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||
var diff = e.touches[0].pageX - this._lastX;
|
||||
if (this._zoom && e.touches.length == 1 && Math.abs(diff) > 20) {
|
||||
this._lastX = e.touches[0].pageX;
|
||||
if ((this._tX <= this._tMin && diff < 0) || (this._tX >= this._tMax && diff > 0))
|
||||
return;
|
||||
this._tX += (diff * Math.abs(this._lastX - this._initX) * 0.05);
|
||||
if (this._tX < this._tMin) this._tX = this._tMin;
|
||||
if (this._tX > this._tMax) this._tX = this._tMax;
|
||||
this._scaleAm.translateX(this._tX).step();
|
||||
this.scaleAm = this._scaleAm.export();
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes show {
|
||||
0% {
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* #ifdef MP-WEIXIN */
|
||||
:host {
|
||||
display: block;
|
||||
overflow: scroll;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
</style>
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
解析和匹配 Css 的选择器
|
||||
github:https://github.com/jin-yufeng/Parser
|
||||
docs:https://jin-yufeng.github.io/Parser
|
||||
author:JinYufeng
|
||||
update:2020/03/15
|
||||
*/
|
||||
var cfg = require('./config.js');
|
||||
class CssHandler {
|
||||
constructor(tagStyle) {
|
||||
var styles = Object.assign({}, cfg.userAgentStyles);
|
||||
for (var item in tagStyle)
|
||||
styles[item] = (styles[item] ? styles[item] + ';' : '') + tagStyle[item];
|
||||
this.styles = styles;
|
||||
}
|
||||
getStyle = data => this.styles = new CssParser(data, this.styles).parse();
|
||||
match(name, attrs) {
|
||||
var tmp, matched = (tmp = this.styles[name]) ? tmp + ';' : '';
|
||||
if (attrs.class) {
|
||||
var items = attrs.class.split(' ');
|
||||
for (var i = 0, item; item = items[i]; i++)
|
||||
if (tmp = this.styles['.' + item])
|
||||
matched += tmp + ';';
|
||||
}
|
||||
if (tmp = this.styles['#' + attrs.id])
|
||||
matched += tmp + ';';
|
||||
return matched;
|
||||
}
|
||||
}
|
||||
module.exports = CssHandler;
|
||||
class CssParser {
|
||||
constructor(data, init) {
|
||||
this.data = data;
|
||||
this.floor = 0;
|
||||
this.i = 0;
|
||||
this.list = [];
|
||||
this.res = init;
|
||||
this.state = this.Space;
|
||||
}
|
||||
parse() {
|
||||
for (var c; c = this.data[this.i]; this.i++)
|
||||
this.state(c);
|
||||
return this.res;
|
||||
}
|
||||
section = () => this.data.substring(this.start, this.i);
|
||||
isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
||||
// 状态机
|
||||
Space(c) {
|
||||
if (c == '.' || c == '#' || this.isLetter(c)) {
|
||||
this.start = this.i;
|
||||
this.state = this.Name;
|
||||
} else if (c == '/' && this.data[this.i + 1] == '*')
|
||||
this.Comment();
|
||||
else if (!cfg.blankChar[c] && c != ';')
|
||||
this.state = this.Ignore;
|
||||
}
|
||||
Comment() {
|
||||
this.i = this.data.indexOf('*/', this.i) + 1;
|
||||
if (!this.i) this.i = this.data.length;
|
||||
this.state = this.Space;
|
||||
}
|
||||
Ignore(c) {
|
||||
if (c == '{') this.floor++;
|
||||
else if (c == '}' && !--this.floor) this.state = this.Space;
|
||||
}
|
||||
Name(c) {
|
||||
if (cfg.blankChar[c]) {
|
||||
this.list.push(this.section());
|
||||
this.state = this.NameSpace;
|
||||
} else if (c == '{') {
|
||||
this.list.push(this.section());
|
||||
this.Content();
|
||||
} else if (c == ',') {
|
||||
this.list.push(this.section());
|
||||
this.Comma();
|
||||
} else if (!this.isLetter(c) && (c < '0' || c > '9') && c != '-' && c != '_')
|
||||
this.state = this.Ignore;
|
||||
}
|
||||
NameSpace(c) {
|
||||
if (c == '{') this.Content();
|
||||
else if (c == ',') this.Comma();
|
||||
else if (!cfg.blankChar[c]) this.state = this.Ignore;
|
||||
}
|
||||
Comma() {
|
||||
while (cfg.blankChar[this.data[++this.i]]);
|
||||
if (this.data[this.i] == '{') this.Content();
|
||||
else {
|
||||
this.start = this.i--;
|
||||
this.state = this.Name;
|
||||
}
|
||||
}
|
||||
Content() {
|
||||
this.start = ++this.i;
|
||||
if ((this.i = this.data.indexOf('}', this.i)) == -1) this.i = this.data.length;
|
||||
var content = this.section();
|
||||
for (var i = 0, item; item = this.list[i++];)
|
||||
if (this.res[item]) this.res[item] += ';' + content;
|
||||
else this.res[item] = content;
|
||||
this.list = [];
|
||||
this.state = this.Space;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,577 @@
|
||||
/*
|
||||
将 html 解析为适用于小程序 rich-text 的 DOM 结构
|
||||
github:https://github.com/jin-yufeng/Parser
|
||||
docs:https://jin-yufeng.github.io/Parser
|
||||
author:JinYufeng
|
||||
update:2020/04/13
|
||||
*/
|
||||
var cfg = require('./config.js'),
|
||||
blankChar = cfg.blankChar,
|
||||
CssHandler = require('./CssHandler.js'),
|
||||
{
|
||||
screenWidth,
|
||||
system
|
||||
} = wx.getSystemInfoSync();
|
||||
// #ifdef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO
|
||||
var entities = {
|
||||
lt: '<',
|
||||
gt: '>',
|
||||
amp: '&',
|
||||
quot: '"',
|
||||
apos: "'",
|
||||
nbsp: '\xA0',
|
||||
ensp: '\u2002',
|
||||
emsp: '\u2003',
|
||||
ndash: '–',
|
||||
mdash: '—',
|
||||
middot: '·',
|
||||
lsquo: '‘',
|
||||
rsquo: '’',
|
||||
ldquo: '“',
|
||||
rdquo: '”',
|
||||
bull: '•',
|
||||
hellip: '…',
|
||||
permil: '‰',
|
||||
copy: '©',
|
||||
reg: '®',
|
||||
trade: '™',
|
||||
times: '×',
|
||||
divide: '÷',
|
||||
cent: '¢',
|
||||
pound: '£',
|
||||
yen: '¥',
|
||||
euro: '€',
|
||||
sect: '§'
|
||||
};
|
||||
// #endif
|
||||
var emoji; // emoji 补丁包 https://jin-yufeng.github.io/Parser/#/instructions?id=emoji
|
||||
class MpHtmlParser {
|
||||
constructor(data, options = {}) {
|
||||
this.attrs = {};
|
||||
this.compress = options.compress;
|
||||
this.CssHandler = new CssHandler(options.tagStyle, screenWidth);
|
||||
this.data = data;
|
||||
this.domain = options.domain;
|
||||
this.DOM = [];
|
||||
this.i = this.start = this.audioNum = this.imgNum = this.videoNum = 0;
|
||||
this.protocol = this.domain && this.domain.includes('://') ? this.domain.split('://')[0] : '';
|
||||
this.state = this.Text;
|
||||
this.STACK = [];
|
||||
this.useAnchor = options.useAnchor;
|
||||
this.xml = options.xml;
|
||||
}
|
||||
parse() {
|
||||
if (emoji) this.data = emoji.parseEmoji(this.data);
|
||||
for (var c; c = this.data[this.i]; this.i++)
|
||||
this.state(c);
|
||||
if (this.state == this.Text) this.setText();
|
||||
while (this.STACK.length) this.popNode(this.STACK.pop());
|
||||
// #ifdef MP-BAIDU || MP-TOUTIAO
|
||||
// 将顶层标签的一些样式提取出来给 rich-text
|
||||
(function f(ns) {
|
||||
for (var i = ns.length, n; n = ns[--i];) {
|
||||
if (n.type == 'text') continue;
|
||||
if (!n.c) {
|
||||
var style = n.attrs.style;
|
||||
if (style) {
|
||||
var j, k, res;
|
||||
if ((j = style.indexOf('display')) != -1)
|
||||
res = style.substring(j, (k = style.indexOf(';', j)) == -1 ? style.length : k);
|
||||
if ((j = style.indexOf('float')) != -1)
|
||||
res += ';' + style.substring(j, (k = style.indexOf(';', j)) == -1 ? style.length : k);
|
||||
n.attrs.contain = res;
|
||||
}
|
||||
} else f(n.children);
|
||||
}
|
||||
})(this.DOM);
|
||||
// #endif
|
||||
if (this.DOM.length) {
|
||||
this.DOM[0].PoweredBy = 'Parser';
|
||||
if (this.title) this.DOM[0].title = this.title;
|
||||
}
|
||||
return this.DOM;
|
||||
}
|
||||
// 设置属性
|
||||
setAttr() {
|
||||
var name = this.getName(this.attrName);
|
||||
if (cfg.trustAttrs[name]) {
|
||||
if (!this.attrVal) {
|
||||
if (cfg.boolAttrs[name]) this.attrs[name] = 'T';
|
||||
} else if (name == 'src') this.attrs[name] = this.getUrl(this.attrVal.replace(/&/g, '&'));
|
||||
else this.attrs[name] = this.attrVal;
|
||||
}
|
||||
this.attrVal = '';
|
||||
while (blankChar[this.data[this.i]]) this.i++;
|
||||
if (this.isClose()) this.setNode();
|
||||
else {
|
||||
this.start = this.i;
|
||||
this.state = this.AttrName;
|
||||
}
|
||||
}
|
||||
// 设置文本节点
|
||||
setText() {
|
||||
var back, text = this.section();
|
||||
if (!text) return;
|
||||
text = (cfg.onText && cfg.onText(text, () => back = true)) || text;
|
||||
if (back) {
|
||||
this.data = this.data.substr(0, this.start) + text + this.data.substr(this.i);
|
||||
let j = this.start + text.length;
|
||||
for (this.i = this.start; this.i < j; this.i++) this.state(this.data[this.i]);
|
||||
return;
|
||||
}
|
||||
if (!this.pre) {
|
||||
// 合并空白符
|
||||
var tmp = [];
|
||||
for (let i = text.length, c; c = text[--i];)
|
||||
if (!blankChar[c] || (!blankChar[tmp[0]] && (c = ' '))) tmp.unshift(c);
|
||||
text = tmp.join('');
|
||||
if (text == ' ') return;
|
||||
}
|
||||
// 处理实体
|
||||
var siblings = this.siblings(),
|
||||
i = -1,
|
||||
j, en;
|
||||
while (1) {
|
||||
if ((i = text.indexOf('&', i + 1)) == -1) break;
|
||||
if ((j = text.indexOf(';', i + 2)) == -1) break;
|
||||
if (text[i + 1] == '#') {
|
||||
en = parseInt((text[i + 2] == 'x' ? '0' : '') + text.substring(i + 2, j));
|
||||
if (!isNaN(en)) text = text.substr(0, i) + String.fromCharCode(en) + text.substring(j + 1);
|
||||
} else {
|
||||
en = text.substring(i + 1, j);
|
||||
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
|
||||
if (en == 'nbsp') text = text.substr(0, i) + '\xA0' + text.substr(j + 1); // 解决 失效
|
||||
else if (en != 'lt' && en != 'gt' && en != 'amp' && en != 'ensp' && en != 'emsp' && en != 'quot' && en != 'apos') {
|
||||
i && siblings.push({
|
||||
type: 'text',
|
||||
text: text.substr(0, i)
|
||||
})
|
||||
siblings.push({
|
||||
type: 'text',
|
||||
text: `&${en};`,
|
||||
en: 1
|
||||
})
|
||||
text = text.substr(j + 1);
|
||||
i = -1;
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO
|
||||
if (entities[en]) text = text.substr(0, i) + entities[en] + text.substr(j + 1);
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
text && siblings.push({
|
||||
type: 'text',
|
||||
text
|
||||
})
|
||||
}
|
||||
// 设置元素节点
|
||||
setNode() {
|
||||
var node = {
|
||||
name: this.tagName.toLowerCase(),
|
||||
attrs: this.attrs
|
||||
},
|
||||
close = cfg.selfClosingTags[node.name] || (this.xml && this.data[this.i] == '/');
|
||||
this.attrs = {};
|
||||
if (!cfg.ignoreTags[node.name]) {
|
||||
this.matchAttr(node);
|
||||
if (!close) {
|
||||
node.children = [];
|
||||
if (node.name == 'pre' && cfg.highlight) {
|
||||
this.remove(node);
|
||||
this.pre = node.pre = true;
|
||||
}
|
||||
this.siblings().push(node);
|
||||
this.STACK.push(node);
|
||||
} else if (!cfg.filter || cfg.filter(node, this) != false)
|
||||
this.siblings().push(node);
|
||||
} else {
|
||||
if (!close) this.remove(node);
|
||||
else if (node.name == 'source') {
|
||||
var parent = this.STACK[this.STACK.length - 1],
|
||||
attrs = node.attrs;
|
||||
if (parent && attrs.src)
|
||||
if (parent.name == 'video' || parent.name == 'audio')
|
||||
parent.attrs.source.push(attrs.src);
|
||||
else {
|
||||
var i, media = attrs.media;
|
||||
if (parent.name == 'picture' && !parent.attrs.src && !(attrs.src.indexOf('.webp') && system.includes('iOS')) &&
|
||||
(!media || (media.includes('px') &&
|
||||
(((i = media.indexOf('min-width')) != -1 && (i = media.indexOf(':', i + 8)) != -1 && screenWidth > parseInt(
|
||||
media.substr(i + 1))) ||
|
||||
((i = media.indexOf('max-width')) != -1 && (i = media.indexOf(':', i + 8)) != -1 && screenWidth < parseInt(
|
||||
media.substr(i + 1)))))))
|
||||
parent.attrs.src = attrs.src;
|
||||
}
|
||||
} else if (node.name == 'base' && !this.domain) this.domain = node.attrs.href;
|
||||
}
|
||||
if (this.data[this.i] == '/') this.i++;
|
||||
this.start = this.i + 1;
|
||||
this.state = this.Text;
|
||||
}
|
||||
// 移除标签
|
||||
remove(node) {
|
||||
var name = node.name,
|
||||
j = this.i;
|
||||
while (1) {
|
||||
if ((this.i = this.data.indexOf('</', this.i + 1)) == -1) {
|
||||
if (name == 'pre' || name == 'svg') this.i = j;
|
||||
else this.i = this.data.length;
|
||||
return;
|
||||
}
|
||||
this.start = (this.i += 2);
|
||||
while (!blankChar[this.data[this.i]] && !this.isClose()) this.i++;
|
||||
if (this.getName(this.section()) == name) {
|
||||
// 代码块高亮
|
||||
if (name == 'pre') {
|
||||
this.data = this.data.substr(0, j + 1) + cfg.highlight(this.data.substring(j + 1, this.i - 5), node.attrs) +
|
||||
this.data.substr(this.i - 5);
|
||||
return this.i = j;
|
||||
} else if (name == 'style')
|
||||
this.CssHandler.getStyle(this.data.substring(j + 1, this.i - 7));
|
||||
else if (name == 'title')
|
||||
this.title = this.data.substring(j + 1, this.i - 7);
|
||||
if ((this.i = this.data.indexOf('>', this.i)) == -1) this.i = this.data.length;
|
||||
// 处理 svg
|
||||
if (name == 'svg') {
|
||||
var src = this.data.substring(j, this.i + 1);
|
||||
if (!node.attrs.xmlns) src = ' xmlns="http://www.w3.org/2000/svg"' + src;
|
||||
var i = j;
|
||||
while (this.data[j] != '<') j--;
|
||||
src = this.data.substring(j, i) + src;
|
||||
var parent = this.STACK[this.STACK.length - 1];
|
||||
if (node.attrs.width == '100%' && parent && (parent.attrs.style || '').includes('inline'))
|
||||
parent.attrs.style = 'width:300px;max-width:100%;' + parent.attrs.style;
|
||||
this.siblings().push({
|
||||
name: 'img',
|
||||
attrs: {
|
||||
src: 'data:image/svg+xml;utf8,' + src.replace(/#/g, '%23'),
|
||||
ignore: 'T'
|
||||
}
|
||||
})
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理属性
|
||||
matchAttr(node) {
|
||||
var attrs = node.attrs,
|
||||
style = this.CssHandler.match(node.name, attrs, node) + (attrs.style || ''),
|
||||
styleObj = {};
|
||||
if (attrs.id) {
|
||||
if (this.compress & 1) attrs.id = void 0;
|
||||
else if (this.useAnchor) this.bubble();
|
||||
}
|
||||
if ((this.compress & 2) && attrs.class) attrs.class = void 0;
|
||||
switch (node.name) {
|
||||
case 'img':
|
||||
if (attrs['data-src']) {
|
||||
attrs.src = attrs.src || attrs['data-src'];
|
||||
attrs['data-src'] = void 0;
|
||||
}
|
||||
if (attrs.src && !attrs.ignore) {
|
||||
if (this.bubble()) attrs.i = (this.imgNum++).toString();
|
||||
else attrs.ignore = 'T';
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
case 'ad':
|
||||
// #ifdef APP-PLUS
|
||||
case 'iframe':
|
||||
case 'embed':
|
||||
// #endif
|
||||
this.bubble();
|
||||
break;
|
||||
case 'font':
|
||||
if (attrs.color) {
|
||||
styleObj['color'] = attrs.color;
|
||||
attrs.color = void 0;
|
||||
}
|
||||
if (attrs.face) {
|
||||
styleObj['font-family'] = attrs.face;
|
||||
attrs.face = void 0;
|
||||
}
|
||||
if (attrs.size) {
|
||||
var size = parseInt(attrs.size);
|
||||
if (size < 1) size = 1;
|
||||
else if (size > 7) size = 7;
|
||||
var map = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'];
|
||||
styleObj['font-size'] = map[size - 1];
|
||||
attrs.size = void 0;
|
||||
}
|
||||
break;
|
||||
case 'video':
|
||||
case 'audio':
|
||||
if (!attrs.id) attrs.id = node.name + (++this[`${node.name}Num`]);
|
||||
else this[`${node.name}Num`]++;
|
||||
if (node.name == 'video') {
|
||||
if (attrs.width) {
|
||||
style = `width:${parseFloat(attrs.width) + (attrs.width.includes('%') ? '%' : 'px')};${style}`;
|
||||
attrs.width = void 0;
|
||||
}
|
||||
if (attrs.height) {
|
||||
style = `height:${parseFloat(attrs.height) + (attrs.height.includes('%') ? '%' : 'px')};${style}`;
|
||||
attrs.height = void 0;
|
||||
}
|
||||
if (this.videoNum > 3) node.lazyLoad = true;
|
||||
}
|
||||
attrs.source = [];
|
||||
if (attrs.src) attrs.source.push(attrs.src);
|
||||
if (!attrs.controls && !attrs.autoplay)
|
||||
console.warn(`存在没有 controls 属性的 ${node.name} 标签,可能导致无法播放`, node);
|
||||
this.bubble();
|
||||
break;
|
||||
case 'td':
|
||||
case 'th':
|
||||
if (attrs.colspan || attrs.rowspan)
|
||||
for (var k = this.STACK.length, item; item = this.STACK[--k];)
|
||||
if (item.name == 'table') {
|
||||
item.c = void 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (attrs.align) {
|
||||
styleObj['text-align'] = attrs.align;
|
||||
attrs.align = void 0;
|
||||
}
|
||||
// 压缩 style
|
||||
var styles = style.replace(/"/g, '"').replace(/&/g, '&').split(';');
|
||||
style = '';
|
||||
for (var i = 0, len = styles.length; i < len; i++) {
|
||||
var info = styles[i].split(':');
|
||||
if (info.length < 2) continue;
|
||||
let key = info[0].trim().toLowerCase(),
|
||||
value = info.slice(1).join(':').trim();
|
||||
if (value.includes('-webkit') || value.includes('-moz') || value.includes('-ms') || value.includes('-o') || value
|
||||
.includes(
|
||||
'safe'))
|
||||
style += `;${key}:${value}`;
|
||||
else if (!styleObj[key] || value.includes('import') || !styleObj[key].includes('import'))
|
||||
styleObj[key] = value;
|
||||
}
|
||||
if (node.name == 'img' && parseInt(styleObj.width || attrs.width) > screenWidth)
|
||||
styleObj.height = 'auto';
|
||||
for (var key in styleObj) {
|
||||
var value = styleObj[key];
|
||||
if (key.includes('flex') || key == 'order' || key == 'self-align') node.c = 1;
|
||||
// 填充链接
|
||||
if (value.includes('url')) {
|
||||
var j = value.indexOf('(');
|
||||
if (j++ != -1) {
|
||||
while (value[j] == '"' || value[j] == "'" || blankChar[value[j]]) j++;
|
||||
value = value.substr(0, j) + this.getUrl(value.substr(j));
|
||||
}
|
||||
}
|
||||
// 转换 rpx
|
||||
else if (value.includes('rpx'))
|
||||
value = value.replace(/[0-9.]+\s*rpx/g, $ => parseFloat($) * screenWidth / 750 + 'px');
|
||||
else if (key == 'white-space' && value.includes('pre'))
|
||||
this.pre = node.pre = true;
|
||||
style += `;${key}:${value}`;
|
||||
}
|
||||
style = style.substr(1);
|
||||
if (style) attrs.style = style;
|
||||
}
|
||||
// 节点出栈处理
|
||||
popNode(node) {
|
||||
// 空白符处理
|
||||
if (node.pre) {
|
||||
node.pre = this.pre = void 0;
|
||||
for (let i = this.STACK.length; i--;)
|
||||
if (this.STACK[i].pre)
|
||||
this.pre = true;
|
||||
}
|
||||
if (node.name == 'head' || (cfg.filter && cfg.filter(node, this) == false))
|
||||
return this.siblings().pop();
|
||||
var attrs = node.attrs;
|
||||
// 替换一些标签名
|
||||
if (node.name == 'picture') {
|
||||
node.name = 'img';
|
||||
if (!attrs.src && (node.children[0] || '').name == 'img')
|
||||
attrs.src = node.children[0].attrs.src;
|
||||
if (attrs.src && !attrs.ignore)
|
||||
attrs.i = (this.imgNum++).toString();
|
||||
return node.children = void 0;
|
||||
}
|
||||
if (cfg.blockTags[node.name]) node.name = 'div';
|
||||
else if (!cfg.trustTags[node.name]) node.name = 'span';
|
||||
// 处理列表
|
||||
if (node.c) {
|
||||
if (node.name == 'ul') {
|
||||
var floor = 1;
|
||||
for (let i = this.STACK.length; i--;)
|
||||
if (this.STACK[i].name == 'ul') floor++;
|
||||
if (floor != 1)
|
||||
for (let i = node.children.length; i--;)
|
||||
node.children[i].floor = floor;
|
||||
} else if (node.name == 'ol') {
|
||||
for (let i = 0, num = 1, child; child = node.children[i++];)
|
||||
if (child.name == 'li') {
|
||||
child.type = 'ol';
|
||||
child.num = ((num, type) => {
|
||||
if (type == 'a') return String.fromCharCode(97 + (num - 1) % 26);
|
||||
if (type == 'A') return String.fromCharCode(65 + (num - 1) % 26);
|
||||
if (type == 'i' || type == 'I') {
|
||||
num = (num - 1) % 99 + 1;
|
||||
var one = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'],
|
||||
ten = ['X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'],
|
||||
res = (ten[Math.floor(num / 10) - 1] || '') + (one[num % 10 - 1] || '');
|
||||
if (type == 'i') return res.toLowerCase();
|
||||
return res;
|
||||
}
|
||||
return num;
|
||||
})(num++, attrs.type) + '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理表格的边框
|
||||
if (node.name == 'table') {
|
||||
var padding = attrs.cellpadding,
|
||||
spacing = attrs.cellspacing,
|
||||
border = attrs.border;
|
||||
if (node.c) {
|
||||
this.bubble();
|
||||
if (!padding) padding = 2;
|
||||
if (!spacing) spacing = 2;
|
||||
}
|
||||
if (border) attrs.style = `border:${border}px solid gray;${attrs.style || ''}`;
|
||||
if (spacing) attrs.style = `border-spacing:${spacing}px;${attrs.style || ''}`;
|
||||
if (border || padding)
|
||||
(function f(ns) {
|
||||
for (var i = 0, n; n = ns[i]; i++) {
|
||||
if (n.name == 'th' || n.name == 'td') {
|
||||
if (border) n.attrs.style = `border:${border}px solid gray;${n.attrs.style}`;
|
||||
if (padding) n.attrs.style = `padding:${padding}px;${n.attrs.style}`;
|
||||
} else f(n.children || []);
|
||||
}
|
||||
})(node.children)
|
||||
}
|
||||
this.CssHandler.pop && this.CssHandler.pop(node);
|
||||
// 自动压缩
|
||||
if (node.name == 'div' && !Object.keys(attrs).length) {
|
||||
var siblings = this.siblings();
|
||||
if (node.children.length == 1 && node.children[0].name == 'div')
|
||||
siblings[siblings.length - 1] = node.children[0];
|
||||
}
|
||||
}
|
||||
// 工具函数
|
||||
bubble() {
|
||||
for (var i = this.STACK.length, item; item = this.STACK[--i];) {
|
||||
if (cfg.richOnlyTags[item.name]) {
|
||||
if (item.name == 'table' && !Object.hasOwnProperty.call(item, 'c')) item.c = 1;
|
||||
return false;
|
||||
}
|
||||
item.c = 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
getName = val => this.xml ? val : val.toLowerCase();
|
||||
getUrl(url) {
|
||||
if (url[0] == '/') {
|
||||
if (url[1] == '/') url = this.protocol + ':' + url;
|
||||
else if (this.domain) url = this.domain + url;
|
||||
} else if (this.domain && url.indexOf('data:') != 0 && !url.includes('://'))
|
||||
url = this.domain + '/' + url;
|
||||
return url;
|
||||
}
|
||||
isClose = () => this.data[this.i] == '>' || (this.data[this.i] == '/' && this.data[this.i + 1] == '>');
|
||||
section = () => this.data.substring(this.start, this.i);
|
||||
siblings = () => this.STACK.length ? this.STACK[this.STACK.length - 1].children : this.DOM;
|
||||
// 状态机
|
||||
Text(c) {
|
||||
if (c == '<') {
|
||||
var next = this.data[this.i + 1],
|
||||
isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
||||
if (isLetter(next)) {
|
||||
this.setText();
|
||||
this.start = this.i + 1;
|
||||
this.state = this.TagName;
|
||||
} else if (next == '/') {
|
||||
this.setText();
|
||||
if (isLetter(this.data[++this.i + 1])) {
|
||||
this.start = this.i + 1;
|
||||
this.state = this.EndTag;
|
||||
} else
|
||||
this.Comment();
|
||||
} else if (next == '!') {
|
||||
this.setText();
|
||||
this.Comment();
|
||||
}
|
||||
}
|
||||
}
|
||||
Comment() {
|
||||
var key;
|
||||
if (this.data.substring(this.i + 2, this.i + 4) == '--') key = '-->';
|
||||
else if (this.data.substring(this.i + 2, this.i + 9) == '[CDATA[') key = ']]>';
|
||||
else key = '>';
|
||||
if ((this.i = this.data.indexOf(key, this.i + 2)) == -1) this.i = this.data.length;
|
||||
else this.i += key.length - 1;
|
||||
this.start = this.i + 1;
|
||||
this.state = this.Text;
|
||||
}
|
||||
TagName(c) {
|
||||
if (blankChar[c]) {
|
||||
this.tagName = this.section();
|
||||
while (blankChar[this.data[this.i]]) this.i++;
|
||||
if (this.isClose()) this.setNode();
|
||||
else {
|
||||
this.start = this.i;
|
||||
this.state = this.AttrName;
|
||||
}
|
||||
} else if (this.isClose()) {
|
||||
this.tagName = this.section();
|
||||
this.setNode();
|
||||
}
|
||||
}
|
||||
AttrName(c) {
|
||||
var blank = blankChar[c];
|
||||
if (blank) {
|
||||
this.attrName = this.section();
|
||||
c = this.data[this.i];
|
||||
}
|
||||
if (c == '=') {
|
||||
if (!blank) this.attrName = this.section();
|
||||
while (blankChar[this.data[++this.i]]);
|
||||
this.start = this.i--;
|
||||
this.state = this.AttrValue;
|
||||
} else if (blank) this.setAttr();
|
||||
else if (this.isClose()) {
|
||||
this.attrName = this.section();
|
||||
this.setAttr();
|
||||
}
|
||||
}
|
||||
AttrValue(c) {
|
||||
if (c == '"' || c == "'") {
|
||||
this.start++;
|
||||
if ((this.i = this.data.indexOf(c, this.i + 1)) == -1) return this.i = this.data.length;
|
||||
this.attrVal = this.section();
|
||||
this.i++;
|
||||
} else {
|
||||
for (; !blankChar[this.data[this.i]] && !this.isClose(); this.i++);
|
||||
this.attrVal = this.section();
|
||||
}
|
||||
this.setAttr();
|
||||
}
|
||||
EndTag(c) {
|
||||
if (blankChar[c] || c == '>' || c == '/') {
|
||||
var name = this.getName(this.section());
|
||||
for (var i = this.STACK.length; i--;)
|
||||
if (this.STACK[i].name == name) break;
|
||||
if (i != -1) {
|
||||
var node;
|
||||
while ((node = this.STACK.pop()).name != name);
|
||||
this.popNode(node);
|
||||
} else if (name == 'p' || name == 'br')
|
||||
this.siblings().push({
|
||||
name,
|
||||
attrs: {}
|
||||
});
|
||||
this.i = this.data.indexOf('>', this.i);
|
||||
this.start = this.i + 1;
|
||||
if (this.i == -1) this.i = this.data.length;
|
||||
else this.state = this.Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = MpHtmlParser;
|
||||
@@ -0,0 +1,80 @@
|
||||
/* 配置文件 */
|
||||
// #ifdef MP-WEIXIN
|
||||
const canIUse = wx.canIUse('editor'); // 高基础库标识,用于兼容
|
||||
// #endif
|
||||
module.exports = {
|
||||
// 过滤器函数
|
||||
filter: null,
|
||||
// 代码高亮函数
|
||||
highlight: null,
|
||||
// 文本处理函数
|
||||
onText: null,
|
||||
blankChar: makeMap(' ,\xA0,\t,\r,\n,\f'),
|
||||
// 块级标签,将被转为 div
|
||||
blockTags: makeMap('address,article,aside,body,caption,center,cite,footer,header,html,nav,section' + (
|
||||
// #ifdef MP-WEIXIN
|
||||
canIUse ? '' :
|
||||
// #endif
|
||||
',pre')),
|
||||
// 将被移除的标签
|
||||
ignoreTags: makeMap(
|
||||
'area,base,basefont,canvas,command,frame,input,isindex,keygen,link,map,meta,param,script,source,style,svg,textarea,title,track,use,wbr'
|
||||
// #ifdef MP-WEIXIN
|
||||
+ (canIUse ? ',rp' : '')
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
+ ',embed,iframe'
|
||||
// #endif
|
||||
),
|
||||
// 只能被 rich-text 显示的标签
|
||||
richOnlyTags: makeMap('a,colgroup,fieldset,legend,picture,table'
|
||||
// #ifdef MP-WEIXIN
|
||||
+ (canIUse ? ',bdi,bdo,caption,rt,ruby' : '')
|
||||
// #endif
|
||||
),
|
||||
// 自闭合的标签
|
||||
selfClosingTags: makeMap(
|
||||
'area,base,basefont,br,col,circle,ellipse,embed,frame,hr,img,input,isindex,keygen,line,link,meta,param,path,polygon,rect,source,track,use,wbr'
|
||||
),
|
||||
// 信任的属性
|
||||
trustAttrs: makeMap(
|
||||
'align,alt,app-id,author,autoplay,border,cellpadding,cellspacing,class,color,colspan,controls,data-src,dir,face,height,href,id,ignore,loop,media,muted,name,path,poster,rowspan,size,span,src,start,style,type,unit-id,width,xmlns'
|
||||
),
|
||||
// bool 型的属性
|
||||
boolAttrs: makeMap('autoplay,controls,ignore,loop,muted'),
|
||||
// 信任的标签
|
||||
trustTags: makeMap(
|
||||
'a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,ul,video'
|
||||
// #ifdef MP-WEIXIN
|
||||
+ (canIUse ? ',bdi,bdo,caption,pre,rt,ruby' : '')
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
+ ',embed,iframe'
|
||||
// #endif
|
||||
),
|
||||
// 默认的标签样式
|
||||
userAgentStyles: {
|
||||
address: 'font-style:italic',
|
||||
big: 'display:inline;font-size:1.2em',
|
||||
blockquote: 'background-color:#f6f6f6;border-left:3px solid #dbdbdb;color:#6c6c6c;padding:5px 0 5px 10px',
|
||||
caption: 'display:table-caption;text-align:center',
|
||||
center: 'text-align:center',
|
||||
cite: 'font-style:italic',
|
||||
dd: 'margin-left:40px',
|
||||
img: 'max-width:100%',
|
||||
mark: 'background-color:yellow',
|
||||
picture: 'max-width:100%',
|
||||
pre: 'font-family:monospace;white-space:pre;overflow:scroll',
|
||||
s: 'text-decoration:line-through',
|
||||
small: 'display:inline;font-size:0.8em',
|
||||
u: 'text-decoration:underline'
|
||||
}
|
||||
}
|
||||
|
||||
function makeMap(str) {
|
||||
var map = {},
|
||||
list = str.split(',');
|
||||
for (var i = list.length; i--;)
|
||||
map[list[i]] = true;
|
||||
return map;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
var inlineTags = {
|
||||
abbr: 1,
|
||||
b: 1,
|
||||
big: 1,
|
||||
code: 1,
|
||||
del: 1,
|
||||
em: 1,
|
||||
i: 1,
|
||||
ins: 1,
|
||||
label: 1,
|
||||
q: 1,
|
||||
small: 1,
|
||||
span: 1,
|
||||
strong: 1
|
||||
}
|
||||
export default {
|
||||
// 从顶层标签的样式中取出一些给 rich-text
|
||||
getStyle: function(style) {
|
||||
if (style) {
|
||||
var i, j, res = '';
|
||||
if ((i = style.indexOf('display')) != -1)
|
||||
res = style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
|
||||
if ((i = style.indexOf('float')) != -1)
|
||||
res += ';' + style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
|
||||
return res;
|
||||
}
|
||||
},
|
||||
getNode: function(item) {
|
||||
return [item];
|
||||
},
|
||||
// 是否通过 rich-text 显示
|
||||
useRichText: function(item) {
|
||||
return !item.c && !inlineTags[item.name] && (item.attrs.style || '').indexOf('display:inline') == -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
var inlineTags = {
|
||||
abbr: 1,
|
||||
b: 1,
|
||||
big: 1,
|
||||
code: 1,
|
||||
del: 1,
|
||||
em: 1,
|
||||
i: 1,
|
||||
ins: 1,
|
||||
label: 1,
|
||||
q: 1,
|
||||
small: 1,
|
||||
span: 1,
|
||||
strong: 1
|
||||
}
|
||||
module.exports = {
|
||||
// 从顶层标签的样式中取出一些给 rich-text
|
||||
getStyle: function(style) {
|
||||
if (style) {
|
||||
var i, j, res = '';
|
||||
if ((i = style.indexOf('display')) != -1)
|
||||
res = style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
|
||||
if ((i = style.indexOf('float')) != -1)
|
||||
res += ';' + style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
|
||||
return res;
|
||||
}
|
||||
},
|
||||
// 处理懒加载
|
||||
getNode: function(item, imgLoad) {
|
||||
if (!imgLoad && item.attrs.i != '0') {
|
||||
var img = {
|
||||
name: 'img',
|
||||
attrs: JSON.parse(JSON.stringify(item.attrs))
|
||||
}
|
||||
delete img.attrs.src;
|
||||
img.attrs.style += ';width:20px;height:20px';
|
||||
return [img];
|
||||
} else return [item];
|
||||
},
|
||||
// 是否通过 rich-text 显示
|
||||
useRichText: function(item) {
|
||||
return !item.c && !inlineTags[item.name] && (item.attrs.style || '').indexOf('display:inline') == -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,476 @@
|
||||
<!--
|
||||
trees 递归显示组件
|
||||
github:https://github.com/jin-yufeng/Parser
|
||||
docs:https://jin-yufeng.github.io/Parser
|
||||
插件市场:https://ext.dcloud.net.cn/plugin?id=805
|
||||
author:JinYufeng
|
||||
update:2020/04/13
|
||||
-->
|
||||
<template>
|
||||
<view class="interlayer">
|
||||
<block v-for="(n, index) in nodes" v-bind:key="index">
|
||||
<!--图片-->
|
||||
<!--#ifdef MP-WEIXIN || MP-QQ || MP-ALIPAY || APP-PLUS-->
|
||||
<rich-text v-if="n.name=='img'" :id="n.attrs.id" class="_img" :style="''+handler.getStyle(n.attrs.style)" :nodes="handler.getNode(n,!lazyLoad||imgLoad)"
|
||||
:data-attrs="n.attrs" @tap="imgtap" @longpress="imglongtap" />
|
||||
<!--#endif-->
|
||||
<!--#ifdef MP-BAIDU || MP-TOUTIAO-->
|
||||
<rich-text v-if="n.name=='img'" :id="n.attrs.id" class="_img" :style="n.attrs.contain" :nodes='[n]' :data-attrs="n.attrs"
|
||||
@tap="imgtap" @longpress="imglongtap" />
|
||||
<!--#endif-->
|
||||
<!--文本-->
|
||||
<!--#ifdef MP-WEIXIN || MP-QQ || APP-PLUS-->
|
||||
<rich-text v-else-if="n.decode" class="_entity" :nodes="[n]"></rich-text>
|
||||
<!--#endif-->
|
||||
<text v-else-if="n.type=='text'" decode>{{n.text}}</text>
|
||||
<text v-else-if="n.name=='br'">\n</text>
|
||||
<!--视频-->
|
||||
<view v-else-if="n.name=='video'">
|
||||
<view v-if="(!loadVideo||n.lazyLoad)&&!(controls[n.attrs.id]&&controls[n.attrs.id].play)" :id="n.attrs.id" :class="'_video '+(n.attrs.class||'')"
|
||||
:style="n.attrs.style" @tap="_loadVideo" />
|
||||
<video v-else :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :autoplay="n.attrs.autoplay||(controls[n.attrs.id]&&controls[n.attrs.id].play)"
|
||||
:controls="n.attrs.controls" :loop="n.attrs.loop" :muted="n.attrs.muted" :poster="n.attrs.poster" :src="n.attrs.source[(controls[n.attrs.id]&&controls[n.attrs.id].index)||0]"
|
||||
:unit-id="n.attrs['unit-id']" :data-id="n.attrs.id" data-from="video" data-source="source" @error="error" @play="play" />
|
||||
</view>
|
||||
<!--音频-->
|
||||
<audio v-else-if="n.name=='audio'" :class="n.attrs.class" :style="n.attrs.style" :author="n.attrs.author" :autoplay="n.attrs.autoplay"
|
||||
:controls="n.attrs.controls" :loop="n.attrs.loop" :name="n.attrs.name" :poster="n.attrs.poster" :src="n.attrs.source[(controls[n.attrs.id]&&controls[n.attrs.id].index)||0]"
|
||||
:data-id="n.attrs.id" data-from="audio" data-source="source" @error="error" @play="play" />
|
||||
<!--链接-->
|
||||
<view v-else-if="n.name=='a'" :class="'_a '+(n.attrs.class||'')" hover-class="_hover" :style="n.attrs.style"
|
||||
:data-attrs="n.attrs" @tap="linkpress">
|
||||
<trees class="_span" :nodes="n.children" />
|
||||
</view>
|
||||
<!--广告(按需打开注释)-->
|
||||
<!--#ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO-->
|
||||
<!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :unit-id="n.attrs['unit-id']"
|
||||
data-from="ad" @error="error" />-->
|
||||
<!--#endif-->
|
||||
<!--#ifdef MP-BAIDU-->
|
||||
<!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :appid="n.attrs.appid"
|
||||
:apid="n.attrs.apid" :type="n.attrs.type" data-from="ad" @error="error" />-->
|
||||
<!--#endif-->
|
||||
<!--#ifdef APP-PLUS-->
|
||||
<!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :adpid="n.attrs.adpid"
|
||||
data-from="ad" @error="error" />-->
|
||||
<!--#endif-->
|
||||
<!--列表-->
|
||||
<view v-else-if="n.name=='li'" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:flex'">
|
||||
<view v-if="n.type=='ol'" class="_ol-bef">{{n.num}}</view>
|
||||
<view v-else class="_ul-bef">
|
||||
<view v-if="n.floor%3==0" class="_ul-p1">█</view>
|
||||
<view v-else-if="n.floor%3==2" class="_ul-p2" />
|
||||
<view v-else class="_ul-p1" style="border-radius:50%">█</view>
|
||||
</view>
|
||||
<!--#ifdef MP-ALIPAY-->
|
||||
<view class="_li">
|
||||
<trees :nodes="n.children" />
|
||||
</view>
|
||||
<!--#endif-->
|
||||
<!--#ifndef MP-ALIPAY-->
|
||||
<trees class="_li" :nodes="n.children" :lazyLoad="lazyLoad" :loadVideo="loadVideo" />
|
||||
<!--#endif-->
|
||||
</view>
|
||||
<!--表格-->
|
||||
<view v-else-if="n.name=='table'&&n.c" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:table'">
|
||||
<view v-for="(tbody, i) in n.children" v-bind:key="i" :class="tbody.attrs.class" :style="(tbody.attrs.style||'')+(tbody.name[0]=='t'?';display:table-'+(tbody.name=='tr'?'row':'row-group'):'')">
|
||||
<view v-for="(tr, j) in tbody.children" v-bind:key="j" :class="tr.attrs.class" :style="(tr.attrs.style||'')+(tr.name[0]=='t'?';display:table-'+(tr.name=='tr'?'row':'cell'):'')">
|
||||
<trees v-if="tr.name=='td'" :nodes="tr.children" :lazyLoad="lazyLoad" :loadVideo="loadVideo" />
|
||||
<block v-else>
|
||||
<!--#ifdef MP-ALIPAY-->
|
||||
<view v-for="(td, k) in tr.children" v-bind:key="k" :class="td.attrs.class" :style="(td.attrs.style||'')+(td.name[0]=='t'?';display:table-'+(td.name=='tr'?'row':'cell'):'')">
|
||||
<trees :nodes="td.children" />
|
||||
</view>
|
||||
<!--#endif-->
|
||||
<!--#ifndef MP-ALIPAY-->
|
||||
<trees v-for="(td, k) in tr.children" v-bind:key="k" :class="td.attrs.class" :style="(td.attrs.style||'')+(td.name[0]=='t'?';display:table-'+(td.name=='tr'?'row':'cell'):'')"
|
||||
:nodes="td.children" :lazyLoad="lazyLoad" :loadVideo="loadVideo" />
|
||||
<!--#endif-->
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!--#ifdef APP-PLUS-->
|
||||
<iframe v-else-if="n.name=='iframe'" :style="n.attrs.style" :allowfullscreen="n.attrs.allowfullscreen" :frameborder="n.attrs.frameborder"
|
||||
:width="n.attrs.width" :height="n.attrs.height" :src="n.attrs.src" />
|
||||
<embed v-else-if="n.name=='embed'" :style="n.attrs.style" :width="n.attrs.width" :height="n.attrs.height" :src="n.attrs.src" />
|
||||
<!--#endif-->
|
||||
<!--富文本-->
|
||||
<!--#ifdef MP-WEIXIN || MP-QQ || MP-ALIPAY || APP-PLUS-->
|
||||
<rich-text v-else-if="handler.useRichText(n)" :id="n.attrs.id" :class="'_p __'+n.name" :nodes="[n]" />
|
||||
<!--#endif-->
|
||||
<!--#ifdef MP-BAIDU || MP-TOUTIAO-->
|
||||
<rich-text v-else-if="!(n.c||n.continue)" :id="n.attrs.id" :class="_p" :style="n.attrs.contain" :nodes="[n]" />
|
||||
<!--#endif-->
|
||||
<!--#ifdef MP-ALIPAY-->
|
||||
<view v-else :id="n.attrs.id" :class="'_'+n.name+' '+(n.attrs.class||'')" :style="n.attrs.style">
|
||||
<trees :nodes="n.children" />
|
||||
</view>
|
||||
<!--#endif-->
|
||||
<!--#ifndef MP-ALIPAY-->
|
||||
<trees v-else :class="(n.attrs.id||'')+' _'+n.name+' '+(n.attrs.class||'')" :style="n.attrs.style" :nodes="n.children"
|
||||
:lazyLoad="lazyLoad" :loadVideo="loadVideo" />
|
||||
<!--#endif-->
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
<script module="handler" lang="wxs" src="./handler.wxs"></script>
|
||||
<script module="handler" lang="sjs" src="./handler.sjs"></script>
|
||||
<script>
|
||||
global.Parser = {};
|
||||
import trees from './trees'
|
||||
export default {
|
||||
components: {
|
||||
trees
|
||||
},
|
||||
name: 'trees',
|
||||
data() {
|
||||
return {
|
||||
controls: {},
|
||||
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
|
||||
imgLoad: false,
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
loadVideo: true
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
props: {
|
||||
nodes: Array,
|
||||
// #ifdef MP-WEIXIN || MP-QQ || H5 || APP-PLUS
|
||||
lazyLoad: Boolean,
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
loadVideo: Boolean
|
||||
// #endif
|
||||
},
|
||||
mounted() {
|
||||
// 获取顶层组件
|
||||
this.top = this.$parent;
|
||||
while (this.top.$options.name != 'parser') {
|
||||
if (this.top.top) {
|
||||
this.top = this.top.top;
|
||||
break;
|
||||
}
|
||||
this.top = this.top.$parent;
|
||||
}
|
||||
},
|
||||
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
|
||||
beforeDestroy() {
|
||||
if (this.observer)
|
||||
this.observer.disconnect();
|
||||
},
|
||||
// #endif
|
||||
methods: {
|
||||
// #ifndef MP-ALIPAY
|
||||
play(e) {
|
||||
if (this.top.videoContexts.length > 1 && this.top.autopause)
|
||||
for (var i = this.top.videoContexts.length; i--;)
|
||||
if (this.top.videoContexts[i].id != e.currentTarget.dataset.id)
|
||||
this.top.videoContexts[i].pause();
|
||||
},
|
||||
// #endif
|
||||
imgtap(e) {
|
||||
var attrs = e.currentTarget.dataset.attrs;
|
||||
if (!attrs.ignore) {
|
||||
var preview = true, data = {
|
||||
id: e.target.id,
|
||||
src: attrs.src,
|
||||
ignore: () => preview = false
|
||||
};
|
||||
global.Parser.onImgtap && global.Parser.onImgtap(data);
|
||||
this.top.$emit('imgtap', data);
|
||||
if (preview) {
|
||||
var urls = this.top.imgList,
|
||||
current = urls[attrs.i] ? parseInt(attrs.i) : (urls = [attrs.src], 0);
|
||||
uni.previewImage({
|
||||
current,
|
||||
urls
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
imglongtap(e) {
|
||||
var attrs = e.item.dataset.attrs;
|
||||
if (!attrs.ignore)
|
||||
this.top.$emit('imglongtap', {
|
||||
id: e.target.id,
|
||||
src: attrs.src
|
||||
})
|
||||
},
|
||||
linkpress(e) {
|
||||
var jump = true,
|
||||
attrs = e.currentTarget.dataset.attrs;
|
||||
attrs.ignore = () => jump = false;
|
||||
global.Parser.onLinkpress && global.Parser.onLinkpress(attrs);
|
||||
this.top.$emit('linkpress', attrs);
|
||||
if (jump) {
|
||||
// #ifdef MP
|
||||
if (attrs['app-id']) {
|
||||
return uni.navigateToMiniProgram({
|
||||
appId: attrs['app-id'],
|
||||
path: attrs.path
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
if (attrs.href) {
|
||||
if (attrs.href[0] == '#') {
|
||||
if (this.top.useAnchor)
|
||||
this.top.navigateTo({
|
||||
id: attrs.href.substring(1)
|
||||
})
|
||||
} else if (attrs.href.indexOf('http') == 0 || attrs.href.indexOf('//') == 0) {
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openWeb(attrs.href);
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
uni.setClipboardData({
|
||||
data: attrs.href,
|
||||
success: () =>
|
||||
uni.showToast({
|
||||
title: '链接已复制'
|
||||
})
|
||||
})
|
||||
// #endif
|
||||
} else
|
||||
uni.navigateTo({
|
||||
url: attrs.href
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
error(e) {
|
||||
var context, target = e.currentTarget,
|
||||
source = target.dataset.from;
|
||||
if (source == 'video' || source == 'audio') {
|
||||
// 加载其他 source
|
||||
var index = this.controls[target.id] ? this.controls[target.id].index + 1 : 1;
|
||||
if (index < target.dataset.source.length)
|
||||
this.$set(this.controls, target.id + '.index', index);
|
||||
if (source == 'video') context = uni.createVideoContext(target.id, this);
|
||||
}
|
||||
this.top && this.top.$emit('error', {
|
||||
source,
|
||||
target,
|
||||
errMsg: e.detail.errMsg,
|
||||
errCode: e.detail.errCode,
|
||||
context
|
||||
});
|
||||
},
|
||||
_loadVideo(e) {
|
||||
this.$set(this.controls, e.currentTarget.id, {
|
||||
play: true,
|
||||
index: 0
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 在这里引入自定义样式 */
|
||||
|
||||
/* 链接和图片效果 */
|
||||
._a {
|
||||
display: inline;
|
||||
color: #366092;
|
||||
word-break: break-all;
|
||||
padding: 1.5px 0 1.5px 0;
|
||||
}
|
||||
|
||||
._hover {
|
||||
opacity: 0.7;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
._img {
|
||||
display: inline-block;
|
||||
text-indent: 0;
|
||||
}
|
||||
|
||||
/* #ifdef MP-WEIXIN */
|
||||
:host {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
/* #ifdef MP */
|
||||
.interlayer {
|
||||
align-content: inherit;
|
||||
align-items: inherit;
|
||||
display: inherit;
|
||||
flex-direction: inherit;
|
||||
flex-wrap: inherit;
|
||||
justify-content: inherit;
|
||||
width: 100%;
|
||||
white-space: inherit;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
._b,
|
||||
._strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
._blockquote,
|
||||
._div,
|
||||
._p,
|
||||
._ol,
|
||||
._ul,
|
||||
._li {
|
||||
display: block;
|
||||
}
|
||||
|
||||
._code {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
._del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
._em,
|
||||
._i {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
._h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
._h2 {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
._h3 {
|
||||
font-size: 1.17em;
|
||||
}
|
||||
|
||||
._h5 {
|
||||
font-size: 0.83em;
|
||||
}
|
||||
|
||||
._h6 {
|
||||
font-size: 0.67em;
|
||||
}
|
||||
|
||||
._h1,
|
||||
._h2,
|
||||
._h3,
|
||||
._h4,
|
||||
._h5,
|
||||
._h6 {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
._ins {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
._li {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
._ol-bef {
|
||||
margin-right: 5px;
|
||||
text-align: right;
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
._ul-bef {
|
||||
line-height: normal;
|
||||
margin: 0 12px 0 23px;
|
||||
}
|
||||
|
||||
._ol-bef,
|
||||
._ul_bef {
|
||||
flex: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
._ul-p1 {
|
||||
display: inline-block;
|
||||
height: 0.3em;
|
||||
line-height: 0.3em;
|
||||
overflow: hidden;
|
||||
width: 0.3em;
|
||||
}
|
||||
|
||||
._ul-p2 {
|
||||
border: 0.05em solid black;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
height: 0.23em;
|
||||
width: 0.23em;
|
||||
}
|
||||
|
||||
._q::before {
|
||||
content: '"';
|
||||
}
|
||||
|
||||
._q::after {
|
||||
content: '"';
|
||||
}
|
||||
|
||||
._sub {
|
||||
font-size: smaller;
|
||||
vertical-align: sub;
|
||||
}
|
||||
|
||||
._sup {
|
||||
font-size: smaller;
|
||||
vertical-align: super;
|
||||
}
|
||||
|
||||
/* #ifndef MP-WEIXIN */
|
||||
._abbr,
|
||||
._b,
|
||||
._code,
|
||||
._del,
|
||||
._em,
|
||||
._i,
|
||||
._ins,
|
||||
._label,
|
||||
._q,
|
||||
._span,
|
||||
._strong,
|
||||
._sub,
|
||||
._sup {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
/* #ifdef MP-WEIXIN || MP-QQ || MP-ALIPAY */
|
||||
.__bdo,
|
||||
.__bdi,
|
||||
.__ruby,
|
||||
.__rt,
|
||||
._entity {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
._video {
|
||||
background-color: black;
|
||||
display: inline-block;
|
||||
height: 225px;
|
||||
position: relative;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
._video::after {
|
||||
border-color: transparent transparent transparent white;
|
||||
border-style: solid;
|
||||
border-width: 15px 0 15px 30px;
|
||||
content: '';
|
||||
left: 50%;
|
||||
margin: -15px 0 0 -15px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<view v-if="isUp">
|
||||
<view class="mobile-bg" v-if="isShow" @click="close"></view>
|
||||
<view class="mobile-mask animated" :class="{slideInUp:isUp}" :style="{position:isPos?'fixed':'static'}">
|
||||
<view class="input-item">
|
||||
<input type="text" v-model="account" placeholder="输入手机号" />
|
||||
</view>
|
||||
<view class="input-item">
|
||||
<input type="text" v-model="codeNum" placeholder="输入验证码" />
|
||||
<button class="code" :disabled="disabled" @click="code">{{text}}</button>
|
||||
</view>
|
||||
<view class="sub_btn" @click="loginBtn">{{(!userInfo.phone && isLogin) || (userInfo.phone && isLogin)?'立即绑定':'立即登录'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const app = getApp();
|
||||
import sendVerifyCode from "@/mixins/SendVerifyCode";
|
||||
import {mapGetters} from "vuex";
|
||||
import * as AuthApi from "@/api/member/auth";
|
||||
import * as UserApi from "@/api/member/user";
|
||||
import * as BrokerageAPI from '@/api/trade/brokerage.js'
|
||||
import { iosBinding } from '@/api/public';
|
||||
const BACK_URL = "login_back_url";
|
||||
export default {
|
||||
name: 'login_mobile',
|
||||
computed: mapGetters(['userInfo','isLogin']),
|
||||
props: {
|
||||
isUp: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
authKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
socialCode: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
socialState: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
isShow: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isPos: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
appleShow: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
platform: {
|
||||
type: String,
|
||||
default: '',
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
account: '',
|
||||
codeNum: '',
|
||||
isApp: 0
|
||||
}
|
||||
},
|
||||
mixins: [sendVerifyCode],
|
||||
methods: {
|
||||
// 获取验证码
|
||||
async code() {
|
||||
if (!this.account) {
|
||||
return this.$util.Tips({
|
||||
title: '请填写手机号码'
|
||||
});
|
||||
}
|
||||
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(this.account)) {
|
||||
return this.$util.Tips({
|
||||
title: '请输入正确的手机号码'
|
||||
});
|
||||
}
|
||||
await AuthApi.sendSmsCode(this.account, 1)
|
||||
.then(res => {
|
||||
this.$util.Tips({title:res.message});
|
||||
this.sendCode();
|
||||
})
|
||||
.catch(err => {
|
||||
return this.$util.Tips({
|
||||
title: err
|
||||
});
|
||||
});
|
||||
},
|
||||
close() {
|
||||
this.$emit('close', false)
|
||||
},
|
||||
// 登录
|
||||
loginBtn() {
|
||||
if (!this.account) {
|
||||
return this.$util.Tips({
|
||||
title: '请填写手机号码'
|
||||
});
|
||||
}
|
||||
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(this.account)) {
|
||||
return this.$util.Tips({
|
||||
title: '请输入正确的手机号码'
|
||||
});
|
||||
}
|
||||
if (!this.codeNum) return this.$util.Tips({
|
||||
title: '请填写验证码'
|
||||
});
|
||||
if (!/^[\w\d]+$/i.test(this.codeNum)) {
|
||||
return this.$util.Tips({
|
||||
title: '请输入正确的验证码'
|
||||
});
|
||||
}
|
||||
uni.showLoading({
|
||||
title: !this.userInfo.phone && this.isLogin?'正在绑定中':'正在登录中'
|
||||
});
|
||||
if (!this.userInfo.phone && this.isLogin) {
|
||||
// TODO 芋艿:不晓得它要搞啥哈???
|
||||
iosBinding({
|
||||
captcha: this.codeNum,
|
||||
phone: this.account
|
||||
}).then(res => {
|
||||
this.$util.Tips({
|
||||
title: '绑定手机号成功',
|
||||
icon: 'success'
|
||||
}, {
|
||||
tab: 3
|
||||
})
|
||||
this.isApp = 1;
|
||||
this.getUserInfo();
|
||||
}).catch(error => {
|
||||
uni.hideLoading()
|
||||
this.$util.Tips({
|
||||
title: error
|
||||
})
|
||||
})
|
||||
} else {
|
||||
AuthApi.smsLogin({
|
||||
mobile: this.account,
|
||||
code: this.codeNum,
|
||||
socialType: 31,
|
||||
socialCode: this.socialCode,
|
||||
socialState: this.socialState
|
||||
}).then(res => {
|
||||
// TODO 芋艿:refreshToken 机制
|
||||
let data = res.data;
|
||||
this.$store.commit("LOGIN", {
|
||||
'token': res.data.accessToken
|
||||
});
|
||||
this.getUserInfo(data);
|
||||
this.bindBrokerUser();
|
||||
}).catch(error => {
|
||||
uni.hideLoading()
|
||||
this.$util.Tips({
|
||||
title: error
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 获取个人用户信息
|
||||
*/
|
||||
getUserInfo: function(data) {
|
||||
this.$store.commit("SETUID", data.userId);
|
||||
this.$store.commit("OPENID", data.openid);
|
||||
UserApi.getUserInfo().then(res => {
|
||||
uni.hideLoading();
|
||||
this.$store.commit("UPDATE_USERINFO", res.data);
|
||||
// 调回登录前页面
|
||||
// #ifdef MP
|
||||
this.$util.Tips({
|
||||
title: '登录成功',
|
||||
icon: 'success'
|
||||
}, {
|
||||
tab: 3
|
||||
})
|
||||
this.close()
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
this.$emit('wechatPhone', true)
|
||||
// #endif
|
||||
});
|
||||
},
|
||||
bindBrokerUser() {
|
||||
const spread = this.$Cache.get("spread");
|
||||
if (spread > 0) {
|
||||
BrokerageAPI.bindBrokerageUser(spread)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.mobile-bg {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.isPos {
|
||||
position: static;
|
||||
}
|
||||
|
||||
.mobile-mask {
|
||||
z-index: 20;
|
||||
// position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 67rpx 30rpx;
|
||||
background: #fff;
|
||||
|
||||
.input-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 86rpx;
|
||||
margin-bottom: 38rpx;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
display: block;
|
||||
height: 100%;
|
||||
padding-left: 40rpx;
|
||||
border-radius: 43rpx;
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
.code {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 220rpx;
|
||||
height: 86rpx;
|
||||
margin-left: 30rpx;
|
||||
background: rgba(233, 51, 35, 0.05);
|
||||
font-size: 28rpx;
|
||||
color: $theme-color;
|
||||
border-radius: 43rpx;
|
||||
|
||||
&[disabled] {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sub_btn {
|
||||
width: 690rpx;
|
||||
height: 86rpx;
|
||||
line-height: 86rpx;
|
||||
margin-top: 60rpx;
|
||||
background: #E93323;
|
||||
border-radius: 43rpx;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.animated {
|
||||
animation-duration: .4s
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<view v-if="isPhoneBox">
|
||||
<view class="mobile-bg" @click="close"></view>
|
||||
<view class="mobile-mask animated" :class="{slideInUp:isUp}">
|
||||
<view class="info-box">
|
||||
<image :src="logoUrl"></image>
|
||||
<view class="title">获取授权</view>
|
||||
<view class="txt">获取微信的手机号授权</view>
|
||||
</view>
|
||||
<button class="sub_btn" open-type="getPhoneNumber" @getphonenumber="getphonenumber">获取微信手机号</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const app = getApp();
|
||||
import Routine from '@/libs/routine';
|
||||
import {
|
||||
loginMobile,
|
||||
registerVerify,
|
||||
getCodeApi,
|
||||
getUserInfo
|
||||
} from "@/api/user";
|
||||
import { getLogo, getUserPhone } from '@/api/public';
|
||||
export default{
|
||||
name:'routine_phone',
|
||||
props:{
|
||||
isPhoneBox:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
},
|
||||
logoUrl:{
|
||||
type:String,
|
||||
default:'',
|
||||
},
|
||||
authKey:{
|
||||
type:String,
|
||||
default:'',
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
keyCode:'',
|
||||
account:'',
|
||||
codeNum:'',
|
||||
isStatus:false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods:{
|
||||
// #ifdef MP
|
||||
// 小程序获取手机号码
|
||||
getphonenumber(e){
|
||||
uni.showLoading({ title: '加载中' });
|
||||
Routine.getCode()
|
||||
.then(code => {
|
||||
this.getUserPhoneNumber(e.detail.encryptedData, e.detail.iv, code);
|
||||
})
|
||||
.catch(error => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
},
|
||||
// 小程序获取手机号码回调
|
||||
getUserPhoneNumber(encryptedData, iv, code) {
|
||||
getUserPhone({
|
||||
encryptedData: encryptedData,
|
||||
iv: iv,
|
||||
code: code,
|
||||
key:this.authKey,
|
||||
type: 'routine'
|
||||
})
|
||||
.then(res => {
|
||||
this.$store.commit('LOGIN', {
|
||||
token: res.data.token
|
||||
});
|
||||
this.$store.commit("SETUID", res.data.uid);
|
||||
this.getUserInfo();
|
||||
})
|
||||
.catch(res => {
|
||||
uni.hideLoading();
|
||||
this.$util.Tips({
|
||||
title: res
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取个人用户信息
|
||||
*/
|
||||
getUserInfo: function() {
|
||||
let that = this;
|
||||
getUserInfo().then(res => {
|
||||
uni.hideLoading();
|
||||
that.userInfo = res.data
|
||||
that.$store.commit("UPDATE_USERINFO", res.data);
|
||||
that.isStatus = true
|
||||
this.close()
|
||||
});
|
||||
},
|
||||
// #endif
|
||||
close(){
|
||||
this.$emit('close',{isStatus:this.isStatus})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.mobile-bg{
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.5);
|
||||
}
|
||||
.mobile-mask {
|
||||
z-index: 20;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 67rpx 30rpx;
|
||||
background: #fff;
|
||||
.info-box{
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
image{
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.title{
|
||||
margin-top: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
.txt{
|
||||
font-size: 30rpx;
|
||||
color: #868686;
|
||||
}
|
||||
}
|
||||
.sub_btn{
|
||||
width: 690rpx;
|
||||
height: 86rpx;
|
||||
line-height: 86rpx;
|
||||
margin-top: 60rpx;
|
||||
background: $theme-color;
|
||||
border-radius: 43rpx;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.animated{
|
||||
animation-duration:.4s
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,406 @@
|
||||
.mpvue-calendar {
|
||||
margin:auto;
|
||||
width: 100%;
|
||||
min-width:350px;
|
||||
background: #fff;
|
||||
user-select:none;
|
||||
position: relative;
|
||||
}
|
||||
.calendar-tools{
|
||||
height:40px;
|
||||
font-size: 20px;
|
||||
line-height: 40px;
|
||||
color:#5e7a88;
|
||||
box-shadow: 0px 4px 8px rgba(25, 47, 89, 0.1);
|
||||
margin-bottom: 20px;
|
||||
border-top: 1px solid rgba(200, 200, 200, .1);
|
||||
}
|
||||
.calendar-tools span{
|
||||
cursor: pointer;
|
||||
}
|
||||
.calendar-prev{
|
||||
width: 14.28571429%;
|
||||
float:left;
|
||||
text-align: center;
|
||||
}
|
||||
.calendar-prev img, .calendar-next img{
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
}
|
||||
.calendar-info{
|
||||
font-size:16px;
|
||||
line-height: 1.3;
|
||||
text-align: center;
|
||||
width: 220px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.calendar-info>div.mc-month{
|
||||
margin:auto;
|
||||
height:24px;
|
||||
width:100px;
|
||||
text-align: center;
|
||||
color:#5e7a88;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.calendar-info>div.mc-month .mc-month-inner{
|
||||
position: absolute;
|
||||
left:0;
|
||||
top:0;
|
||||
height:480px;
|
||||
}
|
||||
.month-transition{
|
||||
transition:top .5s cubic-bezier(0.075, 0.82, 0.165, 1);
|
||||
}
|
||||
.calendar-info .mc-month-text{
|
||||
display:block;
|
||||
font-size:28px;
|
||||
height:40px;
|
||||
width:200px;
|
||||
overflow:hidden;
|
||||
text-align:center;
|
||||
}
|
||||
.calendar-info>div.mc-month .mc-month-inner>span{
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
height:24px;
|
||||
line-height:24px;
|
||||
width:100px;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
}
|
||||
.calendar-info>div.mc-year{
|
||||
font-size:10px;
|
||||
line-height: 1;
|
||||
color:#999;
|
||||
}
|
||||
.calendar-next{
|
||||
width: 14.28571429%;
|
||||
float:right;
|
||||
text-align: center;
|
||||
}
|
||||
.mpvue-calendar table {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
margin-bottom:10px;
|
||||
border-collapse: collapse;
|
||||
color: #444444;
|
||||
}
|
||||
.mpvue-calendar td {
|
||||
margin:2px !important;
|
||||
padding: 4px;
|
||||
width: 14.28571429%;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
font-size:14px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
}
|
||||
.mpvue-calendar td.mc-week{
|
||||
font-size:10px;
|
||||
pointer-events:none !important;
|
||||
cursor: default !important;
|
||||
}
|
||||
.mpvue-calendar td.disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
.mpvue-calendar td.disabled div{
|
||||
color: #ccc;
|
||||
}
|
||||
.mpvue-calendar td span{
|
||||
display:block;
|
||||
height:100%;
|
||||
width:100%;
|
||||
margin:0px auto;
|
||||
border-radius:50%;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
.mpvue-calendar td:not(.disabled) span.mc-date-red{
|
||||
color:#ea6151;
|
||||
}
|
||||
.mc-today{
|
||||
color: #3b75fb;
|
||||
}
|
||||
.mpvue-calendar td.selected span{
|
||||
background-color: #3b75fb;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.mpvue-calendar td .mc-text{
|
||||
box-sizing: border-box;
|
||||
height: 0.7em;
|
||||
overflow: hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space: nowrap;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
font-size: 0.7em;
|
||||
line-height: 0.7em;
|
||||
z-index: 4;
|
||||
}
|
||||
.mpvue-calendar td .isGregorianFestival,
|
||||
.mpvue-calendar td .isTerm,
|
||||
.mpvue-calendar td .isLunarFestival{
|
||||
color:#ea6151;
|
||||
}
|
||||
.mpvue-calendar td.selected span.mc-date-red{
|
||||
background-color: #3b75fb;
|
||||
color: #fff;
|
||||
}
|
||||
.selected .mc-text {
|
||||
color: #fff !important;
|
||||
}
|
||||
.mpvue-calendar .lunarStyle .mc-text{
|
||||
overflow: visible;
|
||||
bottom: 20%;
|
||||
}
|
||||
.mpvue-calendar thead td {
|
||||
text-transform: uppercase;
|
||||
height:30px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.mc-head {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.mc-head div {
|
||||
overflow: hidden;
|
||||
}
|
||||
.mc-head-box div {
|
||||
flex:1;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
}
|
||||
.mc-head-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-content: space-between
|
||||
}
|
||||
.mc-body {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.mc-body tr {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-content: space-between;
|
||||
}
|
||||
.mc-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: #ea6151;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
left: 50%;
|
||||
margin-left: -4px;
|
||||
z-index: 5;
|
||||
}
|
||||
.remark-text {
|
||||
box-sizing: border-box;
|
||||
height: 0.7em;
|
||||
overflow: hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space: nowrap;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
font-size: 0.7em;
|
||||
line-height: 0.7em;
|
||||
z-index: 5;
|
||||
}
|
||||
.slot-element{
|
||||
line-height: normal;
|
||||
position: absolute;
|
||||
z-index: 5;
|
||||
}
|
||||
.mpvue-calendar-change{
|
||||
position: absolute;
|
||||
left:0px;
|
||||
top:42px;
|
||||
right:0px;
|
||||
bottom:0px;
|
||||
background:#fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap:wrap;
|
||||
overflow: auto;
|
||||
transition:all .5s cubic-bezier(0.075, 0.82, 0.165, 1);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transform: translateY(-10px);
|
||||
z-index: 9;
|
||||
}
|
||||
.mpvue-calendar-change.show{
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
.mpvue-calendar-change span{
|
||||
margin:4px 2%;
|
||||
display: inline-block;
|
||||
line-height: 30px;
|
||||
border-radius: 20px;
|
||||
text-align:center;
|
||||
color:#999;
|
||||
width: 20%;
|
||||
float: left;
|
||||
text-align: center;
|
||||
border-radius: 40px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 4%;
|
||||
cursor: pointer;
|
||||
}
|
||||
.mpvue-calendar-change span.active{
|
||||
background-color: #587dff;
|
||||
box-shadow: 2px 2px 2px rgba(88, 125, 255, 0.7);
|
||||
color:#fff;
|
||||
}
|
||||
.mpvue-calendar-change .calendar-week-switch-months{
|
||||
height: 100%;
|
||||
}
|
||||
.mpvue-calendar-change .calendar-week-switch-months span {
|
||||
margin-bottom: 10px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
.calendar-years, .calendar-months{
|
||||
height: 50%;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
.calendar-years:after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 86%;
|
||||
height: 1px;
|
||||
background-color: #eee;
|
||||
position: absolute;
|
||||
bottom: 2%;
|
||||
left: 7%;
|
||||
}
|
||||
/*range background*/
|
||||
.mc-range-mode .selected .mc-range-bg{
|
||||
content: '';
|
||||
display: block;
|
||||
width: 150%;
|
||||
height: 100%;
|
||||
background-color: #01a1ed;
|
||||
position: relative;
|
||||
top: -100%;
|
||||
left: 50%;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .selected .calendar-date{
|
||||
background-color: transparent;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .mc-range-row-last .calendar-date, .mpvue-calendar .mc-range-mode .mc-range-row-first .calendar-date{
|
||||
border-radius: 4px;
|
||||
background-color: #01a1ed;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .mc-range-month-first.selected .calendar-date, .mpvue-calendar .mc-range-mode .mc-range-month-last.selected .calendar-date{
|
||||
background-color: #01a1ed;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.mc-range-mode .mc-range-month-last .mc-range-bg{
|
||||
background-color: transparent;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.mc-range-mode .mc-range-end .mc-range-bg, .mc-range-mode .mc-range-row-last .mc-range-bg{
|
||||
display: none;
|
||||
}
|
||||
.mc-range-row-first.mc-range-end .mc-range-bg{
|
||||
display: block;
|
||||
margin-left: -50%;
|
||||
width: 50%;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.mpvue-calendar .mc-range-row-first.mc-range-end.month-first-date .mc-range-bg{
|
||||
margin-left: 0px;
|
||||
}
|
||||
.mc-range-row-last.mc-range-begin .mc-range-bg{
|
||||
display: block;
|
||||
width: 50%;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .selected.mc-range-second-to-last span{
|
||||
background-color: #01a1ed;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.mc-range-begin.mc-range-second-to-last{
|
||||
background-color: #01a1ed;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .mc-range-end span.calendar-date, .mpvue-calendar .mc-range-mode .mc-range-begin span.calendar-date{
|
||||
background-color: #3b75fb;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .month-last-date.mc-range-begin .mc-range-bg{
|
||||
display: block;
|
||||
width: 50%;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .month-first-date.mc-range-end .mc-range-bg{
|
||||
display: block;
|
||||
width: 50%;
|
||||
border-radius: 4px;
|
||||
left: 0px;
|
||||
}
|
||||
.calendar-wrapper .mpvue-calendar .mc-range-mode .mc-range-select-one div.mc-range-bg{
|
||||
display: none;
|
||||
}
|
||||
.mc-range-mode .mc-range-second-to-last .mc-range-bg{
|
||||
border-radius: 0px 25% 25% 0px;
|
||||
}
|
||||
.mc-today-element .calendar-date{
|
||||
background-color: rgba(25, 47, 89, 0.1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
/*week switch*/
|
||||
.mpvue-calendar .mc-range-mode.week-switch .month-last-date.mc-range-begin .mc-range-bg{
|
||||
width: 150%;
|
||||
border-radius: 0px 20% 20% 0px;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode.week-switch .mc-range-month-last .mc-range-bg{
|
||||
background-color: #01a1ed;
|
||||
border-radius: 0px 20% 20% 0px;
|
||||
}
|
||||
/*month range*/
|
||||
.mpvue-calendar .month-range-mode{
|
||||
border-bottom: 1px solid #f2f2f2;
|
||||
position: relative;
|
||||
}
|
||||
.mpvue-calendar .mc-month-range-mode-head{
|
||||
box-shadow: 0 4px 8px rgba(25,47,89,.1);
|
||||
padding: 8px 0px;
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
background-color: #fff;
|
||||
z-index: 9;
|
||||
}
|
||||
.month-range-mode .month-rang-head {
|
||||
text-align: left;
|
||||
margin: 10px 0px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.month-range-mode .mc-last-month, .month-range-mode .mc-next-month{
|
||||
opacity: 0 !important;
|
||||
}
|
||||
.month-text-background{
|
||||
position: absolute;
|
||||
font-size: 140px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
line-height: 2.4;
|
||||
}
|
||||
@@ -0,0 +1,524 @@
|
||||
/**
|
||||
* @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
|
||||
@@ -0,0 +1,15 @@
|
||||
@font-face {font-family: "iconfont";
|
||||
src: url('data:font/truetype;charset=utf-8;base64,d09GRgABAAAAAASEAAsAAAAABuwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY7d0f0Y21hcAAAAYAAAABTAAABhmJUzs9nbHlmAAAB1AAAALcAAADIzC0F5mhlYWQAAAKMAAAALwAAADYS7IZUaGhlYQAAArwAAAAcAAAAJAfeA4RobXR4AAAC2AAAAAwAAAAMDAAAAGxvY2EAAALkAAAACAAAAAgANgBkbWF4cAAAAuwAAAAfAAAAIAEOACluYW1lAAADDAAAAUUAAAJtPlT+fXBvc3QAAARUAAAALQAAAEOUPjuMeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMj5jYm7438AQw9zA0AAUZgTJAQDdSgvleJztkMERgDAIBPdIzMOxEB8W5MvuTRsRMHbhzSwHR/IBWIDiHE4FXYjQ6akyL6yZ13zT3IXd6jYGfO6S75q7xT81fm1Z9zlZXOsl+j5BD35IDU4AeJwVzUEOwUAYBeD/mfxTEso/mkEJoYluqgtajUjYsHEOSytncROJK/QErjNMd+8lL+8jEP3eqq8uNCPiokK1L4t1ihzVCSPMEekAep3mQCh4tpVm95JWz2QGj3iyiN3LZMJBODU49IMuDxk32YifuI89X4+xqwcsHUtEjfVVWt1p5MvWNs9RY4RowNLrJ7Tq8ZKNN7wmvMp8jBc7PDpW3RPfPrISV5ss4QEO9pxcdrix/gMMIyHOAHicY2BkYGAAYmNBZtV4fpuvDNwsDCBw/dlCBQT9fzMLA3MKkMvBwAQSBQDyNAlAAHicY2BkYGBu+N/AEMPCAAJAkpEBFTADAEcJAmwEAAAABAAAAAQAAAAAAAAAADYAZHicY2BkYGBgZpBlANEMDExAzAWEDAz/wXwGAAuHATgAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicY2BigAAuBuyAmZGJkZmRhYEnKzMxryS/tDgjMS+dC8qpzC9lYAAAiPIJlAAAAA==');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family:"iconfont" !important;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-arrow-right:before { content: "\e602"; }
|
||||
|
||||
.icon-arrow-left:before { content: "\e501"; }
|
||||
@@ -0,0 +1,394 @@
|
||||
.mpvue-calendar {
|
||||
margin:auto;
|
||||
width: 100%;
|
||||
min-width:300rpx;
|
||||
background: #fff;
|
||||
user-select:none;
|
||||
position: relative;
|
||||
}
|
||||
.calendar-tools{
|
||||
height:40px;
|
||||
font-size: 20px;
|
||||
line-height: 40px;
|
||||
color:#5e7a88;
|
||||
box-shadow: 0rpx 4rpx 8rpx rgba(25, 47, 89, 0.1);
|
||||
margin-bottom: 30rpx;
|
||||
border-top: 1px solid rgba(200, 200, 200, .1);
|
||||
}
|
||||
.calendar-prev{
|
||||
width: 14.28571429%;
|
||||
float:left;
|
||||
text-align: center;
|
||||
}
|
||||
.calendar-prev img, .calendar-next img{
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
}
|
||||
.calendar-info{
|
||||
padding-top: 3px;
|
||||
font-size:16px;
|
||||
line-height: 1.3;
|
||||
text-align: center;
|
||||
width: 220rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.calendar-info>div.mc-month{
|
||||
margin:auto;
|
||||
height:40rpx;
|
||||
width:100px;
|
||||
text-align: center;
|
||||
color:#5e7a88;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.calendar-info>div.mc-month .mc-month-inner{
|
||||
position: absolute;
|
||||
left:0;
|
||||
top:0;
|
||||
height:480rpx;
|
||||
}
|
||||
.month-transition{
|
||||
transition:top .5s cubic-bezier(0.075, 0.82, 0.165, 1);
|
||||
}
|
||||
.calendar-info .mc-month-text{
|
||||
display:block;
|
||||
font-size:28rpx;
|
||||
height:40rpx;
|
||||
width:200rpx;
|
||||
overflow:hidden;
|
||||
text-align:center;
|
||||
}
|
||||
.calendar-info>div.mc-month .mc-month-inner>span{
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
height:20px;
|
||||
width:100px;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
}
|
||||
.calendar-info>div.mc-year{
|
||||
font-size:10px;
|
||||
line-height: 1;
|
||||
color:#999;
|
||||
}
|
||||
.calendar-next{
|
||||
width: 14.28571429%;
|
||||
float:right;
|
||||
text-align: center;
|
||||
}
|
||||
.mpvue-calendar table {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
margin-bottom:10px;
|
||||
border-collapse: collapse;
|
||||
color: #444444;
|
||||
}
|
||||
.mpvue-calendar td {
|
||||
margin:2px !important;
|
||||
padding:0px 0;
|
||||
width: 14.28571429%;
|
||||
height:88rpx;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
font-size:14px;
|
||||
line-height: 125%;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
}
|
||||
.mpvue-calendar td.mc-week{
|
||||
font-size:10px;
|
||||
pointer-events:none !important;
|
||||
cursor: default !important;
|
||||
}
|
||||
.mpvue-calendar td.disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
.mpvue-calendar td.disabled div{
|
||||
color: #ccc;
|
||||
}
|
||||
.mpvue-calendar td span{
|
||||
display:block;
|
||||
height:76rpx;
|
||||
width:76rpx;
|
||||
font-size: 28rpx;
|
||||
line-height:76rpx;
|
||||
margin:0px auto;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
.mpvue-calendar td:not(.disabled) span.mc-date-red{
|
||||
color:#ea6151;
|
||||
}
|
||||
.mc-today{
|
||||
color: #3b75fb;
|
||||
}
|
||||
.mpvue-calendar td.selected span{
|
||||
background-color: #3b75fb;
|
||||
color: #fff;
|
||||
border-radius:50%;
|
||||
}
|
||||
.mpvue-calendar td .mc-text{
|
||||
position: absolute;
|
||||
top:28px;
|
||||
left:0;
|
||||
right:0;
|
||||
text-align: center;
|
||||
padding:2px;
|
||||
font-size:20rpx;
|
||||
line-height: 1.2;
|
||||
color:#444;
|
||||
z-index: 4;
|
||||
}
|
||||
.mpvue-calendar td .isGregorianFestival,
|
||||
.mpvue-calendar td .isTerm,
|
||||
.mpvue-calendar td .isLunarFestival{
|
||||
color:#ea6151;
|
||||
}
|
||||
.mpvue-calendar td.selected span.mc-date-red{
|
||||
background-color: #3b75fb;
|
||||
color: #fff;
|
||||
}
|
||||
.selected .mc-text {
|
||||
color: #fff !important;
|
||||
}
|
||||
.mpvue-calendar .lunarStyle span{
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
line-height:54rpx;
|
||||
}
|
||||
.mpvue-calendar .lunarStyle .mc-text{
|
||||
top: 44rpx;
|
||||
}
|
||||
.mpvue-calendar thead td {
|
||||
text-transform: uppercase;
|
||||
height:30px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.mc-head {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.mc-head div {
|
||||
overflow: hidden;
|
||||
}
|
||||
.mc-head-box div {
|
||||
flex:1;
|
||||
text-align: center;
|
||||
}
|
||||
.mc-head-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-content: space-between
|
||||
}
|
||||
.mc-head-box div {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.mc-body tr {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-content: space-between
|
||||
}
|
||||
.mc-dot {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
background-color: #ea6151;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
margin-top: 5rpx;
|
||||
position: absolute;
|
||||
bottom: -5rpx;
|
||||
left: 50%;
|
||||
margin-left: -5rpx;
|
||||
z-index: 5;
|
||||
}
|
||||
.remark-text {
|
||||
padding-left: 8rpx;
|
||||
padding-right: 8rpx;
|
||||
box-sizing: border-box;
|
||||
height: 34rpx;
|
||||
overflow: hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.slot-element{
|
||||
line-height: normal;
|
||||
position: absolute;
|
||||
z-index: 5;
|
||||
}
|
||||
.mpvue-calendar-change{
|
||||
position: absolute;
|
||||
left:0rpx;
|
||||
top:85rpx;
|
||||
right:0rpx;
|
||||
bottom:0rpx;
|
||||
background:#fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap:wrap;
|
||||
overflow: auto;
|
||||
transition:all .5s cubic-bezier(0.075, 0.82, 0.165, 1);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transform: translateY(-10px);
|
||||
z-index: 9;
|
||||
}
|
||||
.mpvue-calendar-change.show{
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
.mpvue-calendar-change span{
|
||||
margin:4px 2%;
|
||||
display: inline-block;
|
||||
line-height: 30px;
|
||||
border-radius: 20px;
|
||||
text-align:center;
|
||||
color:#999;
|
||||
width: 20%;
|
||||
float: left;
|
||||
text-align: center;
|
||||
border-radius: 40px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 4%;
|
||||
}
|
||||
.mpvue-calendar-change span.active{
|
||||
background-color: #587dff;
|
||||
box-shadow: 2px 2px 2px rgba(88, 125, 255, 0.7);
|
||||
color:#fff;
|
||||
}
|
||||
.mpvue-calendar-change .calendar-week-switch-months{
|
||||
height: 100%;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
.mpvue-calendar-change .calendar-week-switch-months span {
|
||||
margin-bottom: 20rpx;
|
||||
margin-top: 0px;
|
||||
font-size: 26rpx;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
.calendar-years, .calendar-months{
|
||||
height: 50%;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
.calendar-years:after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 86%;
|
||||
height: 1rpx;
|
||||
background-color: #eee;
|
||||
position: absolute;
|
||||
bottom: 2%;
|
||||
left: 7%;
|
||||
}
|
||||
/*range background*/
|
||||
.mc-range-mode .selected .mc-range-bg{
|
||||
content: '';
|
||||
display: block;
|
||||
width: 110rpx;
|
||||
height: 80rpx;
|
||||
background-color: #01a1ed;
|
||||
position: absolute;
|
||||
top: 0rpx;
|
||||
left: 50%;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .selected .calendar-date{
|
||||
background-color: transparent;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .mc-range-row-last span.calendar-date, .mpvue-calendar .mc-range-mode .mc-range-row-first span.calendar-date{
|
||||
border-radius: 6rpx;
|
||||
background-color: #01a1ed;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .mc-range-month-first.selected .calendar-date, .mpvue-calendar .mc-range-mode .mc-range-month-last.selected .calendar-date{
|
||||
border-radius: 6rpx;
|
||||
background-color: #01a1ed;
|
||||
}
|
||||
.mc-range-mode .mc-range-month-last .mc-range-bg{
|
||||
background-color: transparent;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
.mc-range-mode .mc-range-end .mc-range-bg, .mc-range-mode .mc-range-row-last .mc-range-bg{
|
||||
display: none;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .mc-range-end span.calendar-date, .mpvue-calendar .mc-range-mode .mc-range-begin span.calendar-date{
|
||||
background-color: #3b75fb;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.mc-range-mode .mc-range-row-first.mc-range-end .mc-range-bg{
|
||||
display: block;
|
||||
border-radius: 6rpx;
|
||||
width: 40rpx;
|
||||
left: 5px;
|
||||
}
|
||||
.mpvue-calendar .mc-range-row-first.mc-range-end.month-first-date .mc-range-bg{
|
||||
margin-left: 0px;
|
||||
}
|
||||
.mc-range-mode .mc-range-row-last.mc-range-begin .mc-range-bg{
|
||||
display: block;
|
||||
border-radius: 4rpx;
|
||||
width: 40rpx;
|
||||
right: 10px;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .month-last-date.mc-range-begin .mc-range-bg{
|
||||
display: block;
|
||||
width: 40rpx;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .month-first-date.mc-range-end .mc-range-bg{
|
||||
display: block;
|
||||
width: 40rpx;
|
||||
border-radius: 6rpx;
|
||||
left: 10rpx;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode .mc-range-select-one div.mc-range-bg{
|
||||
display: none !important;
|
||||
}
|
||||
.mc-body .mc-today-element .calendar-date{
|
||||
background-color: rgba(25, 47, 89, 0.1);
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
/*week switch*/
|
||||
.mpvue-calendar .mc-range-mode.week-switch .month-last-date.mc-range-begin .mc-range-bg{
|
||||
width: 130%;
|
||||
border-radius: 0px 20% 20% 0px;
|
||||
}
|
||||
.mpvue-calendar .mc-range-mode.week-switch .mc-range-month-last .mc-range-bg{
|
||||
background-color: #01a1ed;
|
||||
border-radius: 0px 20% 20% 0px;
|
||||
}
|
||||
/*month range*/
|
||||
.mpvue-calendar .month-range-mode{
|
||||
border-bottom: 1px solid #f2f2f2;
|
||||
position: relative;
|
||||
}
|
||||
.mpvue-calendar .mc-month-range-mode-head{
|
||||
box-shadow: 0 4px 8px rgba(25,47,89,.1);
|
||||
padding: 15rpx 0rpx;
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
background-color: #fff;
|
||||
z-index: 9;
|
||||
}
|
||||
.month-range-mode .month-rang-head {
|
||||
text-align: left;
|
||||
margin: 20rpx 0px;
|
||||
padding-left: 40rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.month-range-mode .mc-last-month, .month-range-mode .mc-next-month{
|
||||
opacity: 0 !important;
|
||||
}
|
||||
.month-text-background{
|
||||
position: absolute;
|
||||
font-size: 140px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
line-height: 2.4;
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<view class="number-box">
|
||||
<block v-for="(myIndex, index) in indexArr" :key="index">
|
||||
<swiper class="swiper" vertical="true" :current="myIndex" circular="true"
|
||||
v-bind:style="{color:color,width:myIndex == 10 ? '14rpx' : myIndex == 1 ? '22rpx' : width+'rpx',height:height+'rpx',lineHeight:fontSize+'rpx',fontSize:fontSize+'rpx',fontWeight: fontWeight}">
|
||||
<swiper-item>
|
||||
<view class="swiper-item">0</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<view class="swiper-item">1</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<view class="swiper-item">2</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<view class="swiper-item">3</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<view class="swiper-item">4</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<view class="swiper-item">5</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<view class="swiper-item">6</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<view class="swiper-item">7</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<view class="swiper-item">8</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<view class="swiper-item">9</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<view class="swiper-item">.</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
num: [String, Number],
|
||||
color: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '30'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '30'
|
||||
},
|
||||
fontSize: {
|
||||
type: String,
|
||||
default: '30'
|
||||
},
|
||||
fontWeight: {
|
||||
type: [String, Number],
|
||||
default: 500
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
indexArr: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
let {
|
||||
num
|
||||
} = this;
|
||||
let arr = new Array(num.toString().length);
|
||||
arr.fill(0);
|
||||
this.indexArr = arr;
|
||||
},
|
||||
watch: {
|
||||
num: function(val, oldVal) {
|
||||
// 处理新老数据长度不一样的情况
|
||||
let arr = Array.prototype.slice.apply(this.indexArr);
|
||||
let newLen = val.toString().length;
|
||||
let oldLen = oldVal.toString().length;
|
||||
if (newLen > oldLen) {
|
||||
for (let i = 0; i < newLen - oldLen; i++) {
|
||||
arr.push(0);
|
||||
}
|
||||
this.indexArr = arr;
|
||||
}
|
||||
if (newLen < oldLen) {
|
||||
for (let i = 0; i < oldLen - newLen; i++) {
|
||||
arr.pop();
|
||||
}
|
||||
this.indexArr = arr;
|
||||
}
|
||||
this.numChange(val);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
//定时器作用:app显示数字滚动
|
||||
this._time = setTimeout(() => {
|
||||
this.numChange(this.num);
|
||||
clearTimeout(this._time);
|
||||
}, 50);
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 数字改变
|
||||
* @value 数字
|
||||
*/
|
||||
numChange(num) {
|
||||
this.$nextTick(() => {
|
||||
let {
|
||||
indexArr
|
||||
} = this;
|
||||
let copyIndexArr = Array.prototype.slice.apply(indexArr);
|
||||
let _num = num.toString();
|
||||
for (let i = 0; i < _num.length; i++) {
|
||||
if (_num[i] === '.') {
|
||||
copyIndexArr[i] = 10;
|
||||
} else {
|
||||
copyIndexArr[i] = Number(_num[i]);
|
||||
}
|
||||
}
|
||||
this.indexArr = copyIndexArr;
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.number-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
position: relative;
|
||||
// line-height: 30upx;
|
||||
// width: 30upx;
|
||||
// height: 30upx;
|
||||
// font-size: 30upx;
|
||||
// background: red;
|
||||
}
|
||||
|
||||
.swiper:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<view class="orderGoods borRadius14">
|
||||
<view class='total'>共{{ totalNmu }}件商品</view>
|
||||
<view class='goodWrapper pad30'>
|
||||
<view class='item acea-row row-between-wrapper' v-for="(item,index) in cartInfo" :key="index"
|
||||
@click="jumpCon(item.spuId)">
|
||||
<view class='pictrue'>
|
||||
<image :src='item.picUrl' />
|
||||
</view>
|
||||
<view class='text'>
|
||||
<view class='acea-row row-between-wrapper'>
|
||||
<view class='name line1'>{{ item.spuName }}</view>
|
||||
<view class='num'>x {{ item.count }}</view>
|
||||
</view>
|
||||
<view class='attr line1'>
|
||||
<text v-for="(property, propertyIndex) in item.properties" :key="propertyIndex" style="padding-right: 10rpx;">
|
||||
{{ property.valueName }}
|
||||
</text>
|
||||
</view>
|
||||
<view class='money font-color'>¥{{ fen2yuan(item.price) }}</view>
|
||||
<!-- 售后状态 -->
|
||||
<!-- TODO 芋艿:这样式不太合理;应该顺着向右对齐 -->
|
||||
<view class="evaluate" style="right: 60px;" v-if="afterSale" @click.stop="afterSaleTap(item)">
|
||||
{{
|
||||
item.afterSaleStatus === 0 ? '申请退款' :
|
||||
item.afterSaleStatus === 10 ? '退款中' : '退款成功'
|
||||
}}
|
||||
</view>
|
||||
<!-- 评价状态 -->
|
||||
<view class='evaluate' v-if='item.commentStatus === false && evaluate === 2' @click.stop="evaluateTap(item)">评价</view>
|
||||
<view class='evaluate' v-else-if="item.replyStatus === true">已评价</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import * as Util from '@/utils/util.js';
|
||||
export default {
|
||||
props: {
|
||||
evaluate: {
|
||||
type: Number,
|
||||
default: 0, // 是否开启评价功能 0 - 不开启;2 - 开启
|
||||
},
|
||||
afterSale: { // 是否开启售后功能
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
cartInfo: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
orderId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
jump: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
productType: {
|
||||
type: Number,
|
||||
default: function() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
totalNmu: 0 // 商品数量
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
cartInfo: function(nVal, oVal) {
|
||||
let num = 0
|
||||
nVal.forEach((item, index) => {
|
||||
num += item.count
|
||||
})
|
||||
this.totalNmu = num
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
evaluateTap(item) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/users/goods_comment_con/index?orderItemId=" + item.id
|
||||
})
|
||||
},
|
||||
afterSaleTap(item) {
|
||||
if (item.afterSaleStatus === 0) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/users/goods_return/index?orderId=" + item.orderId + '&orderItemId=' + item.id
|
||||
})
|
||||
return;
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: "/pages/users/user_return_detail/index?id=" + item.afterSaleId
|
||||
})
|
||||
},
|
||||
jumpCon: function(id) {
|
||||
let type = this.productType === 0 ?'normal':'video'
|
||||
if (this.jump) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/goods_details/index?id=${id}&type=${type}`
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
fen2yuan(price) {
|
||||
return Util.fen2yuan(price)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.orderGoods {
|
||||
background-color: #fff;
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
|
||||
.orderGoods .total {
|
||||
width: 100%;
|
||||
height: 86rpx;
|
||||
padding: 0 24rpx;
|
||||
border-bottom: 2rpx solid #f0f0f0;
|
||||
font-size: 30rpx;
|
||||
color: #282828;
|
||||
line-height: 86rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pictrue image {
|
||||
background: #f4f4f4;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,314 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="payment" :class="pay_close ? 'on' : ''">
|
||||
<view class="title acea-row row-center-wrapper">
|
||||
选择付款方式<text class="iconfont icon-guanbi" @click='close'></text>
|
||||
</view>
|
||||
<view class="item acea-row row-between-wrapper" @click='goPay(item.number || 0 , item.value)'
|
||||
v-for="(item,index) in payMode" :key="index">
|
||||
<view class="left acea-row row-between-wrapper">
|
||||
<view class="iconfont" :class="item.icon"></view>
|
||||
<view class="text">
|
||||
<view class="name">{{item.name}}</view>
|
||||
<view class="info" v-if="item.number">
|
||||
{{item.title}} <span class="money">¥{{ item.number }}</span>
|
||||
</view>
|
||||
<view class="info" v-else>{{item.title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="iconfont icon-xiangyou"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mask" @click='close' v-if="pay_close"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
orderPay,
|
||||
wechatOrderPay,
|
||||
wechatQueryPayResult
|
||||
} from '@/api/order.js';
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
export default {
|
||||
props: {
|
||||
payMode: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
pay_close: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
order_id: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
totalPrice: {
|
||||
type: String,
|
||||
default: '0'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
},
|
||||
computed: mapGetters(['systemPlatform']),
|
||||
methods: {
|
||||
close: function() {
|
||||
this.$emit('onChangeFun', {
|
||||
action: 'payClose'
|
||||
});
|
||||
},
|
||||
goPay: function(number, paytype) {
|
||||
let that = this;
|
||||
let goPages = '/pages/order_pay_status/index?order_id=' + that.order_id;
|
||||
if (!that.order_id) return that.$util.Tips({
|
||||
title: '请选择要支付的订单'
|
||||
});
|
||||
if (paytype == 'yue' && parseFloat(number) < parseFloat(that.totalPrice)) return that.$util.Tips({
|
||||
title: '余额不足!'
|
||||
});
|
||||
uni.showLoading({
|
||||
title: '支付中'
|
||||
});
|
||||
wechatOrderPay({
|
||||
orderNo: that.order_id,
|
||||
// #ifdef MP
|
||||
payChannel: 'routine',
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
payChannel: that.$wechat.isWeixin() ? 'public' : 'weixinh5',
|
||||
// #endif
|
||||
payType: paytype
|
||||
}).then(res => {
|
||||
let jsConfig = res.data.jsConfig;
|
||||
that.order_id = res.data.orderNo;
|
||||
switch (res.data.payType) {
|
||||
case 'weixin':
|
||||
// #ifdef MP
|
||||
uni.requestPayment({
|
||||
timeStamp: jsConfig.timeStamp,
|
||||
nonceStr: jsConfig.nonceStr,
|
||||
package: jsConfig.packages,
|
||||
signType: jsConfig.signType,
|
||||
paySign: jsConfig.paySign,
|
||||
success: function(ress) {
|
||||
uni.hideLoading();
|
||||
wechatQueryPayResult(that.order_id).then(res => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: "支付成功",
|
||||
icon: 'success'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_complete'
|
||||
});
|
||||
});
|
||||
}).cache(err => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: err
|
||||
});
|
||||
})
|
||||
},
|
||||
fail: function(e) {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: '取消支付'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_fail'
|
||||
});
|
||||
});
|
||||
},
|
||||
complete: function(e) {
|
||||
uni.hideLoading();
|
||||
if (e.errMsg == 'requestPayment:cancel') return that.$util
|
||||
.Tips({
|
||||
title: '取消支付'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_fail'
|
||||
});
|
||||
});
|
||||
},
|
||||
})
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
let datas = {
|
||||
timestamp: jsConfig.timeStamp,
|
||||
nonceStr: jsConfig.nonceStr,
|
||||
package: jsConfig.packages,
|
||||
signType: jsConfig.signType,
|
||||
paySign: jsConfig.paySign
|
||||
};
|
||||
that.$wechat.pay(datas).then(res => {
|
||||
if (res.errMsg == 'chooseWXPay:cancel') {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: '支付失败'
|
||||
});
|
||||
} else {
|
||||
wechatQueryPayResult(that.order_id).then(res => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: "支付成功",
|
||||
icon: 'success'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_complete'
|
||||
});
|
||||
});
|
||||
}).cache(err => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: err
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
}).cache(errW => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: errW
|
||||
});
|
||||
})
|
||||
// #endif
|
||||
break;
|
||||
case 'yue':
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: '余额支付成功',
|
||||
icon: 'success'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_complete'
|
||||
});
|
||||
});
|
||||
break;
|
||||
case 'weixinh5':
|
||||
uni.hideLoading();
|
||||
location.replace(jsConfig.mwebUrl + '&redirect_url=' + window.location.protocol +
|
||||
'//' + window.location.host + goPages + '&status=1');
|
||||
return that.$util.Tips({
|
||||
title: "支付中",
|
||||
icon: 'success'
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_complete'
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
}).catch(err => {
|
||||
uni.hideLoading();
|
||||
return that.$util.Tips({
|
||||
title: err
|
||||
}, () => {
|
||||
that.$emit('onChangeFun', {
|
||||
action: 'pay_fail'
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.payment {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
background-color: #fff;
|
||||
padding-bottom: 60rpx;
|
||||
z-index: 99;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
|
||||
transform: translate3d(0, 100%, 0);
|
||||
}
|
||||
|
||||
.payment.on {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
.payment .title {
|
||||
text-align: center;
|
||||
height: 123rpx;
|
||||
font-size: 32rpx;
|
||||
color: #282828;
|
||||
font-weight: bold;
|
||||
padding-right: 30rpx;
|
||||
margin-left: 30rpx;
|
||||
position: relative;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.payment .title .iconfont {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 43rpx;
|
||||
color: #8a8a8a;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.payment .item {
|
||||
border-bottom: 1rpx solid #eee;
|
||||
height: 130rpx;
|
||||
margin-left: 30rpx;
|
||||
padding-right: 30rpx;
|
||||
}
|
||||
|
||||
.payment .item .left {
|
||||
width: 610rpx;
|
||||
}
|
||||
|
||||
.payment .item .left .text {
|
||||
width: 540rpx;
|
||||
}
|
||||
|
||||
.payment .item .left .text .name {
|
||||
font-size: 32rpx;
|
||||
color: #282828;
|
||||
}
|
||||
|
||||
.payment .item .left .text .info {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.payment .item .left .text .info .money {
|
||||
color: #ff9900;
|
||||
}
|
||||
|
||||
.payment .item .left .iconfont {
|
||||
font-size: 45rpx;
|
||||
color: #09bb07;
|
||||
}
|
||||
|
||||
.payment .item .left .iconfont.icon-zhifubao {
|
||||
color: #00aaea;
|
||||
}
|
||||
|
||||
.payment .item .left .iconfont.icon-yuezhifu {
|
||||
color: #ff9900;
|
||||
}
|
||||
|
||||
.payment .item .left .iconfont.icon-yuezhifu1 {
|
||||
color: #eb6623;
|
||||
}
|
||||
|
||||
.payment .item .iconfont {
|
||||
font-size: 0.3rpx;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<view class='product-bg'>
|
||||
<swiper :indicator-dots="indicatorDots" indicator-active-color="#e93323" :autoplay="autoplay"
|
||||
:circular="circular" :interval="interval" :duration="duration" @change="change">
|
||||
|
||||
<!-- 视频 -->
|
||||
<swiper-item v-if="videoline">
|
||||
<view class="item">
|
||||
<view v-show="!controls" style="width:100%;height:100% ">
|
||||
<video id="myVideo" :src='videoline' objectFit="cover" controls style="width:100%;height:100% "
|
||||
show-center-play-btn show-mute-btn="true" auto-pause-if-navigate :custom-cache="false"
|
||||
:enable-progress-gesture="false" :poster="imgUrls[0]" @pause="videoPause"></video>
|
||||
</view>
|
||||
<view class="poster" v-show="controls">
|
||||
<image class="image" :src="imgUrls[0]"></image>
|
||||
</view>
|
||||
<view class="stop" v-show="controls" @tap="bindPause">
|
||||
<image class="image" src="../../static/images/stop.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
|
||||
<!-- 图片 -->
|
||||
<block v-for="(item,index) in imgUrls" :key='index'>
|
||||
<swiper-item>
|
||||
<image :src="item" class="slide-image" />
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
imgUrls: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
videoline: {
|
||||
type: String,
|
||||
value: ""
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
indicatorDots: true,
|
||||
circular: true,
|
||||
autoplay: true,
|
||||
interval: 3000,
|
||||
duration: 500,
|
||||
currents: "1",
|
||||
controls: true,
|
||||
isPlay:true,
|
||||
videoContext:''
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.videoline) {
|
||||
this.imgUrls.shift()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
videoPause(e){
|
||||
},
|
||||
bindPause: function() {
|
||||
this.videoContext.play();
|
||||
this.$set(this, 'controls', false)
|
||||
this.autoplay = false
|
||||
},
|
||||
change: function(e) {
|
||||
this.$set(this, 'currents', e.detail.current + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.product-bg {
|
||||
width: 100%;
|
||||
height: 750rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.product-bg swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.product-bg .slide-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.product-bg .pages {
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
height: 34rpx;
|
||||
padding: 0 10rpx;
|
||||
border-radius: 3rpx;
|
||||
right: 30rpx;
|
||||
bottom: 30rpx;
|
||||
line-height: 34rpx;
|
||||
font-size: 24rpx;
|
||||
color: #050505;
|
||||
}
|
||||
|
||||
#myVideo {
|
||||
width: 100%;
|
||||
height: 100%
|
||||
}
|
||||
|
||||
.product-bg .item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.product-bg .item .poster {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 750rpx;
|
||||
width: 100%;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.product-bg .item .poster .image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.product-bg .item .stop {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 136rpx;
|
||||
height: 136rpx;
|
||||
margin-top: -68rpx;
|
||||
margin-left: -68rpx;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.product-bg .item .stop .image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="product-window"
|
||||
:class="(attr.cartAttr === true ? 'on' : '') + ' ' + (iSbnt ? 'join':'') + ' ' + (iScart ? 'joinCart':'')">
|
||||
<view class="textpic acea-row row-between-wrapper">
|
||||
<view class="pictrue">
|
||||
<image :src="attr.productSelect.picUrl"></image>
|
||||
</view>
|
||||
<view class="text">
|
||||
<view class="line1">
|
||||
{{ attr.productSelect.spuName }}
|
||||
</view>
|
||||
<view class="money font-color">
|
||||
¥<text class="num">{{ fen2yuan(attr.productSelect.price) }}</text>
|
||||
<text class="stock" v-if='isShow'>库存: {{ attr.productSelect.stock }}</text>
|
||||
<text class='stock' v-if="attr.productSelect.limitCount > 0">限购: {{ attr.productSelect.limitCount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="iconfont icon-guanbi" @click="close"></view>
|
||||
</view>
|
||||
<view class="rollTop">
|
||||
<!-- 属性 key + value 列表 -->
|
||||
<view class="productWinList">
|
||||
<view class="item" v-for="(property, propertyIndex) in attr.properties" :key="propertyIndex">
|
||||
<view class="title">{{ property.name }}</view>
|
||||
<view class="listn acea-row row-middle">
|
||||
<view class="itemn" :class="property.index === value.name ? 'on' : ''"
|
||||
v-for="(value, valueIndex) in property.values" :key="valueIndex"
|
||||
@click="clickProperty(propertyIndex, valueIndex)">
|
||||
{{ value.name }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cart acea-row row-between-wrapper">
|
||||
<view class="title">数量</view>
|
||||
<view class="carnum acea-row row-left">
|
||||
<view class="item reduce" :class="attr.productSelect.cart_num <= 1 ? 'on' : ''"
|
||||
@click="CartNumDes">
|
||||
-
|
||||
</view>
|
||||
<view class='item num'>
|
||||
<input type="number" v-model="attr.productSelect.cart_num"
|
||||
data-name="productSelect.cart_num"
|
||||
@input="bindCode(attr.productSelect.cart_num)" />
|
||||
</view>
|
||||
<view v-if="iSplus" class="item plus" :class="attr.productSelect.cart_num >= attr.productSelect.stock ? 'on' : ''" @click="CartNumAdd">
|
||||
+
|
||||
</view>
|
||||
<view v-else class='item plus'
|
||||
:class='(attr.productSelect.cart_num >= attr.productSelect.stock)
|
||||
|| (attr.productSelect.cart_num >= attr.productSelect.limitCount)
|
||||
? "on":""'
|
||||
@click='CartNumAdd'>+</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- TODO 芋艿:拼团 -->
|
||||
<view class="joinBnt bg-color" v-if="iSbnt && attr.productSelect.stock > 0"
|
||||
@click="goCat">我要参团</view>
|
||||
<view class="joinBnt on"
|
||||
v-else-if="iSbnt && attr.productSelect.stock <= 0">已售罄</view>
|
||||
<!-- TODO 芋艿:购物车 -->
|
||||
<view class="joinBnt bg-color" v-if="iScart && attr.productSelect.stock"
|
||||
@click="goCat">确定</view>
|
||||
<view class="joinBnt on"
|
||||
v-else-if="(iScart && !attr.productSelect.stock)">已售罄</view>
|
||||
</view>
|
||||
<view class="mask" @touchmove.prevent :hidden="attr.cartAttr === false" @click="close"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Util from '@/utils/util.js';
|
||||
export default {
|
||||
props: {
|
||||
attr: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
isShow: { // 是否展示库存
|
||||
type: Number,
|
||||
value: 0
|
||||
},
|
||||
iSbnt: { // 是否拼团商品
|
||||
type: Number,
|
||||
value: 0
|
||||
},
|
||||
iSplus: { // 是否允许 + - 操作
|
||||
type: Number,
|
||||
value: 0
|
||||
},
|
||||
iScart: { // 是否来自购物车界面
|
||||
type: Number,
|
||||
value: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
goCat: function() {
|
||||
this.$emit('goCat');
|
||||
},
|
||||
/**
|
||||
* 购物车手动输入数量
|
||||
*/
|
||||
bindCode: function(e) {
|
||||
// TODO 芋艿:【优化】方法名的处理;是否可去掉这个事件,统一处理
|
||||
this.$emit('iptCartNum', this.attr.productSelect.cart_num);
|
||||
},
|
||||
close: function() {
|
||||
this.$emit('close');
|
||||
},
|
||||
CartNumDes: function() {
|
||||
// TODO 芋艿:【优化】方法名的处理;是否可去掉这个事件,统一处理
|
||||
this.$emit('ChangeCartNum', false);
|
||||
},
|
||||
CartNumAdd: function() {
|
||||
// TODO 芋艿:【优化】方法名的处理;是否可去掉这个事件,统一处理
|
||||
this.$emit('ChangeCartNum', true);
|
||||
},
|
||||
/**
|
||||
* 选中某个规格属性
|
||||
*
|
||||
* @param propertyIndex properties 的下标
|
||||
* @param valueIndex values 的下标
|
||||
*/
|
||||
clickProperty: function(propertyIndex, valueIndex) {
|
||||
this.$set(this.attr.properties[propertyIndex], 'index', this.attr.properties[propertyIndex].values[valueIndex].name);
|
||||
let newSkuKey = this.getCheckedValueNames().join(",");
|
||||
// TODO 芋艿:【优化】修改下 ChangeAttr 名字,改成 selectSku 更合适
|
||||
this.$emit("ChangeAttr", newSkuKey, propertyIndex, valueIndex);
|
||||
},
|
||||
/**
|
||||
* 获取被选中属性值的数组
|
||||
*
|
||||
* @returns {*[]} 例如说,['红色', '大']
|
||||
*/
|
||||
getCheckedValueNames: function() {
|
||||
let properties = this.attr.properties;
|
||||
let valueNames = [];
|
||||
for (let i = 0; i < properties.length; i++) {
|
||||
for (let j = 0; j < properties[i].values.length; j++) {
|
||||
if (properties[i].index === properties[i].values[j].name) {
|
||||
valueNames.push(properties[i].values[j].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return valueNames;
|
||||
},
|
||||
|
||||
fen2yuan(price) {
|
||||
return Util.fen2yuan(price)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.product-window {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
background-color: #fff;
|
||||
z-index: 77;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
padding-bottom: 140rpx;
|
||||
transform: translate3d(0, 100%, 0);
|
||||
transition: all .3s cubic-bezier(.25, .5, .5, .9);
|
||||
}
|
||||
|
||||
.product-window.on {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
.product-window.join {
|
||||
padding-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.product-window.joinCart {
|
||||
padding-bottom: 30rpx;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.product-window .textpic {
|
||||
padding: 0 130rpx 0 30rpx;
|
||||
margin-top: 29rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.product-window .textpic .pictrue {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
|
||||
.product-window .textpic .pictrue image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.product-window .textpic .text {
|
||||
width: 410rpx;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.product-window .textpic .text .money {
|
||||
font-size: 24rpx;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.product-window .textpic .text .money .num {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.product-window .textpic .text .money .stock {
|
||||
color: #999;
|
||||
margin-left: 18rpx;
|
||||
}
|
||||
|
||||
.product-window .textpic .iconfont {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
top: -5rpx;
|
||||
font-size: 35rpx;
|
||||
color: #8a8a8a;
|
||||
}
|
||||
|
||||
.product-window .rollTop {
|
||||
max-height: 500rpx;
|
||||
overflow: auto;
|
||||
margin-top: 36rpx;
|
||||
}
|
||||
|
||||
.product-window .productWinList .item~.item {
|
||||
margin-top: 36rpx;
|
||||
}
|
||||
|
||||
.product-window .productWinList .item .title {
|
||||
font-size: 30rpx;
|
||||
color: #999;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.product-window .productWinList .item .listn {
|
||||
padding: 0 30rpx 0 16rpx;
|
||||
}
|
||||
|
||||
.product-window .productWinList .item .listn .itemn {
|
||||
border: 1px solid #F2F2F2;
|
||||
font-size: 26rpx;
|
||||
color: #282828;
|
||||
padding: 7rpx 33rpx;
|
||||
border-radius: 40rpx;
|
||||
margin: 20rpx 0 0 14rpx;
|
||||
background-color: #F2F2F2;
|
||||
}
|
||||
|
||||
.product-window .productWinList .item .listn .itemn.on {
|
||||
color: $theme-color;
|
||||
background: rgba(255, 244, 243, 1);
|
||||
border-color: $theme-color;
|
||||
}
|
||||
|
||||
.product-window .productWinList .item .listn .itemn.limit {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.product-window .cart {
|
||||
margin-top: 36rpx;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.product-window .cart .title {
|
||||
font-size: 30rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.product-window .cart .carnum {
|
||||
height: 54rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.product-window .cart .carnum view {
|
||||
// border: 1px solid #a4a4a4;
|
||||
width: 84rpx;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 54rpx;
|
||||
color: #282828;
|
||||
font-size: 45rpx;
|
||||
}
|
||||
|
||||
.product-window .cart .carnum .reduce {
|
||||
border-right: 0;
|
||||
border-radius: 6rpx 0 0 6rpx;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
|
||||
.product-window .cart .carnum .reduce.on {
|
||||
// border-color: #e3e3e3;
|
||||
color: #DEDEDE;
|
||||
font-size: 44rpx;
|
||||
}
|
||||
|
||||
.product-window .cart .carnum .plus {
|
||||
border-left: 0;
|
||||
border-radius: 0 6rpx 6rpx 0;
|
||||
line-height: 46rpx;
|
||||
}
|
||||
|
||||
.product-window .cart .carnum .plus.on {
|
||||
border-color: #e3e3e3;
|
||||
color: #dedede;
|
||||
}
|
||||
|
||||
.product-window .cart .carnum .num {
|
||||
background: rgba(242, 242, 242, 1);
|
||||
color: #282828;
|
||||
font-size: 28rpx;
|
||||
border-radius: 12rpx;
|
||||
line-height: 29px;
|
||||
height: 54rpx;
|
||||
|
||||
input {
|
||||
display: -webkit-inline-box;
|
||||
}
|
||||
}
|
||||
|
||||
.product-window .joinBnt {
|
||||
font-size: 30rpx;
|
||||
width: 620rpx;
|
||||
height: 86rpx;
|
||||
border-radius: 50rpx;
|
||||
text-align: center;
|
||||
line-height: 86rpx;
|
||||
color: #fff;
|
||||
margin: 21rpx auto 0 auto;
|
||||
}
|
||||
|
||||
.product-window .joinBnt.on {
|
||||
background-color: #bbb;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<view class='recommend'>
|
||||
<view class='title acea-row row-center-wrapper'>
|
||||
<text class='iconfont icon-zhuangshixian'></text>
|
||||
<text class='name'>热门推荐</text>
|
||||
<text class='iconfont icon-zhuangshixian lefticon'></text>
|
||||
</view>
|
||||
<view class='recommendList acea-row row-between-wrapper'>
|
||||
<view class='item' v-for="(item,index) in hostProduct" :key="index" hover-class='none' @tap="goDetail(item)">
|
||||
<view class='pictrue'>
|
||||
<image :src='item.picUrl'></image>
|
||||
<span class="pictrue_log_big pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 1">秒杀</span>
|
||||
<span class="pictrue_log_big pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 2">砍价</span>
|
||||
<span class="pictrue_log_big pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 3">拼团</span>
|
||||
</view>
|
||||
<view class='name line1'>{{ item.name }}</view>
|
||||
<view class='money font-color'>¥<text class='num'>{{ fen2yuan(item.price) }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import { goShopDetail } from '@/libs/order.js'
|
||||
import * as Util from '@/utils/util.js';
|
||||
export default {
|
||||
computed: mapGetters(['uid']),
|
||||
props: {
|
||||
hostProduct: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goDetail(item){
|
||||
goShopDetail(item,this.uid).then(() => {
|
||||
uni.navigateTo({
|
||||
url:`/pages/goods_details/index?id=${item.id}`
|
||||
})
|
||||
})
|
||||
},
|
||||
fen2yuan(price) {
|
||||
return Util.fen2yuan(price)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.recommend {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.recommend .title {
|
||||
height: 135rpx;
|
||||
line-height: 135rpx;
|
||||
font-size: 28rpx;
|
||||
color: #282828;
|
||||
}
|
||||
|
||||
.recommend .title .name {
|
||||
margin: 0 28rpx;
|
||||
}
|
||||
|
||||
.recommend .title .iconfont {
|
||||
font-size: 170rpx;
|
||||
color: #454545;
|
||||
}
|
||||
|
||||
.recommend .title .iconfont.lefticon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.recommend .recommendList {
|
||||
padding: 0 30rpx;
|
||||
/* #ifdef H5 */
|
||||
padding-bottom: 50rpx;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.recommend .recommendList .item {
|
||||
width: 335rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.recommend .recommendList .item .pictrue {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 335rpx;
|
||||
}
|
||||
|
||||
.recommend .recommendList .item .pictrue image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 14rpx;
|
||||
}
|
||||
|
||||
.recommend .recommendList .item .name {
|
||||
font-size: 28rpx;
|
||||
color: #282828;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.recommend .recommendList .item .money {
|
||||
font-size: 20rpx;
|
||||
margin-top: 8rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.recommend .recommendList .item .money .num {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<view v-if="shareInfoStatus" class="poster-first">
|
||||
<view class="mask-share">
|
||||
<image src="/static/images/share-info.png" @click="shareInfoClose" @touchmove.stop.prevent="false" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
shareInfoStatus: {
|
||||
type: Boolean,
|
||||
default:false,
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {};
|
||||
},
|
||||
mounted: function() {},
|
||||
methods: {
|
||||
shareInfoClose: function() {
|
||||
this.$emit("setShareInfoStatus");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.poster-first {
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
.mask-share {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 99;
|
||||
}
|
||||
.mask-share image {
|
||||
width: 100%;
|
||||
height:100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<view class='sharing-packets' :class='!enabled ? "on":""'>
|
||||
<view class='iconfont icon-guanbi' @click="closeShare"></view>
|
||||
<view class='line'></view>
|
||||
<view class='sharing-con' @click='goShare'>
|
||||
<image src='../../static/images/red-packets.png'></image>
|
||||
<view class='text font-color'>
|
||||
<view>会员分享返</view>
|
||||
<view class='money' v-if="sharePacket.brokerageMinPrice && sharePacket.brokerageMaxPrice">
|
||||
<text class='label'>¥</text>{{ fen2yuan(sharePacket.brokerageMinPrice) }}~{{ fen2yuan(sharePacket.brokerageMaxPrice) }}
|
||||
</view>
|
||||
<view class='money' v-else-if="sharePacket.brokerageMinPrice">
|
||||
<text class='label'>¥</text>{{ fen2yuan(sharePacket.brokerageMinPrice) }}
|
||||
</view>
|
||||
<view class='money' v-else-if="sharePacket.brokerageMaxPrice">
|
||||
<text class='label'>¥</text>{{ fen2yuan(sharePacket.brokerageMaxPrice) }}
|
||||
</view>
|
||||
<view class='tip'>下单即返佣金</view>
|
||||
<view class='shareBut'>立即分享</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Util from '@/utils/util.js';
|
||||
export default {
|
||||
props: {
|
||||
sharePacket: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
enabled: true,
|
||||
brokerageMinPrice: undefined,
|
||||
brokerageMaxPrice: undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
enabled() {
|
||||
return this.sharePacket.enabled && (this.sharePacket.brokerageMinPrice || this.sharePacket.brokerageMaxPrice)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closeShare:function(){
|
||||
this.$emit('closeChange');
|
||||
},
|
||||
goShare:function(){
|
||||
this.$emit('listenerActionSheet');
|
||||
},
|
||||
fen2yuan(price) {
|
||||
return Util.fen2yuan(price)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.sharing-packets{position:fixed;left:30rpx;bottom:200rpx;z-index:5;transition:all 0.3s ease-in-out 0s;opacity:1;transform: scale(1);}
|
||||
.sharing-packets.on{transform: scale(0);opacity:0;}
|
||||
.sharing-packets .iconfont{width:44rpx;height:44rpx;border-radius:50%;text-align:center;line-height:44rpx;background-color:#999;font-size:20rpx;color:#fff;margin:0 auto;box-sizing:border-box;padding-left:1px;}
|
||||
.sharing-packets .line{width:2rpx;height:40rpx;background-color:#999;margin:0 auto;}
|
||||
.sharing-packets .sharing-con{width:187rpx;height:210rpx;position:relative;}
|
||||
.sharing-packets .sharing-con image{width:100%;height:100%;}
|
||||
.sharing-packets .sharing-con .text{position:absolute;top:30rpx;font-size:20rpx;width:100%;text-align:center;}
|
||||
.sharing-packets .sharing-con .text .money{font-size:32rpx;font-weight:bold;margin-top:5rpx;white-space: nowrap}
|
||||
.sharing-packets .sharing-con .text .money .label{font-size:20rpx;}
|
||||
.sharing-packets .sharing-con .text .tip{font-size:18rpx;color:#999;margin-top:5rpx;}
|
||||
.sharing-packets .sharing-con .text .shareBut{font-size:22rpx;color:#fff;margin-top:18rpx;height:50rpx;line-height:50rpx;}
|
||||
</style>
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<view class='swiper'>
|
||||
<swiper :autoplay="autoplay" :circular="circular" :interval="interval" :duration="duration" @change="swiperChange">
|
||||
<block v-for="(item,index) in imgUrls" :key="index">
|
||||
<swiper-item>
|
||||
<navigator :url="item.link" style='width:100%;height:100%;' hover-class='none'><image :src="item.img" class="slide-image"/></navigator>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
<view class="dots acea-row">
|
||||
<view class="dot" :class="index == currentSwiper ? 'active' : ''" v-for="(item,index) in imgUrls" :key="index"></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
props: {
|
||||
imgUrls: {
|
||||
type: Array,
|
||||
default: function(){
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
circular: true,
|
||||
autoplay: true,
|
||||
interval: 3000,
|
||||
duration: 500,
|
||||
currentSwiper: 0
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
swiperChange: function (e) {
|
||||
this.currentSwiper = e.detail.current
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.swiper{width:100%;height:282rpx;position:relative;}
|
||||
.swiper swiper{width:100%;height:100%;position:relative;}
|
||||
.swiper swiper .slide-image{width:100%;height:100%;}
|
||||
.swiper .dots{position:absolute;right:40rpx;bottom:20rpx;}
|
||||
.swiper .dots .dot{width:12rpx;height:12rpx;border:2rpx solid #fff;border-radius:50%;margin-right:15rpx;}
|
||||
.swiper .dots .dot.active{border-color:$theme-color;background-color:$theme-color;}
|
||||
</style>
|
||||
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<canvas v-if="canvasId" :id="canvasId" :canvasId="canvasId" :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"
|
||||
@touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error">
|
||||
</canvas>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uCharts from './u-charts.js';
|
||||
var canvases = {};
|
||||
|
||||
export default {
|
||||
props: {
|
||||
chartType: {
|
||||
required: true,
|
||||
type: String,
|
||||
default: 'column'
|
||||
},
|
||||
opts: {
|
||||
required: true,
|
||||
type: Object,
|
||||
default () {
|
||||
return null;
|
||||
},
|
||||
},
|
||||
canvasId: {
|
||||
type: String,
|
||||
default: 'u-canvas',
|
||||
},
|
||||
cWidth: {
|
||||
default: 375,
|
||||
},
|
||||
cHeight: {
|
||||
default: 250,
|
||||
},
|
||||
pixelRatio: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
switch (this.chartType) {
|
||||
case 'column':
|
||||
this.initColumnChart();
|
||||
break;
|
||||
case 'line':
|
||||
this.initLineChart();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
initColumnChart() {
|
||||
canvases[this.canvasId] = new uCharts({
|
||||
$this: this,
|
||||
canvasId: this.canvasId,
|
||||
type: 'column',
|
||||
legend: true,
|
||||
fontSize: 11,
|
||||
background: '#FFFFFF',
|
||||
pixelRatio: this.pixelRatio,
|
||||
animation: true,
|
||||
categories: this.opts.categories,
|
||||
series: this.opts.series,
|
||||
enableScroll: true,
|
||||
xAxis: {
|
||||
disableGrid: true,
|
||||
itemCount: 4,
|
||||
scrollShow: true
|
||||
},
|
||||
yAxis: {
|
||||
//disabled:true
|
||||
},
|
||||
dataLabel: true,
|
||||
width: this.cWidth * this.pixelRatio,
|
||||
height: this.cHeight * this.pixelRatio,
|
||||
extra: {
|
||||
column: {
|
||||
type: 'group',
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
initLineChart() {
|
||||
canvases[this.canvasId] = new uCharts({
|
||||
$this: this,
|
||||
canvasId: this.canvasId,
|
||||
type: 'line',
|
||||
fontSize: 11,
|
||||
legend: true,
|
||||
dataLabel: false,
|
||||
dataPointShape: true,
|
||||
background: '#FFFFFF',
|
||||
pixelRatio: this.pixelRatio,
|
||||
categories: this.opts.categories,
|
||||
series: this.opts.series,
|
||||
animation: true,
|
||||
enableScroll: true,
|
||||
xAxis: {
|
||||
type: 'grid',
|
||||
gridColor: '#CCCCCC',
|
||||
gridType: 'dash',
|
||||
dashLength: 8,
|
||||
itemCount: 4,
|
||||
scrollShow: true
|
||||
},
|
||||
yAxis: {
|
||||
gridType: 'dash',
|
||||
gridColor: '#CCCCCC',
|
||||
dashLength: 8,
|
||||
splitNumber: 5,
|
||||
min: 10,
|
||||
max: 180,
|
||||
format: (val) => {
|
||||
return val.toFixed(0) + '元'
|
||||
}
|
||||
},
|
||||
width: this.cWidth * this.pixelRatio,
|
||||
height: this.cHeight * this.pixelRatio,
|
||||
extra: {
|
||||
line: {
|
||||
type: 'straight'
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 这里仅作为示例传入两个参数,cid为canvas-id,newdata为更新的数据,需要更多参数请自行修改
|
||||
changeData(cid,newdata) {
|
||||
canvases[cid].updateData({
|
||||
series: newdata.series,
|
||||
categories: newdata.categories
|
||||
});
|
||||
},
|
||||
touchStart(e) {
|
||||
canvases[this.canvasId].showToolTip(e, {
|
||||
format: function(item, category) {
|
||||
return category + ' ' + item.name + ':' + item.data
|
||||
}
|
||||
});
|
||||
canvases[this.canvasId].scrollStart(e);
|
||||
},
|
||||
touchMove(e) {
|
||||
canvases[this.canvasId].scroll(e);
|
||||
},
|
||||
touchEnd(e) {
|
||||
canvases[this.canvasId].scrollEnd(e);
|
||||
},
|
||||
error(e) {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.charts {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1 @@
|
||||
'use strict';var config={yAxisWidth:15,yAxisSplit:5,xAxisHeight:15,xAxisLineHeight:15,legendHeight:15,yAxisTitleWidth:15,padding:[10,10,10,10],pixelRatio:1,rotate:!1,columePadding:3,fontSize:13,dataPointShape:["circle","circle","circle","circle"],colors:["#1890ff","#2fc25b","#facc14","#f04864","#8543e0","#90ed7d"],pieChartLinePadding:15,pieChartTextPadding:5,xAxisTextPadding:3,titleColor:"#333333",titleFontSize:20,subtitleColor:"#999999",subtitleFontSize:15,toolTipPadding:3,toolTipBackground:"#000000",toolTipOpacity:.7,toolTipLineHeight:20,radarLabelTextMargin:15,gaugeLabelTextMargin:15};let assign=function(e,...t){function i(e,t){for(let a in t)e[a]=e[a]&&"[object Object]"===e[a].toString()?i(e[a],t[a]):e[a]=t[a];return e}if(null==e)throw new TypeError("Cannot convert undefined or null to object");return!t||0>=t.length?e:(t.forEach(t=>{e=i(e,t)}),e)};var util={toFixed:function(e,t){return t=t||2,this.isFloat(e)&&(e=e.toFixed(t)),e},isFloat:function(e){return 0!=e%1},approximatelyEqual:function(e,t){return 1e-10>Math.abs(e-t)},isSameSign:function(e,t){var i=Math.abs;return i(e)===e&&i(t)===t||i(e)!==e&&i(t)!==t},isSameXCoordinateArea:function(e,t){return this.isSameSign(e.x,t.x)},isCollision:function(e,t){e.end={},e.end.x=e.start.x+e.width,e.end.y=e.start.y-e.height,t.end={},t.end.x=t.start.x+t.width,t.end.y=t.start.y-t.height;var i=t.start.x>e.end.x||t.end.x<e.start.x||t.end.y>e.start.y||t.start.y<e.end.y;return!i}};function getH5Offset(t){return t.mp={changedTouches:[]},t.mp.changedTouches.push({x:t.offsetX,y:t.offsetY}),t}function hexToRgb(e,t){var i=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,a=e.replace(i,function(e,t,i,a){return t+t+i+i+a+a}),o=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(a),n=parseInt(o[1],16),l=parseInt(o[2],16),r=parseInt(o[3],16);return"rgba("+n+","+l+","+r+","+t+")"}function findRange(e,t,i){if(isNaN(e))throw new Error("[uCharts] unvalid series data!");i=i||10,t=t?t:"upper";for(var a=1;1>i;)i*=10,a*=10;for(e="upper"===t?Math.ceil(e*a):Math.floor(e*a);0!=e%i;)"upper"===t?e++:e--;return e/a}function calCandleMA(e,t,i,a){let o=[];for(let n,l=0;l<e.length;l++){n={data:[],name:t[l],color:i[l]};for(let t=0,i=a.length;t<i;t++){if(t<e[l]){n.data.push(null);continue}let i=0;for(let o=0;o<e[l];o++)i+=a[t-o][1];n.data.push(+(i/e[l]).toFixed(3))}o.push(n)}return o}function calValidDistance(e,t,i,a,o){var n=o.width-o.area[1]-o.area[3],l=i.eachSpacing*(o.chartData.xAxisData.xAxisPoints.length-1),r=t;return 0<=t?(r=0,e.event.trigger("scrollLeft")):Math.abs(t)>=l-n&&(r=n-l,e.event.trigger("scrollRight")),r}function isInAngleRange(e,t,i){function a(e){for(;0>e;)e+=2*o;for(;e>2*o;)e-=2*o;return e}var o=Math.PI;return e=a(e),t=a(t),i=a(i),t>i&&(i+=2*o,e<t&&(e+=2*o)),e>=t&&e<=i}function calRotateTranslate(e,t,i){var a=e,o=i-t,n=a+(i-o-a)/1.4142135623730951;n*=-1;return{transX:n,transY:(i-o)*(1.4142135623730951-1)-(i-o-a)/1.4142135623730951}}function createCurveControlPoints(e,t){function i(e,t){return!!(e[t-1]&&e[t+1])&&(e[t].y>=l(e[t-1].y,e[t+1].y)||e[t].y<=n(e[t-1].y,e[t+1].y))}function o(e,t){return!!(e[t-1]&&e[t+1])&&(e[t].x>=l(e[t-1].x,e[t+1].x)||e[t].x<=n(e[t-1].x,e[t+1].x))}var n=Math.min,l=Math.max,r=.2,a=.2,s=null,d=null,h=null,x=null;if(1>t?(s=e[0].x+(e[1].x-e[0].x)*r,d=e[0].y+(e[1].y-e[0].y)*r):(s=e[t].x+(e[t+1].x-e[t-1].x)*r,d=e[t].y+(e[t+1].y-e[t-1].y)*r),t>e.length-3){var c=e.length-1;h=e[c].x-(e[c].x-e[c-1].x)*a,x=e[c].y-(e[c].y-e[c-1].y)*a}else h=e[t+1].x-(e[t+2].x-e[t].x)*a,x=e[t+1].y-(e[t+2].y-e[t].y)*a;return i(e,t+1)&&(x=e[t+1].y),i(e,t)&&(d=e[t].y),o(e,t+1)&&(h=e[t+1].x),o(e,t)&&(s=e[t].x),(d>=l(e[t].y,e[t+1].y)||d<=n(e[t].y,e[t+1].y))&&(d=e[t].y),(x>=l(e[t].y,e[t+1].y)||x<=n(e[t].y,e[t+1].y))&&(x=e[t+1].y),(s>=l(e[t].x,e[t+1].x)||s<=n(e[t].x,e[t+1].x))&&(s=e[t].x),(h>=l(e[t].x,e[t+1].x)||h<=n(e[t].x,e[t+1].x))&&(h=e[t+1].x),{ctrA:{x:s,y:d},ctrB:{x:h,y:x}}}function convertCoordinateOrigin(e,t,i){return{x:i.x+e,y:i.y-t}}function avoidCollision(e,t){if(t)for(;util.isCollision(e,t);)0<e.start.x?e.start.y--:0>e.start.x?e.start.y++:0<e.start.y?e.start.y++:e.start.y--;return e}function fillSeries(e,t,i){var a=0;return e.map(function(e){if(e.color||(e.color=i.colors[a],a=(a+1)%i.colors.length),e.index||(e.index=0),e.type||(e.type=t.type),"undefined"==typeof e.show&&(e.show=!0),e.type||(e.type=t.type),e.pointShape||(e.pointShape="circle"),!e.legendShape)switch(e.type){case"line":e.legendShape="line";break;case"column":e.legendShape="rect";break;case"area":e.legendShape="triangle";break;default:e.legendShape="circle";}return e})}function getDataRange(e,t){var i=0,a=t-e;return i=1e4<=a?1e3:1e3<=a?100:100<=a?10:10<=a?5:1<=a?1:.1<=a?.1:.01<=a?.01:.001<=a?.001:1e-4<=a?1e-4:1e-5<=a?1e-5:1e-6,{minRange:findRange(e,"lower",i),maxRange:findRange(t,"upper",i)}}function measureText(e){var t=1<arguments.length&&arguments[1]!==void 0?arguments[1]:config.fontSize;e=e+"";var e=e.split(""),a=0;for(let t,o=0;o<e.length;o++)t=e[o],a+=/[a-zA-Z]/.test(t)?7:/[0-9]/.test(t)?5.5:/\./.test(t)?2.7:/-/.test(t)?3.25:Line truncated
|
||||