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 @@
@@ -1,3 +1,2 @@
|
||||
def main(): |
||||
# 此处填写业务 |
||||
print("===== 此处业务处理 =====") |
||||
pass |
||||
|
@ -0,0 +1,42 @@
@@ -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 @@
@@ -1,7 +1,8 @@
|
||||
from Server.api import log, systemInfo, serverConfig |
||||
from Server.api import log, serverConfig, jdShopper, loginStatus |
||||
|
||||
def urls(url, request): |
||||
if (url == "/log"): return log(request) |
||||
elif (url == "/system-info"): return systemInfo(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" |
@ -0,0 +1,267 @@
@@ -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 @@
@@ -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