初始化项目

This commit is contained in:
whyour 2021-03-14 22:06:27 +08:00
commit f1f8ece8a2
41 changed files with 3017 additions and 0 deletions

16
.editorconfig Executable file
View 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
View 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
View File

@ -0,0 +1,8 @@
**/*.md
**/*.svg
**/*.ejs
**/*.html
package.json
.umi
.umi-production
.umi-test

11
.prettierrc Normal file
View File

@ -0,0 +1,11 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}

18
.umirc.ts Normal file
View 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
View 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
View 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
View 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
View 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
}
## 更新crontabgitee服务器同一时间限制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 设置为 true2.正常更新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 设置为 true2.正常更新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
View 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
View 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
View 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
View File

@ -0,0 +1 @@
{"user":"admin","password":"adminadmin"}

636
sample/config.sh.sample Executable file
View 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必填 ##################################
## 请依次填入每个用户的CookieCookie的具体形式只有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脚本时账号编号将发生变化
## 举例1TempBlockCookie="2" 临时屏蔽掉Cookie2
## 举例2TempBlockCookie="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

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View 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
View 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
View 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>
);
}

View File

93
src/pages/code/index.tsx Normal file
View 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;

View File

148
src/pages/config/index.tsx Normal file
View 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;

View File

190
src/pages/cookie/index.tsx Normal file
View 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;

View File

View 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
View 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
View 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
View File

92
src/pages/diy/index.tsx Normal file
View 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
View File

112
src/pages/log/index.tsx Normal file
View 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;

View 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
View 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;

View File

View 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
View 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
View 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
View 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
View 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
}

42
update.js Executable file

File diff suppressed because one or more lines are too long