mirror of https://github.com/FanbeiFan/JD-SHOPPER
louisyoungx
3 years ago
19 changed files with 781 additions and 231 deletions
@ -1,3 +1,2 @@ |
|||||||
def main(): |
def main(): |
||||||
# 此处填写业务 |
pass |
||||||
print("===== 此处业务处理 =====") |
|
||||||
|
@ -0,0 +1,42 @@ |
|||||||
|
import subprocess |
||||||
|
import sys |
||||||
|
import os |
||||||
|
from flask import request, Flask, make_response, render_template |
||||||
|
|
||||||
|
HOME = os.path.dirname(os.path.abspath(__file__)) |
||||||
|
|
||||||
|
app = Flask(__name__, |
||||||
|
instance_path=HOME, |
||||||
|
instance_relative_config=True, |
||||||
|
template_folder="../Static", |
||||||
|
static_folder="../Static", |
||||||
|
static_url_path='') |
||||||
|
|
||||||
|
app.config['JSON_AS_ASCII'] = False |
||||||
|
|
||||||
|
@app.route("/") |
||||||
|
def homePage(): |
||||||
|
return render_template('index.html') |
||||||
|
|
||||||
|
@app.route('/api/zpy', methods=['POST', 'OPTIONS']) |
||||||
|
def zpy(): |
||||||
|
if request.method == 'POST': |
||||||
|
code = request.json['code'] |
||||||
|
output = subprocess.check_output([sys.executable, '-c', code]) |
||||||
|
print(output.decode().encode()) |
||||||
|
response = make_response(output.decode()) |
||||||
|
response.headers['Access-Control-Allow-Origin'] = '*' |
||||||
|
response.headers['Access-Control-Allow-Methods'] = 'GET,POST' |
||||||
|
response.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type' |
||||||
|
return response |
||||||
|
else: |
||||||
|
# CORS跨域配置 |
||||||
|
response = make_response() |
||||||
|
response.headers['Access-Control-Allow-Origin'] = '*' |
||||||
|
response.headers['Access-Control-Allow-Methods'] = 'GET,POST' |
||||||
|
response.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type' |
||||||
|
return response |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
app.run(debug=False, host='0.0.0.0', port=5000) |
@ -1,7 +1,8 @@ |
|||||||
from Server.api import log, systemInfo, serverConfig |
from Server.api import log, serverConfig, jdShopper, loginStatus |
||||||
|
|
||||||
def urls(url, request): |
def urls(url, request): |
||||||
if (url == "/log"): return log(request) |
if (url == "/log"): return log(request) |
||||||
elif (url == "/system-info"): return systemInfo(request) |
|
||||||
elif (url == "/config"): return serverConfig(request) |
elif (url == "/config"): return serverConfig(request) |
||||||
|
elif (url == "/jd-shopper"): return jdShopper(request) |
||||||
|
elif (url == "/jd-login-status"): return loginStatus(request) |
||||||
else: return "No Response" |
else: return "No Response" |
@ -0,0 +1,267 @@ |
|||||||
|
<html lang="zh-CN"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<title>404 No Found - Louis Young</title> |
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"> |
||||||
|
<style> |
||||||
|
html, body { |
||||||
|
height: 100%; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.error-page { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
text-align: center; |
||||||
|
height: 100%; |
||||||
|
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; |
||||||
|
} |
||||||
|
|
||||||
|
.error-page h1 { |
||||||
|
font-size: 30vh; |
||||||
|
font-weight: bold; |
||||||
|
position: relative; |
||||||
|
margin: -8vh 0 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.error-page h1:after { |
||||||
|
content: attr(data-h1); |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
color: transparent; |
||||||
|
/* webkit only for graceful degradation to IE */ |
||||||
|
background: -webkit-repeating-linear-gradient(-45deg, #71b7e6, #69a6ce, #b98acc, #ee8176, #b98acc, #69a6ce, #9b59b6); |
||||||
|
-webkit-background-clip: text; |
||||||
|
-webkit-text-fill-color: transparent; |
||||||
|
background-size: 400%; |
||||||
|
text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.25); |
||||||
|
animation: animateTextBackground 10s ease-in-out infinite; |
||||||
|
} |
||||||
|
|
||||||
|
.error-page h1 + p { |
||||||
|
color: #d6d6d6; |
||||||
|
font-size: 8vh; |
||||||
|
font-weight: bold; |
||||||
|
line-height: 10vh; |
||||||
|
max-width: 600px; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.error-page h1 + p:after { |
||||||
|
content: attr(data-p); |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
color: transparent; |
||||||
|
text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.5); |
||||||
|
-webkit-background-clip: text; |
||||||
|
-moz-background-clip: text; |
||||||
|
background-clip: text; |
||||||
|
} |
||||||
|
|
||||||
|
#particles-js { |
||||||
|
position: fixed; |
||||||
|
top: 0; |
||||||
|
right: 0; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
@keyframes animateTextBackground { |
||||||
|
0% { |
||||||
|
background-position: 0 0; |
||||||
|
} |
||||||
|
25% { |
||||||
|
background-position: 100% 0; |
||||||
|
} |
||||||
|
50% { |
||||||
|
background-position: 100% 100%; |
||||||
|
} |
||||||
|
75% { |
||||||
|
background-position: 0 100%; |
||||||
|
} |
||||||
|
100% { |
||||||
|
background-position: 0 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 767px) { |
||||||
|
.error-page h1 { |
||||||
|
font-size: 32vw; |
||||||
|
} |
||||||
|
|
||||||
|
.error-page h1 + p { |
||||||
|
font-size: 8vw; |
||||||
|
line-height: 10vw; |
||||||
|
max-width: 70vw; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
a.back { |
||||||
|
position: fixed; |
||||||
|
right: 40px; |
||||||
|
bottom: 40px; |
||||||
|
background: -webkit-repeating-linear-gradient(-45deg, #71b7e6, #69a6ce, #b98acc, #ee8176); |
||||||
|
border-radius: 5px; |
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); |
||||||
|
color: #fff; |
||||||
|
font-size: 16px; |
||||||
|
font-weight: bold; |
||||||
|
line-height: 24px; |
||||||
|
padding: 15px 30px; |
||||||
|
text-decoration: none; |
||||||
|
transition: 0.25s all ease-in-out; |
||||||
|
} |
||||||
|
|
||||||
|
a.back:hover { |
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
|
<script> |
||||||
|
window.console = window.console || function (t) { |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
|
||||||
|
<script> |
||||||
|
if (document.location.search.match(/type=embed/gi)) { |
||||||
|
window.parent.postMessage("resize", "*"); |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
|
||||||
|
</head> |
||||||
|
|
||||||
|
<body translate="no"> |
||||||
|
<div class="error-page"> |
||||||
|
<div> |
||||||
|
<!--h1(data-h1='400') 400--> |
||||||
|
<!--p(data-p='BAD REQUEST') BAD REQUEST--> |
||||||
|
<!--h1(data-h1='401') 401--> |
||||||
|
<!--p(data-p='UNAUTHORIZED') UNAUTHORIZED--> |
||||||
|
<!--h1(data-h1='403') 403--> |
||||||
|
<!--p(data-p='FORBIDDEN') FORBIDDEN--> |
||||||
|
<h1 data-h1="404">404</h1> |
||||||
|
<p data-p="NOT FOUND">NOT FOUND</p> |
||||||
|
<!--h1(data-h1='500') 500--> |
||||||
|
<!--p(data-p='SERVER ERROR') SERVER ERROR--> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div id="particles-js"> |
||||||
|
<canvas class="particles-js-canvas-el" width="1090" height="1330" style="width: 100%; height: 100%;"></canvas> |
||||||
|
</div> |
||||||
|
<!--a(href="#").back GO BACK--> |
||||||
|
<script src="https://cpwebassets.codepen.io/assets/common/stopExecutionOnTimeout-8216c69d01441f36c0ea791ae2d4469f0f8ff5326f00ae2d00e4bb7d20e24edb.js"></script> |
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/particles.js/2.0.0/particles.min.js"></script> |
||||||
|
<script id="rendered-js"> |
||||||
|
particlesJS("particles-js", { |
||||||
|
"particles": { |
||||||
|
"number": { |
||||||
|
"value": 5, |
||||||
|
"density": { |
||||||
|
"enable": true, |
||||||
|
"value_area": 800 |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
"color": { |
||||||
|
"value": "#fcfcfc" |
||||||
|
}, |
||||||
|
|
||||||
|
"shape": { |
||||||
|
"type": "circle" |
||||||
|
}, |
||||||
|
|
||||||
|
"opacity": { |
||||||
|
"value": 0.5, |
||||||
|
"random": true, |
||||||
|
"anim": { |
||||||
|
"enable": false, |
||||||
|
"speed": 1, |
||||||
|
"opacity_min": 0.2, |
||||||
|
"sync": false |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
"size": { |
||||||
|
"value": 140, |
||||||
|
"random": false, |
||||||
|
"anim": { |
||||||
|
"enable": true, |
||||||
|
"speed": 10, |
||||||
|
"size_min": 40, |
||||||
|
"sync": false |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
"line_linked": { |
||||||
|
"enable": false |
||||||
|
}, |
||||||
|
|
||||||
|
"move": { |
||||||
|
"enable": true, |
||||||
|
"speed": 8, |
||||||
|
"direction": "none", |
||||||
|
"random": false, |
||||||
|
"straight": false, |
||||||
|
"out_mode": "out", |
||||||
|
"bounce": false, |
||||||
|
"attract": { |
||||||
|
"enable": false, |
||||||
|
"rotateX": 600, |
||||||
|
"rotateY": 1200 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
"interactivity": { |
||||||
|
"detect_on": "canvas", |
||||||
|
"events": { |
||||||
|
"onhover": { |
||||||
|
"enable": false |
||||||
|
}, |
||||||
|
|
||||||
|
"onclick": { |
||||||
|
"enable": false |
||||||
|
}, |
||||||
|
|
||||||
|
"resize": true |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
"retina_detect": true |
||||||
|
}); |
||||||
|
//# sourceURL=pen.js |
||||||
|
</script> |
||||||
|
|
||||||
|
</body> |
||||||
|
</html> |
||||||
|
|
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
||||||
|
<!-- // --> |
After Width: | Height: | Size: 776 B |
File diff suppressed because one or more lines are too long
@ -0,0 +1,200 @@ |
|||||||
|
new Vue({ |
||||||
|
el: "#form_container", |
||||||
|
data() { |
||||||
|
return { |
||||||
|
mode: "1", // 模式:定时下单/有货自动下单
|
||||||
|
date: "", |
||||||
|
area: "", // 所在地区
|
||||||
|
skurl: "", // 商品url
|
||||||
|
count: "1", // 购买数量
|
||||||
|
retry: "10", // 重试次数
|
||||||
|
work_count: "1", // 启动线程数
|
||||||
|
timeout: "3", // 超时时间
|
||||||
|
eid: "", |
||||||
|
fp: "", |
||||||
|
timeSelectAble: true, |
||||||
|
dialogVisible: false, |
||||||
|
dialog: "", |
||||||
|
skuid: "", |
||||||
|
qrUrl: "./img/qr_code.png", |
||||||
|
qrVisible: false, |
||||||
|
qrReq: undefined, |
||||||
|
qrID: 0, |
||||||
|
qrReset: true, |
||||||
|
title: "错误", |
||||||
|
task: true |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getEidFp() |
||||||
|
setTimeout(() => { |
||||||
|
this.main() |
||||||
|
}, 100) |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
main() { |
||||||
|
}, |
||||||
|
upload() { |
||||||
|
if (!this.checkValid()) return |
||||||
|
let url = "0.0.0.0:12021/api/jd-shopper" |
||||||
|
let data = { |
||||||
|
mode: this.mode, |
||||||
|
date: this.date, |
||||||
|
area: this.area, |
||||||
|
skuid: this.skuid, |
||||||
|
count: this.count, |
||||||
|
retry: this.retry, |
||||||
|
work_count: this.work_count, |
||||||
|
timeout: this.timeout, |
||||||
|
eid: this.eid, |
||||||
|
fp: this.fp, |
||||||
|
}; |
||||||
|
fetch(url, { |
||||||
|
body: JSON.stringify(data), // must match 'Content-Type' header
|
||||||
|
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
|
||||||
|
credentials: 'same-origin', // include, same-origin, *omit
|
||||||
|
headers: { |
||||||
|
'user-agent': 'Mozilla/4.0 MDN Example', |
||||||
|
'content-type': 'application/json' |
||||||
|
}, |
||||||
|
method: 'POST', // *GET, POST, PUT, DELETE, etc.
|
||||||
|
mode: 'cors', // no-cors, cors, *same-origin
|
||||||
|
redirect: 'follow', // manual, *follow, error
|
||||||
|
referrer: 'no-referrer', // *client, no-referrer
|
||||||
|
}).then(response => { |
||||||
|
return response.json() |
||||||
|
}).then(res => { |
||||||
|
console.log(res) |
||||||
|
setTimeout(() => { |
||||||
|
this.qrShow() |
||||||
|
this.loginCheck() |
||||||
|
}, 200) |
||||||
|
}) |
||||||
|
}, |
||||||
|
buyMode(value) { |
||||||
|
if (this.mode === "1" || this.mode === 1) { |
||||||
|
this.timeSelectAble = true; |
||||||
|
} else { |
||||||
|
this.timeSelectAble = false; |
||||||
|
} |
||||||
|
}, |
||||||
|
getEidFp() { |
||||||
|
let that = this |
||||||
|
setTimeout(() => { |
||||||
|
try { |
||||||
|
getJdEid(function (eid, fp, udfp) { |
||||||
|
that.eid = eid |
||||||
|
that.fp = fp |
||||||
|
}); |
||||||
|
} catch (e) { |
||||||
|
that.dialogShow("获取eid与fp失败,请手动获取。") |
||||||
|
} |
||||||
|
}, 0); |
||||||
|
}, |
||||||
|
reset() { |
||||||
|
this.mode = "1" // 模式:定时下单/有货自动下单
|
||||||
|
this.date = "" |
||||||
|
this.area = "" // 所在地区
|
||||||
|
this.skurl = "" // 商品url
|
||||||
|
this.count = "1" // 购买数量
|
||||||
|
this.retry = "10" // 重试次数
|
||||||
|
this.work_count = "1" // 启动线程数
|
||||||
|
this.timeout = "3" // 超时时间
|
||||||
|
this.eid = "" |
||||||
|
this.fp = "" |
||||||
|
}, |
||||||
|
dialogShow(mes) { |
||||||
|
this.dialog = mes |
||||||
|
this.dialogVisible = true |
||||||
|
}, |
||||||
|
checkValid() { |
||||||
|
if (this.area == "" || this.skurl == "") { |
||||||
|
this.dialogShow("地区ID与商品链接不能为空") |
||||||
|
return false |
||||||
|
} |
||||||
|
else if (this.mode == "2" && this.date == "") { |
||||||
|
this.dialogShow("定时下单需设置时间") |
||||||
|
return false |
||||||
|
} |
||||||
|
let skuid = this.skurl.match(new RegExp(`https://item.jd.com/(.*?).html`)) |
||||||
|
skuid = skuid ? skuid[1] : null |
||||||
|
if (skuid == null) { |
||||||
|
skuid= this.skurl.replace(/[^0-9]/ig,"") |
||||||
|
reNum = /^[0-9]+.?[0-9]*/ |
||||||
|
if (!reNum.test(skuid)) { |
||||||
|
this.dialogShow("请输入正确的网址") |
||||||
|
return false |
||||||
|
} |
||||||
|
} |
||||||
|
this.skuid = skuid |
||||||
|
return true |
||||||
|
}, |
||||||
|
qrShow() { |
||||||
|
this.qrVisible = true |
||||||
|
this.qrID = 0 |
||||||
|
|
||||||
|
|
||||||
|
this.qrReq = setInterval(function () { |
||||||
|
let imgDiv = document.getElementsByClassName("el-image")[0] |
||||||
|
imgDiv.removeChild(imgDiv.childNodes[0]) |
||||||
|
this.qrID++ |
||||||
|
this.qrUrl = './img/qr_code.png' |
||||||
|
this.qrReset = false |
||||||
|
}, 3000) |
||||||
|
}, |
||||||
|
|
||||||
|
loginCheck() { |
||||||
|
let url = './api/jd-login-status' |
||||||
|
let loginReq = setInterval(() => { |
||||||
|
let imgDiv = document.getElementsByClassName("el-image")[0] |
||||||
|
imgDiv.innerHTML = `<img src="./img/qr_code.png?id={this.qrID}" class="el-image__inner">` |
||||||
|
fetch(url) |
||||||
|
.then(response => { |
||||||
|
return response.json(); |
||||||
|
}) |
||||||
|
.then(res => { |
||||||
|
console.log(res); |
||||||
|
if (res.data) { |
||||||
|
this.qrVisible = false |
||||||
|
clearInterval(this.qrReq) |
||||||
|
clearInterval(loginReq) |
||||||
|
this.getLog() |
||||||
|
this.task = false |
||||||
|
} |
||||||
|
}); |
||||||
|
}, 1000) |
||||||
|
}, |
||||||
|
getLog() { |
||||||
|
let url = './api/log' |
||||||
|
|
||||||
|
fetch(url) |
||||||
|
.then(response => { |
||||||
|
return response.json(); |
||||||
|
}) |
||||||
|
.then(res => { |
||||||
|
console.log(res.data); |
||||||
|
document.getElementById('log').innerHTML = res.data |
||||||
|
}); |
||||||
|
|
||||||
|
setInterval(() => { |
||||||
|
fetch(url) |
||||||
|
.then(response => { |
||||||
|
return response.json(); |
||||||
|
}) |
||||||
|
.then(res => { |
||||||
|
console.log(res.data); |
||||||
|
document.getElementById('log').innerHTML = res.data |
||||||
|
}); |
||||||
|
}, 10000) |
||||||
|
} |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
// confirm,e.prototype.$prompt=ya.prompt,e.prototype.$notify=tl,e.prototype.$message=ou};
|
||||||
|
//"undefined"!=typeof window&&window.Vue&&Ld(window.Vue);t.default={version:"2.15.0",
|
||||||
|
//locale:j.use,i18n:j.i18n,install:Ld,CollapseTransition:ii,Loading:_l,Pagination:pt,
|
||||||
|
//Dialog:gt,Autocomplete:kt,Dropdown:At,DropdownMenu:Bt,DropdownItem:Wt,Menu:ei,
|
||||||
|
//Submenu:ai,MenuItem:di,MenuItemGroup:vi,Input:ne,InputNumber:_i,Radio:Si,RadioGroup:Mi,
|
||||||
|
//RadioButton:Ii,Checkbox:Vi,CheckboxButton:Ri,CheckboxGroup:Yi,Switch:Xi,Select:ct,
|
||||||
|
//Option:ht,OptionGroup:en,Button:Et,ButtonGroup:Pt,Table:Un,TableColumn:ir
|
Binary file not shown.
Loading…
Reference in new issue