mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-22 14:26:07 +08:00
初始化项目
This commit is contained in:
commit
f1f8ece8a2
16
.editorconfig
Executable file
16
.editorconfig
Executable file
|
@ -0,0 +1,16 @@
|
|||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/npm-debug.log*
|
||||
/yarn-error.log
|
||||
/yarn.lock
|
||||
/package-lock.json
|
||||
|
||||
# production
|
||||
/dist
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
|
||||
# umi
|
||||
/src/.umi
|
||||
/src/.umi-production
|
||||
/src/.umi-test
|
||||
/.env.local
|
||||
/config
|
8
.prettierignore
Normal file
8
.prettierignore
Normal file
|
@ -0,0 +1,8 @@
|
|||
**/*.md
|
||||
**/*.svg
|
||||
**/*.ejs
|
||||
**/*.html
|
||||
package.json
|
||||
.umi
|
||||
.umi-production
|
||||
.umi-test
|
11
.prettierrc
Normal file
11
.prettierrc
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 80,
|
||||
"overrides": [
|
||||
{
|
||||
"files": ".prettierrc",
|
||||
"options": { "parser": "json" }
|
||||
}
|
||||
]
|
||||
}
|
18
.umirc.ts
Normal file
18
.umirc.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { defineConfig } from 'umi';
|
||||
import { SmileOutlined, CrownOutlined, TabletOutlined, AntDesignOutlined } from '@ant-design/icons';
|
||||
|
||||
export default defineConfig({
|
||||
layout: false,
|
||||
locale: {},
|
||||
nodeModulesTransform: {
|
||||
type: 'none',
|
||||
},
|
||||
fastRefresh: {},
|
||||
favicon: 'http://demo.sc.chinaz.com/Files/pic/iconsico/8002/g5.ico',
|
||||
proxy: {
|
||||
'/api': {
|
||||
'target': 'http://127.0.0.1:5678/',
|
||||
'changeOrigin': true,
|
||||
},
|
||||
},
|
||||
});
|
27
README.md
Normal file
27
README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
## 青龙(WIP)
|
||||
|
||||
青龙,又名苍龙,在中国传统文化中是四象之一、[天之四灵](https://zh.wikipedia.org/wiki/%E5%A4%A9%E4%B9%8B%E5%9B%9B%E7%81%B5)之一,根据五行学说,它是代表东方的灵兽,为青色的龙,五行属木,代表的季节是春季,八卦主震。苍龙与应龙一样,都是身具羽翼。《张果星宗》称“又有辅翼,方为真龙”。
|
||||
|
||||
《后汉书·律历志下》记载:日周于天,一寒一暑,四时备成,万物毕改,摄提迁次,青龙移辰,谓之岁。
|
||||
|
||||
在中国[二十八宿](https://zh.wikipedia.org/wiki/%E4%BA%8C%E5%8D%81%E5%85%AB%E5%AE%BF)中,青龙是东方七宿(角、亢、氐、房、心、尾、箕)的总称。 在早期星宿信仰中,祂是最尊贵的天神[1]。 但被道教信仰吸纳入其神系后,神格大跌,道教将其称为“孟章”,在不同的道经中有“帝君”、“圣将”、“神将”和“捕鬼将”等称呼[2],与白虎监兵神君一起,是道教的护卫天神。
|
||||
|
||||
## 多谢
|
||||
|
||||
本仓库部分shell脚本及其配置参考自[nevinee](https://github.com/nevinee)大佬, [https://github.com/nevinee/jd_shell](https://github.com/nevinee/jd_shell), 感谢👍👍👍
|
||||
|
||||
## 免责声明
|
||||
|
||||
1. 此仓储脚本仅用于学习研究,不保证其合法性、准确性、有效性,请根据情况自行判断,本人对此不承担任何保证责任。
|
||||
|
||||
2. 由于此仓储脚本仅用于学习研究,您必须在下载后 24 小时内将所有内容从您的计算机或手机或任何存储设备中完全删除,若违反规定引起任何事件本人对此均不负责。
|
||||
|
||||
3. 请勿将此仓储脚本用于任何商业或非法目的,若违反规定请自行对此负责。
|
||||
|
||||
4. 此仓储脚本涉及应用与本人无关,本人对因此引起的任何隐私泄漏或其他后果不承担任何责任。
|
||||
|
||||
5. 本人对任何脚本引发的问题概不负责,包括但不限于由脚本错误引起的任何损失和损害。
|
||||
|
||||
6. 如果任何单位或个人认为此仓储脚本可能涉嫌侵犯其权利,应及时通知并提供身份证明,所有权证明,我们将在收到认证文件确认后删除此仓储脚本。
|
||||
|
||||
7. 所有直接或间接使用、查看此仓储脚本的人均应该仔细阅读此声明。本人保留随时更改或补充此声明的权利。一旦您使用或复制了此仓储脚本,即视为您已接受此免责声明。
|
24
csv.sh
Normal file
24
csv.sh
Normal file
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
## 判断环境
|
||||
ShellDir=${JD_DIR:-$(cd $(dirname $0); pwd)}
|
||||
LogDir=${ShellDir}/log
|
||||
Income=${LogDir}/bean_income.csv
|
||||
Outlay=${LogDir}/bean_outlay.csv
|
||||
|
||||
## 执行
|
||||
cd ${LogDir}/jd_bean_change
|
||||
for log in $(ls); do
|
||||
LogDate=$(echo ${log} | cut -c1-10)
|
||||
BeanDate=$(date "+%Y-%m-%d" -d "1 day ago ${LogDate}")
|
||||
|
||||
if [[ -z $(grep "${BeanDate}" ${Income}) ]]; then
|
||||
echo -n "${BeanDate}," >> ${Income}
|
||||
grep -E "昨日收入" ${log} | grep -oE "\d+" | perl -0777 -pe "s|\n(\d+)|,\1|g" >> ${Income}
|
||||
fi
|
||||
|
||||
if [[ -z $(grep "${BeanDate}" ${Outlay}) ]]; then
|
||||
echo -n "${BeanDate}," >> ${Outlay}
|
||||
grep -E "昨日支出" ${log} | grep -oE "\d+" | perl -0777 -pe "s|\n(\d+)|,\1|g" >> ${Outlay}
|
||||
fi
|
||||
done
|
143
export_sharecodes.sh
Executable file
143
export_sharecodes.sh
Executable file
|
@ -0,0 +1,143 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
## 路径、环境判断
|
||||
ShellDir=${JD_DIR:-$(cd $(dirname $0); pwd)}
|
||||
LogDir=${ShellDir}/log
|
||||
ConfigDir=${ShellDir}/config
|
||||
FileConf=${ConfigDir}/config.sh
|
||||
[[ ${ANDROID_RUNTIME_ROOT}${ANDROID_ROOT} ]] && Opt="P" || Opt="E"
|
||||
Tips="从日志中未找到任何互助码"
|
||||
|
||||
## 所有有互助码的活动,只需要把脚本名称去掉前缀 jd_ 后列在 Name1 中,将其中文名称列在 Name2 中,对应 config.sh 中互助码后缀列在 Name3 中即可。
|
||||
## Name1、Name2 和 Name3 中的三个名称必须一一对应。
|
||||
Name1=(fruit pet plantBean dreamFactory jdfactory crazy_joy jdzz jxnc bookshop cash sgmh cfd global)
|
||||
Name2=(东东农场 东东萌宠 京东种豆得豆 京喜工厂 东东工厂 crazyJoy任务 京东赚赚 京喜农场 口袋书店 签到领现金 闪购盲盒 京喜财富岛 环球挑战赛)
|
||||
Name3=(Fruit Pet Bean DreamFactory JdFactory Joy Jdzz Jxnc BookShop Cash Sgmh Cfd Global)
|
||||
|
||||
|
||||
## 导入 config.sh
|
||||
function Import_Conf {
|
||||
if [ -f ${FileConf} ]
|
||||
then
|
||||
. ${FileConf}
|
||||
if [ -z "${Cookie1}" ]; then
|
||||
echo -e "请先在 config.sh 中配置好 Cookie\n"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo -e "配置文件 ${FileConf} 不存在,请先按教程配置好该文件\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
## 用户数量 UserSum
|
||||
function Count_UserSum {
|
||||
for ((i=1; i<=1000; i++)); do
|
||||
Tmp=Cookie$i
|
||||
CookieTmp=${!Tmp}
|
||||
[[ ${CookieTmp} ]] && UserSum=$i || break
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
## 导出互助码的通用程序
|
||||
function Cat_Scodes {
|
||||
if [ -d ${LogDir}/jd_$1 ] && [[ $(ls ${LogDir}/jd_$1) != "" ]]; then
|
||||
cd ${LogDir}/jd_$1
|
||||
|
||||
## 导出助力码变量(My)
|
||||
for log in $(ls -r); do
|
||||
case $# in
|
||||
2)
|
||||
codes=$(cat ${log} | grep -${Opt} "开始【京东账号|您的(好友)?助力码为" | uniq | perl -0777 -pe "{s|\*||g; s|开始||g; s|\n您的(好友)?助力码为(:)?:?|:|g; s|,.+||g}" | sed -r "s/【京东账号/My$2/;s/】.*?:/='/;s/】.*?/='/;s/$/'/;s/\(每次运行都变化,不影响\)//")
|
||||
;;
|
||||
3)
|
||||
codes=$(grep -${Opt} $3 ${log} | uniq | sed -r "s/【京东账号/My$2/;s/(.*?】/='/;s/$/'/")
|
||||
;;
|
||||
esac
|
||||
if [[ ${codes} ]]; then
|
||||
## 添加判断,若未找到该用户互助码,则设置为空值
|
||||
for ((user_num=1;user_num<=${UserSum};user_num++)); do
|
||||
echo -e "${codes}" | grep -${Opt}q "My$2${user_num}="
|
||||
if [ $? -eq 1 ]; then
|
||||
if [ $user_num == 1 ]; then
|
||||
codes=$(echo "${codes}" | sed -r "1i My${2}1=''")
|
||||
else
|
||||
codes=$(echo "${codes}" | sed -r "/My$2$(expr ${user_num} - 1)=/a\My$2${user_num}=''")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
## 导出为他人助力变量(ForOther)
|
||||
if [[ ${codes} ]]; then
|
||||
help_code=""
|
||||
for ((user_num=1;user_num<=${UserSum};user_num++)); do
|
||||
echo -e "${codes}" | grep -${Opt}q "My$2${user_num}=''"
|
||||
if [ $? -eq 1 ]; then
|
||||
help_code=${help_code}"\${My"$2${user_num}"}@"
|
||||
fi
|
||||
done
|
||||
## 生成互助规则模板
|
||||
for_other_codes=""
|
||||
case $HelpType in
|
||||
0) ### 统一优先级助力模板
|
||||
new_code=$(echo ${help_code} | sed "s/@$//")
|
||||
for ((user_num=1;user_num<=${UserSum};user_num++)); do
|
||||
if [ $user_num == 1 ]; then
|
||||
for_other_codes=${for_other_codes}"ForOther"$2${user_num}"=\""${new_code}"\"\n"
|
||||
else
|
||||
for_other_codes=${for_other_codes}"ForOther"$2${user_num}"=\"\${ForOther"${2}1"}\"\n"
|
||||
fi
|
||||
done
|
||||
;;
|
||||
1) ### 均匀助力模板
|
||||
for ((user_num=1;user_num<=${UserSum};user_num++)); do
|
||||
echo ${help_code} | grep "\${My"$2${user_num}"}@" > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
left_str=$(echo ${help_code} | sed "s/\${My$2${user_num}}@/ /g" | awk '{print $1}')
|
||||
right_str=$(echo ${help_code} | sed "s/\${My$2${user_num}}@/ /g" | awk '{print $2}')
|
||||
mark="\${My$2${user_num}}@"
|
||||
else
|
||||
left_str=$(echo ${help_code} | sed "s/${mark}/ /g" | awk '{print $1}')${mark}
|
||||
right_str=$(echo ${help_code} | sed "s/${mark}/ /g" | awk '{print $2}')
|
||||
fi
|
||||
new_code=$(echo ${right_str}${left_str} | sed "s/@$//")
|
||||
for_other_codes=${for_other_codes}"ForOther"$2${user_num}"=\""${new_code}"\"\n"
|
||||
done
|
||||
;;
|
||||
*) ### 普通优先级助力模板
|
||||
for ((user_num=1;user_num<=${UserSum};user_num++)); do
|
||||
new_code=$(echo ${help_code} | sed "s/\${My"$2${user_num}"}@//;s/@$//")
|
||||
for_other_codes=${for_other_codes}"ForOther"$2${user_num}"=\""${new_code}"\"\n"
|
||||
done
|
||||
;;
|
||||
esac
|
||||
echo -e "${codes}\n\n${for_other_codes}" | sed s/[[:space:]]//g
|
||||
else
|
||||
echo ${Tips}
|
||||
fi
|
||||
else
|
||||
echo "未运行过 jd_$1 脚本,未产生日志"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
## 汇总
|
||||
function Cat_All {
|
||||
echo -e "\n从最后一个日志提取互助码,受日志内容影响,仅供参考。"
|
||||
for ((i=0; i<${#Name1[*]}; i++)); do
|
||||
echo -e "\n${Name2[i]}:"
|
||||
[[ $(Cat_Scodes "${Name1[i]}" "${Name3[i]}" "的${Name2[i]}好友互助码") == ${Tips} ]] && Cat_Scodes "${Name1[i]}" "${Name3[i]}" || Cat_Scodes "${Name1[i]}" "${Name3[i]}" "的${Name2[i]}好友互助码"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
## 执行并写入日志
|
||||
LogTime=$(date "+%Y-%m-%d-%H-%M-%S")
|
||||
LogFile="${LogDir}/export_sharecodes/${LogTime}.log"
|
||||
[ ! -d "${LogDir}/export_sharecodes" ] && mkdir -p ${LogDir}/export_sharecodes
|
||||
Import_Conf && Count_UserSum && Cat_All | perl -pe "{s|京东种豆|种豆|; s|crazyJoy任务|疯狂的JOY|}" | tee ${LogFile}
|
372
git_pull.sh
Executable file
372
git_pull.sh
Executable file
|
@ -0,0 +1,372 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
## 文件路径、脚本网址、文件版本以及各种环境的判断
|
||||
ShellDir=${JD_DIR:-$(cd $(dirname $0); pwd)}
|
||||
[[ ${JD_DIR} ]] && ShellJd=jd || ShellJd=${ShellDir}/jd.sh
|
||||
LogDir=${ShellDir}/log
|
||||
[ ! -d ${LogDir} ] && mkdir -p ${LogDir}
|
||||
ScriptsDir=${ShellDir}/scripts
|
||||
Scripts2Dir=${ShellDir}/scripts2
|
||||
ConfigDir=${ShellDir}/config
|
||||
FileConf=${ConfigDir}/config.sh
|
||||
FileDiy=${ConfigDir}/diy.sh
|
||||
FileConfSample=${ShellDir}/sample/config.sh.sample
|
||||
ListCron=${ConfigDir}/crontab.list
|
||||
ListCronLxk=${ScriptsDir}/docker/crontab_list.sh
|
||||
ListCronShylocks=${Scripts2Dir}/docker/crontab_list.sh
|
||||
ListTask=${LogDir}/task.list
|
||||
ListJs=${LogDir}/js.list
|
||||
ListJsAdd=${LogDir}/js-add.list
|
||||
ListJsDrop=${LogDir}/js-drop.list
|
||||
ContentVersion=${ShellDir}/version
|
||||
ContentNewTask=${ShellDir}/new_task
|
||||
ContentDropTask=${ShellDir}/drop_task
|
||||
SendCount=${ShellDir}/send_count
|
||||
isTermux=${ANDROID_RUNTIME_ROOT}${ANDROID_ROOT}
|
||||
ShellURL=${JD_SHELL_URL:-git@gitee.com:evine/jd_shell.git}
|
||||
ScriptsURL=${JD_SCRIPTS_URL:-git@gitee.com:lxk0301/jd_scripts.git}
|
||||
|
||||
## 导入配置文件
|
||||
function Import_Conf {
|
||||
if [ -f ${FileConf} ]; then
|
||||
. ${FileConf}
|
||||
fi
|
||||
}
|
||||
|
||||
## 更新crontab,gitee服务器同一时间限制5个链接,因此每个人更新代码必须错开时间,每次执行git_pull随机生成。
|
||||
## 每天次数随机,更新时间随机,更新秒数随机,至少6次,至多12次,大部分为8-10次,符合正态分布。
|
||||
function Update_Cron {
|
||||
if [[ $(date "+%-H") -le 2 ]] && [ -f ${ListCron} ]; then
|
||||
RanMin=$((${RANDOM} % 60))
|
||||
RanSleep=$((${RANDOM} % 56))
|
||||
RanHourArray[0]=$((${RANDOM} % 3))
|
||||
for ((i=1; i<14; i++)); do
|
||||
j=$(($i - 1))
|
||||
tmp=$((${RANDOM} % 3 + ${RanHourArray[j]} + 2))
|
||||
[[ ${tmp} -lt 24 ]] && RanHourArray[i]=${tmp} || break
|
||||
done
|
||||
RanHour=${RanHourArray[0]}
|
||||
for ((i=1; i<${#RanHourArray[*]}; i++)); do
|
||||
RanHour="${RanHour},${RanHourArray[i]}"
|
||||
done
|
||||
perl -i -pe "s|.+(bash.+git_pull.+log.*)|${RanMin} ${RanHour} \* \* \* sleep ${RanSleep} && \1|" ${ListCron}
|
||||
crontab ${ListCron}
|
||||
fi
|
||||
}
|
||||
|
||||
## 重置仓库remote url
|
||||
function Reset_RepoUrl {
|
||||
if [[ ${JD_DIR} ]] && [[ ${ENABLE_RESET_REPO_URL} == true ]]; then
|
||||
if [ -d ${ShellDir}/.git ]; then
|
||||
cd ${ShellDir}
|
||||
git remote set-url origin ${ShellURL}
|
||||
git reset --hard
|
||||
fi
|
||||
if [ -d ${ScriptsDir}/.git ]; then
|
||||
cd ${ScriptsDir}
|
||||
git remote set-url origin ${ScriptsURL}
|
||||
git reset --hard
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
## 更新shell
|
||||
function Git_PullShell {
|
||||
echo -e "更新shell...\n"
|
||||
cd ${ShellDir}
|
||||
git fetch --all
|
||||
ExitStatusShell=$?
|
||||
git reset --hard origin/master
|
||||
echo
|
||||
}
|
||||
|
||||
## 更新shell成功后的操作
|
||||
function Git_PullShellNext {
|
||||
if [[ ${ExitStatusShell} -eq 0 ]]; then
|
||||
echo -e "更新shell成功...\n"
|
||||
Update_Entrypoint
|
||||
[[ "${PanelDependOld}" != "${PanelDependNew}" ]] && cd ${ShellDir}/panel && Npm_Install panel
|
||||
cp -f ${FileConfSample} ${ConfigDir}/config.sh.sample
|
||||
[ -d ${ScriptsDir}/node_modules ] && Notify_Version
|
||||
else
|
||||
echo -e "更新shell失败,请检查原因...\n"
|
||||
fi
|
||||
}
|
||||
|
||||
## 克隆scripts
|
||||
function Git_CloneScripts {
|
||||
echo -e "克隆scripts...\n"
|
||||
git clone -b master ${ScriptsURL} ${ScriptsDir}
|
||||
ExitStatusScripts=$?
|
||||
echo
|
||||
}
|
||||
|
||||
## 更新scripts
|
||||
function Git_PullScripts {
|
||||
echo -e "更新scripts...\n"
|
||||
cd ${ScriptsDir}
|
||||
git fetch --all
|
||||
ExitStatusScripts=$?
|
||||
git reset --hard origin/master
|
||||
echo
|
||||
}
|
||||
|
||||
## 更新docker-entrypoint
|
||||
function Update_Entrypoint {
|
||||
if [[ ${JD_DIR} ]] && [[ $(cat ${ShellDir}/docker/docker-entrypoint.sh) != $(cat /usr/local/bin/docker-entrypoint.sh) ]]; then
|
||||
cp -f ${ShellDir}/docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||
chmod 777 /usr/local/bin/docker-entrypoint.sh
|
||||
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中的所有任务清单,仅保留脚本名
|
||||
## js.list 上述检测文件中用来运行js脚本的清单(去掉后缀.js,非运行脚本的不会包括在内)
|
||||
## js-add.list 如果上述检测文件增加了定时任务,这个文件内容将不为空
|
||||
## js-drop.list 如果上述检测文件删除了定时任务,这个文件内容将不为空
|
||||
function Diff_Cron {
|
||||
if [ -f ${ListCron} ]; then
|
||||
if [ -n "${JD_DIR}" ]
|
||||
then
|
||||
grep -E " j[drx]_\w+" ${ListCron} | perl -pe "s|.+ (j[drx]_\w+).*|\1|" | sort -u > ${ListTask}
|
||||
else
|
||||
grep "${ShellDir}/" ${ListCron} | grep -E " j[drx]_\w+" | perl -pe "s|.+ (j[drx]_\w+).*|\1|" | sort -u > ${ListTask}
|
||||
fi
|
||||
cat ${ListCronLxk} | grep -E "j[drx]_\w+\.js" | perl -pe "s|.+(j[drx]_\w+)\.js.+|\1|" | sort -u > ${ListJs}
|
||||
grep -vwf ${ListTask} ${ListJs} > ${ListJsAdd}
|
||||
grep -vwf ${ListJs} ${ListTask} > ${ListJsDrop}
|
||||
else
|
||||
echo -e "${ListCron} 文件不存在,请先定义你自己的crontab.list...\n"
|
||||
fi
|
||||
}
|
||||
|
||||
## 发送删除失效定时任务的消息
|
||||
function Notify_DropTask {
|
||||
cd ${ShellDir}
|
||||
node update.js
|
||||
[ -f ${ContentDropTask} ] && rm -f ${ContentDropTask}
|
||||
}
|
||||
|
||||
## 发送新的定时任务消息
|
||||
function Notify_NewTask {
|
||||
cd ${ShellDir}
|
||||
node update.js
|
||||
[ -f ${ContentNewTask} ] && rm -f ${ContentNewTask}
|
||||
}
|
||||
|
||||
## 检测配置文件版本
|
||||
function Notify_Version {
|
||||
## 识别出两个文件的版本号
|
||||
VerConfSample=$(grep " Version: " ${FileConfSample} | perl -pe "s|.+v((\d+\.?){3})|\1|")
|
||||
[ -f ${FileConf} ] && VerConf=$(grep " Version: " ${FileConf} | perl -pe "s|.+v((\d+\.?){3})|\1|")
|
||||
|
||||
## 删除旧的发送记录文件
|
||||
[ -f "${SendCount}" ] && [[ $(cat ${SendCount}) != ${VerConfSample} ]] && rm -f ${SendCount}
|
||||
|
||||
## 识别出更新日期和更新内容
|
||||
UpdateDate=$(grep " Date: " ${FileConfSample} | awk -F ": " '{print $2}')
|
||||
UpdateContent=$(grep " Update Content: " ${FileConfSample} | awk -F ": " '{print $2}')
|
||||
|
||||
## 如果是今天,并且版本号不一致,则发送通知
|
||||
if [ -f ${FileConf} ] && [[ "${VerConf}" != "${VerConfSample}" ]] && [[ ${UpdateDate} == $(date "+%Y-%m-%d") ]]
|
||||
then
|
||||
if [ ! -f ${SendCount} ]; then
|
||||
echo -e "检测到配置文件config.sh.sample有更新\n\n更新日期: ${UpdateDate}\n当前版本: ${VerConf}\n新的版本: ${VerConfSample}\n更新内容: ${UpdateContent}\n更新说明: 如需使用新功能请对照config.sh.sample,将相关新参数手动增加到你自己的config.sh中,否则请无视本消息。本消息只在该新版本配置文件更新当天发送一次。" | tee ${ContentVersion}
|
||||
cd ${ShellDir}
|
||||
node update.js
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "${VerConfSample}" > ${SendCount}
|
||||
[ -f ${ContentVersion} ] && rm -f ${ContentVersion}
|
||||
fi
|
||||
fi
|
||||
else
|
||||
[ -f ${ContentVersion} ] && rm -f ${ContentVersion}
|
||||
[ -f ${SendCount} ] && rm -f ${SendCount}
|
||||
fi
|
||||
}
|
||||
|
||||
## npm install 子程序,判断是否为安卓,判断是否安装有yarn
|
||||
function Npm_InstallSub {
|
||||
if [ -n "${isTermux}" ]
|
||||
then
|
||||
npm install --no-bin-links || npm install --no-bin-links --registry=https://registry.npm.taobao.org
|
||||
elif ! type yarn >/dev/null 2>&1
|
||||
then
|
||||
npm install || npm install --registry=https://registry.npm.taobao.org
|
||||
else
|
||||
echo -e "检测到本机安装了 yarn,使用 yarn 替代 npm...\n"
|
||||
yarn install || yarn install --registry=https://registry.npm.taobao.org
|
||||
fi
|
||||
}
|
||||
|
||||
## npm install
|
||||
function Npm_Install {
|
||||
echo -e "检测到 $1 的依赖包有变化,运行 npm install...\n"
|
||||
Npm_InstallSub
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "\nnpm install 运行不成功,自动删除 $1/node_modules 后再次尝试一遍..."
|
||||
rm -rf node_modules
|
||||
fi
|
||||
echo
|
||||
|
||||
if [ ! -d node_modules ]; then
|
||||
echo -e "运行 npm install...\n"
|
||||
Npm_InstallSub
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "\nnpm install 运行不成功,自动删除 $1/node_modules...\n"
|
||||
echo -e "请进入 $1 目录后手动运行 npm install...\n"
|
||||
echo -e "3...\n"
|
||||
sleep 1
|
||||
echo -e "2...\n"
|
||||
sleep 1
|
||||
echo -e "1...\n"
|
||||
sleep 1
|
||||
rm -rf node_modules
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
## 输出是否有新的定时任务
|
||||
function Output_ListJsAdd {
|
||||
if [ -s ${ListJsAdd} ]; then
|
||||
echo -e "检测到有新的定时任务:\n"
|
||||
cat ${ListJsAdd}
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
## 输出是否有失效的定时任务
|
||||
function Output_ListJsDrop {
|
||||
if [ ${ExitStatusScripts} -eq 0 ] && [ -s ${ListJsDrop} ]; then
|
||||
echo -e "检测到有失效的定时任务:\n"
|
||||
cat ${ListJsDrop}
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
## 自动删除失效的脚本与定时任务,需要5个条件:1.AutoDelCron 设置为 true;2.正常更新js脚本,没有报错;3.js-drop.list不为空;4.crontab.list存在并且不为空;5.已经正常运行过npm install
|
||||
## 检测文件:LXK9301/jd_scripts 仓库中的 docker/crontab_list.sh
|
||||
## 如果检测到某个定时任务在上述检测文件中已删除,那么在本地也删除对应定时任务
|
||||
function Del_Cron {
|
||||
if [ "${AutoDelCron}" = "true" ] && [ -s ${ListJsDrop} ] && [ -s ${ListCron} ] && [ -d ${ScriptsDir}/node_modules ]; then
|
||||
echo -e "开始尝试自动删除定时任务如下:\n"
|
||||
cat ${ListJsDrop}
|
||||
echo
|
||||
JsDrop=$(cat ${ListJsDrop})
|
||||
for Cron in ${JsDrop}
|
||||
do
|
||||
perl -i -ne "{print unless / ${Cron}( |$)/}" ${ListCron}
|
||||
done
|
||||
crontab ${ListCron}
|
||||
echo -e "成功删除失效的脚本与定时任务,当前的定时任务清单如下:\n\n--------------------------------------------------------------\n"
|
||||
crontab -l
|
||||
echo -e "\n--------------------------------------------------------------\n"
|
||||
if [ -d ${ScriptsDir}/node_modules ]; then
|
||||
echo -e "删除失效的定时任务:\n\n${JsDrop}" > ${ContentDropTask}
|
||||
Notify_DropTask
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
## 自动增加新的定时任务,需要5个条件:1.AutoAddCron 设置为 true;2.正常更新js脚本,没有报错;3.js-add.list不为空;4.crontab.list存在并且不为空;5.已经正常运行过npm install
|
||||
## 检测文件:LXK9301/jd_scripts 仓库中的 docker/crontab_list.sh
|
||||
## 如果检测到检测文件中增加新的定时任务,那么在本地也增加
|
||||
## 本功能生效时,会自动从检测文件新增加的任务中读取时间,该时间为北京时间
|
||||
function Add_Cron {
|
||||
if [ "${AutoAddCron}" = "true" ] && [ -s ${ListJsAdd} ] && [ -s ${ListCron} ] && [ -d ${ScriptsDir}/node_modules ]; then
|
||||
echo -e "开始尝试自动添加定时任务如下:\n"
|
||||
cat ${ListJsAdd}
|
||||
echo
|
||||
JsAdd=$(cat ${ListJsAdd})
|
||||
|
||||
for Cron in ${JsAdd}
|
||||
do
|
||||
if [[ ${Cron} == jd_bean_sign ]]
|
||||
then
|
||||
echo "4 0,9 * * * bash ${ShellJd} ${Cron}" >> ${ListCron}
|
||||
else
|
||||
cat ${ListCronLxk} | grep -E "\/${Cron}\." | perl -pe "s|(^.+)node */scripts/(j[drx]_\w+)\.js.+|\1bash ${ShellJd} \2|" >> ${ListCron}
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
crontab ${ListCron}
|
||||
echo -e "成功添加新的定时任务,当前的定时任务清单如下:\n\n--------------------------------------------------------------\n"
|
||||
crontab -l
|
||||
echo -e "\n--------------------------------------------------------------\n"
|
||||
if [ -d ${ScriptsDir}/node_modules ]; then
|
||||
echo -e "成功添加新的定时任务:\n\n${JsAdd}" > ${ContentNewTask}
|
||||
Notify_NewTask
|
||||
fi
|
||||
else
|
||||
echo -e "添加新的定时任务出错,请手动添加...\n"
|
||||
if [ -d ${ScriptsDir}/node_modules ]; then
|
||||
echo -e "尝试自动添加以下新的定时任务出错,请手动添加:\n\n${JsAdd}" > ${ContentNewTask}
|
||||
Notify_NewTask
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
## 在日志中记录时间与路径
|
||||
echo -e "\n--------------------------------------------------------------\n"
|
||||
echo -n "系统时间:"
|
||||
echo $(date "+%Y-%m-%d %H:%M:%S")
|
||||
if [ "${TZ}" = "UTC" ]; then
|
||||
echo
|
||||
echo -n "北京时间:"
|
||||
echo $(date -d "8 hour" "+%Y-%m-%d %H:%M:%S")
|
||||
fi
|
||||
echo -e "\nJS脚本目录:${ScriptsDir}\n"
|
||||
echo -e "--------------------------------------------------------------\n"
|
||||
|
||||
## 导入配置,更新cron,设置url,更新shell,复制sample,复制entrypoint,发送新配置通知
|
||||
Import_Conf "git_pull"
|
||||
Update_Cron
|
||||
Reset_RepoUrl
|
||||
[ -f ${ShellDir}/panel/package.json ] && PanelDependOld=$(cat ${ShellDir}/panel/package.json)
|
||||
Git_PullShell
|
||||
[ -f ${ShellDir}/panel/package.json ] && PanelDependNew=$(cat ${ShellDir}/panel/package.json)
|
||||
Git_PullShellNext
|
||||
|
||||
## 克隆或更新js脚本
|
||||
[ -f ${ScriptsDir}/package.json ] && ScriptsDependOld=$(cat ${ScriptsDir}/package.json)
|
||||
[ -d ${ScriptsDir}/.git ] && Git_PullScripts || Git_CloneScripts
|
||||
[ -f ${ScriptsDir}/package.json ] && ScriptsDependNew=$(cat ${ScriptsDir}/package.json)
|
||||
|
||||
## 执行各函数
|
||||
if [[ ${ExitStatusScripts} -eq 0 ]]
|
||||
then
|
||||
echo -e "更新scripts成功...\n"
|
||||
Diff_Cron
|
||||
[[ "${ScriptsDependOld}" != "${ScriptsDependNew}" ]] && cd ${ScriptsDir} && Npm_Install scripts
|
||||
Output_ListJsAdd
|
||||
Output_ListJsDrop
|
||||
Del_Cron
|
||||
Add_Cron
|
||||
else
|
||||
echo -e "更新scripts失败,请检查原因...\n"
|
||||
fi
|
||||
|
||||
## 调用用户自定义的diy.sh
|
||||
if [[ ${EnableExtraShell} == true ]]; then
|
||||
if [ -f ${FileDiy} ]
|
||||
then
|
||||
. ${FileDiy}
|
||||
else
|
||||
echo -e "${FileDiy} 文件不存在,跳过执行DIY脚本...\n"
|
||||
fi
|
||||
fi
|
281
jd.sh
Executable file
281
jd.sh
Executable file
|
@ -0,0 +1,281 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
## 路径
|
||||
ShellDir=${JD_DIR:-$(cd $(dirname $0); pwd)}
|
||||
[[ ${JD_DIR} ]] && HelpJd=jd || HelpJd=jd.sh
|
||||
[[ ${JD_DIR} ]] && ShellJd=jd || ShellJd=${ShellDir}/jd.sh
|
||||
ScriptsDir=${ShellDir}/scripts
|
||||
ConfigDir=${ShellDir}/config
|
||||
FileConf=${ConfigDir}/config.sh
|
||||
FileConfSample=${ShellDir}/sample/config.sh.sample
|
||||
LogDir=${ShellDir}/log
|
||||
ListScripts=($(cd ${ScriptsDir}; ls *.js | grep -E "j[drx]_"))
|
||||
ListCron=${ConfigDir}/crontab.list
|
||||
ListCronLxk=${ScriptsDir}/docker/crontab_list.sh
|
||||
ListJs=${LogDir}/js.list
|
||||
|
||||
## 导入config.sh
|
||||
function Import_Conf {
|
||||
if [ -f ${FileConf} ]
|
||||
then
|
||||
. ${FileConf}
|
||||
if [ -z "${Cookie1}" ]; then
|
||||
echo -e "请先在config.sh中配置好Cookie...\n"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo -e "配置文件 ${FileConf} 不存在,请先按教程配置好该文件...\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
## 更新crontab
|
||||
function Detect_Cron {
|
||||
if [[ $(cat ${ListCron}) != $(crontab -l) ]]; then
|
||||
crontab ${ListCron}
|
||||
fi
|
||||
}
|
||||
|
||||
## 用户数量UserSum
|
||||
function Count_UserSum {
|
||||
for ((i=1; i<=1000; i++)); do
|
||||
Tmp=Cookie$i
|
||||
CookieTmp=${!Tmp}
|
||||
[[ ${CookieTmp} ]] && UserSum=$i || break
|
||||
done
|
||||
}
|
||||
|
||||
## 组合Cookie和互助码子程序
|
||||
function Combin_Sub {
|
||||
CombinAll=""
|
||||
if [[ ${AutoHelpOther} == true ]] && [[ $1 == ForOther* ]]; then
|
||||
|
||||
ForOtherAll=""
|
||||
MyName=$(echo $1 | perl -pe "s|ForOther|My|")
|
||||
|
||||
for ((m=1; m<=${UserSum}; m++)); do
|
||||
TmpA=${MyName}$m
|
||||
TmpB=${!TmpA}
|
||||
ForOtherAll="${ForOtherAll}@${TmpB}"
|
||||
done
|
||||
|
||||
for ((n=1; n<=${UserSum}; n++)); do
|
||||
for num in ${TempBlockCookie}; do
|
||||
[[ $n -eq $num ]] && continue 2
|
||||
done
|
||||
CombinAll="${CombinAll}&${ForOtherAll}"
|
||||
done
|
||||
|
||||
else
|
||||
for ((i=1; i<=${UserSum}; i++)); do
|
||||
for num in ${TempBlockCookie}; do
|
||||
[[ $i -eq $num ]] && continue 2
|
||||
done
|
||||
Tmp1=$1$i
|
||||
Tmp2=${!Tmp1}
|
||||
CombinAll="${CombinAll}&${Tmp2}"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ${CombinAll} | perl -pe "{s|^&||; s|^@+||; s|&@|&|g; s|@+&|&|g; s|@+|@|g; s|@+$||}"
|
||||
}
|
||||
|
||||
## 组合Cookie、Token与互助码
|
||||
function Combin_All {
|
||||
export JD_COOKIE=$(Combin_Sub Cookie)
|
||||
export FRUITSHARECODES=$(Combin_Sub ForOtherFruit)
|
||||
export PETSHARECODES=$(Combin_Sub ForOtherPet)
|
||||
export PLANT_BEAN_SHARECODES=$(Combin_Sub ForOtherBean)
|
||||
export DREAM_FACTORY_SHARE_CODES=$(Combin_Sub ForOtherDreamFactory)
|
||||
export DDFACTORY_SHARECODES=$(Combin_Sub ForOtherJdFactory)
|
||||
export JDZZ_SHARECODES=$(Combin_Sub ForOtherJdzz)
|
||||
export JDJOY_SHARECODES=$(Combin_Sub ForOtherJoy)
|
||||
export JXNC_SHARECODES=$(Combin_Sub ForOtherJxnc)
|
||||
export JXNCTOKENS=$(Combin_Sub TokenJxnc)
|
||||
export BOOKSHOP_SHARECODES=$(Combin_Sub ForOtherBookShop)
|
||||
export JD_CASH_SHARECODES=$(Combin_Sub ForOtherCash)
|
||||
export JDSGMH_SHARECODES=$(Combin_Sub ForOtherSgmh)
|
||||
export JDCFD_SHARECODES=$(Combin_Sub ForOtherCfd)
|
||||
export JDGLOBAL_SHARECODES=$(Combin_Sub ForOtherGlobal)
|
||||
}
|
||||
|
||||
## 转换JD_BEAN_SIGN_STOP_NOTIFY或JD_BEAN_SIGN_NOTIFY_SIMPLE
|
||||
function Trans_JD_BEAN_SIGN_NOTIFY {
|
||||
case ${NotifyBeanSign} in
|
||||
0)
|
||||
export JD_BEAN_SIGN_STOP_NOTIFY="true"
|
||||
;;
|
||||
1)
|
||||
export JD_BEAN_SIGN_NOTIFY_SIMPLE="true"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
## 转换UN_SUBSCRIBES
|
||||
function Trans_UN_SUBSCRIBES {
|
||||
export UN_SUBSCRIBES="${goodPageSize}\n${shopPageSize}\n${jdUnsubscribeStopGoods}\n${jdUnsubscribeStopShop}"
|
||||
}
|
||||
|
||||
## 申明全部变量
|
||||
function Set_Env {
|
||||
Count_UserSum
|
||||
Combin_All
|
||||
Trans_JD_BEAN_SIGN_NOTIFY
|
||||
Trans_UN_SUBSCRIBES
|
||||
}
|
||||
|
||||
## 随机延迟
|
||||
function Random_Delay {
|
||||
if [[ -n ${RandomDelay} ]] && [[ ${RandomDelay} -gt 0 ]]; then
|
||||
CurMin=$(date "+%-M")
|
||||
if [[ ${CurMin} -gt 2 && ${CurMin} -lt 30 ]] || [[ ${CurMin} -gt 31 && ${CurMin} -lt 59 ]]; then
|
||||
CurDelay=$((${RANDOM} % ${RandomDelay} + 1))
|
||||
echo -e "\n命令未添加 \"now\",随机延迟 ${CurDelay} 秒后再执行任务,如需立即终止,请按 CTRL+C...\n"
|
||||
sleep ${CurDelay}
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
## 使用说明
|
||||
function Help {
|
||||
echo -e "本脚本的用法为:"
|
||||
echo -e "1. bash ${HelpJd} xxx # 如果设置了随机延迟并且当时时间不在0-2、30-31、59分内,将随机延迟一定秒数"
|
||||
echo -e "2. bash ${HelpJd} xxx now # 无论是否设置了随机延迟,均立即运行"
|
||||
echo -e "3. bash ${HelpJd} runall # 运行所有非挂机脚本,非常耗时"
|
||||
echo -e "4. bash ${HelpJd} hangup # 重启挂机程序"
|
||||
echo -e "5. bash ${HelpJd} resetpwd # 重置控制面板用户名和密码"
|
||||
echo -e "\n针对用法1、用法2中的\"xxx\",可以不输入后缀\".js\",另外,如果前缀是\"jd_\"的话前缀也可以省略。"
|
||||
echo -e "当前有以下脚本可以运行(仅列出以jd_、jr_、jx_开头的脚本):"
|
||||
cd ${ScriptsDir}
|
||||
for ((i=0; i<${#ListScripts[*]}; i++)); do
|
||||
Name=$(grep "new Env" ${ListScripts[i]} | awk -F "'|\"" '{print $2}')
|
||||
echo -e "$(($i + 1)).${Name}:${ListScripts[i]}"
|
||||
done
|
||||
}
|
||||
|
||||
## nohup
|
||||
function Run_Nohup {
|
||||
if [[ $(ps -ef | grep "${js}" | grep -v "grep") != "" ]]; then
|
||||
ps -ef | grep "${js}" | grep -v "grep" | awk '{print $2}' | xargs kill -9
|
||||
fi
|
||||
[ ! -d ${LogDir}/${js} ] && mkdir -p ${LogDir}/${js}
|
||||
LogTime=$(date "+%Y-%m-%d-%H-%M-%S")
|
||||
LogFile="${LogDir}/${js}/${LogTime}.log"
|
||||
nohup node ${js}.js > ${LogFile} &
|
||||
}
|
||||
|
||||
## 运行挂机脚本
|
||||
function Run_HangUp {
|
||||
HangUpJs="jd_crazy_joy_coin"
|
||||
cd ${ScriptsDir}
|
||||
for js in ${HangUpJs}; do
|
||||
Import_Conf ${js} && Set_Env
|
||||
if type pm2 >/dev/null 2>&1; then
|
||||
pm2 stop ${js}.js 2>/dev/null
|
||||
pm2 flush
|
||||
pm2 start -a ${js}.js --watch "${ScriptsDir}/${js}.js" --name="${js}"
|
||||
else
|
||||
Run_Nohup >/dev/null 2>&1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
## 重置密码
|
||||
function Reset_Pwd {
|
||||
cp -f ${ShellDir}/sample/auth.json ${ConfigDir}/auth.json
|
||||
echo -e "控制面板重置成功,用户名:admin,密码:adminadmin\n"
|
||||
}
|
||||
|
||||
## 一次性运行所有脚本
|
||||
function Run_All {
|
||||
if [ ! -f ${ListJs} ]; then
|
||||
cat ${ListCronLxk} | grep -E "j[drx]_\w+\.js" | perl -pe "s|.+(j[drx]_\w+)\.js.+|\1|" | sort -u > ${ListJs}
|
||||
fi
|
||||
echo -e "\n==================== 开始运行所有非挂机脚本 ====================\n"
|
||||
echo -e "请注意:本过程将非常非常耗时,一个账号可能长达几小时,账号越多耗时越长,如果是手动运行,退出终端也将终止运行。\n"
|
||||
echo -e "倒计时5秒...\n"
|
||||
for ((sec=5; sec>0; sec--)); do
|
||||
echo -e "$sec...\n"
|
||||
sleep 1
|
||||
done
|
||||
for file in $(cat ${ListJs}); do
|
||||
echo -e "==================== 运行 $file.js 脚本 ====================\n"
|
||||
bash ${ShellJd} $file now
|
||||
done
|
||||
}
|
||||
|
||||
## 正常运行单个脚本
|
||||
function Run_Normal {
|
||||
Import_Conf $1 && Detect_Cron && Set_Env
|
||||
|
||||
FileNameTmp1=$(echo $1 | perl -pe "s|\.js||")
|
||||
FileNameTmp2=$(echo $1 | perl -pe "{s|jd_||; s|\.js||; s|^|jd_|}")
|
||||
SeekDir="${ScriptsDir} ${ScriptsDir}/backUp ${ConfigDir}"
|
||||
FileName=""
|
||||
WhichDir=""
|
||||
|
||||
for dir in ${SeekDir}
|
||||
do
|
||||
if [ -f ${dir}/${FileNameTmp1}.js ]; then
|
||||
FileName=${FileNameTmp1}
|
||||
WhichDir=${dir}
|
||||
break
|
||||
elif [ -f ${dir}/${FileNameTmp2}.js ]; then
|
||||
FileName=${FileNameTmp2}
|
||||
WhichDir=${dir}
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "${FileName}" ] && [ -n "${WhichDir}" ]
|
||||
then
|
||||
[ $# -eq 1 ] && Random_Delay
|
||||
LogTime=$(date "+%Y-%m-%d-%H-%M-%S")
|
||||
LogFile="${LogDir}/${FileName}/${LogTime}.log"
|
||||
[ ! -d ${LogDir}/${FileName} ] && mkdir -p ${LogDir}/${FileName}
|
||||
cd ${WhichDir}
|
||||
node ${FileName}.js 2>&1 | tee ${LogFile}
|
||||
else
|
||||
echo -e "\n在${ScriptsDir}、${ScriptsDir}/backUp、${ConfigDir}三个目录下均未检测到 $1 脚本的存在,请确认...\n"
|
||||
Help
|
||||
fi
|
||||
}
|
||||
|
||||
## 命令检测
|
||||
case $# in
|
||||
0)
|
||||
echo
|
||||
Help
|
||||
;;
|
||||
1)
|
||||
case $1 in
|
||||
hangup)
|
||||
Run_HangUp
|
||||
;;
|
||||
resetpwd)
|
||||
Reset_Pwd
|
||||
;;
|
||||
runall)
|
||||
Run_All
|
||||
;;
|
||||
*)
|
||||
Run_Normal $1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
2)
|
||||
case $2 in
|
||||
now)
|
||||
Run_Normal $1 $2
|
||||
;;
|
||||
*)
|
||||
echo -e "\n命令输入错误...\n"
|
||||
Help
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo -e "\n命令过多...\n"
|
||||
Help
|
||||
;;
|
||||
esac
|
44
package.json
Normal file
44
package.json
Normal file
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "umi dev",
|
||||
"build": "umi build",
|
||||
"postinstall": "umi generate tmp",
|
||||
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
|
||||
"test": "umi-test",
|
||||
"test:coverage": "umi-test --coverage"
|
||||
},
|
||||
"gitHooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,less,md,json}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"*.ts?(x)": [
|
||||
"prettier --parser=typescript --write"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/pro-layout": "^6.5.0",
|
||||
"@umijs/preset-react": "1.x",
|
||||
"codemirror": "^5.59.4",
|
||||
"qrcode.react": "^1.0.1",
|
||||
"react-codemirror2": "^7.2.1",
|
||||
"react-diff-viewer": "^3.1.1",
|
||||
"umi": "^3.3.9",
|
||||
"umi-request": "^1.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/qrcode.react": "^1.0.1",
|
||||
"@types/react": "^17.0.0",
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"@umijs/test": "^3.3.9",
|
||||
"lint-staged": "^10.0.7",
|
||||
"prettier": "^2.2.0",
|
||||
"react": "17.x",
|
||||
"react-dom": "17.x",
|
||||
"typescript": "^4.1.2",
|
||||
"yorkie": "^2.0.0"
|
||||
}
|
||||
}
|
57
rm_log.sh
Executable file
57
rm_log.sh
Executable file
|
@ -0,0 +1,57 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
## 判断环境
|
||||
ShellDir=${JD_DIR:-$(cd $(dirname $0); pwd)}
|
||||
LogDir=${ShellDir}/log
|
||||
|
||||
## 导入配置文件
|
||||
. ${ShellDir}/config/config.sh
|
||||
|
||||
## 删除运行js脚本的旧日志
|
||||
function Rm_JsLog {
|
||||
LogFileList=$(ls -l ${LogDir}/*/*.log | awk '{print $9}')
|
||||
for log in ${LogFileList}
|
||||
do
|
||||
LogDate=$(echo ${log} | awk -F "/" '{print $NF}' | cut -c1-10) #文件名比文件属性获得的日期要可靠
|
||||
if [[ $(uname -s) == Darwin ]]
|
||||
then
|
||||
DiffTime=$(($(date +%s) - $(date -j -f "%Y-%m-%d" "${LogDate}" +%s)))
|
||||
else
|
||||
DiffTime=$(($(date +%s) - $(date +%s -d "${LogDate}")))
|
||||
fi
|
||||
[ ${DiffTime} -gt $((${RmLogDaysAgo} * 86400)) ] && rm -vf ${log}
|
||||
done
|
||||
}
|
||||
|
||||
## 删除git_pull.sh的运行日志
|
||||
function Rm_GitPullLog {
|
||||
if [[ $(uname -s) == Darwin ]]
|
||||
then
|
||||
DateDelLog=$(date -v-${RmLogDaysAgo}d "+%Y-%m-%d")
|
||||
else
|
||||
Stmp=$(($(date "+%s") - 86400 * ${RmLogDaysAgo}))
|
||||
DateDelLog=$(date -d "@${Stmp}" "+%Y-%m-%d")
|
||||
fi
|
||||
LineEndGitPull=$[$(cat ${LogDir}/git_pull.log | grep -n "${DateDelLog} " | head -1 | awk -F ":" '{print $1}') - 3]
|
||||
[ ${LineEndGitPull} -gt 0 ] && perl -i -ne "{print unless 1 .. ${LineEndGitPull} }" ${LogDir}/git_pull.log
|
||||
}
|
||||
|
||||
## 删除空文件夹
|
||||
function Rm_EmptyDir {
|
||||
cd ${LogDir}
|
||||
for dir in $(ls)
|
||||
do
|
||||
if [ -d ${dir} ] && [[ $(ls ${dir}) == "" ]]; then
|
||||
rm -rf ${dir}
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
## 运行
|
||||
if [ -n "${RmLogDaysAgo}" ]; then
|
||||
echo -e "查找旧日志文件中...\n"
|
||||
Rm_JsLog
|
||||
Rm_GitPullLog
|
||||
Rm_EmptyDir
|
||||
echo -e "删除旧日志执行完毕\n"
|
||||
fi
|
1
sample/auth.json
Executable file
1
sample/auth.json
Executable file
|
@ -0,0 +1 @@
|
|||
{"user":"admin","password":"adminadmin"}
|
636
sample/config.sh.sample
Executable file
636
sample/config.sh.sample
Executable file
|
@ -0,0 +1,636 @@
|
|||
## Version: v3.32.1
|
||||
## Date: 2021-03-14
|
||||
## Update Content: 增加三个通知控制变量DDQ_NOTIFY_CONTROL、CASH_NOTIFY_CONTROL和JDZZ_NOTIFY_CONTROL。
|
||||
|
||||
## 上面版本号中,如果第2位数字有变化,那么代表增加了新的参数,如果只有第3位数字有变化,仅代表更新了注释,没有增加新的参数,可更新可不更新
|
||||
|
||||
################################## 说明 ##################################
|
||||
## 以下配置中,带有 export 申明的,均由lxk0301大佬定义,其他互助码,考虑到直接按lxk0301大佬定义的变量去填的话,一是不方便记忆,二是容易搞混,所以最终的变量将由脚本去组合,你只要按注释去填即可
|
||||
## 除此之外,还额外增加了是否自动删除失效任务AutoDelCron、是否自动增加新任务AutoAddCron、删除旧日志时间RmLogDaysAgo、随机延迟启动任务RandomDelay、是否添加自定义脚本EnableExtraShell五个人性化的设置供选择
|
||||
## 所有赋值等号两边不能有空格,所有的值请一律在两侧添加半角的双引号,如果变量值中含有双引号,则外侧改为一对半角的单引号。
|
||||
## 所有的赋值都可以参考 “定义jd_pet是否静默运行” 部分,在不同时间设置不同的值,以达到你想要的效果,具体判断条件如下:
|
||||
## $(date "+%-d") 当前的日期,如:13
|
||||
## $(date "+%-w") 当前是星期几,如:3
|
||||
## $(date "+%-H") 当前的小时数,如:23
|
||||
## $(date "+%-M") 当前的分钟数,如:49
|
||||
## 其他date命令的更多用法,可以在命令行中输入 date --help 查看
|
||||
## 判断条件 -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个月有效期
|
||||
## 必须按数字顺序1、2、3、4...依次编号下去,例子只有6个,超出6个你继续往下编号即可
|
||||
## 不允许有汉字,如果ID有汉字,请在PC浏览器上获取Cookie,会自动将汉字转换为URL编码
|
||||
Cookie1=""
|
||||
Cookie2=""
|
||||
Cookie3=""
|
||||
Cookie4=""
|
||||
Cookie5=""
|
||||
Cookie6=""
|
||||
|
||||
|
||||
################################## 临时屏蔽某个Cookie(选填) ##################################
|
||||
## 如果某些Cookie已经失效了,但暂时还没法更新,可以使用此功能在不删除该Cookie和重新修改Cookie编号的前提下,临时屏蔽掉某些编号的Cookie
|
||||
## 多个Cookie编号以半角的空格分隔,两侧一对半角双引号,使用此功能后,在运行js脚本时账号编号将发生变化
|
||||
## 举例1:TempBlockCookie="2" 临时屏蔽掉Cookie2
|
||||
## 举例2:TempBlockCookie="2 4" 临时屏蔽掉Cookie2和Cookie4
|
||||
## 如果只是想要屏蔽某个账号不玩某些小游戏,可以参考下面 case 这个命令的例子来控制,脚本名称请去掉后缀 “.js”
|
||||
## case $1 in
|
||||
## jd_fruit)
|
||||
## TempBlockCookie="5" # 账号5不玩jd_fruit
|
||||
## ;;
|
||||
## jd_dreamFactory | jd_jdfactory)
|
||||
## TempBlockCookie="2" # 账号2不玩jd_dreamFactory和jd_jdfactory
|
||||
## ;;
|
||||
## jd_jdzz | jd_joy)
|
||||
## TempBlockCookie="3 6" # 账号3、账号6不玩jd_jdzz和jd_joy
|
||||
## ;;
|
||||
## esac
|
||||
TempBlockCookie=""
|
||||
|
||||
|
||||
################################## 定义是否自动删除失效的脚本与定时任务(选填) ##################################
|
||||
## 有的时候,某些JS脚本只在特定的时间有效,过了时间就失效了,需要自动删除失效的本地定时任务,则设置为 "true" ,否则请设置为 "false"
|
||||
## 检测文件:lxk0301/jd_scripts 仓库中的 docker/crontab_list.sh
|
||||
## 当设置为 "true" 时,会自动从检测文件中读取比对删除的任务(识别以“jd_”、“jr_”、“jx_”开头的任务)
|
||||
## 当设置为 "true" 时,脚本只会删除一整行失效的定时任务,不会修改其他现有任务,所以任何时候,你都可以自己调整你的crontab.list
|
||||
## 当设置为 "true" 时,如果你有添加额外脚本是以“jd_”“jr_”“jx_”开头的,如检测文件中,会被删除,不是以“jd_”“jr_”“jx_”开头的任务则不受影响
|
||||
AutoDelCron="true"
|
||||
|
||||
|
||||
################################## 定义是否自动增加新的本地定时任务(选填) ##################################
|
||||
## lxk0301 大佬会在有需要的时候,增加定时任务,如需要本地自动增加新的定时任务,则设置为 "true" ,否则请设置为 "false"
|
||||
## 检测文件:lxk0301/jd_scripts 仓库中的 docker/crontab_list.sh
|
||||
## 当设置为 "true" 时,如果检测到检测文件中有增加新的定时任务,那么在本地也增加(识别以“jd_”、“jr_”、“jx_”开头的任务)
|
||||
## 当设置为 "true" 时,会自动从检测文件新增加的任务中读取时间,该时间为北京时间
|
||||
## 当设置为 "true" 时,脚本只会增加新的定时任务,不会修改其他现有任务,所以任何时候,你都可以自己调整你的crontab.list
|
||||
AutoAddCron="true"
|
||||
|
||||
|
||||
################################## 定义删除日志的时间(选填) ##################################
|
||||
## 定义在运行删除旧的日志任务时,要删除多少天以前的日志,请输入正整数,不填则禁用删除日志的功能
|
||||
RmLogDaysAgo="7"
|
||||
|
||||
|
||||
################################## 定义随机延迟启动任务(选填) ##################################
|
||||
## 如果任务不是必须准点运行的任务,那么给它增加一个随机延迟,由你定义最大延迟时间,单位为秒,如 RandomDelay="300" ,表示任务将在 1-300 秒内随机延迟一个秒数,然后再运行
|
||||
## 在crontab.list中,在每小时第0-2分、第30-31分、第59分这几个时间内启动的任务,均算作必须准点运行的任务,在启动这些任务时,即使你定义了RandomDelay,也将准点运行,不启用随机延迟
|
||||
## 在crontab.list中,除掉每小时上述时间启动的任务外,其他任务在你定义了 RandomDelay 的情况下,一律启用随机延迟,但如果你按照Wiki教程给某些任务添加了 "now",那么这些任务也将无视随机延迟直接启动
|
||||
RandomDelay="300"
|
||||
|
||||
|
||||
################################## 定义User-Agent(选填) ##################################
|
||||
## 自定义lxk0301大佬仓库里JD系列js脚本的User-Agent,不懂不知不会User-Agent的请不要随意填写内容,随意填写了出错概不负责
|
||||
## 如需使用,请自行解除下一行注释
|
||||
# export JD_USER_AGENT=""
|
||||
|
||||
|
||||
################################## 定义通知TOKEN(选填) ##################################
|
||||
## 想通过什么渠道收取通知,就填入对应渠道的值
|
||||
## 1. ServerChan,教程:http://sc.ftqq.com/3.version
|
||||
export PUSH_KEY=""
|
||||
|
||||
## 2. BARK,教程(看BARK_PUSH和BARK_SOUND的说明):https://gitee.com/lxk0301/jd_docker/blob/master/githubAction.md#%E4%B8%8B%E6%96%B9%E6%8F%90%E4%BE%9B%E4%BD%BF%E7%94%A8%E5%88%B0%E7%9A%84-secrets%E5%85%A8%E9%9B%86%E5%90%88
|
||||
export BARK_PUSH=""
|
||||
export BARK_SOUND=""
|
||||
|
||||
## 3. Telegram,如需使用,TG_BOT_TOKEN和TG_USER_ID必须同时赋值,教程:https://gitee.com/lxk0301/jd_docker/blob/master/backUp/TG_PUSH.md
|
||||
export TG_BOT_TOKEN=""
|
||||
export TG_USER_ID=""
|
||||
|
||||
## 4. 钉钉,教程(看DD_BOT_TOKEN和DD_BOT_SECRET部分):https://gitee.com/lxk0301/jd_docker/blob/master/githubAction.md#%E4%B8%8B%E6%96%B9%E6%8F%90%E4%BE%9B%E4%BD%BF%E7%94%A8%E5%88%B0%E7%9A%84-secrets%E5%85%A8%E9%9B%86%E5%90%88
|
||||
export DD_BOT_TOKEN=""
|
||||
export DD_BOT_SECRET=""
|
||||
|
||||
## 5. iGot聚合推送,支持多方式推送,填写iGot的推送key。教程:https://wahao.github.io/Bark-MP-helper/#/
|
||||
export IGOT_PUSH_KEY=""
|
||||
|
||||
## 6. Push Plus,微信扫码登录后一对一推送或一对多推送,参考文档:http://pushplus.hxtrip.com/
|
||||
## 其中PUSH_PLUS_USER是一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码)注:(1、需订阅者扫描二维码 2、如果您是创建群组所属人,也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送),只填PUSH_PLUS_TOKEN默认为一对一推送
|
||||
export PUSH_PLUS_TOKEN=""
|
||||
export PUSH_PLUS_USER=""
|
||||
|
||||
## 7. 企业微信机器人消息推送 webhook 后面的 key,文档:https://work.weixin.qq.com/api/doc/90000/90136/91770
|
||||
export QYWX_KEY=""
|
||||
|
||||
## 8. 企业微信应用消息推送的值,文档:https://work.weixin.qq.com/api/doc/90000/90135/90236
|
||||
## 依次填上corpid的值,corpsecret的值,touser的值,agentid,media_id的值,注意用,号隔开,例如:"wwcff56746d9adwers,B-791548lnzXBE6_BWfxdf3kSTMJr9vFEPKAbh6WERQ,mingcheng,1000001,2COXgjH2UIfERF2zxrtUOKgQ9XklUqMdGSWLBoW_lSDAdafat"
|
||||
export QYWX_AM=""
|
||||
|
||||
|
||||
################################## Telegram 代理(选填) ##################################
|
||||
## Telegram 代理的 IP,代理类型为 http,比如你代理是 http://127.0.0.1:1080,则填写 export TG_PROXY_HOST="127.0.0.1",export TG_PROXY_PORT="1080"
|
||||
## 如需使用,请自行解除注释
|
||||
# export TG_PROXY_HOST=""
|
||||
# export TG_PROXY_PORT=""
|
||||
|
||||
## Telegram api自建的反向代理地址,例子:反向代理地址 http://aaa.bbb.ccc 则填写 aaa.bbb.ccc,教程:https://www.hostloc.com/thread-805441-1-1.html
|
||||
## 如需使用,请自行解除下注释
|
||||
# export TG_API_HOST=""
|
||||
|
||||
|
||||
################################## 定义每日签到的通知形式(选填) ##################################
|
||||
## js脚本每日签到提供3种通知方式,分别为:
|
||||
## 关闭通知,那么请在下方填入0
|
||||
## 简洁通知,那么请在下方填入1,其效果见:https://gitee.com/lxk0301/jd_docker/blob/master/icon/bean_sign_simple.jpg
|
||||
## 原始通知,那么请在下方填入2,如果不填也默认为2,内容比较长,这也是默认通知方式
|
||||
NotifyBeanSign=""
|
||||
|
||||
|
||||
################################## 定义每日签到每个接口间的延迟时间(选填) ##################################
|
||||
## 默认每个签到接口并发无延迟,如需要依次进行每个接口,请自定义延迟时间,单位为毫秒,延迟作用于每个签到接口, 如填入延迟则切换顺序签到(耗时较长)
|
||||
## 例: "2000" 则表示每个接口延迟2秒; "2000-5000" 则表示每个接口之间最小2秒至最大5秒内的随机延迟
|
||||
export JD_BEAN_STOP=""
|
||||
|
||||
|
||||
################################## 自动按顺序进行账号间互助(选填) ##################################
|
||||
## 设置为 true 时,以下所有互助活动,账号间将按照config.sh中Cookie顺序进行互助,此时,不会助力不在config.sh中的账号,无法和别人交换助力
|
||||
## MyXxxx系列变量仍然需要填写,但ForOtherXxxx系列变量不再需要填写(填写了也无效)
|
||||
## 如果启用了TempBlockCookie,那么只是被屏蔽的账号不助力其他账号,其他账号还是会助力被屏蔽的账号
|
||||
AutoHelpOther=""
|
||||
|
||||
|
||||
################################## 定义导出互助码模板样式(选填) ##################################
|
||||
## 定义 export_sharecodes.sh 导出的互助码模板样式,目前预定义三种模板,其他模板待开发。
|
||||
## 不填则默认按“普通优先级助力模板”导出,Cookie编号在前的优先助力
|
||||
## 填 0 将使用“统一优先级助力模板”,所有账户要助力的码全部一致,和启用 AutoHelpOther 的效果差不多
|
||||
## 填 1 使用“均匀助力模板”,所有账户获得助力次数一致
|
||||
HelpType=""
|
||||
|
||||
|
||||
################################## 定义jd_fruit互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyFruit1=""
|
||||
MyFruit2=""
|
||||
MyFruit3=""
|
||||
MyFruit4=""
|
||||
MyFruit5=""
|
||||
MyFruit6=""
|
||||
MyFruitA=""
|
||||
MyFruitB=""
|
||||
|
||||
ForOtherFruit1=""
|
||||
ForOtherFruit2=""
|
||||
ForOtherFruit3=""
|
||||
ForOtherFruit4=""
|
||||
ForOtherFruit5=""
|
||||
ForOtherFruit6=""
|
||||
|
||||
|
||||
################################## 定义jd_pet互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyPet1=""
|
||||
MyPet2=""
|
||||
MyPet3=""
|
||||
MyPet4=""
|
||||
MyPet5=""
|
||||
MyPet6=""
|
||||
MyPetA=""
|
||||
MyPetB=""
|
||||
|
||||
ForOtherPet1=""
|
||||
ForOtherPet2=""
|
||||
ForOtherPet3=""
|
||||
ForOtherPet4=""
|
||||
ForOtherPet5=""
|
||||
ForOtherPet6=""
|
||||
|
||||
|
||||
################################## 定义jd_plantBean互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyBean1=""
|
||||
MyBean2=""
|
||||
MyBean3=""
|
||||
MyBean4=""
|
||||
MyBean5=""
|
||||
MyBean6=""
|
||||
MyBeanA=""
|
||||
MyBeanB=""
|
||||
|
||||
ForOtherBean1=""
|
||||
ForOtherBean2=""
|
||||
ForOtherBean3=""
|
||||
ForOtherBean4=""
|
||||
ForOtherBean5=""
|
||||
ForOtherBean6=""
|
||||
|
||||
|
||||
################################## 定义jd_dreamFactory互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyDreamFactory1=""
|
||||
MyDreamFactory2=""
|
||||
MyDreamFactory3=""
|
||||
MyDreamFactory4=""
|
||||
MyDreamFactory5=""
|
||||
MyDreamFactory6=""
|
||||
MyDreamFactoryA=""
|
||||
MyDreamFactoryB=""
|
||||
|
||||
ForOtherDreamFactory1=""
|
||||
ForOtherDreamFactory2=""
|
||||
ForOtherDreamFactory3=""
|
||||
ForOtherDreamFactory4=""
|
||||
ForOtherDreamFactory5=""
|
||||
ForOtherDreamFactory6=""
|
||||
|
||||
|
||||
################################## 定义jd_jdfactory互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyJdFactory1=""
|
||||
MyJdFactory2=""
|
||||
MyJdFactory3=""
|
||||
MyJdFactory4=""
|
||||
MyJdFactory5=""
|
||||
MyJdFactory6=""
|
||||
MyJdFactoryA=""
|
||||
MyJdFactoryB=""
|
||||
|
||||
ForOtherJdFactory1=""
|
||||
ForOtherJdFactory2=""
|
||||
ForOtherJdFactory3=""
|
||||
ForOtherJdFactory4=""
|
||||
ForOtherJdFactory5=""
|
||||
ForOtherJdFactory6=""
|
||||
|
||||
|
||||
################################## 定义jd_jdzz互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyJdzz1=""
|
||||
MyJdzz2=""
|
||||
MyJdzz3=""
|
||||
MyJdzz4=""
|
||||
MyJdzz5=""
|
||||
MyJdzz6=""
|
||||
MyJdzzA=""
|
||||
MyJdzzB=""
|
||||
|
||||
ForOtherJdzz1=""
|
||||
ForOtherJdzz2=""
|
||||
ForOtherJdzz3=""
|
||||
ForOtherJdzz4=""
|
||||
ForOtherJdzz5=""
|
||||
ForOtherJdzz6=""
|
||||
|
||||
|
||||
################################## 定义jd_crazy_joy互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyJoy1=""
|
||||
MyJoy2=""
|
||||
MyJoy3=""
|
||||
MyJoy4=""
|
||||
MyJoy5=""
|
||||
MyJoy6=""
|
||||
MyJoyA=""
|
||||
MyJoyB=""
|
||||
|
||||
ForOtherJoy1=""
|
||||
ForOtherJoy2=""
|
||||
ForOtherJoy3=""
|
||||
ForOtherJoy4=""
|
||||
ForOtherJoy5=""
|
||||
ForOtherJoy6=""
|
||||
|
||||
|
||||
################################## 定义jd_jxnc互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
## jd_jxnc助力码为 JSON 格式因此使用单引号,json 格式如下
|
||||
## {"smp":"22bdadsfaadsfadse8a","active":"jdnc_1_btorange210113_2","joinnum":"1"}
|
||||
## 助力码获取可以通过 bash jd.sh jd_get_share_code now 命令获取
|
||||
## 注意:jd_jxnc 种植种子发生变化的时候,互助码也会变!!
|
||||
MyJxnc1=''
|
||||
MyJxnc2=''
|
||||
MyJxnc3=''
|
||||
MyJxnc4=''
|
||||
MyJxnc5=''
|
||||
MyJxnc6=''
|
||||
MyJxncA=''
|
||||
MyJxncB=''
|
||||
|
||||
ForOtherJxnc1=""
|
||||
ForOtherJxnc2=""
|
||||
ForOtherJxnc3=""
|
||||
ForOtherJxnc4=""
|
||||
ForOtherJxnc5=""
|
||||
ForOtherJxnc6=""
|
||||
|
||||
|
||||
################################## 定义jd_bookshop互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyBookShop1=""
|
||||
MyBookShop2=""
|
||||
MyBookShop3=""
|
||||
MyBookShop4=""
|
||||
MyBookShop5=""
|
||||
MyBookShop6=""
|
||||
MyBookShopA=""
|
||||
MyBookShopB=""
|
||||
|
||||
ForOtherBookShop1=""
|
||||
ForOtherBookShop2=""
|
||||
ForOtherBookShop3=""
|
||||
ForOtherBookShop4=""
|
||||
ForOtherBookShop5=""
|
||||
ForOtherBookShop6=""
|
||||
|
||||
|
||||
################################## 定义jd_cash互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyCash1=""
|
||||
MyCash2=""
|
||||
MyCash3=""
|
||||
MyCash4=""
|
||||
MyCash5=""
|
||||
MyCash6=""
|
||||
MyCashA=""
|
||||
MyCashB=""
|
||||
|
||||
ForOtherCash1=""
|
||||
ForOtherCash2=""
|
||||
ForOtherCash3=""
|
||||
ForOtherCash4=""
|
||||
ForOtherCash5=""
|
||||
ForOtherCash6=""
|
||||
|
||||
|
||||
################################## 定义jd_sgmh互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MySgmh1=""
|
||||
MySgmh2=""
|
||||
MySgmh3=""
|
||||
MySgmh4=""
|
||||
MySgmh5=""
|
||||
MySgmh6=""
|
||||
MySgmhA=""
|
||||
MySgmhB=""
|
||||
|
||||
ForOtherSgmh1=""
|
||||
ForOtherSgmh2=""
|
||||
ForOtherSgmh3=""
|
||||
ForOtherSgmh4=""
|
||||
ForOtherSgmh5=""
|
||||
ForOtherSgmh6=""
|
||||
|
||||
|
||||
################################## 定义jd_cfd活动互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyCfd1=""
|
||||
MyCfd2=""
|
||||
MyCfd3=""
|
||||
MyCfd4=""
|
||||
MyCfd5=""
|
||||
MyCfd6=""
|
||||
MyCfdA=""
|
||||
MyCfdB=""
|
||||
|
||||
ForOtherCfd1=""
|
||||
ForOtherCfd2=""
|
||||
ForOtherCfd3=""
|
||||
ForOtherCfd4=""
|
||||
ForOtherCfd5=""
|
||||
ForOtherCfd6=""
|
||||
|
||||
|
||||
################################## 定义jd_global活动互助(选填) ##################################
|
||||
## 具体填法及要求详见本文件最下方“互助码填法示例”
|
||||
MyGlobal1=""
|
||||
MyGlobal2=""
|
||||
MyGlobal3=""
|
||||
MyGlobal4=""
|
||||
MyGlobal5=""
|
||||
MyGlobal6=""
|
||||
MyGlobalA=""
|
||||
MyGlobalB=""
|
||||
|
||||
ForOtherGlobal1=""
|
||||
ForOtherGlobal2=""
|
||||
ForOtherGlobal3=""
|
||||
ForOtherGlobal4=""
|
||||
ForOtherGlobal5=""
|
||||
ForOtherGlobal6=""
|
||||
|
||||
|
||||
################################## 定义jd_superMarket蓝币兑换数量(选填) ##################################
|
||||
## jd_superMarket蓝币兑换,可用值包括:
|
||||
## 一、0:表示不兑换京豆,这也是js脚本的默认值
|
||||
## 二、20:表示兑换20个京豆
|
||||
## 三、1000:表示兑换1000个京豆
|
||||
## 四、可兑换清单的商品名称,输入能跟唯一识别出来的关键词即可,比如:MARKET_COIN_TO_BEANS="抽纸"
|
||||
## 注意:有些比较贵的实物商品JD只是展示出来忽悠人的,即使你零点用脚本去抢,也会提示没有或提示已下架
|
||||
export MARKET_COIN_TO_BEANS="0"
|
||||
|
||||
|
||||
################################## 定义jd_superMarket蓝币成功兑换奖品是否静默运行(选填) ##################################
|
||||
## 默认 "false" 关闭(即:奖品兑换成功后会发出通知提示),如需要静默运行不发出通知,请改为 "true"
|
||||
export MARKET_REWARD_NOTIFY=""
|
||||
|
||||
|
||||
################################## 定义jd_superMarket是否自动使用金币去抽奖(选填) ##################################
|
||||
## 是否用金币去抽奖,默认 "false" 关闭,如需开启,请修改为 "true"
|
||||
export SUPERMARKET_LOTTERY=""
|
||||
|
||||
|
||||
################################## 定义jd_superMarket是否自动参加PK队伍(选填) ##################################
|
||||
## 是否每次PK活动参加脚本作者创建的PK队伍,"true" 表示参加,"false" 表示不参加,默认为 "true"
|
||||
export JOIN_PK_TEAM=""
|
||||
|
||||
|
||||
################################## 定义jd_fruit是否静默运行(选填) ##################################
|
||||
## 默认为 "false",不静默,发送推送通知消息,如不想收到通知,请修改为 "true"
|
||||
## 如果你不想完全关闭或者完全开启通知,只想在特定的时间发送通知,可以参考下面的“定义jd_pet是否静默运行”部分,设定几个if判断条件
|
||||
export FRUIT_NOTIFY_CONTROL=""
|
||||
|
||||
|
||||
################################## 定义jd_fruit是否使用水滴换豆卡(选填) ##################################
|
||||
## 如果出现限时活动时100g水换20豆,此时比浇水划算,"true" 表示换豆(不浇水),"false" 表示不换豆(继续浇水),默认是"false"
|
||||
## 如需切换为换豆(不浇水),请修改为 "true"
|
||||
export FRUIT_BEAN_CARD=""
|
||||
|
||||
|
||||
################################## 定义jd_joy喂食克数(选填) ##################################
|
||||
## 你期望的jd_joy每次喂食克数,只能填入10、20、40、80,默认为10
|
||||
## 如实际持有食物量小于所设置的克数,脚本会自动降一档,直到降无可降
|
||||
## 具体情况请自行在jd_joy游戏中去查阅攻略
|
||||
export JOY_FEED_COUNT=""
|
||||
|
||||
|
||||
################################## 定义jd_joy兑换京豆数量(选填) ##################################
|
||||
## 目前的可用值包括:0、20、500、1000,其中0表示为不自动兑换京豆,如不设置,将默认为"20"
|
||||
## 不同等级可兑换不同数量的京豆,详情请见jd_joy游戏中兑换京豆选项
|
||||
## 500、1000的京豆每天有总量限制,设置了并且你也有足够积分时,也并不代表就一定能抢到
|
||||
export JD_JOY_REWARD_NAME=""
|
||||
|
||||
|
||||
################################## 定义jd_joy兑换京豆是否静默运行(选填) ##################################
|
||||
## 默认为 "false",在成功兑换京豆时将发送推送通知消息(失败不发送),如想要静默不发送通知,请修改为 "true"
|
||||
export JD_JOY_REWARD_NOTIFY=""
|
||||
|
||||
|
||||
################################## 定义jd_joy是否自动给好友的汪汪喂食(选填) ##################################
|
||||
## 默认 "false" 不会自动给好友的汪汪喂食,如想自动喂食,请改成 "true"
|
||||
export JOY_HELP_FEED=""
|
||||
|
||||
|
||||
################################## 定义jd_joy是否自动报名宠物赛跑(选填) ##################################
|
||||
## 默认 "true" 参加宠物赛跑,如需关闭,请改成 "false"
|
||||
export JOY_RUN_FLAG=""
|
||||
|
||||
|
||||
################################## 定义jd_joy参加比赛类型(选填) ##################################
|
||||
## 当JOY_RUN_FLAG不设置或设置为 "true" 时生效
|
||||
## 可选值:2,10,50,其他值不可以。其中2代表参加双人PK赛,10代表参加10人突围赛,50代表参加50人挑战赛,不填时默认为2
|
||||
## 各个账号间请使用 & 分隔,比如:JOY_TEAM_LEVEL="2&2&50&10"
|
||||
## 如果你有5个账号但只写了四个数字,那么第5个账号将默认参加2人赛,账号如果更多,与此类似
|
||||
export JOY_TEAM_LEVEL=""
|
||||
|
||||
|
||||
################################## 定义jd_joy赛跑自己账号内部是否开启互助(选填) ##################################
|
||||
## 输入 true 为开启内部互助
|
||||
export JOY_RUN_HELP_MYSELF=""
|
||||
|
||||
|
||||
################################## 定义jd_joy赛跑获胜后是否推送通知(选填) ##################################
|
||||
## 控制jd_joy.js脚本jd_joy赛跑获胜后是否推送通知,"false" 为否(不推送通知消息),"true" 为是(即:发送推送通知消息),默认为 "true"
|
||||
export JOY_RUN_NOTIFY=""
|
||||
|
||||
|
||||
################################## 定义jd_moneyTree是否自动将金果卖出变成金币(选填) ##################################
|
||||
## 金币有时效,默认为 "false",不卖出金果为金币,如想希望自动卖出,请修改为 "true"
|
||||
export MONEY_TREE_SELL_FRUIT=""
|
||||
|
||||
|
||||
################################## 定义jd_pet是否静默运行(选填) ##################################
|
||||
## 默认 "false"(不静默,发送推送通知消息),如想静默请修改为 true
|
||||
## 每次执行脚本通知太频繁了,改成只在周三和周六中午那一次运行时发送通知提醒
|
||||
## 除掉上述提及时间之外,均设置为 true,静默不发通知
|
||||
## 特别说明:针对北京时间有效。
|
||||
if [ $(date "+%-w") -eq 6 ] && [ $(date "+%-H") -ge 9 ] && [ $(date "+%-H") -lt 14 ]; then
|
||||
export PET_NOTIFY_CONTROL="false"
|
||||
elif [ $(date "+%-w") -eq 3 ] && [ $(date "+%-H") -ge 9 ] && [ $(date "+%-H") -lt 14 ]; then
|
||||
export PET_NOTIFY_CONTROL="false"
|
||||
else
|
||||
export PET_NOTIFY_CONTROL="true"
|
||||
fi
|
||||
|
||||
|
||||
################################## 定义jd_dreamFactory控制哪个JD账号不运行此脚本(选填) ##################################
|
||||
## 输入"1"代表第一个JD账号不运行,多个使用 & 连接,例:"1&3" 代表账号1和账号3不运行jd_dreamFactory脚本,注:输入"0",代表全部账号不运行jd_dreamFactory脚本
|
||||
## 如果使用了 “临时屏蔽某个Cookie” TempBlockCookie 功能,编号会发生变化
|
||||
export DREAMFACTORY_FORBID_ACCOUNT=""
|
||||
|
||||
|
||||
################################## 定义jd_jdfactory控制哪个JD账号不运行此脚本(选填) ##################################
|
||||
## 输入"1"代表第一个JD账号不运行,多个使用 & 连接,例:"1&3" 代表账号1和账号3不运行jd_jdfactory脚本,注:输入"0",代表全部账号不运行jd_jdfactory脚本
|
||||
## 如果使用了 “临时屏蔽某个Cookie” TempBlockCookie 功能,编号会发生变化
|
||||
export JDFACTORY_FORBID_ACCOUNT=""
|
||||
|
||||
|
||||
################################## 定义jd_jdfactory心仪的商品(选填) ##################################
|
||||
## 只有在满足以下条件时,才自动投入电力:一是存储的电力满足生产商品所需的电力,二是心仪的商品有库存,如果没有输入心仪的商品,那么当前你正在生产的商品视作心仪的商品
|
||||
## 如果你看不懂上面的话,请去jd_jdfactory游戏中查阅攻略
|
||||
## 心仪的商品请输入商品的全称或能唯一识别出该商品的关键字
|
||||
export FACTORAY_WANTPRODUCT_NAME=""
|
||||
|
||||
|
||||
################################## 定义jd_jxnc通知级别(选填) ##################################
|
||||
## 可用值: 0(不通知); 1(本次获得水滴>0); 2(任务执行); 3(任务执行+未种植种子),默认为"3"
|
||||
export JXNC_NOTIFY_LEVEL="3"
|
||||
|
||||
|
||||
################################## 定义jd_cfd通知开关(选填) ##################################
|
||||
## 输入 true 为通知,不填则为不通知
|
||||
export CFD_NOTIFY_CONTROL=""
|
||||
|
||||
|
||||
################################## 定义jd_jxd是否自动把抽奖卷兑换为兑币 ##################################
|
||||
## 输入 true 为自动兑换,不填则为不兑换
|
||||
export JD_JXD_EXCHANGE=""
|
||||
|
||||
|
||||
################################## 定义jd_necklace是否是否静默运行 ##################################
|
||||
## 控制点点券是否静默运行,false 为否(默认值false,发送推送通知消息),true 为是(即:不发送推送通知消息)
|
||||
export DDQ_NOTIFY_CONTROL=""
|
||||
|
||||
|
||||
################################## 定义jd_cash是否是否静默运行 ##################################
|
||||
## 控制签到领现金是否静默运行,false 为否(默认值false,发送推送通知消息),true 为是(即:不发送推送通知消息)
|
||||
export CASH_NOTIFY_CONTROL=""
|
||||
|
||||
|
||||
################################## 定义jd_jdzz是否是否静默运行 ##################################
|
||||
## 控制京东赚赚是否静默运行,false 为否(默认值false,发送推送通知消息),默认每月1日推送一次通知,true 为是(即:不发送推送通知消息),
|
||||
export JDZZ_NOTIFY_CONTROL=""
|
||||
|
||||
|
||||
################################## 定义取关参数(选填) ##################################
|
||||
## jd_unsubscribe这个任务是用来取关每天做任务关注的商品和店铺,默认在每次运行时取关20个商品和20个店铺
|
||||
## 如果取关数量不够,可以根据情况增加,还可以设置 jdUnsubscribeStopGoods 和 jdUnsubscribeStopShop
|
||||
## 商品取关数量
|
||||
goodPageSize=""
|
||||
## 店铺取关数量
|
||||
shopPageSize=""
|
||||
## 遇到此商品不再取关此商品以及它后面的商品,需去商品详情页长按拷贝商品信息
|
||||
jdUnsubscribeStopGoods=""
|
||||
## 遇到此店铺不再取关此店铺以及它后面的店铺,请从头开始输入店铺名称
|
||||
jdUnsubscribeStopShop=""
|
||||
|
||||
|
||||
################################## 定义注销店铺会员参数(选填) ##################################
|
||||
## jd_unbind脚本需要的,注销JD已开的店铺会员,不是注销JDplus会员,个别店铺无法注销
|
||||
## 此参数控制每次运行脚本时注销多少个店铺会员,默认200
|
||||
export UN_BIND_CARD_NUM=""
|
||||
|
||||
## 遇到此参数设定的会员卡则跳过不进行注销,多个会员卡之间以 & 分隔,默认值"JDPLUS会员"
|
||||
export UN_BIND_STOP_CARD=""
|
||||
|
||||
|
||||
################################## jd_crazy_joy(选填) ##################################
|
||||
## jd_crazy_joy循环助力,"true" 表示循环助力,"false" 表示不循环助力,默认 "false"
|
||||
export JDJOY_HELPSELF=""
|
||||
|
||||
## jd_crazy_joy京豆兑换,目前最小值为500/1000京豆,默认为 "0" 不开启京豆兑换
|
||||
export JDJOY_APPLYJDBEAN=""
|
||||
|
||||
## jd_crazy_joy自动购买什么等级的JOY,如需要使用请自行解除注释
|
||||
# export BUY_JOY_LEVEL=""
|
||||
|
||||
|
||||
################################## 定义是否自动加购物车(选填) ##################################
|
||||
## jd_bookshop和jd_small_home有些任务需要将商品加进购物车才能完成,默认 "false" 不做这些任务,如想做,请设置为 "true"
|
||||
export PURCHASE_SHOPS=""
|
||||
|
||||
|
||||
################################## 是否添加DIY脚本(选填) ##################################
|
||||
## 如果你自己会写shell脚本,并且希望在每次git_pull.sh这个脚本运行时,额外运行你的DIY脚本,请赋值为 "true"
|
||||
## 同时,请务必将你的脚本命名为 diy.sh (只能叫这个文件名),放在 config 目录下
|
||||
## 我已定义好的变量,你如果想直接使用,可以参考本仓库下 git_pull.sh 文件
|
||||
EnableExtraShell=""
|
||||
|
||||
|
||||
################################## 互助码填法示例 ##################################
|
||||
## **互助码是填在My系列变量中的,ForOther系统变量中只要填入My系列的变量名即可,按注释中的例子拼接,以jd_fruit为例,如下所示。**
|
||||
## **实际上jd_fruit一个账号只能给别人助力3次,我多写的话,只有前几个会被助力。但如果前面的账号获得的助力次数已经达到上限了,那么还是会尝试继续给余下的账号助力,所以多填也是有意义的。**
|
||||
## **ForOther系列变量必须从1开始编号,依次编下去。**
|
||||
|
||||
# MyFruit1="e6e04602d5e343258873af1651b603ec" # 这是Cookie1这个账号的互助码
|
||||
# MyFruit2="52801b06ce2a462f95e1d59d7e856ef4" # 这是Cookie2这个账号的互助码
|
||||
# MyFruit3="e2fd1311229146cc9507528d0b054da8" # 这是Cookie3这个账号的互助码
|
||||
# MyFruit4="6dc9461f662d490991a31b798f624128" # 这是Cookie4这个账号的互助码
|
||||
# MyFruit5="30f29addd75d44e88fb452bbfe9f2110" # 这是Cookie5这个账号的互助码
|
||||
# MyFruit6="1d02fc9e0e574b4fa928e84cb1c5e70b" # 这是Cookie6这个账号的互助码
|
||||
# MyFruitA="5bc73a365ff74a559bdee785ea97fcc5" # 这是我和别人交换互助,另外一个用户A的互助码
|
||||
# MyFruitB="6d402dcfae1043fba7b519e0d6579a6f" # 这是我和别人交换互助,另外一个用户B的互助码
|
||||
# MyFruitC="5efc7fdbb8e0436f8694c4c393359576" # 这是我和别人交换互助,另外一个用户C的互助码
|
||||
|
||||
# ForOtherFruit1="${MyFruit2}@${MyFruitB}@${MyFruit4}" # Cookie1这个账号助力Cookie2的账号的账号、Cookie4的账号以及用户B
|
||||
# ForOtherFruit2="${MyFruit1}@${MyFruitA}@${MyFruit4}" # Cookie2这个账号助力Cookie1的账号的账号、Cookie4的账号以及用户A
|
||||
# ForOtherFruit3="${MyFruit1}@${MyFruit2}@${MyFruitC}@${MyFruit4}@${MyFruitA}@${MyFruit6}" # 解释同上,jd_fruit实际上只能助力3次
|
||||
# ForOtherFruit4="${MyFruit1}@${MyFruit2}@${MyFruit3}@${MyFruitC}@${MyFruit6}@${MyFruitA}" # 解释同上,jd_fruit实际上只能助力3次
|
||||
# ForOtherFruit5="${MyFruit1}@${MyFruit2}@${MyFruit3}@${MyFruitB}@${MyFruit4}@${MyFruit6}@${MyFruitC}@${MyFruitA}"
|
||||
# ForOtherFruit6="${MyFruit1}@${MyFruit2}@${MyFruit3}@${MyFruitA}@${MyFruit4}@${MyFruit5}@${MyFruitC}"
|
||||
|
||||
|
||||
################################## 额外的环境变量(选填) ##################################
|
||||
## 请在以下补充你需要用到的额外的环境变量,形式:export 变量名="变量值"
|
||||
|
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
81
src/layouts/defaultProps.tsx
Normal file
81
src/layouts/defaultProps.tsx
Normal file
|
@ -0,0 +1,81 @@
|
|||
import {
|
||||
FormOutlined,
|
||||
FieldTimeOutlined,
|
||||
DiffOutlined,
|
||||
SettingOutlined,
|
||||
CodeOutlined,
|
||||
FolderOutlined,
|
||||
LockOutlined,
|
||||
RadiusSettingOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import logo from '@/assets/logo.png';
|
||||
|
||||
export default {
|
||||
route: {
|
||||
routes: [
|
||||
{
|
||||
name: 'login',
|
||||
path: '/login',
|
||||
hideInMenu: true,
|
||||
component: '@/pages/login/index',
|
||||
},
|
||||
{
|
||||
path: '/cookie',
|
||||
name: 'Cookie管理',
|
||||
icon: <RadiusSettingOutlined />,
|
||||
component: '@/pages/cookie/index',
|
||||
},
|
||||
{
|
||||
path: '/config',
|
||||
name: '配置文件',
|
||||
icon: <SettingOutlined />,
|
||||
component: '@/pages/config/index',
|
||||
},
|
||||
{
|
||||
path: '/diy',
|
||||
name: '自定义脚本',
|
||||
icon: <FormOutlined />,
|
||||
component: '@/pages/diy/index',
|
||||
},
|
||||
{
|
||||
path: '/crontab',
|
||||
name: '定时任务',
|
||||
icon: <FieldTimeOutlined />,
|
||||
component: '@/pages/crontab/index',
|
||||
},
|
||||
{
|
||||
path: '/diff',
|
||||
name: '对比工具',
|
||||
icon: <DiffOutlined />,
|
||||
component: '@/pages/diff/index',
|
||||
},
|
||||
{
|
||||
path: '/code',
|
||||
name: '互助码',
|
||||
icon: <CodeOutlined />,
|
||||
component: '@/pages/code/index',
|
||||
},
|
||||
{
|
||||
path: '/log',
|
||||
name: '日志',
|
||||
icon: <FolderOutlined />,
|
||||
component: '@/pages/log/index',
|
||||
},
|
||||
{
|
||||
path: '/password',
|
||||
name: '修改密码',
|
||||
icon: <LockOutlined />,
|
||||
component: '@/pages/password/index',
|
||||
},
|
||||
],
|
||||
},
|
||||
location: {
|
||||
pathname: '/',
|
||||
},
|
||||
fixSiderbar: true,
|
||||
navTheme: 'light',
|
||||
primaryColor: '#1890ff',
|
||||
contentWidth: 'Fixed',
|
||||
splitMenus: false,
|
||||
logo: logo,
|
||||
} as any;
|
23
src/layouts/index.less
Normal file
23
src/layouts/index.less
Normal file
|
@ -0,0 +1,23 @@
|
|||
body {
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
background-color: rgb(248, 248, 248);
|
||||
}
|
||||
|
||||
@import '~codemirror/lib/codemirror.css';
|
||||
@import '~codemirror/theme/dracula.css';
|
||||
|
||||
.code-mirror-wrapper .CodeMirror {
|
||||
position: absolute;
|
||||
height: calc(100% - 24px);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ant-pro-grid-content.wide {
|
||||
max-width: unset;
|
||||
height: calc(100vh - 72px);
|
||||
overflow: auto;
|
||||
.ant-pro-page-container-children-content{
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
54
src/layouts/index.tsx
Normal file
54
src/layouts/index.tsx
Normal file
|
@ -0,0 +1,54 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Button, Descriptions, Result, Avatar, Space, Statistic } from 'antd';
|
||||
import { LikeOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import ProLayout, {
|
||||
PageContainer,
|
||||
PageLoading,
|
||||
SettingDrawer,
|
||||
} from '@ant-design/pro-layout';
|
||||
import defaultProps from './defaultProps';
|
||||
import { Link, history } from 'umi';
|
||||
import config from '@/utils/config';
|
||||
import 'codemirror/mode/shell/shell.js'
|
||||
import './index.less';
|
||||
|
||||
export default function (props: any) {
|
||||
useEffect(() => {
|
||||
const isAuth = localStorage.getItem(config.authKey);
|
||||
if (!isAuth) {
|
||||
history.push('/login');
|
||||
}
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (props.location.pathname === '/') {
|
||||
history.push('/config');
|
||||
}
|
||||
}, [props.location.pathname]);
|
||||
if (props.location.pathname === '/login') {
|
||||
return props.children;
|
||||
}
|
||||
return (
|
||||
<ProLayout
|
||||
selectedKeys={[props.location.pathname]}
|
||||
title="控制面板"
|
||||
menuItemRender={(menuItemProps: any, defaultDom) => {
|
||||
if (
|
||||
menuItemProps.isUrl ||
|
||||
!menuItemProps.path ||
|
||||
location.pathname === menuItemProps.path
|
||||
) {
|
||||
return defaultDom;
|
||||
}
|
||||
return <Link to={menuItemProps.path}>{defaultDom}</Link>;
|
||||
}}
|
||||
// rightContentRender={() => (
|
||||
// <div>
|
||||
// <Avatar shape="square" size="small" icon={<UserOutlined />} />
|
||||
// </div>
|
||||
// )}
|
||||
{...defaultProps}
|
||||
>
|
||||
{props.children}
|
||||
</ProLayout>
|
||||
);
|
||||
}
|
0
src/pages/code/index.less
Normal file
0
src/pages/code/index.less
Normal file
93
src/pages/code/index.tsx
Normal file
93
src/pages/code/index.tsx
Normal file
|
@ -0,0 +1,93 @@
|
|||
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
|
||||
import { Button, notification, Modal } from 'antd';
|
||||
import config from '@/utils/config';
|
||||
import { PageContainer } from '@ant-design/pro-layout';
|
||||
import { Controlled as CodeMirror } from 'react-codemirror2';
|
||||
import { request } from '@/utils/http';
|
||||
|
||||
const Crontab = () => {
|
||||
const [width, setWdith] = useState('100%');
|
||||
const [marginLeft, setMarginLeft] = useState(0);
|
||||
const [marginTop, setMarginTop] = useState(-72);
|
||||
const [value, setValue] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const getConfig = () => {
|
||||
setLoading(true);
|
||||
request.get(`${config.apiPrefix}config/shareCode`).then((data) => {
|
||||
setValue(data);
|
||||
}).finally(() => setLoading(false));
|
||||
};
|
||||
|
||||
const updateConfig = () => {
|
||||
request
|
||||
.post(`${config.apiPrefix}save`, {
|
||||
data: { content: value, name: 'diy.sh' },
|
||||
})
|
||||
.then((data) => {
|
||||
notification.success({
|
||||
message: data.msg,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (document.body.clientWidth < 768) {
|
||||
setWdith('auto');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(0);
|
||||
} else {
|
||||
setWdith('100%');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(-72);
|
||||
}
|
||||
getConfig();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageContainer
|
||||
className="code-mirror-wrapper"
|
||||
title="互助码"
|
||||
loading={loading}
|
||||
extra={[
|
||||
<Button key="1" type="primary" onClick={updateConfig}>
|
||||
保存
|
||||
</Button>,
|
||||
]}
|
||||
header={{
|
||||
style: {
|
||||
padding: '4px 16px 4px 15px',
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 20,
|
||||
marginTop,
|
||||
width,
|
||||
marginLeft,
|
||||
},
|
||||
}}
|
||||
style={{
|
||||
height: '100vh',
|
||||
}}
|
||||
>
|
||||
<CodeMirror
|
||||
value={value}
|
||||
options={{
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
styleActiveLine: true,
|
||||
matchBrackets: true,
|
||||
mode: 'shell',
|
||||
theme: 'dracula',
|
||||
readOnly: 'nocursor',
|
||||
}}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
setValue(value);
|
||||
}}
|
||||
onChange={(editor, data, value) => {}}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Crontab;
|
0
src/pages/config/index.less
Normal file
0
src/pages/config/index.less
Normal file
148
src/pages/config/index.tsx
Normal file
148
src/pages/config/index.tsx
Normal file
|
@ -0,0 +1,148 @@
|
|||
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
|
||||
import { Button, notification, Modal } from 'antd';
|
||||
import config from '@/utils/config';
|
||||
import { PageContainer } from '@ant-design/pro-layout';
|
||||
import { Controlled as CodeMirror } from 'react-codemirror2';
|
||||
import { request } from '@/utils/http';
|
||||
import QRCode from 'qrcode.react';
|
||||
|
||||
const Config = () => {
|
||||
const [width, setWdith] = useState('100%');
|
||||
const [marginLeft, setMarginLeft] = useState(0);
|
||||
const [marginTop, setMarginTop] = useState(-72);
|
||||
const [value, setValue] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const getConfig = () => {
|
||||
setLoading(true);
|
||||
request.get(`${config.apiPrefix}config/config`).then((data) => {
|
||||
setValue(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));
|
||||
}
|
||||
|
||||
const showQrCode = () => {
|
||||
request.get(`${config.apiPrefix}qrcode`).then(async (data) => {
|
||||
const modal = Modal.info({
|
||||
title: '二维码',
|
||||
content: (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
marginLeft: -38,
|
||||
}}
|
||||
>
|
||||
<QRCode
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
marginBottom: 10,
|
||||
marginTop: 20,
|
||||
}}
|
||||
value={data.qrcode}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
getCookie(modal);
|
||||
});
|
||||
};
|
||||
|
||||
const getCookie = async (modal: { destroy: () => void }) => {
|
||||
for (let i = 0; i < 50; i++) {
|
||||
const result = await request.get(`${config.apiPrefix}cookie`);
|
||||
console.log(i, result);
|
||||
if (result && result.cookie) {
|
||||
notification.success({
|
||||
message: 'Cookie获取成功',
|
||||
});
|
||||
modal.destroy();
|
||||
Modal.success({
|
||||
title: '获取Cookie成功',
|
||||
content: <div>{result.cookie}</div>,
|
||||
});
|
||||
break;
|
||||
}
|
||||
await sleep(2000);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (document.body.clientWidth < 768) {
|
||||
setWdith('auto');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(0);
|
||||
} else {
|
||||
setWdith('100%');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(-72);
|
||||
}
|
||||
getConfig();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageContainer
|
||||
className="code-mirror-wrapper"
|
||||
title="config.sh"
|
||||
loading={loading}
|
||||
extra={[
|
||||
<Button key="1" type="primary" onClick={updateConfig}>
|
||||
保存
|
||||
</Button>,
|
||||
<Button key="2" type="primary" onClick={showQrCode}>
|
||||
扫码获取Cookie
|
||||
</Button>,
|
||||
]}
|
||||
header={{
|
||||
style: {
|
||||
padding: '4px 16px 4px 15px',
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 20,
|
||||
marginTop,
|
||||
width,
|
||||
marginLeft,
|
||||
},
|
||||
}}
|
||||
style={{
|
||||
height: '100vh',
|
||||
}}
|
||||
>
|
||||
<CodeMirror
|
||||
value={value}
|
||||
options={{
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
styleActiveLine: true,
|
||||
matchBrackets: true,
|
||||
mode: 'shell',
|
||||
theme: 'dracula',
|
||||
}}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
setValue(value);
|
||||
}}
|
||||
onChange={(editor, data, value) => {}}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Config;
|
0
src/pages/cookie/index.less
Normal file
0
src/pages/cookie/index.less
Normal file
190
src/pages/cookie/index.tsx
Normal file
190
src/pages/cookie/index.tsx
Normal file
|
@ -0,0 +1,190 @@
|
|||
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
|
||||
import { Button, notification, Modal, Table, Tag, Space } from 'antd';
|
||||
import config from '@/utils/config';
|
||||
import { PageContainer } from '@ant-design/pro-layout';
|
||||
import { request } from '@/utils/http';
|
||||
import QRCode from 'qrcode.react';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '用户名',
|
||||
dataIndex: 'pin',
|
||||
key: 'pin',
|
||||
},
|
||||
{
|
||||
title: '昵称',
|
||||
dataIndex: 'nickname',
|
||||
key: 'nickname',
|
||||
},
|
||||
{
|
||||
title: '值',
|
||||
dataIndex: 'cookie',
|
||||
key: 'cookie',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
dataIndex: 'status',
|
||||
render: (text: string, record: any) => (
|
||||
<Tag color="success">success</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
render: (text: string, record: any) => (
|
||||
<Space size="middle">
|
||||
<a>Invite {record.name}</a>
|
||||
<a>Delete</a>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const data = [
|
||||
{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
tags: ['nice', 'developer'],
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: 'Jim Green',
|
||||
age: 42,
|
||||
address: 'London No. 1 Lake Park',
|
||||
tags: ['loser'],
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
name: 'Joe Black',
|
||||
age: 32,
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
tags: ['cool', 'teacher'],
|
||||
},
|
||||
];
|
||||
|
||||
const Config = () => {
|
||||
const [width, setWdith] = useState('100%');
|
||||
const [marginLeft, setMarginLeft] = useState(0);
|
||||
const [marginTop, setMarginTop] = useState(-72);
|
||||
const [value, setValue] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const getConfig = () => {
|
||||
setLoading(true);
|
||||
request.get(`${config.apiPrefix}config/config`).then((data) => {
|
||||
setValue(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));
|
||||
}
|
||||
|
||||
const showQrCode = () => {
|
||||
request.get(`${config.apiPrefix}qrcode`).then(async (data) => {
|
||||
const modal = Modal.info({
|
||||
title: '二维码',
|
||||
content: (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
marginLeft: -38,
|
||||
}}
|
||||
>
|
||||
<QRCode
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
marginBottom: 10,
|
||||
marginTop: 20,
|
||||
}}
|
||||
value={data.qrcode}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
getCookie(modal);
|
||||
});
|
||||
};
|
||||
|
||||
const getCookie = async (modal: { destroy: () => void }) => {
|
||||
for (let i = 0; i < 50; i++) {
|
||||
const result = await request.get(`${config.apiPrefix}cookie`);
|
||||
console.log(i, result);
|
||||
if (result && result.cookie) {
|
||||
notification.success({
|
||||
message: 'Cookie获取成功',
|
||||
});
|
||||
modal.destroy();
|
||||
Modal.success({
|
||||
title: '获取Cookie成功',
|
||||
content: <div>{result.cookie}</div>,
|
||||
});
|
||||
break;
|
||||
}
|
||||
await sleep(2000);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (document.body.clientWidth < 768) {
|
||||
setWdith('auto');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(0);
|
||||
} else {
|
||||
setWdith('100%');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(-72);
|
||||
}
|
||||
getConfig();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageContainer
|
||||
className="code-mirror-wrapper"
|
||||
title="Cookie管理"
|
||||
loading={loading}
|
||||
extra={[
|
||||
<Button key="2" type="primary" onClick={showQrCode}>
|
||||
扫码获取Cookie
|
||||
</Button>,
|
||||
]}
|
||||
header={{
|
||||
style: {
|
||||
padding: '4px 16px 4px 15px',
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 20,
|
||||
marginTop,
|
||||
width,
|
||||
marginLeft,
|
||||
},
|
||||
}}
|
||||
style={{
|
||||
height: '100vh',
|
||||
}}
|
||||
>
|
||||
<Table columns={columns} pagination={{hideOnSinglePage: true}} dataSource={data} />
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Config;
|
0
src/pages/crontab/index.less
Normal file
0
src/pages/crontab/index.less
Normal file
92
src/pages/crontab/index.tsx
Normal file
92
src/pages/crontab/index.tsx
Normal file
|
@ -0,0 +1,92 @@
|
|||
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
|
||||
import { Button, notification, Modal } from 'antd';
|
||||
import config from '@/utils/config';
|
||||
import { PageContainer } from '@ant-design/pro-layout';
|
||||
import { Controlled as CodeMirror } from 'react-codemirror2';
|
||||
import { request } from '@/utils/http';
|
||||
|
||||
const Crontab = () => {
|
||||
const [width, setWdith] = useState('100%');
|
||||
const [marginLeft, setMarginLeft] = useState(0);
|
||||
const [marginTop, setMarginTop] = useState(-72);
|
||||
const [value, setValue] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const getConfig = () => {
|
||||
setLoading(true);
|
||||
request.get(`${config.apiPrefix}config/crontab`).then((data) => {
|
||||
setValue(data);
|
||||
}).finally(() => setLoading(false));
|
||||
};
|
||||
|
||||
const updateConfig = () => {
|
||||
request
|
||||
.post(`${config.apiPrefix}save`, {
|
||||
data: { content: value, name: 'crontab.list' },
|
||||
})
|
||||
.then((data) => {
|
||||
notification.success({
|
||||
message: data.msg,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (document.body.clientWidth < 768) {
|
||||
setWdith('auto');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(0);
|
||||
} else {
|
||||
setWdith('100%');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(-72);
|
||||
}
|
||||
getConfig();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageContainer
|
||||
className="code-mirror-wrapper"
|
||||
title="crontab.list"
|
||||
loading={loading}
|
||||
extra={[
|
||||
<Button key="1" type="primary" onClick={updateConfig}>
|
||||
保存
|
||||
</Button>,
|
||||
]}
|
||||
header={{
|
||||
style: {
|
||||
padding: '4px 16px 4px 15px',
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 20,
|
||||
marginTop,
|
||||
width,
|
||||
marginLeft,
|
||||
},
|
||||
}}
|
||||
style={{
|
||||
height: '100vh',
|
||||
}}
|
||||
>
|
||||
<CodeMirror
|
||||
value={value}
|
||||
options={{
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
styleActiveLine: true,
|
||||
matchBrackets: true,
|
||||
mode: 'shell',
|
||||
theme: 'dracula',
|
||||
}}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
setValue(value);
|
||||
}}
|
||||
onChange={(editor, data, value) => {}}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Crontab;
|
12
src/pages/diff/index.less
Normal file
12
src/pages/diff/index.less
Normal file
|
@ -0,0 +1,12 @@
|
|||
.d2h-files-diff {
|
||||
height: calc(100vh - 130px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.d2h-code-side-linenumber {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.d2h-code-side-line {
|
||||
padding: 0 0.5em;
|
||||
}
|
93
src/pages/diff/index.tsx
Normal file
93
src/pages/diff/index.tsx
Normal file
|
@ -0,0 +1,93 @@
|
|||
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
|
||||
import { Button, notification, Modal } from 'antd';
|
||||
import config from '@/utils/config';
|
||||
import { PageContainer } from '@ant-design/pro-layout';
|
||||
import { request } from '@/utils/http';
|
||||
import ReactDiffViewer from 'react-diff-viewer';
|
||||
import './index.less';
|
||||
|
||||
const Crontab = () => {
|
||||
const [width, setWdith] = useState('100%');
|
||||
const [marginLeft, setMarginLeft] = useState(0);
|
||||
const [marginTop, setMarginTop] = useState(-72);
|
||||
const [value, setValue] = useState('');
|
||||
const [sample, setSample] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const getConfig = () => {
|
||||
request.get(`${config.apiPrefix}config/config`).then((data) => {
|
||||
setValue(data);
|
||||
});
|
||||
};
|
||||
|
||||
const getSample = () => {
|
||||
setLoading(true);
|
||||
request.get(`${config.apiPrefix}config/sample`).then((data) => {
|
||||
setSample(data);
|
||||
}).finally(() => setLoading(false));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (document.body.clientWidth < 768) {
|
||||
setWdith('auto');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(0);
|
||||
} else {
|
||||
setWdith('100%');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(-72);
|
||||
}
|
||||
getConfig();
|
||||
getSample();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageContainer
|
||||
className="code-mirror-wrapper"
|
||||
title="对比工具"
|
||||
loading={loading}
|
||||
header={{
|
||||
style: {
|
||||
padding: '4px 16px 4px 15px',
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 20,
|
||||
marginTop,
|
||||
width,
|
||||
marginLeft,
|
||||
},
|
||||
}}
|
||||
style={{
|
||||
height: '100vh',
|
||||
}}
|
||||
>
|
||||
<ReactDiffViewer
|
||||
styles={{ diffRemoved: {
|
||||
overflowX: 'auto',
|
||||
maxWidth: 300,
|
||||
},
|
||||
diffAdded: {
|
||||
overflowX: 'auto',
|
||||
maxWidth: 300,
|
||||
},line: {
|
||||
wordBreak: 'break-word',
|
||||
}, }}
|
||||
oldValue={value}
|
||||
newValue={sample}
|
||||
splitView={true}
|
||||
leftTitle="config.sh"
|
||||
rightTitle="config.sh.sample"
|
||||
disableWordDiff={true}
|
||||
/>
|
||||
{/* <CodeDiff
|
||||
style={{ height: 'calc(100vh - 72px)', overflowY: 'auto' }}
|
||||
outputFormat="side-by-side"
|
||||
oldStr={value}
|
||||
newStr={sample}
|
||||
/> */}
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Crontab;
|
0
src/pages/diy/index.less
Normal file
0
src/pages/diy/index.less
Normal file
92
src/pages/diy/index.tsx
Normal file
92
src/pages/diy/index.tsx
Normal file
|
@ -0,0 +1,92 @@
|
|||
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
|
||||
import { Button, notification, Modal } from 'antd';
|
||||
import config from '@/utils/config';
|
||||
import { PageContainer } from '@ant-design/pro-layout';
|
||||
import { Controlled as CodeMirror } from 'react-codemirror2';
|
||||
import { request } from '@/utils/http';
|
||||
|
||||
const Crontab = () => {
|
||||
const [width, setWdith] = useState('100%');
|
||||
const [marginLeft, setMarginLeft] = useState(0);
|
||||
const [marginTop, setMarginTop] = useState(-72);
|
||||
const [value, setValue] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const getConfig = () => {
|
||||
setLoading(true);
|
||||
request.get(`${config.apiPrefix}config/diy`).then((data) => {
|
||||
setValue(data);
|
||||
}).finally(() => setLoading(false));
|
||||
};
|
||||
|
||||
const updateConfig = () => {
|
||||
request
|
||||
.post(`${config.apiPrefix}save`, {
|
||||
data: { content: value, name: 'diy.sh' },
|
||||
})
|
||||
.then((data) => {
|
||||
notification.success({
|
||||
message: data.msg,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (document.body.clientWidth < 768) {
|
||||
setWdith('auto');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(0);
|
||||
} else {
|
||||
setWdith('100%');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(-72);
|
||||
}
|
||||
getConfig();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageContainer
|
||||
className="code-mirror-wrapper"
|
||||
title="diy.sh"
|
||||
loading={loading}
|
||||
extra={[
|
||||
<Button key="1" type="primary" onClick={updateConfig}>
|
||||
保存
|
||||
</Button>,
|
||||
]}
|
||||
header={{
|
||||
style: {
|
||||
padding: '4px 16px 4px 15px',
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 20,
|
||||
marginTop,
|
||||
width,
|
||||
marginLeft,
|
||||
},
|
||||
}}
|
||||
style={{
|
||||
height: '100vh',
|
||||
}}
|
||||
>
|
||||
<CodeMirror
|
||||
value={value}
|
||||
options={{
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
styleActiveLine: true,
|
||||
matchBrackets: true,
|
||||
mode: 'shell',
|
||||
theme: 'dracula',
|
||||
}}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
setValue(value);
|
||||
}}
|
||||
onChange={(editor, data, value) => {}}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Crontab;
|
0
src/pages/log/index.less
Normal file
0
src/pages/log/index.less
Normal file
112
src/pages/log/index.tsx
Normal file
112
src/pages/log/index.tsx
Normal file
|
@ -0,0 +1,112 @@
|
|||
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
|
||||
import { Button, notification, Modal, TreeSelect } from 'antd';
|
||||
import config from '@/utils/config';
|
||||
import { PageContainer } from '@ant-design/pro-layout';
|
||||
import { Controlled as CodeMirror } from 'react-codemirror2';
|
||||
import { request } from '@/utils/http';
|
||||
const Log = () => {
|
||||
const [width, setWdith] = useState('100%');
|
||||
const [marginLeft, setMarginLeft] = useState(0);
|
||||
const [marginTop, setMarginTop] = useState(-72);
|
||||
const [title, setTitle] = useState('log');
|
||||
const [value, setValue] = useState('请选择日志文件');
|
||||
const [select, setSelect] = useState();
|
||||
const [data, setData] = useState();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const getConfig = () => {
|
||||
request.get(`${config.apiPrefix}logs`).then((data) => {
|
||||
setData(formatData(data.dirs) as any);
|
||||
});
|
||||
};
|
||||
|
||||
const formatData = (tree: any[]) => {
|
||||
return tree.map(x => {
|
||||
x.title = x.dirName;
|
||||
x.value = x.dirName;
|
||||
x.disabled = true;
|
||||
x.children = x.files.map((y: string) => ({ title: y, key: y, value: y, parent: x.dirName }));
|
||||
return x;
|
||||
})
|
||||
}
|
||||
|
||||
const getLog = (node: any) => {
|
||||
setLoading(true);
|
||||
request.get(`${config.apiPrefix}logs/${node.parent}/${node.value}`).then((data) => {
|
||||
setValue(data);
|
||||
}).finally(() => setLoading(false));
|
||||
};
|
||||
|
||||
const onSelect = (value: any, node: any) => {
|
||||
setSelect(value);
|
||||
setTitle(node.parent);
|
||||
getLog(node);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (document.body.clientWidth < 768) {
|
||||
setWdith('auto');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(0);
|
||||
} else {
|
||||
setWdith('100%');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(-72);
|
||||
}
|
||||
getConfig();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageContainer
|
||||
className="code-mirror-wrapper"
|
||||
title={title}
|
||||
loading={loading}
|
||||
extra={[
|
||||
<TreeSelect
|
||||
style={{ width: 280 }}
|
||||
value={select}
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
treeData={data}
|
||||
placeholder="请选择日志文件"
|
||||
showSearch
|
||||
key="title"
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
]}
|
||||
header={{
|
||||
style: {
|
||||
padding: '4px 16px 4px 15px',
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 20,
|
||||
marginTop,
|
||||
width,
|
||||
marginLeft,
|
||||
},
|
||||
}}
|
||||
style={{
|
||||
height: '100vh',
|
||||
}}
|
||||
>
|
||||
<CodeMirror
|
||||
value={value}
|
||||
options={{
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
styleActiveLine: true,
|
||||
matchBrackets: true,
|
||||
mode: 'shell',
|
||||
theme: 'dracula',
|
||||
readOnly: 'nocursor',
|
||||
}}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
setValue(value);
|
||||
}}
|
||||
onChange={(editor, data, value) => {}}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Log;
|
58
src/pages/login/index.less
Normal file
58
src/pages/login/index.less
Normal file
|
@ -0,0 +1,58 @@
|
|||
.form {
|
||||
position: absolute;
|
||||
top: 45%;
|
||||
left: 50%;
|
||||
margin: -160px 0 0 -160px;
|
||||
width: 320px;
|
||||
height: 320px;
|
||||
padding: 36px;
|
||||
box-shadow: 0 0 100px rgba(0, 0, 0, 0.08);
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
p {
|
||||
color: rgb(204, 204, 204);
|
||||
text-align: center;
|
||||
margin-top: 16px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin-bottom: 24px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 40px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
display: inline-block;
|
||||
font-weight: 700;
|
||||
// color: @primary-color;
|
||||
// .text-gradient();
|
||||
}
|
||||
}
|
||||
|
||||
.ant-spin-container,
|
||||
.ant-spin-nested-loading {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
}
|
73
src/pages/login/index.tsx
Normal file
73
src/pages/login/index.tsx
Normal file
|
@ -0,0 +1,73 @@
|
|||
import React, { Fragment, useEffect } from 'react';
|
||||
import { Button, Row, Input, Form, notification } from 'antd';
|
||||
import config from '@/utils/config';
|
||||
import { history } from 'umi';
|
||||
import styles from './index.less';
|
||||
import { request } from '@/utils/http';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const Login = () => {
|
||||
const handleOk = (values: any) => {
|
||||
request
|
||||
.post(`${config.apiPrefix}auth`, {
|
||||
data: {
|
||||
username: values.username,
|
||||
password: values.password,
|
||||
},
|
||||
})
|
||||
.then((data) => {
|
||||
if (data.err == 0) {
|
||||
localStorage.setItem(config.authKey, 'true');
|
||||
history.push('/cookie');
|
||||
} else {
|
||||
notification.open({
|
||||
message: data.msg,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const isAuth = localStorage.getItem(config.authKey);
|
||||
if (isAuth) {
|
||||
history.push('/cookie');
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={styles.form}>
|
||||
<div className={styles.logo}>
|
||||
<span>{config.siteName}</span>
|
||||
</div>
|
||||
<Form onFinish={handleOk}>
|
||||
<FormItem
|
||||
name="username"
|
||||
rules={[{ required: true, message: '请输入用户名' }]}
|
||||
hasFeedback
|
||||
>
|
||||
<Input placeholder="用户名" autoFocus/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
name="password"
|
||||
rules={[{ required: true, message: '请输入密码' }]}
|
||||
hasFeedback
|
||||
>
|
||||
<Input type="password" placeholder="密码" />
|
||||
</FormItem>
|
||||
<Row>
|
||||
<Button type="primary" htmlType="submit">
|
||||
Sign in
|
||||
</Button>
|
||||
</Row>
|
||||
</Form>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default Login;
|
0
src/pages/password/index.less
Normal file
0
src/pages/password/index.less
Normal file
84
src/pages/password/index.tsx
Normal file
84
src/pages/password/index.tsx
Normal file
|
@ -0,0 +1,84 @@
|
|||
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
|
||||
import { Button, notification, Input, Form } from 'antd';
|
||||
import config from '@/utils/config';
|
||||
import { PageContainer } from '@ant-design/pro-layout';
|
||||
import { Controlled as CodeMirror } from 'react-codemirror2';
|
||||
import { request } from '@/utils/http';
|
||||
|
||||
const Password = () => {
|
||||
const [width, setWdith] = useState('100%');
|
||||
const [marginLeft, setMarginLeft] = useState(0);
|
||||
const [marginTop, setMarginTop] = useState(-72);
|
||||
const [value, setValue] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const handleOk = (values: any) => {
|
||||
request
|
||||
.post(`${config.apiPrefix}auth?t=${Date.now()}`, {
|
||||
data: {
|
||||
username: values.username,
|
||||
password: values.password,
|
||||
},
|
||||
})
|
||||
.then((data) => {
|
||||
if (data.err == 0) {
|
||||
localStorage.setItem(config.authKey, 'true');
|
||||
} else {
|
||||
notification.open({
|
||||
message: data.msg,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (document.body.clientWidth < 768) {
|
||||
setWdith('auto');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(0);
|
||||
} else {
|
||||
setWdith('100%');
|
||||
setMarginLeft(0);
|
||||
setMarginTop(-72);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageContainer
|
||||
className="code-mirror-wrapper"
|
||||
title="修改密码"
|
||||
header={{
|
||||
style: {
|
||||
padding: '4px 16px 4px 15px',
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 20,
|
||||
marginTop,
|
||||
width,
|
||||
marginLeft,
|
||||
},
|
||||
}}
|
||||
style={{
|
||||
height: '100vh',
|
||||
}}
|
||||
>
|
||||
<Form onFinish={handleOk} style={{ padding: 20, background: '#fff', height: 'calc(100vh - 96px)' }}>
|
||||
<Form.Item name="username" rules={[{ required: true, message: '请输入用户名' }]} hasFeedback style={{width:300}}>
|
||||
<Input placeholder="用户名" autoFocus/>
|
||||
</Form.Item>
|
||||
<Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]} hasFeedback style={{width:300}}>
|
||||
<Input type="password" placeholder="密码" />
|
||||
</Form.Item>
|
||||
<Button type="primary" htmlType="submit">
|
||||
保存
|
||||
</Button>
|
||||
</Form>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Password;
|
37
src/utils/config.ts
Normal file
37
src/utils/config.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
export default {
|
||||
siteName: '京东羊毛脚本控制面板',
|
||||
apiPrefix: '/api/',
|
||||
authKey: 'whyour',
|
||||
|
||||
/* Layout configuration, specify which layout to use for route. */
|
||||
layouts: [
|
||||
{
|
||||
name: 'primary',
|
||||
include: [/.*/],
|
||||
exclude: [/(\/(en|zh))*\/login/],
|
||||
},
|
||||
],
|
||||
|
||||
/* I18n configuration, `languages` and `defaultLanguage` are required currently. */
|
||||
i18n: {
|
||||
/* Countrys flags: https://www.flaticon.com/packs/countrys-flags */
|
||||
languages: [
|
||||
{
|
||||
key: 'pt-br',
|
||||
title: 'Português',
|
||||
flag: '/portugal.svg',
|
||||
},
|
||||
{
|
||||
key: 'en',
|
||||
title: 'English',
|
||||
flag: '/america.svg',
|
||||
},
|
||||
{
|
||||
key: 'zh',
|
||||
title: '中文',
|
||||
flag: '/china.svg',
|
||||
},
|
||||
],
|
||||
defaultLanguage: 'en',
|
||||
},
|
||||
};
|
29
src/utils/http.ts
Normal file
29
src/utils/http.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { extend } from 'umi-request';
|
||||
import { history } from 'umi';
|
||||
|
||||
const time = Date.now();
|
||||
const errorHandler = function (error: any) {
|
||||
if (error.response) {
|
||||
console.log(error.response)
|
||||
} else {
|
||||
console.log(error.message);
|
||||
}
|
||||
|
||||
throw error; // 如果throw. 错误将继续抛出.
|
||||
// return {some: 'data'};
|
||||
};
|
||||
|
||||
const _request = extend({ timeout: 5000, params: { t: time }, errorHandler });
|
||||
|
||||
_request.interceptors.response.use(async response => {
|
||||
const res = await response.clone().text()
|
||||
if (res === '请先登录!') {
|
||||
setTimeout(() => {
|
||||
localStorage.removeItem('whyour');
|
||||
history.push('/login');
|
||||
});
|
||||
}
|
||||
return response;
|
||||
})
|
||||
|
||||
export const request = _request;
|
37
tsconfig.json
Normal file
37
tsconfig.json
Normal file
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"jsx": "react-jsx",
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": "./",
|
||||
"strict": true,
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
"@@/*": ["src/.umi/*"]
|
||||
},
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"include": [
|
||||
"mock/**/*",
|
||||
"src/**/*",
|
||||
"config/**/*",
|
||||
".umirc.ts",
|
||||
"typings.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"lib",
|
||||
"es",
|
||||
"dist",
|
||||
"typings",
|
||||
"**/__test__",
|
||||
"test",
|
||||
"docs",
|
||||
"tests"
|
||||
]
|
||||
}
|
8
typings.d.ts
vendored
Normal file
8
typings.d.ts
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
declare module '*.css';
|
||||
declare module '*.less';
|
||||
declare module '*.png';
|
||||
declare module '*.svg' {
|
||||
export function ReactComponent(props: React.SVGProps<SVGSVGElement>): React.ReactElement
|
||||
const url: string
|
||||
export default url
|
||||
}
|
Loading…
Reference in New Issue
Block a user