From ad30e6bbeb05276e09f575aa0982c58d01265f19 Mon Sep 17 00:00:00 2001 From: whyour Date: Mon, 22 Mar 2021 17:59:21 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84Cookie=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=92=8C=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/cookie.ts | 63 +++++++++++++++++++++++++++++- back/config/index.ts | 2 + back/services/cookie.ts | 48 ++++++++++++++++++----- docker/docker-entrypoint.sh | 12 +++++- sample/config.sh.sample | 14 ------- shell/export_sharecodes.sh | 7 ++-- shell/git_pull.sh | 13 +------ shell/jd.sh | 6 ++- shell/notify.sh | 1 + shell/rm_log.sh | 1 + src/pages/cookie/index.tsx | 78 +++++++++++++++++++++++++++---------- src/pages/cookie/modal.tsx | 74 +++++++++++++++++++++++++++++++++++ 12 files changed, 255 insertions(+), 64 deletions(-) create mode 100644 src/pages/cookie/modal.tsx diff --git a/back/api/cookie.ts b/back/api/cookie.ts index 76f5e59a..ef1bc2b3 100644 --- a/back/api/cookie.ts +++ b/back/api/cookie.ts @@ -46,7 +46,9 @@ export default (app: Router) => { const logger: Logger = Container.get('logger'); try { const cookieService = Container.get(CookieService); - const data = await cookieService.addCookie(req.query.cookie as string); + const data = await cookieService.addQrCookie( + req.query.cookie as string, + ); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); @@ -55,6 +57,65 @@ export default (app: Router) => { }, ); + route.post( + '/cookie', + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const cookieService = Container.get(CookieService); + const data = await cookieService.addCookie(req.body.cookies); + if (data) { + return res.send({ code: 500, data }); + } else { + return res.send({ code: 200, data: '新建成功' }); + } + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.put( + '/cookie', + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const cookieService = Container.get(CookieService); + const data = await cookieService.updateCookie(req.body); + if (data) { + return res.send({ code: 500, data }); + } else { + return res.send({ code: 200, data: '新建成功' }); + } + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.delete( + '/cookie', + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const cookieService = Container.get(CookieService); + const data = await cookieService.deleteCookie( + req.body.cookie as string, + ); + if (data) { + return res.send({ code: 500, data }); + } else { + return res.send({ code: 200, data: '新建成功' }); + } + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + route.post( '/cookie/refresh', async (req: Request, res: Response, next: NextFunction) => { diff --git a/back/config/index.ts b/back/config/index.ts index 3feb8516..42e867a1 100644 --- a/back/config/index.ts +++ b/back/config/index.ts @@ -5,6 +5,7 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'development'; const envFound = dotenv.config(); const rootPath = path.resolve(__dirname, '../../'); +const cookieFile = path.join(rootPath, 'config/cookie.sh'); const confFile = path.join(rootPath, 'config/config.sh'); const sampleFile = path.join(rootPath, 'sample/config.sh.sample'); const crontabFile = path.join(rootPath, 'config/crontab.list'); @@ -41,6 +42,7 @@ export default { crontabFile, sampleFile, confFile, + cookieFile, fileMap: { 'config.sh': confFile, 'crontab.list': crontabFile, diff --git a/back/services/cookie.ts b/back/services/cookie.ts index aa8919ed..11e4e14e 100644 --- a/back/services/cookie.ts +++ b/back/services/cookie.ts @@ -155,14 +155,14 @@ export default class CookieService { return userCookie; } - public async addCookie(oldCookie: string) { + public async addQrCookie(cookie: string) { const res: any = await this.checkLogin(); if (res.body.errcode === 0) { let ucookie = this.getCookie(res); let content = getFileContentByName(config.confFile); const regx = /.*Cookie[0-9]{1}\=\"(.+?)\"/g; if (content.match(regx)) { - const lastCookie = oldCookie || (content.match(regx) as any[]).pop(); + const lastCookie = cookie || (content.match(regx) as any[]).pop(); const cookieRegx = /Cookie([0-9]+)\=.+?/.exec(lastCookie); if (cookieRegx) { const num = parseInt(cookieRegx[1]) + 1; @@ -181,6 +181,40 @@ export default class CookieService { } } + public async addCookie(cookies: string[]) { + let content = getFileContentByName(config.cookieFile); + const originCookies = content.split('\n').filter((x) => !!x); + const result = originCookies.concat(cookies); + fs.writeFileSync(config.cookieFile, result.join('\n')); + return ''; + } + + public async updateCookie({ cookie, oldCookie }) { + let content = getFileContentByName(config.cookieFile); + const cookies = content.split('\n'); + const index = cookies.findIndex((x) => x === oldCookie); + if (index !== -1) { + cookies[index] = cookie; + fs.writeFileSync(config.cookieFile, cookies.join('\n')); + return ''; + } else { + return '未找到要原有Cookie'; + } + } + + public async deleteCookie(cookie: string) { + let content = getFileContentByName(config.cookieFile); + const cookies = content.split('\n'); + const index = cookies.findIndex((x) => x === cookie); + if (index !== -1) { + cookies.splice(index, 1); + fs.writeFileSync(config.cookieFile, cookies.join('\n')); + return ''; + } else { + return '未找到要删除的Cookie'; + } + } + private async checkLogin() { try { if (this.cookies == '') { @@ -224,14 +258,8 @@ export default class CookieService { } public async getCookies() { - const content = getFileContentByName(config.confFile); - const regx = /Cookie[0-9]{1}\=\"(.+?)\"/g; - let m, - data = []; - while ((m = regx.exec(content)) !== null) { - data.push(m[1]); - } - return this.formatCookie(data); + const content = getFileContentByName(config.cookieFile); + return this.formatCookie(content.split('\n').filter((x) => !!x)); } private async formatCookie(data: any[]) { diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 2a416370..11ddff53 100644 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -15,6 +15,12 @@ crond crontab ${JD_DIR}/config/crontab.list echo -e "成功添加定时任务...\n" +if [ ! -s ${JD_DIR}/config/cookie.sh ]; then + echo -e "检测到config配置目录下不存在config.sh,从示例文件复制一份用于初始化...\n" + touch ${JD_DIR}/config/cookie.sh + echo +fi + if [ ! -s ${JD_DIR}/config/config.sh ]; then echo -e "检测到config配置目录下不存在config.sh,从示例文件复制一份用于初始化...\n" cp -fv ${JD_DIR}/sample/config.sh.sample ${JD_DIR}/config/config.sh @@ -38,12 +44,14 @@ bash ${JD_DIR}/shell/git_pull.sh echo echo -e "======================4. 启动挂机程序========================\n" +CookieConf=${JD_DIR}/config/cookie.sh . ${JD_DIR}/config/config.sh -if [ -n "${Cookie1}" ]; then +. ${CookieConf} +if [ -s ${CookieConf} ]; then bash ${JD_DIR}/shell/jd.sh hangup 2>/dev/null echo -e "挂机程序启动成功...\n" else - echo -e "config.sh中还未填入有效的Cookie,可能是首次部署容器,因此不启动挂机程序...\n" + echo -e "尚未在Cookie管理中添加一条Cookie,可能是首次部署容器,因此不启动挂机程序...\n" fi echo -e "======================5. 启动控制面板========================\n" diff --git a/sample/config.sh.sample b/sample/config.sh.sample index 8fb814e2..6f83f862 100644 --- a/sample/config.sh.sample +++ b/sample/config.sh.sample @@ -19,20 +19,6 @@ ## 判断条件 -eq -ne -gt -ge -lt -le ,具体含义可百度一下 -################################## 定义Cookie(必填) ################################## -## 请依次填入每个用户的Cookie,Cookie的具体形式(只有pt_key字段和pt_pin字段,没有其他字段):pt_key=xxxxxxxxxx;pt_pin=xxxx; -## 1. 如果是通过控制面板编辑本文件,点击页面上方“扫码获取Cookie”即可获取,此方式获取的Cookie有效期为3个月 -## 2. 还可以通过浏览器开发工具获取,此方式获得的Cookie只有1个月有效期,教程:https://github.com/LXK9301/jd_scripts/wiki/GetCookies -## 必须按数字顺序1、2、3、4...依次编号下去,例子只有6个,超出6个你继续往下编号即可 -## 不允许有汉字,如果ID有汉字,请在PC浏览器上获取Cookie,会自动将汉字转换为URL编码 -Cookie1="" -Cookie2="" -Cookie3="" -Cookie4="" -Cookie5="" -Cookie6="" - - ################################## 临时屏蔽某个Cookie(选填) ################################## ## 如果某些Cookie已经失效了,但暂时还没法更新,可以使用此功能在不删除该Cookie和重新修改Cookie编号的前提下,临时屏蔽掉某些编号的Cookie ## 多个Cookie编号以半角的空格分隔,两侧一对半角双引号,使用此功能后,在运行js脚本时账户编号将发生变化 diff --git a/shell/export_sharecodes.sh b/shell/export_sharecodes.sh index 2d32145d..832d4bed 100755 --- a/shell/export_sharecodes.sh +++ b/shell/export_sharecodes.sh @@ -19,13 +19,14 @@ Name3=(Fruit Pet Bean DreamFactory JdFactory Joy Jdzz Jxnc BookShop Cash Sgmh Cf function Import_Conf { if [ -f ${FileConf} ] then + . ${CookieConf} . ${FileConf} - if [ -z "${Cookie1}" ]; then - echo -e "请先在 config.sh 中配置好 Cookie\n" + if [ ! -s ${CookieConf} ]; then + echo -e "请先在Cookie管理中添加一条Cookie...\n" exit 1 fi else - echo -e "配置文件 ${FileConf} 不存在,请先按教程配置好该文件\n" + echo -e "配置文件 ${FileConf} 不存在,请先按教程配置好该文件...\n" exit 1 fi } diff --git a/shell/git_pull.sh b/shell/git_pull.sh index 13d8af3a..e28a4a28 100755 --- a/shell/git_pull.sh +++ b/shell/git_pull.sh @@ -8,6 +8,7 @@ LogDir=${ShellDir}/log ScriptsDir=${ShellDir}/scripts ConfigDir=${ShellDir}/config FileConf=${ConfigDir}/config.sh +CookieConf=${ConfigDir}/cookie.sh FileDiy=${ConfigDir}/diy.sh FileConfSample=${ShellDir}/sample/config.sh.sample ListCron=${ConfigDir}/crontab.list @@ -27,6 +28,7 @@ ScriptsURL=https://github.com.cnpmjs.org/RikudouPatrickstar/jd_scripts ## 导入配置文件 function Import_Conf { if [ -f ${FileConf} ]; then + . ${CookieConf} . ${FileConf} fi } @@ -108,17 +110,6 @@ function Update_Entrypoint { fi } -## 用户数量UserSum -function Count_UserSum { - i=1 - while [ $i -le 1000 ]; do - Tmp=Cookie$i - CookieTmp=${!Tmp} - [[ ${CookieTmp} ]] && UserSum=$i || break - let i++ - done -} - ## 检测文件:LXK9301/jd_scripts 仓库中的 docker/crontab_list.sh ## 检测定时任务是否有变化,此函数会在Log文件夹下生成四个文件,分别为: ## task.list crontab.list中的所有任务清单,仅保留脚本名 diff --git a/shell/jd.sh b/shell/jd.sh index af37b8b5..b16fb828 100755 --- a/shell/jd.sh +++ b/shell/jd.sh @@ -7,6 +7,7 @@ ShellDir=${JD_DIR:-$(cd $(dirname $0); pwd)} ScriptsDir=${ShellDir}/scripts ConfigDir=${ShellDir}/config FileConf=${ConfigDir}/config.sh +CookieConf=${ConfigDir}/cookie.sh FileConfSample=${ShellDir}/sample/config.sh.sample LogDir=${ShellDir}/log ListScripts=($(cd ${ScriptsDir}; ls *.js | grep -E "j[drx]_")) @@ -18,9 +19,10 @@ ListJs=${LogDir}/js.list function Import_Conf { if [ -f ${FileConf} ] then + . ${CookieConf} . ${FileConf} - if [ -z "${Cookie1}" ]; then - echo -e "请先在config.sh中配置好Cookie...\n" + if [ ! -s ${CookieConf} ]; then + echo -e "请先在Cookie管理中添加一条Cookie...\n" exit 1 fi else diff --git a/shell/notify.sh b/shell/notify.sh index aa28894b..e5ab49a3 100755 --- a/shell/notify.sh +++ b/shell/notify.sh @@ -1,6 +1,7 @@ #!/bin/bash #author:spark thanks to: https://github.com/sparkssssssss/scripts +. /jd/config/cookie.sh . /jd/config/config.sh title=$(echo $1|sed 's/-/_/g') msg=$(echo -e $2) diff --git a/shell/rm_log.sh b/shell/rm_log.sh index 565c2902..1b97a47b 100755 --- a/shell/rm_log.sh +++ b/shell/rm_log.sh @@ -5,6 +5,7 @@ ShellDir=${JD_DIR:-$(cd $(dirname $0); pwd)} LogDir=${ShellDir}/log ## 导入配置文件 +. ${ShellDir}/config/cookie.sh . ${ShellDir}/config/config.sh ## 删除运行js脚本的旧日志 diff --git a/src/pages/cookie/index.tsx b/src/pages/cookie/index.tsx index eb20f811..d92e5b05 100644 --- a/src/pages/cookie/index.tsx +++ b/src/pages/cookie/index.tsx @@ -1,9 +1,11 @@ import React, { PureComponent, Fragment, useState, useEffect } from 'react'; import { Button, notification, Modal, Table, Tag, Space } from 'antd'; +import { EditOutlined, DeleteOutlined } from '@ant-design/icons'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import QRCode from 'qrcode.react'; +import CookieModal from './modal'; enum Status { '正常', @@ -74,13 +76,8 @@ const Config = () => { align: 'center' as const, render: (text: string, record: any, index: number) => ( - {record.status === 0 && -} - {record.status === 1 && ( - reacquire(record)}>重新获取 - )} - {record.status === 2 && ( - refreshStatus(record, index)}>刷新状态 - )} + editCookie(record, index)} /> + deleteCookie(record, index)} /> ), }, @@ -90,29 +87,19 @@ const Config = () => { const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(); const [loading, setLoading] = useState(true); + const [isModalVisible, setIsModalVisible] = useState(false); + const [editedCookie, setEditedCookie] = useState(); const getCookies = () => { setLoading(true); request .get(`${config.apiPrefix}cookies`) - .then((data) => { + .then((data: any) => { setValue(data.data); }) .finally(() => setLoading(false)); }; - const updateConfig = () => { - request - .post(`${config.apiPrefix}save`, { - data: { content: value, name: 'config.sh' }, - }) - .then((data) => { - notification.success({ - message: data.msg, - }); - }); - }; - function sleep(time: number) { return new Promise((resolve) => setTimeout(resolve, time)); } @@ -198,6 +185,50 @@ const Config = () => { }); }; + const addCookie = () => { + setIsModalVisible(true); + }; + + const editCookie = (record: any, index: number) => { + setEditedCookie(record.cookie); + setIsModalVisible(true); + }; + + const deleteCookie = (record: any, index: number) => { + Modal.confirm({ + title: '确认删除', + content: `确认删除Cookie ${record.cookie} 吗`, + onOk() { + request + .delete(`${config.apiPrefix}cookie`, { + data: { cookie: record.cookie }, + }) + .then((data: any) => { + if (data.code === 200) { + notification.success({ + message: '删除成功', + }); + getCookies(); + } else { + notification.error({ + message: data, + }); + } + }); + }, + onCancel() { + console.log('Cancel'); + }, + }); + }; + + const handleCancel = (needUpdate?: boolean) => { + setIsModalVisible(false); + if (needUpdate) { + getCookies(); + } + }; + useEffect(() => { if (document.body.clientWidth < 768) { setWdith('auto'); @@ -217,7 +248,7 @@ const Config = () => { title="Cookie管理" loading={loading} extra={[ - , ]} @@ -246,6 +277,11 @@ const Config = () => { bordered scroll={{ x: '100%' }} /> + ); }; diff --git a/src/pages/cookie/modal.tsx b/src/pages/cookie/modal.tsx new file mode 100644 index 00000000..6b1f134c --- /dev/null +++ b/src/pages/cookie/modal.tsx @@ -0,0 +1,74 @@ +import React, { useEffect, useState } from 'react'; +import { Modal, notification, Input, Form } from 'antd'; +import { request } from '@/utils/http'; +import config from '@/utils/config'; + +const CookieModal = ({ + cookie, + handleCancel, + visible, +}: { + cookie?: string; + visible: boolean; + handleCancel: (needUpdate?: boolean) => void; +}) => { + const [form] = Form.useForm(); + + const handleOk = async (values: any) => { + const method = cookie ? 'put' : 'post'; + const payload = cookie + ? { cookie: values.cookie, oldCookie: cookie } + : { cookies: values.cookie.split('\n') }; + const { code, data } = await request[method](`${config.apiPrefix}cookie`, { + data: payload, + }); + if (code === 200) { + notification.success({ + message: cookie ? '更新Cookie成功' : '添加Cookie成功', + }); + } else { + notification.error({ + message: data, + }); + } + handleCancel(true); + }; + + useEffect(() => { + if (cookie) { + form.setFieldsValue({ cookie }); + } + }, [cookie]); + + return ( + { + form + .validateFields() + .then((values) => { + handleOk(values); + }) + .catch((info) => { + console.log('Validate Failed:', info); + }); + }} + onCancel={() => handleCancel()} + > +
+ + + +
+
+ ); +}; + +export default CookieModal;