diff --git a/plugins/alist/ico.png b/plugins/alist/ico.png
new file mode 100644
index 000000000..b1d76cb4f
Binary files /dev/null and b/plugins/alist/ico.png differ
diff --git a/plugins/alist/index.html b/plugins/alist/index.html
new file mode 100755
index 000000000..a47d91ed8
--- /dev/null
+++ b/plugins/alist/index.html
@@ -0,0 +1,30 @@
+
+
+
+
\ No newline at end of file
diff --git a/plugins/alist/index.py b/plugins/alist/index.py
new file mode 100755
index 000000000..beb263bd6
--- /dev/null
+++ b/plugins/alist/index.py
@@ -0,0 +1,263 @@
+# coding:utf-8
+
+import sys
+import io
+import os
+import time
+import re
+
+sys.path.append(os.getcwd() + "/class/core")
+import mw
+
+app_debug = False
+if mw.isAppleSystem():
+ app_debug = True
+
+
+def getPluginName():
+ return 'alist'
+
+
+def getPluginDir():
+ return mw.getPluginDir() + '/' + getPluginName()
+
+
+def getServerDir():
+ return mw.getServerDir() + '/' + getPluginName()
+
+
+def getInitDFile():
+ current_os = mw.getOs()
+ if current_os == 'darwin':
+ return '/tmp/' + getPluginName()
+
+ if current_os.startswith('freebsd'):
+ return '/etc/rc.d/' + getPluginName()
+
+ return '/etc/init.d/' + getPluginName()
+
+
+def getInitDTpl():
+ path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
+ return path
+
+
+def getArgs():
+ args = sys.argv[3:]
+ tmp = {}
+ args_len = len(args)
+
+ if args_len == 1:
+ t = args[0].strip('{').strip('}')
+ if t.strip() == '':
+ tmp = []
+ else:
+ t = t.split(':')
+ tmp[t[0]] = t[1]
+ tmp[t[0]] = t[1]
+ elif args_len > 1:
+ for i in range(len(args)):
+ t = args[i].split(':')
+ tmp[t[0]] = t[1]
+ return tmp
+
+def checkArgs(data, ck=[]):
+ for i in range(len(ck)):
+ if not ck[i] in data:
+ return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
+ return (True, mw.returnJson(True, 'ok'))
+
+
+def getConf():
+ path = getServerDir() + "/data/config.json"
+ return path
+
+def configTpl():
+ path = getPluginDir() + '/tpl'
+ pathFile = os.listdir(path)
+ tmp = []
+ for one in pathFile:
+ file = path + '/' + one
+ tmp.append(file)
+ return mw.getJson(tmp)
+
+
+def readConfigTpl():
+ args = getArgs()
+ data = checkArgs(args, ['file'])
+ if not data[0]:
+ return data[1]
+
+ content = mw.readFile(args['file'])
+ content = contentReplace(content)
+ return mw.returnJson(True, 'ok', content)
+
+
+def status():
+ data = mw.execShell(
+ "ps aux|grep alist |grep -v grep | grep -v python | grep -v mdserver-web | awk '{print $2}'")
+
+ if data[0] == '':
+ return 'stop'
+ return 'start'
+
+def contentReplace(content):
+ service_path = mw.getServerDir()
+ content = content.replace('{$ROOT_PATH}', mw.getRootDir())
+ content = content.replace('{$SERVER_PATH}', service_path)
+ content = content.replace('{$SERVER_APP}', service_path + '/'+getPluginName())
+ return content
+
+def initDreplace():
+
+ file_tpl = getInitDTpl()
+ service_path = os.path.dirname(os.getcwd())
+
+ initD_path = getServerDir() + '/init.d'
+ if not os.path.exists(initD_path):
+ os.mkdir(initD_path)
+ file_bin = initD_path + '/' + getPluginName()
+
+ # initd replace
+ if not os.path.exists(file_bin):
+ content = mw.readFile(file_tpl)
+ content = content.replace('{$SERVER_PATH}', service_path)
+ mw.writeFile(file_bin, content)
+ mw.execShell('chmod +x ' + file_bin)
+
+ # systemd
+ systemDir = mw.systemdCfgDir()
+ systemService = systemDir + '/' + getPluginName() + '.service'
+ if os.path.exists(systemDir) and not os.path.exists(systemService):
+ systemServiceTpl = getPluginDir() + '/init.d/' + getPluginName() + '.service.tpl'
+ service_path = mw.getServerDir()
+ se_content = mw.readFile(systemServiceTpl)
+ se_content = se_content.replace('{$SERVER_PATH}', service_path)
+ mw.writeFile(systemService, se_content)
+ mw.execShell('systemctl daemon-reload')
+
+ return file_bin
+
+
+def alistOp(method):
+ file = initDreplace()
+
+ current_os = mw.getOs()
+ if current_os == "darwin":
+ data = mw.execShell(file + ' ' + method)
+ if data[1] == '':
+ return 'ok'
+ return data[1]
+
+ if current_os.startswith("freebsd"):
+ data = mw.execShell('service ' + getPluginName() + ' ' + method)
+ if data[1] == '':
+ return 'ok'
+ return data[1]
+
+ data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
+ if data[1] == '':
+ return 'ok'
+ return data[1]
+
+
+def start():
+ return alistOp('start')
+
+
+def stop():
+ return alistOp('stop')
+
+
+def restart():
+ status = alistOp('restart')
+ return status
+
+
+def reload():
+ return alistOp('reload')
+
+
+def initdStatus():
+ current_os = mw.getOs()
+ if current_os == 'darwin':
+ return "Apple Computer does not support"
+
+ if current_os.startswith('freebsd'):
+ initd_bin = getInitDFile()
+ if os.path.exists(initd_bin):
+ return 'ok'
+
+ shell_cmd = 'systemctl status ' + \
+ getPluginName() + ' | grep loaded | grep "enabled;"'
+ data = mw.execShell(shell_cmd)
+ if data[0] == '':
+ return 'fail'
+ return 'ok'
+
+
+def initdInstall():
+ current_os = mw.getOs()
+ if current_os == 'darwin':
+ return "Apple Computer does not support"
+
+ # freebsd initd install
+ if current_os.startswith('freebsd'):
+ import shutil
+ source_bin = initDreplace()
+ initd_bin = getInitDFile()
+ shutil.copyfile(source_bin, initd_bin)
+ mw.execShell('chmod +x ' + initd_bin)
+ mw.execShell('sysrc ' + getPluginName() + '_enable="YES"')
+ return 'ok'
+
+ mw.execShell('systemctl enable ' + getPluginName())
+ return 'ok'
+
+
+def initdUinstall():
+ current_os = mw.getOs()
+ if current_os == 'darwin':
+ return "Apple Computer does not support"
+
+ if current_os.startswith('freebsd'):
+ initd_bin = getInitDFile()
+ os.remove(initd_bin)
+ mw.execShell('sysrc ' + getPluginName() + '_enable="NO"')
+ return 'ok'
+
+ mw.execShell('systemctl disable ' + getPluginName())
+ return 'ok'
+
+
+def runLog():
+ return getServerDir() + '/data/log/log.log'
+
+if __name__ == "__main__":
+ func = sys.argv[1]
+ if func == 'status':
+ print(status())
+ elif func == 'start':
+ print(start())
+ elif func == 'stop':
+ print(stop())
+ elif func == 'restart':
+ print(restart())
+ elif func == 'reload':
+ print(reload())
+ elif func == 'initd_status':
+ print(initdStatus())
+ elif func == 'initd_install':
+ print(initdInstall())
+ elif func == 'initd_uninstall':
+ print(initdUinstall())
+ elif func == 'conf':
+ print(getConf())
+ elif func == 'run_log':
+ print(runLog())
+ elif func == 'config_tpl':
+ print(configTpl())
+ elif func == 'read_config_tpl':
+ print(readConfigTpl())
+ else:
+ print('error')
diff --git a/plugins/alist/info.json b/plugins/alist/info.json
new file mode 100755
index 000000000..9a06ad35d
--- /dev/null
+++ b/plugins/alist/info.json
@@ -0,0 +1,17 @@
+{
+ "sort": 7,
+ "ps": "一个支持多种存储的文件列表程序",
+ "name": "alist",
+ "title": "Alist",
+ "shell": "install.sh",
+ "versions":["3.37.4"],
+ "tip": "soft",
+ "checks": "server/alist",
+ "path": "server/alist",
+ "display": 1,
+ "author": "alist",
+ "date": "2022-10-09",
+ "home": "https://alist.nn.ci",
+ "type": 0,
+ "pid": "5"
+}
diff --git a/plugins/alist/init.d/alist.service.tpl b/plugins/alist/init.d/alist.service.tpl
new file mode 100644
index 000000000..95ef9d1cd
--- /dev/null
+++ b/plugins/alist/init.d/alist.service.tpl
@@ -0,0 +1,12 @@
+[Unit]
+Description=A file list program that supports multiple storage
+After=network.target
+
+[Service]
+Type=forking
+ExecStart={$SERVER_PATH}/alist/alist server
+ExecReload=/bin/kill -USR2 $MAINPID
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/plugins/alist/init.d/alist.tpl b/plugins/alist/init.d/alist.tpl
new file mode 100644
index 000000000..ae3c86273
--- /dev/null
+++ b/plugins/alist/init.d/alist.tpl
@@ -0,0 +1,46 @@
+#!/bin/sh
+# chkconfig: 2345 55 25
+# description: alist Service
+
+### BEGIN INIT INFO
+# Provides: alist
+# Required-Start: $all
+# Required-Stop: $all
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: starts alist
+# Description: starts the MDW-Web
+### END INIT INFO
+
+# Simple alist init.d script conceived to work on Linux systems
+# as it does use of the /proc filesystem.
+
+app_start(){
+ echo "Starting alist server..."
+ cd {$SERVER_PATH}/alist
+ ./alist server >> {$SERVER_PATH}/alist/logs.pl 2>&1 &
+}
+
+app_stop(){
+ echo "dztasks stopped"
+ ps -ef| grep alist | grep -v grep | grep -v python | grep -v sh | awk '{print $2}'| xargs kill
+}
+
+
+case "$1" in
+ start)
+ app_start
+ ;;
+ stop)
+ app_stop
+ ;;
+ restart|reload)
+ app_stop
+ sleep 0.3
+ app_start
+ ;;
+ *)
+ echo "Please use start or stop as first argument"
+ ;;
+esac
+
diff --git a/plugins/alist/install.sh b/plugins/alist/install.sh
new file mode 100755
index 000000000..be75f6ac8
--- /dev/null
+++ b/plugins/alist/install.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
+export PATH
+
+curPath=`pwd`
+rootPath=$(dirname "$curPath")
+rootPath=$(dirname "$rootPath")
+serverPath=$(dirname "$rootPath")
+
+# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/alist && bash install.sh install 3.37.4
+
+install_tmp=${rootPath}/tmp/mw_install.pl
+VERSION=$2
+
+sysArch=`arch`
+sysName=`uname`
+
+ALIST_ARCH_NAME=amd64
+if [ "$sysArch" == "arm64" ];then
+ ALIST_ARCH_NAME=arm64
+elif [ "$sysArch" == "x86_64" ]; then
+ ALIST_ARCH_NAME=amd64
+elif [ "$sysArch" == "aarch64" ]; then
+ ALIST_ARCH_NAME=aarch64
+fi
+
+ALIST_NAME=linux
+if [ "$sysName" == "Darwin" ];then
+ ALIST_NAME=darwin
+fi
+
+Install_App()
+{
+ echo '正在安装脚本文件...'
+
+ mkdir -p $serverPath/source
+ mkdir -p $serverPath/source/alist
+
+ FILE_TGZ=alist-${ALIST_NAME}-${ALIST_ARCH_NAME}.tar.gz
+
+ ALIST_DIR=$serverPath/source/alist
+
+ if [ ! -f $ALIST_DIR/${FILE_TGZ} ];then
+ wget -O $ALIST_DIR/${FILE_TGZ} https://github.com/alist-org/alist/releases/download/v${VERSION}/${FILE_TGZ}
+ fi
+
+ mkdir -p $serverPath/alist
+
+ cd $ALIST_DIR && tar -zxvf ${FILE_TGZ} -C $serverPath/alist
+ echo "${VERSION}" > $serverPath/alist/version.pl
+
+ cd ${rootPath} && python3 ${rootPath}/plugins/alist/index.py start
+ cd ${rootPath} && python3 ${rootPath}/plugins/alist/index.py initd_install
+
+ echo '安装完成'
+}
+
+Uninstall_App()
+{
+ if [ -f /usr/lib/systemd/system/alist.service ];then
+ systemctl stop alist
+ systemctl disable alist
+ rm -rf /usr/lib/systemd/system/alist.service
+ systemctl daemon-reload
+ fi
+
+ if [ -f /lib/systemd/system/alist.service ];then
+ systemctl stop alist
+ systemctl disable alist
+ rm -rf /lib/systemd/system/alist.service
+ systemctl daemon-reload
+ fi
+
+ if [ -f $serverPath/alist/initd/alist ];then
+ $serverPath/alist/initd/alist stop
+ fi
+
+ if [ -d $serverPath/alist ];then
+ rm -rf $serverPath/alist
+ fi
+
+ echo "卸载alist成功"
+}
+
+action=$1
+if [ "${1}" == 'install' ];then
+ Install_App
+else
+ Uninstall_App
+fi
diff --git a/plugins/alist/js/alist.js b/plugins/alist/js/alist.js
new file mode 100755
index 000000000..e662a133d
--- /dev/null
+++ b/plugins/alist/js/alist.js
@@ -0,0 +1,71 @@
+function alistPost(method, version, args,callback){
+ var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
+
+ var req_data = {};
+ req_data['name'] = 'alist';
+ req_data['func'] = method;
+ req_data['version'] = version;
+
+ if (typeof(args) == 'string'){
+ req_data['args'] = JSON.stringify(toArrayObject(args));
+ } else {
+ req_data['args'] = JSON.stringify(args);
+ }
+
+ $.post('/plugins/run', req_data, function(data) {
+ layer.close(loadT);
+ if (!data.status){
+ //错误展示10S
+ layer.msg(data.msg,{icon:0,time:2000,shade: [10, '#000']});
+ return;
+ }
+
+ if(typeof(callback) == 'function'){
+ callback(data);
+ }
+ },'json');
+}
+
+function alistPostCallbak(method, version, args,callback){
+ var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
+
+ var req_data = {};
+ req_data['name'] = 'alist';
+ req_data['func'] = method;
+ args['version'] = version;
+
+ if (typeof(args) == 'string'){
+ req_data['args'] = JSON.stringify(toArrayObject(args));
+ } else {
+ req_data['args'] = JSON.stringify(args);
+ }
+
+ $.post('/plugins/callback', req_data, function(data) {
+ layer.close(loadT);
+ if (!data.status){
+ layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
+ return;
+ }
+
+ if(typeof(callback) == 'function'){
+ callback(data);
+ }
+ },'json');
+}
+
+
+function alistReadme(){
+ var cmd_01 = '/www/server/redis/bin/redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 --cluster-replicas 0';
+ var cmd_02 = '/www/server/redis/bin/redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 --cluster-replicas 1';
+
+
+ var readme = '';
+ readme += '- 集群创建1
';
+ readme += '- '+cmd_01+'
';
+ readme += '- 集群创建2
';
+ readme += '- '+cmd_02+'
';
+ readme += '
';
+
+ $('.soft-man-con').html(readme);
+}
+