Files
ptools/templates/auto_pt/status.html

1806 lines
87 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
{% include 'admin/includes/css-part.html' %}
<style>
body {
background-color: #2f4155;
background-image: url("{% static 'img/leaf.png' %}");
opacity: 0.95;
}
.site-logo:hover {
cursor: pointer;
transform: scale(1.3);
transition: all 0.3s;
text-underline: #000b16;
color: orange;
margin-top: -25px;
}
.info-card {
background-color: rgba(227, 229, 229, 0.6);
border: 2px solid skyblue;
width: 100%;
}
.info-card .el-card__header {
background-color: rgba(122, 246, 173, 0.2);
border-bottom: 2px solid skyblue;
height: 60px;
}
.info-card .el-card__header a {
color: orangered;
text-decoration: none;
}
.info-card .el-card__header a:hover {
text-decoration: underline orangered;
color: dodgerblue;
}
.chart-button {
float: right;
margin-right: 5px;
}
.el-drawer__header {
height: 35px !important;
}
</style>
</head>
<body>
<div id="status">
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<span>站点数据</span>
<span class="chart-button">
<el-button size="mini" :type="shuffle ? 'primary' : ''" @click="shuffleList">
随机
</el-button>
<el-button size="mini" :type="!shuffle ? 'primary' : ''" @click="sortList">
正序
</el-button>
<el-button type="primary" size="mini" v-if="showList"
@click="setPie">图表
</el-button>
<el-button type="success" size="mini" v-else="showList"
@click="setCard">卡片
</el-button>
</span>
</div>
<div class="body">
<el-row v-if="showList">
<el-row :gutter="20">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4"
style="margin-bottom: 10px;float: right;text-align: center;">
<el-input autofocus
prefix-icon="el-icon-search"
clearable
size="mini"
style="width: 78%;"
v-model="searchKey"
@input="siteSearch"
placeholder="请输入站点名称或者网址搜索">
</el-input>
<el-button size="mini" type="success" @click="editSite(0)" style="width: 18%;">添加
</el-button>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" style="margin-bottom: 10px;" v-if="ptData">
<el-card class="box-card info-card">
<div slot="header" class="clearfix">
<div style="text-align: center;line-height: 100%;margin-top: -15px;">
{# <img :src="site.icon"#}
{# style="width: 16px;border-radius: 50%;margin-bottom: -5px;">#}
{# <br>#}
{# <a :href="site.url" target="blank" style="margin-top: -5px;">#}
<h3 style="text-align: left;">
数据汇总
<span v-text="'P龄'+ptData.total_data.p_years"
style="font-size: 14px;float: right;color: orange"></span>
</h3>
{# </a>#}
{# </div>#}
{# <span style="font-size: 12px;float: right;">#}
{# <i class="el-icon-user-solid" v-text="' ' + site.class" style="color: indianred"#}
{# title="用户等级"></i>#}
{# <br v-if="site.hr == 0 || site.mail < 0">#}
{# <i class="el-icon-postcard" v-text="' ' + site.invite" style="color: #003366"#}
{# title="邀请"></i>#}
{# <i class="el-icon-date" v-text="' ' + site.weeks" style="color: darkgreen"#}
{# :title="'加入时间:' + site.time_join"></i>#}
{# <br v-if="site.hr != 0 || site.mail > 0">#}
{##}
{# <i class="el-icon-warning" style="color: orangered" v-if="site.hr!=0" title="H&R"#}
{# v-text="' ' + site.hr"></i>#}
{# <span style="color: darkred;font-size: 13px;" v-if="site.mail > 0">#}
{# <i class="fas fa-envelope el-fade-in"></i>#}
{# <span v-text="site.mail"></span>#}
{# </span>#}
{# <div class="el-badge item" v-if="site.mail > 0" style="float: right">#}
{# <i class="fas fa-sms" style="color: darkred" v-text="site.mail"></i>#}
{# <sup class="el-badge__content is-fixed" v-if="site.mail > 0"#}
{# v-text="site.mail">{}</sup>#}
</div>
{# </span>#}
</div>
<div class="text item" style="font-size: 13px;text-align: right;">
<div>
<el-button-group>
<el-button type="primary" size="mini" @click="signIn(0)">
签到
</el-button>
<el-button type="warning" size="mini" @click="updateSite(0)">更新
</el-button>
<el-button type="success" size="mini" @click="showHistoryList(0)">历史
</el-button>
<el-button type="danger" size="mini" @click="getTorrent(0)">种子
</el-button>
</el-button-group>
</div>
<hr>
<div>
<span style="float: left;font-weight: bold;color: #3b5769;line-height: 32px;">
关注度
</span>
<span>
<el-button size="mini" type="primary" plain @click="changeSortStep">
关注度按钮单次步进值:
<span v-text="sortStep"></span></el-button>
</span>
</div>
<hr>
<div>
<span style="float: left;font-weight: bold;color: #3b5769;">保种分享:</span>
<i class="el-icon-upload" title="做种量"
v-text="' ' + renderSize(ptData.total_data.seeding_size)"></i>
<el-divider direction="vertical"></el-divider>
<i class="el-icon-share" style="color: saddlebrown" title="分享率"
v-text="' ' + ptData.total_data.ratio.toFixed(3)"></i>
</div>
<hr>
<div>
<span style="float: left;font-weight: bold;color: #3b5769;line-height: 36px">实时数据:</span>
<span style="text-align: center">
<span title="做种数量" v-text="ptData.total_data.seeding"
style="color: green"></span>
<span>
<i class="el-icon-d-caret"></i>
</span>
<span title="正在下载" v-text="ptData.total_data.leeching"
style="color: indianred"></span>
<br>
<span title="上传量" style="color: green"
v-text="renderSize(ptData.total_data.uploaded)"></span>
<i class="fas fa-sort"></i>
<span title="下载量" style="color: indianred"
v-text="renderSize(ptData.total_data.downloaded)"></span>
</span>
</div>
<hr>
<div>
<span style="float: left;line-height: 36px;font-weight: bold;color: #3b5769;">魔力/积分:</span>
<i class="el-icon-magic-stick"
v-text="' ' + numberFormat(ptData.total_data.sp) + ' / ' + numberFormat(ptData.total_data.bonus)"
style="color: darkorange" title="魔力/积分"></i>
<br>
<i class="el-icon-lollipop" v-text="' ' + ptData.total_data.sp_hour.toFixed(2)"
style="color: coral" title="时魔"></i>
</div>
<hr>
<div>
<span style="float: left;font-weight: bold;color: #3b5769;">更新时间:</span>
<i class="el-icon-date"
v-text="ptData.total_data.now"
style="color: #1b1b1b;" title="最新数据更新时间"></i>
</div>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" style="margin-bottom: 10px;"
v-for="site in showData">
<el-card class="box-card info-card">
<div slot="header" class="clearfix">
<div style="float: left;text-align: center;margin-top: -5px;font-size: 12px;height: 28px;">
<el-tooltip content="点击打开站点" placement="top" effect="light">
<el-link :href="site.url" target="_blank"
class="site-logo"
style="margin-top: -5px;">
<img :src="site.icon"
{# @click="updateSite(site.id)" #}
style="width: 16px;border-radius: 50%;margin-bottom: -5px;">
<br>
<el-link v-text="site.name"
type="success"
icon="el-icon-edit">
</el-link>
</el-link>
</el-tooltip>
{# <el-tooltip content="点击修改站点信息" placement="bottom" effect="light">#}
{# </el-tooltip>#}
{# <span class="el-dropdown-link">#}
{# 下拉菜单<i class="el-icon-arrow-down el-icon--right"></i>#}
{# </span>#}
</div>
<span style="font-size: 10px;float: right;">
<i class="el-icon-user-solid" v-text="' ' + site.class" style="color: indianred"
title="用户等级"></i>
<br v-if="site.hr == 0 && site.mail <= 0">
<i class="el-icon-postcard" v-text="' ' + site.invite" style="color: #003366"
title="邀请"></i>
<i class="el-icon-date" v-text="' ' + site.weeks" style="color: darkgreen"
:title="'加入时间:' + site.time_join"></i>
<br v-if="site.hr != 0 || site.mail > 0">
<i class="el-icon-warning" style="color: orangered" v-if="site.hr!=0" title="H&R"
v-text="' ' + site.hr"></i>
<el-link style="color: darkred;font-size: 13px;"
:href="site.url" target="_blank"
v-if="site.mail > 0">
<i class="fas fa-envelope el-fade-in"></i>
<span v-text="site.mail"></span>
</el-link>
</span>
</div>
<div class="text item" style="font-size: 13px;text-align: right;">
<div>
<el-button-group>
<el-button type="primary" size="mini" @click="signIn(site.id)"
v-if="site.sign_in_support && !site.sign_in_state">
签到
</el-button>
<el-tooltip class="item" effect="dark" v-if="site.sign_in_state"
content="已签到,点击查看最近签到记录"
placement="bottom" effect="light">
<el-button type="success" icon="el-icon-success" plain size="mini"
@click="showSignIn(site.id)">
</el-button>
</el-tooltip>
<el-button type="warning" size="mini" @click="updateSite(site.id)">更新
</el-button>
<el-dropdown split-button type="success" size="mini"
@click="showHistoryList(site.id)">
历史
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<el-link @click="editSite(site.id)"
size="mini" plain
icon="el-icon-edit">编辑
</el-link>
</el-dropdown-item>
<el-dropdown-item>
<el-link @click="getTorrent(site.id)"
size="mini" plain
icon="el-icon-edit">种子
</el-link>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-button-group>
</div>
<hr>
<div>
<span style="float: left;font-weight: bold;color: #3b5769;line-height: 32px;">
关注度
</span>
<span>
<el-button-group>
<el-button type="primary" icon="el-icon-arrow-left"
style="color: #2F9688;"
plain size="mini" @click="sortCustom(site.id, 0-sortStep)">
</el-button>
<el-button type="primary" icon="el-icon-arrow-right"
@click="sortCustom(site.id, sortStep)"
style="color: #2F9688;" plain size="mini">
</el-button>
</el-button-group>
</span>
</div>
<hr>
<div>
<span style="float: left;font-weight: bold;color: #3b5769;">保种分享:</span>
<i class="el-icon-upload" title="做种量"
v-text="renderSize(site.seeding_size)"></i>
<span style="color: grey">|</span>
{# <el-divider direction="vertical"></el-divider>#}
<i class="el-icon-share" style="color: saddlebrown" title="分享率"
v-text="site.downloaded > 0 ? numberFormat((site.uploaded / site.downloaded).toFixed(2)) : '∞'"></i>
</div>
<hr>
<div>
<span style="float: left;font-weight: bold;color: #3b5769;line-height: 36px">实时数据:</span>
<span style="text-align: center">
<span title="做种数量" v-text="site.seeding" style="color: green"></span>
<span>
<i class="el-icon-d-caret"></i>
</span>
<span title="正在下载" v-text="site.leeching" style="color: indianred"></span>
<br>
<span title="上传量" style="color: green"
v-text="renderSize(site.uploaded)"></span>
<i class="fas fa-sort"></i>
<span title="下载量" style="color: indianred"
v-text="renderSize(site.downloaded)"></span>
</span>
</div>
<hr>
<div>
<span style="float: left;line-height: 36px;font-weight: bold;color: #3b5769;">魔力/积分:</span>
<i class="el-icon-magic-stick"
v-text="' ' + numberFormat(site.sp) + ' / ' + numberFormat(site.bonus)"
style="color: darkorange" title="魔力/积分"></i>
<br>
<i class="el-icon-lollipop"
v-text="site.sp_hour.toFixed(2) + ' / ' + site.sp_hour_full"
style="color: coral" title="时魔"></i>
</div>
<hr>
<div>
<span style="float: left;font-weight: bold;color: #3b5769;">更新时间:</span>
<i class="el-icon-date"
v-text="site.last_active"
style="color: #1b1b1b;" title="最新数据更新时间"></i>
</div>
</div>
</el-card>
</el-col>
</el-row>
</el-row>
<div v-else="showList" style="margin-top: -15px;">
<div style="text-align: center">
<el-button-group>
<el-button size="mini" :type="begInvite ? 'primary' : ''" @click="begInviteMode">
求药
</el-button>
<el-button size="mini" :type="showLegend ? 'primary' : ''" @click="showLegendMode">
图例
</el-button>
<el-button size="mini" :type="showLogo ? 'primary' : ''" @click="showLogoMode"
v-if="showLegend">
Logo
</el-button>
</el-button-group>
</div>
<charts ref="charts" style="height: 700px;margin-top: 5px;" :option="option"></charts>
</div>
</div>
</el-card>
<el-drawer
:visible.sync="showSiteChart"
direction="btt"
size="96%"
append-to-body
style="background-color: rgba(227, 229, 229, 0.6);">
<div slot="title" style="text-align: center;line-height: 35px;">
<h3><span v-text="site.name"></span></h3>
</div>
<div v-if="showSignList" style="width: 90%;margin: auto;">
<el-timeline>
<el-timeline-item
v-for="(signIn, index) in signInList"
:key="index"
{# :icon="activity.icon" #}
{# :type="activity.type" #}
color="#0bbd87"
{# :size="activity.size" #}
placement="top"
:timestamp="signIn.created_at">
<el-card shadow="hover">
<p v-html="signIn.sign_in_info">
</p>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
<div v-else="showSignList" style="width: 95%;text-align: center;margin: 10px auto;">
<div style="margin-bottom: 5px;">
<el-radio-group v-model="dataLength" size="mini"
{# @change="showAllIncrementHistory">#}
@change="showHistoryList(site.id)">
<el-radio-button label="-7">7天</el-radio-button>
<el-radio-button label="-15">15天</el-radio-button>
<el-radio-button label="-30">30天</el-radio-button>
<el-radio-button label="-61">两个月</el-radio-button>
<el-radio-button label="-91">三个月</el-radio-button>
<el-radio-button label="-184">半年</el-radio-button>
<el-radio-button label="-366">一年</el-radio-button>
<el-radio-button label="0">全部</el-radio-button>
</el-radio-group>
<el-button size="mini" v-if="showAllHistory"
:type="showLegend ? 'success' : 'primary'" @click="showAllIncrementHistory(this)">
图例
</el-button>
</div>
<charts ref="history_charts" style="height: 620px;margin: auto;"
v-if="showAllHistory" :option="option"></charts>
<el-row :gutter="20" v-else="showAllHistory">
<el-col :span="24">
<charts ref="seeding_charts" style="height: 420px;margin-top: 15px;" :option="option"></charts>
</el-col>
<el-col :span="24">
<charts ref="diff_charts" style="height: 220px;margin-top: 15px;" :option="option"></charts>
</el-col>
<el-col :span="12">
<charts ref="bonus_charts" :span="12" style="height: 220px;margin-top: 15px;"
:option="option"></charts>
</el-col>
<el-col :span="12">
<charts ref="ratio_charts" :span="12" style="height: 220px;margin-top: 15px;"
:option="option"></charts>
</el-col>
</el-row>
</div>
</el-drawer>
<el-dialog :title="addMySiteForm.id==0 ? '添加站点' : '编辑站点'" :visible.sync="showAddMySite" fullscreen center>
<el-form :model="addMySiteForm" size="small" ref="addMySiteForm"
status-icon
inline-message
:rules="addMySiteFormRules">
<el-input v-model="addMySiteForm.id" v-show="false"
placeholder="请输入数字UIDAZ,CZ,EZ,Reel莫妮卡、普斯特等请填写用户名">
</el-input>
<el-form-item label="选择站点" label-position="left" prop="site">
<el-select :disabled="addMySiteForm.id!=0"
v-model="addMySiteForm.site"
filterable="true"
@visible-change="getSiteList(addMySiteForm.site)"
placeholder="请选择要添加的站点">
<el-option
v-for="site in site_list"
:label="site.name"
:value="site.id"
:key="site.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="功能开关" label-position="right" required>
<el-radio-group>
<el-checkbox-button v-model="addMySiteForm.sign_in" label="签 到" border></el-checkbox-button>
<el-checkbox-button v-model="addMySiteForm.hr" label="HR下载" border></el-checkbox-button>
<el-checkbox-button v-model="addMySiteForm.search" label="搜 索" border></el-checkbox-button>
</el-radio-group>
</el-form-item>
<el-form-item v-show="false" label="注册时间" label-position="right" prop="time_join">
<el-date-picker
text="注册时间"
:disabled="addMySiteForm.id!=0"
v-model="addMySiteForm.time_join"
type="datetime"
placeholder="选择注册日期时间">
</el-date-picker>
</el-form-item>
<el-form-item label="用户UID" label-position="left" prop="user_id">
<el-input v-model="addMySiteForm.user_id" clearable show-word-limit
placeholder="请输入数字UIDAZ,CZ,EZ,Reel莫妮卡、普斯特等请填写用户名">
</el-input>
</el-form-item>
<el-form-item label="Passkey" :label-position="top" prop="passkey">
<el-input v-model="addMySiteForm.passkey" clearable
show-password show-word-limit></el-input>
</el-form-item>
<el-form-item label="Cookies" :label-position="top" prop="cookie">
<el-input type="textarea"
placeholder="请输入站点Cookies与UA搭配使用效果更佳"
v-model="addMySiteForm.cookie"
autosize="{minRows: 3, maxRows: 6}"
autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="UserAgent" label-position="top" prop="user_agent">
<el-input type="textarea" v-model="addMySiteForm.user_agent"
autosize="{minRows: 3, maxRows: 6}"
autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-popconfirm title="确定删除此站点信息吗?"
v-if="addMySiteForm.id!=0"
@confirm="removeMySite(addMySiteForm.id)">
<el-button slot="reference" type="danger">删 除
</el-button>
</el-popconfirm>
<el-button @click="showAddMySite = false">取 消</el-button>
<el-button type="primary" @click="editMySite('addMySiteForm')">
<span v-text="addMySiteForm.id==0 ? '添加站点' : '编辑站点'"></span>
</el-button>
</div>
</el-dialog>
</div>
{% include 'admin/includes/js-part.html' %}
<script src="{% static 'js/utils.js' %}"></script>
<script src="{% static 'admin/simpleui-x/js/axios.min.js' %}"></script>
<script src="{% static 'js/echarts.min.js' %}"></script>
<script src="{% static 'js/echarts-component.js' %}"></script>
<script>
const vm = new Vue({
el: '#status',
data() {
return {
chart: null,
ptData: null,
site: {},
option: {},
showList: true,
showSiteChart: false,
begInvite: false,
showLogo: true,
showLegend: true,
shuffle: false,
searchKey: '',
sortStep: 1,
showData: [],
showAllHistory: false,
incrementData: {},
dataLength: -7,
showSignList: false,
signInList: [],
showAddMySite: false,
site_list: [],
addMySiteForm: {
id: 0,
site: null,
sign_in: true,
hr: false,
search: true,
user_id: '',
passkey: '',
time_join: '2023-01-01 12:00:00',
user_agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.52',
cookie: ''
},
addMySiteFormRules: {
site: [
{required: true, message: '请选择要添加的站点', trigger: 'change'},
],
user_id: [
{required: true, message: '请输入数字UID指定站点请输入用户名', trigger: 'blur'},
],
passkey: [
{required: true, message: '请输入Passkey', trigger: 'blur'},
{min: 16, max: 32, message: '长度为32位', trigger: 'blur'}
],
cookie: [
{required: true, message: '请输入站点Cookies与UA搭配使用效果更佳', trigger: 'change'}
]
}
}
},
beforeMount() {
},
mounted() {
{#this.chart = this.$refs.charts.chart#}
this.getData()
},
watch: {
obj: {
option(newValue, oldValue) {
// option发生变化时自动重新渲染
this.chart.setOption(newValue)
},
searchKey(newValue, oldValue) {
console.log(newValue)
},
// immediate: true,
deep: true,
}
},
methods: {
getTorrent(id) {
axios.get(
"{% url 'get_site_torrents' %}" + `?id=${id}`
).then(res => {
console.log('抓取种子成功', res.data.msg)
if (res.data.code === 0) {
this.$message({
type: 'success',
message: res.data.msg
});
} else {
this.$message({
type: 'warning',
message: res.data.msg
});
}
}).catch(res => {
console.log('抓取种子失败', res)
this.$message({
type: 'warning',
message: '抓取种子失败!' + res
});
})
},
siteSearch() {
console.log(this.searchKey)
{#this.showData#}
this.searchKey == '' ? this.showData = this.ptData.status_list : this.showData = this.ptData.status_list.filter(site => {
return site.url.toLowerCase().includes(this.searchKey.toLowerCase()) || site.name.toLowerCase().includes(this.searchKey.toLowerCase())
})
console.log(this.showData)
},
changeSortStep() {
console.log(this.sortStep)
if (this.sortStep < 5) {
this.sortStep += 1
} else {
this.sortStep = 1
}
},
sortCustom(id, sort) {
console.log(sort)
axios.get(
"{% url 'site_sort_api' %}" + `?id=${id}&sort=${sort}`
).then(res => {
console.log('修改关注度成功', res.data)
{#let data = res.data#}
{#console.log(typeof res.data.data)#}
if (res.data.code === 0) {
this.getData()
this.$message({
type: 'success',
message: res.data.msg
});
} else {
this.$message({
type: 'warning',
message: res.data.msg
});
}
}).catch(res => {
console.log('修改关注度失败', res)
this.$message({
type: 'warning',
message: '修改关注度失败!' + res
});
})
},
signIn(id) {
axios.get(
"{% url 'sign_in_api' %}" + `?id=${id}`
).then(res => {
console.log('获取数据成功', res.data.msg)
if (res.data.code === 0) {
this.getData()
this.$message({
type: 'success',
message: res.data.msg
});
} else {
this.$message({
type: 'warning',
message: res.data.msg
});
}
}).catch(res => {
console.log('签到失败', res)
this.$message({
type: 'warning',
message: '签到失败!' + res
});
})
},
showSignIn(id) {
axios.get(
"{% url 'show_sign_api' %}" + `?id=${id}`
).then(res => {
console.log('获取数据成功', res.data.data)
if (res.data.code === 0) {
this.signInList = res.data.data.sign_in_list
this.site = res.data.data.site
this.showSiteChart = true
this.showSignList = true
} else {
this.$message({
type: 'warning',
message: res.data.msg
});
}
}).catch(res => {
console.log('签到失败', res)
this.$message({
type: 'warning',
message: '签到失败!' + res
});
})
},
updateSite(id) {
axios.get(
"{% url 'update_site_api' %}" + '?id=' + id
).then(res => {
console.log('获取数据列表成功', res.data)
{#let data = res.data#}
{#console.log(typeof res.data.data)#}
if (res.data.code === 0) {
this.getData()
this.$message({
type: 'success',
message: res.data.msg
});
} else {
this.$message({
type: 'warning',
message: res.data.msg
});
}
}).catch(res => {
console.log('更新数据失败', res)
this.$message({
type: 'warning',
message: '更新数据失败!' + res
});
})
},
getSiteList() {
/**
* 获取要添加的站点列表
* @type {null}
*/
let id = this.addMySiteForm.site
if (this.addMySiteForm.id == 0) {
id = 0
}
axios.get(
"{% url 'get_site_list' %}" + '?id=' + id
).then(res => {
console.log('获取数据列表成功', res.data)
{#console.log(typeof res.data.data)#}
if (res.data.code === 0) {
{#this.ptData = res.data.data#}
this.site_list = res.data.data.site_list
} else {
this.$message({
type: 'warning',
message: res.data.msg
});
}
}).catch(res => {
console.log('获取数据列表失败', res)
this.$message({
type: 'warning',
message: '获取数据列表失败!' + res
});
})
},
editMySite(formName) {
/**
* 修改站点信息
* @type {null}
*/
this.$refs[formName].validate((valid) => {
if (valid) {
const options = {
method: 'POST',
headers: {'content-type': 'application/json;charset=utf-8'},
data: this.addMySiteForm,
url: "{% url 'edit_my_site' %}"
}
axios(options).then(res => {
console.log('获取数据列表成功', res.data)
{#console.log(typeof res.data.data)#}
if (res.data.code === 0) {
{#this.ptData = res.data.data#}
{#this.site_list = res.data.data.site_list#}
this.addMySiteForm = {
id: 0,
site: null,
sign_in: true,
hr: false,
search: true,
user_id: '',
passkey: '',
time_join: '2023-01-01 12:00:00',
user_agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.52',
cookie: ''
}
this.showAddMySite = false
this.getData()
this.$message({
type: 'success',
message: res.data.msg
});
} else {
this.$message({
type: 'warning',
message: res.data.msg
});
}
}).catch(res => {
console.log('获取数据列表失败', res)
this.$message({
type: 'warning',
message: '获取数据列表失败!' + res
});
})
} else {
this.$message({
type: 'warning',
message: '数据验证失败!请认真填写'
});
return false;
}
});
},
editSite(id) {
/**
* 打开编辑页面
* @type {null}
*/
if (id == 0) {
this.addMySiteForm = {
id: 0,
site: null,
sign_in: true,
hr: false,
search: true,
user_id: '',
passkey: '',
time_join: '2023-01-01 12:00:00',
user_agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.52',
cookie: ''
}
this.showAddMySite = true
return
}
axios.get(
"{% url 'edit_my_site' %}" + '?id=' + id
).then(res => {
console.log('获取数据列表成功', res.data.data)
{#let data = res.data#}
{#console.log(typeof res.data.data)#}
if (res.data.code === 0) {
this.addMySiteForm = res.data.data.my_site
this.getSiteList(this.addMySiteForm.site)
this.showAddMySite = true
} else {
this.$message({
type: 'warning',
message: '获取数据列表失败!'
});
}
}).catch(res => {
console.log('获取数据列表失败', res)
this.$message({
type: 'warning',
message: '获取数据列表失败!' + res
});
})
},
removeMySite(id) {
axios.get(
"{% url 'remove_my_site' %}" + '?id=' + id
).then(res => {
console.log('获取数据列表成功', res.data.data)
{#let data = res.data#}
{#console.log(typeof res.data.data)#}
if (res.data.code === 0) {
this.addMySiteForm = {}
this.getData()
this.showAddMySite = false
this.$message({
type: 'success',
message: res.data.msg
});
} else {
this.$message({
type: 'warning',
message: res.data.msg
});
}
}).catch(res => {
console.log('删除失败', res)
this.$message({
type: 'warning',
message: '删除失败!' + res
});
})
},
showHistoryList(id) {
if (!id) {
id = 0
}
axios.get(
"{% url 'site_data_api' %}" + '?id=' + id
).then(res => {
console.log('获取数据列表成功', res.data)
{#console.log(typeof res.data.data)#}
if (res.data.code === 0) {
{#this.ptData = res.data.data#}
{#this.ptData = res.data.data#}
{#this.setPie()#}
{#this.setCard()#}
this.incrementData = res.data.data
this.showSignList = false
id == 0 ? this.showAllIncrementHistory() : this.setLine()
} else {
this.$message({
type: 'warning',
message: res.data.msg
});
}
}).catch(res => {
console.log('获取数据列表失败', res)
this.$message({
type: 'warning',
message: '获取数据列表失败!' + res
});
})
},
showAllIncrementHistory($event) {
console.log($event)
if (typeof $event == "object") {
this.showLegend = !this.showLegend
}
{#console.log(this.incrementData)#}
let dateList = this.incrementData.date_list.slice(this.dataLength)
{#console.log(dateList)#}
let diff = []
this.incrementData.diff.forEach((item, index) => {
let diff_item = {}
diff_item = JSON.parse(JSON.stringify(item));
{#console.log(item)#}
diff_item.data = item.data.slice(this.dataLength)
{#console.log(diff_item)#}
diff.push(diff_item)
})
let option = {
title: {
text: '每日增量--全部站点',
textStyle: {
color: 'orangered',
},
left: 'center',
top: '3%',
},
tooltip: {
show: true,
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: function (params) {
//console.log(params)
// console.log(params[0].value[1])
let text = ''
let total = 0
params.sort((a, b) => {
return b.value - a.value
})
params.forEach((param, index) => {
let temp = param.value == 0 ? '' : `
<div style="display: block;height:14px;width: 48%;float:left;padding: 1%;font-size: 10px;">
<span style="float:left;"><i style="width: 8px;height: 8px;display: inline-block;background: ${param.color};border-radius: 8px;"></i>${param.seriesName}: </span>
<span style="float:right;">${renderSize(param.value)}</span>
</div>
`
text += temp
total += param.value
})
let total_str = `
<div style="display: block;height:14px;text-align: left;padding: 1%;font-size: 12px;">
<span style="float: left;">
<i style="width: 8px;height: 8px;display: inline-block;background: darkorange;border-radius: 8px;">
</i>总计:${renderSize(total)}</span>
<text style="float: right;">${params[0].axisValue}</text>
</div>
<hr>
`
total_str += text
return `<div style="width: 280px;">${total_str}</div>`
},
position: function (point, params, dom, rect, size) {
let customVH = window.innerWidth
if (customVH - point[0] < 280) {
point[0] = customVH - 320
}
console.log(customVH)
console.log(point[0])
if (customVH > 768) {
return point
}
return [point[0], 5]
},
order: 'valueDesc',
confine: false,
extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);', // 附加阴影样式
},
legend: {
show: this.showLegend,
{#top: '3%',#}
left: 'center',
bottom: '12',
tooltip: {
show: true
},
},
grid: {
left: '3%',
right: '4%',
bottom: '25%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {},
dataZoom: {},
}
},
xAxis: {
type: 'category',
boundaryGap: true,
axisTick: {
{#alignWithLabel: true#}
},
axisLine: {
onZero: false
},
data: dateList
},
yAxis: {
type: 'value',
axisLabel: {
formatter: function (value, index) {
return renderSize(value);
}
},
},
series: diff,
};
this.site.name = '全部站点'
this.showSiteChart = true
this.showAllHistory = true
this.showLegend ? option.grid.bottom = '25%' : option.grid.bottom = '3%'
setTimeout(() => {
this.chart = this.$refs.history_charts.chart
this.chart.clear()
this.setChartOption(this.chart, option)
}, 15)
},
begInviteMode() {
this.begInvite = !this.begInvite
if (this.begInvite) {
this.showLegend = false
this.showLogo = false
}
this.setPie()
},
showLogoMode() {
this.showLogo = !this.showLogo
this.setPie()
},
showLegendMode() {
this.showLegend = !this.showLegend
this.setPie()
},
setChartOption(charts, option) {
{#this.option = option#}
if (charts) {
charts.clear()
}
charts.setOption(option)
window.addEventListener("resize", () => {
charts.resize()
})
//this.$nextTick(() => {//自适应宽度
// this.chart.resize();
//})
},
shuffleList() {
this.shuffle = true
this.ptData.status_list.sort(() => {
return Math.random() > 0.5 ? -1 : 1
})
this.showList ? this.setCard() : this.setPie()
},
sortList() {
//if (this.shuffle == false) {
// return
//}
this.shuffle = false
this.ptData.status_list.sort((a, b) => {
if (b.mail == a.mail) {
if (b.sort_id == a.sort_id) {
return b.id - a.id
}
return a.sort_id - b.sort_id
}
return b.mail - a.mail
})
this.showList ? this.setCard() : this.setPie()
},
setCard() {
if (this.chart) {
this.chart.clear()
}
//乱序
{#this.shuffleList()#}
this.showList = true
this.siteSearch()
},
setPie() {
let uploadedList = []
let siteList = []
let ptData = this.ptData
let begInvite = !this.begInvite
let status_list = ptData.status_list
this.showList = false
//if (this.shuffle) {
// status_list.sort(shuffle)
//}
status_list.forEach((site, index) => {
uploadedList.push({
'value': site.uploaded,
'path': 'uploaded/' + site.name,
'name': site.name
})
//downloadedList.push({
// 'value': site.downloaded,
// 'path': 'downloaded/' + site.name,
// 'name': site.name
//})
siteList.push({
name: site.name,
icon: this.showLogo ? `image://${site.icon}` : 'roundRect'
})
})
let option = {
title: {
text: 'PT站点数据',
textStyle: {
color: 'orangered',
fontWeight: 'bold',
fontFamily: '黑体',
fontSize: '18',
lineHeight: 22,
rich: ''
},
subtext: `🔼${renderSize(ptData.total_data.uploaded)}\n🔽${renderSize(ptData.total_data.downloaded)}\n☁️${renderSize(ptData.total_data.seeding_size)}\n分享率${ptData.total_data.ratio}\nP 龄:${ptData.total_data.p_years}\nCopy By PTools`,
subtextStyle: {
color: 'orange',
fontWeight: 'bold',
fontFamily: '黑体',
fontSize: '14',
lineHeight: 18,
},
left: '5%',
top: '2%',
},
tooltip: {
show: true,
formatter: function (params) {
return params.name + '\t' + renderSize(params.data.value)
},
valueFormatter: function (value) {
return renderSize(value)
}
},
{#color: [#}
{# '#f66c73',#}
{# '#f68645',#}
{# '#7af6ad',#}
{# '#f4d55f',#}
{# '#488ff6',#}
{# '#0fba8d',#}
{# '#8a47dc',#}
{# '#d677f6',#}
{#],#}
legend: {
show: this.showLegend,
{#type: 'scroll',#}
{#top: 'bottom',#}
right: '2%',
top: '5%',
bottom: '5%',
orient: 'vertical',
data: [],
},
toolbox: {
show: true,
feature: {
mark: {show: true},
{#dataView: {show: true, readOnly: false},#}
{#restore: {show: true},#}
saveAsImage: {show: true}
}
},
series: [
{
name: '站点数据',
type: 'pie',
top: '10%',
bottom: '10%',
radius: '55%',
{#visualDimension: 1,#}
center: ['45%', '50%'],
roseType: '',
label: {
show: true,
formatter: function (params) {
{#return params.name + ' \t ' + renderSize(params.data.value)#}
return `${begInvite ? params.name : ''} \t ${renderSize(params.data.value)}`
},
itemHeight: 12,
itemWidth: 20
},
itemStyle: {
borderRadius: 7
},
data: [
{value: 40, name: 'rose 1'},
{value: 38, name: 'rose 2'},
{value: 32, name: 'rose 3'},
{value: 30, name: 'rose 4'},
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
}
option.series[0].data = uploadedList
option.legend.data = siteList
setTimeout(() => {
console.log(666)
this.chart = this.$refs.charts.chart
this.setChartOption(this.chart, option)
}, 50)
},
setTree() {
let ptData = this.ptData
let begInvite = !this.begInvite
let uploadedList = []
let downloadedList = []
ptData.status_list.forEach((site, index) => {
uploadedList.push({
'value': site.uploaded,
'path': 'uploaded/' + site.name,
'name': `${site.name}\t${renderSize(site.uploaded)}`
})
downloadedList.push({
'value': site.downloaded,
'path': 'downloaded/' + site.name,
'name': `${site.name}\t${renderSize(site.downloaded)}`
})
})
let option = {
backgroundColor: '#130f2c',
title: {
text: 'PT站点数据',
subtext: `上传量:${renderSize(ptData.total_data.uploaded)}\t做种量:${renderSize(ptData.total_data.seeding_size)}\t下载量:${renderSize(ptData.total_data.downloaded)}\t分享率:${ptData.total_data.ratio}`,
subtextStyle: {
color: '#969696',
fontWeight: 'bold',
fontFamily: '黑体',
fontSize: '16',
lineHeight: 32,
},
left: '10%',
},
tooltip: {
show: true,
//formatter: function (params) {
// return params.name + '\t' + renderSize(params.data.value)
//}
valueFormatter: function (value) {
return renderSize(value)
}
},
color: [
'#f66c73',
'#f68645',
'#7af6ad',
'#f4d55f',
'#488ff6',
'#0fba8d',
'#8a47dc',
'#d677f6',
'#130f2c',
'#2f4155',
],
toolbox: {
show: true,
feature: {
mark: {show: true},
saveAsImage: {show: true}
}
},
series: [
{
type: 'treemap',
name: '数据汇总',
colorMappingBy: 'index',
{#colorSaturation: [0.9, 0.9],#}
label: {
show: true,
formatter: function (params) {
{#return params.name + '\t' + renderSize(params.data.value)#}
return `${begInvite ? params.name : ''} \t ${renderSize(params.data.value)}`
}
},
data: [
{
name: '上传',
value: 0,
}
]
}
]
}
/**
console.log(this.treeOption.series[0].data)
this.treeOption.series[0].data.push({
name: '总下载',
value: ptData.total_data.downloaded,
})
let treeData = this.treeOption.series[0].data[0]
treeData.value = ptData.total_data.uploaded
treeData.children = dataList
**/
option.series[0].data.push({
name: `总上传\t${renderSize(ptData.total_data.uploaded)}`,
value: ptData.total_data.uploaded,
path: "uploaded",
children: uploadedList
}, {
name: `总下载\t${renderSize(ptData.total_data.downloaded)}`,
value: ptData.total_data.downloaded,
path: "downloaded",
children: downloadedList
})
{#this.treeOption.series[0].data.push()#}
{#this.$refs.charts.chart.setOption(treeOption)#}
this.chart = this.$refs.charts.chart
this.setChartOption(this.chart, option)
},
setBar() {
let option = {
title: {
text: 'PT数据聚合图'
},
color: [
'skyblue',
'orange'
],
tooltip: {
trigger: 'axis',
show: true,
axisPointer: {
type: 'shadow'
},
valueFormatter: function (value) {
return renderSize(value)
}
},
legend: {
show: this.showLegend
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: []
},
yAxis: {
type: 'value',
axisLabel: {
formatter: function (value, index) {
return renderSize(value);
}
},
label: {
formatter: function (value, index) {
return renderSize(value);
}
},
boundaryGap: [0, 0.01]
},
series: []
};
let ptData = this.ptData
let uploadedList = []
let downloadedList = []
let siteList = []
{#uploadedList.push(ptData.total_data.uploaded)#}
{#downloadedList.push(ptData.total_data.downloaded)#}
{#siteList.push('总量')#}
ptData.status_list.forEach((site, index) => {
downloadedList.push(site.downloaded)
uploadedList.push(site.uploaded)
siteList.push(site.name)
})
let uploaded = {
name: '上传量',
type: 'bar',
stack: 'Ad',
barMaxWidth: '60%',
data: uploadedList
}
let downloaded = {
name: '下载量',
type: 'bar',
stack: 'Ad',
barMaxWidth: '60%',
data: downloadedList
}
option.series.push(downloaded, uploaded)
option.xAxis.data = siteList
this.chart = this.$refs.charts.chart
this.setChartOption(this.chart, option)
},
setLine() {
let siteData = this.incrementData
this.site = siteData.site
let dataList = siteData.site_status_list
let uploadedList = []
let downloadedList = []
let bonusList = []
let spList = []
let ratioList = []
let seedingSizeList = []
let dateList = []
dataList.sort((a, b) => {
return a.info_date - b.info_date
})
let resList = []
resList = JSON.parse(JSON.stringify(dataList)).slice(this.dataLength);
{#dataList.forEach((info, index) => {#}
resList.forEach((info, index) => {
uploadedList.push(info.uploaded)
ratioList.push(info.ratio)
seedingSizeList.push(info.seedingSize)
downloadedList.push(info.downloaded)
spList.push(info.sp)
bonusList.push(info.bonus)
dateList.push(info.info_date)
if (index > 1 && index < dataList.length) {
console.log(info.info_date, info.uploaded, dataList[index - 1].uploaded, info.uploaded - dataList[index - 1].uploaded,)
}
})
let uploaded1 = uploadedList.filter((item, index) => index > 0)
let uploaded2 = uploadedList.filter((item, index) => index < uploadedList.length)
let diff = [0,]
uploaded1.forEach((item, index) => {
let d = item - uploaded2[index]
console.log(dateList[index], item, uploaded2[index], d)
if (!d || d < 0) {
diff.push(0)
} else {
diff.push(d)
}
})
console.log(diff)
let option = {
//title: {
// text: site.name,
// textStyle: {
// color: 'orangered',
// },
// left: 'center',
// top: '3%',
//},
tooltip: {
show: true,
trigger: 'axis',
//formatter: function (params) {
// return params.name + '\t' + renderSize(params.data.value)
//},
valueFormatter: function (value) {
return renderSize(value)
}
},
legend: {
show: true,
top: '3%',
left: 'center',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: true,
data: dateList
},
yAxis: [{
type: 'value',
axisLabel: {
formatter: function (value, index) {
return renderSize(value);
}
},
}, {
type: 'value',
axisLabel: {
formatter: function (v, i) {
if (i === 0) {
v = '0';
}
if (i === 1) {
v = '1';
}
if (i === 2) {
v = '3';
}
if (i === 3) {
v = '5';
}
if (i === 4) {
v = '30';
}
if (i === 5) {
v = '1000';
}
if (i === 6) {
v = '5000';
}
if (i === 7) {
v = '12000';
}
return v;
}
},
}],
series: [
{
name: '做种量',
type: 'line',
yAxisIndex: 0,
{#stack: 'Total',#}
data: seedingSizeList
},
{
name: '上传量',
type: 'line',
yAxisIndex: 0,
{#stack: 'Total',#}
data: uploadedList
},
{
name: '下载量',
type: 'line',
yAxisIndex: 0,
{#stack: 'Total',#}
data: downloadedList
},
{
name: '上传增量',
type: 'bar',
yAxisIndex: 0,
barMaxWidth: '60%',
{#stack: 'Total',#}
data: diff
},
{
name: '魔力值',
type: 'line',
yAxisIndex: 1,
tooltip: {
show: true,
trigger: 'axis',
//formatter: function (params) {
// return params.name + '\t' + renderSize(params.data.value)
//},
valueFormatter: function (value) {
return numberFormat(value)
}
},
{#stack: 'Total',#}
data: spList
},
{
name: '积分',
type: 'line',
yAxisIndex: 1,
tooltip: {
show: true,
trigger: 'axis',
//formatter: function (params) {
// return params.name + '\t' + renderSize(params.data.value)
//},
valueFormatter: function (value) {
return numberFormat(value)
}
},
{#stack: 'Total',#}
data: bonusList
},
{
name: '分享率',
type: 'line',
yAxisIndex: 1,
{#stack: 'Total',#}
tooltip: {
show: true,
trigger: 'axis',
//formatter: function (params) {
// return params.name + '\t' + renderSize(params.data.value)
//},
valueFormatter: function (value) {
return value
}
},
data: ratioList
}
]
};
this.showSiteChart = true
this.showAllHistory = false
setTimeout(() => {
this.chart = this.$refs.seeding_charts.chart
this.setChartOption(this.chart, option)
option.series = [{
name: '上传增量',
type: 'bar',
{#stack: 'Total',#}
barMaxWidth: '60%',
data: diff
}]
this.setChartOption(this.$refs.diff_charts.chart, option)
{#option.title.text = `${site.name} - 魔力积分`#}
option.series = [{
name: '魔力值',
type: 'line',
yAxisIndex: 0,
tooltip: {
show: true,
trigger: 'axis',
//formatter: function (params) {
// return params.name + '\t' + renderSize(params.data.value)
//},
valueFormatter: function (value) {
return numberFormat(value)
}
},
{#stack: 'Total',#}
data: spList
}, {
name: '积分',
type: 'line',
yAxisIndex: 0,
tooltip: {
show: true,
trigger: 'axis',
//formatter: function (params) {
// return params.name + '\t' + renderSize(params.data.value)
//},
valueFormatter: function (value) {
return numberFormat(value)
}
},
{#stack: 'Total',#}
data: bonusList
}, {
name: '分享率',
type: 'line',
yAxisIndex: 1,
{#stack: 'Total',#}
data: ratioList,
tooltip: {
show: true,
trigger: 'axis',
//formatter: function (params) {
// return params.name + '\t' + renderSize(params.data.value)
//},
valueFormatter: function (value) {
return numberFormat(value)
}
},
}]
//option.tooltip.valueFormatter = function (value) {
// return numberFormat(value)
//}
option.yAxis[0].axisLabel.formatter = function (value) {
return numberFormat(value)
}
this.setChartOption(this.$refs.bonus_charts.chart, option)
{#option.title.text = `${site.name} - 分享率`#}
option.series = [{
name: '分享率',
type: 'line',
{#stack: 'Total',#}
data: ratioList
}]
option.tooltip.valueFormatter = null
option.yAxis = {}
this.setChartOption(this.$refs.ratio_charts.chart, option)
}, 50)
},
getData() {
axios.get(
"{% url "site_status_api" %}"
).then(res => {
console.log('获取数据列表成功', res.data)
if (res.data.code === 0) {
console.log(res.data.data)
{#this.ptData = res.data.data#}
this.ptData = res.data.data
{#this.setPie()#}
{#this.setCard()#}
this.sortList()
} else {
this.$message({
type: 'warning',
message: '获取数据列表失败!'
});
}
}).catch(res => {
console.log('获取数据列表失败', res)
this.$message({
type: 'warning',
message: '获取数据列表失败!' + res
});
})
}
}
})
;
</script>
</body>
</html>