add 新增了批量订阅 add

This commit is contained in:
2024-11-21 18:29:19 +08:00
parent b15d1c917f
commit 35b014c585
39 changed files with 1871 additions and 280 deletions

BIN
Web/assets/def.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

View File

@@ -9,6 +9,7 @@
<body>
<div id="header"></div>
不想做了,鸽
</body>
<script src="/layui/layui.js"></script>
<script src="/js/jquery-3.2.1.js"></script>

View File

@@ -89,6 +89,9 @@
]],
done: function () {
done();
if (getParam('type') === 'createRoom') {
createRoom('')
}
},
error: function (res, msg) {
console.log(res, msg)

View File

@@ -23,7 +23,8 @@
</script>
<script type="text/html" id="toolDemo">
<div class="layui-clear-space">
<a class="layui-btn layui-btn-xs" lay-event="edit">删除</a>
<a class="layui-btn layui-btn-xs" lay-event="del">删除</a>
<a class="layui-btn layui-btn-xs" lay-event="input">导入关注</a>
</div>
</script>
<script>
@@ -39,8 +40,12 @@
});
}
function refreshCookie(data) {
console.log(data)
function refresh(data) {
refreshCookie(data)
.then(data => {
console.log(data)
layer.msg(data.message)
})
}
function createRoom() {
login()
@@ -54,9 +59,10 @@
shadeClose: false, // 点击遮罩区域,关闭弹层
maxmin: true, // 允许全屏最小化
anim: 1, // 0-6 的动画形式,-1 不开启
content: '<div style="padding: 32px;text-align: center;" id="qrdiv">登陆后刷新</div>',
content: '<div style="padding: 32px;text-align: center;" id="qrdiv"><span id="loginTip">登陆后刷新</span></div>',
success: function (layero, index, that) {
new QRCode(document.getElementById("qrdiv"), data.data.qrcode);
reloadLogin(document.getElementById("loginTip"))
}
});
} else if (data.status === 301) {
@@ -67,6 +73,17 @@
})
}
function reloadLogin(tips) {
setTimeout(() => {
login()
.then(data => {
tips.innerHTML = data.message;
if (data.code !== 302) {
reloadLogin(tips)
}
})
}, 1000);
}
</script>
<script src="/layui/layui.js"></script>
<script src="/js/jquery-3.2.1.js"></script>
@@ -105,20 +122,56 @@
{ field: 'uid', title: 'UID', width: 150, sort: true, fixed: 'left', templet: '<div><a href="https://space.bilibili.com/{{= d.uid}}" target="_blank">{{= d.uid}}</a>' },
{ field: 'uname', title: '用户名', width: 150, fixed: 'left' },
{ field: 'face', title: '头像', width: 80, templet: '<div><image src="" onerror="showImage(\'{{= d.face }}\',this);" style="width: 30px;height: 30px;"></div>' },
{ field: 'status', title: '状态', width: 150, templet: '<div> {{= d.status}} <button class="layui-btn layui-btn-xs" onclick="refreshCookie(\'{{= d.uid }}\')">刷新cookie</button>' },
{ field: 'status', title: '状态', width: 150, templet: '<div> {{= d.status}} <button class="layui-btn layui-btn-xs" onclick="refresh(\'{{= d.uid }}\')">刷新cookie</button>' },
{ field: 'sql_time', title: '添加时间', width: 190 },
{ fixed: "right", title: "操作", width: 80, align: "center", toolbar: "#toolDemo" }
{ fixed: "right", title: "操作", width: 180, align: "center", toolbar: "#toolDemo" }
]],
done: function () {
onDone();
},
error: function (res, msg) {
console.log(res, msg)
}
});
function onDone() {
table.on('tool(roomTable)', function (obj) {
var id = obj.config.id;
var data = obj.data;
var checkStatus = table.checkStatus(id);
var othis = lay(this);
switch (obj.event) {
case 'input':
onClickInput(data.uid)
break;
};
});
}
function onClickInput(uid) {
layer.open({
type: 2, // page 层类型
area: ['650px', '400px'],
title: '选择主播',
shade: 0.6, // 遮罩透明度
shadeClose: false, // 点击遮罩区域,关闭弹层
maxmin: true, // 允许全屏最小化
anim: 1, // 0-6 的动画形式,-1 不开启
// btn: ['确定', '取消'],
content: '/html/ui/userFollow.html?uid=' + uid,
yes: function (index, layero) {
var iframeWin = window[layero.find('iframe')[0]['name']];
var anchorRoomId = iframeWin.$('#anchorRoomId')[0].value;
if (!hasString(anchorRoomId)) {
layer.msg("请选择")
return
}
let url = new URL(window.location.href);
url.searchParams.set('roomId', anchorRoomId);
window.location.href = url.toString();
}
});
}
});

View File

@@ -46,8 +46,14 @@
&nbsp; <div id="slider" lay-options="{value: 100,input:true}"></div>
<span>弹幕透明度</span>
</div>
</div>
<div class="layui-row">
<div class="layui-col-xs2">&nbsp;</div>
<div class="layui-col-xs7">
<canvas id="giftChart" height="200"></canvas>
</div>
</div>
<div style="margin-bottom: 10vh;"></div>
</body>
<script id="menulist" type="text/html">
<ul class="layui-tab-title">
@@ -106,7 +112,7 @@
<script src="/js/hls.js"></script>
<script src="/js/fly-barrage.iife.js"></script>
<script src="/js/lodash.min.js"></script>
<script src="/js/Chart.min.js"></script>
<script>
headerModel = 2;
@@ -221,9 +227,49 @@
playVideo(data.data)
}, 300)
})
});
initChart(roomId, options.id)
});
function initChart(roomId, videoId) {
getVideoGiftInfo(roomId, videoId)
.then(data => {
if (data.status != 100) {
return
}
var lables = [];
var values = [];
data.data.guardInfo.forEach(item => {
lables.push(item.gift_name+"\n"+item.total_price/100+"¥")
values.push(item.total_num)
});
data.data.giftInfo.forEach(item => {
lables.push(item.gift_name+"\n"+item.total_price/100+"¥")
values.push(item.total_gift_num)
});
new Chart($('#giftChart').get(0), {
type: 'bar',
data: {
labels: lables,
datasets: [{
label: '礼物(总额:'+data.data.price/100+"¥)",
data: values,
borderWidth: 1
}
]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
})
}
function initMenu(data) {
var view = $("#menuView").get(0);
laytpl($('#menulist').get(0).innerHTML).render(data, function (html) {
@@ -244,7 +290,7 @@
layer.open({
type: 2, // page 层类型
area: ['320px', '400px'],
title: '打开B站客户端扫码登陆',
title: '选择主播',
shade: 0.6, // 遮罩透明度
shadeClose: false, // 点击遮罩区域,关闭弹层
maxmin: true, // 允许全屏最小化

133
Web/html/ui/userFollow.html Normal file
View File

@@ -0,0 +1,133 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="/layui/css/layui.css">
</head>
<table class="layui-hide" id="followList" lay-filter="followTable"></table>
<body>
</body>
<script src="/layui/layui.js"></script>
<script src="/js/jquery-3.2.1.js"></script>
<script src="/js/CommonConfig.js"></script>
<script src="/js/httpUtils.js"></script>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" onclick="addAll()">一键配置全部</button>
<button class="layui-btn layui-btn-sm" lay-event="select">配置选择项</button>
</div>
</script>
<script type="text/html" id="toolDemo">
<div class="layui-clear-space">
<a class="layui-btn layui-btn-xs" lay-event="add">添加</a>
</div>
</script>
<script>
var userId = getParam("uid");
function addAll() {
addAllFollow(userId)
.then(data => {
layer.msg(data.message)
})
}
layui.use(function () {
var laytpl = layui.laytpl;
var table = layui.table;
table.render({
elem: '#followList',
url: '/live/config/follow?userId=' + userId,
toolbar: '#toolbarDemo',
height: '350px',
totalRow: true, // 开启合计行
page: true,
response: {
statusCode: 100 // 重新规定成功的状态码为 200table 组件默认为 0
},
parseData: function (res) {
return {
"code": res.status, //解析接口状态
"msg": res.message, //解析提示文本
"data": res.data.list, //解析数据列表
"count": res.count
};
},
cols: [[
{ type: 'checkbox', fixed: 'left' },
{ field: 'mid', title: 'UID', width: 150, sort: true, fixed: 'left', templet: '<div><a href="https://space.bilibili.com/{{= d.mid}}" target="_blank">{{= d.mid}}</a>' },
{ field: 'uname', title: '用户名', width: 150, fixed: 'left' },
{ field: 'face', title: '头像', width: 80, templet: '<div><image src="" onerror="showImage(\'{{= d.face }}\',this);" style="width: 30px;height: 30px;"></div>' },
{ field: 'mtime', title: '关注时间', width: 150, templet: '<div> {{= formatDate(d.mtime*1000)}} </div>' },
{ fixed: "right", title: "操作", width: 50, align: "center", toolbar: "#toolDemo" }
]],
done: function () {
onDone()
},
error: function (res, msg) {
console.log(res, msg)
}
});
function onDone() {
table.on('toolbar(followTable)', function (obj) {
if (obj.event === 'select') {
var data = table.checkStatus(obj.config.id).data;
console.log(data)
var array=[]
data.forEach(item => {
array.push({
"mid":item.mid,
"uname":item.uname
})
});
addFollowList(userId,JSON.stringify(array))
.then(json=>{
layer.msg(json.message)
})
}
})
table.on('tool(followTable)', function (obj) {
if (obj.event === 'add') {
var loadIndex = layer.msg('配置中', {
icon: 16,
shade: 0.6
});;
addFollow(userId, obj.data.mid)
.then(data => {
layer.close(loadIndex)
if (data.status === 3) {
openTips(data.message,obj.data.mid)
} else {
layer.msg(data.message)
}
})
}
})
}
function openTips(message,mid) {
layer.alert(message, {
title: "提示",
btn: ['打开配置页', '前往UP主页', '取消'],
btnAlign: 'c', // 按钮居中显示
btn1: function () {
window.open("/html/body/live.html?type=createRoom" , '_blank')
},
btn2: function () {
window.open("https://space.bilibili.com/" + mid, '_blank')
},
btn3: function () {
}
});
}
})
</script>

View File

@@ -11,12 +11,38 @@
<body>
<div id="header"></div>
<div class="layui-row layui-col-space15">
<div id="follow">
</div>
<div id="card"></div>
</div><br>
<div id="page"></div>
</body>
<script id="followStatus" type="text/html">
{{# layui.each(d.data, function(index, item){ }}
{{# if(item.status !== -1) { }}
{{# var color = item.status === -100 ? "#16b777" : "#ffb800"; }}
{{# var icon = item.status === -100 ? "layui-icon-ok-circle" : "layui-icon-flag"; }}
{{# var isOver = item.status === -100; }}
<blockquote class="layui-elem-quote" style="border-left: 5px solid {{= color}}; margin-left: 5dvw; margin-top: 5dvh; margin-right: 5dvw;">
<i class="layui-icon {{= icon }}" style="font-size: 20px; color: {{= color}};"></i>
<span style="font-size: 16px;" id="{{= item.data}}">
{{= item.message}}
</span>
{{# if(isOver) { }}
<span style="float: right;">
<button type="button" class="layui-btn layui-btn-sm" onclick="confirmFollow({{= item.data}})">确认</button>
</span>
{{# } else { }}
<span style="float: right;">
<button type="button" class="layui-btn layui-btn-sm layui-bg-orange" onclick="confirmFollow({{= item.data}})">取消</button>
</span>
{{# } }}
</blockquote>
{{# } }}
{{# }); }}
</script>
<script id="liveCard" type="text/html">
{{# layui.each(d.data, function(index, item){ }}
<div class="layui-col-xs3 layui-col-sm3 layui-col-md3">
@@ -33,20 +59,21 @@
</span>
</div>
<div class="layui-card-body">
<img src="#" onerror="showTmpImage('{{= item.cover}}',this)" onclick="toLive('{{= item.roomId}}')" style="width: 100%; height: 100%;"/><br>
<img src="#" onerror="showTmpImage('{{= item.cover}}',this)" onclick="toLive('{{= item.roomId}}')" style="width: 312px; height: 175px; object-fit: cover;"/><br>
<!-- <img src="#" onerror="showImage('{{= item.cover}}',this)" onclick="toLive('{{= item.roomId}}')" style="width: 100%; height: 100%;"/><br> -->
{{= item.title}}<br>
<p>开播时长:{{= item.liveTime}}</p>
直播录制状态:
{{# if(item.downloadVideo){ }}
<span style="color: #16b777" onclick="clickVideo('{{= item.roomId}}',true)">录制中</span>
{{# } else{ }}
<span style="color: #FD482C" onclick="clickVideo('{{= item.roomId}}',false)">监听</span>
<span style="color: #FD482C" onclick="clickVideo('{{= item.roomId}}',false)">待机</span>
{{# }; }}<br>
弹幕录制状态:
{{# if(item.danmu){ }}
<span style="color: #16b777" onclick="clickDanmu('{{= item.roomId}}',true)">录制中</span>
{{# } else{ }}
<span style="color: #FD482C" onclick="clickDanmu('{{= item.roomId}}',false)">监听</span>
<span style="color: #FD482C" onclick="clickDanmu('{{= item.roomId}}',false)">待机</span>
{{# }; }}<br>
</div>
</div>
@@ -64,9 +91,9 @@
<script>
headerModel = 0;
$('#header').load("/html/header.html");
function toLive(roomId){
function toLive(roomId) {
console.log(roomId)
window.open("https://live.bilibili.com/"+roomId,'_blank')
window.open("https://live.bilibili.com/" + roomId, '_blank')
}
function clickVideo(roomId, status) {
const title = "是否" + (status ? "停止" : "启动") + "录制视频?"
@@ -114,6 +141,12 @@
layer.msg('点击取消的回调');
});
}
function confirmFollow(userId) {
confirmFollowStatus(userId)
.then(data => {
layer.msg(data.message)
})
}
</script>
<script>
layui.use(['laytpl', 'laypage'], function () {
@@ -121,9 +154,9 @@
var laypage = layui.laypage;
var pageIndex = 1;
var pageMax = 16;
var listCount=10;
var listMax=pageMax;
var initPage=true;
var listCount = 10;
var listMax = pageMax;
var initPage = true;
function initCard() {
var loadIndex = layer.msg('加载中', {
icon: 16,
@@ -131,9 +164,9 @@
});
getAllLive(pageIndex, pageMax)
.then(data => {
listCount=data.count;
if(initPage){
initPage=false;
listCount = data.count;
if (initPage) {
initPage = false;
initPageView();
}
var view = $("#card").get(0);
@@ -141,29 +174,53 @@
view.innerHTML = html;
layer.close(loadIndex)
});
})
}
function initFollowStatus(init) {
checkFollowStatus('')
.then(data => {
var tmp = -1;
data.data.forEach(element => {
tmp = element.status;
});
if (tmp === -1) {
return
}
if (init) {
var view = $("#follow").get(0);
laytpl($('#followStatus').get(0).innerHTML).render(data, function (html) {
view.innerHTML = html;
});
}
setTimeout(() => {
initFollowStatus(true)
}, 1000);
})
}
function init() {
initCard()
initCard();
initFollowStatus(true);
}
function initPageView(){
function initPageView() {
laypage.render({
elem: 'page',
limit: 16,
curr: pageIndex,
limits: [4, 8, 16, 24, 32, 40],
layout: ['prev', 'page', 'next', 'limit'],
count: listCount, // 数据总数
jump: function (obj, first) {
listMax=obj.limit
if (!first) {
pageIndex =obj.curr;
pageMax = obj.limit;
initCard()
}
}
});
elem: 'page',
limit: 16,
curr: pageIndex,
limits: [4, 8, 16, 24, 32, 40],
layout: ['prev', 'page', 'next', 'limit'],
count: listCount, // 数据总数
jump: function (obj, first) {
listMax = obj.limit
if (!first) {
pageIndex = obj.curr;
pageMax = obj.limit;
initCard()
}
}
});
}
init()
})

19
Web/js/Chart.min.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -17,6 +17,7 @@ function getParam(name){
}
}
function showImage(url, imgElement) {
getHttpImage(url)
.then(imageUrl => {
imgElement.src = imageUrl;
@@ -27,6 +28,11 @@ function showImage(url, imgElement) {
});
}
function showTmpImage(url, imgElement) {
console.log(url)
if(!hasString(url)){
imgElement.src='/assets/def.png'
return
}
getHttpTmpImage(url)
.then(blob => {
imgElement.src ="data:image/jpeg;base64,"+blob;
@@ -38,4 +44,17 @@ function showTmpImage(url, imgElement) {
}
function hasString(text){
return !!text;
}
function formatDate(timestamp) {
const date = new Date(timestamp);
const padZero = (num) => (num < 10 ? '0' + num : num);
const year = date.getFullYear();
const month = padZero(date.getMonth() + 1);
const day = padZero(date.getDate());
const hours = padZero(date.getHours());
const minutes = padZero(date.getMinutes());
const seconds = padZero(date.getSeconds());
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

View File

@@ -112,7 +112,23 @@ function getRoomConfig(roomId){
function deleteRoomConfig(roomId){
return get("/live/config/delete?roomId="+roomId)
}
function checkFollowStatus(userId){
return get("/live/config/follow/check?userId="+userId)
}
function confirmFollowStatus(userId){
return get("/live/config/follow/confirm?userId="+userId)
}
function addAllFollow(userId){
return get("/live/config/follow/all?userId="+userId)
}
function addFollow(uid,anchorId){
return get("/live/config/follow/add?anchorId="+anchorId+"&uid="+uid)
}
function addFollowList(uid,array){
const formData = new FormData();
formData.append("array", array);
return post("/live/config/follow/addList?uid="+uid,formData,true)
}
//----------------直播配置相关接口end
//----------------首页相关接口
function getAllLive(page,limit){
@@ -154,4 +170,12 @@ function getBiliAllUser(){
function login(){
return get("/user/login")
}
//----------------用户相关接口end
function refreshCookie(userId){
return get("/user/refreshCookie?uid="+userId)
}
//----------------用户相关接口end
//----------------礼物相关接口
function getVideoGiftInfo(roomId,videoId){
return get("/live/gift/info?roomId="+roomId+"&videoId="+videoId)
}
//----------------礼物相关接口end