初始化

master
飘泊客 1 year ago
parent 2080f93560
commit f5b22f173d

@ -0,0 +1,40 @@
/*
* @Description:
* @Autor: 飘泊客
* @Date: 2023-02-14 15:16:38
* @LastEditors: 飘泊客
* @LastEditTime: 2023-03-16 15:10:55
*/
const VUE_APP_BASE_API = 'https://cdp.baiyee.vip'
// const axios = require('axios')
const CookiesFlict = Cookies.noConflict()
function getCookie(name) {
return CookiesFlict.get(name)
}
function setCookie(name, cookie) {
return CookiesFlict.set(name, cookie, {expires: 7})
}
function removeCookie(name) {
CookiesFlict.remove(name)
}
// 随机生成数字字母组合字符串
function getRandomAlphaNum(len) {
let rdmString = ''
for (; rdmString.length < len; rdmString += Math.random().toString(36).substring(2)); return rdmString.substring(0, len)
}
function getUserinfo(cookie) {
return new Promise((resolve, reject) => {
axios.get( VUE_APP_BASE_API + '/api-xhs/xhs/requestXhsApi?cid=' + cookie, {
}).then(res => {
console.log('res==', res)
resolve(res.data)
}).catch(err => {
console.log('err==', err.response)
reject(err.response)
})
})
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,741 @@
<!--
* @Description:
* @Autor: 飘泊客
* @Date: 2023-01-30 16:40:50
* @LastEditors: 飘泊客
* @LastEditTime: 2023-03-24 19:00:14
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link rel="shortcut icon" href="https://baiyee.vip/favicon.ico">
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="./auth.js"></script>
</head>
<body>
<div id="app">
<!-- <header class="u-flex u-flex-between">
顶部信息
<at-button size="small" @click="showLoginProp">添加</at-button>
</header> -->
<!-- <at-button @click="showMessage1">get1</at-button> -->
<div class="account-wrap">
<div class="account-list-wrap">
<header>
<div class="p-10">
<el-popover
v-model="visible"
placement="bottom"
width="320"
trigger="manual">
<div>
<el-form ref="form" :model="form" label-width="0">
<el-form-item >
<el-input v-model="form.nickName" size="small" placeholder="搜索账号" style="width: 100%;"></el-input>
</el-form-item>
<el-form-item>
<el-select v-model="form.terrace" placeholder="平台" size="small" style="width: 100%;">
<el-option label="小红书" value="1"></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item>
<el-select v-model="form.status" placeholder="状态" size="small" style="width: 100%;">
<el-option label="已登录" value="1"></el-option>
<el-option label="未登录" value="2"></el-option>
</el-select>
</el-form-item> -->
<el-form-item style="text-align: right;">
<el-button size="small" @click="initAccount" >重置</el-button>
<el-button type="primary" size="small" @click="toSearch" >搜索</el-button>
</el-form-item>
</el-form>
</div>
<el-input slot="reference" size="small" placeholder="搜索账号" readonly suffix-icon="el-icon-search" @focus="visible = !visible" />
</el-popover>
</div>
<div class="u-flex u-flex-between" style="padding: 0 10px 10px;">
<el-button size="small" type="primary" icon="el-icon-plus" @click="addGroupProp">分类组</el-button>
<el-button size="small" type="primary" icon="el-icon-plus" @click="openSelect">账号</el-button>
</div>
</header>
<div class="account-list-content mt-5 sim-cont">
<el-menu
v-if="accountList.length > 0"
:default-active="activeName"
class="el-menu-vertical-demo"
@select="changAccountSelect"
style="width: 202px;"
:unique-opened="true"
>
<el-submenu v-for="(item, index) in accountList" :index="index">
<template slot="title">
<span>{{ item.groupName }}</span>
</template>
<el-menu-item-group v-for="(it, idx) in item.childList" :key="idx" title="">
<el-menu-item :index="index + '-' + idx">
<div class="u-flex account-item">
<img :src="it.avater" class="u-avater" :class="{'u-filter': it.loginStatus == 2}">
<div class="ml-5 account-item-right" :class="{'u-filter': it.loginStatus == 2}">
<span class="account-list-name">{{ it.nickName }}</span>
<span class="line-span">{{ it.type == 1 ? '小红书' : '未知' }}</span>
</div>
</div>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
<div v-else>
<el-empty description="快去添加账号吧~"></el-empty>
</div>
</div>
</div>
<div class="account-tabs-wrap">
<div class="at-tabs">
<el-tabs v-model="activeTabName" closable @tab-click="handleTabClick" @tab-remove="handleTabRemove">
<el-tab-pane v-for="(item, index) in tabList" :key="item.characteristic" :name="item.characteristic" >
<div slot="label" class="u-flex">
<el-avatar size="small" shape="circle" :src="item.avater"></el-avatar>
<span class="ml-5">{{ item.type == 1 ? '小红书' : '未知' }}-{{ item.label }}</span>
</div>
<div class="tab-web-view">
<div class="ant-tabs-content">
<webview :id="item.characteristic" :src="item.url" :partition="item.partition" style="width: 100%; height: 100%; border: 0px;"/>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</div>
<el-dialog
title=""
:visible.sync="addAcount"
class="loginProp"
width="98vw"
>
<div id="login" ref="login" style="height: 820px;width: 100%;"></div>
<!-- <at-button @click="showMessage1">get1</at-button> -->
</el-dialog>
<el-dialog
title="新增账号"
:visible.sync="selectProp"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
width="30%"
>
<el-select v-model="groupRegion" size="small" placeholder="选择分类组" style="width: 100%;">
<el-option v-for="(item, index) in accountList" :label="item.groupName" :value="item.groupId" />
</el-select>
<span slot="footer" class="dialog-footer">
<el-button size="small" @click="closeSelect">取 消</el-button>
<el-button size="small" type="primary" @click="showLoginProp">确 定</el-button>
</span>
</el-dialog>
</div>
</body>
<script>
// const request = require('request')
// var request = require('sync-request')
const session = require('express-session')
new Vue({
el: '#app',
data: {
addAcount: false,
selectProp: false,
addPartition: '',
seachName: '',
visible: false,
activeName: '', // 当前active
activeTabName: '', // 当前tab
groupRegion: '', // 新增的组
vwId: '', // 生成主键
tabList: [], // 账号列表
form: {
nickName: '',
terrace: '1',
status: ''
},
routerInterval: null,
accountList: [
// {
// groupName: '幽密蘑菇林',
// groupId: '10',
// childList: [
// {
// id: '1',
// nickName: '蘑菇',
// label: '蘑菇',
// characteristic: 'webview_F8As5EnDBf',
// partition: 'persist:F8As5EnDBf',
// url: 'https://creator.xiaohongshu.com/creator/home',
// avater: 'https://pic4.zhimg.com/80/v2-7e84978160b3dc2b2733000a01c408cb_720w.webp',
// personal_desc: '无',
// type: 1
// },
// {
// id: '2',
// nickName: '呀哈哈',
// label: '呀哈哈',
// characteristic: 'webview_P00MJiPZ1L',
// partition: 'persist:P00MJiPZ1L',
// url: 'https://creator.xiaohongshu.com/creator/home',
// avater: 'https://pic4.zhimg.com/80/v2-7e84978160b3dc2b2733000a01c408cb_720w.webp',
// personal_desc: '无',
// type: 1
// }
// ]
// }
]
},
mounted() {
// 取出cookie 暂不处理
// 解密拼接
// 传值iframe
this.accountList = JSON.parse(localStorage.getItem('accountList')) || []
this.tabList = JSON.parse(localStorage.getItem('tabList')) || []
console.log('accountList=', this.accountList)
this.$nextTick(() => {
if (this.accountList.length > 0 && this.tabList.length > 0) {
// this.activeName = this.accountList[0].childList[0].characteristic
this.activeTabName = this.tabList[0].characteristic
}
})
},
methods: {
closeSelect() {
this.groupRegion = ''
this.selectProp = false
},
addGroupProp() {
this.$prompt('请输入分类名', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(({ value }) => {
let obj = {
groupName: value,
groupId: getRandomAlphaNum(3),
childList: []
}
this.accountList.push(obj)
localStorage.setItem('accountList', JSON.stringify(this.accountList))
}).catch(() => {});
},
// tabclose
handleTabClick(e) {
// this.activeName = e.name
},
// 打开账号添加
openSelect() {
this.initAccount()
this.selectProp = true
},
// 重置搜索
initAccount() {
this.visible = false
this.form.nickName = ''
this.accountList = JSON.parse(localStorage.getItem('accountList')) || []
},
// 搜索
toSearch() {
const accList = JSON.parse(localStorage.getItem('accountList')) || []
let arr = []
accList.forEach(item => {
arr = [...arr, ...item.childList.filter(it => it.nickName.search(this.form.nickName) !== -1)]
})
let obj = {
groupName: '共搜索到' + arr.length + '条',
groupId: '01',
childList: arr
}
this.accountList = [obj]
this.visible = false
},
initTime() {
// setInterval(() => {
// this.tabList.forEach(item => {
// this.useGetCookie('https://creator.xiaohongshu.com/creator/home', document.getElementById(item.characteristic).getCookieStoreId()).then(res => {
// this.accountList.forEach(it => {
// it.childList.forEach(t => {
// if (t.characteristic === item.characteristic) return t.cookies = this.handleCookie(res)
// })
// })
// })
// })
// }, 60000 * 60)
},
handleTabRemove(e) {
let index = this.tabList.findIndex(item => item.characteristic === e)
if (this.activeTabName === e && this.tabList.length > 1) {
this.activeTabName = this.tabList[index = index == 0 ? index + 1 : index - 1].characteristic
}
this.tabList.splice(this.tabList.findIndex(item => item.characteristic === e), 1)
localStorage.setItem('tabList', JSON.stringify(this.tabList))
},
// 左侧选择
changAccountSelect(key) {
const headIndex = key.split('-')[0]
const afterIndex = key.split('-')[1]
const characteristic = this.accountList[headIndex].childList[afterIndex].characteristic
let tabIndex = this.tabList.findIndex(item => item.characteristic === characteristic)
if (tabIndex !== -1) {
this.activeTabName = this.tabList[tabIndex].characteristic
} else {
this.accountList.forEach(res => {
const obj = res.childList.filter(it => it.characteristic === characteristic)[0] || null
obj && this.tabList.push(obj)
})
tabIndex = this.tabList.length - 1
this.activeTabName = this.tabList[tabIndex].characteristic
}
//验证cookie
this.intendedEffect(headIndex, afterIndex, tabIndex)
},
// 定时器间隔拉取右侧有效cookie同步到左侧用户信息
// 点击时效验cookie 是否失效
showMessage1: function () {
this.tabList.forEach(item => {
this.useGetCookie('https://creator.xiaohongshu.com/creator/home', document.getElementById(item.characteristic).getCookieStoreId()).then(res => {
console.log('cookies=', res)
// if (res.findIndex(item => item.name === 'access-token') !== -1) {
// }
})
})
},
showLoginProp() {
if (!this.groupRegion) {
this.$message({
message: '请选择组',
type: 'warning'
})
return false
}
this.selectProp = false
this.addAcount = true
// this.vwId = 'webview_123456788'
// this.addPartition = 'persist:123456788'
const identification = getRandomAlphaNum(9)
this.addPartition = 'persist:' + identification
this.vwId = 'webview_' + identification
this.$nextTick(() => {
const viewWrap = `<webview id="${this.vwId}" partition="${this.addPartition}" src="https://creator.xiaohongshu.com/login" style="width: 100%; height: 100%; border: 0px;"/>`
document.getElementById('login').innerHTML = viewWrap
// 临时处理监听跳转关闭
const routerInterval = setInterval(() => {
this.useGetCookie('https://creator.xiaohongshu.com/creator/home', document.getElementById(this.vwId).getCookieStoreId()).then(res => {
if (res.length >= 10) {
// 获取个人信息
this.getUserInfo_personal(res)
clearInterval(routerInterval)
}
})
}, 3000)
})
},
// 效验cookie
async intendedEffect(headIndex, afterIndex, tabIndex) {
// 2 获取右侧cookie信息判断是否有效
// 3 匹配同步cookie信息
setTimeout( async() => {
let userInfo = this.tabList[tabIndex]
const cookies = await this.useGetCookie('https://creator.xiaohongshu.com/creator/home', document.getElementById(userInfo.characteristic).getCookieStoreId()).then(res => {
return this.handleCookie(res)
})
try {
const resultDaata = (await getUserinfo(cookies))
if (resultDaata.data) {
userInfo.nickName = resultDaata.data.name
userInfo.label = resultDaata.data.name
userInfo.avater = resultDaata.data.avatar
userInfo.personal_desc = resultDaata.data.personal_desc
userInfo.loginStatus = 1
userInfo.cookies = cookies
} else if(resultDaata.result === -100){
userInfo.loginStatus = 2
}
this.tabList[tabIndex] = userInfo
this.accountList[headIndex].childList[afterIndex] = userInfo
localStorage.setItem('accountList', JSON.stringify(this.accountList))
localStorage.setItem('tabList', JSON.stringify(this.tabList))
} catch (e) {
console.log('response', e)
if (e.data.code === 401) {
userInfo.loginStatus = 2
}
this.accountList[headIndex].childList[afterIndex] = userInfo
this.tabList[tabIndex] = userInfo
localStorage.setItem('accountList', JSON.stringify(this.accountList))
localStorage.setItem('tabList', JSON.stringify(this.tabList))
// return Promise.reject(e)
}
}, 1500)
},
async getUserInfo_personal(data) {
let notUplicate = true
// 用户信息
const userInfo = (await getUserinfo(this.handleCookie(data))).data
const groupIndex = this.accountList.findIndex(item => item.groupId === this.groupRegion)
// const groupInfo = this.accountList[groupIndex]
// 获取源数据
// 判断是否id已存在
// 根据组id差入数据、
this.accountList.forEach(item => {
// 小红书
// if (groupInfo.type === 1) {
if (item.childList.filter(it => it.id === userInfo.red_num).length > 0) {
this.$message({
message: '请勿重复添加用户',
type: 'error'
})
notUplicate = false
return false
}
// }
})
if (notUplicate) {
const obj = {
characteristic: this.vwId,
partition: this.addPartition,
type: 1,
url: 'https://creator.xiaohongshu.com/creator/home',
cookies: this.handleCookie(data),
loginStatus: 1
}
obj.nickName = userInfo.name
obj.label = userInfo.name
obj.avater = userInfo.avatar
obj.id = userInfo.red_num
obj.personal_desc = userInfo.personal_desc
this.accountList[groupIndex].childList.push(obj)
localStorage.setItem('accountList', JSON.stringify(this.accountList))
}
this.addAcount = false
},
handleCookie(data) {
let cookie = ''
data.forEach(item => { cookie += `${item.name} = ${item.value};`})
return cookie
},
useGetCookie(e, t) {
return new Promise(function(resolve, reject) {
chrome.cookies.getAll({
url: e,
storeId: t
}, function(e) {
resolve(e)
})
})
}
}
})
// var cookieArr = []
// var gui = require('nw.gui');
// var win = gui.Window.get();
// win.on('new-win-policy', newWinPolicyHandler);
// function newWinPolicyHandler(frame, url, policy) {
// policy.ignore(); //ignore policy first to prevent popup
// // $("#ifr2").attr("src",url); //load popup url into iFrame 后来$("#ifr2")获取不到了;改成下面的方式:
// // document.getElementById("#welIfr1").src = url;
// // document.getElementById("#welIfr1").contentDocument.getElementById("#ifr2").src = url; 这个是设置iframe内的iframe路径
// // document.getElementById("ifr4").contentWindow.document.getElementById("cctvIfr")
// $("#ifr4").attr("src", url)
// }
// nw.Window.get().on('new-win-policy', function(frame, url, policy) {
// console.log('neibu')
// // 不打开窗口
// policy.ignore();
// // 在系统默认浏览器打开
// nw.Shell.openExternal(url);
// });
// nw.Window.get().on('navigation', function(frame, url, policy){
// console.log('我是frame', frame)
// console.log('我是url', url)
// console.log('我是policy', policy)
// })
// function getCookie() {
// var win = nw.Window.get()
// win.title = 'cc'
// console.log('win2=', win)
// }
// function opentab(id) {
// $('#' + id).toggleClass('no')
// }
// function openWin() {
// // nw.window.open('https://creator.xiaohongshu.com/login?lastUrl=%252Fcreator%252Fhome', {}, function(new_win) {
// // // 监听新窗口焦点事件
// // new_win.on('focus', function() {
// // console.log('New window is focused');
// // });
// // })
// nw.Window.open('https://www.baidu.com', {
// id: 'login',
// title: '小红书',
// position: 'center',
// width: 1150,
// height: 750,
// new_instance: false,
// id: 'tab3',
// resizable: false // 是否可拖动
// }, function(new_win) {
// new_win.setAlwaysOnTop(false)
// new_win.setVisibleOnAllWorkspaces(false)
// new_win.on('loaded', () => {
// console.log('我是loaded')
// })
// new_win.on('blur', () => {
// console.log('我是blur')
// })
// new_win.on('onunload', () => {
// console.log('我是onunload')
// })
// new_win.on('closed', () => {
// console.log('我是closed')
// })
// new_win.on('onbeforeunload', () => {
// console.log('我是onbeforeunload')
// })
// new_win.on('navigation', function(frame, url, policy){
// console.log('我是frame', frame)
// console.log('我是url', url)
// console.log('我是policy', policy)
// })
// });
// }
</script>
<style>
body {
padding: 0;
margin: 0;
}
.loginProp .el-dialog{
margin-top: 1vh!important;
}
.loginProp .el-dialog__body {
padding: 0;
}
.el-tabs__nav {
display: flex;
}
.el-form-item {
margin-bottom: 0;
}
.el-menu-item.is-active:after{
content: "";
display: inline-block;
position: absolute;
top: 0;
left: 0;
width: 6px;
height: 100%;
background-color: #6190e8;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
box-shadow: 1px 0 12px 0 #6190e8;
}
.el-tabs__content {
height: calc(100vh - 60px);
overflow-y: auto;
}
.el-tab-pane {
height: 99%;
}
.el-tabs__item {
display: flex;
align-items: center;
position: relative;
cursor: pointer;
font-size: 12px;
margin-top: 4px;
padding: 0 12px;
}
.el-menu-item-group__title {
display: none;
}
.el-submenu .el-menu-item {
padding: 0;
}
.account-list-content {
height: calc(100vh - 83px);
overflow-y: scroll;
overflow-x: hidden;
}
.account-list-name {
font-size: 14px;
font-family: PingFangSC-Regular,PingFang SC;
font-weight: 500;
color: rgba(0,0,0,.85);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-bottom: 3px;
}
.account-item {
height: inherit;
}
.account-item-right {
width: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.account-item-right span {
line-height: normal;
}
.u-filter {
filter: grayscale(1);
}
.u-avater {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 10px;
}
.line-span {
font-size: 12px;
color: rgba(0,0,0,.45);
}
.mt-5 {
margin-top: 5px;
}
.ml-5 {
margin-left: 5px;
}
.p-10 {
padding: 10px;
}
.text-hide {
overflow: hidden;
text-overflow: ellipsis;
white-space:nowrap
}
.text-hide-2 {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.u-flex {
display: flex;
align-items: center;
}
.flex-start {
align-items: flex-start;
}
.u-flex-between {
justify-content: space-between;
}
.u-flex-center {
justify-content: center;
}
.u-flex-around {
justify-content: space-around;
}
.u-flex-end {
justify-content: flex-end;
}
.u-flex-wrap {
flex-wrap: wrap;
}
.flex-1 {
flex: 1;
}
#app {
display: flex;
flex-direction: column;
height: 100%;
}
header {
position: relative;
width: 100%;
height: 82px;
z-index: 11;
color: rgba(0,0,0,.85);
background: #fff;
box-shadow: 0 2px 9px 0 rgb(0 0 0 / 5%);
-webkit-app-region: no-drag;
}
.width-100 {
width: 100%;
}
.account-wrap {
display: flex;
justify-content: flex-start;
align-items: flex-start;
height: 100%;
overflow: hidden;
}
.account-list-wrap {
position: relative;
width: 202px;
display: flex;
flex-direction: column;
height: 100%;
background: #fff;
border-right: 1px solid #eee;
transition: all .2s ease-in-out;
}
.account-tabs-wrap {
flex: 1;
height: 100vh;
}
.at-tabs {
width: calc(100vw - 202px);
height: 100%;
background: #fff;
box-sizing: border-box;
margin: 0;
padding: 0;
color: rgba(0,0,0,.85);
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5715;
list-style: none;
display: flex;
flex-direction: column;
}
.tab-web-view {
height: 100%;
}
.ant-tabs-content {
flex: auto;
min-width: 0;
min-height: 0;
height: 100%;
}
.sim-cont{
max-height: 100%;
overflow: auto;
}
.sim-cont::-webkit-scrollbar { /*滚动条整体样式*/
width: 5px;
height: 3px;
}
.sim-cont::-webkit-scrollbar-thumb { /*滚动条里面小方块样式*/
border-radius: 100px;
-webkit-box-shadow: inset 0 0 5px rgba(151, 151, 151, 0.2);
background:rgba(0,0,0,0.1);;
}
.sim-cont::-webkit-scrollbar-track { /*滚动条里面轨道样式*/
-webkit-box-shadow: inset 0 0 5px rgba(223, 223, 223, 0.2);
border-radius: 100px;
background: rgba(0,0,0,0.1);
}
</style>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

@ -0,0 +1,47 @@
{
"name": "service-cdp",
"version": "1.0.3",
"description": "",
"build": "100001",
"main": "index.html",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"window": {
"title": "太空猫 v1.0.3",
"icon": "./logo.png",
"toolbar": true,
"frame": true,
"resizable": true,
"id": "tab3",
"width": 1275,
"height": 830,
"position": "mouse",
"min_width": 800,
"min_height": 500,
"transparent": false,
"show": true,
"show_in_taskbar": true
},
"webkit": {
"plugin": true
},
"keywords": [],
"author": "",
"license": "ISC",
"webview": {
"partitions": [
{
"name": "trusted",
"accessible_resources": [
"<all_urls>"
]
}
]
},
"dependencies": {
"express-session": "^1.17.3",
"request": "^2.88.2",
"sync-request": "^6.1.0"
}
}

@ -0,0 +1,7 @@
/*
* @Description:
* @Autor: 飘泊客
* @Date: 2023-02-20 17:28:44
* @LastEditors: 飘泊客
* @LastEditTime: 2023-02-23 14:34:14
*/
Loading…
Cancel
Save