Compare commits

...

14 Commits
2.18 ... main

Author SHA1 Message Date
Hanada
7f2d57331e feat: 网宿CDNPro支持直接部署指定证书 (#488) 2026-06-06 16:07:00 +08:00
nameless
a98d7427d8 fix 火山云部署证书增加上传项目名称,增加延迟一秒修改证书实例 (#484)
* fix 火山云部署证书增加上传项目名称,增加延迟一秒修改证书实例

* fix 火山云视频直播上传证书支持上传到指定项目名称

* fix 格式化代码
2026-06-02 09:49:09 +08:00
net909
80f1f543e3 优化服务端列头排序 2026-05-18 11:06:09 +08:00
TomyJan
53cb2ac875 feat: 全部列表页支持服务端列头排序 (#470) 2026-05-18 10:49:18 +08:00
net909
12a40cfa7a 修复权限校验问题 2026-05-17 13:19:36 +08:00
net909
9bddf14be9 优化持久化分页大小功能 2026-05-17 13:08:44 +08:00
TomyJan
04acd73033 refactor: 重构分页系统,统一使用localStorage持久化分页大小 (#467)
* refactor: 重构分页系统,统一使用localStorage持久化分页大小

所有列表统一分页大小选项 [10, 15, 20, 30, 50, 100, 200, 300, 500],默认值 15
前端所有表格页面使用 localStorage 替代 cookie 持久化用户选择的分页大小
前端 getStoredPageSize/setStoredPageSize 对分页大小做白名单校验
后端新增 validateLimit() 方法对所有 limit 参数做白名单校验
移除原有的 cookie 分页大小存储逻辑

* fix: 避免缓存 custom.js
2026-05-17 12:53:35 +08:00
net909
ab7a40afbd Merge branch 'main' of ssh://ssh.github.com:443/netcccyun/dnsmgr 2026-05-09 12:42:23 +08:00
net909
a4fe9393b8 阿里云腾讯云DNS支持解析记录分组 2026-05-09 12:42:02 +08:00
dependabot[bot]
f2c769375b build(deps): bump docker/login-action from 3 to 4 (#461)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 18:57:55 +08:00
dependabot[bot]
fb057050fe build(deps): bump actions/checkout from 4 to 6 (#462)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 18:57:44 +08:00
dependabot[bot]
a35f6c90df build(deps): bump docker/setup-buildx-action from 3 to 4 (#463)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 18:57:34 +08:00
dependabot[bot]
8b13dee807 build(deps): bump docker/setup-qemu-action from 3 to 4 (#464)
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 18:57:26 +08:00
dependabot[bot]
c736ddf2fc build(deps): bump docker/build-push-action from 6 to 7 (#460)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 18:57:17 +08:00
36 changed files with 745 additions and 162 deletions

View File

@@ -18,29 +18,29 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Log in to Huawei SWR
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: swr.cn-east-3.myhuaweicloud.com
username: ${{ secrets.HUAWEI_SWR_USERNAME }}
password: ${{ secrets.HUAWEI_SWR_PASSWORD }}
- name: Build and push (Docker Hub + Huawei SWR, latest only)
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .github/docker
file: .github/docker/Dockerfile

View File

@@ -33,13 +33,21 @@ class Cert extends BaseController
$kw = $this->request->post('kw', null, 'trim');
$offset = input('post.offset/d');
$limit = input('post.limit/d');
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$select = Db::name('cert_account')->where('deploy', $deploy);
if (!empty($kw)) {
$select->whereLike('name|remark', '%' . $kw . '%')->whereOr('id', $kw);
}
$total = $select->count();
$rows = $select->order('id', 'desc')->limit($offset, $limit)->select();
$allowedSort = ['id' => 'id', 'typename' => 'type', 'name' => 'name', 'remark' => 'remark', 'addtime' => 'addtime'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('id', 'desc');
}
$rows = $select->limit($offset, $limit)->select();
$list = [];
foreach ($rows as $row) {
@@ -216,6 +224,8 @@ class Cert extends BaseController
$status = input('post.status', null, 'trim');
$offset = input('post.offset/d');
$limit = input('post.limit/d');
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$select = Db::name('cert_order')->alias('A')->leftJoin('cert_account B', 'A.aid = B.id');
if (!empty($id)) {
@@ -242,7 +252,13 @@ class Cert extends BaseController
}
}
$total = $select->count();
$rows = $select->fieldRaw('A.*,B.type,B.remark aremark')->order('id', 'desc')->limit($offset, $limit)->select();
$allowedSort = ['id' => 'A.id', 'typename' => 'B.type', 'keytype' => 'A.keytype', 'isauto' => 'A.isauto', 'issuetime' => 'A.issuetime', 'end_day' => 'A.expiretime', 'status' => 'A.status'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('A.id', 'desc');
}
$rows = $select->fieldRaw('A.*,B.type,B.remark aremark')->limit($offset, $limit)->select();
$list = [];
foreach ($rows as $row) {
@@ -650,6 +666,8 @@ class Cert extends BaseController
$remark = input('post.remark', null, 'trim');
$offset = input('post.offset/d');
$limit = input('post.limit/d');
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$select = Db::name('cert_deploy')->alias('A')->leftJoin('cert_account B', 'A.aid = B.id')->leftJoin('cert_order C', 'A.oid = C.id')->leftJoin('cert_account D', 'C.aid = D.id');
if (!empty($oid)) {
@@ -671,7 +689,13 @@ class Cert extends BaseController
$select->where('A.remark', $remark);
}
$total = $select->count();
$rows = $select->fieldRaw('A.*,B.type,B.remark aremark,B.name aname,D.type certtype,D.id certaid')->order('id', 'desc')->limit($offset, $limit)->select();
$allowedSort = ['id' => 'A.id', 'typename' => 'B.type', 'remark' => 'A.remark', 'active' => 'A.active', 'lasttime' => 'A.lasttime', 'status' => 'A.status'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('A.id', 'desc');
}
$rows = $select->fieldRaw('A.*,B.type,B.remark aremark,B.name aname,D.type certtype,D.id certaid')->limit($offset, $limit)->select();
$list = [];
foreach ($rows as $row) {
@@ -862,13 +886,21 @@ class Cert extends BaseController
$kw = $this->request->post('kw', null, 'trim');
$offset = input('post.offset/d');
$limit = input('post.limit/d');
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$select = Db::name('cert_cname')->alias('A')->leftJoin('domain B', 'A.did = B.id');
if (!empty($kw)) {
$select->whereLike('A.domain', '%' . $kw . '%');
}
$total = $select->count();
$rows = $select->order('A.id', 'desc')->limit($offset, $limit)->field('A.*,B.name cnamedomain')->select();
$allowedSort = ['id' => 'A.id', 'domain' => 'A.domain', 'status' => 'A.status', 'addtime' => 'A.addtime'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('A.id', 'desc');
}
$rows = $select->limit($offset, $limit)->field('A.*,B.name cnamedomain')->select();
$list = [];
foreach ($rows as $row) {

View File

@@ -43,6 +43,8 @@ class Dmonitor extends BaseController
$kw = input('post.kw', null, 'trim');
$offset = input('post.offset/d');
$limit = input('post.limit/d');
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$select = Db::name('dmtask')->alias('A')->join('domain B', 'A.did = B.id');
if (!empty($kw)) {
@@ -62,7 +64,13 @@ class Dmonitor extends BaseController
$select->where('status', intval($status));
}
$total = $select->count();
$list = $select->order('A.id', 'desc')->limit($offset, $limit)->field('A.*,B.name domain')->select()->toArray();
$allowedSort = ['id' => 'A.id', 'rr' => 'A.rr', 'main_value' => 'A.main_value', 'type' => 'A.type', 'checktype' => 'A.checktype', 'frequency' => 'A.frequency', 'status' => 'A.status', 'active' => 'A.active', 'checktimestr' => 'A.checktime', 'addtimestr' => 'A.addtime', 'remark' => 'A.remark'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('A.id', 'desc');
}
$list = $select->limit($offset, $limit)->field('A.*,B.name domain')->select()->toArray();
foreach ($list as &$row) {
$row['addtimestr'] = date('Y-m-d H:i:s', $row['addtime']);

View File

@@ -26,13 +26,21 @@ class Domain extends BaseController
$kw = $this->request->post('kw', null, 'trim');
$offset = input('post.offset/d');
$limit = input('post.limit/d');
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$select = Db::name('account');
if (!empty($kw)) {
$select->whereLike('name|remark', '%' . $kw . '%');
}
$total = $select->count();
$rows = $select->order('id', 'desc')->limit($offset, $limit)->select();
$allowedSort = ['id' => 'id', 'typename' => 'type', 'name' => 'name', 'remark' => 'remark', 'addtime' => 'addtime'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('id', 'desc');
}
$rows = $select->limit($offset, $limit)->select();
$list = [];
foreach ($rows as $row) {
@@ -192,7 +200,8 @@ class Domain extends BaseController
$type = input('post.type', null, 'trim');
$status = input('post.status', null, 'trim');
$cid = input('post.cid', null, 'trim');
$order = input('post.order', null, 'trim');
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$offset = input('post.offset/d', 0);
$limit = input('post.limit/d', 10);
$id = input('post.id');
@@ -224,21 +233,11 @@ class Domain extends BaseController
}
}
$total = $select->count();
switch ($order) {
case '1':
$select->order('A.regtime', 'asc');
break;
case '2':
$select->order('A.regtime', 'desc');
break;
case '3':
$select->order('A.expiretime', 'asc');
break;
case '4':
$select->order('A.expiretime', 'desc');
break;
default:
$select->order('A.id', 'desc');
$allowedSort = ['id' => 'A.id', 'name' => 'A.name', 'recordcount' => 'A.recordcount', 'addtime' => 'A.addtime', 'regtime' => 'A.regtime', 'expiretime' => 'A.expiretime', 'is_notice' => 'A.is_notice', 'is_hide' => 'A.is_hide', 'is_sso' => 'A.is_sso', 'typename' => 'B.type', 'category_name' => 'A.cid', 'remark' => 'A.remark'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('A.id', 'desc');
}
$rows = $select->fieldRaw('A.*,B.type,B.remark aremark')->limit($offset, $limit)->select();
@@ -256,12 +255,12 @@ class Domain extends BaseController
public function domain_op()
{
if (!checkPermission(1)) return $this->alert('error', '无权限');
$act = input('param.act');
if ($act == 'get') {
$id = input('post.id/d');
$row = Db::name('domain')->where('id', $id)->find();
if (!$row) return json(['code' => -1, 'msg' => '域名不存在']);
if (!checkPermission(0, $row['name'])) return json(['code' => -1, 'msg' => '无权限']);
return json(['code' => 0, 'data' => $row]);
} elseif ($act == 'add') {
if (!checkPermission(2)) return $this->alert('error', '无权限');
@@ -771,6 +770,18 @@ class Domain extends BaseController
}
}
$msg = '批量修改备注,成功' . $success . '条,失败' . $fail . '条';
} else if ($action == 'group') {
$dnstype = Db::name('account')->where('id', $drow['aid'])->value('type');
if (!in_array($dnstype, ['aliyun', 'dnspod'])) {
return json(['code' => -1, 'msg' => '该DNS类型不支持分组']);
}
$groupid = input('post.groupid', '', 'trim');
$recordIdList = array_column($recordinfo, 'RecordId');
if ($dns->changeRecordGroup($recordIdList, $groupid)) {
$msg = '成功修改' . count($recordIdList) . '条记录的分组';
} else {
return json(['code' => -1, 'msg' => '修改分组失败,' . $dns->getError()]);
}
}
return json(['code' => 0, 'msg' => $msg]);
}
@@ -1078,6 +1089,38 @@ class Domain extends BaseController
}
}
public function record_groups()
{
$id = input('param.id/d');
$drow = Db::name('domain')->where('id', $id)->find();
if (!$drow) {
return json(['code' => -1, 'msg' => '域名不存在']);
}
if (!checkPermission(0, $drow['name'])) return json(['code' => -1, 'msg' => '无权限']);
$dnstype = Db::name('account')->where('id', $drow['aid'])->value('type');
if (!in_array($dnstype, ['aliyun', 'dnspod'])) {
return json(['code' => -1, 'msg' => '该DNS类型不支持分组']);
}
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
$groups = $dns->getRecordGroups();
if ($groups === false) {
return json(['code' => -1, 'msg' => '获取分组列表失败,' . $dns->getError()]);
}
$groupList = [];
if ($dnstype == 'dnspod') {
$groupList[] = ['id' => '', 'name' => '全部记录'];
}
foreach ($groups as $group) {
$groupList[] = [
'id' => $group['GroupId'],
'name' => $group['GroupName'] . (isset($group['RecordCount']) ? '(' . $group['RecordCount'] . ')' : ''),
];
}
return json(['code' => 0, 'data' => $groupList]);
}
private function add_log($domain, $action, $data)
{
if (strlen($data) > 500) $data = substr($data, 0, 500);
@@ -1348,10 +1391,18 @@ class Domain extends BaseController
if (!checkPermission(2)) return json(['total' => 0, 'rows' => []]);
$offset = input('post.offset/d', 0);
$limit = input('post.limit/d', 10);
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$select = Db::name('domain_category');
$total = $select->count();
$rows = $select->order('sort', 'asc')->order('id', 'desc')->limit($offset, $limit)->select()->toArray();
$allowedSort = ['id' => 'id', 'name' => 'name', 'remark' => 'remark', 'sort' => 'sort', 'addtime' => 'addtime'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('id', 'desc');
}
$rows = $select->limit($offset, $limit)->select()->toArray();
foreach ($rows as &$row) {
$row['domain_count'] = Db::name('domain')->where('cid', $row['id'])->count();

View File

@@ -45,6 +45,8 @@ class Optimizeip extends BaseController
$status = input('post.status', null);
$offset = input('post.offset/d');
$limit = input('post.limit/d');
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$select = Db::name('optimizeip')->alias('A')->join('domain B', 'A.did = B.id');
if (!empty($kw)) {
@@ -58,7 +60,13 @@ class Optimizeip extends BaseController
$select->where('status', intval($status));
}
$total = $select->count();
$list = $select->order('A.id', 'desc')->limit($offset, $limit)->field('A.*,B.name domain')->select();
$allowedSort = ['id' => 'A.id', 'rr' => 'A.rr', 'cdn_type' => 'A.cdn_type', 'recordnum' => 'A.recordnum', 'ip_type' => 'A.ip_type', 'active' => 'A.active', 'updatetime' => 'A.updatetime', 'status' => 'A.status'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('A.id', 'desc');
}
$list = $select->limit($offset, $limit)->field('A.*,B.name domain')->select();
return json(['total' => $total, 'rows' => $list]);
}

View File

@@ -24,6 +24,8 @@ class Schedule extends BaseController
$stype = input('post.stype', null);
$offset = input('post.offset/d');
$limit = input('post.limit/d');
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$select = Db::name('sctask')->alias('A')->join('domain B', 'A.did = B.id');
if (!empty($kw)) {
@@ -41,7 +43,13 @@ class Schedule extends BaseController
$select->where('type', $stype);
}
$total = $select->count();
$list = $select->order('A.id', 'desc')->limit($offset, $limit)->field('A.*,B.name domain')->select()->toArray();
$allowedSort = ['id' => 'A.id', 'rr' => 'A.rr', 'type' => 'A.type', 'switchtype' => 'A.switchtype', 'active' => 'A.active', 'updatetimestr' => 'A.updatetime', 'nexttimestr' => 'A.nexttime', 'addtimestr' => 'A.addtime', 'remark' => 'A.remark'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('A.id', 'desc');
}
$list = $select->limit($offset, $limit)->field('A.*,B.name domain')->select()->toArray();
foreach ($list as &$row) {
$row['addtimestr'] = date('Y-m-d H:i:s', $row['addtime']);

View File

@@ -28,13 +28,21 @@ class User extends BaseController
$kw = input('post.kw', null, 'trim');
$offset = input('post.offset/d');
$limit = input('post.limit/d');
$sort = input('post.sortName', null, 'trim');
$orderDir = strtolower(input('post.sortOrder', 'desc')) === 'asc' ? 'asc' : 'desc';
$select = Db::name('user');
if (!empty($kw)) {
$select->whereLike('id|username', $kw);
}
$total = $select->count();
$rows = $select->order('id', 'desc')->limit($offset, $limit)->select();
$allowedSort = ['id' => 'id', 'username' => 'username', 'level' => 'level', 'is_api' => 'is_api', 'regtime' => 'regtime', 'lasttime' => 'lasttime', 'status' => 'status'];
if ($sort && isset($allowedSort[$sort])) {
$select->order($allowedSort[$sort], $orderDir);
} else {
$select->order('id', 'desc');
}
$rows = $select->limit($offset, $limit)->select();
return json(['total' => $total, 'rows' => $rows]);
}

View File

@@ -2035,6 +2035,12 @@ ctrl+x 保存退出<br/>',
'show' => 'product==\'clb\'||product==\'alb\'',
'required' => true,
],
'project_name' => [
'name' => '证书上传项目名称',
'type' => 'input',
'placeholder' => '证书实例所属的火山引擎项目名称。如果不设置该参数证书实例会属于default项目。',
'required' => false,
],
],
],
'west' => [
@@ -2116,6 +2122,7 @@ ctrl+x 保存退出<br/>',
'options' => [
['value'=>'cdn', 'label'=>'CDN'],
['value'=>'cdnpro', 'label'=>'CDN Pro'],
['value'=>'cdnpro_certificate', 'label'=>'CDN Pro证书管理'],
['value'=>'certificate', 'label'=>'证书管理']
],
'value' => 'cdn',
@@ -2138,7 +2145,7 @@ ctrl+x 保存退出<br/>',
'cert_id' => [
'name' => '证书ID',
'type' => 'input',
'show' => 'product==\'certificate\'',
'show' => 'product==\'certificate\'||product==\'cdnpro_certificate\'',
'placeholder' => '',
'required' => true,
],

View File

@@ -33,7 +33,7 @@ class huoshan implements DeployInterface
if ($config['product'] == 'live') {
$this->deploy_live($fullchain, $privatekey, $config);
} else {
$cert_id = $this->get_cert_id($fullchain, $privatekey);
$cert_id = $this->get_cert_id($fullchain, $privatekey, $config);
if (!$cert_id) throw new Exception('获取证书ID失败');
$info['cert_id'] = $cert_id;
if (!isset($config['product']) || $config['product'] == 'cdn') {
@@ -121,6 +121,9 @@ class huoshan implements DeployInterface
],
'UseWay' => 'https',
];
if (!empty($config['project_name'])) {
$param['ProjectName'] = $config['project_name'];
}
$result = $client->request('POST', 'CreateCert', $param);
$this->log('上传证书成功 ChainID=' . $result['ChainID']);
@@ -214,7 +217,7 @@ class huoshan implements DeployInterface
$this->log('ALB监听器 ' . $config['listener_id'] . ' 部署证书成功!');
}
private function get_cert_id($fullchain, $privatekey)
private function get_cert_id($fullchain, $privatekey, $config)
{
$certInfo = openssl_x509_parse($fullchain, true);
if (!$certInfo) throw new Exception('证书解析失败');
@@ -229,6 +232,9 @@ class huoshan implements DeployInterface
'PrivateKey' => $privatekey,
],
];
if (!empty($config['project_name'])) {
$param['ProjectName'] = $config['project_name'];
}
try {
$data = $client->request('POST', 'ImportCertificate', $param);
} catch (Exception $e) {
@@ -237,7 +243,7 @@ class huoshan implements DeployInterface
if (!empty($data['InstanceId'])) {
$cert_id = $data['InstanceId'];
$this->log('上传证书成功 CertId=' . $cert_id);
sleep(1);
$param = [
'InstanceId' => $cert_id,
'Options' => [

View File

@@ -44,6 +44,10 @@ class wangsu implements DeployInterface
$cert_name = str_replace('*.', '', $certInfo['subject']['CN']) . '-' . $certInfo['validFrom_time_t'];
$serial_no = strtolower($certInfo['serialNumberHex']);
$this->get_cert_id($fullchain, $privatekey, $cert_name, $config['cert_id'], $serial_no, true);
} elseif ($config['product'] == 'cdnpro_certificate') {
$this->deploy_cdnpro_certificate($fullchain, $privatekey, $config, $info);
} else {
throw new Exception('未知的产品类型');
}
@@ -213,6 +217,56 @@ class wangsu implements DeployInterface
$info['cert_id'] = $cert_id;
}
public function deploy_cdnpro_certificate($fullchain, $privatekey, $config, &$info)
{
$certInfo = openssl_x509_parse($fullchain, true);
if (!$certInfo) {
throw new Exception('证书解析失败');
}
$cert_name = str_replace('*.', '', $certInfo['subject']['CN']) . '-' . $certInfo['validFrom_time_t'];
$cert_id = isset($config['cert_id']) ? $config['cert_id'] : null;
if (empty($cert_id)) {
throw new Exception('证书ID不能为空');
}
$result = $this->update_cert_id_cdnpro($fullchain, $privatekey, $cert_name, $cert_id);
$cert_id = $result['cert_id'];
if (empty($result['updated'])) {
$info['cert_id'] = $cert_id;
return;
}
$certVersion = $result['version'];
// 下发证书部署任务
$deploymentTasks = [
'target' => 'production',
'actions' => [
[
'action' => 'deploy_cert',
'certificateId' => $cert_id,
'version' => intval($certVersion),
]
],
'name' => 'Deploy certificate ' . $cert_name,
];
try {
$data = $this->request('/cdn/deploymentTasks', $deploymentTasks, true, null, 'POST', false, ['Check-Certificate' => 'no', 'Check-Usage' => 'no']);
} catch (Exception $e) {
throw new Exception('下发证书部署任务失败:' . $e->getMessage());
}
$url_parts = parse_url($data);
$path_parts = explode('/', $url_parts['path']);
$deploymentTaskId = end($path_parts);
$this->log('证书部署任务下发成功部署任务ID' . $deploymentTaskId);
$info['cert_id'] = $cert_id;
}
private function get_cert_id($fullchain, $privatekey, $cert_name, $cert_id = null, $serial_no = null, $overwrite = false)
{
if ($cert_id) {
@@ -349,6 +403,49 @@ class wangsu implements DeployInterface
return $cert_id;
}
private function update_cert_id_cdnpro($fullchain, $privatekey, $cert_name, $cert_id)
{
try {
$data = $this->request('/cdn/certificates/' . $cert_id);
} catch (Exception $e) {
throw new Exception('证书ID ' . $cert_id . ' 不存在或获取失败:' . $e->getMessage());
}
if (isset($data['name']) && $data['name'] == $cert_name) {
$this->log('证书已是最新无需更新证书ID' . $cert_id);
return ['cert_id' => $cert_id, 'updated' => false];
}
$this->log('证书已过期,准备更新...');
$date = gmdate("D, d M Y H:i:s T");
$encryptedKey = $this->encryptPrivateKey($privatekey, $date);
$param = [
'name' => $cert_name,
'newVersion' => [
'privateKey' => $encryptedKey,
'certificate' => $fullchain,
'comments' => $cert_name,
]
];
try {
$location = $this->request('/cdn/certificates/' . $cert_id, $param, true, $date, 'PATCH', true);
} catch (Exception $e) {
throw new Exception('更新证书失败:' . $e->getMessage());
}
// 从 Location 头解析版本号,格式:.../certificates/{id}/versions/{version}
$version = 1;
if (is_string($location)) {
$path_parts = explode('/', parse_url($location, PHP_URL_PATH));
$version = intval(end($path_parts));
}
$this->log('更新证书成功证书ID' . $cert_id . ',版本号:' . $version);
return ['cert_id' => $cert_id, 'version' => $version, 'updated' => true];
}
private function encryptPrivateKey($privateKey, $date = null)
{
// 获取当前 GMT 时间DATE

View File

@@ -72,6 +72,10 @@ class aliyun implements DnsInterface
$Status = $Status == '1' ? 'Enable' : 'Disable';
$param += ['Status' => $Status];
}
$groupid = request()->post('groupid');
if (!empty($groupid)) {
$param += ['GroupId' => $groupid];
}
$data = $this->request($param, true);
if ($data) {
$list = [];
@@ -234,7 +238,7 @@ class aliyun implements DnsInterface
public function getDomainInfo()
{
if (!empty($this->domainInfo)) return $this->domainInfo;
$param = ['Action' => 'DescribeDomainInfo', 'DomainName' => $this->domain, 'NeedDetailAttributes' => 'true'];
$param = ['Action' => 'DescribeDomainInfo', 'DomainName' => $this->domain, 'NeedDetailAttributes' => 'true', 'Lang' => 'zh'];
$data = $this->request($param, true);
if ($data) {
$this->domainInfo = $data;
@@ -253,6 +257,24 @@ class aliyun implements DnsInterface
return false;
}
//获取解析记录分组列表
public function getRecordGroups()
{
$param = ['Action' => 'DescribeRecordGroups', 'DomainName' => $this->domain, 'PageSize' => 100, 'Lang' => 'zh'];
$data = $this->request($param, true);
if ($data) {
return $data['RecordGroups']['RecordGroup'];
}
return false;
}
//修改解析记录分组
public function changeRecordGroup($RecordIdList, $GroupId)
{
$param = ['Action' => 'ChangeRecordGroup', 'DomainName' => $this->domain, 'RecordIdList' => json_encode($RecordIdList), 'GroupId' => $GroupId];
return $this->request($param);
}
//获取权重配置子域名列表
public function getWeightSubDomains($PageNumber = 1, $PageSize = 20, $SubDomain = null)
{

View File

@@ -66,7 +66,8 @@ class dnspod implements DnsInterface
public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
{
$offset = ($PageNumber - 1) * $PageSize;
if (!isNullOrEmpty($Status) || !isNullOrEmpty($Value)) {
$groupid = request()->post('groupid');
if (!isNullOrEmpty($Status) || !isNullOrEmpty($Value) || !empty($groupid)) {
$action = 'DescribeRecordFilterList';
$param = ['Domain' => $this->domain, 'Offset' => $offset, 'Limit' => $PageSize, 'RecordValue' => $Value];
if (!isNullOrEmpty($SubDomain)) $param['SubDomain'] = $SubDomain;
@@ -78,6 +79,7 @@ class dnspod implements DnsInterface
}
if (!isNullOrEmpty($Type)) $param['RecordType'] = [$this->convertType($Type)];
if (!isNullOrEmpty($Line)) $param['RecordLine'] = [$Line];
if (!empty($groupid)) $param['GroupId'] = [intval($groupid)];
} else {
$action = 'DescribeRecordList';
$param = ['Domain' => $this->domain, 'Subdomain' => $SubDomain, 'RecordType' => $this->convertType($Type), 'RecordLineId' => $Line, 'Keyword' => $KeyWord, 'Offset' => $offset, 'Limit' => $PageSize];
@@ -365,6 +367,28 @@ class dnspod implements DnsInterface
return is_array($data);
}
//获取解析记录分组列表
public function getRecordGroups()
{
$action = 'DescribeRecordGroupList';
$param = ['Domain' => $this->domain];
$data = $this->send_request($action, $param);
if ($data) {
return $data['GroupList'];
}
return false;
}
//将记录移动到分组
public function changeRecordGroup($RecordIdList, $GroupId)
{
$action = 'ModifyRecordToGroup';
$RecordIdList = implode('|', $RecordIdList);
$param = ['Domain' => $this->domain, 'GroupId' => intval($GroupId), 'RecordId' => strval($RecordIdList)];
$data = $this->send_request($action, $param);
return is_array($data);
}
private function convertLineCode($line)
{
$convert_dict = ['default' => '0', 'unicom' => '10=1', 'telecom' => '10=0', 'mobile' => '10=3', 'edu' => '10=2', 'oversea' => '3=0', 'btvn' => '10=22', 'search' => '80=0', 'internal' => '7=0'];

View File

@@ -27,42 +27,52 @@
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'certaccount_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/cert/account/data?deploy=0',
pageNumber: pageNumber,
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'typename',
title: '所属平台',
sortable: true,
formatter: function(value, row, index) {
return '<img src="/static/images/'+row.icon+'" class="type-logo"></img>'+value;
}
},
{
field: 'name',
title: '账户名称'
title: '账户名称',
sortable: true
},
{
field: 'remark',
title: '备注'
title: '备注',
sortable: true
},
{
field: 'addtime',
title: '添加时间'
title: '添加时间',
sortable: true
},
{
field: 'action',
@@ -72,7 +82,10 @@ $(document).ready(function(){
return html;
}
},
]
],
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function delItem(id){

View File

@@ -55,13 +55,15 @@ pre.pre-log{height: 330px;overflow-y: auto;width: 100%;background-color: rgba(51
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/FileSaver-2.0.5.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 10;
const pageSizeKey = 'certorder_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey, 10);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/cert/order/data',
@@ -69,6 +71,9 @@ $(document).ready(function(){
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
uniqueId: 'id',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: '',
@@ -76,11 +81,13 @@ $(document).ready(function(){
},
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'typename',
title: '证书账户',
sortable: true,
formatter: function(value, row, index) {
if(value){
return '<span title="'+row.aremark+'" data-toggle="tooltip" data-placement="right"><img src="/static/images/'+row.icon+'" class="type-logo">'+value+'('+row.aid+')</span>';
@@ -98,6 +105,7 @@ $(document).ready(function(){
{
field: 'keytype',
title: '证书信息',
sortable: true,
formatter: function(value, row, index) {
return '<span class="text-muted">签名算法:</span>'+row.keytype+'('+row.keysize+')'+(row.issuer?'<br/><span class="text-muted">颁发机构:</span>'+row.issuer:'');
}
@@ -105,6 +113,7 @@ $(document).ready(function(){
{
field: 'isauto',
title: '自动续签',
sortable: true,
formatter: function(value, row, index) {
if(value == 1){
return '<div class="material-switch"><input id="isauto'+row.id+'" type="checkbox" checked onchange="setAuto('+row.id+',0)"/><label for="isauto'+row.id+'" class="label-primary"></label></div>';
@@ -116,6 +125,7 @@ $(document).ready(function(){
{
field: 'issuetime',
title: '签发时间',
sortable: true,
formatter: function(value, row, index) {
return value ? value.substring(0,10) : '暂未签发';
}
@@ -123,6 +133,7 @@ $(document).ready(function(){
{
field: 'end_day',
title: '到期时间',
sortable: true,
formatter: function(value, row, index) {
if(value != null){
if(value > 7){
@@ -140,6 +151,7 @@ $(document).ready(function(){
{
field: 'status',
title: '状态',
sortable: true,
formatter: function(value, row, index) {
if(value == 4) {
return '<span class="label" style="background-color: #a5a5a5;">已吊销</span>';
@@ -252,7 +264,10 @@ $(document).ready(function(){
}
$(e.target).children('.dropdown-menu').css({position:'fixed', top:top, left:left});
});
}
},
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function showmsg(msg){

View File

@@ -74,13 +74,15 @@ tbody tr>td:nth-child(4){word-break:break-all;max-width:260px;}
<script src="/static/js/clipboard-1.7.1.min.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'cname_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/cert/cname/data',
@@ -88,14 +90,19 @@ $(document).ready(function(){
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
uniqueId: 'id',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'domain',
title: '被代理域名'
title: '被代理域名',
sortable: true
},
{
field: 'host',
@@ -114,6 +121,7 @@ $(document).ready(function(){
{
field: 'status',
title: '状态',
sortable: true,
formatter: function(value, row, index) {
var html = '';
if(value == 1) {
@@ -127,7 +135,8 @@ $(document).ready(function(){
},
{
field: 'addtime',
title: '添加时间'
title: '添加时间',
sortable: true
},
{
field: 'action',
@@ -147,6 +156,9 @@ $(document).ready(function(){
layer.msg('复制失败', {icon: 2});
});
},
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function addframe(){

View File

@@ -27,42 +27,52 @@
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'deployaccount_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/cert/account/data?deploy=1',
pageNumber: pageNumber,
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'typename',
title: '账户类型',
sortable: true,
formatter: function(value, row, index) {
return '<img src="/static/images/'+row.icon+'" class="type-logo"></img>'+value;
}
},
{
field: 'name',
title: '账户名称'
title: '账户名称',
sortable: true
},
{
field: 'remark',
title: '备注'
title: '备注',
sortable: true
},
{
field: 'addtime',
title: '添加时间'
title: '添加时间',
sortable: true
},
{
field: 'action',
@@ -72,7 +82,10 @@ $(document).ready(function(){
return html;
}
},
]
],
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function delItem(id){

View File

@@ -54,13 +54,15 @@ pre.pre-log{height: 330px;overflow-y: auto;width: 100%;background-color: rgba(51
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/FileSaver-2.0.5.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 10;
const pageSizeKey = 'deploytask_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey, 10);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/cert/deploy/data',
@@ -68,6 +70,9 @@ $(document).ready(function(){
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
uniqueId: 'id',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: '',
@@ -75,11 +80,13 @@ $(document).ready(function(){
},
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'typename',
title: '自动部署账户',
sortable: true,
formatter: function(value, row, index) {
if(!value) return '已被删除'
return '<span title="'+row.aname+'" data-toggle="tooltip" data-placement="right"><img src="/static/images/'+row.icon+'" class="type-logo">'+(row.aremark?row.aremark:value+'('+row.aid+')')+'</span>';
@@ -97,11 +104,13 @@ $(document).ready(function(){
},
{
field: 'remark',
title: '备注'
title: '备注',
sortable: true
},
{
field: 'active',
title: '任务开关',
sortable: true,
formatter: function(value, row, index) {
if(value == 1){
return '<div class="material-switch"><input id="active'+row.id+'" type="checkbox" checked onchange="setActive('+row.id+',0)"/><label for="active'+row.id+'" class="label-primary"></label></div>';
@@ -113,6 +122,7 @@ $(document).ready(function(){
{
field: 'lasttime',
title: '上次执行时间',
sortable: true,
formatter: function(value, row, index) {
return value ? value : '暂未执行'
}
@@ -120,6 +130,7 @@ $(document).ready(function(){
{
field: 'status',
title: '状态',
sortable: true,
formatter: function(value, row, index) {
if(value == 1) {
return '<span class="label label-success">已完成</span>';
@@ -173,7 +184,10 @@ $(document).ready(function(){
}
$(e.target).children('.dropdown-menu').css({position:'fixed', top:top, left:left});
});
}
},
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function showmsg(msg){

View File

@@ -458,7 +458,7 @@
<script src="/static/js/bootstrapValidator.min.js"></script>
<script src="/static/js/select2-4.0.13.min.js"></script>
<script src="/static/js/select2-i18n-zh-CN-4.0.13.min.js"></script>
<script src="/static/js/custom.js?v=1005"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
var currentVerificationHostnameId = '';
var allHostnameData = []; // 保存完整的原始数据用于客户端搜索
@@ -468,6 +468,7 @@ $(document).ready(function(){
$("#form-store").bootstrapValidator();
loadFallbackOrigin();
loadDcvDelegationUuid();
const pageSizeKey = 'hostnames_pagesize';
$("#listTable").bootstrapTable({
url: '/cloudflare/hostnames/data/{$domainId}',
method: 'post',
@@ -476,8 +477,7 @@ $(document).ready(function(){
uniqueId: 'id',
sidePagination: 'client',
pagination: true,
pageSize: 20,
pageList: [10, 20, 50, 100],
pageSize: getStoredPageSize(pageSizeKey),
queryParams: function(params){ return {}; },
responseHandler: hostnameResponseHandler,
columns: [
@@ -502,7 +502,10 @@ $(document).ready(function(){
+ '<a href="javascript:deleteHostname(\''+row.id+'\', \''+htmlEscape(row.hostname)+'\')" class="btn btn-danger btn-xs">删除</a>';
}
}
]
],
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
});
// 添加复选框事件监听

View File

@@ -164,7 +164,7 @@
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/bootstrapValidator.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
var selectedTunnelId = '';
var selectedTunnelName = '';
@@ -172,12 +172,14 @@ var selectedTunnelName = '';
$(document).ready(function(){
$("#form-tunnel").bootstrapValidator();
const pageSizeKey = 'tunnels_pagesize';
$("#listTable").bootstrapTable({
url: '/cloudflare/tunnels/data/{$accountId}',
method: 'post',
toolbar: '',
classes: 'table table-striped table-hover table-bordered',
uniqueId: 'id',
pageSize: getStoredPageSize(pageSizeKey),
responseHandler: tableResponseHandler,
columns: [
{field: 'name', title: '名称'},
@@ -197,7 +199,10 @@ $(document).ready(function(){
+ '<a href="javascript:deleteTunnel(\''+row.id+'\', \''+htmlEscape(row.name)+'\')" class="btn btn-danger btn-xs">删除</a>';
}
}
]
],
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
});
$("#publicTable").bootstrapTable({

View File

@@ -45,19 +45,24 @@ tbody tr>td:nth-child(4){overflow: hidden;text-overflow: ellipsis;white-space: n
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'dmtask_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/dmonitor/task/data',
pageNumber: pageNumber,
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: '',
@@ -65,11 +70,13 @@ $(document).ready(function(){
},
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'rr',
title: '域名',
sortable: true,
formatter: function(value, row, index) {
return '<span title="'+row.remark+'" data-toggle="tooltip" data-placement="right">' + value + '.' + row.domain + '</span>';
}
@@ -77,6 +84,7 @@ $(document).ready(function(){
{
field: 'main_value',
title: '解析记录',
sortable: true,
formatter: function(value, row, index) {
return value;
}
@@ -123,6 +131,7 @@ $(document).ready(function(){
{
field: 'status',
title: '健康状况',
sortable: true,
formatter: function(value, row, index) {
if(value == 0) {
return '<span class="label label-success">正常</span>';
@@ -134,6 +143,7 @@ $(document).ready(function(){
{
field: 'active',
title: '运行开关',
sortable: true,
formatter: function(value, row, index) {
if(value == 1){
return '<div class="material-switch"><input id="active'+row.id+'" type="checkbox" checked onchange="setActive('+row.id+',0)"/><label for="active'+row.id+'" class="label-primary"></label></div>';
@@ -144,16 +154,19 @@ $(document).ready(function(){
},
{
field: 'checktimestr',
title: '上次检测时间'
title: '上次检测时间',
sortable: true
},
{
field: 'addtimestr',
title: '添加时间',
sortable: true,
visible: false
},
{
field: 'remark',
title: '备注',
sortable: true,
visible: false
},
{
@@ -170,7 +183,10 @@ $(document).ready(function(){
],
onLoadSuccess: function(data) {
$('[data-toggle="tooltip"]').tooltip()
}
},
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function setActive(id, active){

View File

@@ -32,14 +32,14 @@ tbody tr>td:nth-child(4){overflow: hidden;text-overflow: ellipsis;white-space: n
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
var action_name = {$info.action_name|json_encode|raw};
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'dmtaskinfo_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
$("#listTable").bootstrapTable({
url: '/dmonitor/task/log/data/{$info.id}',
@@ -67,6 +67,9 @@ $(document).ready(function(){
title: '异常原因'
}
],
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
</script>

View File

@@ -27,43 +27,53 @@
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
var userLevel = "{$user['level']|default=''}";
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'account_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/account/data',
pageNumber: pageNumber,
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'typename',
title: '所属平台',
sortable: true,
formatter: function(value, row, index) {
return '<img src="/static/images/'+row.icon+'" class="type-logo"></img>'+value;
}
},
{
field: 'name',
title: '账户名称'
title: '账户名称',
sortable: true
},
{
field: 'remark',
title: '备注'
title: '备注',
sortable: true
},
{
field: 'addtime',
title: '添加时间'
title: '添加时间',
sortable: true
},
{
field: 'action',
@@ -78,6 +88,9 @@ $(document).ready(function(){
}
},
],
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function delItem(id) {

View File

@@ -65,7 +65,7 @@
{/block}
{block name="script"}
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
var domainId = {$domainId};

View File

@@ -61,13 +61,15 @@
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/bootstrapValidator.min.js"></script>
<script src="/static/js/custom.js?v=1003"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
let defaultPageSize = getCookie('category_pagesize') ? getCookie('category_pagesize') : 10;
const pageSizeKey = 'category_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/domain/category/data',
@@ -75,25 +77,32 @@ $(document).ready(function(){
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
uniqueId: 'id',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'name',
title: '分类名称'
title: '分类名称',
sortable: true
},
{
field: 'remark',
title: '备注',
sortable: true,
formatter: function(value, row, index) {
return value ? value : '-';
}
},
{
field: 'sort',
title: '排序'
title: '排序',
sortable: true
},
{
field: 'domain_count',
@@ -104,7 +113,8 @@ $(document).ready(function(){
},
{
field: 'addtime',
title: '添加时间'
title: '添加时间',
sortable: true
},
{
field: 'action',
@@ -118,9 +128,7 @@ $(document).ready(function(){
},
],
onPageChange: function(number, size){
if(size != defaultPageSize){
setCookie('category_pagesize', size, 24 * 3600 * 30);
}
setStoredPageSize(pageSizeKey, size);
},
});

View File

@@ -155,9 +155,6 @@
<div class="form-group">
<select name="status" class="form-control"><option value="">所有状态</option><option value="1">即将到期</option><option value="2">已到期</option></select>
</div>
<div class="form-group">
<select name="order" class="form-control"><option value="">默认排序</option><option value="1">注册时间↑</option><option value="2">注册时间↓</option><option value="3">到期时间↑</option><option value="4">到期时间↓</option></select>
</div>
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button>
<a href="javascript:searchClear()" class="btn btn-default" title="刷新域名列表"><i class="fa fa-refresh"></i> 刷新</a>
{if $user['level'] eq 2}<a href="javascript:addframe()" class="btn btn-success"><i class="fa fa-plus"></i> 添加</a>
@@ -184,14 +181,16 @@
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/select2-4.0.13.min.js"></script>
<script src="/static/js/select2-i18n-zh-CN-4.0.13.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
var userLevel = "{$user['level']|default=''}";
$(document).ready(function(){
updateToolbar();
const defaultPageSize = getCookie('domain_pagesize') ? getCookie('domain_pagesize') : 15;
const pageSizeKey = 'domain_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/domain/data',
@@ -199,6 +198,9 @@ $(document).ready(function(){
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
uniqueId: 'id',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: '',
@@ -206,11 +208,13 @@ $(document).ready(function(){
},
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'typename',
title: '平台账户',
sortable: true,
formatter: function(value, row, index) {
return '<img src="/static/images/'+row.icon+'" class="type-logo"></img>'+(row.aremark?row.aremark:value+'('+row.aid+')');
}
@@ -218,21 +222,25 @@ $(document).ready(function(){
{
field: 'name',
title: '域名',
sortable: true,
formatter: function(value, row, index) {
return '<a href="/record/'+row.id+'" title="进入解析记录管理" onclick="loading()">'+value+'</a>';
}
},
{
field: 'recordcount',
title: '记录数'
title: '记录数',
sortable: true
},
{
field: 'addtime',
title: '添加时间'
title: '添加时间',
sortable: true
},
{
field: 'regtime',
title: '注册时间',
sortable: true,
visible: false,
formatter: function(value, row, index) {
var html = '';
@@ -251,6 +259,7 @@ $(document).ready(function(){
{
field: 'expiretime',
title: '到期时间',
sortable: true,
formatter: function(value, row, index) {
var html = '';
if(value == null) {
@@ -278,6 +287,7 @@ $(document).ready(function(){
{
field: 'is_notice',
title: '到期提醒',
sortable: true,
formatter: function(value, row, index) {
return value==1?'<font color="green">是</font>':'<font color="blue">否</font>';
}
@@ -285,6 +295,7 @@ $(document).ready(function(){
{
field: 'is_hide',
title: '是否隐藏',
sortable: true,
visible: false,
formatter: function(value, row, index) {
return value==1?'<font color="grey">是</font>':'<font color="blue">否</font>';
@@ -293,6 +304,7 @@ $(document).ready(function(){
{
field: 'is_sso',
title: '对接开关',
sortable: true,
visible: false,
formatter: function(value, row, index) {
return value==1?'<font color="green">是</font>':'<font color="red">否</font>';
@@ -301,13 +313,15 @@ $(document).ready(function(){
{
field: 'category_name',
title: '分类',
sortable: true,
formatter: function(value, row, index) {
return value ? '<span class="label label-default">' + value + '</span>' : '-';
}
},
{
field: 'remark',
title: '备注'
title: '备注',
sortable: true
},
{
field: 'action',
@@ -326,9 +340,7 @@ $(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip()
},
onPageChange: function(number, size){
if(size != defaultPageSize){
setCookie('domain_pagesize', size, 24 * 3600 * 30);
}
setStoredPageSize(pageSizeKey, size);
},
})

View File

@@ -51,6 +51,7 @@
{block name="script"}
<script src="/static/js/vue-2.7.16.min.js"></script>
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
new Vue({
el: '#app',
@@ -58,7 +59,7 @@ new Vue({
aid: '',
domainList: [],
page: 1,
pagesize: 10,
pagesize: getStoredPageSize('domainadd_pagesize'),
checkall: false,
},
watch: {

View File

@@ -18,13 +18,13 @@
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'domainlog_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
$("#listTable").bootstrapTable({
url: '/record/log/{$domainId}',
@@ -41,6 +41,9 @@ $(document).ready(function(){
title: '操作行为'
}
],
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
</script>

View File

@@ -188,7 +188,7 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
{if $dnsconfig.type=='dnspod'}<a href="/record/alias/{$domainId}" class="btn btn-default">域名别名</a>{/if}
<div class="btn-group" role="group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">批量操作 <span class="caret"></span></button>
<ul class="dropdown-menu"><li><a href="/record/batchadd/{$domainId}">添加</a></li><li><a href="javascript:operation('open')">启用</a></li><li><a href="javascript:operation('pause')">暂停</a></li><li><a href="javascript:operation('edit')">修改记录</a></li><li><a href="javascript:operation('editline')">修改线路</a></li>{if $dnsconfig.remark == 1}<li><a href="javascript:operation('editremark')">修改备注</a></li>{/if}<li><a href="javascript:operation('delete')">删除</a></li></ul>
<ul class="dropdown-menu"><li><a href="/record/batchadd/{$domainId}">添加</a></li><li><a href="javascript:operation('open')">启用</a></li><li><a href="javascript:operation('pause')">暂停</a></li><li><a href="javascript:operation('edit')">修改记录</a></li><li><a href="javascript:operation('editline')">修改线路</a></li>{if $dnsconfig.remark == 1}<li><a href="javascript:operation('editremark')">修改备注</a></li>{/if}{if $dnsconfig.type=='aliyun' || $dnsconfig.type=='dnspod'}<li><a href="javascript:operation('editgroup')">修改分组</a></li>{/if}<li><a href="javascript:operation('delete')">删除</a></li></ul>
</div>
<div class="btn-group" role="group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">日志 <span class="caret"></span></button>
@@ -223,6 +223,11 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
<div class="form-group">
<input type="text" class="form-control" name="value" placeholder="输入记录值">
</div>
{if $dnsconfig.type=='aliyun' || $dnsconfig.type=='dnspod'}
<div class="form-group">
<select name="groupid" id="groupid" class="form-control"></select>
</div>
{/if}
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button>
<a href="javascript:searchClear()" class="btn btn-default" title="刷新解析记录列表"><i class="fa fa-refresh"></i> 刷新</a>
<a href="javascript:advanceSearch()" class="btn"><i class="fa fa-angle-up"></i> 收起</a>
@@ -241,7 +246,7 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/bootstrapValidator.min.js"></script>
<script src="/static/js/custom.js?v=1003"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
var recordLine = {$recordLine|json_encode|raw};
var dnsconfig = {$dnsconfig|json_encode|raw};
@@ -250,9 +255,9 @@ var sidePagination = dnsconfig.page ? 'client' : 'server';
var showWeight = dnsconfig.weight;
$(document).ready(function(){
updateToolbar();
let defaultPageSize = getCookie('record_pagesize') ? getCookie('record_pagesize') : 15;
const pageSizeKey = 'record_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
$("#listTable").bootstrapTable({
url: '/record/data/{$domainId}',
@@ -294,11 +299,11 @@ $(document).ready(function(){
formatter: function(value, row, index) {
var copyId = 'copy-value-' + row.RecordId;
if(row.Type == 'MX' && dnsconfig.type!='huawei') {
return '<span id="'+copyId+'" data-value="'+htmlEscape(value)+'">'+value+'</span>'
return '<span id="'+copyId+'" data-value="'+htmlEscape(value)+'">'+htmlEscape(value)+'</span>'
+ '<a href="javascript:void(0);" title="复制记录值" onclick="copyToClipboard(null, \'#'+copyId+'\')" style="padding-left:6px;"><i class=\"fa fa-copy\"></i></a>'
+ '<span class="mx-priority"> | '+row.MX+'</span>';
} else {
return '<span id="'+copyId+'" data-value="'+htmlEscape(value)+'">'+value+'</span>'
return '<span id="'+copyId+'" data-value="'+htmlEscape(value)+'">'+htmlEscape(value)+'</span>'
+ '<a href="javascript:void(0);" title="复制记录值" onclick="copyToClipboard(null, \'#'+copyId+'\')" style="padding-left:6px;"><i class=\"fa fa-copy\"></i></a>';
}
}
@@ -365,9 +370,7 @@ $(document).ready(function(){
},
],
onPageChange: function(number, size){
if(size != defaultPageSize){
setCookie('record_pagesize', size, 24 * 3600 * 30);
}
setStoredPageSize(pageSizeKey, size);
},
});
@@ -397,6 +400,7 @@ $(document).ready(function(){
$("#searchToolbar select[name='line']").append('<option value="'+item.id+'">'+item.name+'</option>');
}
})
})
function initLine(option, elem){
option = option || '';
@@ -588,6 +592,9 @@ function operation(action){
}else if(action == 'editremark'){
batch_edit_remark(rows)
return;
}else if(action == 'editgroup'){
batch_edit_group(rows)
return;
}
layer.confirm('确定要'+(action=='open'?'启用':(action=='pause'?'暂停':'删除'))+'所选记录吗?', {title: '提示', icon: 0}, function(){
@@ -714,6 +721,74 @@ function batch_edit_remark(rows) {
}
});
}
function batch_edit_group(rows) {
var showDialog = function(options){
layer.open({
type: 1,
area: ['350px'],
closeBtn: 2,
title: '批量修改分组',
content: '<div style="padding:15px"><div class="form-group"><select class="form-control" id="batch_groupid">'+options+'</select></div></div>',
btn: ['确认', '取消'],
yes: function(){
var groupid = $('#batch_groupid').val();
var recordIds = rows.map(function(r){ return r.RecordId; });
var ii = layer.load(2, {shade:[0.1,'#fff']});
$.ajax({
type: 'POST',
url: '/record/batch/{$domainId}',
data: {action:'group', recordinfo: JSON.stringify(rows), groupid: groupid},
dataType: 'json',
success: function(data){
layer.close(ii);
layer.alert(data.msg, {icon: data.code==0?1:2, closeBtn: false}, function(){
layer.closeAll();
if(data.code == 0) searchRefresh();
groupLoaded = false;
});
},
error: function(){
layer.close(ii);
layer.msg('服务器错误');
}
});
}
});
};
if(groupLoaded && $('#groupid').length > 0){
var options = '';
$('#groupid option').each(function(){ options += '<option value="'+$(this).val()+'">'+$(this).text()+'</option>'; });
showDialog(options);
}else{
var ii = layer.load(2);
$.post('/record/groups/{$domainId}', function(res){
layer.close(ii);
if(res.code == 0){
var options = '';
$.each(res.data, function(i, item){
options += '<option value="'+item.id+'">'+item.name+'</option>';
});
showDialog(options);
}else{
layer.alert(res.msg, {icon: 2});
}
}, 'json');
}
}
var groupLoaded = false;
function loadRecordGroups(){
if(groupLoaded || (dnsconfig.type != 'aliyun' && dnsconfig.type != 'dnspod')) return;
groupLoaded = true;
$.post('/record/groups/{$domainId}', function(res){
if(res.code == 0){
$('#groupid').empty();
$.each(res.data, function(i, item){
$('#groupid').append('<option value="'+item.id+'">'+item.name+'</option>');
});
updateToolbar();
}
}, 'json');
}
function advanceSearch(){
$('#searchToolbar').find('input[name]').each(function() {
$(this).val('');
@@ -724,6 +799,7 @@ function advanceSearch(){
if($("#searchbox1").is(":visible")){
$("#searchbox1").slideUp();
$("#searchbox2").slideDown();
loadRecordGroups();
}else{
$("#searchbox2").slideUp();
$("#searchbox1").slideDown();

View File

@@ -76,7 +76,7 @@
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
var dnsconfig = {$dnsconfig|json_encode|raw};
var recordLine = {$recordLine|json_encode|raw};
@@ -85,9 +85,9 @@ var weightList = [];
var lineList = [];
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'weight_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
$("#listTable").bootstrapTable({
url: '/record/weight/data/{$domainId}',
@@ -138,6 +138,9 @@ $(document).ready(function(){
}
},
],
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function editframe(id){

View File

@@ -40,27 +40,34 @@ tbody tr>td:nth-child(2){overflow: hidden;text-overflow: ellipsis;white-space: n
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'opiplist_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/optimizeip/opiplist/data',
pageNumber: pageNumber,
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'rr',
title: '域名',
sortable: true,
formatter: function(value, row, index) {
return '<span title="'+row.remark+'" data-toggle="tooltip" data-placement="right">' + value + '.' + row.domain + '</span>';
}
@@ -68,6 +75,7 @@ $(document).ready(function(){
{
field: 'cdn_type',
title: 'CDN运营商',
sortable: true,
formatter: function(value, row, index) {
if(value == 1){
return 'CloudFlare';
@@ -85,6 +93,7 @@ $(document).ready(function(){
{
field: 'recordnum',
title: '解析数量',
sortable: true,
formatter: function(value, row, index) {
return '<span title="" data-toggle="tooltip" data-placement="bottom" data-original-title="TTL'+row.ttl+'" class="tips">'+value+'</span>';
}
@@ -92,6 +101,7 @@ $(document).ready(function(){
{
field: 'ip_type',
title: '解析IP类型',
sortable: true,
formatter: function(value, row, index) {
var value = value.split(',')
value.forEach((element, index) => {
@@ -104,6 +114,7 @@ $(document).ready(function(){
{
field: 'active',
title: '任务开关',
sortable: true,
formatter: function(value, row, index) {
if(value == 1){
return '<div class="material-switch"><input id="active'+row.id+'" type="checkbox" checked onchange="setActive('+row.id+',0)"/><label for="active'+row.id+'" class="label-primary"></label></div>';
@@ -115,6 +126,7 @@ $(document).ready(function(){
{
field: 'updatetime',
title: '上次更新时间',
sortable: true,
formatter: function(value, row, index) {
return value ? value : '无';
}
@@ -122,6 +134,7 @@ $(document).ready(function(){
{
field: 'status',
title: '上次更新结果',
sortable: true,
formatter: function(value, row, index) {
if(value == 1) {
return '<span class="label label-success">成功</span>';
@@ -146,7 +159,10 @@ $(document).ready(function(){
],
onLoadSuccess: function(data) {
$('[data-toggle="tooltip"]').tooltip()
}
},
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function setActive(id, active){

View File

@@ -45,19 +45,24 @@ tbody tr>td:nth-child(5){overflow: hidden;text-overflow: ellipsis;white-space: n
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'stask_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/schedule/stask/data',
pageNumber: pageNumber,
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: '',
@@ -65,11 +70,13 @@ $(document).ready(function(){
},
{
field: 'id',
title: 'ID'
title: 'ID',
sortable: true
},
{
field: 'rr',
title: '域名',
sortable: true,
formatter: function(value, row, index) {
return '<span title="'+row.remark+'" data-toggle="tooltip" data-placement="right">' + value + '.' + row.domain + '</span>';
}
@@ -112,6 +119,7 @@ $(document).ready(function(){
{
field: 'active',
title: '运行开关',
sortable: true,
formatter: function(value, row, index) {
if(value == 1){
return '<div class="material-switch"><input id="active'+row.id+'" type="checkbox" checked onchange="setActive('+row.id+',0)"/><label for="active'+row.id+'" class="label-primary"></label></div>';
@@ -122,21 +130,25 @@ $(document).ready(function(){
},
{
field: 'updatetimestr',
title: '上次切换时间'
title: '上次切换时间',
sortable: true
},
{
field: 'nexttimestr',
title: '下次切换时间',
sortable: true,
visible: false
},
{
field: 'addtimestr',
title: '添加时间',
sortable: true,
visible: false
},
{
field: 'remark',
title: '备注'
title: '备注',
sortable: true
},
{
field: 'action',
@@ -153,7 +165,10 @@ $(document).ready(function(){
],
onLoadSuccess: function(data) {
$('[data-toggle="tooltip"]').tooltip()
}
},
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function setActive(id, active){

View File

@@ -29,13 +29,13 @@
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap-table-1.21.4.min.js"></script>
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'userlog_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
$("#listTable").bootstrapTable({
url: '/log/data',
@@ -71,6 +71,9 @@ $(document).ready(function(){
title: '时间'
}
],
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
</script>

View File

@@ -113,31 +113,39 @@
<script src="/static/js/bootstrap-table-page-jump-to-1.21.4.min.js"></script>
<script src="/static/js/select2-4.0.13.min.js"></script>
<script src="/static/js/select2-i18n-zh-CN-4.0.13.min.js"></script>
<script src="/static/js/custom.js"></script>
<script src="/static/js/custom.js?v=1006"></script>
<script>
$(document).ready(function(){
updateToolbar();
const defaultPageSize = 15;
const pageSizeKey = 'user_pagesize';
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
const pageSize = getStoredPageSize(pageSizeKey);
var urlSort = typeof window.$_GET['sortName'] != 'undefined' ? window.$_GET['sortName'] : undefined;
var urlOrder = typeof window.$_GET['sortOrder'] != 'undefined' ? window.$_GET['sortOrder'] : undefined;
$("#listTable").bootstrapTable({
url: '/user/data',
pageNumber: pageNumber,
pageSize: pageSize,
classes: 'table table-striped table-hover table-bordered',
sortReset: false,
sortName: urlSort,
sortOrder: urlOrder,
columns: [
{
field: 'id',
title: 'UID'
title: 'UID',
sortable: true
},
{
field: 'username',
title: '用户名'
title: '用户名',
sortable: true
},
{
field: 'level',
title: '用户等级',
sortable: true,
formatter: function(value, row, index) {
switch(value){
case 1: return '<font color="blue">普通用户</font>';break;
@@ -148,6 +156,7 @@ $(document).ready(function(){
{
field: 'is_api',
title: 'API接口',
sortable: true,
formatter: function(value, row, index) {
switch(value){
case 0: return '<font color="grey">关闭</font>';break;
@@ -157,15 +166,18 @@ $(document).ready(function(){
},
{
field: 'regtime',
title: '添加时间'
title: '添加时间',
sortable: true
},
{
field: 'lasttime',
title: '上次登录时间'
title: '上次登录时间',
sortable: true
},
{
field: 'status',
title: '状态',
sortable: true,
formatter: function(value, row, index) {
switch(value){
case 0: return '<a href="javascript:setStatus('+row.id+',1)"><font color=red><i class="fa fa-times-circle"></i>封禁</font></a>';break;
@@ -182,6 +194,9 @@ $(document).ready(function(){
}
},
],
onPageChange: function(number, size){
setStoredPageSize(pageSizeKey, size);
},
})
})
function addframe(){

View File

@@ -4,5 +4,6 @@
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:/$1]
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
</IfModule>

View File

@@ -49,13 +49,16 @@ function updateToolbar(){
function updateQueryStr(obj){
var arr = [];
for (var p in obj){
if (obj.hasOwnProperty(p) && typeof obj[p] != 'undefined' && obj[p] != '') {
if (obj.hasOwnProperty(p) && typeof obj[p] != 'undefined' && obj[p] != null && obj[p] != '') {
arr.push(p + "=" + encodeURIComponent(obj[p]));
}
}
history.replaceState({}, null, '?'+arr.join("&"));
}
var VALID_PAGE_SIZES = [10, 15, 20, 30, 50, 100, 200, 300, 500];
var DEFAULT_PAGE_SIZE = 15;
if (typeof $.fn.bootstrapTable !== "undefined") {
$.fn.bootstrapTable.custom = {
method: 'post',
@@ -64,8 +67,8 @@ if (typeof $.fn.bootstrapTable !== "undefined") {
pagination: true,
sidePagination: 'server',
pageNumber: 1,
pageSize: 20,
pageList: [10, 15, 20, 30, 50, 100],
pageSize: 15,
pageList: [10, 15, 20, 30, 50, 100, 200, 300, 500],
loadingFontSize: '18px',
toolbar: '#searchToolbar',
showColumns: true,
@@ -98,7 +101,32 @@ if (typeof $.fn.bootstrapTable !== "undefined") {
},
formatNoMatches: function(){
return '没有找到匹配的记录';
}
},
onSort: function(name, order) {
var $table = $('#listTable');
if (!name) {
$table.data('_sortClicks', null);
return;
}
var clicks = $table.data('_sortClicks') || {};
if (clicks._last !== name) {
clicks = {_last: name};
clicks[name] = 1;
this.sortOrder = 'desc';
} else {
clicks[name] = (clicks[name] || 0) + 1;
if (clicks[name] === 1) {
this.sortOrder = 'desc';
} else if (clicks[name] === 2) {
this.sortOrder = 'asc';
} else {
this.sortName = undefined;
this.sortOrder = undefined;
clicks = {};
}
}
$table.data('_sortClicks', clicks);
},
};
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.custom);
}
@@ -171,4 +199,27 @@ function delCookie(name)
if(cval!=null){
document.cookie= name + "="+cval+";expires="+exp.toGMTString();
}
}
}
function getStoredPageSize(key, defaultSize) {
defaultSize = defaultSize || DEFAULT_PAGE_SIZE;
var urlSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : null;
if (urlSize && VALID_PAGE_SIZES.indexOf(urlSize) !== -1) {
return urlSize;
}
var stored = localStorage.getItem(key);
if (stored) {
var storedSize = parseInt(stored);
if (VALID_PAGE_SIZES.indexOf(storedSize) !== -1) {
return storedSize;
}
}
return defaultSize;
}
function setStoredPageSize(key, size) {
var intSize = parseInt(size);
if (VALID_PAGE_SIZES.indexOf(intSize) !== -1) {
localStorage.setItem(key, intSize);
}
}

View File

@@ -108,6 +108,7 @@ Route::group(function () {
Route::get('/record/batchadd', 'domain/record_batch_add2');
Route::any('/record/batchedit', 'domain/record_batch_edit2');
Route::any('/record/log/:id', 'domain/record_log');
Route::post('/record/groups/:id', 'domain/record_groups');
Route::post('/record/list', 'domain/record_list');
Route::post('/record/weight/data/:id', 'domain/weight_data');
Route::any('/record/weight/:id', 'domain/weight');