更新3.1 优化 全网搜索模式

This commit is contained in:
admin
2025-04-18 15:48:16 +08:00
parent 126bdbc5ec
commit b5debce23c
56 changed files with 5670 additions and 343 deletions

View File

@@ -18,6 +18,14 @@
## 🚀 更新日志 ## 🚀 更新日志
### v3.1
- 🔍 优化 全网搜索模式:由直接展示转存结果,改为先显示第三方搜索结果,用户点击后再转存分享
- 🌐 全网搜索支持 夸克网盘 和 百度网盘
- 🔗 新增 全网搜转存模式:可选转链或直链展示
- 🕵️ 新增 全网搜的结果先进行资源有效性过滤(仅支持夸克)
- 💻 新增 PC端访问方式选择跳转/扫码)
- 🧱 重构视图结构将前后台的html及静态文件放至public/views
### v3.0 ### v3.0
- 🌟 **新增** 一键安装向导,简化部署流程 - 🌟 **新增** 一键安装向导,简化部署流程
- 🔗 **新增** 多网盘转存导入功能,支持 **夸克、阿里、百度、UC** - 🔗 **新增** 多网盘转存导入功能,支持 **夸克、阿里、百度、UC**

View File

@@ -95,21 +95,21 @@ class Chatbot extends QfShop
$is_times = 0; $is_times = 0;
if (!empty($list)) { if (!empty($list)) {
foreach ($list as $item) { foreach ($list as $item) {
$content = $content . "\n"; $content = $content . "\n \n";
if(!empty($item['is_time']) && $item['is_time'] == 1){ if(!empty($item['is_time']) && $item['is_time'] == 1){
$content = $content . "\n🌐️ " . $item['title'] . "\n<a href='" . $item['url'] . "'>" . $item['url'] . "</a>"; $content = $content . "\n🌐️ " . $item['title'] . "\n<a href='" . $item['url'] . "'>" . $item['url'] . "</a>";
$is_times++; $is_times++;
}else{ }else{
$content = $content . "\n" . $item['title'] . "\n<a href='" . $item['url'] . "'>" . $item['url'] . "</a>"; $content = $content . "\n" . $item['title'] . "\n<a href='" . $item['url'] . "'>" . $item['url'] . "</a>";
} }
} }
$content = $content . "\n"; $content = $content . "\n \n";
if($is_times>0){ if($is_times>0){
$content = $content . "\n🌐️ 资源来源网络30分钟后删除"; $content = $content . "🌐️ 资源来源网络30分钟后删除";
}else if(!empty($newString)){ }else if(!empty($newString)){
$content = $content . "\n 不是短剧?请尝试:<a href='weixin://bizmsgmenu?msgmenucontent=全网搜".$newString."&msgmenuid=全网搜".$newString."'>全网搜".$newString."</a>"; $content = $content . "不是短剧?请尝试:<a href='weixin://bizmsgmenu?msgmenucontent=全网搜".$newString."&msgmenuid=全网搜".$newString."'>全网搜".$newString."</a>";
} }
$content = $content . "\n ------------------------------------------------"; // $content = $content . "\n ------------------------------------------------";
$content = $content . "\n 欢迎观看!如果喜欢可以喊你的朋友一起来哦"; $content = $content . "\n 欢迎观看!如果喜欢可以喊你的朋友一起来哦";
} else { } else {
// 如果没有找到匹配的剧名,提示用户减少关键词尝试搜索 // 如果没有找到匹配的剧名,提示用户减少关键词尝试搜索
@@ -117,7 +117,6 @@ class Chatbot extends QfShop
$content = $content . "\n 未找到,可换个关键词尝试哦~"; $content = $content . "\n 未找到,可换个关键词尝试哦~";
$content = $content . "\n ⚠️宁少写,不多写、错写~"; $content = $content . "\n ⚠️宁少写,不多写、错写~";
} }
$this->sendMessage($msg, $content); $this->sendMessage($msg, $content);
} }

View File

@@ -16,6 +16,175 @@ class Other extends QfShop
parent::__construct($app); parent::__construct($app);
$this->model = new SourceModel(); $this->model = new SourceModel();
} }
public function search1()
{
$searchdata = input('');
if (empty($title)) {
if (empty($searchdata['title'])) {
return jerr("请输入名称");
}
$title = $searchdata['title'];
}
$apiType = $searchdata['num']??0;
$is_type = $searchdata['is_type']??0;
$searchList = []; // 查询的结果集
$num_total = 10; // 最多想要几条结果
$num_success = 0;
$sources = ['source1'];
// 遍历所有源
foreach ($sources as $source) {
if ($num_success >= $num_total) {
break; // 有效结果数量已达到
}
foreach ($source(Config('qfshop.is_quan_zc'),$title,$is_type,5,$apiType) as $value) {
if ($num_success >= $num_total) {
break; // 有效结果数量已达到
}
// 如果 URL 不存在则新增 $value
if (!$this->urlExists($searchList, $value['url'])) {
$searchList[] = $value;
$num_success++;
}
}
}
$searchList = array_map(function($value) {
$value['is_type'] = determineIsType($value['url']);
if(Config('qfshop.is_quan_type') != 1){
$value['url'] = encryptObject($value['url']);
}
return $value;
}, $searchList);
return jok('网盘资源均来源于互联网,资源内容与本站无关', $searchList);
}
public function search2()
{
$searchdata = input('');
if (empty($title)) {
if (empty($searchdata['title'])) {
return jerr("请输入名称");
}
$title = $searchdata['title'];
}
$is_type = $searchdata['is_type']??0;
$searchList = []; // 查询的结果集
$num_total = 10; // 最多想要几条结果
$num_success = 0;
// 定义源的顺序
$sources = ['source2'];
// 遍历所有源
foreach ($sources as $source) {
if ($num_success >= $num_total) {
break; // 有效结果数量已达到
}
foreach ($source(Config('qfshop.is_quan_zc'),$title,$is_type) as $value) {
if ($num_success >= $num_total) {
break; // 有效结果数量已达到
}
// 如果 URL 不存在则新增 $value
if (!$this->urlExists($searchList, $value['url'])) {
$searchList[] = $value;
$num_success++;
}
}
}
$searchList = array_map(function($value) {
$value['is_type'] = determineIsType($value['url']);
if(Config('qfshop.is_quan_type') != 1){
$value['url'] = encryptObject($value['url']);
}
return $value;
}, $searchList);
return jok('网盘资源均来源于互联网,资源内容与本站无关', $searchList);
}
/**
* 解密url并转存
* @return void
*/
public function save_url()
{
$value = [
'title' => input('title', ''),
'url' => urldecode(input('url', '')),
'stoken' => input('stoken', ''),
];
$value['url'] = decryptObject($value['url']);
if (empty($value['title']) || empty($value['url'])) {
return jerr("参数不对");
}
$map[] = ['status', '=', 1];
$map[] = ['is_delete', '=', 0];
$map[] = ['is_time', '=', 1];
$map[] = ['content', '=', $value['url']];
$url = $this->model->where($map)->field('source_id as id, title, url')->find();
if (!empty($url)) {
$this->model->where('source_id', $url['id'])->update(['update_time' => time()]);
unset($url['id']);
return jok('临时资源获取成功', $url);
}
//同一个搜索内容锁机
$keys = $value['url'].'ACAA';
if (Cache::has($keys)) {
// 检查缓存中是否已有结果
return jok('临时资源获取成功', Cache::get($keys));
}
// 检查是否有正在处理的请求
if (Cache::has($keys . '_processing')) {
// 如果当前正在处理相同关键词的请求,等待结果
$startTime = time(); // 记录开始时间
while (Cache::has($keys . '_processing')) {
usleep(1000000); // 暂停1秒
// 检查是否超过60秒
if (time() - $startTime > 60) {
return jok('临时资源获取成功', []);
}
}
return jok('临时资源获取成功', Cache::get($keys));
}
// 设置处理状态为正在处理
Cache::set($keys . '_processing', true, 60); // 锁定60秒
$datas = [];
$num_total = 1;
$num_success = 0;
$res = $this->processUrl($value, $num_success, $datas, true);
Cache::delete($keys . '_processing'); // 解锁
if($res['code'] !== 200){
return jerr($res['message']);
}else{
$result['title'] = $res['data']['title'];
$result['url'] = $res['data']['url'];
Cache::set($keys, $result, 60); // 缓存结果60秒
return jok('临时资源获取成功', $result);
}
}
/** /**
* 全网搜索 该接口仅用于微信自动回复 * 全网搜索 该接口仅用于微信自动回复
@@ -79,7 +248,7 @@ class Other extends QfShop
break; break;
} }
foreach ($source($title) as $value) { foreach ($source(true,$title) as $value) {
if ($num_success >= $num_total) { if ($num_success >= $num_total) {
break; break;
} }
@@ -96,46 +265,6 @@ class Other extends QfShop
return !empty($param) ? $datas : jok('临时资源获取成功', $datas); return !empty($param) ? $datas : jok('临时资源获取成功', $datas);
} }
/**
* 全网搜索 测试能不能拿到第三方数据
*
* @return void
*/
public function text_search($param='')
{
$title = $param ?: input('title', '');
if (empty($title)) {
return jerr("请输入要看的内容");
}
$searchList = []; //查询的结果集
$datas = []; //最终数据
$num_total = 20; //最多想要几条结果
$num_success = 0;
// 定义源的顺序
$sources = ['source1', 'source2'];
foreach ($sources as $source) {
if ($num_success >= $num_total) {
break;
}
foreach ($source($title) as $value) {
if ($num_success >= $num_total) {
break;
}
if (!$this->urlExists($searchList, $value['url'])) {
$searchList[] = $value;
$num_success++;
}
}
}
return jok('网盘资源均来源于互联网,资源内容与本站无关', $searchList);
}
// 检查 URL 是否已存在(忽略查询参数) // 检查 URL 是否已存在(忽略查询参数)
public function urlExists($searchList, $urlToCheck) { public function urlExists($searchList, $urlToCheck) {
@@ -161,17 +290,25 @@ class Other extends QfShop
* *
* @return void * @return void
*/ */
public function processUrl($value, &$num_success, &$datas) public function processUrl($value, &$num_success, &$datas, $type=false)
{ {
$substring = strstr($value['url'], 's/'); $substring = strstr($value['url'], 's/');
if ($substring === false) { if ($substring === false) {
return; // 模拟 continue 行为 if($type){
return jerr2("资源地址格式有误");
}else{
return; // 模拟 continue 行为
}
}
$code = '';
if (preg_match('/\?pwd=([^,\s&]+)/',$value['url'], $pwdMatch)) {
$code = trim($pwdMatch[1]);
} }
$pwd_id = substr($substring, 2); // 去除 's/' 部分
$urlData = array( $urlData = array(
'url' => $value['url'], 'url' => $value['url'],
'code' => $code,
'expired_type' => 2, 'expired_type' => 2,
'ad_fid' => '', //分享时带上这个文件 'ad_fid' => '', //分享时带上这个文件
); );
@@ -180,7 +317,11 @@ class Other extends QfShop
$res = $transfer->transfer($urlData); $res = $transfer->transfer($urlData);
if($res['code'] !== 200){ if($res['code'] !== 200){
return; // 模拟 continue 行为 if($type){
return jerr2($res['message']);
}else{
return; // 模拟 continue 行为
}
} }
$patterns = '/^\d+\./'; $patterns = '/^\d+\./';
@@ -189,6 +330,7 @@ class Other extends QfShop
$data["title"] =$title; $data["title"] =$title;
$data["url"] =$res['data']['share_url']; $data["url"] =$res['data']['share_url'];
$data["is_type"] = determineIsType($data["url"]); $data["is_type"] = determineIsType($data["url"]);
$data["content"] =$value['url'];
$dataFid = $res['data']['fid']??''; $dataFid = $res['data']['fid']??'';
$data["fid"] = is_array($dataFid) ? json_encode($dataFid) : $dataFid; $data["fid"] = is_array($dataFid) ? json_encode($dataFid) : $dataFid;
$data["is_time"] = 1; $data["is_time"] = 1;
@@ -197,6 +339,10 @@ class Other extends QfShop
$data["id"] = $this->model->insertGetId($data); $data["id"] = $this->model->insertGetId($data);
$datas[] =$data; $datas[] =$data;
$num_success++; $num_success++;
if($type){
return jok2('转存成功',$data);
}
} }

View File

@@ -886,15 +886,43 @@ function parsePanLinks($input)
return array_values($result); return array_values($result);
} }
/**
* 夸克线路一
* @return array
*/
function source1($isStoken=false,$title,$type=0,$num=5,$index=0)
{
return sourceData1($isStoken,$title,$type,$num,$index);
}
/**
* 夸克线路二
* @return array
*/
function source2($isStoken=false,$title,$type=0,$num=5)
{
return sourceData2($isStoken,$title,$type,$num);
}
/** /**
* 网络资源搜索源一 * 网络资源搜索源一
* @return array * @return array
*/ */
function source1($title) function sourceData1($isStoken=false,$title, $type = 0, $maxCount = 100, $apiType = 0)
{ {
$urlDefault = "https://m.kkkba.com"; //http://s.kkkob.com $urlDefault = "https://m.kkkba.com"; //http://s.kkkob.com
$url2 = []; $url2 = [];
// 定义匹配不同网盘的正则表达式
$pattern = [
0 => '/https:\/\/pan\.quark\.cn\/[^\s]*/', // 只匹配夸克
2 => '/https:\/\/pan\.baidu\.com\/[^\s]*/' // 只匹配百度
];
if (!isset($pattern[$type])) {
return [];
}
try { try {
$res = curlHelper($urlDefault."/v/api/getToken", "GET", null, [], "", "", 5)['body']; $res = curlHelper($urlDefault."/v/api/getToken", "GET", null, [], "", "", 5)['body'];
} catch (Exception $err ) { } catch (Exception $err ) {
@@ -906,66 +934,105 @@ function source1($title)
if(empty($token)){ if(empty($token)){
return $url2; return $url2;
} }
$urlData = array( $urlData = array(
'name' => $title, 'name' => $title,
'token' => $token 'token' => $token
); );
$urlHeader = array('Content-Type: application/json'); $urlHeader = array('Content-Type: application/json');
// 定义正则表达式模式
$pattern = '/https:\/\/pan\.quark\.cn\/[^\s]*/'; $allApiList = [
1 => "/v/api/getJuzi",
// 线路 API 列表 2 => "/v/api/search",
$apiList = [ 3 => "/v/api/getXiaoyu",
"/v/api/getJuzi", 4 => "/v/api/getDJ",
"/v/api/search", 5 => "/v/api/getKK"
"/v/api/getXiaoyu",
"/v/api/getDJ"
]; ];
// 根据 apiType 确定要调用的接口列表
if ($apiType == 0) {
// 全部接口
$apiList = array_values($allApiList);
} elseif (isset($allApiList[$apiType])) {
// 指定某个接口
$apiList = [$allApiList[$apiType]];
} else {
// 错误类型,直接返回空
return [];
}
foreach ($apiList as $api) { foreach ($apiList as $api) {
$res = curlHelper($urlDefault . $api, "POST", json_encode($urlData), $urlHeader)['body']; $res = curlHelper($urlDefault . $api, "POST", json_encode($urlData), $urlHeader, "", "", 5)['body'];
$res = json_decode($res, true); $res = json_decode($res, true);
if (!empty($res['list'] ?? [])) { if (!empty($res['list'] ?? [])) {
foreach ($res['list'] as $value) { foreach ($res['list'] as $value) {
if (preg_match($pattern, $value['answer'], $matches)) { if (preg_match($pattern[$type], $value['answer'], $matches)) {
$link = $matches[0]; $link = $matches[0];
$url2[] = [ if (preg_match('/提取码[:]?\s*([a-zA-Z0-9]{4})/', $value['answer'], $codeMatch)) {
'title' => preg_replace('/\s*[\(]?(夸克|百度)?[\)]?\s*/u', '', $value['question']), $link .= '?pwd=' . $codeMatch[1];
'url' => $link }
]; $titleText = preg_replace('/\s*[\(]?(夸克|百度)?[\)]?\s*/u', '', $value['question']);
if ($isStoken && $type == 0) {
$infoData = verificationUrl($link);
if (!empty($infoData['stoken'])) {
$url2[] = [
'title' => $titleText,
'url' => $link,
'stoken' => $infoData['stoken']
];
}
} else {
$url2[] = [
'title' => $titleText,
'url' => $link
];
}
if (count($url2) >= $maxCount) {
return $url2;
}
} }
} }
} }
} }
return $url2; return $url2;
} }
/** /**
* 网络资源搜索源二 * 网络资源搜索源二
* @return array * @return array
*/ */
function source2($title) function sourceData2($isStoken=false,$title, $type = 0, $maxCount = 100)
{ {
$url = 'https://www.pansearch.me/search?keyword='.urlencode($title).'&pan=quark'; // 根据类型选择搜索参数
$panType = [
0 => 'quark', // 夸克
2 => 'baidu' // 百度
];
if (!isset($panType[$type])) {
return [];
}
$results = [];
// 仅获取指定网盘的资源
$url = 'https://www.pansearch.me/search?keyword='.urlencode($title).'&pan='.$panType[$type];
$dom = getDom($url); $dom = getDom($url);
$finder = new DomXPath($dom); $finder = new DomXPath($dom);
// 使用 XPath 查询选择具有特定类名的元素 // XPath 选择 class 包含 "whitespace-pre-wrap break-all" 的 div
$nodes =$finder->query('//div[contains(concat(" ", normalize-space(@class), " "), " whitespace-pre-wrap ") and contains(concat(" ", normalize-space(@class), " "), " break-all ")]'); $nodes = $finder->query('//div[contains(concat(" ", normalize-space(@class), " "), " whitespace-pre-wrap ") and contains(concat(" ", normalize-space(@class), " "), " break-all ")]');
$results = [];
foreach ($nodes as $node) { foreach ($nodes as $node) {
// 获取元素的内容,包括其子元素
$content = $node->textContent; $content = $node->textContent;
// Initialize an associative array to store parsed data
$parsedItem = [ $parsedItem = [
'title' => '', 'title' => '',
'url' => '' 'url' => ''
]; ];
// Use regular expressions to extract the title and url // 提取资源名称
if (preg_match('/名称:(.*?)\n\n描述/s', $content, $titleMatch)) { if (preg_match('/名称:(.*?)\n\n描述/s', $content, $titleMatch)) {
$parsedItem['title'] = trim($titleMatch[1]); $parsedItem['title'] = trim($titleMatch[1]);
} else { } else {
@@ -973,25 +1040,79 @@ function source2($title)
} }
// 定义不同类型的链接匹配规则(百度网盘包含提取码) // 定义不同类型的链接匹配规则(百度网盘包含提取码)
$pattern = '/https:\/\/pan\.quark\.cn\/s\/[a-zA-Z0-9]+/'; // 夸克 $pattern = [
0 => '/https:\/\/pan\.quark\.cn\/s\/[a-zA-Z0-9]+/', // 夸克
2 => '/https:\/\/pan\.baidu\.com\/s\/[a-zA-Z0-9_-]+(\?pwd=[a-zA-Z0-9]+)?/' // 百度(包含提取码)
];
// 提取下载链接 // 提取下载链接
if (preg_match($pattern, $content, $urlMatch)) { if (preg_match($pattern[$type], $content, $urlMatch)) {
$parsedItem['url'] = trim($urlMatch[0]); $parsedItem['url'] = trim($urlMatch[0]);
} }
if ($parsedItem['title'] && $parsedItem['url']) { if ($parsedItem['title'] && $parsedItem['url']) {
// $results[] = $parsedItem; // 只有标题包含搜索关键字才加入结果
if (strpos($parsedItem['title'], $title) !== false || strpos($title, $parsedItem['title']) !== false) { if (strpos($parsedItem['title'], $title) !== false || strpos($title, $parsedItem['title']) !== false) {
$results[] = $parsedItem; if($isStoken && $type==0){
$infoData = verificationUrl($parsedItem['url']);
if(!empty($infoData['stoken'])){
$parsedItem['stoken'] = $infoData['stoken'];
$results[] = $parsedItem;
}
}else{
$results[] = $parsedItem;
}
} }
} }
if (count($results) >= 3) { // 如果已获取的条目达到限制数量,退出循环
break; if (count($results) >= $maxCount) {
return $results;
} }
} }
return $results; return $results;
} }
/**
* 验证夸克地址是否有效
* @return array
*/
function verificationUrl($url) {
$code = '';
if (preg_match('/\?pwd=([^,\s&]+)/', $url, $pwdMatch)) {
$code = trim($pwdMatch[1]);
}
$urlData = [
'url' => $url,
'code' => $code,
'isType' => 1
];
$transfer = new \netdisk\Transfer();
$res = $transfer->transfer($urlData);
if ($res['code'] !== 200) {
return 0;
}
return $res['data'];
}
function encryptObject($object) {
$jsonString = json_encode($object);
// 使用 AES 加密算法加密 JSON 字符串
$key = 'ABCD'; // 加密密钥
$encrypted = openssl_encrypt($jsonString, 'aes-256-cbc', $key, 0, '1234567890123456');
return $encrypted;
}
function decryptObject($encryptedObject) {
// 解密密钥
$key = 'ABCD';
// 解密加密后的对象字符串
$decryptedJson = openssl_decrypt($encryptedObject, 'aes-256-cbc', $key, 0, '1234567890123456');
// 将解密后的 JSON 字符串转换回对象
$object = json_decode($decryptedJson, true); // true 转换为关联数组
return $object;
}

View File

@@ -77,7 +77,7 @@ class Index extends QfShop
View::assign('seo_title', $config['app_name'].' - '.$config['app_title']); View::assign('seo_title', $config['app_name'].' - '.$config['app_title']);
View::assign('seo_keywords', $config['app_keywords']); View::assign('seo_keywords', $config['app_keywords']);
View::assign('seo_description', $config['app_description']); View::assign('seo_description', $config['app_description']);
return View::fetch('/news/index'); return View::fetch('/theme1/index');
} }

View File

@@ -1,199 +0,0 @@
{include file="common/header"}
</head>
<body>
<div class="headBg" style="background-image: url({$config.home_bg});"></div>
<div id="app" v-cloak>
{include file="common/head"}
<div class="searchBox searchList">
<div class="search">
<div class="select" @click="selectBtn">
{if condition="$category_id == ''"}全部{/if}
{foreach $category as $key=>$vo }
{if condition='$category_id == $vo.id'}{$vo.name}{/if}
{/foreach}
<i class="iconfont icon-xiala" style="font-size: 3vw"></i>
</div>
<input type="text" v-model="keyword" placeholder="输入关键字进行搜索" @keyup.enter="searchBtn" confirm-type="search" @confirm="searchBtn">
<div class="btn" @click="searchBtn">
<i class="iconfont icon-sousuo"></i>
</div>
</div>
</div>
<div class="listBox">
<div class="screen">
<div class="fixed">
<h3>筛选</h3>
<div class="box">
<a href="/s/{$keyword}.html" class="{eq name="category_id" value=""}active{/eq}">全部</a>
{foreach $category as $key=>$vo }
<a href="/s/{$keyword}-1-{$vo.id}.html" class="{if condition='$category_id == $vo.id'}active{/if}">{$vo.name}</a>
{/foreach}
</div>
</div>
</div>
<div class="left">
<h3 v-if="total_result>0">为您找到【<span>{$keyword}</span>】相关资源<span>&nbsp;{{total_result}}&nbsp;</span></h3>
<h3 v-else>为您找到【<span>{$keyword}</span>】相关资源<span>&nbsp;{$list.total_result}&nbsp;</span></h3>
{if condition="$config.is_quan == 1"}
<div class="Ebox" v-if="QStatus">
<div class="Qloading" v-if="QLoading">
<div class="loader"></div>
</div>
<div class="list">
<div class="item" v-for="(item,index) in QList" :key="index">
<a target="_blank" :href="item.url" class="title">
{{item.title}}
</a>
<div class="type time">30分钟后自动删除请及时保存</div>
<div class="type">
<span>来源:网络资源</span>
</div>
<div class="btns">
<div class="btn" @click.stop="copyText($event,item.title,item.url,'')"><i class="iconfont icon-fenxiang1"></i>复制分享</div>
<a :href="'/d/'+item.id+'.html'" class="btn"><i class="iconfont icon-fangwen"></i>查看详情</a>
<a target="_blank" :href="item.url" class="btn">
<img src="/static/index/images/0.png" class="icon" alt="立即访问" />
立即访问
</a>
</div>
</div>
</div>
<block v-if="!QLoading && QList.length==0">
<div class="Qtips" v-if="QStatus==1">
<p>未找到更多的资源~</p>
</div>
<el-empty v-else style="margin-top: 10%;padding-bottom: 10%;" :image-size="200" image="{$config.search_bg??''}" description="{$config.search_tips|default='未找到,可换个关键词尝试哦~'}"></el-empty>
</block>
</div>
{/if}
<div class="box" v-if="QStatus!=2">
{if condition="$list.total_result>0"}
{if condition="$config.is_quan == 1"}
<div class="Qbtn">
<div class="btn" onclick="getMore()">以下资源不是你想要的?点击尝试获取新资源</div>
</div>
{/if}
<div class="list">
{foreach $list.items as $key=>$vo }
<div class="item">
<a target="_blank" href="{$vo.url}" class="title">
{$vo.name|raw}
</a>
<!-- <div class="type cate">分类:{$vo.category.name|default='其它'}</div> -->
<div class="type time">{$vo.times}</div>
<div class="type">
{if condition="$vo.is_type==1"}
<span>来源:阿里云盘</span>
{elseif condition="$vo.is_type==2"/}
<span>来源:百度网盘</span>
{elseif condition="$vo.is_type==3"/}
<span>来源UC网盘</span>
{elseif condition="$vo.is_type==4"/}
<span>来源:迅雷网盘</span>
{else /}
<span>来源:夸克网盘</span>
{/if}
{notempty name="vo.code"}
<span>提取码:<span>{$vo.code}</span></span>
{/notempty}
</div>
<div class="btns">
<div class="btn" @click.stop="copyText($event,'{$vo.title|trim}','{$vo.url}','{$vo.code}')"><i class="iconfont icon-fenxiang1"></i>复制分享</div>
<a href="/d/{$vo.id}.html" class="btn"><i class="iconfont icon-fangwen"></i>查看详情</a>
<a target="_blank" href="{$vo.url}" class="btn">
<img src="/static/index/images/{$vo.is_type}.png" class="icon" alt="立即访问" />
立即访问
</a>
</div>
</div>
{/foreach}
</div>
<div class="page">
{notempty name="list.total_result"}
<el-pagination background layout="prev, pager, next" :pager-count="3" :default-current-page="{$page_no}" :default-page-size="{$page_size}" :total="{$list.total_result}" @change="changeBtn"></el-pagination>
{/notempty}
</div>
{else /}
<el-empty style="margin-top: 10%;" :image-size="200" image="{$config.search_bg??''}" description="{$config.search_tips|default='未找到,可换个关键词尝试哦~'}"></el-empty>
{/if}
</div>
</div>
<div class="right">
{volist name="hotList" id="vo"}
<div class="nav">
{notempty name="vo.image"}
<img src="{$vo.image}" alt="{$vo.name}">
{/notempty}
{$vo.name}
</div>
<div class="box">
<div class="list">
{volist name="vo.list" id="vos" length="5"}
<a href="/s/{$vos.title}.html" class="item">
<p>
<span>{$key+1}</span>
{$vos.title}
</p>
</a>
{/volist}
</div>
</div>
{/volist}
</div>
</div>
{include file="common/foot"}
</div>
{include file="common/footer"}
<script type="text/javascript" charset="utf-8">
app.rankList = JSON.parse('<?php echo json_encode($rankList, JSON_UNESCAPED_UNICODE); ?>');
for (const item of app.rankList) {
axios.get('/api/tool/ranking',{
params: {
channel: item.name
}
})
}
var status
if({$list.total_result} == 0){
if('{$config.is_quan}' == 1) {
//默认资源没有直接执行
status = 2
app.QStatus = status
getAll()
}
}
function getMore(){
if('{$config.is_quan}' == 1){
status = 1
app.QStatus = status
getAll()
}
}
function getAll() {
if(app.QStatus==0 || app.QLoading || '{$config.is_quan}' != 1) return
app.QLoading = true
axios.post('/api/tool/Qsearch',{
title: app.keyword
})
.then(function (res) {
app.QLoading = false
app.QStatus = status
app.QList = res.data.data
app.total_result = {$list.total_result} + app.QList.length
})
.catch(function (error) {
app.QLoading = false;
app.QStatus = status
app.QList = []
app.total_result = {$list.total_result} + app.QList.length
});
}
</script>
</body>
</html>

View File

@@ -9,7 +9,7 @@ return [
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法 // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
'auto_rule' => 1, 'auto_rule' => 1,
// 模板目录名 // 模板目录名
'view_dir_name' => 'view', 'view_dir_name' => 'public/views',
// 模板后缀 // 模板后缀
'view_suffix' => 'html', 'view_suffix' => 'html',
// 模板文件名分隔符 // 模板文件名分隔符
@@ -22,4 +22,7 @@ return [
'taglib_begin' => '{', 'taglib_begin' => '{',
// 标签库标签结束标记 // 标签库标签结束标记
'taglib_end' => '}', 'taglib_end' => '}',
'tpl_replace_string' => [
'__STATIC__' => '/views/index'
],
]; ];

View File

@@ -184,7 +184,8 @@ class BaiduPan extends BasePan
// 创建分享 // 创建分享
$expiry = 0; // 0为永久 $expiry = 0; // 0为永久
$password = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'), 0, 4); // 随机4位提取码 // $password = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'), 0, 4); // 随机4位提取码
$password = '6666'; // 随机4位提取码
$shareLink = $network->createShare(implode(',', $fsIdList), $expiry, $password); $shareLink = $network->createShare(implode(',', $fsIdList), $expiry, $password);
if (is_numeric($shareLink)) { if (is_numeric($shareLink)) {

View File

@@ -4,15 +4,15 @@ namespace netdisk\pan;
class BaiduWork class BaiduWork
{ {
protected $errorCodes = [ protected $errorCodes = [
-1 => '链接错误,链接失效或缺少提取码', -1 => '链接错误,链接失效或缺少提取码或访问频繁风控',
-4 => '无效登录。请退出账号在其他地方的登录', -4 => '无效登录。请退出账号在其他地方的登录',
-6 => '请用浏览器无痕模式获取 Cookie 后再试', -6 => '请用浏览器无痕模式获取 Cookie 后再试',
-7 => '转存失败,转存文件夹名有非法字符,不能包含 < > | * ? \\ :,请改正目录名后重试', -7 => '转存失败,转存文件夹名有非法字符,不能包含 < > | * ? \\ :,请改正目录名后重试',
-8 => '转存失败,目录中已有同名文件或文件夹存在', -8 => '转存失败,目录中已有同名文件或文件夹存在',
-9 => '链接错误,提取码错误', -9 => '链接不存在或提取码错误',
-10 => '转存失败,容量不足', -10 => '转存失败,容量不足',
-12 => '链接错误,提取码错误', -12 => '链接错误,提取码错误',
-62 => '转存失败,链接访问次数过多,请手动转存或稍后再试', -62 => '链接访问次数过多,请手动转存或稍后再试',
0 => '转存成功', 0 => '转存成功',
2 => '转存失败,目标目录不存在', 2 => '转存失败,目标目录不存在',
4 => '转存失败,目录中存在同名文件', 4 => '转存失败,目录中存在同名文件',

View File

@@ -59,6 +59,7 @@ class QuarkPan extends BasePan
if($this->isType == 1){ if($this->isType == 1){
$urls['title'] = $infoData['title']; $urls['title'] = $infoData['title'];
$urls['share_url'] = $this->url; $urls['share_url'] = $this->url;
$urls['stoken'] = $infoData['stoken'];
return jok2('检验成功', $urls); return jok2('检验成功', $urls);
} }
$stoken = $infoData['stoken']; $stoken = $infoData['stoken'];
@@ -183,8 +184,17 @@ class QuarkPan extends BasePan
'passcode' => '', 'passcode' => '',
'pwd_id' => $pwd_id, 'pwd_id' => $pwd_id,
); );
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/share/sharepage/token?pr=ucpro&fr=pc&uc_param_str=", "POST",json_encode($urlData), $this->urlHeader)['body']; $queryParams = [
return json_decode($res, true); 'pr' => 'ucpro',
'fr' => 'pc',
'uc_param_str' => '',
];
return $this->executeApiRequest(
"https://drive-pc.quark.cn/1/clouddrive/share/sharepage/token",
"POST",
$urlData,
$queryParams
);
} }
@@ -211,8 +221,12 @@ class QuarkPan extends BasePan
"_fetch_total" => "1", "_fetch_total" => "1",
"_sort" => "file_type:asc,updated_at:desc" "_sort" => "file_type:asc,updated_at:desc"
]; ];
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/share/sharepage/detail", "GET", json_encode($urlData), $this->urlHeader,$queryParams)['body']; return $this->executeApiRequest(
return json_decode($res, true); "https://drive-pc.quark.cn/1/clouddrive/share/sharepage/detail",
"GET",
$urlData,
$queryParams
);
} }
@@ -223,10 +237,15 @@ class QuarkPan extends BasePan
*/ */
public function getShareSave($pwd_id,$stoken,$fid_list,$fid_token_list) public function getShareSave($pwd_id,$stoken,$fid_list,$fid_token_list)
{ {
$to_pdir_fid = Config('qfshop.quark_file'); //默认存储路径 if(!empty($this->to_pdir_fid)){
if($this->expired_type == 2){ $to_pdir_fid = $this->to_pdir_fid;
$to_pdir_fid = Config('qfshop.quark_file_time'); //临时资源路径 }else{
$to_pdir_fid = Config('qfshop.quark_file'); //默认存储路径
if($this->expired_type == 2){
$to_pdir_fid = Config('qfshop.quark_file_time'); //临时资源路径
}
} }
$urlData = array( $urlData = array(
'fid_list' => $fid_list, 'fid_list' => $fid_list,
'fid_token_list' => $fid_token_list, 'fid_token_list' => $fid_token_list,
@@ -242,8 +261,13 @@ class QuarkPan extends BasePan
"fr" => "pc", "fr" => "pc",
"uc_param_str" => "" "uc_param_str" => ""
]; ];
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/share/sharepage/save", "POST", json_encode($urlData), $this->urlHeader,$queryParams)['body'];
return json_decode($res, true); return $this->executeApiRequest(
"https://drive-pc.quark.cn/1/clouddrive/share/sharepage/save",
"POST",
$urlData,
$queryParams
);
} }
/** /**
@@ -267,8 +291,13 @@ class QuarkPan extends BasePan
"fr" => "pc", "fr" => "pc",
"uc_param_str" => "" "uc_param_str" => ""
]; ];
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/share", "POST", json_encode($urlData), $this->urlHeader,$queryParams)['body'];
return json_decode($res, true); return $this->executeApiRequest(
"https://drive-pc.quark.cn/1/clouddrive/share",
"POST",
$urlData,
$queryParams
);
} }
@@ -287,8 +316,12 @@ class QuarkPan extends BasePan
"task_id" => $task_id, "task_id" => $task_id,
"retry_index" => $retry_index "retry_index" => $retry_index
]; ];
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/task", "GET", json_encode($urlData), $this->urlHeader, $queryParams)['body']; return $this->executeApiRequest(
return json_decode($res, true); "https://drive-pc.quark.cn/1/clouddrive/task",
"GET",
$urlData,
$queryParams
);
} }
/** /**
@@ -306,8 +339,12 @@ class QuarkPan extends BasePan
"fr" => "pc", "fr" => "pc",
"uc_param_str" => "" "uc_param_str" => ""
]; ];
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/share/password", "POST", json_encode($urlData), $this->urlHeader,$queryParams)['body']; return $this->executeApiRequest(
return json_decode($res, true); "https://drive-pc.quark.cn/1/clouddrive/share/password",
"POST",
$urlData,
$queryParams
);
} }
@@ -328,8 +365,12 @@ class QuarkPan extends BasePan
"fr" => "pc", "fr" => "pc",
"uc_param_str" => "" "uc_param_str" => ""
]; ];
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/file/delete", "POST", json_encode($urlData), $this->urlHeader,$queryParams)['body']; return $this->executeApiRequest(
return json_decode($res, true); "https://drive-pc.quark.cn/1/clouddrive/file/delete",
"POST",
$urlData,
$queryParams
);
} }
/** /**
@@ -351,11 +392,58 @@ class QuarkPan extends BasePan
'_fetch_sub_dirs' => 0, '_fetch_sub_dirs' => 0,
'_sort' => 'file_type:asc,updated_at:desc', '_sort' => 'file_type:asc,updated_at:desc',
]; ];
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/file/sort", "GET", json_encode($urlData), $this->urlHeader,$queryParams)['body']; try {
$res = json_decode($res, true); $res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/file/sort", "GET", json_encode($urlData), $this->urlHeader,$queryParams)['body'];
if($res['status'] !== 200){ $res = json_decode($res, true);
if($res['status'] !== 200){
return [];
}
return $res['data']['list'];
} catch (\Throwable $e) {
return []; return [];
} }
return $res['data']['list']; }
/**
* 执行API请求并处理重试逻辑
*
* @param string $url 请求URL
* @param string $method 请求方法(GET/POST)
* @param array $data 请求数据
* @param array $queryParams 查询参数
* @param int $maxRetries 最大重试次数
* @param int $retryDelay 重试延迟(秒)
* @return array 响应结果
*/
protected function executeApiRequest($url, $method, $data = [], $queryParams = [], $maxRetries = 3, $retryDelay = 2)
{
$attempt = 0;
while ($attempt < $maxRetries) {
$attempt++;
try {
$res = curlHelper($url, $method, json_encode($data), $this->urlHeader, $queryParams)['body'];
return json_decode($res, true);
} catch (\Throwable $e) {
$this->logApiError($url, $attempt, $e->getMessage());
if ($attempt < $maxRetries) {
sleep($retryDelay);
}
}
}
return ['status' => 500, 'message' => '接口请求异常'];
}
/**
* 记录API错误日志
*
* @param string $prefix 日志前缀
* @param int $attempt 尝试次数
* @param mixed $error 错误信息
*/
protected function logApiError($prefix, $attempt, $error)
{
$errorMsg = is_scalar($error) ? $error : json_encode($error);
$logMessage = date('Y-m-d H:i:s') . ' ' . $prefix . '请求失败(尝试次数: ' . $attempt . ' 错误: ' . $errorMsg . "\n";
file_put_contents('error.log', $logMessage, FILE_APPEND);
} }
} }

View File

@@ -0,0 +1,8 @@
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

View File

@@ -169,6 +169,10 @@ INSERT INTO `qf_conf` VALUES ('63', 'xunlei_cookie', '', '迅雷Cookie', '', '0'
INSERT INTO `qf_conf` VALUES ('64', 'xunlei_file', '', '迅雷默认转存目录', '', '0', '0', NULL, '4', '1', '58', '1', '1743149819', '1743149819'); INSERT INTO `qf_conf` VALUES ('64', 'xunlei_file', '', '迅雷默认转存目录', '', '0', '0', NULL, '4', '1', '58', '1', '1743149819', '1743149819');
INSERT INTO `qf_conf` VALUES ('65', 'xunlei_file_time', '', '迅雷临时资源目录', '', '0', '0', NULL, '4', '1', '57', '1', '1743149860', '1743149860'); INSERT INTO `qf_conf` VALUES ('65', 'xunlei_file_time', '', '迅雷临时资源目录', '', '0', '0', NULL, '4', '1', '57', '1', '1743149860', '1743149860');
INSERT INTO `qf_conf` VALUES ('66', 'api_key', '', '接口api_key', '个别接口需要此参数方可调用', '0', '0', NULL, '1', '1', '0', '1', '1743154753', '1743154753'); INSERT INTO `qf_conf` VALUES ('66', 'api_key', '', '接口api_key', '个别接口需要此参数方可调用', '0', '0', NULL, '1', '1', '0', '1', '1743154753', '1743154753');
INSERT INTO `qf_conf` VALUES ('67', 'pc_type', '0', 'PC端访问方式', '跳转:直接通过链接访问;扫码:提示用户用手机扫码访问', '0', '2', '跳转+扫码=>0\n仅跳转=>1\n仅扫码=>2', '3', '1', '90', '1', '1744861402', '1744861423');
INSERT INTO `qf_conf` VALUES ('68', 'is_quan_type', '0', '全网搜模式', '第三方直链: 直接展示第三方接口的资源', '0', '2', '转存分享=>0\n第三方直链=>1', '1', '1', '1', '1', '1744882575', '1744882612');
INSERT INTO `qf_conf` VALUES ('69', 'is_quan_zc', '1', '检测资源', '开启后全网搜将会过滤失效的资源;仅支持夸克', '0', '2', '开启=>1\n关闭=>0', '1', '1', '1', '1', '1744882765', '1744882765');

View File

@@ -1,6 +1,7 @@
<script src="/static/index/js/vue.global.min.js"></script> <script src="__STATIC__/news/common/static/js/vue.global.min.js"></script>
<script src="/static/index/js/index.full.min.js"></script> <script src="__STATIC__/news/common/static/js/index.full.min.js"></script>
<script src="/static/index/js/axios.min.js"></script> <script src="__STATIC__/news/common/static/js/axios.min.js"></script>
<script src="__STATIC__/news/common/static/js/qrcanvas@3.js"></script>
<script> <script>
const { createApp, ref, onMounted, onUnmounted } = Vue; const { createApp, ref, onMounted, onUnmounted } = Vue;
const { ElButton, ElMessage } = ElementPlus; const { ElButton, ElMessage } = ElementPlus;
@@ -19,10 +20,15 @@
const rankDj = ref([]); const rankDj = ref([]);
const is_m = ref(0); const is_m = ref(0);
const newList = ref([]); const newList = ref([]);
const QStatus = ref(0);
const QList = ref([]); const QList = ref([]);
const QLoading = ref(false); const QLoading = ref(false);
const total_result = ref(0); const total_result = ref(0);
const currentSource = ref(0);
const dialogUrl = ref(false);
const dialogLoading = ref(false);
const dialogItem = ref({});
const is_type = ref(0);
const pc_type = ref(0);
// 公共消息方法 // 公共消息方法
@@ -102,7 +108,7 @@
event.preventDefault(); event.preventDefault();
var text = '标题:'+title+'\n链接'+url var text = '标题:'+title+'\n链接'+url
if (code) text += `\n提取码${code}`; if (code) text += `\n提取码${code}`;
text += `\n由【${'{$config.app_name}'}${window.location.hostname}】供网盘分享链接`; text += `\n由【${'{$config.app_name}'}${window.location.hostname}】供网盘分享链接`;
try { try {
@@ -135,12 +141,13 @@
} }
const selectBtn = () => { const selectBtn = () => {
if(!is_m.value) return;
const boxElement = document.querySelector('.listBox .screen .fixed .box'); const boxElement = document.querySelector('.listBox .screen .fixed .box');
// 切换 display 属性,显示或隐藏 // 切换 display 属性,显示或隐藏
if (boxElement.style.display === 'none' || boxElement.style.display === '') { if (boxElement.style.display === 'none' || boxElement.style.display === '') {
boxElement.style.display = 'block'; // 显示 boxElement.style.display = 'block'; // 显示
} else { } else {
boxElement.style.display = 'none'; // 隐藏 boxElement.style.display = ''; // 隐藏
} }
} }
@@ -149,9 +156,11 @@
if (isMobile) { if (isMobile) {
// 手机端的逻辑 // 手机端的逻辑
is_m.value = 1 is_m.value = 1
pc_type.value = 1
} else { } else {
// 电脑端的逻辑 // 电脑端的逻辑
is_m.value = 0 is_m.value = 0
pc_type.value = '{$config.pc_type}';
} }
}; };
@@ -171,7 +180,7 @@
}); });
// 返回数据和方法 // 返回数据和方法
return { elementOpacity, scrollThreshold, keyword, searchBtn, rankList,newList, setnum, qcodeVisible, layerVisible, content, saveBtn, rankDj,goLink,changeBtn,copyText,drawer,selectBtn,is_m,QList,QLoading,QStatus,total_result }; return { elementOpacity, scrollThreshold, keyword, searchBtn, rankList,newList, setnum, qcodeVisible, layerVisible, content, saveBtn, rankDj,goLink,changeBtn,copyText,drawer,selectBtn,is_m,QList,QLoading,total_result,currentSource,dialogUrl,dialogLoading,dialogItem,is_type,pc_type };
} }
}) })
.use(ElementPlus) // 使用 Element Plus .use(ElementPlus) // 使用 Element Plus

View File

@@ -54,6 +54,7 @@
<div class="vbtn" @click="saveBtn">提交</div> <div class="vbtn" @click="saveBtn">提交</div>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog <el-dialog
v-model="drawer" v-model="drawer"
width="300" width="300"
@@ -68,4 +69,35 @@
{/empty} {/empty}
<div class="btns" v-html="`{$config.app_links}`"></div> <div class="btns" v-html="`{$config.app_links}`"></div>
</div> </div>
</el-dialog>
<el-dialog title="" v-model="dialogUrl" class="dialogUrlBox" :close-on-click-modal="false">
<div v-loading="dialogLoading" class="dialogUrl" v-if="dialogUrl">
<div v-if="dialogItem.showUrl">
<block v-show="pc_type!=1">
<div class="title">请使用 <span>夸克APP</span> 扫码获取</div>
<div class="tips">打开夸克APP- 点击搜索框中的相机 - 点击扫码</div>
<div class="qrcode" id="qrcode"></div>
</block>
<div class="nav">
<div class="item">
<span class="t">{{dialogItem.title}}</span>
</div>
<div class="item" v-show="pc_type!=2">
<span>资源地址:</span>
<a :href="dialogItem.showUrl" target="_blank">{{dialogItem.showUrl}}</a>
</div>
</div>
</div>
<div v-else-if="!dialogLoading">
<div class="title">获取失败</div>
<div class="tips" style="color: #FF3F3D;">{{dialogItem.message}}</div>
</div>
<div class="statement">
<div class="content">
<p>🔔 声明:本站链接均由程序自动收集自公开网盘,不存储、不传播任何文件,跳转链接指向网盘官网。</p>
<p>文件内容请自行辨别,如发现违规请向网盘平台举报。本站仅供学习交流,无任何收费行为。</p>
</div>
</div>
</div>
</el-dialog> </el-dialog>

View File

@@ -10,9 +10,10 @@
<title>{$seo_title}</title> <title>{$seo_title}</title>
<meta name="keywords" content="{$seo_keywords}" /> <meta name="keywords" content="{$seo_keywords}" />
<meta name="description" content="{$seo_description}" /> <meta name="description" content="{$seo_description}" />
<link rel="stylesheet" href="/static/index/css/index.min.css"> <meta name="referrer" content="no-referrer">
<link rel="stylesheet" href="/static/index/css/app.css"> <link rel="stylesheet" href="__STATIC__/news/common/static/css/index.min.css">
<link rel="stylesheet" href="/static/index/css/m.css"> <link rel="stylesheet" href="__STATIC__/news/common/static/css/app.css">
<link rel="stylesheet" href="__STATIC__/news/common/static/css/m.css">
{$config.seo_statistics|raw} {$config.seo_statistics|raw}

View File

@@ -835,6 +835,148 @@ a:hover {
} }
/*全网搜线路切换*/
.source-switch {
display: flex;
align-items: center;
white-space: nowrap;
overflow-x: auto;
}
.source-switch h3{
margin-right: 6px;
}
.switch-items {
display: flex;
gap: 18px;
padding-top: 16px;
}
.switch-items a {
position: relative;
padding: 5px 0;
text-decoration: none;
transition: all 0.3s;
}
.switch-items a:hover {
color: var(--theme-theme);
}
.switch-items a.active {
color: var(--theme-theme);
font-weight: bold;
}
.switch-items a.active:after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
width: 20px;
height: 4px;
margin: auto;
border-radius: 4px;
background-color: var(--theme-theme);
}
.vtips{
font-size: 14px;
color: #999;
padding: 10px 0 0;
}
.vtips a{
font-weight: bold;
color: var(--theme-theme);
}
.btns2{
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
height: 30px;
line-height: 30px;
color: var(--theme-other_background);
background-color: var(--theme-theme);
font-size: 14px;
width: 100px;
cursor: pointer;
position: absolute;
bottom: 15px;
right: 0;
}
.dialogUrlBox{
width: 450px;
border-radius: 18px;
}
.dialogUrlBox .dialogUrl{
min-height: 100px;
}
.dialogUrlBox .dialogUrl .title {
font-size: 20px;
font-weight: bold;
text-align: center;
color: #000;
}
.dialogUrlBox .dialogUrl .title span {
color: var(--theme-theme);
}
.dialogUrlBox .dialogUrl .tips {
margin-top: 12px;
color: #666;
font-size: 14px;
text-align: center;
}
.dialogUrlBox .dialogUrl .qrcode {
margin: 24px auto 0;
width: 200px;
height: 200px;
border: 1.5px solid #e5e6e8;
border-radius: 4px;
}
.dialogUrlBox .dialogUrl .qrcode canvas{
width: 100%;
height: 100%;
padding: 10px;
}
.dialogUrlBox .dialogUrl .nav{
margin-top: 15px;
font-size: 15px;
}
.dialogUrlBox .dialogUrl .nav .item{
color: #333;
text-align: center;
margin-top: 5px;
}
.dialogUrlBox .dialogUrl .nav .item .t {
font-weight: 600;
}
.dialogUrlBox .dialogUrl .nav .item a {
color: var(--theme-theme);
}
.dialogUrlBox .dialogUrl .statement {
margin-top: 24px;
padding-top: 15px;
text-align: left;
font-size: 14px;
border-top: 1px dashed #e6e6e6;
}
.dialogUrlBox .dialogUrl .statement .content {
margin-bottom: 8px;
color: #666;
line-height: 1.6;
}
.dialogUrlBox .dialogUrl .statement .content p{
text-align: justify;
margin-top: 5px;
}
.dialogUrlBox .el-icon{
font-size: 20px;
}
@font-face { @font-face {

View File

@@ -329,6 +329,26 @@
} }
.switch-items {
gap: 4.2vw;
padding-top: 20vw;
}
.switch-items a {
font-size: 3.8vw;
}
.btns2 {
height: 8.2vw;
line-height: 8.2vw;
font-size: 3.4vw;
width: 25vw;
bottom: 4vw;
}
.listBox .left .Ebox .list .item:last-child .btns2{
bottom: 0;
}
.dialogUrlBox{
width: 90vw;
}
} }

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +1,9 @@
{include file="common/header"} {include file="news/common/header"}
</head> </head>
<body> <body>
<div class="headBg" style="background-image: url({$config.home_bg});"></div> <div class="headBg" style="background-image: url({$config.home_bg});"></div>
<div id="app" v-cloak> <div id="app" v-cloak>
{include file="common/head"} {include file="news/common/head"}
<div class="searchBox searchDetail"> <div class="searchBox searchDetail">
<div class="search"> <div class="search">
<input type="text" v-model="keyword" placeholder="输入关键字进行搜索" @keyup.enter="searchBtn" confirm-type="search" @confirm="searchBtn"> <input type="text" v-model="keyword" placeholder="输入关键字进行搜索" @keyup.enter="searchBtn" confirm-type="search" @confirm="searchBtn">
@@ -49,7 +49,7 @@
<div class="cat"> <div class="cat">
<div class="l">资源类型</div> <div class="l">资源类型</div>
<div class="r"> <div class="r">
<img src="/static/index/images/{$detail.is_type}.png" class="icon" alt="网盘图标" /> <img src="__STATIC__/news/common/static/images/{$detail.is_type}.png" class="icon" alt="网盘图标" />
{if condition="$detail.is_type==1"} {if condition="$detail.is_type==1"}
<span>阿里云盘</span> <span>阿里云盘</span>
{elseif condition="$detail.is_type==2"/} {elseif condition="$detail.is_type==2"/}
@@ -63,10 +63,10 @@
{/if} {/if}
</div> </div>
</div> </div>
<div class="cat"> <div class="cat" v-show="pc_type!=2">
<div class="l">资源地址</div> <div class="l">资源地址</div>
<div class="r"> <div class="r">
<a href="{$detail.url}" target="_blank">{$detail.url}</a> <a href="javascript:;" onclick="linkBtn()" class="btn">{$detail.url}</a>
</div> </div>
</div> </div>
{notempty name="detail.code"} {notempty name="detail.code"}
@@ -76,8 +76,8 @@
</div> </div>
{/notempty} {/notempty}
<div class="btns"> <div class="btns">
<div class="btn btnCol" @click.stop="copyText($event,'{$detail.title|trim}','{$detail.url}','{$detail.code}')"><i class="iconfont icon-fenxiang1"></i>复制分享</div> <div class="btn" @click.stop="copyText($event,'{$detail.title|trim}','{$detail.url}','{$detail.code}')"><i class="iconfont icon-fenxiang1"></i>复制分享</div>
<a href="{$detail.url}" target="_blank" class="btn"><i class="iconfont icon-yun_o"></i>立即访问</a> <a class="btn btnCol" href="javascript:;" onclick="linkBtn()"><i class="iconfont icon-yun_o"></i>立即访问</a>
</div> </div>
</div> </div>
<h3 class="samelistNav">相关资源</h3> <h3 class="samelistNav">相关资源</h3>
@@ -117,9 +117,9 @@
{/volist} {/volist}
</div> </div>
</div> </div>
{include file="common/foot"} {include file="news/common/foot"}
</div> </div>
{include file="common/footer"} {include file="news/common/footer"}
<script type="text/javascript" charset="utf-8"> <script type="text/javascript" charset="utf-8">
app.rankList = JSON.parse('<?php echo json_encode($rankList, JSON_UNESCAPED_UNICODE); ?>'); app.rankList = JSON.parse('<?php echo json_encode($rankList, JSON_UNESCAPED_UNICODE); ?>');
for (const item of app.rankList) { for (const item of app.rankList) {
@@ -129,6 +129,30 @@
} }
}) })
} }
function linkBtn() {
var item = JSON.parse('<?php echo json_encode($detail, JSON_UNESCAPED_UNICODE); ?>');
if(app.pc_type == 1){
window.open(item.url);
}else{
item.showUrl = item.url
app.dialogUrl = true;
showUrlFun(item);
}
}
function showUrlFun(item) {
app.dialogItem = item
if(item.showUrl) {
var canvas = qrcanvas.qrcanvas({
data: item.showUrl,
size: 120
});
setTimeout(() => {
document.getElementById('qrcode').appendChild(canvas);
}, 200);
}
}
</script> </script>
</body> </body>
</html> </html>

View File

@@ -1,10 +1,10 @@
{include file="common/header"} {include file="news/common/header"}
<meta name="referrer" content="never"> <meta name="referrer" content="never">
</head> </head>
<body> <body>
<div class="headBg" style="background-image: url({$config.home_bg});"></div> <div class="headBg" style="background-image: url({$config.home_bg});"></div>
<div id="app" v-cloak> <div id="app" v-cloak>
{include file="common/head"} {include file="news/common/head"}
<div class="homeBox searchBox"> <div class="homeBox searchBox">
<div class="box"> <div class="box">
<div class="logoBox"> <div class="logoBox">
@@ -113,9 +113,9 @@
</div> </div>
</div> </div>
{include file="common/foot"} {include file="news/common/foot"}
</div> </div>
{include file="common/footer"} {include file="news/common/footer"}
<script type="text/javascript" charset="utf-8"> <script type="text/javascript" charset="utf-8">
app.rankList = JSON.parse('<?php echo json_encode($rankList, JSON_UNESCAPED_UNICODE); ?>'); app.rankList = JSON.parse('<?php echo json_encode($rankList, JSON_UNESCAPED_UNICODE); ?>');
for (const item of app.rankList) { for (const item of app.rankList) {

View File

@@ -0,0 +1,295 @@
{include file="news/common/header"}
</head>
<body>
<div class="headBg" style="background-image: url({$config.home_bg});"></div>
<div id="app" v-cloak>
{include file="news/common/head"}
<div class="searchBox searchList">
<div class="search">
<div class="select" @click="selectBtn" v-if="currentSource === 1">
<span>{{is_type==2?'百度':'夸克'}}</span>
<i class="iconfont icon-xiala" style="font-size: 3vw"></i>
</div>
<div class="select" @click="selectBtn" v-else>
{if condition="$category_id == ''"}全部{/if}
{foreach $category as $key=>$vo }
{if condition='$category_id == $vo.id'}{$vo.name}{/if}
{/foreach}
<i class="iconfont icon-xiala" style="font-size: 3vw"></i>
</div>
<input type="text" v-model="keyword" placeholder="输入关键字进行搜索" @keyup.enter="searchBtn" confirm-type="search" @confirm="searchBtn">
<div class="btn" @click="searchBtn">
<i class="iconfont icon-sousuo"></i>
</div>
</div>
</div>
<div class="listBox">
<div class="screen">
<div class="fixed">
<h3>筛选</h3>
<div class="box" v-if="currentSource === 1">
<a href="javascript:;" :class="{active: is_type==0}" onclick="setType(0)">夸克网盘</a>
<a href="javascript:;" :class="{active: is_type==2}" onclick="setType(2)">百度网盘</a>
</div>
<div class="box" v-else>
<a href="/s/{$keyword}.html" class="{eq name="category_id" value=""}active{/eq}">全部</a>
{foreach $category as $key=>$vo }
<a href="/s/{$keyword}-1-{$vo.id}.html" class="{if condition='$category_id == $vo.id'}active{/if}">{$vo.name}</a>
{/foreach}
</div>
</div>
</div>
<div class="left">
{if condition="$config.is_quan == 1"}
<div class="source-switch">
<h3>切换搜索源:</h3>
<div class="switch-items">
<a href="javascript:;" onclick="switchSource(0)" :class="{active: currentSource==0}">本地搜</a>
<a href="javascript:;" onclick="switchSource(1)" :class="{active: currentSource==1}">全网搜</a>
</div>
</div>
{else /}
<h3 v-if="total_result>0">为您找到【<span>{$keyword}</span>】相关资源<span>&nbsp;{{total_result}}&nbsp;</span></h3>
<h3 v-else>为您找到【<span>{$keyword}</span>】相关资源<span>&nbsp;{$list.total_result}&nbsp;</span></h3>
{/if}
<div class="box" v-show="currentSource === 0">
{if condition="$list.total_result>0"}
{if condition="$config.is_quan == 1"}
<div class="Qbtn">
<div class="btn">
<p v-if="total_result>0">为您找到【<span>{$keyword}</span>】相关资源<span>&nbsp;{{total_result}}&nbsp;</span></p>
<p v-else>为您找到【<span>{$keyword}</span>】相关资源<span>&nbsp;{$list.total_result}&nbsp;</span></p>
</div>
</div>
{/if}
<div class="list">
{foreach $list.items as $key=>$vo }
<div class="item">
<a href="javascript:;" onclick="linkBtn(this)" data-index="{$key}" class="title">
{$vo.name|raw}
</a>
<!-- <div class="type cate">分类:{$vo.category.name|default='其它'}</div> -->
<div class="type time">{$vo.times}</div>
<div class="type">
{if condition="$vo.is_type==1"}
<span>来源:阿里云盘</span>
{elseif condition="$vo.is_type==2"/}
<span>来源:百度网盘</span>
{elseif condition="$vo.is_type==3"/}
<span>来源UC网盘</span>
{elseif condition="$vo.is_type==4"/}
<span>来源:迅雷网盘</span>
{else /}
<span>来源:夸克网盘</span>
{/if}
{notempty name="vo.code"}
<span>提取码:<span>{$vo.code}</span></span>
{/notempty}
</div>
<div class="btns">
<div class="btn" @click.stop="copyText($event,'{$vo.title|trim}','{$vo.url}','{$vo.code}')"><i class="iconfont icon-fenxiang1"></i>复制分享</div>
<a href="/d/{$vo.id}.html" class="btn"><i class="iconfont icon-fangwen"></i>查看详情</a>
<a href="javascript:;" onclick="linkBtn(this)" data-index="{$key}" class="btn">
<img src="__STATIC__/news/common/static/images/{$vo.is_type}.png" class="icon" alt="立即访问" />
立即访问
</a>
</div>
</div>
{/foreach}
</div>
<div class="page">
{notempty name="list.total_result"}
<el-pagination background layout="prev, pager, next" :pager-count="3" :default-current-page="{$page_no}" :default-page-size="{$page_size}" :total="{$list.total_result}" @change="changeBtn"></el-pagination>
{/notempty}
</div>
{else /}
<el-empty style="margin-top: 10%;" :image-size="200" image="{$config.search_bg??''}" description="{$config.search_tips|default='未找到,可换个关键词尝试哦~'}">
{if condition="$config.is_quan == 1"}
<div class="vtips" onclick="switchSource(1)">请尝试切换&nbsp;<a href="javascript:;">全网搜</a>&nbsp;获取资源</div>
{/if}
</el-empty>
{/if}
</div>
<div class="Ebox" v-show="currentSource === 1">
<div class="Qloading" v-if="QLoading">
<div class="loader"></div>
</div>
<div class="Qbtn">
<div class="btn">
<p>为您找到【<span>{$keyword}</span>】相关资源<span>&nbsp;{{QList.length}}&nbsp;</span></p>
</div>
</div>
<div class="list">
<div class="item" v-for="(item,index) in QList" :key="index">
<a href="javascript:;" onclick="getUrlBtn(this)" :data-index="index" class="title">
{{item.title}}
</a>
<div class="type">
<span v-if="item.is_type==1">来源:阿里云盘</span>
<span v-else-if="item.is_type==2">来源:百度网盘</span>
<span v-else-if="item.is_type==3">来源UC网盘</span>
<span v-else-if="item.is_type==4">来源:迅雷网盘</span>
<span v-else>来源:夸克网盘</span>
</div>
<div class="btns2" onclick="getUrlBtn(this)" :data-index="index">
获取资源
</div>
</div>
</div>
<block v-if="!QLoading && QList.length==0">
<el-empty style="margin-top: 10%;" :image-size="200" image="{$config.search_bg??''}" description="{$config.search_tips|default='未找到,可换个关键词尝试哦~'}">
{if condition="$config.is_quan == 1"}
<div class="vtips" onclick="switchSource(0)">请尝试切换&nbsp;<a href="javascript:;">本地搜</a>&nbsp;获取资源</div>
{/if}
</el-empty>
</block>
</div>
</div>
<div class="right">
{volist name="hotList" id="vo"}
<div class="nav">
{notempty name="vo.image"}
<img src="{$vo.image}" alt="{$vo.name}">
{/notempty}
{$vo.name}
</div>
<div class="box">
<div class="list">
{volist name="vo.list" id="vos" length="5"}
<a href="/s/{$vos.title}.html" class="item">
<p>
<span>{$key+1}</span>
{$vos.title}
</p>
</a>
{/volist}
</div>
</div>
{/volist}
</div>
</div>
{include file="news/common/foot"}
</div>
{include file="news/common/footer"}
<script type="text/javascript" charset="utf-8">
app.rankList = JSON.parse('<?php echo json_encode($rankList, JSON_UNESCAPED_UNICODE); ?>');
for (const item of app.rankList) {
axios.get('/api/tool/ranking',{
params: {
channel: item.name
}
})
}
function linkBtn(element) {
const index = element.getAttribute('data-index');
const list = JSON.parse('<?php echo json_encode($list["items"], JSON_UNESCAPED_UNICODE); ?>');
const item = list[index];
if(app.pc_type == 1){
window.open(item.url);
}else{
item.showUrl = item.url
app.dialogUrl = true;
showUrlFun(item);
}
}
function getUrlBtn(element) {
app.dialogUrl = true;
const index = element.getAttribute('data-index');
const item = app.QList[index];
if(item.url.startsWith('http')) {
item.showUrl = item.url
showUrlFun(item);
}else{
app.dialogLoading = true;
axios.post('/api/other/save_url',{
url: encodeURIComponent(item.url),
title: item.title
}).then(res => {
if(res.data.code == 200) {
item.url = res.data.data.url
item.showUrl = res.data.data.url
}else{
item.showUrl = ''
item.message = res.data.message
}
app.dialogLoading = false;
showUrlFun(item)
})
.catch(err => {
app.dialogLoading = false
})
}
}
function showUrlFun(item) {
app.dialogItem = item
if(item.showUrl) {
var canvas = qrcanvas.qrcanvas({
data: item.showUrl,
size: 120
});
setTimeout(() => {
document.getElementById('qrcode').appendChild(canvas);
}, 200);
}
}
let cancelSource = null;
function setType(type) {
app.selectBtn()
if(type == app.is_type) return
app.is_type = type;
app.QLoading = false
app.QList = []
switchSource(1)
}
function switchSource(source) {
app.currentSource = source;
if(app.currentSource == 1){
if(app.QLoading || app.QList.length>0) return
if (cancelSource) {
cancelSource.cancel('用户切换了数据源,取消上次请求');
setTimeout(() => {
app.QLoading = true
}, 100);
}
cancelSource = axios.CancelToken.source();
app.QLoading = true
// search1线路 有5个接口
const searchTypes = [1, 2, 3, 4, 5];
const promises = [
...searchTypes.map(num => searchRequest('search1', num)),
searchRequest('search2')
];
Promise.all(promises)
.then(() => {
app.QLoading = false
})
}
}
function searchRequest(api, num = null) {
const params = {
title: app.keyword,
is_type: app.is_type,
}
if(num) params.num = num
return axios.post(`/api/other/${api}`, params, {
cancelToken: cancelSource.token // 直接用全局变量
})
.then(res => {
app.QList = app.QList.concat(res.data.data)
})
}
</script>
</body>
</html>

View File

@@ -0,0 +1,449 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加</el-button>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-delete" size="small" @click="postMultDelete" plain>批量删除</el-button>
</el-form-item>
<div style="float:right">
<el-form-item>
<el-select placeholder="请选择状态" size="small" v-model="search.admin_status">
<el-option value="" label="全部用户">
</el-option>
<el-option value="0" label="正常用户">
</el-option>
<el-option value="1" label="禁用用户">
</el-option>
</el-select>
</el-form-item>
<el-form-item style="width:120px;">
<el-select placeholder="筛选类别" size="small" v-model="search.filter">
<el-option value="admin_id" label="用户ID">
</el-option>
<el-option value="admin_name" label="用户昵称">
</el-option>
<el-option value="admin_account" label="用户帐号">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input placeholder="输入关键词搜索" size="small" v-model="search.keyword"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="getList_search" plain>搜索</el-button>
</el-form-item>
</div>
</el-form>
<el-table :data="dataList.data" @selection-change="changeSelection" v-loading="loading">
<el-table-column type="selection" width="50">
</el-table-column>
<el-table-column prop="admin_id" label="ID" width="100">
</el-table-column>
<el-table-column prop="admin_account" label="帐号">
</el-table-column>
<el-table-column prop="admin_name" label="昵称">
</el-table-column>
<el-table-column prop="group_name" label="用户组">
</el-table-column>
<el-table-column prop="admin_ipreg" label="注册IP" width="150">
</el-table-column>
<el-table-column label="最后活跃" width="120">
<template slot-scope="scope">
{{time2string(scope.row.admin_updatetime)}}
</template>
</el-table-column>
<el-table-column label="注册时间" width="120">
<template slot-scope="scope">
{{time2string(scope.row.admin_createtime)}}
</template>
</el-table-column>
<el-table-column label="禁用" width="80">
<template slot-scope="scope">
<el-switch v-model="scope.row.admin_status==1?true:false" active-color="#ff4949"
@change="clickStatus(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-link type="primary" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>&nbsp;
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
<!-- 添加框 -->
<el-dialog title="添加用户" :visible.sync="dialogFormAdd" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formAdd" status-icon :rules="rules" ref="formAdd">
<el-form-item label="帐号" :label-width="formLabelWidth" prop="admin_account">
<el-input size="medium" autocomplete="off" v-model="formAdd.admin_account"></el-input>
</el-form-item>
<el-form-item label="密码" :label-width="formLabelWidth" prop="admin_password">
<el-input size="medium" show-password="true" autocomplete="off" v-model="formAdd.admin_password">
</el-input>
</el-form-item>
<el-form-item label="昵称" :label-width="formLabelWidth" prop="admin_name">
<el-input size="medium" autocomplete="off" v-model="formAdd.admin_name"></el-input>
</el-form-item>
<el-form-item label="邮箱" :label-width="formLabelWidth" prop="admin_email">
<el-input size="medium" autocomplete="off" v-model="formAdd.admin_email"></el-input>
</el-form-item>
<el-form-item label="身份证" :label-width="formLabelWidth" prop="admin_idcard">
<el-input size="medium" autocomplete="off" v-model="formAdd.admin_idcard"></el-input>
</el-form-item>
<el-form-item label="真实姓名" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.admin_truename"></el-input>
</el-form-item>
<el-form-item label="用户组" :label-width="formLabelWidth">
<el-select size="medium" placeholder="请选择用户组" v-model="formAdd.admin_group">
<el-option v-for="group_add in groupList" :value="group_add.group_id" :label="group_add.group_name">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改用户" :visible.sync="dialogFormEdit" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formEdit" status-icon :rules="rules" ref="formEdit">
<el-form-item label="帐号" :label-width="formLabelWidth" prop="admin_account">
<el-input size="medium" autocomplete="off" v-model="formEdit.admin_account"></el-input>
</el-form-item>
<el-form-item label="密码" :label-width="formLabelWidth" prop="new_password">
<el-input size="medium" show-password="true" autocomplete="off" v-model="formEdit.new_password"
placeholder="不修改请留空">
</el-input>
</el-form-item>
<el-form-item label="昵称" :label-width="formLabelWidth" prop="admin_name">
<el-input size="medium" autocomplete="off" v-model="formEdit.admin_name"></el-input>
</el-form-item>
<el-form-item label="邮箱" :label-width="formLabelWidth" prop="admin_email">
<el-input size="medium" autocomplete="off" v-model="formEdit.admin_email"></el-input>
</el-form-item>
<el-form-item label="身份证" :label-width="formLabelWidth" prop="admin_idcard">
<el-input size="medium" autocomplete="off" v-model="formEdit.admin_idcard"></el-input>
</el-form-item>
<el-form-item label="真实姓名" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.admin_truename"></el-input>
</el-form-item>
<el-form-item label="用户组" :label-width="formLabelWidth">
<el-select size="medium" placeholder="请选择用户组" v-model="formEdit.admin_group">
<el-option v-for="group_edit in groupList" :value="group_edit.group_id"
:label="group_edit.group_name"></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit">确认修改</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
search: {
admin_status: "",
keyword: "",
filter: "admin_id"
},
formLabelWidth: '80px',
dialogFormAdd: false,
dialogFormEdit: false,
loading: true,
dataList: [],
groupList: [],
selectList: [],
form: {
page: 1,
per_page: 10
},
formAdd: {
admin_group: 1
},
formEdit: {
admin_group: 1
},
rules: {
admin_account: [
{ required: true, message: '帐号必须填写', trigger: 'blur' },
],
admin_name: [
{ required: true, message: '昵称必须填写', trigger: 'blur' },
],
admin_password: [
{ required: true, message: '密码必须填写', trigger: 'blur' },
// { required: true, pattern: /^(?=.*[a-z])(?=.*\d).{6,16}$/, message: '密码必须包含字母和数字(6-16位)', trigger: 'blur' },
],
new_password: [
{ required: true, message: '密码必须填写', trigger: 'blur' },
// { pattern: /^(?=.*[a-z])(?=.*\d).{6,16}$/, message: '密码必须包含字母和数字(6-16位)', trigger: 'blur' },
],
admin_email: [
{ pattern: /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/, message: '邮箱格式不正确', trigger: 'blur' },
],
admin_idcard: [
{ pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '身份证格式不正确', trigger: 'blur' },
],
}
}
},
methods: {
getList_search() {
this.form.page = 1;
this.getList();
},
time2string(timestamps) {
var now = new Date(timestamps * 1000),
y = now.getFullYear(),
m = now.getMonth() + 1,
d = now.getDate();
// return y + "-" + (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d) + " " + now.toTimeString().substr(0, 8);
return (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d) + " " + now.toTimeString().substr(0, 5);
},
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何用户!');
return;
}
this.$confirm('即将删除选中的用户, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/admin/delete', Object.assign({}, PostBase, {
admin_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].admin_id);
}
},
postEdit() {
var that = this;
that.$refs['formEdit'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/admin/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
postAdd() {
var that = this;
that.$refs['formAdd'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/admin/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
clickAdd() {
var that = this;
that.formAdd = {
admin_group: 1
};
axios.post('/admin/group/getList', Object.assign({}, PostBase))
.then(function (response) {
that.groupList = response.data.data;
if (response.data.code == CODE_SUCCESS) {
that.dialogFormAdd = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个用户, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/admin/delete', Object.assign({}, PostBase, {
admin_id: row.admin_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
clickStatus(row) {
var that = this;
axios.post(row.admin_status ? '/admin/admin/enable' : '/admin/admin/disable', Object.assign({}, PostBase, {
admin_id: row.admin_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/group/getList', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.groupList = response.data.data;
axios.post('/admin/admin/detail', Object.assign({}, PostBase, {
admin_id: row.admin_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/admin/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
},
}
})
</script>
</html>

View File

@@ -0,0 +1,263 @@
<!DOCTYPE html>
<html>
<head>
<title>后台管理系统</title>
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="/static/admin/css/element.css">
<link rel="stylesheet" href="/static/admin/css/YAdmin.css">
<style>
.login-container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: space-around;
min-width: 1280px;
min-height: 800px;
background: url(/static/admin/images/login_bg.jpg) no-repeat;
background-size: 100% 100%;
background-color: #ffffff;
}
.login-container:before{
content: " ";
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: url(/static/admin/images/login_bg_bottom.png) no-repeat;
background-size: 100% 100%;
height: 170px;
}
.login-box img{
width: 720px;
}
.login-border {
display: flex;
justify-content: center;
flex-direction: column;
position: relative;
top: -30px;
right: 100px;
}
.login-main{
background-color: #ffffff;
padding: 35px 45px 15px 45px;
border-radius: 6px;
}
.login-main .vadmin{
font-size: 16px;
font-weight: bold;
color: #6881ec;
line-height: 20px;
padding-bottom: 6px;
}
.login-logo {
margin: 0 0 20px;
}
.login-logo p {
color: #ffffff;
font-size: 25px;
font-weight: bold;
}
.login-submit {
margin-top: 10px;
width: 100%;
}
.login-form {
margin: 10px 0;
}
.login-form .el-form-item__content {
width: 270px;
}
.login-form .el-form-item {
margin-bottom: 26px;
}
.login-form .el-input input {
text-indent: 5px;
border-color: #DCDCDC;
border-radius: 3px;
border: none;
border-bottom: 1px solid #eee;
}
.login-form .el-input .el-input__prefix i {
padding: 0 5px;
font-size: 16px !important;
}
.login-code {
display: flex;
align-items: center;
justify-content: space-around;
margin-left: 10px;
cursor: pointer;
}
.login-code-img {
margin-top: 1px;
width: 100px;
height: 38px;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<div id="app" v-cloak>
<div class="login-container">
<div class="login-box">
<img src="/static/admin/images/login_bg_box.png">
</div>
<div class="login-border">
<div class="login-logo">
<p>后台登录</p>
</div>
<div class="login-main">
<p class="vadmin">管理员登录</p>
<el-form class="login-form" status-icon :rules="loginRules" ref="loginForm" :model="loginForm"
label-width="0" size="default">
<el-form-item prop="admin_account">
<el-input @keyup.enter.native="handleLogin()" v-model="loginForm.admin_account"
auto-complete="off" placeholder="请输入账号">
<i slot="prefix" class="el-icon-user"></i>
</el-input>
</el-form-item>
<el-form-item prop="admin_password">
<el-input @keyup.enter.native="handleLogin()" v-model="loginForm.admin_password" show-password
auto-complete="off" placeholder="请输入密码">
<i slot="prefix" class="el-icon-key"></i>
</el-input>
</el-form-item>
<el-form-item v-if="codeUrl" prop="admin_code">
<el-row :span="34">
<el-col :span="14">
<el-input @keyup.enter.native="handleLogin()" v-model="loginForm.admin_code"
auto-complete="off" placeholder="请输入验证码">
<i slot="prefix" class="el-icon-mobile"></i>
</el-input>
</el-col>
<el-col :span="10">
<div class="login-code">
<img :src="codeUrl" class="login-code-img" @click="getCaptcha" alt="" />
</div>
</el-col>
</el-row>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loading" @click.native.prevent="handleLogin"
class="login-submit">登 录
</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="/static/admin/js/vue-2.6.10.min.js"></script>
<script src="/static/admin/js/axios.min.js"></script>
<script src="/static/admin/js/element.js"></script>
<script src="/static/admin/js/YAdmin.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
codeUrl: '',
codeToken: '',
loading: false,
loginForm: {
admin_account: '',
admin_password: '',
admin_code: '',
},
loginRules: {
admin_account: [
{ required: true, message: '请输入账号', trigger: 'blur' }
],
admin_password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码长度最少为6位', trigger: 'blur' }
],
admin_code: [
{ required: true, message: '请输入验证码', trigger: 'blur' },
{ min: 4, max: 4, message: '验证码长度为4位', trigger: 'blur' }
]
}
}
},
created() {
this.getCaptcha();
},
methods: {
/**
* @description 正式登录
*/
handleLogin() {
var that = this;
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.loginForm.token = this.codeToken
axios.post('/admin/admin/login', Object.assign({}, PostBase, this.loginForm))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: '登录成功,正在跳转中',
type: 'success'
});
setTimeout(function () {
location.replace('/qfadmin');
}, 1000)
} else {
that.$message.error(response.data.message);
that.loading = false
that.getCaptcha();
}
})
.catch(function (error) {
that.$message.error('登录失败,服务器内部错误');
that.loading = false
});
}
})
},
onSubmit() {
var that = this;
axios.post('/admin/admin/login', Object.assign({}, PostBase, this.form))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: '登录成功,正在跳转中',
type: 'success'
});
setTimeout(function () {
location.replace('{$callback}');
}, 1000)
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('登录失败,服务器内部错误');
});
},
getCaptcha() {
var that = this;
axios.post('/admin/system/getCaptcha', Object.assign({}, PostBase))
.then(function (res) {
that.codeUrl = res.data.data.img
that.codeToken = res.data.data.token
})
.catch(function (error) {
that.$message.error('获取失败');
});
},
}
})
</script>
</html>

View File

@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span>修改我的密码</span>
</div>
<div class="text item">
<el-form :model="form" status-icon :rules="rules" ref="form" label-width="80px">
<el-form-item label="原密码" prop="oldPassword">
<el-input show-password v-model="form.oldPassword" placeholder="请输入原密码"></el-input>
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input show-password password="password" v-model="form.newPassword" placeholder="请输入新密码">
</el-input>
</el-form-item>
<el-form-item label="新密码" prop="checkPassword">
<el-input show-password v-model="form.checkPassword" placeholder="请确认新密码"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">修改密码</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
form: {
oldPassword: "",
newPassword: "",
checkPassword: "",
},
rules: {
oldPassword: [
{ required: true, message: '原密码必须输入', trigger: 'blur' },
],
newPassword: [
{ required: true, message: '必须输入', trigger: 'blur' },
],
checkPassword: [
{ required: true, message: '必须输入', trigger: 'blur' },
],
}
}
},
methods: {
onSubmit() {
var that = this;
that.$refs['form'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
if (that.form.newPassword != that.form.checkPassword) {
that.$message.error('两次密码输入不一致,请确认');
return;
}
axios.post('/admin/admin/motifypassword', Object.assign({}, PostBase, {
oldPassword: that.form.oldPassword,
newPassword: that.form.newPassword,
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
setTimeout(function () {
location.href = "/qfadmin/admin/login";
}, 2000);
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
}
});
</script>
</html>

View File

@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span>修改我的资料</span>
</div>
<div class="text item">
<el-form :model="form" status-icon :rules="rules" ref="form" label-width="80px">
<el-form-item label="昵称" prop="admin_name">
<el-input v-model="form.admin_name" placeholder="请输入你的昵称"></el-input>
</el-form-item>
<el-form-item label="姓名" prop="admin_truename">
<el-input v-model="form.admin_truename" placeholder="请输入你的真实姓名"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="admin_email">
<el-input v-model="form.admin_email" placeholder="请输入你的邮箱"></el-input>
</el-form-item>
<el-form-item label="身份证" prop="admin_idcard">
<el-input v-model="form.admin_idcard" placeholder="请输入你的身份证"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">更新资料</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getData();
return {
form: {
},
rules: {
admin_name: [
{ required: true, message: '昵称必须填写', trigger: 'blur' },
],
admin_email: [
{ pattern: /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/, message: '邮箱格式不正确', trigger: 'blur' },
],
admin_idcard: [
{ pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '身份证格式不正确', trigger: 'blur' },
],
}
}
},
methods: {
getData() {
var that = this;
axios.post('/admin/admin/getmyinfo', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.form = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
onSubmit() {
var that = this;
that.$refs['form'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
if (that.form.newPassword != that.form.checkPassword) {
that.$message.error('两次密码输入不一致,请确认');
return;
}
axios.post('/admin/admin/updateMyInfo', Object.assign({}, PostBase, that.form))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
}
});
</script>
</html>

View File

@@ -0,0 +1,214 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-upload class="upload-demo" action="/admin/attach/uploadImage" :on-success="handleUploadSuccess"
:file-list="fileList" :show-file-list="false" :before-upload="beforeUpload" :data="postData"
v-loading.fullscreen.lock="fullscreenLoading">
<el-button size="small" type="primary">上传图片</el-button>
</el-upload>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-delete" size="small" @click="postMultDelete" plain>批量删除</el-button>
</el-form-item>
</el-form>
<el-table :data="dataList.data" @selection-change="changeSelection" v-loading="loading">
<el-table-column type="selection" width="50">
</el-table-column>
<el-table-column prop="attach_id" label="ID" width="60">
</el-table-column>
<el-table-column label="文件预览" width="120">
<template slot-scope="scope">
<div style="display: flex;align-items: center;">
<el-link :href="scope.row.attach_path" :underline="false" target="_blank">
<el-image style="width: 80px; height: 80px;flex:none;margin-right: 10px;background-color: #f8f8f9;border-radius: 6px;"
fit="contain" :src="scope.row.attach_path">
</el-image>
</el-link>
</div>
</template>
</el-table-column>
<el-table-column prop="attach_name" label="文件名称">
</el-table-column>
<el-table-column prop="attach_size" label="附件大小" width="100">
</el-table-column>
<el-table-column label="附件类型" width="100">
<template slot-scope="scope">
<el-tag size="medium" type="warning">{{scope.row.attach_type.toUpperCase()}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
fullscreenLoading: false,
search: {
keyword: "",
filter: "attach_phone"
},
loading: true,
dataList: [],
selectList: [],
fileList: [],
form: {
page: 1,
per_page: 10,
},
postData: PostBase,
}
},
methods: {
handleUploadSuccess(res, file) {
this.fullscreenLoading = false;
if (res.code == CODE_SUCCESS) {
this.$message({
message: res.message,
type: 'success'
});
this.getList();
} else {
this.$message.error(res.message);
}
},
beforeUpload(file) {
const isImage = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isImage) {
this.$message.error('上传图片只能是 JPG/PNG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
this.fullscreenLoading = true;
return isImage && isLt2M;
},
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
time2string(timestamps, formatStr = 'MM-dd hh:mm') {
var now = new Date(timestamps * 1000),
y = now.getFullYear(),
m = now.getMonth() + 1,
d = now.getDate();
return y + "-" + (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d) + " " + now.toTimeString().substr(0, 8);
},
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何附件!');
return;
}
this.$confirm('即将删除选中的附件, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/attach/delete', Object.assign({}, PostBase, {
attach_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => { });
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].attach_id);
}
},
clickAdd() {
var that = this;
that.formAdd = {};
that.dialogFormAdd = true;
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个附件, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/attach/delete', Object.assign({}, PostBase, {
attach_id: row.attach_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => { });
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/attach/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
}
}
})
</script>
</html>

View File

@@ -0,0 +1,19 @@
</el-main>
</el-container>
</el-container>
<Uploads ref="upload"></Uploads>
<Goodslists ref="goodslist"></Goodslists>
</div>
</body>
{include file="component/view"/}
<script src="/static/admin/js/vue-2.6.10.min.js"></script>
<script src="/static/admin/js/axios.min.js"></script>
<script src="/static/admin/js/element.js"></script>
<script src="/static/admin/js/YAdmin.js"></script>
<script src="/static/admin/js/SkuForm.umd.js"></script>
<script src="/static/admin/UEditor/vue-ueditor-wrap.min.js"></script>
<script src="/static/admin/UEditor/ueditor.config.js"></script>
<script src="/static/admin/UEditor/ueditor.all.js"></script>
<script src="/static/admin/js/component.js"></script>
<script src="/static/admin/js/Sortable.min.js"></script>
<script src="/static/admin/js/vuedraggable.umd.min.js"></script>

View File

@@ -0,0 +1,67 @@
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="/static/admin/css/element.css">
<link rel="stylesheet" href="/static/admin/css/YAdmin.css">
</head>
<body>
<div id="app" v-cloak>
<el-container>
<el-header>
<el-col style="width: auto;">
<el-menu class="el-menu-vertical" text-color="#333333" :default-active="'{if condition="$node.node_pid"}{$node.node_pid}{else}{$node.node_id}{/if}'" unique-opened
style="border:none;" mode="horizontal" active-text-color="#333333">
{volist name="menuList" id="item"}
{if condition="count($item.subList)>0"}
{if condition="count($item.subList[0]['subList'])>0"}
<el-menu-item index="{$item.node_id}"
onclick="location.href='/{$item['subList'][0]['subList'][0]['node_module']}/{$item['subList'][0]['subList'][0]['node_controller']}/{$item['subList'][0]['subList'][0]['node_action']}';"
{if
condition="$menu==$item.node_id"
}class="is-active" {/if}>
<i class="{$item.node_icon}"></i> {$item.node_title}
</el-menu-item>
{else}
<el-menu-item index="{$item.node_id}"
onclick="location.href='/{$item['subList'][0]['node_module']}/{$item['subList'][0]['node_controller']}/{$item['subList'][0]['node_action']}';" {if
condition="$menu==$item.node_id"
}class="is-active" {/if}>
<i class="{$item.node_icon}"></i> {$item.node_title}
</el-menu-item>
{/if}
{else}
{if condition="count($item.subList)>0 || $item.node_controller=='index'"}
<el-menu-item index="{$item.node_id}"
onclick="location.href='/{$item.node_module}/{$item.node_controller}/{$item.node_action}';" {if
condition="$menu==$item.node_id"
}class="is-active" {/if}>
<i class="{$item.node_icon}"></i> {$item.node_title}
</el-menu-item>
{/if}
{/if}
{/volist}
</el-menu>
</el-col>
<el-col style="width: 240px;float: right;">
<span class="topArea">
<el-link :underline="false" class="el-icon-full-screen menuicon" onclick="requestFullScreen()"></el-link>
<!-- <el-link :underline="false" class="el-icon-brush menuicon"></el-link> -->
<el-dropdown>
<el-link :underline="false">&nbsp;{$adminInfo['admin_name']}<i class="el-icon-arrow-down"></i></el-link>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item onclick="location.href='/qfadmin/admin/updatemyinfo';">修改资料
</el-dropdown-item>
<el-dropdown-item onclick="location.href='/qfadmin/admin/motifypassword';">修改密码
</el-dropdown-item>
<el-dropdown-item onclick="location.href='/qfadmin/system/clean';">清除缓存
</el-dropdown-item>
<el-dropdown-item onclick="logout()">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</span>
</el-col>
</el-header>
<el-container class="body">
{include file="common/menu"/}
<el-main>

View File

@@ -0,0 +1,47 @@
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="/static/admin/css/element.css">
<link rel="stylesheet" href="/static/admin/css/YAdmin.css">
</head>
<body>
<div id="app" v-cloak>
<el-container>
<el-header>
<el-col style="width: auto;">
<el-menu class="el-menu-vertical" text-color="#333333" unique-opened
style="border:none;" mode="horizontal" active-text-color="#333333">
<el-menu-item onclick="location.href='./index.html?meeting_id={$datas.meeting_id??''}'" {if
condition="$action=='index'"
}class="is-active" {/if}>
<i class="el-icon-user-solid"></i> 客户管理
</el-menu-item>
<el-menu-item onclick="location.href='./team.html?meeting_id={$datas.meeting_id??''}'" {if
condition="$action=='team'"
}class="is-active" {/if}>
<i class="el-icon-s-custom"></i> 团队管理
</el-menu-item>
<el-menu-item onclick="location.href='./valetor.html?meeting_id={$datas.meeting_id??''}'" {if
condition="$action=='valetor'"
}class="is-active" {/if}>
<i class="el-icon-s-help"></i> 会务人员管理
</el-menu-item>
</el-menu>
</el-col>
<el-col style="width: 240px;float: right;">
<span class="topArea">
<el-link :underline="false" class="el-icon-full-screen menuicon" onclick="requestFullScreen()"></el-link>
<!-- <el-link :underline="false" class="el-icon-brush menuicon"></el-link> -->
<el-dropdown>
<el-link :underline="false">&nbsp;{$adminInfo['admin_name']}<i class="el-icon-arrow-down"></i></el-link>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item onclick="logout()">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</span>
</el-col>
</el-header>
<el-container class="body">
{include file="common/menu"/}
<el-main>

View File

@@ -0,0 +1,44 @@
{if condition="$menuLists"}
<el-aside width="160px">
<a class="titlehome" href="/qfadmin" style="display: block;height: 62px;line-height: 62px;text-align: center;"><img src="/static/admin/images/logo.png" width="40px" style="vertical-align: middle;" /></a>
<el-menu class="el-menu-vertical-demo" text-color="#333333" default-active="'{$node.node_pid}-{$node.node_id}'" :collapse="false" :default-openeds="['{$node.node_pid}']">
{volist name="menuLists" id="item"}
{if condition="count($item.subList)>0"}
<el-submenu index="{$item.node_id}">
<template slot="title">
<i {if condition='$item.node_icon'}class="{$item.node_icon}"{else}class="el-icon-menu"{/if}></i> {$item.node_title}
</template>
{volist name="$item.subList" id="subItem"}
<el-menu-item onclick="location.href='/{$subItem.node_module}/{$subItem.node_controller}/{$subItem.node_action}';"
index="{$item.node_id}-{$subItem.node_id}" {if
condition="$subItem.node_controller==strtolower($controller) && $subItem.node_action==strtolower($action)"
}class="is-active" {/if}>{$subItem.node_title}</el-menu-item>
{/volist}
</el-submenu>
{else}
{if condition="$item.node_controller=='' && $item.node_action==''"}
<el-menu-item index="{$item.node_id}" onclick="testalert('暂无该功能')">
<i {if condition='$item.node_icon' }class="{$item.node_icon}" {else}class="el-icon-menu" {/if}></i>
{$item.node_title}
</el-menu-item>
{else}
<el-menu-item index="{$item.node_id}"
onclick="location.href='/{$item.node_module}/{$item.node_controller}/{$item.node_action}';" {if
condition="$item.node_controller==strtolower($controller) && $item.node_action==strtolower($action)"
}class="is-active" {/if}>
<i {if condition='$item.node_icon' }class="{$item.node_icon}" {else}class="el-icon-menu" {/if}></i>
{$item.node_title}
</el-menu-item>
{/if}
{/if}
{/volist}
<div style="height: 120px;"></div>
</el-menu>
<div class="version">资源管理系统<br> Version 3.1</div>
</el-aside>
{else}
<div style="position: absolute;top: -72px;left: 0;width: 160px;background-color: #ffffff;box-shadow: 0 0 12px 0 rgb(47 75 168 / 6%);border-radius: 12px;">
<a class="title" href="/admin" style="display: block;height: 62px;line-height: 62px;text-align: center;"><img
src="/static/admin/images/logo.png" width="40px" style="vertical-align: middle;" /></a>
</div>
{/if}

View File

@@ -0,0 +1,152 @@
<template id="Upload">
<el-dialog title="图片库" :visible.sync="visible" :modal-append-to-body='false' append-to-body :close-on-click-modal="false"
width="725px">
<div class="upload-boxs">
<el-upload class="upload-right" action="/admin/attach/uploadImage" :on-success="handleUploadSuccess"
:file-list="fileList" :show-file-list="false" :before-upload="beforeUpload" :data="postData"
v-loading.fullscreen.lock="fullscreenLoading">
<el-button size="small" type="primary" icon="el-icon-upload">上传图片</el-button>
</el-upload>
</div>
<ul class="storage-list">
<li :class="item.select?'active':''" v-for="(item, index) in dataList.data" :key="index" @click="select(index)">
<el-image fit="contain" :src="item.attach_path"></el-image>
<p>{{item.attach_name}}</p>
</li>
</ul>
<p v-if="dataList.data&&dataList.data.length==0" style="text-align: center;">暂无资源</p>
<el-pagination @current-change="changeCurrentPage" layout="prev, pager, next" :current-page="dataList.current_page"
:page-count="dataList.last_page" hide-on-single-page background>
</el-pagination>
<div slot="footer" class="dialog-footer">
<div style="float: left; font-size: 13px;">
<span v-if="multiple">
当前已选 <span style="color: #F56C6C;">{{selectList.length+selected_num}}</span> 个,最多允许选择 <span
style="color: #F56C6C;">{{total_num}}</span> 个资源
</span>
<span v-else>当前已选 <span style="color: #F56C6C;">{{selectList.length}}</span> 个资源</span>
</div>
<el-button @click="visible = false" size="small">取消</el-button>
<el-button type="primary" @click="save" size="small">确定</el-button>
</div>
</el-dialog>
</template>
<template id="Single">
<div class="slectimg" v-if="multiple">
<block v-if="value.length>0">
<draggable v-model="value" chosenClass="chosen" forceFallback="true" animation="600" @start="onStart"
@end="onEnd">
<transition-group>
<div class="imgs" v-for="(v, s) in value" :key="s" style="cursor: all-scroll;">
<el-image fit="contain" :src="v" :preview-src-list="value" :z-index="s"></el-image>
<!-- <el-image fit="contain" :src="v" ></el-image> -->
<i class="close el-icon-error" @click="deles(s)"></i>
</div>
</transition-group>
</draggable>
</block>
<div class="noimg" @click="selectimg()">
<i class="el-icon-plus"></i>
</div>
</div>
<div class="slectimg" v-else>
<div class="imgs" v-if="value.length>0">
<el-image fit="contain" :src="value" :preview-src-list="[value]"></el-image>
<i class="close el-icon-error" @click="deles()"></i>
</div>
<div class="noimg" v-else @click="selectimg()">
<i class="el-icon-plus"></i>
</div>
</div>
</template>
<template id="Ueditor">
<Ueditors v-model="value" ref="Ueditor" :config="config"></Ueditors>
</template>
<template id="skuforms">
<div>
<div style="padding-bottom: 10px;">
<el-input style="width: 120px;" v-if="inputVisible" v-model="inputValue" ref="saveTagInput" size="small"
@keyup.enter.native="handleInputConfirm" placeholder="回车确定">
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput" style="width: 120px;">+添加规格组</el-button>
</div>
<sku-form :source-attribute="sourceAttribute" :attribute.sync="attribute" :structure="structure" :sku.sync="sku"
ref="skuForm"></sku-form>
</div>
</template>
<template id="Goodslist">
<el-dialog title="商品库" :before-close="handleClose" :visible.sync="visible" :modal-append-to-body='false' append-to-body
:close-on-click-modal="false" width="900px">
<el-form :inline="true">
<div style="float:right">
<el-form-item style="width:100px; margin-bottom: 0;">
<el-cascader v-model="search.classify" placeholder="商品分类" :options="categoryList" :props="cascaderProps"
style="width: 100%;" filterable clearable size="small" :show-all-levels="false">
</el-cascader>
</el-form-item>
<el-form-item style="margin-bottom: 0;">
<el-input placeholder="输入商品名称搜索" size="small" v-model="search.keyword" @keyup.enter.native="getList_search"
clearable @clear="getList_search"></el-input>
</el-form-item>
<el-form-item style="margin-bottom: 0;">
<el-button type="primary" icon="el-icon-search" size="small" @click="getList_search" plain>搜索
</el-button>
<el-button icon="el-icon-refresh-left" size="small" @click="getList_search(0)" plain>重置</el-button>
</el-form-item>
</div>
</el-form>
<el-table :data="dataList.data" ref="multipleTable" @selection-change="changeSelection" row-key="goods_id" reserve-selection="true" style="min-height: 425px;" v-loading="loading">
<el-table-column align="center" type="selection" reserve-selection="true" width="55"></el-table-column>
<el-table-column label="商品" prop="goods_id" min-width="380">
<template slot-scope="scope">
<el-image class="goods-image" style="width: 50px;height: 50px;" :src="scope.row.picture[0]" :preview-src-list="[scope.row.picture[0]]"
fit="contain" lazy></el-image>
<div class="goods-info cs-ml">
<p class="action" style="overflow:hidden;text-overflow:ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;">
<span :title="scope.row.goods_name" class="link">{{scope.row.goods_name}}</span>
</p>
</div>
</template>
</el-table-column>
<el-table-column label="本店价" prop="goods_price">
<template slot-scope="scope">
<div class="action">
<span class="goods-shop-price">{{scope.row.goods_price}}</span>
</div>
</template>
</el-table-column>
<el-table-column label="库存" prop="stock_total">
<template slot-scope="scope">
<div class="action">
<span>{{scope.row.stock_total}}</span>
</div>
</template>
</el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<p style="padding-bottom: 10px;">
<el-pagination hide-on-single-page="true" layout="prev, pager, next" background :current-page="form.page" @current-change="changeCurrentPage" :page-size="5" :total="dataList.total">
</el-pagination>
</p>
<p>
<el-button @click="cancels" size="small">取消</el-button>
<el-button type="primary" @click="save" size="small">确定</el-button>
</p>
</div>
</el-dialog>
</template>

View File

@@ -0,0 +1,194 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-card class="box-card" shadow="never">
<el-tabs v-model="activeName">
<el-tab-pane :label="item.name" :name="item.val" v-for="(item, index) in tabname" :key="index" v-if="item.show">
<div class="base_form" style="padding-right: 220px;">
<el-form ref="form" label-width="220px">
<block v-for="(items, indexs) in form" :key="indexs">
<el-form-item :label="items.conf_title?items.conf_title:items.conf_key" v-if="items.conf_type==item.val">
<block v-if="items.conf_spec==1">
<el-input type="textarea" :rows="4" v-model="items.conf_value"></el-input>
</block>
<block v-else-if="items.conf_spec==2">
<el-radio v-model="items.conf_value" v-for="(val, key) in items.conf_content" :key="key" :label="val.value">{{val.name}}</el-radio>
</block>
<block v-else-if="items.conf_spec==3">
<el-checkbox-group v-model="items.conf_value">
<el-checkbox v-for="(val, key) in items.conf_content" :key="key" :label="val.value">{{val.name}}</el-checkbox>
</el-checkbox-group>
</block>
<block v-else-if="items.conf_spec==4">
<Single v-model="items.conf_value"/>
</block>
<block v-else-if="items.conf_spec==5">
<Single v-model="items.conf_value" multiple="true" :selected_num="items.conf_value.length"/>
</block>
<block v-else-if="items.conf_spec==6">
<Ueditor v-model="items.conf_value"></Ueditor>
</block>
<block v-else-if="items.conf_spec==7">
<el-color-picker v-model="items.conf_value"></el-color-picker>
</block>
<block v-else>
<el-input v-model="items.conf_value"></el-input>
</block>
<span class="f_tips">{{items.conf_desc}}<span v-if="items.conf_spec==5"> 最多上传10张</span></span>
</el-form-item>
</block>
<el-form-item>
<el-button type="primary" @click="onSubmit(item.val)">保存配置</el-button>
</el-form-item>
</el-form>
</div>
</el-tab-pane>
</el-tabs>
</el-card>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getData();
return {
form: [],
activeName: "0",
tabname: [
{
name: '基础设置',
val: '0',
show: false,
},
{
name: 'SEO设置',
val: '9',
show: false,
},
{
name: '前端模版',
val: '3',
show: false,
},
{
name: '搜索设置',
val: '1',
show: false,
},
{
name: '微信设置',
val: '8',
show: false,
},
{
name: '交易设置',
val: '10',
show: false,
},
{
name: '售后设置',
val: '11',
show: false,
},
{
name: '上传配置',
val: '2',
show: false,
},
{
name: '其他配置',
val: '4',
show: false,
},
],
}
},
methods: {
getData() {
var that = this;
axios.post('/admin/conf/getBaseConfig', Object.assign({}, PostBase))
.then(function (res) {
if (res.data.code == 200) {
for (let item of res.data.data) {
if (item.conf_spec == 2) {
for (let i = 0; i < item.conf_content.length; i++) {
let d = item.conf_content[i].split("=>");
item.conf_content[i] = {
name: d[0].toString(),
value: d[1].toString()
}
}
}else if(item.conf_spec==3){
for (let i = 0; i < item.conf_content.length; i++) {
let d = item.conf_content[i].split("=>");
item.conf_content[i] = {
name: d[0].toString(),
value: d[1].toString()
}
}
if(item.conf_value){
item.conf_value = item.conf_value.split(",");
}else{
item.conf_value = []
}
}else if (item.conf_spec == 5) {
if(item.conf_value){
item.conf_value = item.conf_value.split(",");
for (let i = 0; i < item.conf_value.length; i++) {
if (!item.conf_value[i]) {
item.conf_value.splice(i, 1);
}
}
} else {
item.conf_value = []
}
}
for (let i = 0; i < that.tabname.length; i++) {
if(that.tabname[i].val == item.conf_type){
that.tabname[i].show = true
}
}
}
that.form = res.data.data;
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
onSubmit(index) {
var that = this;
var postData = {};
for (var i = 0; i < that.form.length; i++) {
if(that.form[i].conf_type == index){
postData[that.form[i].conf_key] = that.form[i].conf_value;
}
}
axios.post('/admin/conf/updateBaseConfig', Object.assign({}, PostBase, postData))
.then(function (res) {
if (res.data.code == 200) {
that.$message({
message: res.data.message,
type: 'success'
});
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
}
})
</script>
</html>

View File

@@ -0,0 +1,468 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加</el-button>
</el-form-item>
<div style="float:right">
<el-form-item style="width:120px;">
<el-select placeholder="筛选类别" size="small" v-model="search.filter">
<el-option value="conf_id" label="参数ID">
</el-option>
<el-option value="conf_title" label="参数名称">
</el-option>
<el-option value="conf_key" label="参数字段">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input placeholder="输入关键词搜索" size="small" v-model="search.keyword"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="getList_search" plain>搜索</el-button>
</el-form-item>
</div>
</el-form>
<el-table :data="dataList.data" @selection-change="changeSelection" v-loading="loading">
<el-table-column prop="conf_id" label="ID" width="60">
</el-table-column>
<el-table-column prop="conf_type" label="所属分类" width="150">
<template slot-scope="scope">
<el-tag size="small" type="success" v-if="scope.row.conf_type==1">搜索设置</el-tag>
<el-tag size="small" type="warning" v-else-if="scope.row.conf_type==2">上传配置</el-tag>
<el-tag size="small" type="info" v-else-if="scope.row.conf_type==3">前端模版</el-tag>
<el-tag size="small" type="danger" v-else-if="scope.row.conf_type==4">其他配置</el-tag>
<el-tag size="small" type="success" v-else-if="scope.row.conf_type==5">微信支付配置</el-tag>
<el-tag size="small" type="warning" v-else-if="scope.row.conf_type==6">支付宝支付配置</el-tag>
<el-tag size="small" type="success" v-else-if="scope.row.conf_type==7">微信小程序配置</el-tag>
<el-tag size="small" type="danger" v-else-if="scope.row.conf_type==8">微信公众号配置</el-tag>
<el-tag size="small" type="danger" v-else-if="scope.row.conf_type==9">SEO设置</el-tag>
<el-tag size="small" type="danger" v-else-if="scope.row.conf_type==10">交易设置</el-tag>
<el-tag size="small" type="danger" v-else-if="scope.row.conf_type==11">售后设置</el-tag>
<el-tag size="small" v-else>基础设置</el-tag>
</template>
</el-table-column>
<el-table-column prop="conf_title" label="参数名称">
</el-table-column>
<el-table-column prop="conf_desc" label="参数描述">
</el-table-column>
<el-table-column prop="conf_key" label="参数字段">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.conf_title" placement="top">
<el-link>{{scope.row.conf_key}}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="conf_sort" label="排序" width="90">
</el-table-column>
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-link type="primary" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>&nbsp;
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false" v-if="scope.row.conf_system==0">删除</el-link>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
<!-- 添加框 -->
<el-dialog title="添加配置" :visible.sync="dialogFormAdd" width="800px" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formAdd" status-icon :rules="rules" ref="formAdd">
<el-form-item label="所属分类" :label-width="formLabelWidth" prop="conf_type">
<el-select v-model="formAdd.conf_type" placeholder="请选择所属分类" size="medium">
<el-option label="基础设置" value="0"></el-option>
<el-option label="SEO设置" value="9"></el-option>
<el-option label="搜索设置" value="1"></el-option>
<el-option label="上传配置" value="2"></el-option>
<el-option label="前端模版" value="3"></el-option>
<el-option label="其他配置" value="4"></el-option>
<el-option label="微信支付配置" value="5"></el-option>
<el-option label="支付宝支付配置" value="6"></el-option>
<el-option label="微信小程序配置" value="7"></el-option>
<el-option label="微信公众号配置" value="8"></el-option>
<el-option label="交易设置" value="10"></el-option>
<el-option label="售后设置" value="11"></el-option>
</el-select>
</el-form-item>
<el-form-item label="参数名称" :label-width="formLabelWidth" prop="conf_title">
<el-input size="medium" autocomplete="off" v-model="formAdd.conf_title"></el-input>
<span style="color: #999;">参数名称网站LOGO</span>
</el-form-item>
<el-form-item label="参数字段" :label-width="formLabelWidth" prop="conf_key">
<el-input size="medium" autocomplete="off" v-model="formAdd.conf_key"></el-input>
<span style="color: #999;">参数字段logo</span>
</el-form-item>
<el-form-item label="参数描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.conf_desc"></el-input>
<span style="color: #999;">参数描述,如:建议尺寸: 300*300</span>
</el-form-item>
<el-form-item label="字段类型" :label-width="formLabelWidth">
<el-radio-group v-model="formAdd.conf_spec" size="small">
<el-radio-button label="0">文本框</el-radio-button>
<el-radio-button label="1">多行文本框</el-radio-button>
<el-radio-button label="2">单选框</el-radio-button>
<el-radio-button label="3">多选框</el-radio-button>
<el-radio-button label="4">单图</el-radio-button>
<el-radio-button label="5">多图</el-radio-button>
<el-radio-button label="6">富文本</el-radio-button>
</el-radio-group>
<el-input v-if="formAdd.conf_spec==2 || formAdd.conf_spec==3" type="textarea" v-model="formAdd.conf_content"
:rows="4" placeholder="参数方式例如:&#10;开启=>1&#10;关闭=>0" style="margin-top: 10px;"></el-input>
</el-form-item>
<el-form-item label="显示隐藏" :label-width="formLabelWidth">
<el-switch size="medium" v-model="formAdd.conf_status"></el-switch>
</el-form-item>
<el-form-item label="排序" :label-width="formLabelWidth">
<el-input-number v-model="formAdd.conf_sort" :min="0" :max="999" size="medium" style="width: 120px;" controls-position="right" />
</el-form-item>
<el-form-item label="系统参数" :label-width="formLabelWidth">
<el-switch size="medium" v-model="formAdd.conf_system"></el-switch>
<div style="color: #999;">开启后,添加的参数将无法删除</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改配置" :visible.sync="dialogFormEdit" width="800px" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formEdit" status-icon :rules="rules" ref="formEdit">
<el-form-item label="所属分类" :label-width="formLabelWidth" prop="conf_type">
<el-select v-model="formEdit.conf_type" placeholder="请选择所属分类" size="medium">
<el-option label="基础设置" value="0"></el-option>
<el-option label="SEO设置" value="9"></el-option>
<el-option label="搜索设置" value="1"></el-option>
<el-option label="上传配置" value="2"></el-option>
<el-option label="前端模版" value="3"></el-option>
<el-option label="其他配置" value="4"></el-option>
<el-option label="微信支付配置" value="5"></el-option>
<el-option label="支付宝支付配置" value="6"></el-option>
<el-option label="微信小程序配置" value="7"></el-option>
<el-option label="微信公众号配置" value="8"></el-option>
<el-option label="交易设置" value="10"></el-option>
<el-option label="售后设置" value="11"></el-option>
</el-select>
</el-form-item>
<el-form-item label="参数名称" :label-width="formLabelWidth" prop="conf_title">
<el-input size="medium" autocomplete="off" v-model="formEdit.conf_title"></el-input>
<span style="color: #999;">参数名称网站LOGO</span>
</el-form-item>
<el-form-item label="参数字段" :label-width="formLabelWidth" prop="conf_key">
<el-input size="medium" autocomplete="off" v-model="formEdit.conf_key"></el-input>
<span style="color: #6881ec;">参数字段,切勿随意修改</span>
</el-form-item>
<el-form-item label="参数描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.conf_desc"></el-input>
<span style="color: #999;">参数描述,如:建议尺寸: 300*300</span>
</el-form-item>
<el-form-item label="字段类型" :label-width="formLabelWidth">
<el-radio-group v-model="formEdit.conf_spec" size="small">
<el-radio-button label="0">文本框</el-radio-button>
<el-radio-button label="1">多行文本框</el-radio-button>
<el-radio-button label="2">单选框</el-radio-button>
<el-radio-button label="3">多选框</el-radio-button>
<el-radio-button label="4">单图</el-radio-button>
<el-radio-button label="5">多图</el-radio-button>
<el-radio-button label="6">富文本</el-radio-button>
<el-radio-button label="7">颜色选择</el-radio-button>
</el-radio-group>
<el-input v-if="formEdit.conf_spec==2 || formEdit.conf_spec==3" type="textarea" v-model="formEdit.conf_content" :rows="4" placeholder="参数方式例如:&#10;开启=>1&#10;关闭=>0" style="margin-top: 10px;"></el-input>
</el-form-item>
<el-form-item label="显示隐藏" :label-width="formLabelWidth">
<el-switch size="medium" v-model="formEdit.conf_status"></el-switch>
</el-form-item>
<el-form-item label="排序" :label-width="formLabelWidth">
<el-input-number v-model="formEdit.conf_sort" :min="0" :max="999" size="medium" style="width: 120px;"
controls-position="right" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit">确认修改</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
search: {
keyword: "",
filter: "conf_id"
},
formLabelWidth: '80px',
dialogFormAdd: false,
dialogFormEdit: false,
loading: true,
dataList: [],
selectList: [],
form: {
page: 1,
per_page: 10
},
formAdd: {
conf_status: true,
conf_spec: 0,
conf_sort: 0,
},
formEdit: {},
rules: {
conf_title: [
{ required: true, message: '参数名称必须填写', trigger: 'blur' },
],
conf_key: [
{ required: true, message: '参数字段必须填写', trigger: 'blur' },
],
conf_type: [
{ required: true, message: '所属分类必须填写', trigger: 'blur' },
],
}
}
},
methods: {
getList_search() {
this.form.page = 1;
this.getList();
},
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何配置!');
return;
}
this.$confirm('即将删除选中的配置, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/conf/delete', Object.assign({}, PostBase, {
conf_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].conf_id);
}
},
postEdit() {
var that = this;
that.$refs['formEdit'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/conf/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
postAdd() {
var that = this;
that.$refs['formAdd'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/conf/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
clickAdd() {
var that = this;
that.formAdd = {
conf_status: true,
conf_spec: 0,
conf_sort: 0,
};
axios.post('/admin/conf/getList', Object.assign({}, PostBase))
.then(function (response) {
that.groupList = response.data.data;
if (response.data.code == CODE_SUCCESS) {
that.dialogFormAdd = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个配置, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/conf/delete', Object.assign({}, PostBase, {
conf_id: row.conf_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
clickStatus(row) {
var that = this;
axios.post(row.conf_status ? '/admin/conf/enable' : '/admin/conf/disable', Object.assign({}, PostBase, {
conf_id: row.conf_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/conf/getList', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.groupList = response.data.data;
axios.post('/admin/conf/detail', Object.assign({}, PostBase, {
conf_id: row.conf_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
response.data.data.conf_status = response.data.data.conf_status?true:false;
response.data.data.conf_type = response.data.data.conf_type.toString();
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/conf/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
}
}
})
</script>
</html>

View File

@@ -0,0 +1,408 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加</el-button>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-delete" size="small" @click="postMultDelete" plain>批量删除</el-button>
</el-form-item>
</el-form>
<el-table :data="dataList" @selection-change="changeSelection" v-loading="loading">
<el-table-column type="selection" width="50">
</el-table-column>
<el-table-column prop="group_id" label="组ID" width="100">
</el-table-column>
<el-table-column prop="group_name" label="组名称" width="200">
</el-table-column>
<el-table-column prop="group_desc" label="组描述">
</el-table-column>
</el-table-column>
<el-table-column label="禁用" width="80">
<template slot-scope="scope">
<el-switch v-model="scope.row.group_status==1?true:false" active-color="#ff4949"
@change="clickStatus(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-link type="primary" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>&nbsp;
<el-link type="primary" @click="clickAuth(scope.row)" :underline="false">授权</el-link>&nbsp;
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</template>
</el-table-column>
</el-table>
<!-- 添加框 -->
<el-dialog title="添加用户组" :visible.sync="dialogFormAdd" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formAdd" status-icon :rules="rules" ref="formAdd">
<el-form-item label="组名称" :label-width="formLabelWidth" prop="group_name">
<el-input size="medium" autocomplete="off" v-model="formAdd.group_name"></el-input>
</el-form-item>
<el-form-item label="组描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.group_desc"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改用户组" :visible.sync="dialogFormEdit" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formEdit" status-icon :rules="rules" ref="formEdit">
<el-form-item label="组名称" :label-width="formLabelWidth" prop="group_name">
<el-input size="medium" autocomplete="off" v-model="formEdit.group_name"></el-input>
</el-form-item>
<el-form-item label="组描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.group_desc"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit">确认修改</el-button>
</div>
</el-dialog>
<!-- 授权框 -->
<el-dialog class="pub_dialog" title="用户组授权" :visible.sync="dialogFormAuth" :modal-append-to-body='false' append-to-body
width="60%" :close-on-click-modal='false'>
<div style="padding: 10px 30px;">
<el-tree :data="nodeList" @check="currentChecked" show-checkbox node-key="node_id" :props="defaultProps" :default-checked-keys="defaultkeys"></el-tree>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAuth">确认授权</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
checkAll: false,
search: {
group_status: "",
keyword: "",
filter: "group_id"
},
formLabelWidth: '80px',
dialogFormAdd: false,
dialogFormEdit: false,
dialogFormAuth: false,
loading: true,
dataList: [],
groupList: [],
selectList: [],
selectNodeList: [],
selectedGroupId: 0,
nodeList: [],
defaultProps: {
children: 'sub',
label: 'node_title'
},
defaultkeys: [],
form: {
page: 1
},
formAdd: {},
formEdit: {},
rules: {
group_name: [
{ required: true, message: '组名称必须填写', trigger: 'blur' },
],
}
}
},
methods: {
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何用户!');
return;
}
this.$confirm('即将删除选中的用户, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/group/delete', Object.assign({}, PostBase, {
group_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].group_id);
}
},
postAuth() {
var that = this;
axios.post('/admin/group/authorize', Object.assign({}, PostBase, {
node_ids: that.selectNodeList.join(','),
group_id: that.selectedGroupId
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAuth = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
postEdit() {
var that = this;
that.$refs['formEdit'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/group/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
postAdd() {
var that = this;
that.$refs['formAdd'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/group/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
clickAdd() {
var that = this;
that.formAdd = {};
axios.post('/admin/group/getList', Object.assign({}, PostBase))
.then(function (response) {
that.groupList = response.data.data;
if (response.data.code == CODE_SUCCESS) {
that.dialogFormAdd = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个用户, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/group/delete', Object.assign({}, PostBase, {
group_id: row.group_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
clickStatus(row) {
var that = this;
axios.post(row.group_status ? '/admin/group/enable' : '/admin/group/disable', Object.assign({}, PostBase, {
group_id: row.group_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickAuth(row) {
var that = this;
that.selectNodeList = [];
that.selectedGroupId = row.group_id;
axios.post('/admin/node/getList', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.nodeList = response.data.data.data;
that.dialogFormAuth = true;
that.getAuthList(row);
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
getAuthList(row) {
var that = this;
that.defaultkeys = [];
axios.post('/admin/group/getAuthorize', Object.assign({}, PostBase, {
group_id: row.group_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.defaultkeys = [];
for (var i in response.data.data) {
that.defaultkeys.push(response.data.data[i].auth_node);
}
that.dialogFormAuth = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('设置选中状态失败');
});
},
currentChecked(nodeObj, SelectedObj) {
this.selectNodeList = SelectedObj.checkedKeys
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/group/getList', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.groupList = response.data.data;
axios.post('/admin/group/detail', Object.assign({}, PostBase, {
group_id: row.group_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/group/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
}
}
})
</script>
</html>

View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<title>后台管理系统</title>
{include file="common/header"/}
<div class="homecontainer" style="height: 100%;display: flex;align-items: center;justify-content: center;">
<div>
<img src="/static/admin/images/logo@2x.png" alt="">
<p style="color: #999999;">@资源管理系统</p>
</div>
</div>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
data: {}
}
},
methods: {
}
});
</script>
</html>

View File

@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-table :data="dataList.data" v-loading="loading">
<el-table-column prop="id" label="ID" align="center" width="100">
</el-table-column>
<el-table-column prop="name" label="name">
</el-table-column>
<el-table-column prop="ip" label="IP">
</el-table-column>
<el-table-column prop="domain" label="address">
</el-table-column>
<el-table-column prop="create_time" label="创建时间" align="center" width="200">
</el-table-column>
<el-table-column prop="update_time" label="最新时间" align="center" width="200">
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
loading: true,
dataList: [],
form: {
page: 1,
per_page: 10,
order: 'id desc'
},
}
},
created() {
this.getList();
},
methods: {
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/log/getList', Object.assign({}, PostBase, that.form))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
for (let i = 0; i < that.dataList.data.length; i++) {
if(!that.dataList.data[i].domain){
that.getAdd(i)
}
}
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
});
},
getAdd(index){
var that = this;
axios.get('https://api.suyanw.cn/api/ipcha.php?ip='+that.dataList.data[index].ip)
.then(function (res) {
that.dataList.data[index].domain = res.data.text
axios.post('/admin/log/setDomain', Object.assign({}, PostBase, {
id: that.dataList.data[index].id,
domain: that.dataList.data[index].domain,
}))
.then(function (response) {
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
});
})
},
}
})
</script>
</html>

View File

@@ -0,0 +1,462 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加</el-button>
</el-form-item>
<div style="float:right">
<el-form-item style="width:120px;">
<el-select placeholder="显示状态" size="small" v-model="search.node_show">
<el-option value="" label="全部状态">
</el-option>
<el-option v-for="show in showList" :value="show.show_id" :label="show.show_title">
</el-option>
</el-select>
</el-form-item>
<el-form-item style="width:120px;">
<el-select placeholder="筛选类别" size="small" v-model="search.filter">
<el-option value="node_id" label="节点ID">
</el-option>
<el-option value="node_title" label="节点名称">
</el-option>
<el-option value="node_desc" label="节点描述">
</el-option>
<el-option value="node_module" label="模块">
</el-option>
<el-option value="node_controller" label="控制器">
</el-option>
<el-option value="node_action" label="方法">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input placeholder="输入关键词搜索" size="small" v-model="search.keyword"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="getList_search" plain>搜索</el-button>
</el-form-item>
</div>
</el-form>
<el-table :data="dataList" default-expand-all @selection-change="changeSelection" v-loading="loading" row-key="node_id" :tree-props="{children: 'sub', hasChildren: 'hasChildren'}">
<el-table-column prop="node_id" label="ID" width="120">
</el-table-column>
<el-table-column prop="node_title" label="节点名称">
<template slot-scope="scope">
<i :class="scope.row.node_icon" style="font-size: 16px;"></i>&nbsp;{{scope.row.node_title}}
</template>
</el-table-column>
<el-table-column label="节点地址">
<template slot-scope="scope">
{{scope.row.node_module+"/"+scope.row.node_controller+"/"+scope.row.node_action}}
</template>
</el-table-column>
<el-table-column prop="node_order" label="排序" width="">
</el-table-column>
<el-table-column label="隐藏" width="80">
<template slot-scope="scope">
<el-switch v-model="scope.row.node_show==0?true:false" active-color="#ff4949"
@change="clickShow(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-link type="primary" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>&nbsp;
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</template>
</el-table-column>
</el-table>
<!-- 添加框 -->
<el-dialog title="添加节点" :visible.sync="dialogFormAdd" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formAdd" status-icon :rules="rules" ref="formAdd">
<el-form-item label="节点名称" :label-width="formLabelWidth" prop="node_title">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_title"></el-input>
</el-form-item>
<el-form-item label="节点描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_desc"></el-input>
</el-form-item>
<el-form-item label="节点图标" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_icon"></el-input>
</el-form-item>
<el-form-item label="所属模块" :label-width="formLabelWidth" prop="node_module">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_module"></el-input>
</el-form-item>
<el-form-item label="控制器" :label-width="formLabelWidth" prop="node_controller">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_controller"></el-input>
</el-form-item>
<el-form-item label="方法" :label-width="formLabelWidth" prop="node_action">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_action"></el-input>
</el-form-item>
<el-form-item label="是否显示" :label-width="formLabelWidth">
<el-select placeholder="请选择是否显示到菜单" size="small" v-model="formAdd.node_show">
<el-option v-for="show in showList" :value="show.show_id" :label="show.show_title">
</el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="父级菜单" :label-width="formLabelWidth">
<el-select placeholder="请选择菜单" size="small" v-model="formAdd.node_pid">
<el-option v-for="parent in parentList" :value="parent.node_id" :label="parent.node_title">
</el-option>
</el-select>
</el-form-item> -->
<el-form-item label="父级菜单" :label-width="formLabelWidth">
<el-cascader :options="parentList" v-model="formAdd.node_pid" :props="props" :show-all-levels="false">
</el-cascader>
</el-form-item>
<el-form-item label="显示顺序" :label-width="formLabelWidth" prop="node_order">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_order"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改节点" :visible.sync="dialogFormEdit" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formEdit" status-icon :rules="rules" ref="formEdit">
<el-form-item label="节点名称" :label-width="formLabelWidth" prop="node_title">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_title"></el-input>
</el-form-item>
<el-form-item label="节点描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_desc"></el-input>
</el-form-item>
<el-form-item label="节点图标" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_icon"></el-input>
</el-form-item>
<el-form-item label="所属模块" :label-width="formLabelWidth" prop="node_module">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_module"></el-input>
</el-form-item>
<el-form-item label="控制器" :label-width="formLabelWidth" prop="node_controller">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_controller"></el-input>
</el-form-item>
<el-form-item label="方法" :label-width="formLabelWidth" prop="node_action">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_action"></el-input>
</el-form-item>
<el-form-item label="是否显示" :label-width="formLabelWidth">
<el-select placeholder="请选择是否显示到菜单" size="small" v-model="formEdit.node_show">
<el-option v-for="show in showList" :value="show.show_id" :label="show.show_title">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="父级菜单" :label-width="formLabelWidth">
<el-cascader :options="parentList" v-model="formEdit.node_pid" :props="props" :show-all-levels="false"></el-cascader>
</el-form-item>
<el-form-item label="显示顺序" :label-width="formLabelWidth" prop="node_order">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_order"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit">确认修改</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
search: {
node_show: "",
keyword: "",
filter: "node_id"
},
formLabelWidth: '80px',
dialogFormAdd: false,
dialogFormEdit: false,
loading: true,
dataList: [],
parentList: [],
props: {
checkStrictly: true,
emitPath: false,
value: 'node_id',
label: 'node_title',
children: 'sub',
},
showList: [
{
show_id: 0,
show_title: "隐藏"
},
{
show_id: 1,
show_title: "显示"
}
],
selectList: [],
formAdd: {
node_readonly: 0,
node_pid: 0,
node_order: 1,
node_show: 1,
},
formEdit: {
node_readonly: 0,
node_pid: 0,
},
rules: {
node_title: [
{ required: true, message: '节点名称必须填写', trigger: 'blur' },
],
node_controller: [
// { required: true, pattern: /^[a-z]+$/, message: '控制器为有效小写字母', trigger: 'blur' },
],
node_module: [
{ required: true, pattern: /^[a-z]+$/, message: '模块名为有效小写字母', trigger: 'blur' },
],
node_action: [
{ required: true, pattern: /^[a-z]+$/, message: '方法名为有效小写字母', trigger: 'blur' },
],
node_order: [
{ required: true, pattern: /^\d$/, message: '顺序为有效自然数', trigger: 'blur' },
],
}
}
},
methods: {
getList_search() {
this.form.page = 1;
this.getList();
},
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何节点!');
return;
}
this.$confirm('即将删除选中的节点, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/node/delete', Object.assign({}, PostBase, {
node_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].node_id);
}
},
postEdit() {
var that = this;
axios.post('/admin/node/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
postAdd() {
var that = this;
axios.post('/admin/node/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickAdd() {
var that = this;
that.formAdd = {
node_readonly: 0,
node_pid: 0,
node_order: 1,
node_show: 1,
};
axios.post('/admin/node/getList', Object.assign({}, PostBase))
.then(function (response) {
that.groupList = response.data.data;
if (response.data.code == CODE_SUCCESS) {
that.dialogFormAdd = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个节点, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/node/delete', Object.assign({}, PostBase, {
node_id: row.node_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
clickShow(row) {
var that = this;
axios.post(row.node_show ? '/admin/node/hide_menu' : '/admin/node/show_menu', Object.assign({}, PostBase, {
node_id: row.node_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/node/getList', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.groupList = response.data.data;
axios.post('/admin/node/detail', Object.assign({}, PostBase, {
node_id: row.node_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
response.data.data.node_pid = response.data.data.node_pid==0?'0':response.data.data.node_pid
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/node/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (res) {
that.loading = false;
if (res.data.code == 200) {
that.dataList = JSON.parse(JSON.stringify(res.data.data.data));
that.parentList = [];
that.parentList.push({
node_id: "0",
node_title: "顶级菜单",
sub: [],
});
for (var i in res.data.data.data) {
res.data.data.data[i].node_id = res.data.data.data[i].node_id
that.parentList.push(res.data.data.data[i]);
}
for (let item of that.parentList) {
if(item.sub.length>0){
for (let items of item.sub) {
items.sub = undefined
}
}else{
item.sub = undefined
}
}
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
}
}
})
</script>
</html>

View File

@@ -0,0 +1,330 @@
<!DOCTYPE html>
<html>
<head>
<title>资源分类</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加</el-button>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-warning-outline" size="small" @click="dayShow=true" plain>如何每日更新?</el-button>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-warning-outline" size="small" @click="allShow=true" plain>如何全部转存?</el-button>
</el-form-item>
</el-form>
<el-table :data="dataList" @selection-change="changeSelection" v-loading="loading">
<el-table-column type="selection" width="50">
</el-table-column>
<el-table-column prop="source_category_id" label="ID" width="60">
</el-table-column>
<el-table-column label="分类名称">
<template slot-scope="scope">
<img :src="scope.row.image" style="width: 30px;height:30px;vertical-align: middle;" v-if="scope.row.image" />
<span style="vertical-align: middle;margin-left: 5px">{{scope.row.name}}</span>
</template>
</el-table-column>
<el-table-column label="是否每日更新" width="150" align="center">
<template slot-scope="scope">
<el-switch v-model="scope.row.is_update==1?true:false"
@change="clickStatus(scope.row,1)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="是否前台展示" width="150" align="center">
<template slot-scope="scope">
<el-switch v-model="scope.row.status==1?false:true"
@change="clickStatus(scope.row,0)">
</el-switch>
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="150" align="center">
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-link type="primary" @click="s2Btn(scope.row)" :underline="false">一键转存</el-link>&nbsp;&nbsp;&nbsp;&nbsp;
<el-link type="primary" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>&nbsp;&nbsp;&nbsp;&nbsp;
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</template>
</el-table-column>
</el-table>
<!-- 添加框 -->
<el-dialog title="添加资源分类名称" :visible.sync="dialogFormAdd" width="500px" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formAdd" :rules="rules" ref="formAdd">
<el-form-item prop="name" label="分类名称" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.name"></el-input>
</el-form-item>
<el-form-item prop="image" label="图标" :label-width="formLabelWidth">
<Single v-model="formAdd.image"></Single>
</el-form-item>
<el-form-item prop="sort" label="排序" :label-width="formLabelWidth">
<el-input-number v-model="formAdd.sort" :min="0" :max="999" size="medium" style="width: 120px;"
controls-position="right" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd()">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改资源分类信息" :visible.sync="dialogFormEdit" width="500px" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formEdit" :rules="rules" ref="formEdit">
<el-form-item prop="name" label="分类名称" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.name" disabled ></el-input>
</el-form-item>
<el-form-item prop="image" label="图标" :label-width="formLabelWidth">
<Single v-model="formEdit.image"></Single>
</el-form-item>
<el-form-item prop="sort" label="排序" :label-width="formLabelWidth">
<el-input-number v-model="formEdit.sort" :min="0" :max="999" size="medium" style="width: 120px;"
controls-position="right" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit()">确认修改</el-button>
</div>
</el-dialog>
<!-- 每日更新 -->
<el-dialog title="每日更新" :visible.sync="dayShow" width="500px" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<div style="margin-bottom: 20px;font-size:14px;color:#666;line-height: 2">
<font color=orangered>功能暂停使用</font>
<p>自动更新:<font color=orangered>转存当日及昨天的资源数据;</font></p>
<font color=orangered>将此接口添加到计划任务中,计划任务每日执行一次即可;</font>
<p>接口地址:{{domain}}/api/source/day</p>
<p>Tips添加计划任务后方可生效名称重复的资源会跳过转存</p>
<p>宝塔任务类型访问URL-GET</p>
</div>
</el-dialog>
<!-- 全部更新 -->
<el-dialog title="全部转存" :visible.sync="allShow" width="500px" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<div style="margin-bottom: 20px;font-size:14px;color:#666;line-height: 2">
<font color=orangered>功能暂停使用</font>
<p>全部转存:<font color=orangered>一键转存所有资源到自己的网盘及系统中</font></p>
<font color=orangered>全部转存速度比较慢,提交后请耐心等待;名称重复的资源会跳过转存;</font>
<p>全部转存需要按类别转存:见下方列表一键转存按钮</p>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
formLabelWidth: '80px',
dialogFormAdd: false,
dialogFormEdit: false,
loading: true,
dataList: [],
selectList: [],
formAdd: {
image: '',
sort: 0
},
formEdit: {
},
rules: {
name: [ { required: true, message: '请输入分类名称', trigger: 'blur' }],
},
allShow: false,
dayShow: false,
domain: window.location.protocol+'//'+window.location.host
}
},
methods: {
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].source_category_id);
}
},
postEdit() {
var that = this;
that.$refs["formEdit"].validate((valid) => {
if (valid) {
axios.post('/admin/source_category/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}
});
},
postAdd() {
var that = this;
that.$refs['formAdd'].validate((valid) => {
if (valid) {
axios.post('/admin/source_category/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}
});
},
clickAdd() {
var that = this;
that.formAdd = { sort: 0,image: '' };
that.dialogFormAdd = true;
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个分类, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/source_category/delete', Object.assign({}, PostBase, {
source_category_id: row.source_category_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
clickStatus(row,type) {
var that = this;
let url = row.status ? '/admin/source_category/enable' : '/admin/source_category/disable'
if(type==1){
url = !row.is_update ? '/admin/source_category/enable' : '/admin/source_category/disable'
}
axios.post(url, Object.assign({}, PostBase, {
source_category_id: row.source_category_id,
type: type
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/source_category/detail', Object.assign({}, PostBase, {
source_category_id: row.source_category_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.formEdit = response.data.data;
that.formEdit.image = that.formEdit.image||''
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/source_category/getList', Object.assign({}, PostBase))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
},
s2Btn(row){
let that = this
if(row.source_category_id!=1) return that.$message.error('当前版本仅支持短剧');
this.$confirm('全部转存速度比较慢,提交后请耐心等待,该操作不可暂停, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/source/transferAll', Object.assign({}, PostBase,{
source_category_id: row.source_category_id
}))
.then(function (res) {
if (res.data.code == 200) {
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
});
that.$message({
message: "已提交任务,稍后查看结果",
type: 'success'
});
}).catch(() => {});
},
}
})
</script>
</html>

View File

@@ -0,0 +1,390 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
<style>
textarea{
height: 300px;
}
</style>
{include file="common/header"/}
<el-card class="box-card" shadow="never">
<el-tabs v-model="activeName">
<el-tab-pane label="夸克网盘" name="0">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>夸克网盘</span>
</div>
<div style="font-size:14px;color:#666;">
<el-form :model="form">
<el-form-item label="设置cookie">
<el-input style="width: 100%;" v-model="form.quark_cookie" placeholder="请输入">
<el-button slot="prepend" @click="getFile(0)">账号检测</el-button>
</el-input>
<span class="f_tips">cookie修改后请保存后再选择转存目录和检测</span>
</el-form-item>
<el-form-item label="默认转存目录">
<el-input style="width: 100%" v-model="form.quark_file" placeholder="请输入或选择">
<div slot="prepend" style="position: relative;">
<p>请选择</p>
<el-cascader style="opacity: 0; height: 38px; position: absolute;inset: 0;" v-model="form.quark_file" :props="quark_props"></el-cascader>
</div>
</el-input>
</el-form-item>
<el-form-item label="临时资源目录">
<el-input style="width: 100%" v-model="form.quark_file_time" placeholder="请输入或选择">
<div slot="prepend" style="position: relative;">
<p>请选择</p>
<el-cascader style="opacity: 0; height: 38px; position: absolute;inset: 0;" v-model="form.quark_file_time" :props="quark_props"></el-cascader>
</div>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
</el-tab-pane>
<el-tab-pane label="阿里云盘" name="1">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>阿里云盘</span>
</div>
<div style="font-size:14px;color:#666;">
<el-form :model="form">
<el-form-item label="设置Token">
<el-input style="width: 100%;" v-model="form.Authorization" placeholder="请输入">
<el-button slot="prepend" @click="getFile(1)">账号检测</el-button>
</el-input>
<span class="f_tips">token修改后请保存后再选择转存目录和检测</span>
</el-form-item>
<el-form-item label="默认转存目录">
<el-input style="width: 100%" v-model="form.ali_file" placeholder="请输入或选择">
<div slot="prepend" style="position: relative;">
<p>请选择</p>
<el-cascader style="opacity: 0; height: 38px; position: absolute;inset: 0;" v-model="form.ali_file" :props="ali_props"></el-cascader>
</div>
</el-input>
</el-form-item>
<el-form-item label="临时资源目录">
<el-input style="width: 100%" v-model="form.ali_file_time" placeholder="请输入或选择">
<div slot="prepend" style="position: relative;">
<p>请选择</p>
<el-cascader style="opacity: 0; height: 38px; position: absolute;inset: 0;" v-model="form.ali_file_time" :props="ali_props"></el-cascader>
</div>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存</el-button>
</el-form-item>
</el-form>
<p>Tips转存目录不能为空为空将无法转存; <font color=orangered>阿里网盘禁止香港及海外服务器调用分享接口</font></p>
</div>
</el-card>
</el-tab-pane>
<el-tab-pane label="百度网盘" name="2">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>百度网盘</span>
</div>
<div style="font-size:14px;color:#666;">
<el-form :model="form">
<el-form-item label="设置cookie">
<el-input style="width: 100%;" v-model="form.baidu_cookie" placeholder="请输入">
<el-button slot="prepend" @click="getFile(2)">账号检测</el-button>
</el-input>
<span class="f_tips">cookie修改后请保存后再选择转存目录和检测</span>
</el-form-item>
<el-form-item label="默认转存目录">
<el-input style="width: 100%;" v-model="form.baidu_file" placeholder="请输入或选择">
<div slot="prepend" style="position: relative;">
<p>请选择</p>
<el-cascader style="opacity: 0; height: 38px; position: absolute;inset: 0;" v-model="form.baidu_file" :props="baidu_props"></el-cascader>
</div>
</el-input>
</el-form-item>
<el-form-item label="临时资源目录">
<el-input style="width: 100%;" v-model="form.baidu_file_time" placeholder="请输入或选择">
<div slot="prepend" style="position: relative;">
<p>请选择</p>
<el-cascader style="opacity: 0; height: 38px; position: absolute;inset: 0;" v-model="form.baidu_file_time" :props="baidu_props" ></el-cascader>
</div>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
</el-tab-pane>
<el-tab-pane label="UC网盘" name="3">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>UC网盘</span>
</div>
<div style="font-size:14px;color:#666;">
<el-form :model="form">
<el-form-item label="设置cookie">
<el-input style="width: 100%;" v-model="form.uc_cookie" placeholder="请输入">
<el-button slot="prepend" @click="getFile(3)">账号检测</el-button>
</el-input>
<span class="f_tips">cookie修改后请保存后再选择转存目录和检测</span>
</el-form-item>
<el-form-item label="默认转存目录">
<el-input style="width: 100%" v-model="form.uc_file" placeholder="请输入或选择">
<div slot="prepend" style="position: relative;">
<p>请选择</p>
<el-cascader style="opacity: 0; height: 38px; position: absolute;inset: 0;" v-model="form.uc_file" :props="uc_props"></el-cascader>
</div>
</el-input>
</el-form-item>
<el-form-item label="临时资源目录">
<el-input style="width: 100%" v-model="form.uc_file_time" placeholder="请输入或选择">
<div slot="prepend" style="position: relative;">
<p>请选择</p>
<el-cascader style="opacity: 0; height: 38px; position: absolute;inset: 0;" v-model="form.uc_file_time" :props="uc_props"></el-cascader>
</div>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
</el-tab-pane>
<el-tab-pane label="迅雷云盘" name="4">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>迅雷云盘</span>
</div>
<div style="font-size:14px;color:#666;">
<p>Tips<font color=orangered>迅雷云盘暂不支持</font></p>
<el-form :model="form">
<el-form-item label="设置cookie">
<el-input style="width: 100%;" v-model="form.xunlei_cookie" placeholder="请输入">
</el-input>
<span class="f_tips">cookie修改后请保存后再选择转存目录和检测</span>
</el-form-item>
<el-form-item label="默认转存目录">
<el-input style="width: 100%" v-model="form.xunlei_file" placeholder="请输入或选择">
</el-input>
</el-form-item>
<el-form-item label="临时资源目录">
<el-input style="width: 100%" v-model="form.xunlei_file_time" placeholder="请输入或选择">
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
</el-tab-pane>
</el-tabs>
</el-card>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
activeName: '0',
configKeys: ['quark_cookie', 'quark_file', 'quark_file_time','baidu_cookie', 'baidu_file', 'baidu_file_time','Authorization', 'ali_file', 'ali_file_time','uc_cookie', 'uc_file', 'uc_file_time','xunlei_cookie', 'xunlei_file', 'xunlei_file_time'],
form: {
quark_file: ''
},
quark_files: [],
quark_props: {
lazy: true,
emitPath: false,
checkStrictly: true,
lazyLoad (node, resolve) {
const { level, value } = node;
let that = this;
axios.post('/admin/source/getFiles', Object.assign({
type: 0,
pdir_fid: value || 0
}, PostBase))
.then(function (res) {
if (res.data.code == 200) {
// 只显示文件夹
const nodes = (res.data.data || [])
.map(item => ({
value: item.fid,
label: item.file_name,
disabled: !item.dir,
}));
resolve(nodes);
} else {
resolve([]);
}
})
.catch(function (error) {
console.error(error);
resolve([]);
});
}
},
baidu_props: {
lazy: true,
emitPath: false,
checkStrictly: true,
lazyLoad (node, resolve) {
const { level, value } = node;
let that = this;
axios.post('/admin/source/getFiles', Object.assign({
type: 2,
pdir_fid: value || 0
}, PostBase))
.then(function (res) {
if (res.data.code == 200) {
// 只显示文件夹
const nodes = (res.data.data || [])
.map(item => ({
value: item.path,
label: item.server_filename,
disabled: !item.isdir,
}));
resolve(nodes);
} else {
resolve([]);
}
})
.catch(function (error) {
console.error(error);
resolve([]);
});
}
},
ali_props: {
lazy: true,
emitPath: false,
checkStrictly: true,
lazyLoad (node, resolve) {
const { level, value } = node;
let that = this;
axios.post('/admin/source/getFiles', Object.assign({
type: 1,
pdir_fid: value || 0
}, PostBase))
.then(function (res) {
if (res.data.code == 200) {
// 只显示文件夹
const nodes = (res.data.data || [])
.map(item => ({
value: item.file_id,
label: item.name,
disabled: item.type!='folder',
}));
resolve(nodes);
} else {
resolve([]);
}
})
.catch(function (error) {
console.error(error);
resolve([]);
});
}
},
uc_props: {
lazy: true,
emitPath: false,
checkStrictly: true,
lazyLoad (node, resolve) {
const { level, value } = node;
let that = this;
axios.post('/admin/source/getFiles', Object.assign({
type: 3,
pdir_fid: value || 0
}, PostBase))
.then(function (res) {
if (res.data.code == 200) {
// 只显示文件夹
const nodes = (res.data.data || [])
.map(item => ({
value: item.fid,
label: item.file_name,
disabled: !item.dir,
}));
resolve(nodes);
} else {
resolve([]);
}
})
.catch(function (error) {
console.error(error);
resolve([]);
});
}
},
};
},
created() {
this.getData();
},
methods: {
getData(){
let that = this
axios.post('/admin/conf/getBaseConfig', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == 200) {
for (let item of response.data.data) {
if (that.configKeys.includes(item.conf_key)) {
that.$set(that.form, item.conf_key, item.conf_value)
}
}
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
});
},
onSubmit(){
let that = this
axios.post('/admin/conf/updateBaseConfig', Object.assign({}, PostBase, that.form))
.then(function (response) {
if (response.data.code == 200) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
getFile(type){
let that = this
axios.post('/admin/source/getFiles', Object.assign({
type
}, PostBase))
.then(function (res) {
if (res.data.code == 200) {
that.$message.success("已登录cookie可用");
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
}
})
</script>
</html>

View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-table :data="dataList.data" v-loading="loading">
<el-table-column prop="id" label="ID" align="center" width="100">
</el-table-column>
<el-table-column prop="content" label="用户想要的资源描述">
</el-table-column>
<el-table-column prop="create_time" label="提交时间" align="center" width="200">
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
loading: true,
dataList: [],
form: {
page: 1,
per_page: 10,
order: 'id desc'
},
}
},
created() {
this.getList();
},
methods: {
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/feedback/getList', Object.assign({}, PostBase, that.form))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
});
},
}
})
</script>
</html>

View File

@@ -0,0 +1,522 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true" @submit.native.prevent>
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加资源</el-button>
<el-button icon="el-icon-delete" size="small" @click="postMultDelete" plain>批量删除</el-button>
<el-button icon="el-icon-document-copy" size="small" @click="getExport" plain>导出资源</el-button>
<el-button icon="el-icon-plus" size="small" @click="ImportShow" plain>表格导入</el-button>
<el-button icon="el-icon-plus" size="small" @click="ImportBatch" plain>批量导入</el-button>
</el-form-item>
<div style="float:right">
<el-form-item style="width:120px;">
<el-select size="small" v-model="search.source_category_id" placeholder="筛选分类">
<el-option v-for="item in category" :key="item.source_category_id" :label="item.name" :value="item.source_category_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input placeholder="输入关键词搜索" size="small" v-model="search.keyword" @keyup.enter.native="getList_search"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="getList_search" plain>搜索
</el-button>
<el-button icon="el-icon-refresh-left" size="small" @click="getList_search(0)" plain>重置</el-button>
</el-form-item>
</div>
</el-form>
<el-table :data="dataList.data" @selection-change="changeSelection" v-loading="loading">
<el-table-column type="selection" width="50">
</el-table-column>
<el-table-column prop="source_id" label="ID" width="80">
</el-table-column>
<el-table-column prop="title" label="资源名称">
</el-table-column>
<el-table-column prop="source_category_id_name" label="资源分类">
</el-table-column>
<el-table-column prop="url" label="资源地址" align="center">
</el-table-column>
<el-table-column prop="create_time" label="入库时间" align="center" width="200">
</el-table-column>
<el-table-column prop="update_time" label="更新时间" align="center" width="200">
</el-table-column>
<el-table-column label="操作" width="180" align="center">
<template slot-scope="scope">
<div class="order-text">
<p>
<el-link type="success" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>
</p>
<p>
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</p>
</div>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
<!-- 添加框 -->
<el-dialog title="添加资源" :visible.sync="dialogFormAdd" :modal-append-to-body='false' append-to-body
:close-on-click-modal='false' width="680px">
<el-form :model="formAdd" :rules="rules" ref="formAdd">
<el-form-item prop="source_category_id" label="资源分类" :label-width="formLabelWidth">
<el-select size="medium" v-model="formAdd.source_category_id" placeholder="请选择分类">
<el-option v-for="item in category" :key="item.source_category_id" :label="item.name" :value="item.source_category_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="title" label="资源名称" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" placeholder="请输入资源名称" v-model="formAdd.title"></el-input>
</el-form-item>
<el-form-item prop="url" label="资源地址" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" placeholder="请输入资源地址" v-model="formAdd.url"></el-input>
</el-form-item>
<el-form-item label="关键词搜索" :label-width="formLabelWidth">
<el-input type="textarea" :rows="5" size="medium" autocomplete="off" placeholder="一行一个名称" v-model="formAdd.description"></el-input>
</el-form-item>
<el-form-item label="资源介绍" :label-width="formLabelWidth">
<el-input type="textarea" :rows="5" size="medium" autocomplete="off" placeholder="" v-model="formAdd.vod_content"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd()">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改资源" :visible.sync="dialogFormEdit" :modal-append-to-body='false' append-to-body
:close-on-click-modal='false' width="680px">
<el-form :model="formEdit" :rules="rules" ref="formEdit">
<el-form-item prop="source_category_id" label="资源分类" :label-width="formLabelWidth">
<el-select size="medium" v-model="formEdit.source_category_id" placeholder="请选择分类" clearable>
<el-option v-for="item in category" :key="item.source_category_id" :label="item.name"
:value="item.source_category_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="title" label="资源名称" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" placeholder="请输入资源名称" v-model="formEdit.title"></el-input>
</el-form-item>
<el-form-item prop="url" label="资源地址" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" placeholder="请输入资源地址" v-model="formEdit.url"></el-input>
</el-form-item>
<el-form-item label="关键词搜索" :label-width="formLabelWidth">
<el-input type="textarea" :rows="5" size="medium" autocomplete="off" placeholder="一行一个名称" v-model="formEdit.description"></el-input>
</el-form-item>
<el-form-item label="资源介绍" :label-width="formLabelWidth">
<el-input type="textarea" :rows="5" size="medium" autocomplete="off" placeholder="" v-model="formEdit.vod_content"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit()">确认修改</el-button>
</div>
</el-dialog>
<!-- 夸克导入数据 -->
<el-dialog title="导入资源" :visible.sync="dialogImport" :modal-append-to-body='false' append-to-body
:close-on-click-modal='false' width="600px">
<el-form :model="Importform">
<el-form-item prop="source_category_id" label="资源分类" label-width="90px">
<el-select size="medium" v-model="Importform.source_category_id" placeholder="请选择分类" clearable>
<el-option v-for="item in category" :key="item.source_category_id" :label="item.name"
:value="item.source_category_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="" label-width="90px">
<el-upload class="upload-demo" :data="Importform" name="file"
ref="ImportUpload"
drag
:auto-upload="false"
limit="1"
:on-exceed="handleExceed"
:on-success="handleAvatarSuccess"
action="/admin/source/imports"
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
<span style="color: #999;">请使用xlsx格式第一列资源名称 第二列资源地址</span>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="ImportPost()">提交</el-button>
</div>
</el-dialog>
<!-- 批量导入数据 -->
<el-dialog title="导入资源" :visible.sync="dialogBatch" :modal-append-to-body='false' append-to-body
:close-on-click-modal='false' width="790px">
<el-form :model="Batchform">
<el-form-item prop="type" label="选择方式" label-width="70px">
<el-radio-group v-model="Batchform.type">
<el-radio-button :label="1">直接导入</el-radio-button>
<el-radio-button :label="2">转存分享导入</el-radio-button>
</el-radio-group>
<p style="color: #999;" v-if='Batchform.type==1'>直接导入链接校验有效后直接入库Tips该功能不会检测是否重复</p>
<p style="color: #999;" v-else-if='Batchform.type==2'>将资源转存到自己网盘后分享入库Tips该功能不会检测是否重复</p>
<span style="color: #999;" v-if='Batchform.type==1'>支持<font color=orangered>夸克、阿里、UC、百度</font>的网盘资源(一次最多可以上传500条资源)</span>
<span style="color: #999;" v-else-if='Batchform.type==2'>支持<font color=orangered>夸克、阿里、UC、百度</font>的网盘资源(一次最多可以上传500条资源)</span>
</el-form-item>
<el-form-item prop="source_category_id" label="资源分类" label-width="70px" v-if="Batchform.type">
<el-select size="medium" v-model="Batchform.source_category_id" placeholder="请选择分类" clearable>
<el-option v-for="item in category" :key="item.source_category_id" :label="item.name"
:value="item.source_category_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="urls" label="资源分类" label-width="70px" v-if="Batchform.type">
<el-input
type="textarea"
placeholder="资源示例:
一条资源一行
https://pan.quark.cn/s/xxxxxxxx
https://www.alipan.com/s/xxxxxxxxx
https://drive.uc.cn/s/xxxxxxxxxxx
https://pan.baidu.com/s/xxxxxx?pwd=xxxx"
v-model="Batchform.urls"
rows="20"
show-word-limit
>
</el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="BatchPost()">提交</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
search: {
keyword: "",
filter: "title",
source_category_id: ''
},
formLabelWidth: '120px',
dialogFormAdd: false,
dialogFormEdit: false,
loading: true,
selectList: [],
dataList: [],
form: {
page: 1,
per_page: 10,
order: 'create_time desc'
},
formAdd: {
},
formEdit: {
},
rules: {
title: [{ required: true, message: '请输入资源名称', trigger: 'blur' }],
url: [{ required: true, message: '请输入资源地址', trigger: 'blur' }],
},
dialogImport: false,
Importform: {
},
category: [],
dialogBatch: false,
Batchform: {},
}
},
created() {
this.getcategory();
},
methods: {
getList_search(val) {
if (val == 0) {
this.search = {
keyword: "",
filter: "title",
source_category_id: ''
}
}
this.form.page = 1;
this.getList();
},
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
postEdit() {
var that = this;
that.$refs["formEdit"].validate((valid) => {
if (valid) {
axios.post('/admin/source/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}
});
},
postAdd() {
var that = this;
that.$refs['formAdd'].validate((valid) => {
if (valid) {
axios.post('/admin/source/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
});
}
});
},
clickAdd() {
var that = this;
that.formAdd = { status: 1, share_image: '' };
that.dialogFormAdd = true;
},
clickDelete(row) {
var that = this;
this.$confirm('删除后,资源将无法查看,是否继续删除?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/source/delete', Object.assign({}, PostBase, {
source_id: row.source_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
});
}).catch(() => {
});
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/source/detail', Object.assign({}, PostBase, {
source_id: row.source_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
response.data.data.source_category_id = response.data.data.source_category_id || undefined
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
});
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getcategory(){
var that = this;
axios.post('/admin/source_category/getList', Object.assign({}, PostBase))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.category = response.data.data;
that.getList();
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/source/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
that.setcategory()
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
});
},
setcategory(){
for (let item of this.dataList.data) {
for (let items of this.category) {
if(item.source_category_id == items.source_category_id){
item.source_category_id_name = items.name
}
}
}
},
//导入数据
ImportShow() {
this.Importform = {
}
this.dialogImport = true
},
handleExceed(files, fileList) {
this.$message.warning(`只能选择一个文件`);
},
handleAvatarSuccess(res, file) {
if (res.code == 200) {
this.getList();
this.$message({
message: res.message,
type: 'success'
});
this.dialogImport = false;
} else {
this.$message.error(res.message);
}
this.$refs.ImportUpload.clearFiles();
},
ImportPost(){
this.Importform = Object.assign(this.Importform, PostBase)
this.$nextTick(() => {
this.$refs.ImportUpload.submit();
})
},
//批量导入数据
ImportBatch() {
this.Batchform = {}
this.dialogBatch = true
},
BatchPost(){
var that = this;
if(!that.Batchform.type) return that.$message.error('请选择导入方式');
if(!that.Batchform.urls) return that.$message.error('请输入资源地址');
axios.post('/admin/source/transfer', Object.assign({}, PostBase, that.Batchform))
.then(function (res) {
})
.catch(function (error) {
that.$message.error('服务器内部错误');
});
that.$message({
message: "已提交任务,稍后查看结果",
type: 'success'
});
},
//数据导出
getExport(){
var that = this;
var filters = Object.assign({}, PostBase, that.search);
var url = '/admin/source/excel?';
for (let key in filters) {
url += key + "=" + filters[key] + "&";
}
window.open(url);
that.$message.success('数据导出成功');
},
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何资源!');
return;
}
this.$confirm('即将删除选中的资源, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/source/delete', Object.assign({}, PostBase, {
source_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].source_id);
}
},
}
})
</script>
</html>

View File

@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-table :data="dataList.data" v-loading="loading">
<el-table-column prop="name" label="任务名称">
</el-table-column>
<el-table-column prop="total_num" label="转存/导入总数" align="center">
</el-table-column>
<el-table-column prop="new_num" label="新增数" align="center">
</el-table-column>
<el-table-column prop="skip_num" label="重复跳过" align="center">
</el-table-column>
<el-table-column prop="fail_num" label="失败数" align="center">
</el-table-column>
<el-table-column prop="fail_dec" label="最新错误信息" align="center">
</el-table-column>
<el-table-column label="状态" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.end_time">已完成</el-tag>
<el-tag type="danger" v-else>转存中</el-tag>
</template>
</el-table-column>
<el-table-column prop="create_time" label="时间" align="center" width="240">
<template slot-scope="scope">
<p>任务开始:{{scope.row.create_time}}</p>
<p v-if="scope.row.end_time">任务结束:{{scope.row.end_time}}</p>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
loading: true,
dataList: [],
form: {
page: 1,
per_page: 10,
order: 'source_log_id desc'
},
}
},
created() {
this.getList();
},
methods: {
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/source_log/getList', Object.assign({}, PostBase, that.form))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
});
},
}
})
</script>
</html>

View File

@@ -0,0 +1,100 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span>系统数据清理</span>
</div>
<div class="text item">
<!-- <el-card class="box-card">
<div slot="header" class="clearfix">
<span>清理授权记录</span>
</div>
<div style="margin-bottom: 20px;font-size:14px;color:#666;">
用户组授权信息清理为
<font color=orangered>不可逆操作</font>,请谨慎操作!<br> 清理完毕后,除超级管理用户组外,其他任何用户组将无法访问系统任何功能!
<br> 建议仅在用户组权限混乱或出现其他账号安全问题时进行清理操作。
<br> 清理成功后可重新对用户组进行权限授权,即可恢复正常使用。
</div>
<el-button type="danger" @click="clearAuth">清理授权</el-button>
</el-card>
<br> -->
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>清除缓存</span>
</div>
<div style="margin-bottom: 20px;font-size:14px;color:#666;">
清除缓存
<font color=orangered>不可逆操作</font>
</div>
<el-button type="danger" @click="clearLog">清除缓存</el-button>
</el-card>
</div>
</el-card>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {};
},
methods: {
clearLog() {
var that = this;
this.$confirm('即将清除缓存, 是否确认?', '删除日志', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/system/clean', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
// clearAuth() {
// var that = this;
// this.$confirm('即将删除授权信息, 是否确认?', '清空授权', {
// confirmButtonText: '删除',
// cancelButtonText: '取消',
// type: 'warning'
// }).then(() => {
// axios.post('/admin/auth/clean', Object.assign({}, PostBase))
// .then(function (response) {
// if (response.data.code == CODE_SUCCESS) {
// that.$message({
// message: response.data.message,
// type: 'success'
// });
// } else {
// that.$message.error(response.data.message);
// }
// })
// .catch(function (error) {
// that.$message.error('服务器内部错误');
// console.log(error);
// });
// }).catch(() => {
// });
// },
}
})
</script>
</html>