Browse Source

新版本要来了 先提交一个系统预览吧

docker-svn
witersen 3 years ago
parent
commit
87bfab5009
  1. 8
      .gitignore
  2. BIN
      00.static/01.images/002.png
  3. BIN
      00.static/01.images/003.png
  4. BIN
      00.static/01.images/01.jpg
  5. BIN
      00.static/01.images/02.jpg
  6. BIN
      00.static/01.images/021.jpg
  7. BIN
      00.static/01.images/022.jpg
  8. BIN
      00.static/01.images/023.jpg
  9. BIN
      00.static/01.images/024.jpg
  10. BIN
      00.static/01.images/025.jpg
  11. BIN
      00.static/01.images/03.jpg
  12. BIN
      00.static/01.images/04.jpg
  13. BIN
      00.static/01.images/05.jpg
  14. BIN
      00.static/01.images/06.jpg
  15. BIN
      00.static/01.images/07.jpg
  16. BIN
      00.static/01.images/08.jpg
  17. BIN
      00.static/01.images/09.jpg
  18. BIN
      00.static/01.images/10.jpg
  19. BIN
      00.static/01.images/11.jpg
  20. BIN
      00.static/01.images/12.jpg
  21. BIN
      00.static/01.images/13.jpg
  22. BIN
      00.static/01.images/14.jpg
  23. BIN
      00.static/01.images/15.jpg
  24. BIN
      00.static/01.images/16.jpg
  25. BIN
      00.static/01.images/17.jpg
  26. BIN
      00.static/01.images/18.jpg
  27. BIN
      00.static/01.images/19.jpg
  28. BIN
      00.static/01.images/20.jpg
  29. BIN
      00.static/01.images/21.jpg
  30. BIN
      00.static/01.images/22.jpg
  31. BIN
      00.static/01.images/23.jpg
  32. BIN
      00.static/01.images/24.jpg
  33. BIN
      00.static/01.images/25.jpg
  34. BIN
      00.static/01.images/26.jpg
  35. BIN
      00.static/01.images/27.jpg
  36. BIN
      00.static/01.images/28.jpg
  37. BIN
      00.static/01.images/29.jpg
  38. BIN
      01.web/01.web.zip
  39. 5
      01.web/jsconfig.json
  40. 16553
      01.web/package-lock.json
  41. 19
      01.web/package.json
  42. 22
      01.web/src/app.vue
  43. 0
      01.web/src/assets/images/login.png
  44. BIN
      01.web/src/assets/images/logo.png
  45. 2
      01.web/src/components/login-form/index.js
  46. 73
      01.web/src/components/login-form/login-form.vue
  47. 205
      01.web/src/libs/export/Blob.js
  48. 141
      01.web/src/libs/export/Export2Excel.js
  49. 5
      01.web/src/libs/util.js
  50. 121
      01.web/src/main.js
  51. 131
      01.web/src/router.js
  52. BIN
      01.web/src/static/images/logo.png
  53. BIN
      01.web/src/static/images/validate0.jpg
  54. 8
      01.web/src/styles/common.css
  55. 530
      01.web/src/views/advance/index.vue
  56. 798
      01.web/src/views/analysis/analysis.vue
  57. 11
      01.web/src/views/global/token.vue
  58. 463
      01.web/src/views/group/group.vue
  59. 307
      01.web/src/views/index/index.vue
  60. 0
      01.web/src/views/layout/basicLayout/index.css
  61. 238
      01.web/src/views/layout/basicLayout/index.vue
  62. 12
      01.web/src/views/layout/blankLayout/index.vue
  63. 37
      01.web/src/views/layout/layout.less
  64. 222
      01.web/src/views/layout/layout.vue
  65. 203
      01.web/src/views/login/index.vue
  66. 20
      01.web/src/views/login/login.less
  67. 137
      01.web/src/views/login/login.vue
  68. 270
      01.web/src/views/personal/index.vue
  69. 657
      01.web/src/views/repository/repository.vue
  70. 645
      01.web/src/views/repositoryGroup/index.vue
  71. 2203
      01.web/src/views/repositoryInfo/index.vue
  72. 464
      01.web/src/views/repositoryUser/index.vue
  73. 910
      01.web/src/views/setting/setting.vue
  74. 250
      01.web/src/views/systemLog/index.vue
  75. 335
      01.web/src/views/user/user.vue
  76. 24
      01.web/src/vuex/store.js
  77. 11
      01.web/webpack.dev.config.js
  78. 7
      01.web/webpack.prod.config.js
  79. 86
      02.php/api.php
  80. 57
      02.php/app/controller/blacktoken.class.php
  81. 169
      02.php/app/controller/client.class.php
  82. 181
      02.php/app/controller/common.class.php
  83. 218
      02.php/app/controller/config.class.php
  84. 31
      02.php/app/controller/crontab.class.php
  85. 145
      02.php/app/controller/firewall.class.php
  86. 90
      02.php/app/controller/logs.class.php
  87. 166
      02.php/app/controller/mail.class.php
  88. 115
      02.php/app/controller/personal.class.php
  89. 16
      02.php/app/controller/safe.class.php
  90. 238
      02.php/app/controller/statistics.class.php
  91. 196
      02.php/app/controller/subversion.class.php
  92. 16
      02.php/app/controller/svnadmin.class.php
  93. 491
      02.php/app/controller/svngroup.class.php
  94. 1119
      02.php/app/controller/svnrep.class.php
  95. 1704
      02.php/app/controller/svnserve.class.php
  96. 291
      02.php/app/controller/svnuser.class.php
  97. 328
      02.php/app/controller/system.class.php
  98. 25
      02.php/app/controller/update.class.php
  99. 109
      02.php/app/controller/user.class.php
  100. 126
      02.php/app/core/controller.class.php
  101. Some files were not shown because too many files have changed in this diff Show More

8
.gitignore vendored

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
01.web/node_modules
01.web/node_modules/*
01.web/dist
01.web/dist/*
01.web/index.html
01.web/index_prod.html
02.php/.vscode
02.php/.vscode/*

BIN
00.static/01.images/002.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

BIN
00.static/01.images/003.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 KiB

BIN
00.static/01.images/01.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

BIN
00.static/01.images/02.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

BIN
00.static/01.images/021.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

BIN
00.static/01.images/022.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

BIN
00.static/01.images/023.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

BIN
00.static/01.images/024.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

BIN
00.static/01.images/025.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

BIN
00.static/01.images/03.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

BIN
00.static/01.images/04.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

BIN
00.static/01.images/05.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

BIN
00.static/01.images/06.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

BIN
00.static/01.images/07.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
00.static/01.images/08.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

BIN
00.static/01.images/09.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

BIN
00.static/01.images/10.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

BIN
00.static/01.images/11.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

BIN
00.static/01.images/12.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

BIN
00.static/01.images/13.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

BIN
00.static/01.images/14.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

BIN
00.static/01.images/15.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

BIN
00.static/01.images/16.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
00.static/01.images/17.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
00.static/01.images/18.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
00.static/01.images/19.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
00.static/01.images/20.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

BIN
00.static/01.images/21.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
00.static/01.images/22.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

BIN
00.static/01.images/23.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
00.static/01.images/24.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

BIN
00.static/01.images/25.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

BIN
00.static/01.images/26.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

BIN
00.static/01.images/27.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

BIN
00.static/01.images/28.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

BIN
00.static/01.images/29.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
01.web/01.web.zip

Binary file not shown.

5
01.web/jsconfig.json

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
{
"include": [
"./src/*"
]
}

16553
01.web/package-lock.json generated

File diff suppressed because it is too large Load Diff

19
01.web/package.json

@ -15,16 +15,14 @@ @@ -15,16 +15,14 @@
"author": "Aresn",
"license": "MIT",
"dependencies": {
"axios": "^0.19.2",
"echarts": "^4.9.0",
"moment": "^2.24.0",
"view-design": "^4.0.0",
"axios": "^0.25.0",
"file-saver": "^2.0.5",
"streamsaver": "^2.0.6",
"view-design": "^4.7.0",
"vue": "^2.5.16",
"vue-clipboard2": "^0.3.1",
"vue-jsonp": "^0.1.8",
"vue-monoplasty-slide-verify": "^1.1.3",
"vue-clipboard2": "^0.3.3",
"vue-router": "^2.8.1",
"vuex": "^3.1.2"
"xlsx": "^0.18.5"
},
"devDependencies": {
"autoprefixer-loader": "^2.0.0",
@ -37,11 +35,12 @@ @@ -37,11 +35,12 @@
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^2.0.0",
"file-loader": "^0.8.5",
"html-loader": "^0.5.5",
"html-loader": "^0.3.0",
"html-webpack-plugin": "^2.28.0",
"iview-loader": "^1.2.1",
"less": "^2.7.1",
"less-loader": "^2.2.3",
"script-loader": "^0.7.2",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"vue-hot-reload-api": "^1.3.3",
@ -50,7 +49,7 @@ @@ -50,7 +49,7 @@
"vue-style-loader": "^1.0.0",
"vue-template-compiler": "^2.2.1",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.11.5",
"webpack-dev-server": "^2.4.1",
"webpack-merge": "^3.0.0"
},
"bugs": {

22
01.web/src/app.vue

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
@import "styles/common.css";
</style>
<template>
<div>
<div class="app">
<router-view></router-view>
</div>
</template>
@ -13,6 +13,24 @@ export default { @@ -13,6 +13,24 @@ export default {
},
mounted() {},
beforeDestroy() {},
methods: {}
methods: {},
};
</script>
<style lang="less">
.size {
width: 100%;
height: 100%;
}
.app,
html,
body {
.size;
overflow: hidden;
margin: 0;
padding: 0;
}
#app {
.size;
}
</style>

0
01.web/src/static/images/login.png → 01.web/src/assets/images/login.png

Before

Width:  |  Height:  |  Size: 399 KiB

After

Width:  |  Height:  |  Size: 399 KiB

BIN
01.web/src/assets/images/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

2
01.web/src/components/login-form/index.js

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
import LoginForm from './login-form.vue'
export default LoginForm

73
01.web/src/components/login-form/login-form.vue

@ -1,73 +0,0 @@ @@ -1,73 +0,0 @@
<template>
<Form
ref="loginForm"
:model="form"
:rules="rules"
@keydown.enter.native="handleSubmit"
>
<FormItem prop="userName">
<Input v-model="form.userName" placeholder="请输入用户名">
<span slot="prepend">
<Icon :size="16" type="ios-person"></Icon>
</span>
</Input>
</FormItem>
<FormItem prop="password">
<Input type="password" v-model="form.password" placeholder="请输入密码">
<span slot="prepend">
<Icon :size="14" type="md-lock"></Icon>
</span>
</Input>
</FormItem>
<FormItem>
<Button @click="handleSubmit" type="primary" long>登录</Button>
</FormItem>
</Form>
</template>
<script>
export default {
name: "LoginForm",
props: {
userNameRules: {
type: Array,
default: () => {
return [{ required: true, message: "用户名不能为空", trigger: "blur" }];
},
},
passwordRules: {
type: Array,
default: () => {
return [{ required: true, message: "密码不能为空", trigger: "blur" }];
},
},
},
data() {
return {
form: {
userName: "",
password: "",
},
};
},
computed: {
rules() {
return {
userName: this.userNameRules,
password: this.passwordRules,
};
},
},
methods: {
handleSubmit() {
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.$emit("on-success-valid", {
userName: this.form.userName,
password: this.form.password,
});
}
});
},
},
};
</script>

205
01.web/src/libs/export/Blob.js

@ -0,0 +1,205 @@ @@ -0,0 +1,205 @@
/* eslint-disable */
/* Blob.js*/
/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
(function (view) {
"use strict";
view.URL = view.URL || view.webkitURL;
if (view.Blob && view.URL) {
try {
new Blob;
return;
} catch (e) {}
}
// Internally we use a BlobBuilder implementation to base Blob off of
// in order to support older browsers that only have BlobBuilder
var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function (view) {
var
get_class = function (object) {
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
},
FakeBlobBuilder = function BlobBuilder() {
this.data = [];
},
FakeBlob = function Blob(data, type, encoding) {
this.data = data;
this.size = data.length;
this.type = type;
this.encoding = encoding;
},
FBB_proto = FakeBlobBuilder.prototype,
FB_proto = FakeBlob.prototype,
FileReaderSync = view.FileReaderSync,
FileException = function (type) {
this.code = this[this.name = type];
},
file_ex_codes = (
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " +
"NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
).split(" "),
file_ex_code = file_ex_codes.length,
real_URL = view.URL || view.webkitURL || view,
real_create_object_URL = real_URL.createObjectURL,
real_revoke_object_URL = real_URL.revokeObjectURL,
URL = real_URL,
btoa = view.btoa,
atob = view.atob
,
ArrayBuffer = view.ArrayBuffer,
Uint8Array = view.Uint8Array
,
origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/;
FakeBlob.fake = FB_proto.fake = true;
while (file_ex_code--) {
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
}
// Polyfill URL
if (!real_URL.createObjectURL) {
URL = view.URL = function (uri) {
var
uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a"),
uri_origin;
uri_info.href = uri;
if (!("origin" in uri_info)) {
if (uri_info.protocol.toLowerCase() === "data:") {
uri_info.origin = null;
} else {
uri_origin = uri.match(origin);
uri_info.origin = uri_origin && uri_origin[1];
}
}
return uri_info;
};
}
URL.createObjectURL = function (blob) {
var
type = blob.type,
data_URI_header;
if (type === null) {
type = "application/octet-stream";
}
if (blob instanceof FakeBlob) {
data_URI_header = "data:" + type;
if (blob.encoding === "base64") {
return data_URI_header + ";base64," + blob.data;
} else if (blob.encoding === "URI") {
return data_URI_header + "," + decodeURIComponent(blob.data);
}
if (btoa) {
return data_URI_header + ";base64," + btoa(blob.data);
} else {
return data_URI_header + "," + encodeURIComponent(blob.data);
}
} else if (real_create_object_URL) {
return real_create_object_URL.call(real_URL, blob);
}
};
URL.revokeObjectURL = function (object_URL) {
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
real_revoke_object_URL.call(real_URL, object_URL);
}
};
FBB_proto.append = function (data /*, endings*/ ) {
var bb = this.data;
// decode data to a binary string
if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
var
str = "",
buf = new Uint8Array(data),
i = 0,
buf_len = buf.length;
for (; i < buf_len; i++) {
str += String.fromCharCode(buf[i]);
}
bb.push(str);
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
if (FileReaderSync) {
var fr = new FileReaderSync;
bb.push(fr.readAsBinaryString(data));
} else {
// async FileReader won't work as BlobBuilder is sync
throw new FileException("NOT_READABLE_ERR");
}
} else if (data instanceof FakeBlob) {
if (data.encoding === "base64" && atob) {
bb.push(atob(data.data));
} else if (data.encoding === "URI") {
bb.push(decodeURIComponent(data.data));
} else if (data.encoding === "raw") {
bb.push(data.data);
}
} else {
if (typeof data !== "string") {
data += ""; // convert unsupported types to strings
}
// decode UTF-16 to binary string
bb.push(unescape(encodeURIComponent(data)));
}
};
FBB_proto.getBlob = function (type) {
if (!arguments.length) {
type = null;
}
return new FakeBlob(this.data.join(""), type, "raw");
};
FBB_proto.toString = function () {
return "[object BlobBuilder]";
};
FB_proto.slice = function (start, end, type) {
var args = arguments.length;
if (args < 3) {
type = null;
}
return new FakeBlob(
this.data.slice(start, args > 1 ? end : this.data.length), type, this.encoding
);
};
FB_proto.toString = function () {
return "[object Blob]";
};
FB_proto.close = function () {
this.size = 0;
delete this.data;
};
return FakeBlobBuilder;
}(view));
view.Blob = function (blobParts, options) {
var type = options ? (options.type || "") : "";
var builder = new BlobBuilder();
if (blobParts) {
for (var i = 0, len = blobParts.length; i < len; i++) {
if (Uint8Array && blobParts[i] instanceof Uint8Array) {
builder.append(blobParts[i].buffer);
} else {
builder.append(blobParts[i]);
}
}
}
var blob = builder.getBlob(type);
if (!blob.slice && blob.webkitSlice) {
blob.slice = blob.webkitSlice;
}
return blob;
};
var getPrototypeOf = Object.getPrototypeOf || function (object) {
return object.__proto__;
};
view.Blob.prototype = getPrototypeOf(new view.Blob());
}(
typeof self !== "undefined" && self ||
typeof window !== "undefined" && window ||
this
));

141
01.web/src/libs/export/Export2Excel.js

@ -0,0 +1,141 @@ @@ -0,0 +1,141 @@
/* eslint-disable */
require('script-loader!file-saver');
require('script-loader!./Blob');
require('script-loader!xlsx/dist/xlsx.core.min');
function generateArray(table) {
var out = [];
var rows = table.querySelectorAll('tr');
var ranges = [];
for (var R = 0; R < rows.length; ++R) {
var outRow = [];
var row = rows[R];
var columns = row.querySelectorAll('td');
for (var C = 0; C < columns.length; ++C) {
var cell = columns[C];
var colspan = cell.getAttribute('colspan');
var rowspan = cell.getAttribute('rowspan');
var cellValue = cell.innerText;
if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
//Skip ranges
ranges.forEach(function (range) {
if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
}
});
//Handle Row Span
if (rowspan || colspan) {
rowspan = rowspan || 1;
colspan = colspan || 1;
ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}});
}
;
//Handle Value
outRow.push(cellValue !== "" ? cellValue : null);
//Handle Colspan
if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
}
out.push(outRow);
}
return [out, ranges];
};
function datenum(v, date1904) {
if (date1904) v += 1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};
for (var R = 0; R != data.length; ++R) {
for (var C = 0; C != data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
var cell = {v: data[R][C]};
if (cell.v == null) continue;
var cell_ref = XLSX.utils.encode_cell({c: C, r: R});
if (typeof cell.v === 'number') cell.t = 'n';
else if (typeof cell.v === 'boolean') cell.t = 'b';
else if (cell.v instanceof Date) {
cell.t = 'n';
cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
}
else cell.t = 's';
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
}
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
export function export_table_to_excel(id) {
var theTable = document.getElementById(id);
console.log('a')
var oo = generateArray(theTable);
var ranges = oo[1];
/* original data */
var data = oo[0];
var ws_name = "SheetJS";
console.log(data);
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add ranges to worksheet */
// ws['!cols'] = ['apple', 'banan'];
ws['!merges'] = ranges;
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
}
function formatJson(jsonData) {
console.log(jsonData)
}
export function export_json_to_excel(th, jsonData, defaultTitle) {
/* original data */
var data = jsonData;
data.unshift(th);
var ws_name = "SheetJS";
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
var title = defaultTitle || '列表'
saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
}

5
01.web/src/libs/util.js

@ -1,7 +1,8 @@ @@ -1,7 +1,8 @@
let util = {};
let util = {
};
util.title = function (title) {
title = title ? title + ' - Svn Admin' : 'Svn Admin';
title = title ? title + ' - SVNAdmin' : 'SVNAdmin';
window.document.title = title;
};

121
01.web/src/main.js

@ -1,116 +1,97 @@ @@ -1,116 +1,97 @@
import Vue from 'vue';
import App from './app.vue';
import Routers from './router';
import Vuex from 'vuex';
import store from './vuex/store';
import ViewUI from 'view-design';
Vue.use(ViewUI);
import SlideVerify from 'vue-monoplasty-slide-verify';
Vue.use(SlideVerify);
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import Routers from './router';
import Util from './libs/util';
Vue.prototype.$util = Util;
import App from './app.vue';
import 'view-design/dist/styles/iview.css';
/**
* 以下为手动安装配置的依赖
* 通过 Vue.prototype.$name 的方式 使$name在所有的Vue实例中可用
*/
//http请求 -> axios
import axios from 'axios';
Vue.prototype.$axios = axios;
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
import VueClipboard from 'vue-clipboard2'
Vue.use(VueClipboard)
import 'view-design/dist/styles/iview.css';
Vue.use(VueRouter);
Vue.use(ViewUI);
/**
* 路由配置
*/
// import streamSaver from 'streamsaver'
// 路由配置
const RouterConfig = {
mode: 'hash',
routes: Routers
};
const router = new VueRouter(RouterConfig);
//路由拦截器 beforeEach
router.beforeEach((to, from, next) => {
ViewUI.LoadingBar.start();
Util.title(to.meta.title);
if (to.matched.some(m => m.meta.requireAuth)) {
if (window.sessionStorage.token) {
if (to.meta.roles.indexOf(Number(window.sessionStorage.roleid)) == -1) {
// console.log("要访问的页面需要登录->本地存在token->要访问的页面不在允许范围内->跳转到首页");
next('/repository');
}else if (to.path == '/login') {
// console.log("要访问的页面需要登录->本地存在token->要访问的页面为登录页,则跳转到首页");
next({ path: '/repository' })
} else {
// console.log("要访问的页面需要登录->本地存在token->要访问的页面不为登录页,则放行");
//页面跳转逻辑
next();
}
} else {
// console.log("要访问的页面需要登录->本地不存在token->跳转到登录页");
next({ path: '/login' })
}
} else if (to.path == '/login' && window.sessionStorage.token) {
// console.log("要访问的页面不需要登录->要访问的页面为登录页且存在token->跳转到首页");
next({ path: '/repository' })
}
else {
// console.log("要访问的页面不需要登录,则放行");
next();
}
// if (to.matched.some(m => m.meta.requireAuth)) {
// if (window.sessionStorage.token) {
// if (to.path == '/login') {
// next({ path: '/residentManage' })
// } else {
// next();
// }
// } else {
// next({ path: '/login' })
// }
// } else if (to.path == '/login' && window.sessionStorage.token) {
// next({ path: '/residentManage' })
// }
// else {
// next();
// }
});
//路由拦截器 afterEach
router.afterEach((to, from, next) => {
ViewUI.LoadingBar.finish();
window.scrollTo(0, 0);
});
/**
* 配置请求拦截器
* 请求拦截器
*/
axios.defaults.baseURL = "/"; //公共url
axios.interceptors.request.use(config => {
axios.interceptors.request.use(function (config) {
if (window.sessionStorage.token) {
config.headers.common['token'] = window.sessionStorage.token; //将token加入到请求头
} else {
//将token加入到请求头
config.headers.common['token'] = window.sessionStorage.token;
}
return config
}, error => {
// 异常
if (error.response) {
// switch (error.response.status) {
// case 401:
// sessionStorage.removeItem('token');
// router.replace({
// path: '/',
// query: { redirect: router.currentRoute.fullPath }//登录成功后跳入浏览的当前页面
// })
// }
}
})
}, function (error) {
return Promise.reject(error);
});
/**
* 配置响应拦截器
* 响应拦截器
*/
axios.interceptors.response.use(response => {
axios.interceptors.response.use(function (response) {
if (response.data.code != undefined && response.data.code != '') {
if (response.data.code != 200) {
window.sessionStorage.removeItem('token');//清除本地token
sessionStorage.removeItem('token');
sessionStorage.removeItem('user_name');
sessionStorage.removeItem('user_role_id');
sessionStorage.removeItem('user_role_name');
router.push('/');
}
}
return response
}, error => {
// 异常
return Promise.reject(error)
})
return response;
}, function (error) {
return Promise.reject(error);
});
new Vue({
el: '#app',
router: router,
store,
render: h => h(App)
});

131
01.web/src/router.js

@ -1,81 +1,120 @@ @@ -1,81 +1,120 @@
const publicRoutes = [
const routers = [
{
name: 'login',
path: '/login',
meta: {
requireAuth: false,
title: ''
},
component: (resolve) => require(['./views/login/login.vue'], resolve)
component: (resolve) => require(['./views/login/index.vue'], resolve)
},
{
name: 'manage',
path: '/',
redirect: 'repository',
redirect: { name: 'login' },
meta: {
requireAuth: true,
roles: [1, 2]
title: 'SVNAdmin',
},
component: (resolve) => require(['./views/layout/layout.vue'], resolve),
component: (resolve) => require(['./views/layout/basicLayout/index.vue'], resolve),
children: [
{
name: 'repository',
path: 'repository',
name: 'index',
path: '/index',
meta: {
title: '服务总览',
isNav: true,
requireAuth: true,
roles: [1, 2]
title: '信息统计',
icon: "ios-stats",
user_role_id: ['1'],
group: {
name: "仓库",
num: 1
}
},
component: (resolve) => require(['./views/analysis/analysis.vue'], resolve)
component: (resolve) => require(['./views/index/index.vue'], resolve)
},
{
name: 'analysis',
path: 'analysis',
name: 'repositoryInfo',
path: '/repositoryInfo',
meta: {
title: '仓库管理',
isNav: true,
requireAuth: true,
roles: [1, 2]
title: 'SVN仓库',
icon: 'logo-buffer',
user_role_id: ['1', '2'],
group: {
name: "",
num: 1
}
},
component: (resolve) => require(['./views/repository/repository.vue'], resolve)
component: (resolve) => require(['./views/repositoryInfo/index.vue'], resolve)
},
{
name: 'user',
path: 'user',
name: 'repositoryUser',
path: '/repositoryUser',
meta: {
title: '用户管理',
isNav: true,
requireAuth: true,
roles: [1]
title: 'SVN用户',
icon: 'md-person',
user_role_id: ['1'],
group: {
name: "",
num: 1
}
},
component: (resolve) => require(['./views/user/user.vue'], resolve)
component: (resolve) => require(['./views/repositoryUser/index.vue'], resolve),
},
{
name: 'group',
path: 'group',
name: 'repositoryGroup',
path: '/repositoryGroup',
meta: {
title: '分组管理',
isNav: true,
requireAuth: true,
roles: [1]
title: 'SVN分组',
icon: 'md-people',
user_role_id: ['1'],
group: {
name: "",
num: 1
}
},
component: (resolve) => require(['./views/group/group.vue'], resolve)
component: (resolve) => require(['./views/repositoryGroup/index.vue'], resolve),
},
{
name: 'sys',
path: 'setting',
name: 'systemLog',
path: '/systemLog',
meta: {
title: '系统设置',
isNav: true,
requireAuth: true,
roles: [1]
title: '系统日志',
icon: 'md-bug',
user_role_id: ['1'],
group: {
name: "运维",
num: 2
}
},
component: (resolve) => require(['./views/setting/setting.vue'], resolve),
component: (resolve) => require(['./views/systemLog/index.vue'], resolve),
},
{
name: 'personal',
path: '/personal',
meta: {
title: '个人中心',
icon: 'md-cube',
user_role_id: ['1', '2'],
group: {
name: "高级",
num: 3
}
},
component: (resolve) => require(['./views/personal/index.vue'], resolve),
},
{
name: 'advance',
path: '/advance',
meta: {
title: '系统配置',
icon: 'md-settings',
user_role_id: ['1'],
group: {
name: "",
num: 3
}
},
component: (resolve) => require(['./views/advance/index.vue'], resolve),
}
]
},
];
export default publicRoutes;
export default routers;

BIN
01.web/src/static/images/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

BIN
01.web/src/static/images/validate0.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

8
01.web/src/styles/common.css

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
/*列表上方操作信息*/
.page-card-oper { overflow: hidden; margin-top: 10px;}
.page-card-oper .oper {float: left;}
.page-card-oper .search {float: right;}
/*列表中操作信息*/
.page-table .pager {float: right;margin-top: 20px; }
.page-table {margin-top: 20px;/* overflow: hidden; */margin-bottom: 10px;}
.operButton {margin-right: 5px;}

530
01.web/src/views/advance/index.vue

@ -0,0 +1,530 @@ @@ -0,0 +1,530 @@
<template>
<div>
<Card :bordered="false" :dis-hover="true">
<Tabs value="1">
<TabPane label="Subversion" name="1">
<Card :bordered="false" :dis-hover="true" style="width: 620px">
<Form :label-width="140">
<FormItem label="Subversion">
<Row :gutter="16">
<Col span="12">
<span>{{ formSvn.version }}</span>
</Col>
<Col span="6">
<Button
type="error"
v-if="formSvn.installed == 1 || formSvn.installed == 2"
@click="UnInstall"
>卸载</Button
>
<Button
type="primary"
v-if="formSvn.installed == 0"
@click="Install"
>安装</Button
>
</Col>
</Row>
</FormItem>
<FormItem label="运行状态">
<Row :gutter="16">
<Col span="12">
<span style="color: #ff9900" v-if="formSvn.installed == 0"
>未安装</span
>
<span style="color: #2db7f5" v-if="formSvn.installed == 1"
>未启动</span
>
<span style="color: #19be6b" v-if="formSvn.installed == 2"
>运行中</span
>
<span style="color: #ed4014" v-if="formSvn.installed == -1"
>未知</span
>
</Col>
<Col span="6">
<Button
type="success"
v-if="formSvn.installed == 1"
@click="Start"
>启动</Button
>
<Button
type="success"
v-if="formSvn.installed == 2"
@click="Stop"
>停止</Button
>
</Col>
</Row>
</FormItem>
<FormItem label="svnserve绑定端口">
<Row :gutter="16">
<Col span="12">
<span>{{ formSvn.bindPort }}</span>
</Col>
<Col span="6">
<Button type="warning" @click="ModalEditPort">修改</Button>
</Col>
</Row>
</FormItem>
<FormItem label="svnserve绑定主机名">
<Row :gutter="16">
<Col span="12">
<span>{{ formSvn.bindHost }}</span>
</Col>
<Col span="6">
<Tooltip
:transfer="true"
max-width="350"
content="请注意,如果您的机器为公网服务器且非弹性IP,则可能会绑定失败。原因与云服务器厂商分配公网IP给服务器的方式有关。如果绑定失败,建议配置使用管理系统主机名代替检出地址。"
>
<Button type="warning" @click="ModalEditHost"
>修改</Button
>
</Tooltip>
</Col>
</Row>
</FormItem>
<FormItem label="管理系统主机名">
<Row :gutter="16">
<Col span="12">
<span>{{ formSvn.manageHost }}</span>
</Col>
<Col span="6">
<Button type="warning" @click="ModalEditManageHost"
>修改</Button
>
</Col>
</Row>
</FormItem>
<FormItem label="检出地址选用">
<Row :gutter="16">
<Col span="12">
<RadioGroup
v-model="formSvn.enable"
@on-change="EditEnable"
>
<Radio :label="formSvn.bindHost"></Radio>
<Radio :label="formSvn.manageHost"></Radio>
</RadioGroup>
</Col>
<Col span="6"> </Col>
</Row>
</FormItem>
<FormItem label="svnserve运行日志">
<Row :gutter="16">
<Col span="12">
<span>{{ formSvn.svnserveLog }}</span>
</Col>
<Col span="6">
<Button type="success" @click="ViewSvnserveLog"
>查看</Button
>
</Col>
</Row>
</FormItem>
</Form>
</Card>
</TabPane>
<TabPane label="配置文件" name="2">
<Card :bordered="false" :dis-hover="true" style="width: 600px">
<Form :label-width="160">
<FormItem
:label="item.key"
v-for="(item, index) in configList"
:key="index"
>
<Row :gutter="16">
<Col span="12">
<span>{{ item.value }}</span>
</Col>
</Row>
</FormItem>
</Form>
</Card>
</TabPane>
<TabPane label="邮件服务" name="3">
<Card :bordered="false" :dis-hover="true" style="width: 600px">
<Form :label-width="140">
<FormItem label="SMTP主机">
<Row :gutter="16">
<Col span="12">
<Input value="2.4.0"></Input>
</Col>
</Row>
</FormItem>
<FormItem label="SMTP端口">
<Row :gutter="16">
<Col span="12">
<Input value="2.4.0"></Input>
</Col>
</Row>
</FormItem>
<FormItem label="SMTP用户名">
<Row :gutter="16">
<Col span="12">
<Input value="2.4.0"></Input>
</Col>
</Row>
</FormItem>
<FormItem label="SMTP密码">
<Row :gutter="16">
<Col span="12">
<Input value="2.4.0"></Input>
</Col>
</Row>
</FormItem>
<FormItem label="发件人邮箱">
<Row :gutter="16">
<Col span="12">
<Input value="2.4.0"></Input>
</Col>
</Row>
</FormItem>
<FormItem label="测试接收邮箱">
<Row :gutter="16">
<Col span="12">
<Input value="2.4.0"></Input>
</Col>
<Col span="6">
<Button type="success">发送测试邮件</Button>
</Col>
</Row>
</FormItem>
<FormItem label="默认启用状态">
<Row :gutter="16">
<Col span="12">
<Switch>
<Icon type="md-checkmark" slot="open"></Icon>
<Icon type="md-close" slot="close"></Icon>
</Switch>
</Col>
</Row>
</FormItem>
<FormItem>
<Button type="primary">保存</Button>
</FormItem>
</Form>
</Card>
</TabPane>
<TabPane label="消息推送" name="4">
<Card :bordered="false" :dis-hover="true" style="width: 600px">
<Form :label-width="140">
<FormItem label="用户登录">
<Row :gutter="16">
<Col span="12">
<Switch>
<Icon type="md-checkmark" slot="open"></Icon>
<Icon type="md-close" slot="close"></Icon>
</Switch>
</Col>
</Row>
</FormItem>
<FormItem label="用户密码修改">
<Row :gutter="16">
<Col span="12">
<Switch>
<Icon type="md-checkmark" slot="open"></Icon>
<Icon type="md-close" slot="close"></Icon>
</Switch>
</Col>
</Row>
</FormItem>
<FormItem label="任务计划执行失败">
<Row :gutter="16">
<Col span="12">
<Switch>
<Icon type="md-checkmark" slot="open"></Icon>
<Icon type="md-close" slot="close"></Icon>
</Switch>
</Col>
</Row>
</FormItem>
<FormItem>
<Button type="primary">保存</Button>
</FormItem>
</Form>
</Card>
</TabPane>
<TabPane label="系统安全" name="5">
<Card :bordered="false" :dis-hover="true" style="width: 600px">
<Form :label-width="140">
<FormItem label="token">
1本系统使用token进行鉴权和登录状态保持<br />
2密钥 + 算法 = token<br />
3密钥泄露会导致token被伪造从而登录本系统<br />
4定期重置密钥可以增加系统的安全性<br />
5重置密钥后所有管理系统在线用户会被下线<br />
</FormItem>
<FormItem label="密钥">
<Row :gutter="16">
<Col span="12">
<Input type="password" readonly value="2.4.0"></Input>
</Col>
<Col span="6"> <Button type="primary">重置</Button></Col>
</Row>
</FormItem>
</Form>
</Card>
</TabPane>
<TabPane label="系统更新" name="6">
<Card :bordered="false" :dis-hover="true" style="width: 600px">
<Form :label-width="140">
<FormItem label="当前版本">
<Badge> v2.3 </Badge>
</FormItem>
<FormItem label="支持PHP-FPM版本">
<Row :gutter="16">
<Col span="12">
<span>5.4+</span>
</Col>
</Row>
</FormItem>
<FormItem label="支持PHP-CLI版本">
<Row :gutter="16">
<Col span="12">
<span>5.4+</span>
</Col>
</Row>
</FormItem>
<FormItem label="支持数据库">
<Row :gutter="16">
<Col span="12">
<span>MySQLsqlite</span>
</Col>
</Row>
</FormItem>
<FormItem label="开源地址">
<Row>
<Badge>
<a href="" target="_blank">GitHub</a>
</Badge>
</Row>
<Row>
<Badge>
<a href="" target="_blank">Gitee</a>
</Badge>
</Row>
</FormItem>
<FormItem>
<Tooltip max-width="300" content="111" placement="top" transfer>
<Button type="primary" @click="CheckUpdate()"
>检测更新</Button
>
</Tooltip>
</FormItem>
</Form>
</Card>
</TabPane>
</Tabs>
</Card>
</div>
</template>
<script>
export default {
data() {
return {
/**
* subversion信息
*/
formSvn: {
version: "",
installed: null,
bindPort: "",
bindHost: "",
manageHost: "",
enable: "",
svnserveLog: "",
},
/**
*
*/
configList: [],
/**
* 对话框
*/
//
modalAddRep: false,
//
modalEditRepName: false,
/**
* 表单
*/
//
formRepAdd: {},
//
formRepEdit: {
repNameOld: "",
repNameNew: "",
},
/**
* 表格
*/
//
tableRepColumn: [
{
title: "序号",
type: "index",
},
{
title: "用户名",
key: "repName",
tooltip: true,
sortable: true,
},
{
title: "密码",
key: "repRev",
tooltip: true,
},
{
title: "启用状态",
slot: "repStatus",
sortable: true,
},
{
title: "过期时间",
key: "repRemarks",
sortable: true,
},
{
title: "备注信息",
key: "repRemarks",
},
{
title: "其它",
slot: "action",
width: 180,
},
],
tableRepData: [
{
repName: "xxxxxxxxxxxxxxxxxxxxxxxxxx",
repRev: 12,
repSize: 128,
repStatus: 0,
},
],
};
},
computed: {},
created() {},
mounted() {
this.GetDetail();
this.GetConfig();
},
methods: {
/**
* 获取版本信息
*/
GetDetail() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=subversion&a=GetDetail&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.formSvn = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 获取配置文件信息
*/
GetConfig() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=subversion&a=GetConfig&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.configList = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 安装SVN
*/
Install() {},
/**
* 卸载SVN
*/
UnInstall() {},
/**
* 启动SVN
*/
Start() {},
/**
* 停止SVN
*/
Stop() {},
/**
* 修改svnserve的绑定端口
*/
ModalEditPort() {},
EditPort() {},
/**
* 修改svnserve的绑定主机
*/
ModalEditHost() {},
EditHost() {},
/**
* 修改管理系统主机名
*/
ModalEditManageHost() {},
EditManageHost() {},
/**
* 修改检出地址
*/
EditEnable(value) {},
/**
* 查看svnserve运行日志
*/
ViewSvnserveLog() {},
/**
* 添加仓库
*/
ModalAddRep() {
this.modalAddRep = true;
},
AddRep() {},
/**
* 编辑仓库名称
*/
ModalEditRepName(index, repName) {
this.modalEditRepName = true;
},
EditRepName() {},
/**
* 删除仓库
*
*/
DelRep(index, repName) {
this.$Modal.confirm({
title: "删除SVN用户-xxxxx用户",
content: "确定要删除该用户吗?<br/>该操作不可逆!",
onOk: () => {},
});
},
},
};
</script>
<style >
</style>

798
01.web/src/views/analysis/analysis.vue

@ -1,798 +0,0 @@ @@ -1,798 +0,0 @@
<style scoped lang="less">
.circle {
// display: inline-block;
width: 100px;
height: 100px;
margin: 0 auto;
}
.gailan {
width: 200px;
height: 40px;
line-height: 40px;
font-size: 32px;
color: #28bcfe;
}
.p_top {
margin-bottom: 4px;
color: #999;
}
.p_bottom {
margin-top: 4px;
color: #999;
}
/* 一级导航 */
</style>
<template>
<div>
<Card :bordered="false" :dis-hover="true">
<p slot="title" font-size:10px>状态</p>
<Row>
<Col span="4">
<Card style="width: 200px" :dis-hover="true" :bordered="false">
<div style="text-align: center">
<P class="p_top">负载状态</P>
<div id="fuzai" class="circle"></div>
<P class="p_bottom">运行流畅</P>
</div>
</Card>
</Col>
<Col span="4">
<Card style="width: 200px" :dis-hover="true" :bordered="false">
<div style="text-align: center">
<P class="p_top">CPU利用率</P>
<div id="cpu" class="circle"></div>
<P class="p_bottom">1核心</P>
</div>
</Card>
</Col>
<Col span="4">
<Card style="width: 200px" :dis-hover="true" :bordered="false">
<div style="text-align: center">
<P class="p_top">内存利用率</P>
<div id="neicun" class="circle"></div>
<P class="p_bottom"
>{{ this.system_mem_status.used }}/{{
this.system_mem_status.total
}}(MB)</P
>
</div>
</Card>
</Col>
<Col span="4">
<Card style="width: 200px" :dis-hover="true" :bordered="false">
<div style="text-align: center">
<P class="p_top">硬盘利用率</P>
<div id="yingpan" class="circle"></div>
<P class="p_bottom"
>{{ this.system_disk_status.DiskUsed }}/{{
this.system_disk_status.DiskTotal
}}(GB)</P
>
</div>
</Card>
</Col>
</Row>
</Card>
<br />
<Card :bordered="false" :dis-hover="true">
<p slot="title" font-size:10px>概览</p>
<Row>
<Col span="4">
<Card style="width: 235px" :dis-hover="true" :bordered="true">
<div style="text-align: center">
<P class="p_top">操作系统</P>
<div class="gailan">{{ this.gailan.os_type }}</div>
</div>
</Card>
</Col>
<Col span="4">
<Card style="width: 235px" :dis-hover="true" :bordered="true">
<div style="text-align: center">
<P class="p_top">服务器运行天数</P>
<div class="gailan">{{ this.gailan.os_runtime }}</div>
</div>
</Card>
</Col>
<Col span="4">
<Card style="width: 235px" :dis-hover="true" :bordered="true">
<div style="text-align: center">
<P class="p_top">SVN仓库</P>
<div class="gailan">{{ this.gailan.repository_count }}</div>
</div>
</Card>
</Col>
<Col span="4">
<Card style="width: 235px" :dis-hover="true" :bordered="true">
<div style="text-align: center">
<P class="p_top">系统管理员</P>
<div class="gailan">{{ this.gailan.super_count }}</div>
</div>
</Card>
</Col>
<!-- <Col span="4">
<Card style="width: 235px" :dis-hover="true" :bordered="true">
<div style="text-align: center">
<P class="p_top">系统管理员</P>
<div class="gailan">{{ this.gailan.sys_count }}</div>
</div>
</Card>
</Col> -->
<Col span="4">
<Card style="width: 235px" :dis-hover="true" :bordered="true">
<div style="text-align: center">
<P class="p_top">SVN用户</P>
<div class="gailan">{{ this.gailan.user_count }}</div>
</div>
</Card>
</Col>
</Row>
</Card>
<br />
<!-- <Card :bordered="false" :dis-hover="true">
<p slot="title" font-size:10px>实时流量</p>
<div v-for="(item, index) in network" :key="item.index">
<Row>
<Col span="20">
<Card :dis-hover="true" :bordered="true">
<p slot="title" font-size:10px>{{ index }}</p>
<div :id="index" style="height: 230px"></div>
</Card>
</Col>
</Row>
<br />
</div>
<br />
</Card> -->
</div>
</template>
<script>
export default {
data() {
return {
//
network: {
// eth0: [
// {
// ReceiveSpeed: 0,
// TransmitSpeed: 0,
// time: "17:32:03",
// },
// ],
},
//
gailan: {
os_type: "",
os_runtime: "",
repository_count: "",
super_count: "",
sys_count: "",
user_count: "",
},
//
system_fuzai_status: {
avg_percent: "5",
minute_1_avg: "最近1分钟平均负载:",
minute_5_avg: "最近5分钟平均负载:",
minute_15_avg: "最近15分钟平均负载:",
},
//CPU
system_cpu_status: {
percent: "5",
num: "",
},
//
system_mem_status: {
total: "5",
free: "5",
used: "5",
percent: "5",
},
//
system_disk_status: {
DiskTotal: "5",
DiskFree: "5",
DiskUsed: "5",
DiskPercent: "5",
},
};
},
methods: {
//1
GetNetwork() {
console.log("加载函数GetNetwork");
var that = this;
var data = {};
that.$axios
.post("/api.php?c=system&a=GetNetwork", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.network = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
//2
NetworkDraw() {
console.log("加载函数NetworkDraw");
var that = this;
Object.keys(that.network).forEach(function (item, index) {
that.liuliangTable(item);
});
},
//3 id
liuliangTable(network_name) {
console.log("加载函数liuliangTable");
var that = this;
var liuliang = that.$echarts.init(document.getElementById(network_name));
var charts = {
lineX: ["17:01", "17:02", "17:03", "17:04", "17:05", "17:06", "17:07"],
// lineX: [],
value: [
[1451, 352, 303, 534, 95, 236, 217, 328],
[360, 545, 80, 192, 330, 580, 192, 80],
],
// value: [
// [],
// [],
// ],
};
var option = {
series: [
{
name: "上行",
type: "line",
color: "rgba(23, 255, 243)",
smooth: true, //使线
symbol: "circle",
data: charts.value[0],
areaStyle: {}, //线
symbol: "none", //
},
{
name: "下行",
type: "line",
color: "rgba(255,100,97)",
smooth: true,
symbol: "circle",
data: charts.value[1],
areaStyle: {}, //线
symbol: "none", //
},
],
tooltip: {
trigger: "axis",
},
legend: {
textStyle: {
fontSize: 12,
},
right: "18%",
},
grid: {
top: "14%",
left: "1%",
right: "13%",
bottom: "0",
containLabel: true, //
},
xAxis: {
type: "category",
data: charts.lineX,
boundaryGap: false,
},
yAxis: {
name: "Kbps",
type: "value",
},
};
liuliang.setOption(option);
// setInterval(function () {
// that.GetNetworkByName(network_name);
// liuliang.setOption(option);
// }, 10000);
},
//4 pushdatadata
GetNetworkByName(network_name) {
var that = this;
var data = {
network_name: network_name,
};
that.$axios
.post("/api.php?c=system&a=GetNetworkByName", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.network[network_name].push(result.data[0].data[0]);
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
flush_on_time() {
var that = this;
that.GetCPURate();
that.GetLoadAvg();
that.GetMemInfo();
that.GetDiskInfo();
},
GetGailan() {
var that = this;
var data = {
};
that.$axios
.post("/api.php?c=svnserve&a=GetGailan", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.gailan = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
GetLoadAvg() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=system&a=GetLoadAvg", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.system_fuzai_status = result.data;
that.fuzaicircle();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
GetCPURate() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=system&a=GetCPURate", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.system_cpu_status = result.data;
// console.log(that.system_cpu_status);
that.cpucircle();
} else {
// console.log(result);
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
GetMemInfo() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=system&a=GetMemInfo", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.system_mem_status = result.data;
that.neicuncricle();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
GetDiskInfo() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=system&a=GetDiskInfo", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.system_disk_status = result.data;
that.yingpancricle();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
fuzaicircle() {
var that = this;
let fuzai = that.$echarts.init(document.getElementById("fuzai"));
var getvalue = [that.system_fuzai_status.avg_percent];
fuzai.setOption({
title: {
text: getvalue + "%",
textStyle: {
color: "#28BCFE",
fontSize: 20,
},
// subtext: "",
// subtextStyle: {
// color: "#666666",
// fontSize: 12,
// },
// itemGap: 20,
left: "center",
top: "40%",
},
tooltip: {
position: ["50%", "50%"],
formatter: function (params) {
return (
'<span style="color: #fff;">' +
that.system_fuzai_status.minute_1_avg +
"<br/>" +
that.system_fuzai_status.minute_5_avg +
"<br/>" +
that.system_fuzai_status.minute_15_avg +
"</span>"
);
},
},
angleAxis: {
max: 100,
clockwise: true, //
// 线
show: false,
},
radiusAxis: {
type: "category",
show: true,
axisLabel: {
show: false,
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
polar: {
center: ["50%", "50%"],
radius: ["85%", "100%"], //
},
series: [
{
type: "bar",
data: getvalue,
showBackground: true,
backgroundStyle: {
color: "#BDEBFF",
},
coordinateSystem: "polar",
roundCap: true,
barWidth: 9,
itemStyle: {
normal: {
opacity: 1,
color: new that.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#25BFFF",
},
{
offset: 1,
color: "#5284DE",
},
]),
shadowBlur: 5,
shadowColor: "#2A95F9",
},
},
},
],
});
},
cpucircle() {
var that = this;
let cpu = that.$echarts.init(document.getElementById("cpu"));
var getvalue = [that.system_cpu_status.percent];
cpu.setOption({
title: {
text: getvalue + "%",
textStyle: {
color: "#28BCFE",
fontSize: 20,
},
// subtext: "CPU",
// subtextStyle: {
// color: "#666666",
// fontSize: 12,
// },
itemGap: 20,
left: "center",
top: "40%",
},
tooltip: {
formatter: function (params) {
return (
'<span style="color: #fff;">CPU使用率:' + getvalue + "%</span>"
);
},
},
angleAxis: {
max: 100,
clockwise: true, //
// 线
show: false,
},
radiusAxis: {
type: "category",
show: true,
axisLabel: {
show: false,
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
polar: {
center: ["50%", "50%"],
radius: ["85%", "100%"], //
},
series: [
{
type: "bar",
data: getvalue,
showBackground: true,
backgroundStyle: {
color: "#BDEBFF",
},
coordinateSystem: "polar",
roundCap: true,
barWidth: 9,
itemStyle: {
normal: {
opacity: 1,
color: new that.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#25BFFF",
},
{
offset: 1,
color: "#5284DE",
},
]),
shadowBlur: 5,
shadowColor: "#2A95F9",
},
},
},
],
});
},
neicuncricle() {
var that = this;
let neicun = that.$echarts.init(document.getElementById("neicun"));
//使
var getvalue = [that.system_mem_status.percent];
neicun.setOption({
title: {
text: getvalue + "%",
textStyle: {
color: "#28BCFE",
fontSize: 20,
},
// subtext: "",
// subtextStyle: {
// color: "#666666",
// fontSize: 12,
// },
itemGap: 20,
left: "center",
top: "40%",
},
tooltip: {
formatter: function (params) {
return (
'<span style="color: #fff;">内存使用率:' + getvalue + "%</span>"
);
},
},
angleAxis: {
max: 100,
clockwise: true, //
// 线
show: false,
},
radiusAxis: {
type: "category",
show: true,
axisLabel: {
show: false,
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
polar: {
center: ["50%", "50%"],
radius: ["85%", "100%"], //
},
series: [
{
type: "bar",
data: getvalue,
showBackground: true,
backgroundStyle: {
color: "#BDEBFF",
},
coordinateSystem: "polar",
roundCap: true,
barWidth: 9,
itemStyle: {
normal: {
opacity: 1,
color: new that.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#25BFFF",
},
{
offset: 1,
color: "#5284DE",
},
]),
shadowBlur: 5,
shadowColor: "#2A95F9",
},
},
},
],
});
},
yingpancricle() {
var that = this;
let yingpan = that.$echarts.init(document.getElementById("yingpan"));
var getvalue = [that.system_disk_status.DiskPercent];
yingpan.setOption({
title: {
text: getvalue + "%",
textStyle: {
color: "#28BCFE",
fontSize: 20,
},
// subtext: "",
// subtextStyle: {
// color: "#666666",
// fontSize: 12,
// },
itemGap: 20,
left: "center",
top: "40%",
},
tooltip: {
formatter: function (params) {
return (
'<span style="color: #fff;">硬盘使用率:' + getvalue + "%</span>"
);
},
},
angleAxis: {
max: 100,
clockwise: true, //
// 线
show: false,
},
radiusAxis: {
type: "category",
show: true,
axisLabel: {
show: false,
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
polar: {
center: ["50%", "50%"],
radius: ["85%", "100%"], //
},
series: [
{
type: "bar",
data: getvalue,
showBackground: true,
backgroundStyle: {
color: "#BDEBFF",
},
coordinateSystem: "polar",
roundCap: true,
barWidth: 9,
itemStyle: {
normal: {
opacity: 1,
color: new that.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#25BFFF",
},
{
offset: 1,
color: "#5284DE",
},
]),
shadowBlur: 5,
shadowColor: "#2A95F9",
},
},
},
],
});
},
},
created() {},
mounted() {
var that = this;
const timer = window.setInterval(() => {
setTimeout(that.flush_on_time(), 0);
}, 5000);
that.$once("hook:beforeDestroy", () => {
clearInterval(timer);
});
that.GetGailan();
that.GetLoadAvg();
that.GetCPURate();
that.GetMemInfo();
that.GetDiskInfo();
that.cpucircle();
that.neicuncricle();
that.yingpancricle();
that.fuzaicircle();
// that.GetNetwork();
},
beforeDestroy() {
// clearInterval(this.timer);
},
updated() {
// var that = this;
// that.NetworkDraw();
},
};
</script>

11
01.web/src/views/global/token.vue

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
<template></template>
<script>
const logo_svnadmin = "";
export default {
logo_svnadmin,
};
</script>
<style>
</style>

463
01.web/src/views/group/group.vue

@ -1,463 +0,0 @@ @@ -1,463 +0,0 @@
<template>
<Card :bordered="false" :dis-hover="true">
<Tooltip max-width="150" :content="toolTipAddGroup">
<Button type="primary" @click="ModalAddRepGroup()">新建分组</Button>
</Tooltip>
<div class="page-table">
<Table :columns="tableColumnRepGroup" :data="tableDataRepGroup">
<template slot-scope="{ index }" slot="id">
<strong>{{ index + 1 }}</strong>
</template>
<template slot-scope="{ index }" slot="action">
<Button
type="primary"
size="small"
@click="ModalRepGroupUserGet(index)"
>用户</Button
>
<Button
type="primary"
size="small"
@click="ModalRepGroupGroupGet(index)"
>分组</Button
>
<Button type="success" size="small" @click="ModalRepGroupEdit(index)"
>编辑</Button
>
<Button type="error" size="small" @click="ModalRepGroupDel(index)"
>删除</Button
>
</template>
</Table>
<Card :bordered="false" :dis-hover="true">
<Page
v-if="numRepGroupTotal != 0"
:total="numRepGroupTotal"
:page-size="numRepGroupPageSize"
@on-change="PagesizeChange"
/>
</Card>
</div>
<Modal
v-model="modalRepGroupAdd"
title="新建SVN分组"
@on-ok="RepAddGroup()"
>
<Form
ref="formRepGroup"
:model="formRepGroup"
:label-width="80"
@submit.native.prevent
>
<FormItem label="组名称">
<Input v-model="formRepGroup.groupName" />
</FormItem>
</Form>
</Modal>
<Modal
v-model="modalRepGroupEdit"
title="编辑SVN分组信息"
@on-ok="RepEditGroup()"
>
<Form ref="formRepGroup" :model="formRepGroup" :label-width="80">
<FormItem label="组名称">
<Input v-model="formRepGroup.groupName" />
</FormItem>
</Form>
</Modal>
<Modal
v-model="modalRepGroupUserGet"
title="将选择的用户作为当前分组的成员"
@on-ok="SetRepUserGroup"
>
<Table
height="400"
border
:columns="tableColumnRepUser"
:data="tableDataRepUser"
>
<template slot-scope="{ index }" slot="id">
<strong>{{ index + 1 }}</strong>
</template>
<template slot-scope="{ index }" slot="slot_status">
<RadioGroup type="button" v-model="tableDataRepUser[index].status">
<Radio label="in"><span>成员</span></Radio>
<Radio label="no"><span>非成员</span></Radio>
</RadioGroup>
</template>
</Table>
</Modal>
<Modal
v-model="modalRepGroupGroupGet"
title="将选择的分组作为当前分组的成员"
@on-ok="SetRepGroupGroup"
>
<Table
height="400"
border
:columns="tableColumnRepGroupGroup"
:data="tableDataRepGroupGroup"
>
<template slot-scope="{ index }" slot="id">
<strong>{{ index + 1 }}</strong>
</template>
<template slot-scope="{ index }" slot="slot_status">
<RadioGroup
type="button"
v-model="tableDataRepGroupGroup[index].status"
>
<Radio label="in"><span>成员</span></Radio>
<Radio label="no"><span>非成员</span></Radio>
</RadioGroup>
</template>
</Table>
</Modal>
</Card>
</template>
<script>
export default {
data() {
return {
toolTipAddGroup: "SVN分组名称只能包含字母、数字、破折号、下划线、点",
/**
* 布尔值
*/
boolIsAdmin: window.sessionStorage.roleid == 1 ? true : false,
/**
* 对话框控制
*/
modalRepGroupAdd: false, //
modalRepGroupEdit: false, //
modalRepGroupUserGet: false,
modalRepGroupGroupGet: false,
/**
* 临时数据
*/
tempRepGroupName: "",
tempRepGroupUserCurrentSelect: "",
tempRepGroupGroupCurrentSelect: "",
/**
* 分页数据
*/
numRepGroupPageCurrent: 1,
numRepGroupPageSize: 10,
numRepGroupTotal: 20,
formRepGroup: {
groupName: "", //
},
/**
* 分组表格数据
*/
tableColumnRepGroup: [
{
title: "序号",
slot: "id",
width: 150,
},
{
title: "组名称",
key: "groupName",
},
{
title: "包含用户数",
key: "includeUserCount",
},
{
title: "包含分组数",
key: "includeGroupCount",
},
{
title: "操作",
slot: "action",
align: "center",
},
],
tableDataRepGroup: [
// {
// groupName: "",
// includeUserCount: 0,
// },
],
/**
* 分组的用户表格
*/
tableColumnRepUser: [
{
title: "序号",
key: "id",
slot: "id",
width: 70,
},
{
title: "用户名",
key: "username",
},
{
title: "状态",
key: "status",
slot: "slot_status",
},
],
tableDataRepUser: [],
/**
* 分组的分组表格
*/
tableColumnRepGroupGroup: [
{
title: "序号",
key: "id",
slot: "id",
width: 70,
},
{
title: "分组名",
key: "groupName",
},
{
title: "状态",
key: "status",
slot: "slot_status",
},
],
tableDataRepGroupGroup: [],
};
},
methods: {
PagesizeChange(value) {
var that = this;
that.numRepGroupPageCurrent = value; //
that.RepGetGroupList();
},
//
ModalRepGroupUserGet(index) {
var that = this;
that.modalRepGroupUserGet = true;
that.tempRepGroupUserCurrentSelect =
that.tableDataRepGroup[index]["groupName"];
that.GetRepGroupUser(that.tableDataRepGroup[index]["groupName"]);
},
//
ModalRepGroupGroupGet(index) {
var that = this;
that.modalRepGroupGroupGet = true;
that.tempRepGroupGroupCurrentSelect =
that.tableDataRepGroup[index]["groupName"];
that.GetRepGroupGroup(that.tableDataRepGroup[index]["groupName"]);
},
//
GetRepGroupUser(groupName) {
var that = this;
var data = {
groupName: groupName,
};
that.$axios
.post("/api.php?c=svnserve&a=RepGetGroupUserList", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.tableDataRepUser = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
//
GetRepGroupGroup(groupName) {
var that = this;
var data = {
groupName: groupName,
};
that.$axios
.post("/api.php?c=svnserve&a=RepGetGroupGroupList", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.tableDataRepGroupGroup = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
//
SetRepUserGroup() {
var that = this;
var data = {
group_name: that.tempRepGroupUserCurrentSelect,
this_account_list: that.tableDataRepUser,
};
that.$axios
.post("/api.php?c=svnserve&a=RepSetGroupUserList", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.modalRepGroupUserGet = false;
that.RepGetGroupList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
//
SetRepGroupGroup() {
var that = this;
var data = {
groupName: that.tempRepGroupGroupCurrentSelect,
thisAccountList: that.tableDataRepGroupGroup,
};
that.$axios
.post("/api.php?c=svnserve&a=RepSetGroupGroupList", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.modalRepGroupGroupGet = false;
that.RepGetGroupList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
//
ModalRepGroupEdit(index) {
var that = this;
that.modalRepGroupEdit = true;
that.tempRepGroupName = that.tableDataRepGroup[index]["groupName"];
that.formRepGroup.groupName = that.tableDataRepGroup[index]["groupName"];
},
//
ModalAddRepGroup() {
var that = this;
that.modalRepGroupAdd = true;
that.formRepGroup.groupName = "";
},
//
RepEditGroup() {
var that = this;
var data = {
oldGroup: that.tempRepGroupName,
newGroup: that.formRepGroup.groupName,
};
that.$axios
.post("/api.php?c=svnserve&a=RepEditGroup", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.modalRepGroupEdit = false;
that.RepGetGroupList();
} else {
that.$Message.error(result.message);
that.modalRepGroupEdit = false;
}
})
.catch(function (error) {
console.log(error);
});
},
//
RepAddGroup() {
var that = this;
var data = {
groupName: that.formRepGroup.groupName,
};
that.$axios
.post("/api.php?c=svnserve&a=RepAddGroup", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.modalRepGroupAdd = false;
that.RepGetGroupList();
} else {
that.$Message.error(result.message);
that.modalRepGroupAdd = false;
}
})
.catch(function (error) {
console.log(error);
});
},
//
RepGetGroupList() {
var that = this;
var data = {
pageSize: that.numRepGroupPageSize,
currentPage: that.numRepGroupPageCurrent,
};
that.$axios
.post("/api.php?c=svnserve&a=RepGetGroupList", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.tableDataRepGroup = result.data;
that.numRepGroupTotal = result.total;
} else {
that.$Message.error(result.message);
that.numRepGroupTotal = 0;
}
})
.catch(function (error) {
console.log(error);
});
},
//
ModalRepGroupDel(index) {
var that = this;
var data = {
del_groupname: that.tableDataRepGroup[index]["groupName"],
};
that.$Modal.confirm({
title: "警告",
content: "确定要删除该账户吗?",
loading: true,
onOk: () => {
that.$axios
.post("/api.php?c=svnserve&a=RepGroupDel", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.$Modal.remove();
that.RepGetGroupList();
} else {
that.$Message.error(result.message);
that.$Modal.remove();
}
})
.catch(function (error) {
console.log(error);
});
},
onCancel: () => {},
});
},
},
created() {},
mounted() {
var that = this;
that.RepGetGroupList();
},
};
</script>

307
01.web/src/views/index/index.vue

@ -0,0 +1,307 @@ @@ -0,0 +1,307 @@
<template>
<div>
<Card :bordered="false" :dis-hover="true">
<p slot="title">
<Icon type="md-bulb" />
{{ systemBrif.os }}
</p>
<div>
<Row>
<Col span="4" >
<div class="statusTop">负载状态</div>
<Tooltip placement="bottom" max-width="200">
<Circle
:percent="statusInfo.load.percent"
dashboard
:size="100"
:stroke-color="statusInfo.load.color"
class="statusCircle"
>
<span class="demo-circle-inner" style="font-size: 24px"
>{{ statusInfo.load.percent }}%</span
>
</Circle>
<div slot="content">
<p>最近1分钟平均负载{{ statusInfo.load.cpuLoad1Min }}</p>
<p>最近5分钟平均负载{{ statusInfo.load.cpuLoad5Min }}</p>
<p>最近15分钟平均负载{{ statusInfo.load.cpuLoad15Min }}</p>
</div>
</Tooltip>
<div class="statusBottom">{{ statusInfo.load.title }}</div>
</Col>
<Col span="4">
<div class="statusTop">CPU使用率</div>
<Tooltip placement="bottom" max-width="200">
<Circle
:percent="statusInfo.cpu.percent"
dashboard
:size="100"
:stroke-color="statusInfo.cpu.color"
class="statusCircle"
>
<span class="demo-circle-inner" style="font-size: 24px"
>{{ statusInfo.cpu.percent }}%</span
>
</Circle>
<div slot="content">
<p v-for="item in statusInfo.cpu.cpu" :key="item">{{ item }}</p>
<p>物理CPU个数{{ statusInfo.cpu.cpuPhysical }}</p>
<p>物理CPU的总核心数{{ statusInfo.cpu.cpuCore }}</p>
<p>物理CPU的线程总数{{ statusInfo.cpu.cpuProcessor }}</p>
</div>
</Tooltip>
<div class="statusBottom">{{ statusInfo.cpu.cpuCore }}核心</div>
</Col>
<Col span="4">
<div class="statusTop">内存使用率</div>
<Circle
:percent="statusInfo.mem.percent"
dashboard
:size="100"
:stroke-color="statusInfo.mem.color"
class="statusCircle"
>
<span class="demo-circle-inner" style="font-size: 24px"
>{{ statusInfo.mem.percent }}%</span
>
</Circle>
<div class="statusBottom">
{{ statusInfo.mem.memUsed }} / {{ statusInfo.mem.memTotal }}(MB)
</div>
</Col>
<Col span="4" v-for="(item, index) in diskList" :key="index">
<div class="statusTop">{{ item.mountedOn }}</div>
<Tooltip placement="bottom" max-width="200">
<div slot="content">
<p>文件系统{{ item.fileSystem }}</p>
<p>容量{{ item.size }}</p>
<p>已使用{{ item.used }}</p>
<p>可使用{{ item.avail }}</p>
<p>使用率{{ item.percent }}%</p>
<p>挂载点{{ item.mountedOn }}</p>
</div>
<Circle
:percent="item.percent"
dashboard
:size="100"
:stroke-color="item.color"
class="statusCircle"
>
<span class="demo-circle-inner" style="font-size: 24px"
>{{ item.percent }}%</span
>
</Circle>
</Tooltip>
<div class="statusBottom">
{{ item.used }} /
{{ item.size }}
</div>
</Col>
</Row>
</div>
</Card>
<Card :bordered="false" :dis-hover="true" style="margin-top: 10px">
<p slot="title">
<Icon type="ios-options" />
统计
</p>
<div>
<Row :gutter="16">
<Col span="4">
<Card :dis-hover="true">
<div style="text-align: center">
<p>仓库占用</p>
<h2 style="color: #28bcfe">{{ systemBrif.repSize }}</h2>
</div>
</Card>
</Col>
<Col span="4">
<Card :dis-hover="true">
<div style="text-align: center">
<p>SVN仓库</p>
<h2 style="color: #28bcfe">{{ systemBrif.repCount }}</h2>
</div>
</Card>
</Col>
<Col span="4">
<Card :dis-hover="true">
<div style="text-align: center">
<p>SVN用户</p>
<h2 style="color: #28bcfe">{{ systemBrif.repUser }}</h2>
</div>
</Card>
</Col>
<Col span="4">
<Card :dis-hover="true">
<div style="text-align: center">
<p>SVN分组</p>
<h2 style="color: #28bcfe">{{ systemBrif.repGroup }}</h2>
</div>
</Card>
</Col>
<Col span="4">
<Card :dis-hover="true">
<div style="text-align: center">
<p>运行日志/</p>
<h2 style="color: #28bcfe">{{ systemBrif.logCount }}</h2>
</div>
</Card>
</Col>
</Row>
</div>
</Card>
</div>
</template>
<script>
export default {
data() {
return {
/**
* 硬盘信息
*/
diskList: [],
/**
* 状态信息
*/
statusInfo: {
load: {
cpuLoad15Min: 0.22,
cpuLoad5Min: 0.28,
cpuLoad1Min: 0.32,
percent: 16,
color: "#28bcfe",
},
cpu: {
percent: 28.2,
cpu: ["Intel(R) Xeon(R) Platinum 8255C CPU @ 2.50GHz"],
cpuPhysical: 1,
cpuPhysicalCore: 1,
cpuCore: 1,
cpuProcessor: 1,
color: "#28bcfe",
},
mem: {
memTotal: 1838,
memUsed: 975,
memFree: 863,
percent: 53,
color: "#28bcfe",
},
},
/**
* 统计信息
*/
systemBrif: {
os: "",
repSize: 0,
repCount: 0,
repUser: 0,
repGroup: 0,
logCount: 0,
},
};
},
computed: {},
created() {},
mounted() {
var that = this;
this.GetDisk();
this.GetSystemStatus();
this.GetSystemAnalysis();
//
that.timer = window.setInterval(() => {
setTimeout(that.GetSystemStatus(), 0);
}, 3000);
//
that.$once("hook:beforeDestroy", () => {
clearInterval(that.timer);
});
},
methods: {
/**
* 获取磁盘
*/
GetDisk() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=statistics&a=GetDisk&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.diskList = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 获取状态
*/
GetSystemStatus() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=statistics&a=GetSystemStatus&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.statusInfo = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 获取统计
*/
GetSystemAnalysis() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=statistics&a=GetSystemAnalysis&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.systemBrif = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
},
};
</script>
<style>
.statusTop {
width: 140px;
text-align: center;
margin-bottom: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.statusCircle {
margin-left: 20px;
}
.statusBottom {
width: 140px;
text-align: center;
margin-bottom: 15px;
}
</style>

0
01.web/src/views/layout/basicLayout/index.css

238
01.web/src/views/layout/basicLayout/index.vue

@ -0,0 +1,238 @@ @@ -0,0 +1,238 @@
<style scoped>
@import "./index.css";
</style>
<template>
<div>
<Layout>
<Header
style="
background-color: #9b1be5;
background-image: -webkit-linear-gradient(
0,
#9b1be5 0%,
#2085ea 100%
);
background-image: -o-linear-gradient(0, #9b1be5 0%, #2085ea 100%);
background-image: -moz-linear-gradient(0, #9b1be5 0%, #2085ea 100%);
background-image: linear-gradient(90deg, #9b1be5 0%, #2085ea 100%);
color: #fff;
position: fixed;
width: 100%;
z-index: 99;
"
>
<img
src="../../../assets/images/logo.png"
style="line-height: 64px; position: absolute; top: 12px; left: 1%"
/>
<Dropdown
trigger="click"
@on-click="LogOut"
style="float: right; zindex: 99"
>
<a href="javascript:void(0)" style="margin-left: 8px; color: #fff">
{{ currentUsername }}
<Icon type="md-arrow-dropdown" />
</a>
<DropdownMenu slot="list">
<DropdownItem>退出</DropdownItem>
</DropdownMenu>
</Dropdown>
<!-- <div style="float: right">
<Divider type="vertical" />
</div>
<Dropdown trigger="click" style="float: right; zindex: 99">
<a href="javascript:void(0)" style="margin-left: 8px; color: #fff">
语言
<Icon type="md-arrow-dropdown" />
</a>
<DropdownMenu slot="list">
<DropdownItem>中文简体</DropdownItem>
</DropdownMenu>
<DropdownMenu slot="list">
<DropdownItem>中文繁体</DropdownItem>
</DropdownMenu>
<DropdownMenu slot="list">
<DropdownItem>English</DropdownItem>
</DropdownMenu>
</Dropdown> -->
<div style="float: right">
<Divider type="vertical" />
</div>
<div style="float: right">
<!-- <Avatar icon="ios-person" /> -->
<a style="margin-left: 8px; color: #fff; cursor: default">{{
currentRoleName
}}</a>
</div>
</Header>
<Layout style="margin-top: 64px">
<Sider
style="
min-height: calc(100vh - 64px);
position: fixed;
z-index: 99;
height: 100%;
"
>
<Menu
theme="light"
width="auto"
:active-name="currentActiveName"
style="height: 100%"
>
<MenuGroup
:title="itemGroup.title"
v-for="(itemGroup, indexGroup) in navList"
:key="indexGroup"
>
<MenuItem
:name="itemItem.name"
:to="itemItem.path"
v-for="(itemItem, indexItem) in itemGroup.value"
:key="indexGroup + '-' + indexItem"
>
<Icon :type="itemItem.meta.icon" />
{{ itemItem.meta.title }}
</MenuItem>
</MenuGroup>
</Menu>
</Sider>
<Layout
style="padding: 20px 30px 0px 220px; height: calc(100vh - 64px)"
>
<Breadcrumb style="padding: 0px 0px 20px 0px">
<BreadcrumbItem v-for="(item, index) in breadcrumb" :key="index">{{
item.meta.title
}}</BreadcrumbItem>
</Breadcrumb>
<Content>
<router-view></router-view>
</Content>
</Layout>
</Layout>
</Layout>
</div>
</template>
<script>
export default {
data() {
return {
//
currentActiveName: "",
//logo
logoContent: "SVN Admin",
//
currentUsername: sessionStorage.user_name,
currentRoleName: sessionStorage.user_role_name,
//
navList: [],
//
breadcrumb: [],
};
},
methods: {
//退
LogOut() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=common&a=Logout&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
sessionStorage.removeItem("token");
sessionStorage.removeItem("user_name");
sessionStorage.removeItem("user_role_id");
sessionStorage.removeItem("user_role_name");
that.$Message.success(result.message);
that.$router.push({ name: "login" });
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
// 退
handleCommand(command) {
switch (command) {
case "logOut":
this.logOUt();
break;
}
},
//
//
CreateNav() {
var that = this;
//
var result = that.$router.options.routes.filter(
(item) => item.name == "manage"
);
// that.navList = result[0].children;
result = result[0].children;
//
var groupTitleArray = result
.map((item) => item.meta.group)
.filter((item) => item.name != "");
//
result = result.filter((item) => item.meta.group.num > 0);
//
result = result.filter(
(item) => item.meta.user_role_id.indexOf(sessionStorage.user_role_id) != -1
);
//
var navList = [];
for (var i = 0; i < groupTitleArray.length; i++) {
var groupItemArray = [];
for (var j = 0; j < result.length; j++) {
if (result[j].meta.group.num == groupTitleArray[i].num) {
groupItemArray.push(result[j]);
}
}
if (groupItemArray.length == 0) {
continue;
}
navList.push({
title: groupTitleArray[i].name,
value: groupItemArray,
});
}
that.navList = navList;
},
//
SetBreadcrumb() {
var that = this;
that.breadcrumb = that.$route.matched;
},
//
SetActiveName() {
this.currentActiveName = this.$route.name;
},
},
mounted() {
var that = this;
//
that.CreateNav();
//
that.SetBreadcrumb();
//
this.SetActiveName();
},
watch: {
//
$route() {
//
this.SetBreadcrumb();
},
},
};
</script>

12
01.web/src/views/layout/blankLayout/index.vue

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
<template>
<div>
<router-view></router-view>
</div>
</template>
<script>
export default {};
</script>
<style>
</style>

37
01.web/src/views/layout/layout.less

@ -1,37 +0,0 @@ @@ -1,37 +0,0 @@
.ivu-layout-header {
background: #3377de;
padding: 0 20px;
.layout-logo {
overflow: hidden;
cursor: pointer;
float: left;
.logo {
margin-top: 19px;
height: 35px;
width: 195px;
float: left;
color: #fff;
}
}
.layout-role {
float: right;
margin-right: 20px;
a {
color: #fff;
}
}
.layout-user {
float: right;
}
}
.breadcrumb {
width: 100%;
height: 49px;
display: block;
line-height: 49px;
text-indent: 20px;
}

222
01.web/src/views/layout/layout.vue

@ -1,222 +0,0 @@ @@ -1,222 +0,0 @@
<style scoped lang="less">
@import "../../styles/common.css";
@import "./layout.less";
</style>
<template>
<div class="layout">
<Layout>
<Header>
<div class="layout-logo">
<div class="logo">
<img src="../../static/images/logo.png" style="display: block" />
</div>
</div>
<div class="layout-user">
<template>
<Dropdown trigger="click" @on-click="dropdown_click">
<a href="javascript:void(0)">
<Avatar size="40" icon="ios-person" />
<span style="color: #fff">{{ username }}</span>
<Icon type="ios-arrow-down" color="#fff"></Icon>
</a>
<DropdownMenu slot="list">
<!-- <DropdownItem name="info">个人信息</DropdownItem> -->
<!-- <DropdownItem name="logout" divided>退出</DropdownItem> -->
<DropdownItem name="logout">退出</DropdownItem>
</DropdownMenu>
</Dropdown>
</template>
</div>
<div class="layout-role">
<template>
<Dropdown trigger="click">
<a href="javascript:void(0)">当前角色{{ rolename }}</a>
</Dropdown>
</template>
</div>
</Header>
<Layout>
<Sider
:style="{
left: 0,
overflow: 'auto',
background: '#fff',
position: 'relative',
zIndex: '99',
minHeight: 'calc(100vh - 64px)',
}"
>
<!-- 二级导航 -->
<Menu
theme="light"
width="auto"
:accordion="true"
ref="MenuList"
style="height: 100%"
:active-name="activeName"
:open-names="openNames"
>
<div v-for="(item, index) in moduleList" :key="index">
<Submenu
:name="item.name"
:to="item.path"
v-if="
item.children &&
item['children'].filter((node) => node.meta.isNav).length > 1
"
>
<template slot="title">
<Icon :type="item.icon" size="18" />
{{ item.meta.title }}
</template>
<div
v-for="(node, index2) in item['children'].filter(
(item) => item.meta.isNav
)"
:key="index2"
>
<MenuItem :name="node.name" :to="node.path">{{
node.meta.title
}}</MenuItem>
</div>
</Submenu>
<div v-else>
<MenuItem :name="item.name" :to="item.path">
<Icon :type="item.icon" size="18" />
{{ item.meta.title }}
</MenuItem>
</div>
</div>
</Menu>
</Sider>
<Layout :style="{ padding: '0 20px 20px' }">
<Breadcrumb :style="{ margin: '14px 0' }">
<BreadcrumbItem>首页</BreadcrumbItem>
<span v-for="item in breadcrumbItems" :key="item.name">
<BreadcrumbItem v-if="item.path != ''">{{
item.title
}}</BreadcrumbItem>
</span>
</Breadcrumb>
<Content :style="{ padding: '0px', minHeight: '280px' }">
<router-view></router-view>
</Content>
</Layout>
</Layout>
</Layout>
</div>
</template>
<script>
export default {
data() {
return {
rolename: window.sessionStorage.rolename, //
username: window.sessionStorage.username, //
moduleList: [],
activeName: "",
openNames: [],
breadcrumbItems: [],
};
},
created() {
// this.$router.options.routes['children'].filter((node)=> node.meta.isNav).length
// console.log(this.$router.options.routes[0]['children'].filter((node)=> node.meta.isNav));
},
mounted() {
let that = this;
that.getModuleList();
that.setNavActive();
},
watch: {
$route() {
this.setNavActive();
},
},
methods: {
//退
dropdown_click(name) {
var that = this;
var data = {};
if (name == "logout") {
window.sessionStorage.removeItem("token"); //userid
window.sessionStorage.removeItem("userid"); //userid
window.sessionStorage.removeItem("username"); //username
window.sessionStorage.removeItem("roleid"); //roleid
window.sessionStorage.removeItem("rolename"); //rolename
let token = window.sessionStorage.token;
if (token === "null" || token === "" || token === undefined) {
that.$Message.success("退出登录成功");
that.$router.push({ name: "login" }); //
} else {
that.$Message.success("退出登录失败");
}
}
},
//
setNavActive() {
let that = this;
var _array = new Array();
var i = 0;
for (var e of that.$route.matched) {
if (e.meta.parent !== undefined) {
var obj = new Object();
obj.path = e.path;
obj.name = e.path;
obj.title = e.meta.title;
if (e.meta.isNav == undefined) {
e.meta.isNav = false;
}
obj.isNav = e.meta.isNav;
_array[i] = obj;
i = i + 1;
}
var obj = new Object();
obj.path = e.path;
obj.name = e.name;
obj.title = e.meta.title;
if (e.meta.isNav == undefined) {
e.meta.isNav = false;
}
obj.isNav = e.meta.isNav;
_array[i] = obj;
i = i + 1;
}
that.breadcrumbItems = _array;
let navList = _array.filter((item) => item.isNav);
if (navList.length >= 2) {
that.activeName = navList[navList.length - 1].name;
that.openNames = [navList[navList.length - 2].name];
} else {
that.activeName = navList[navList.length - 1].name;
}
that.$nextTick(() => {
that.$refs.MenuList.updateOpened();
that.$refs.MenuList.updateActiveName();
});
},
//
getModuleList() {
let that = this;
let _modules = that.$router.options.routes.filter(
(item) => item.name == "manage"
);
that.moduleList.splice(0, that.moduleList.length);
_modules[0]["children"].forEach((element) => {
if (
element.meta.isNav &&
element.meta.roles.indexOf(Number(window.sessionStorage.roleid)) != -1
) {
that.moduleList.push(element);
}
});
},
}
};
</script>

203
01.web/src/views/login/index.vue

@ -0,0 +1,203 @@ @@ -0,0 +1,203 @@
<style lang="less">
@import "./login.less";
</style>
<template>
<div class="login">
<div class="login-con">
<Card icon="log-in" title="SVNAdmin V2.3" :bordered="false">
<div class="form-con">
<Form
ref="formUserLogin"
:model="formUserLogin"
:rules="ruleValidateLogin"
@keydown.enter.native="Submit('formUserLogin')"
>
<FormItem prop="user_name">
<Input
v-model="formUserLogin.user_name"
placeholder="请输入用户名"
>
<span slot="prepend">
<Icon :size="16" type="ios-person"></Icon>
</span>
</Input>
</FormItem>
<FormItem prop="user_pass">
<Input
type="password"
password
v-model="formUserLogin.user_pass"
placeholder="请输入密码"
>
<span slot="prepend">
<Icon :size="14" type="md-lock"></Icon>
</span>
</Input>
</FormItem>
<FormItem>
<Select v-model="formUserLogin.user_role">
<Option value="1">管理人员</Option>
<Option value="2">SVN用户</Option>
</Select>
</FormItem>
<FormItem prop="code">
<Row>
<Col span="11"
><Input
v-model="formUserLogin.code"
placeholder="请输入验证码"
></Input
></Col>
<Col span="1"></Col>
<Col span="12">
<img
@click="GetVeryfyCode"
:src="formUserLogin.base64"
:alt="loadingGetVeryfyCode"
style="width: 100%; cursor: pointer"
/>
</Col>
</Row>
</FormItem>
<FormItem>
<Button
type="primary"
long
@click="Submit('formUserLogin')"
:loading="loadingLogin"
>登录</Button
>
</FormItem>
</Form>
</div>
</Card>
</div>
</div>
</template>
<script>
export default {
data() {
return {
/**
* 加载
*/
loadingGetVeryfyCode: "loading......",
loadingLogin: false,
/**
* 表单
*/
//
formUserLogin: {
user_name: "",
user_pass: "",
user_role: "2",
code: "",
uuid: "",
base64: "",
},
/**
* 校验规则
*/
//
ruleValidateLogin: {
user_name: [
{ required: true, message: "用户名不能为空", trigger: "blur" },
],
user_pass: [
{ required: true, message: "密码不能为空", trigger: "blur" },
],
code: [{ required: true, message: "验证码不能为空", trigger: "blur" }],
},
};
},
computed: {},
created() {},
mounted() {
this.GetVeryfyCode();
},
methods: {
//
Submit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.Login();
} else {
return false;
}
});
},
/**
* 请求验证码
*/
GetVeryfyCode() {
var that = this;
that.formUserLogin.base64 = "";
that.loadingGetVeryfyCode = "loading......";
var data = {};
that.$axios
.post("/api.php?c=common&a=GetVeryfyCode&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.formUserLogin.uuid = result.data.uuid;
that.formUserLogin.base64 = result.data.base64;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
//
Login() {
var that = this;
that.loadingLogin = true;
var data = {
user_name: that.formUserLogin.user_name,
user_pass: that.formUserLogin.user_pass,
user_role: that.formUserLogin.user_role,
uuid: that.formUserLogin.uuid,
code: that.formUserLogin.code,
};
that.$axios
.post("/api.php?c=common&a=Login&t=web", data)
.then(function (response) {
that.loadingLogin = false;
var result = response.data;
if (result.status == 1) {
//
sessionStorage.setItem("token", result.data.token);
sessionStorage.setItem("user_name", result.data.user_name);
sessionStorage.setItem("user_role_id", result.data.user_role_id);
sessionStorage.setItem(
"user_role_name",
result.data.user_role_name
);
that.$Message.success(result.message);
if (result.data.user_role_id == 1) {
//
that.$router.push({ name: "index" });
} else if (result.data.user_role_id == 2) {
//
that.$router.push({ name: "repositoryInfo" });
}
} else {
that.GetVeryfyCode();
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.loadingLogin = false;
console.log(error);
});
},
},
};
</script>

20
01.web/src/views/login/login.less

@ -1,26 +1,26 @@ @@ -1,26 +1,26 @@
.login {
.login{
width: 100%;
height: calc(100vh);
background-image: url("../../static/images/login.png");
height: 100%;
background-image: url('../../assets/images/login.png');
background-size: cover;
background-position: center;
position: relative;
&-con {
&-con{
position: absolute;
right: 320px;
top: 48%;
right: 160px;
top: 50%;
transform: translateY(-60%);
width: 320px;
&-header {
width: 300px;
&-header{
font-size: 16px;
font-weight: 300;
text-align: center;
padding: 30px 0;
}
.form-con {
.form-con{
padding: 10px 0 0;
}
.login-tip {
.login-tip{
font-size: 10px;
text-align: center;
color: #c3c3c3;

137
01.web/src/views/login/login.vue

@ -1,137 +0,0 @@ @@ -1,137 +0,0 @@
<style lang="less">
@import "./login.less";
</style>
<template>
<div class="login">
<div class="login-con">
<Card icon="log-in" :bordered="false">
<p slot="title">
<Icon type="ios-finger-print" />
SVN Admin 2.0
</p>
<div class="form-con">
<login-form @on-success-valid="handleSubmit"></login-form>
</div>
</Card>
</div>
<Modal v-model="showVali" footer-hide :closable="false" width="340">
<slide-verify
:r="10"
ref="slideblock"
@success="onSuccess"
@again="onAgain"
@fulfilled="onFulfilled"
@fail="onFail"
@refresh="onRefresh"
:slider-text="text"
:imgs="imgs"
:accuracy="accuracy"
></slide-verify>
<div>{{ msg }}</div>
</Modal>
</div>
</template>
<script>
import img0 from "../../static/images/validate0.jpg";
import LoginForm from "../../components/login-form";
export default {
components: {
LoginForm,
},
data() {
return {
msg: "",
demo: true,
text: "向右滑动->",
imgs: [img0],
accuracy: 5,
showVali: false, //
loginForm: {
username: "",
password: "",
},
ruleValidate: {
username: [
{
required: true,
message: "用户名不能为空.",
trigger: "blur",
},
],
password: [
{
required: true,
message: "密码不能为空.",
trigger: "blur",
},
],
},
};
},
methods: {
handleSubmit({ userName, password }) {
var that = this;
that.loginForm.username = userName;
that.loginForm.password = password;
that.login();
// that.showVali = true;
},
onSuccess(times) {
var that = this;
that.showVali = false;
that.login();
that.onRest();
},
onFail() {
this.msg = "验证失败,请重新验证";
},
onRefresh() {
this.msg = "";
},
onFulfilled() {
//
},
onAgain() {
var that = this;
that.msg = "操作异常 请重试";
that.onRest();
},
onRest() {
var that = this;
that.$refs.slideblock.reset();
that.msg = "";
},
login() {
var that = this;
var data = {
username: that.loginForm.username,
password: that.loginForm.password,
};
that.$axios
.post("/api.php?c=user&a=Login", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
window.sessionStorage.setItem("token", result.token);
// window.sessionStorage.setItem("userid", result.userid);
window.sessionStorage.setItem("username", result.username);
window.sessionStorage.setItem("roleid", result.roleid);
window.sessionStorage.setItem("rolename", result.rolename);
that.$Message.success(result.message);
that.$router.push({ name: "repository" }); //
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
},
};
</script>

270
01.web/src/views/personal/index.vue

@ -0,0 +1,270 @@ @@ -0,0 +1,270 @@
<template>
<div>
<Card :bordered="false" :dis-hover="true">
<Tabs value="name1">
<TabPane label="修改密码" name="name1">
<Card
:bordered="false"
:dis-hover="true"
style="width: 450px; min-height: 321px"
>
<Form :label-width="100" v-if="user_role_id == 1">
<FormItem label="管理员账户">
<Row :gutter="16">
<Col span="12">
<Input
v-model="formEditAdminUserName.displayUserName"
readonly
></Input>
</Col>
<Col span="6">
<Button type="success" @click="ModalEditAdminUserName"
>修改</Button
></Col
>
</Row>
</FormItem>
<FormItem label="管理员密码">
<Row :gutter="16">
<Col span="12">
<Input type="password" value="******" readonly></Input>
</Col>
<Col span="6">
<Button type="success" @click="ModalEditAdminUserPass"
>修改</Button
></Col
>
</Row>
</FormItem>
</Form>
<Form
:model="formEditSvnUserPass"
:label-width="100"
v-if="user_role_id == 2"
>
<FormItem label="用户名">
<Input readonly v-model="formEditSvnUserPass.userName"></Input>
</FormItem>
<FormItem label="旧密码">
<Input
type="password"
password
v-model="formEditSvnUserPass.oldPassword"
></Input>
</FormItem>
<FormItem label="新密码">
<Input
type="password"
password
v-model="formEditSvnUserPass.newPassword"
></Input>
</FormItem>
<FormItem label="确认新密码">
<Input
type="password"
password
v-model="formEditSvnUserPass.confirm"
></Input>
</FormItem>
<FormItem>
<Button type="primary" :loading="loadingEditSvnUserPass" @click="EditSvnUserPass"
>确认修改</Button
>
</FormItem>
</Form>
</Card>
</TabPane>
</Tabs>
</Card>
<Modal
v-model="modalEditAdminUserName"
title="修改管理员账号"
:loading="loadingEditAdminUserName"
@on-ok="EditAdminUserName"
>
<Form :model="formEditAdminUserName" :label-width="80">
<FormItem label="新账号">
<Input v-model="formEditAdminUserName.userName"></Input>
</FormItem>
<FormItem label="确认">
<Input v-model="formEditAdminUserName.confirm"></Input>
</FormItem>
</Form>
</Modal>
<Modal
v-model="modalEditAdminUserPass"
title="修改管理员密码"
:loading="loadingEditAdminUserPass"
@on-ok="EditAdminUserPass"
>
<Form :model="formEditAdminUserPass" :label-width="80">
<FormItem label="新密码">
<Input v-model="formEditAdminUserPass.password"></Input>
</FormItem>
<FormItem label="确认">
<Input v-model="formEditAdminUserPass.confirm"></Input>
</FormItem>
</Form>
</Modal>
</div>
</template>
<script>
export default {
data() {
return {
user_role_id: sessionStorage.user_role_id,
/**
* 对话框
*/
modalEditAdminUserName: false,
modalEditAdminUserPass: false,
/**
* 加载
*/
loadingEditAdminUserName: true,
loadingEditAdminUserPass: true,
loadingEditSvnUserPass: false,
/**
* 表单
*/
formEditAdminUserName: {
displayUserName: sessionStorage.user_name,
userName: "",
confirm: "",
},
formEditAdminUserPass: {
password: "",
confirm: "",
},
formEditSvnUserPass: {
userName: sessionStorage.user_name,
oldPassword: "",
newPassword: "",
confirm: "",
},
};
},
computed: {},
created() {},
mounted() {},
methods: {
/**
* 管理人员修改账号
*/
ModalEditAdminUserName() {
this.modalEditAdminUserName = true;
},
EditAdminUserName() {
var that = this;
var data = {
userName: that.formEditAdminUserName.userName,
confirm: that.formEditAdminUserName.confirm,
};
that.$axios
.post("/api.php?c=personal&a=EditAdminUserName&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.LogOut();
} else {
that.$Message.error(result.message);
}
that.modalEditAdminUserName = false;
})
.catch(function (error) {
that.modalEditAdminUserName = false;
console.log(error);
});
},
/**
* 管理人员修改密码
*/
ModalEditAdminUserPass() {
this.modalEditAdminUserPass = true;
},
EditAdminUserPass() {
var that = this;
var data = {
password: that.formEditAdminUserPass.password,
confirm: that.formEditAdminUserPass.confirm,
};
that.$axios
.post("/api.php?c=personal&a=EditAdminUserPass&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.LogOut();
} else {
that.$Message.error(result.message);
}
that.modalEditAdminUserPass = false;
})
.catch(function (error) {
that.modalEditAdminUserPass = false;
console.log(error);
});
},
/**
* SVN用户修改自己的密码
*/
EditSvnUserPass() {
var that = this;
that.loadingEditSvnUserPass = true;
var data = {
userName: sessionStorage.user_name,
oldPassword: that.formEditSvnUserPass.oldPassword,
newPassword: that.formEditSvnUserPass.newPassword,
confirm: that.formEditSvnUserPass.confirm,
};
that.$axios
.post("/api.php?c=personal&a=EditSvnUserPass&t=web", data)
.then(function (response) {
that.loadingEditSvnUserPass = false;
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.LogOut();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.loadingEditSvnUserPass = false;
console.log(error);
});
},
/**
* 退出登录
*/
//退
LogOut() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=common&a=Logout&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
sessionStorage.removeItem("token");
sessionStorage.removeItem("user_name");
sessionStorage.removeItem("user_role_id");
sessionStorage.removeItem("user_role_name");
that.$Message.success(result.message);
that.$router.push({ name: "login" });
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
},
};
</script>
<style >
</style>

657
01.web/src/views/repository/repository.vue

@ -1,657 +0,0 @@ @@ -1,657 +0,0 @@
<template>
<Card :bordered="false" :dis-hover="true">
<Tooltip max-width="150" :content="toolTipAddRep">
<Button
type="primary"
@click="modalAddRep = true"
:disabled="!boolIsAdmin"
>新建仓库</Button
>
</Tooltip>
<div class="page-table">
<Table :columns="tableColumnRep" :data="tableDataRep">
<template slot-scope="{ index }" slot="id">
<strong>{{ index + 1 }}</strong>
</template>
<template slot-scope="{ index }" slot="action">
<Button type="primary" size="small" @click="ModelRepTree(index)"
>目录</Button
>
<Button
type="primary"
size="small"
@click="ModelRepUserGet(index)"
:disabled="!boolIsAdmin"
>用户</Button
>
<Button
type="primary"
size="small"
@click="ModelRepGroupGet(index)"
:disabled="!boolIsAdmin"
>分组</Button
>
<Button
type="primary"
size="small"
@click="ModelRepHooksGet(index)"
:disabled="!boolIsAdmin"
>Hooks</Button
>
<Button
type="success"
size="small"
@click="ModelRepRename(index)"
:disabled="!boolIsAdmin"
>编辑</Button
>
<Button
type="error"
size="small"
@click="ModelRepDel(index)"
:disabled="!boolIsAdmin"
>删除</Button
>
</template>
</Table>
<Card :bordered="false" :dis-hover="true">
<Page
v-if="numRepTotal != 0"
:total="numRepTotal"
:page-size="numRepPageSize"
@on-change="PagesizeChange"
/>
</Card>
</div>
<Modal v-model="modalAddRep" title="新建仓库" @on-ok="AddRep()">
<Form :label-width="80" @submit.native.prevent>
<FormItem label="仓库名称">
<Input v-model="tempRepAddName" />
</FormItem>
</Form>
</Modal>
<Modal
v-model="modalRepUserPriGet"
title="SVN用户授权"
@on-ok="SetRepUserPri"
>
<Table
height="400"
border
:columns="tableColumnRepUserPri"
:data="tableDataRepUserPri"
>
<template slot-scope="{ index }" slot="id">
<strong>{{ index + 1 }}</strong>
</template>
<template slot-scope="{ index }" slot="slot_privilege">
<RadioGroup
type="button"
v-model="tableDataRepUserPri[index].privilege"
>
<Radio label="rw"><span>读写</span></Radio>
<Radio label="r"><span></span></Radio>
<Radio label="no"><span></span></Radio>
</RadioGroup>
</template>
</Table>
</Modal>
<Modal v-model="modalRepTree" title="目录浏览">
<Scroll>
<Tree :data="treeRep" ></Tree>
</Scroll>
</Modal>
<Modal
v-model="modalRepGroupPriGet"
title="SVN用户组授权"
@on-ok="SetRepGroupPri"
>
<Table
height="400"
border
:columns="tableColumnRepGroupPri"
:data="tableDataRepGroupPri"
>
<template slot-scope="{ index }" slot="id">
<strong>{{ index + 1 }}</strong>
</template>
<template slot-scope="{ index }" slot="slot_privilege">
<RadioGroup
type="button"
v-model="tableDataRepGroupPri[index].privilege"
>
<Radio label="rw"><span>读写</span></Radio>
<Radio label="r"><span></span></Radio>
<Radio label="no"><span></span></Radio>
</RadioGroup>
</template>
</Table>
</Modal>
<Modal
v-model="modalRepHooksGet"
title="设置仓库钩子"
width="600px"
@on-ok="SetRepHooks()"
>
<Form ref="formRepHooks" :model="formRepHooks" :label-width="90">
<FormItem label="Hooks类型">
<Select v-model="formRepHooks.select_hooks_type">
<Option
v-for="item in formRepHooks.hooks_type_list"
:value="item.value"
:key="item.value"
>{{ item.label }}</Option
>
</Select>
</FormItem>
<FormItem label="脚本内容">
<Input
v-model="formRepHooks.hooks_type_list[formRepHooks.select_hooks_type].shell"
maxlength="10000"
:rows="15"
show-word-limit
type="textarea"
placeholder="请输入hooks shell脚本 首行需为:#!/bin/bash 或 #!/bin/sh"
/>
</FormItem>
</Form>
</Modal>
<Modal
v-model="modalRepRenameGet"
title="修改仓库名称"
@on-ok="SetRepRename()"
>
<Form :label-width="80">
<FormItem label="仓库名称">
<Input v-model="tempRepEditName" />
</FormItem>
</Form>
</Modal>
</Card>
</template>
<script>
export default {
data() {
return {
//
treeRep: [],
toolTipAddRep:
"SVN仓库名称只能包含字母、数字、破折号、下划线、点,不能以点开头或结尾",
/**
* 分页数据
*/
numRepPageCurrent: 1,
numRepPageSize: 10,
numRepTotal: 20,
/**
* 对话框控制
*/
modalRepTree: false, //
modalAddRep: false, //
modalRepRenameGet: false, //
modalRepUserPriGet: false, //
modalRepGroupPriGet: false, //
modalRepHooksGet: false, //
/**
* 布尔值
*/
boolIsAdmin: Boolean(
Number(window.sessionStorage.roleid) == 1 ? true : false
),
/**
* 临时变量
*/
tempRepAddName: "", //
tempRepEditName: "", //
tempRepCurrentSelect: "", //
old_repository_name: "", //
new_repository_name: "", //
account_info: {
account: "", //
password: "", //
},
formRepHooks: {
select_hooks_type: "start-commit",
hooks_type_list: {
"start-commit": {
value: "start-commit",
label: "start-commit---事务创建前",
shell: "",
},
"pre-commit": {
value: "pre-commit",
label: "pre-commit---事务提交前",
shell: "",
},
"post-commit": {
value: "post-commit",
label: "post-commit---事务提交后",
shell: "",
},
"pre-lock": {
value: "pre-lock",
label: "pre-lock---锁定文件前",
shell: "",
},
"post-lock": {
value: "post-lock",
label: "post-lock---锁定文件后",
shell: "",
},
"pre-unlock": {
value: "pre-unlock",
label: "pre-unlock---解锁文件前",
shell: "",
},
"post-unlock": {
value: "post-unlock",
label: "post-unlock---解锁文件后",
shell: "",
},
"pre-revprop-change": {
value: "pre-revprop-change",
label: "pre-revprop-change---修改修订版属性前",
shell: "",
},
"post-revprop-change": {
value: "post-revprop-change",
label: "post-revprop-change---修改修订版属性后",
shell: "",
},
},
},
/**
* 仓库 字段和数据
*/
tableColumnRep: [
{
title: "序号",
key: "id",
slot: "id",
width: 150,
},
{
title: "仓库名称",
key: "repName",
},
{
title: "检出路径",
key: "repCheckoutUrl",
},
{
title: "服务器路径",
key: "repUrl",
},
{
title: "仓库体积(MB)",
key: "repSize",
},
{
title: "操作",
slot: "action",
width: 400,
align: "center",
},
],
tableDataRep: [
// {
// id: 1,
// repName: "",
// repCheckoutUrl: "svn:127.0.0.1/",
// repUrl: "/var/svn/",
// repSize: "",
// },
],
/**
* 仓库用户组 字段和数据
*/
tableColumnRepGroupPri: [
{
title: "序号",
key: "id",
slot: "id",
width: 70,
},
{
title: "名称",
key: "account",
},
{
title: "读写权限",
key: "privilege",
slot: "slot_privilege",
},
],
tableDataRepGroupPri: [],
/**
* 仓库用户 字段和数据
*/
tableColumnRepUserPri: [
{
title: "序号",
key: "id",
slot: "id",
width: 70,
},
{
title: "名称",
key: "account",
},
{
title: "读写权限",
key: "privilege",
slot: "slot_privilege",
},
],
tableDataRepUserPri: [
// {
// id: 1,
// account: "root",
// privilege: "no",
// },
],
};
},
methods: {
SetRepHooks() {
var that = this;
var data = {
repository_name: that.tempRepCurrentSelect,
hooks_type_list: that.formRepHooks.hooks_type_list,
};
that.$axios
.post("/api.php?c=svnserve&a=SetRepHooks", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.modalRepHooksGet = false;
} else {
that.$Message.error(result.message);
that.modalRepHooksGet = false;
}
})
.catch(function (error) {
console.log(error);
that.modalRepHooksGet = false;
});
},
GetRepositoryHooks(repository_name) {
var that = this;
var data = {
repository_name: repository_name,
};
that.$axios
.post("/api.php?c=svnserve&a=GetRepositoryHooks", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.formRepHooks.hooks_type_list = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
PagesizeChange(value) {
var that = this;
that.numRepPageCurrent = value; //
that.GetRepositoryList();
},
//
ModelRepRename(index) {
var that = this;
that.modalRepRenameGet = true;
that.tempRepEditName = that.tableDataRep[index]["repName"];
that.old_repository_name = that.tableDataRep[index]["repName"];
},
//
SetRepRename() {
var that = this;
that.new_repository_name = that.tempRepEditName;
var data = {
old_repository_name: that.old_repository_name,
new_repository_name: that.new_repository_name,
};
that.$axios
.post("/api.php?c=svnserve&a=SetRepositoryInfo", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.modalRepRenameGet = false;
that.GetRepositoryList();
} else {
that.$Message.error(result.message);
that.modalRepRenameGet = false;
}
})
.catch(function (error) {
console.log(error);
that.modalRepRenameGet = false;
});
},
//
ModelRepDel(index) {
var that = this;
var repository_name = that.tableDataRep[index]["repName"];
var data = {
repository_name: repository_name,
};
that.$Modal.confirm({
title: "警告",
content: "确定要删除该仓库吗?",
loading: true,
onOk: () => {
that.$axios
.post("/api.php?c=svnserve&a=DeleteRepository", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.$Modal.remove();
that.GetRepositoryList();
} else {
that.$Message.error(result.message);
that.$Modal.remove();
}
})
.catch(function (error) {
console.log(error);
});
},
onCancel: () => {},
});
},
//
SetRepGroupPri() {
var that = this;
var data = {
repository_name: that.tempRepCurrentSelect,
this_account_list: that.tableDataRepGroupPri,
};
that.$axios
.post("/api.php?c=svnserve&a=SetRepositoryGroupPrivilege", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.modalRepGroupPriGet = false;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
//
SetRepUserPri() {
var that = this;
var data = {
repository_name: that.tempRepCurrentSelect,
this_account_list: that.tableDataRepUserPri,
};
that.$axios
.post("/api.php?c=svnserve&a=SetRepositoryUserPrivilege", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.modalRepUserPriGet = false;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
ModelRepHooksGet(index) {
var that = this;
that.modalRepHooksGet = true;
that.tempRepCurrentSelect = that.tableDataRep[index]["repName"];
that.GetRepositoryHooks(that.tempRepCurrentSelect);
},
//
ModelRepTree(index) {
var that = this;
that.modalRepTree = true;
that.GetRepTree(that.tableDataRep[index]["repName"]);
},
//svn
ModelRepUserGet(index) {
var that = this;
that.modalRepUserPriGet = true;
that.tempRepCurrentSelect = that.tableDataRep[index]["repName"];
that.GetRepUserPri(that.tableDataRep[index]["repName"]);
},
//svn
ModelRepGroupGet(index) {
var that = this;
that.modalRepGroupPriGet = true;
that.tempRepCurrentSelect = that.tableDataRep[index]["repName"];
that.GetRepGroupPri(that.tableDataRep[index]["repName"]);
},
GetRepTree(repository_name) {
var that = this;
var data = {
repository_name: repository_name,
};
that.$axios
.post("/api.php?c=svnserve&a=GetRepTree", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.treeRep = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
AddRep() {
var that = this;
var data = {
repository_name: that.tempRepAddName,
};
that.$axios
.post("/api.php?c=svnserve&a=AddRepository", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.modalAddRep = false;
that.GetRepositoryList();
} else {
that.$Message.error(result.message);
that.modalAddRep = false;
}
})
.catch(function (error) {
console.log(error);
that.modalAddRep = false;
});
},
GetRepositoryList() {
var that = this;
var data = {
pageSize: that.numRepPageSize,
currentPage: that.numRepPageCurrent,
};
that.$axios
.post("/api.php?c=svnserve&a=GetRepositoryList", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.tableDataRep = result.data;
that.numRepTotal = result.total;
} else {
that.$Message.error(result.message);
that.numRepTotal = 0;
}
})
.catch(function (error) {
console.log(error);
});
},
//
GetRepUserPri(repository_name) {
var that = this;
var data = {
repository_name: repository_name,
};
that.$axios
.post("/api.php?c=svnserve&a=GetRepositoryUserPrivilegeList", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.tableDataRepUserPri = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
//
GetRepGroupPri(repository_name) {
var that = this;
var data = {
repository_name: repository_name,
};
that.$axios
.post("/api.php?c=svnserve&a=GetRepositoryGroupPrivilegeList", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.tableDataRepGroupPri = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
},
created() {},
mounted() {
var that = this;
that.GetRepositoryList();
},
};
</script>

645
01.web/src/views/repositoryGroup/index.vue

@ -0,0 +1,645 @@ @@ -0,0 +1,645 @@
<template>
<div>
<Card :bordered="false" :dis-hover="true">
<Row style="margin-bottom: 15px">
<Col
type="flex"
justify="space-between"
:xs="21"
:sm="20"
:md="19"
:lg="18"
>
<Button icon="md-add" type="primary" ghost @click="ModalCreateGroup"
>新建SVN分组</Button
>
</Col>
<Col :xs="3" :sm="4" :md="5" :lg="6">
<Input
v-model="searchKeywordGroup"
search
enter-button
placeholder="通过SVN分组名、备注搜索..."
style="width: 100%"
@on-enter="GetGroupList"
/></Col>
</Row>
<Table
@on-sort-change="SortChangeGroup"
border
:columns="tableGroupColumn"
:data="tableGroupData"
:loading="loadingGroup"
size="small"
>
<template slot-scope="{ row, index }" slot="svn_group_note">
<Input
:border="false"
v-model="tableGroupData[index].svn_group_note"
@on-blur="EditGroupNote(index, row.svn_group_name)"
/>
</template>
<template slot-scope="{ row }" slot="action">
<Button
type="success"
size="small"
@click="ModalGetGroupMember(row.svn_group_name)"
>成员</Button
>
<Button
type="warning"
size="small"
@click="ModalEditGroupName(row.svn_group_name)"
>编辑</Button
>
<Button
type="error"
size="small"
@click="DelGroup(row.svn_group_name)"
>删除</Button
>
</template>
</Table>
<Card :bordered="false" :dis-hover="true">
<Page
v-if="totalGroup != 0"
:total="totalGroup"
:current="pageCurrentGroup"
:page-size="pageSizeGroup"
@on-page-size-change="GroupPageSizeChange"
@on-change="GroupPageChange"
size="small"
show-sizer
/>
</Card>
</Card>
<Modal v-model="modalAddGroup" title="新建SVN分组" @on-ok="CreateGroup">
<Form :model="formCreateGroup" :label-width="80">
<FormItem label="分组名">
<Input v-model="formCreateGroup.svn_group_name"></Input>
</FormItem>
<FormItem>
<Alert type="warning" show-icon
>分组名只能包含字母数字破折号下划线</Alert
>
</FormItem>
</Form>
</Modal>
<Modal
v-model="modalEditGroupName"
:title="titleEditGroupName"
@on-ok="EditGroupName"
>
<Form :model="formEditGroupName" :label-width="80">
<FormItem label="分组名">
<Input v-model="formEditGroupName.groupNameNew"></Input>
</FormItem>
<FormItem>
<Alert type="warning" show-icon
>分组名只能包含字母数字破折号下划线</Alert
>
</FormItem>
</Form>
</Modal>
<Modal v-model="modalGetGroupMember" :title="titleGetGroupMember">
<Tabs type="card">
<TabPane label="用户成员">
<Table
height="350"
:show-header="true"
:columns="tableRepAllUserColumn"
:data="tableRepAllUserData"
:loading="loadingRepAllUser"
size="small"
>
<template slot-scope="{ row }" slot="isMember">
<Switch
v-model="row.isMember"
@on-change="(value) => ChangeUserMember(value, row.userName)"
>
<span slot="open"></span>
<span slot="close"></span>
</Switch>
</template>
<template slot-scope="{ row }" slot="disabled">
<Tag color="blue" v-if="row.disabled == 0">正常</Tag>
<Tag color="red" v-else>禁用</Tag>
</template>
</Table>
</TabPane>
<TabPane label="分组成员">
<Table
height="350"
:show-header="true"
:columns="tableRepAllGroupColumn"
:data="tableRepAllGroupData"
:loading="loadingRepAllGroup"
size="small"
>
<template slot-scope="{ row }" slot="isMember">
<Switch
v-model="row.isMember"
@on-change="(value) => ChangeGroupMember(value, row.groupName)"
>
<span slot="open"></span>
<span slot="close"></span>
</Switch>
</template>
</Table>
</TabPane>
</Tabs>
<div slot="footer">
<Button type="primary" @click="modalGetGroupMember = false"
>取消</Button
>
</div>
</Modal>
</div>
</template>
<script>
export default {
data() {
return {
/**
* 分页数据
*/
//
pageCurrentGroup: 1,
pageSizeGroup: 10,
totalGroup: 0,
/**
* 搜索关键词
*/
searchKeywordGroup: "",
/**
* 排序数据
*/
sortName: "svn_group_name",
sortType: "asc",
/**
* 加载
*/
//
loadingGroup: true,
//
loadingRepAllUser: true,
//
loadingRepAllGroup: true,
/**
* 临时变量
*/
currentSelectGroupName: "",
/**
* 标题
*/
titleEditGroupName: "",
titleGetGroupMember: "",
/**
* 对话框
*/
//
modalAddGroup: false,
//
modalEditGroupName: false,
//
modalGetGroupMember: false,
/**
* 表单
*/
//
formCreateGroup: {
svn_group_name: "",
},
//
formEditGroupName: {
groupNameOld: "",
groupNameNew: "",
},
/**
* 表格
*/
//
tableGroupColumn: [
{
title: "序号",
type: "index",
fixed: "left",
minWidth: 80,
},
{
title: "分组名",
key: "svn_group_name",
tooltip: true,
sortable: "custom",
minWidth: 120,
},
{
title: "包含用户数量",
key: "include_user_count",
sortable: "custom",
minWidth: 130,
},
{
title: "包含分组数量",
key: "include_group_count",
sortable: "custom",
minWidth: 130,
},
{
title: "备注信息",
slot: "svn_group_note",
minWidth: 120,
},
{
title: "其它",
slot: "action",
minWidth: 180,
},
],
tableGroupData: [],
//
tableRepAllUserColumn: [
{
title: "用户名",
key: "userName",
},
{
title: "是否为成员",
slot: "isMember",
},
{
title: "当前状态",
slot: "disabled",
},
],
tableRepAllUserData: [],
//
tableRepAllGroupColumn: [
{
title: "分组名",
key: "groupName",
},
{
title: "是否为成员",
slot: "isMember",
},
],
tableRepAllGroupData: [],
};
},
computed: {},
created() {},
mounted() {
this.GetGroupList();
},
methods: {
/**
* 每页数量改变
*/
GroupPageSizeChange(value) {
//
this.pageSizeGroup = value;
this.GetGroupList();
},
/**
* 页码改变
*/
GroupPageChange(value) {
//
this.pageCurrentGroup = value;
this.GetGroupList();
},
/**
* 分组排序
*/
SortChangeGroup(value) {
this.sortName = value.key;
if (value.order == "desc" || value.order == "asc") {
this.sortType = value.order;
}
this.GetGroupList();
},
/**
* 获取SVN分组列表
*/
GetGroupList() {
var that = this;
that.loadingGroup = true;
that.tableGroupData = [];
that.totalGroup = 0;
var data = {
pageSize: that.pageSizeGroup,
currentPage: that.pageCurrentGroup,
searchKeyword: that.searchKeywordGroup,
sortName: that.sortName,
sortType: that.sortType,
};
that.$axios
.post("/api.php?c=svngroup&a=GetGroupList&t=web", data)
.then(function (response) {
that.loadingGroup = false;
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.tableGroupData = result.data.data;
that.totalGroup = result.data.total;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.loadingGroup = false;
console.log(error);
});
},
/**
* 编辑分组备注信息
*/
EditGroupNote(index, svn_group_name) {
var that = this;
var data = {
svn_group_name: svn_group_name,
svn_group_note: that.tableGroupData[index].svn_group_note,
};
that.$axios
.post("/api.php?c=svngroup&a=EditGroupNote&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 添加分组
*/
ModalCreateGroup() {
this.modalAddGroup = true;
},
CreateGroup() {
var that = this;
var data = {
svn_group_name: that.formCreateGroup.svn_group_name,
};
that.$axios
.post("/api.php?c=svngroup&a=CreateGroup&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetGroupList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 编辑分组名称
*/
ModalEditGroupName(svn_group_name) {
//
this.formEditGroupName.groupNameOld = svn_group_name;
//
this.formEditGroupName.groupNameNew = svn_group_name;
//
this.titleEditGroupName = "编辑SVN分组名-" + svn_group_name;
//
this.modalEditGroupName = true;
},
EditGroupName() {
var that = this;
var data = {
groupNameOld: that.formEditGroupName.groupNameOld,
groupNameNew: that.formEditGroupName.groupNameNew,
};
that.$axios
.post("/api.php?c=svngroup&a=EditGroupName&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetGroupList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 删除分组
*/
DelGroup(svn_group_name) {
var that = this;
that.$Modal.confirm({
title: "删除SVN分组-" + svn_group_name,
content: "确定要删除该用户吗?<br/>该操作不可逆!",
onOk: () => {
var data = {
svn_group_name: svn_group_name,
};
that.$axios
.post("/api.php?c=svngroup&a=DelGroup&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetGroupList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
});
},
/**
* 配置分组成员
*/
ModalGetGroupMember(grouName) {
//
this.currentSelectGroupName = grouName;
//
this.modalGetGroupMember = true;
//
this.titleGetGroupMember = "编辑分组成员信息-" + grouName;
//
this.GetGroupMember();
},
/**
* 获取SVN分组的用户成员和分组成员
*/
GetGroupMember() {
var that = this;
that.loadingRepAllUser = true;
that.loadingRepAllGroup = true;
that.tableRepAllUserData = [];
that.tableRepAllGroupData = [];
var data = {
svn_group_name: that.currentSelectGroupName,
};
that.$axios
.post("/api.php?c=svngroup&a=GetGroupMember&t=web", data)
.then(function (response) {
that.loadingRepAllUser = false;
that.loadingRepAllGroup = false;
var result = response.data;
if (result.status == 1) {
that.tableRepAllUserData = result.data.userList;
that.tableRepAllGroupData = result.data.groupList;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.loadingRepAllUser = false;
that.loadingRepAllGroup = false;
console.log(error);
});
},
/**
* 设置分组的用户成员
*/
ChangeUserMember(value, userName) {
if (value == true) {
this.GroupAddUser(userName);
} else {
this.GroupRemoveUser(userName);
}
},
/**
* 设置分组的分组成员
*/
ChangeGroupMember(value, groupName) {
if (value == true) {
this.GroupAddGroup(groupName);
} else {
this.GroupRemoveGroup(groupName);
}
},
/**
* 将用户添加为SVN分组的成员
*/
GroupAddUser(userName) {
var that = this;
var data = {
svn_group_name: that.currentSelectGroupName,
svn_user_name: userName,
};
that.$axios
.post("/api.php?c=svngroup&a=GroupAddUser&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetGroupMember();
} else {
that.$Message.error(result.message);
that.GetGroupMember();
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 将用户从SVN分组的成员移除
*/
GroupRemoveUser(userName) {
var that = this;
var data = {
svn_group_name: that.currentSelectGroupName,
svn_user_name: userName,
};
that.$axios
.post("/api.php?c=svngroup&a=GroupRemoveUser&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetGroupMember();
} else {
that.$Message.error(result.message);
that.GetGroupMember();
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 将分组添加为SVN分组的成员
*/
GroupAddGroup(groupName) {
var that = this;
var data = {
svn_group_name: that.currentSelectGroupName,
svn_group_name_add: groupName,
};
that.$axios
.post("/api.php?c=svngroup&a=GroupAddGroup&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetGroupMember();
} else {
that.$Message.error(result.message);
that.GetGroupMember();
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 将分组从SVN分组的成员移除
*/
GroupRemoveGroup(groupName) {
var that = this;
var data = {
svn_group_name: that.currentSelectGroupName,
svn_group_name_del: groupName,
};
that.$axios
.post("/api.php?c=svngroup&a=GroupRemoveGroup&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetGroupMember();
} else {
that.$Message.error(result.message);
that.GetGroupMember();
}
})
.catch(function (error) {
console.log(error);
});
},
},
};
</script>
<style >
</style>

2203
01.web/src/views/repositoryInfo/index.vue

File diff suppressed because it is too large Load Diff

464
01.web/src/views/repositoryUser/index.vue

@ -0,0 +1,464 @@ @@ -0,0 +1,464 @@
<template>
<div>
<Card :bordered="false" :dis-hover="true">
<Row style="margin-bottom: 15px">
<Col
type="flex"
justify="space-between"
:xs="21"
:sm="20"
:md="19"
:lg="18"
>
<Button icon="md-add" type="primary" ghost @click="ModalCreateUser"
>新建SVN用户</Button
>
</Col>
<Col :xs="3" :sm="4" :md="5" :lg="6">
<Input
v-model="searchKeywordUser"
search
enter-button
placeholder="通过SVN用户名、备注搜索..."
style="width: 100%"
@on-enter="GetUserList"
/></Col>
</Row>
<Table
@on-sort-change="SortChangeUser"
border
:columns="tableColumnUser"
:data="tableDataUser"
:loading="loadingUser"
size="small"
>
<template slot-scope="{ row }" slot="svn_user_pass">
<Input
:border="false"
v-model="row.svn_user_pass"
readonly
type="password"
password
/>
</template>
<template slot-scope="{ row }" slot="svn_user_status">
<Switch
v-model="row.svn_user_status"
false-color="#ff4949"
@on-change="(value) => ChangeUserStatus(value, row.svn_user_name)"
>
<Icon type="md-checkmark" slot="open"></Icon>
<Icon type="md-close" slot="close"></Icon>
</Switch>
</template>
<template slot-scope="{ row, index }" slot="svn_user_note">
<Input
:border="false"
v-model="tableDataUser[index].svn_user_note"
@on-blur="EditUserNote(index, row.svn_user_name)"
/>
</template>
<template slot-scope="{ row, index }" slot="action">
<Button
type="warning"
size="small"
@click="ModalEditUserPass(index, row.svn_user_name)"
>修改</Button
>
<Button
type="error"
size="small"
@click="DelUser(index, row.svn_user_name)"
>删除</Button
>
</template>
</Table>
<Card :bordered="false" :dis-hover="true">
<Page
v-if="totalUser != 0"
:total="totalUser"
:current="pageCurrentUser"
:page-size="pageSizeUser"
@on-page-size-change="UserPageSizeChange"
@on-change="UserPageChange"
size="small"
show-sizer
/>
</Card>
</Card>
<Modal v-model="modalCreateUser" title="新建SVN用户" @on-ok="CreateUser">
<Form :model="formCreateUser" :label-width="80">
<FormItem label="用户名">
<Input v-model="formCreateUser.svn_user_name"></Input>
</FormItem>
<FormItem>
<Alert type="warning" show-icon
>用户名只能包含字母数字破折号下划线</Alert
>
</FormItem>
<FormItem label="密码">
<Input
type="password"
password
v-model="formCreateUser.svn_user_pass"
></Input>
</FormItem>
</Form>
</Modal>
<Modal
v-model="modalEditUserPass"
:title="titleEditUser"
@on-ok="EditUserPass"
>
<Form :model="formEditUser" :label-width="80">
<FormItem label="新密码">
<Input v-model="formEditUser.svn_user_pass"></Input>
</FormItem>
</Form>
</Modal>
</div>
</template>
<script>
export default {
data() {
return {
/**
* 分页数据
*/
//
pageCurrentUser: 1,
pageSizeUser: 10,
totalUser: 0,
/**
* 搜索关键词
*/
searchKeywordUser: "",
/**
* 排序数据
*/
sortName: "svn_user_name",
sortType: "asc",
/**
* 加载
*/
//
loadingUser: true,
/**
* 对话框
*/
//
modalCreateUser: false,
//
modalEditUserPass: false,
/**
* 表单
*/
//
formCreateUser: {
svn_user_name: "",
svn_user_pass: "",
},
//
formEditUser: {
svn_user_name: "",
svn_user_pass: "",
index: -1,
},
/**
* 标题
*/
titleEditUser: "",
/**
* 表格
*/
//
tableColumnUser: [
{
title: "序号",
type: "index",
fixed: "left",
minWidth: 80,
},
{
title: "用户名",
key: "svn_user_name",
tooltip: true,
sortable: "custom",
minWidth: 120,
},
{
title: "密码",
slot: "svn_user_pass",
minWidth: 120,
},
{
title: "启用状态",
key: "svn_user_status",
slot: "svn_user_status",
sortable: "custom",
minWidth: 120,
},
{
title: "备注信息",
slot: "svn_user_note",
minWidth: 120,
},
{
title: "其它",
slot: "action",
minWidth: 180,
},
],
tableDataUser: [],
};
},
computed: {},
created() {},
mounted() {
this.GetUserList();
},
methods: {
/**
* 每页数量改变
*/
UserPageSizeChange(value) {
//
this.pageSizeUser = value;
this.GetUserList();
},
/**
* 页码改变
*/
UserPageChange(value) {
//
this.pageCurrentUser = value;
this.GetUserList();
},
/**
* 获取SVN用户列表
*/
GetUserList() {
var that = this;
that.loadingUser = true;
that.tableDataUser = [];
that.totalUser = 0;
var data = {
pageSize: that.pageSizeUser,
currentPage: that.pageCurrentUser,
searchKeyword: that.searchKeywordUser,
sortName: that.sortName,
sortType: that.sortType,
};
that.$axios
.post("/api.php?c=svnuser&a=GetUserList&t=web", data)
.then(function (response) {
that.loadingUser = false;
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.tableDataUser = result.data.data;
that.totalUser = result.data.total;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.loadingUser = false;
console.log(error);
});
},
/**
* 禁用用户
*/
ChangeUserStatus(value, svn_user_name) {
if (value == true) {
this.EnableUser(svn_user_name);
} else {
this.DisableUser(svn_user_name);
}
},
/**
* 启用用户
*/
EnableUser(svn_user_name) {
var that = this;
var data = {
svn_user_name: svn_user_name,
};
that.$axios
.post("/api.php?c=svnuser&a=EnableUser&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 禁用用户
*/
DisableUser(svn_user_name) {
var that = this;
var data = {
svn_user_name: svn_user_name,
};
that.$axios
.post("/api.php?c=svnuser&a=DisableUser&t=web", data)
.then(function (response) {
that.loadingUser = false;
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 编辑用户备注信息
*/
EditUserNote(index, svn_user_name) {
var that = this;
var data = {
svn_user_name: svn_user_name,
svn_user_note: that.tableDataUser[index].svn_user_note,
};
that.$axios
.post("/api.php?c=svnuser&a=EditUserNote&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 用户排序
*/
SortChangeUser(value) {
this.sortName = value.key;
if (value.order == "desc" || value.order == "asc") {
this.sortType = value.order;
}
this.GetUserList();
},
/**
* 新建用户
*/
ModalCreateUser() {
this.modalCreateUser = true;
},
CreateUser() {
var that = this;
var data = {
svn_user_name: that.formCreateUser.svn_user_name,
svn_user_pass: that.formCreateUser.svn_user_pass,
};
that.$axios
.post("/api.php?c=svnuser&a=CreateUser&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetUserList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 修改用户密码
*/
ModalEditUserPass(index, svn_user_name) {
//
this.titleEditUser = "修改密码-" + svn_user_name;
//
this.formEditUser.svn_user_name = svn_user_name;
//
this.formEditUser.svn_user_pass = this.tableDataUser[index].svn_user_pass;
//
this.formEditUser.index = index;
//
this.modalEditUserPass = true;
},
EditUserPass() {
var that = this;
var data = {
svn_user_name: that.formEditUser.svn_user_name,
svn_user_pass: that.formEditUser.svn_user_pass,
svn_user_status:
that.tableDataUser[that.formEditUser.index].svn_user_status,
};
that.$axios
.post("/api.php?c=svnuser&a=EditUserPass&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetUserList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
/**
* 删除SVN用户
*/
DelUser(index, svn_user_name) {
var that = this;
that.$Modal.confirm({
title: "删除SVN用户-" + svn_user_name,
content:
"确定要删除该用户吗?<br/>将会从所有仓库和分组下将该用户移除<br/>该操作不可逆!",
onOk: () => {
var data = {
svn_user_name: svn_user_name,
svn_user_status: that.tableDataUser[index].svn_user_status,
};
that.$axios
.post("/api.php?c=svnuser&a=DelUser&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetUserList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
});
},
},
};
</script>
<style >
</style>

910
01.web/src/views/setting/setting.vue

@ -1,910 +0,0 @@ @@ -1,910 +0,0 @@
<style lang="less">
.text-wrapper {
white-space: pre-wrap;
}
</style>
<template>
<Card :bordered="false" :dis-hover="true">
<Tabs value="tab1">
<TabPane label="基础配置" name="tab1">
<Row>
<Col span="8">
<Card :bordered="true" :dis-hover="true">
<p slot="title">服务器配置信息</p>
<Form ref="formConfig" :model="formConfig" :label-width="140">
<FormItem label="版本库父目录">
<Input v-model="formConfig.svn_repository_path" disabled />
</FormItem>
<FormItem label="SVN配置文件">
<Input v-model="formConfig.svnserve" disabled />
</FormItem>
<FormItem label="用户文件(passwd)">
<Input v-model="formConfig.passwd" disabled />
</FormItem>
<FormItem label="权限文件(authz)">
<Input v-model="formConfig.authz" disabled />
</FormItem>
<FormItem label="备份目录">
<Input v-model="formConfig.backup_path" disabled />
</FormItem>
<FormItem label="日志目录">
<Input v-model="formConfig.logs" disabled />
</FormItem>
</Form>
</Card>
</Col>
<Col span="8" offset="1">
<Card :bordered="true" :dis-hover="true">
<p slot="title">管理系统配置信息</p>
<Form ref="formConfig" :model="formConfig" :label-width="140">
<FormItem label="服务器域名">
<Input v-model="formConfig.server_domain" />
</FormItem>
<FormItem label="服务器IP">
<Input v-model="formConfig.server_ip" />
</FormItem>
<FormItem label="加密密钥">
<Input
v-model="formConfig.token"
placeholder="如果是初次安装 请修改打乱该token"
/>
</FormItem>
<FormItem label="消息通知服务">
<Switch
true-color="#13ce66"
false-color="#ff4949"
v-model="formConfig.all_mail_status"
/>
</FormItem>
<FormItem>
<Tooltip
max-width="300"
:content="toolTipSave"
placement="top"
transfer
>
<Button type="primary" @click="SetBasicSetting()"
>保存</Button
>
</Tooltip>
</FormItem>
</Form>
</Card>
</Col>
</Row>
</TabPane>
<TabPane label="服务管理" name="tab2">
<Row>
<Col span="8">
<Card dis-hover style="height: 460px">
<p slot="title">SVN服务</p>
<p>服务状态</p>
<br />
<Button :type="svnserve.type" ghost>{{ svnserve.status }}</Button
><br /><br />
<p>服务端口</p>
<br />
<Button type="info" ghost>{{ svnserve.port }}</Button
><br /><br />
<p>状态管理</p>
<br />
<ButtonGroup>
<Button type="info" @click="SetSvnserveStatus('startSvn')"
>开启服务</Button
>
<Button type="warning" @click="SetSvnserveStatus('restartSvn')"
>重启服务</Button
>
<Button type="error" @click="SetSvnserveStatus('stopSvn')"
>关闭服务</Button
> </ButtonGroup
><br /><br />
<p>安装卸载</p>
<br />
<ButtonGroup>
<Tooltip
max-width="300"
:content="toolTipInstall"
placement="top"
transfer
>
<Button
type="info"
@click="Install"
:loading="svnserveLoading.installSvn"
>安装服务</Button
>
</Tooltip>
<Tooltip
max-width="300"
:content="toolTipRepaire"
placement="top"
transfer
disabled
>
<Button
type="warning"
disabled
@click="Repaire"
:loading="svnserveLoading.repaireSvn"
>修复异常</Button
>
</Tooltip>
<Tooltip
max-width="300"
:content="toolTipUnInstall"
placement="top"
transfer
>
<Button
type="error"
@click="UnInstall"
:loading="svnserveLoading.unInstallSvn"
>卸载服务</Button
>
</Tooltip>
</ButtonGroup>
</Card>
</Col>
<Col span="8" offset="1">
<Card dis-hover style="height: 460px">
<p slot="title">防火墙服务</p>
<p>服务状态</p>
<br />
<Button :type="firewallStatus.type" ghost>{{
firewallStatus.status
}}</Button
><br /><br />
<p>状态管理</p>
<br />
<ButtonGroup>
<Button
type="info"
@click="SetFirewallStatus('startFirewall')"
:loading="firewallLoading.startFirewall"
>开启服务</Button
>
<Button
type="warning"
@click="SetFirewallStatus('restartFirewall')"
:loading="firewallLoading.restartFirewall"
>重启服务</Button
>
<Button
type="error"
@click="SetFirewallStatus('stopFirewall')"
:loading="firewallLoading.stopFirewall"
>关闭服务</Button
> </ButtonGroup
><br /><br />
<p>快捷放行</p>
<br />
<template>
HTTP(TCP/80)
<Switch
disabled
true-color="#13ce66"
false-color="#ff4949"
v-model="firewallPort.http"
@on-change="SetFirewallPolicy('80', 'http')"
:loading="firewallPortLoading.http"
/><br /><br />
SVN(TCP/3690)
<Switch
true-color="#13ce66"
false-color="#ff4949"
v-model="firewallPort.svn"
@on-change="SetFirewallPolicy('3690', 'svn')"
:loading="firewallPortLoading.svn"
/><br /><br />
HTTPS(TCP/443)
<Switch
true-color="#13ce66"
false-color="#ff4949"
v-model="firewallPort.https"
@on-change="SetFirewallPolicy('443', 'https')"
:loading="firewallPortLoading.https"
/>
</template>
</Card>
</Col>
</Row>
</TabPane>
<TabPane label="消息通知" name="tab3">
<Row>
<Col span="8">
<Card dis-hover style="height: 540px">
<p slot="title">邮件服务器</p>
<Form ref="formEmail" :model="formEmail" :label-width="110">
<FormItem label="SMTP主机">
<Input v-model="formEmail.smtp_host" />
</FormItem>
<FormItem label="SMTP端口">
<InputNumber
:max="99999"
:min="0"
v-model="formEmail.smtp_port"
></InputNumber>
</FormItem>
<FormItem label="SMTP用户名">
<Input v-model="formEmail.smtp_user" />
</FormItem>
<FormItem label="SMTP密码">
<Input v-model="formEmail.smtp_password" />
</FormItem>
<FormItem label="发送邮箱">
<Input v-model="formEmail.smtp_send_email" />
</FormItem>
<FormItem label="测试邮箱">
<Input v-model="formEmail.smtp_test_email" />
</FormItem>
<FormItem>
<Button type="primary" @click="SendTestMail()"
>发送测试邮件</Button
>
</FormItem>
<FormItem>
<Tooltip
max-width="300"
:content="toolTipSave"
placement="top"
transfer
>
<Button type="primary" @click="SetMailInfo()">保存</Button>
</Tooltip>
</FormItem>
</Form>
</Card>
</Col>
</Row>
</TabPane>
<TabPane label="管理员信息" name="tab5">
<Row>
<Col span="8">
<Card :bordered="true" :dis-hover="true">
<p slot="title">账户密码</p>
<Form
ref="formAdminInfo"
:model="formAdminInfo"
:label-width="110"
>
<FormItem label="管理员账号">
<Input v-model="formAdminInfo.manageUser" disabled />
</FormItem>
<FormItem label="管理员密码">
<Input v-model="formAdminInfo.managePass" />
</FormItem>
<FormItem label="管理员邮箱">
<Input v-model="formAdminInfo.manageEmail" />
</FormItem>
<FormItem>
<Tooltip
max-width="300"
:content="toolTipSave"
placement="top"
transfer
>
<Button type="primary" @click="SetManageSetting()"
>保存</Button
>
</Tooltip>
</FormItem>
</Form>
</Card>
</Col>
</Row>
</TabPane>
<TabPane label="系统更新" name="tab4">
<Row>
<Col span="8">
<Card dis-hover style="height: 320px">
<p slot="title">当前版本信息</p>
<Form
ref="formSoftwareInfo"
:model="formSoftwareInfo"
:label-width="110"
>
<FormItem label="当前版本">
<Badge>
{{ formSoftwareInfo.current_verson }}
</Badge>
</FormItem>
<FormItem label="作者主页">
<Badge>
<a :href="formSoftwareInfo.author" target="_blank">{{
formSoftwareInfo.author
}}</a>
</Badge>
</FormItem>
<FormItem label="开源地址">
<Row>
<Badge>
<a :href="formSoftwareInfo.github" target="_blank"
>GitHub</a
>
</Badge>
</Row>
<Row>
<Badge>
<a :href="formSoftwareInfo.gitee" target="_blank"
>Gitee</a
>
</Badge>
</Row>
</FormItem>
<FormItem>
<Tooltip
max-width="300"
:content="toolTipUpdate"
placement="top"
transfer
>
<Button type="primary" @click="CheckUpdate()"
>检测更新</Button
>
</Tooltip>
</FormItem>
</Form>
</Card>
</Col>
</Row>
</TabPane>
</Tabs>
<Modal v-model="modalSofawareUpdateGet" title="最新版本信息">
<Form ref="formSoftwareNew" :model="formSoftwareNew" :label-width="90">
<FormItem label="最新版本">
<Badge dot>
{{ formSoftwareNew.latestVersion }}
</Badge>
</FormItem>
<FormItem label="升级类型">
<Badge>
{{ formSoftwareNew.updateStep }}
</Badge>
</FormItem>
<FormItem label="修复bug">
<i-input
v-html="formSoftwareNew.fixedContent"
type="textarea"
autosize
></i-input>
</FormItem>
<FormItem label="新增功能">
<i-input
v-html="formSoftwareNew.newContent"
type="textarea"
autosize
></i-input>
</FormItem>
</Form>
</Modal>
</Card>
</template>
<script>
export default {
data() {
return {
current: 1, //
page_size: 10, //
content_total: 20, //
toolTipRepaire: "",
toolTipInstall:
"此操作会使用yum install方式进行Subversion服务的安装和相关的配置文件修改 请务必通过本方式安装 请确保软件所在主机能够访问外网",
toolTipUnInstall:
"此操作会通过yum remove方式卸载Subversion服务 不会删除用户的SVN存储库和密码与权限文件 但还是建议操作前先进行数据备份",
modalSofawareUpdateGet: false,
toolTipUpdate:
"此操作是通过读取位于GitHub和Gitee公开仓库(witersen/update)的配置文件进行软件更新检测 所以需要软件所在主机能够访问外网",
toolTipSave:
"由于配置信息是通过PHP配置文件进行管理读写 如果遇到设置不生效的情况 请检查 web 用户(可能是apache等) 对 $path/config 文件及下属文件的读写权限 您可以直接重设777权限 或联系开发者解决",
//
formSoftwareInfo: {
current_verson: "",
github: "",
gitee: "",
author: "",
},
//
formSoftwareNew: {
newContent: "",
latestVersion: "",
fixedContent: "",
updateType: "",
updateStep: "",
},
//
formAdminInfo: {
manageUser: "",
managePass: "",
manageEmail: "",
},
crontab_data: [],
formMessage: {
api_name: "",
accesskey_id: "",
accesskey_secret: "",
model_code: "",
signature: "",
test_phone: "",
},
formEmail: {
smtp_host: "",
smtp_port: 25,
smtp_user: "",
smtp_password: "",
smtp_send_email: "",
smtp_test_email: "",
},
formConfig: {
// server_ip: "127.0.0.1",
// server_domain: "localhost",
// svn_repository_path: "/www/svn",
// backup_path: "/backup",
// all_mail_status: 1,
},
svnserve: {
// status: "",
// port: "3690",
// type: "error",
},
firewallStatus: {
// status: "",
// type: "success",
},
firewallPort: {
svn: false,
http: false,
https: false,
},
svnserveLoading: {
installSvn: false,
repaireSvn: false,
unInstallSvn: false,
},
firewallLoading: {
startFirewall: false,
restartFirewall: false,
stopFirewall: false,
},
firewallPortLoading: {
svn: false,
http: false,
https: false,
},
};
},
methods: {
pageChange(value) {
var that = this;
that.current = value;
},
GetVersionInfo() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=update&a=GetVersionInfo", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.formSoftwareInfo = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
CheckUpdate() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=update&a=CheckUpdate", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
if (result.data != null) {
that.formSoftwareNew = result.data;
that.modalSofawareUpdateGet = true;
} else {
that.$Message.success(result.message);
}
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
GetMailInfo() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=mail&a=GetMailInfo", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.formEmail = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
SetMailInfo() {
var that = this;
var data = {
host: that.formEmail.smtp_host,
port: that.formEmail.smtp_port,
username: that.formEmail.smtp_user,
password: that.formEmail.smtp_password,
from: that.formEmail.smtp_send_email,
};
that.$axios
.post("/api.php?c=mail&a=SetMailInfo", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
SendTestMail() {
var that = this;
var data = {
host: that.formEmail.smtp_host,
port: that.formEmail.smtp_port,
username: that.formEmail.smtp_user,
password: that.formEmail.smtp_password,
from: that.formEmail.smtp_send_email,
to: that.formEmail.smtp_test_email,
};
that.$axios
.post("/api.php?c=mail&a=SendTestMail", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
SetBasicSetting() {
var that = this;
var data = {
token: that.formConfig.token,
server_ip: that.formConfig.server_ip,
server_domain: that.formConfig.server_domain,
all_mail_status: that.formConfig.all_mail_status,
};
that.$axios
.post("/api.php?c=config&a=SetBasicSetting", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
SetManageSetting() {
var that = this;
var data = {
manageUser: that.formAdminInfo.manageUser,
managePass: that.formAdminInfo.managePass,
manageEmail: that.formAdminInfo.manageEmail,
};
that.$axios
.post("/api.php?c=config&a=SetManageSetting", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
GetManageSetting() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=config&a=GetManageSetting", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.formAdminInfo = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
GetBasicSetting() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=config&a=GetBasicSetting", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.formConfig = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
GetSvnserveStatus() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=svnserve&a=GetSvnserveStatus", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
//that.$Message.success(result.message);
that.svnserve = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
SetSvnserveStatus(action) {
var that = this;
var data = {
action: action,
};
that.$axios
.post("/api.php?c=svnserve&a=SetSvnserveStatus", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetSvnserveStatus();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
Install() {
var that = this;
var data = {};
that.$Modal.confirm({
title: "警告",
content: "此操作将会安装Subversion服务,确认继续吗?",
onOk: () => {
that.svnserveLoading.installSvn = true;
that.$axios
.post("/api.php?c=svnserve&a=Install", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetSvnserveStatus();
that.svnserveLoading.installSvn = false;
that.GetFirewallStatus();
} else {
that.svnserveLoading.installSvn = false;
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.svnserveLoading.installSvn = false;
console.log(error);
});
},
onCancel: () => {},
});
},
Repaire() {
var that = this;
var data = {};
that.$Modal.confirm({
title: "警告",
content: "此操作将会尝试修复一些问题,确认继续吗?",
onOk: () => {
that.svnserveLoading.repaireSvn = true;
that.$axios
.post("/api.php?c=svnserve&a=Repaire", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetSvnserveStatus();
that.svnserveLoading.repaireSvn = false;
} else {
that.svnserveLoading.repaireSvn = false;
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.svnserveLoading.repaireSvn = false;
console.log(error);
});
},
onCancel: () => {},
});
},
UnInstall() {
var that = this;
var data = {};
that.$Modal.confirm({
title: "警告",
content: "此操作将会卸载Subversion服务,确认继续吗?",
onOk: () => {
that.svnserveLoading.unInstallSvn = true;
that.$axios
.post("/api.php?c=svnserve&a=UnInstall", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetSvnserveStatus();
that.svnserveLoading.unInstallSvn = false;
} else {
that.svnserveLoading.unInstallSvn = false;
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.svnserveLoading.unInstallSvn = false;
console.log(error);
});
},
onCancel: () => {},
});
},
GetFirewallStatus() {
var that = this;
var data = {};
that.$axios
.post("/api.php?c=firewall&a=GetFirewallStatus", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
//that.$Message.success(result.message);
that.firewallStatus = result.data;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
SetFirewallStatus(action) {
var that = this;
that.firewallLoading[`${action}`] = true;
var data = {
action: action,
};
that.$axios
.post("/api.php?c=firewall&a=SetFirewallStatus", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.firewallLoading[`${action}`] = false;
that.GetFirewallStatus();
that.GetFirewallPolicy();
} else {
that.firewallLoading[`${action}`] = false;
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.firewallLoading[`${action}`] = false;
console.log(error);
});
},
SetFirewallPolicy(port, serve) {
var that = this;
that.firewallPortLoading.http = true;
that.firewallPortLoading.https = true;
that.firewallPortLoading.svn = true;
var data = {
port: port,
type: that.firewallPort[`${serve}`],
};
that.$axios
.post("/api.php?c=firewall&a=SetFirewallPolicy", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetFirewallPolicy();
that.GetFirewallStatus();
} else {
that.firewallPortLoading.http = false;
that.firewallPortLoading.https = false;
that.firewallPortLoading.svn = false;
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.GetFirewallPolicy();
that.GetFirewallStatus();
console.log(error);
});
},
GetFirewallPolicy() {
var that = this;
that.firewallPortLoading.http = true;
that.firewallPortLoading.https = true;
that.firewallPortLoading.svn = true;
var data = {};
that.$axios
.post("/api.php?c=firewall&a=GetFirewallPolicy", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.firewallPortLoading.http = false;
that.firewallPortLoading.https = false;
that.firewallPortLoading.svn = false;
//that.$Message.success(result.message);
that.firewallPort = result.data;
} else {
that.firewallPortLoading.http = false;
that.firewallPortLoading.https = false;
that.firewallPortLoading.svn = false;
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.firewallPortLoading.http = false;
that.firewallPortLoading.https = false;
that.firewallPortLoading.svn = false;
console.log(error);
});
},
},
mounted() {
var that = this;
that.GetSvnserveStatus();
that.GetFirewallStatus();
that.GetFirewallPolicy();
that.GetBasicSetting();
that.GetMailInfo();
that.GetVersionInfo();
that.GetManageSetting();
},
};
</script>

250
01.web/src/views/systemLog/index.vue

@ -0,0 +1,250 @@ @@ -0,0 +1,250 @@
<template>
<div>
<Card :bordered="false" :dis-hover="true">
<Row style="margin-bottom: 15px">
<Col
type="flex"
justify="space-between"
:xs="21"
:sm="20"
:md="19"
:lg="18"
>
<Button
icon="ios-trash-outline"
type="warning"
ghost
@click="ClearLogs"
>清空日志</Button
>
<Button
icon="ios-cloud-download-outline"
type="success"
ghost
@click="ExportLog"
>导出日志</Button
>
</Col>
<Col :xs="3" :sm="4" :md="5" :lg="6">
<Input
v-model="searchKeywordLog"
search
enter-button
placeholder="通过所有信息搜索..."
style="width: 100%"
@on-enter="GetLogList"
/></Col>
</Row>
<Table
border
:loading="loadingGetLogList"
:columns="tableColumnLog"
:data="tableDataLog"
size="small"
>
</Table>
<Card :bordered="false" :dis-hover="true">
<Page
v-if="totalLog != 0"
:total="totalLog"
:current="pageCurrentLog"
:page-size="pageSizeLog"
@on-page-size-change="LogPageSizeChange"
@on-change="LogPageChange"
size="small"
show-sizer
/>
</Card>
</Card>
</div>
</template>
<script>
export default {
data() {
return {
/**
* 分页数据
*/
//
pageCurrentLog: 1,
pageSizeLog: 10,
totalLog: 0,
/**
* 搜索关键词
*/
searchKeywordLog: "",
/**
* 加载
*/
loadingGetLogList: true,
/**
* 表格
*/
//
tableColumnLog: [
{
title: "序号",
type: "index",
fixed: "left",
minWidth: 80,
},
{
title: "操作人",
key: "log_add_user_name",
minWidth: 120,
},
{
title: "日志类型",
key: "log_type_name",
minWidth: 150,
},
{
title: "详细信息",
key: "log_content",
tooltip: true,
minWidth: 120,
},
{
title: "操作时间",
key: "log_add_time",
minWidth: 150,
},
],
tableDataLog: [],
};
},
computed: {},
created() {},
mounted() {
this.GetLogList();
},
methods: {
/**
* 每页数量改变
*/
LogPageSizeChange(value) {
//
this.pageSizeLog = value;
this.GetLogList();
},
/**
* 页码改变
*/
LogPageChange(value) {
//
this.pageCurrentLog = value;
this.GetLogList();
},
/**
* 获取日志
*/
GetLogList() {
var that = this;
that.loadingGetLogList = true;
that.tableDataLog = [];
that.totalLog = 0;
var data = {
pageSize: that.pageSizeLog,
currentPage: that.pageCurrentLog,
searchKeyword: that.searchKeywordLog,
};
that.$axios
.post("/api.php?c=logs&a=GetLogList&t=web", data)
.then(function (response) {
that.loadingGetLogList = false;
var result = response.data;
if (result.status == 1) {
// that.$Message.success(result.message);
that.tableDataLog = result.data.data;
that.totalLog = result.data.total;
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.loadingGetLogList = false;
console.log(error);
});
},
/**
* 清空日志
*/
ClearLogs() {
var that = this;
that.$Modal.confirm({
title: "清空日志",
content: "确定要清空日志记录吗?此操作不可逆!",
onOk: () => {
var data = {};
that.$axios
.post("/api.php?c=logs&a=ClearLogs&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetLogList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
});
},
/**
* 导出日志
*/
ExportLog() {
require.ensure([], () => {
//Export2Excel
const {
export_json_to_excel,
} = require("../../libs/export/Export2Excel");
// iveiwtitle
const tHeader = [
"序号",
"操作人",
"日志类型",
"详细信息",
"操作时间",
];
// iviewkey
const filterVal = [
"index",
"log_add_user_name",
"log_type_name",
"log_content",
"log_add_time",
];
//iview
var list = this.tableDataLog;
//
for (const i in list) {
list[i].index = parseInt(i) + 1;
}
const data = this.FormatJson(filterVal, list);
//excel
export_json_to_excel(tHeader, data, "logs-" + new Date());
});
},
FormatJson(filterVal, jsonData) {
return jsonData.map((v) => filterVal.map((j) => v[j]));
},
},
};
</script>
<style >
</style>

335
01.web/src/views/user/user.vue

@ -1,335 +0,0 @@ @@ -1,335 +0,0 @@
<template>
<Card :bordered="false" :dis-hover="true">
<Tooltip max-width="150" :content="toolTipAddUser">
<Button type="primary" @click="ModalAddRepUser()">新建用户</Button>
</Tooltip>
<div class="page-table">
<Table :columns="tableColumnRepUser" :data="tableDataRepUser">
<template slot-scope="{ index }" slot="id">
<strong>{{ index + 1 }}</strong>
</template>
<template slot-scope="{ row }" slot="disabled">
{{ row.disabled == 1 ? "禁用" : "启用" }}
</template>
<template slot-scope="{ row, index }" slot="action">
<Button
type="info"
size="small"
v-if="row.disabled == 1"
@click="RepUserEnabled(index)"
>启用</Button
>
<Button
type="info"
size="small"
v-else
@click="RepUserDisabled(index)"
>禁用</Button
>
<Button type="success" size="small" @click="ModalRepUserEdit(index)"
>密码</Button
>
<Button type="error" size="small" @click="ModalRepUserDel(index)"
>删除</Button
>
</template>
</Table>
<Card :bordered="false" :dis-hover="true">
<Page
v-if="numRepUserTotal != 0"
:total="numRepUserTotal"
:page-size="numRepUserPageSize"
@on-change="PagesizeChange"
/>
</Card>
</div>
<Modal
v-model="ModalRepUserAdd"
title="新建SVN用户"
@on-ok="RepAddUser()"
@submit.native.prevent
>
<Form ref="formRepUser" :model="formRepUser" :label-width="80">
<FormItem label="用户名">
<Input v-model="formRepUser.userName" />
</FormItem>
<FormItem label="密码">
<Input v-model="formRepUser.userPass" />
</FormItem>
<FormItem label="确认密码">
<Input v-model="formRepUser.userPass2" />
</FormItem>
</Form>
</Modal>
<Modal
v-model="modalRepUserEdit"
title="编辑SVN用户信息"
@on-ok="RepEditUser()"
>
<Form ref="formRepUser" :model="formRepUser" :label-width="80">
<FormItem label="用户名">
<Input v-model="formRepUser.userName" disabled />
</FormItem>
<FormItem label="密码">
<Input v-model="formRepUser.userPass" />
</FormItem>
<FormItem label="确认密码">
<Input v-model="formRepUser.userPass2" />
</FormItem>
</Form>
</Modal>
</Card>
</template>
<script>
export default {
data() {
return {
toolTipAddUser: "SVN用户名称只能包含字母、数字、破折号、下划线、点",
/**
* 布尔值
*/
boolIsAdmin: window.sessionStorage.roleid == 1 ? true : false,
/**
* 对话框控制
*/
ModalRepUserAdd: false, //
modalRepUserEdit: false, //
/**
* 分页数据
*/
numRepUserPageCurrent: 1,
numRepUserPageSize: 10,
numRepUserTotal: 20,
formRepUser: {
userid: "", //id
userName: "", //
userPass: "", //
userPass2: "", //
realname: "", //
email: "", //
phone: "", //
roleid: "", //id
},
/**
* 用户表格数据
*/
tableColumnRepUser: [
{
title: "序号",
slot: "id",
width: 150,
},
{
title: "用户名",
key: "userName",
},
{
title: "密码",
key: "userPass",
},
{
title: "状态",
key: "disabled",
slot: "disabled",
},
{
title: "操作",
slot: "action",
align: "center",
},
],
tableDataRepUser: [
// {
// id: 1,
// uid: "",
// roleid: "",
// userName: "",
// userPass: "",
// realname: "",
// email: "",
// phone: "",
// },
],
};
},
methods: {
PagesizeChange(value) {
var that = this;
that.numRepUserPageCurrent = value; //
that.RepGetUserList();
},
//
RepUserEnabled(index) {
var that = this;
var data = {
userName: that.tableDataRepUser[index]["userName"],
};
that.$axios
.post("/api.php?c=svnserve&a=RepEnabledUser", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.RepGetUserList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
//
RepUserDisabled(index) {
var that = this;
var data = {
userName: that.tableDataRepUser[index]["userName"],
};
that.$axios
.post("/api.php?c=svnserve&a=RepDisabledUser", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.RepGetUserList();
} else {
that.$Message.error(result.message);
}
})
.catch(function (error) {
console.log(error);
});
},
ModalRepUserEdit(index) {
var that = this;
that.modalRepUserEdit = true;
that.formRepUser.userName = that.tableDataRepUser[index]["userName"];
that.formRepUser.userPass = that.tableDataRepUser[index]["userPass"];
that.formRepUser.userPass2 = that.tableDataRepUser[index]["userPass"];
},
//
ModalAddRepUser() {
var that = this;
that.ModalRepUserAdd = true;
that.formRepUser.userName = "";
that.formRepUser.userPass = "";
that.formRepUser.userPass2 = "";
},
RepEditUser() {
var that = this;
var data = {
edit_username: String(that.formRepUser.userName),
edit_password: String(that.formRepUser.userPass),
edit_password2: String(that.formRepUser.userPass2),
};
that.$axios
.post("/api.php?c=svnserve&a=RepEditUser", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.modalRepUserEdit = false;
that.RepGetUserList();
} else {
that.$Message.error(result.message);
that.modalRepUserEdit = false;
}
})
.catch(function (error) {
console.log(error);
that.modalRepUserEdit = false;
});
},
//
RepAddUser() {
var that = this;
var data = {
userName: that.formRepUser.userName,
userPass: that.formRepUser.userPass,
userPass2: that.formRepUser.userPass2,
};
that.$axios
.post("/api.php?c=svnserve&a=RepAddUser", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.ModalRepUserAdd = false;
that.RepGetUserList();
} else {
that.$Message.error(result.message);
that.ModalRepUserAdd = false;
}
})
.catch(function (error) {
console.log(error);
that.ModalRepUserAdd = false;
});
},
//
RepGetUserList() {
var that = this;
var data = {
pageSize: that.numRepUserPageSize,
currentPage: that.numRepUserPageCurrent,
};
that.$axios
.post("/api.php?c=svnserve&a=RepGetUserList", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.tableDataRepUser = result.data;
that.numRepUserTotal = result.total;
} else {
that.$Message.error(result.message);
that.numRepUserTotal = 0;
}
})
.catch(function (error) {
console.log(error);
});
},
//
ModalRepUserDel(index) {
var that = this;
var data = {
del_username: that.tableDataRepUser[index]["userName"],
};
that.$Modal.confirm({
title: "警告",
content: "确定要删除该账户吗?",
loading: true,
onOk: () => {
that.$axios
.post("/api.php?c=svnserve&a=RepUserDel", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.$Modal.remove();
that.RepGetUserList();
} else {
that.$Message.error(result.message);
that.$Modal.remove();
}
})
.catch(function (error) {
console.log(error);
});
},
onCancel: () => {},
});
},
},
created() {},
mounted() {
var that = this;
that.RepGetUserList();
},
};
</script>

24
01.web/src/vuex/store.js

@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
import Vue from 'vue'
import Vuex from 'vuex'
import Routers from '../router';
Vue.use(Vuex)
// userid: null,
// username:null,
// roleid: null,
// rolename:null,
// token:null
const state = {
userInfo: ""
};
export default new Vuex.Store({
getters: {
},
mutations: {
}
})

11
01.web/webpack.dev.config.js

@ -4,19 +4,14 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin'); @@ -4,19 +4,14 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin');
const merge = require('webpack-merge');
const webpackBaseConfig = require('./webpack.base.config.js');
const fs = require('fs');
const path = require('path');
fs.open('./src/config/env.js', 'w', function (err, fd) {
const buf = 'export default "development";';
//fs.write(fd, buf, 0, buf.length, 0, function (err, written, buffer){});
// fs.write(fd, buf, 0, buf.length, 0, function (err, written, buffer){});
fs.write(fd, buf, 0, 'utf-8', function (err, written, buffer) { });
});
module.exports = merge(webpackBaseConfig, {
resolve: {
alias: {
lib: path.resolve(__dirname, 'src/libs/'),
}
},
devtool: '#source-map',
output: {
publicPath: '/dist/',
@ -38,7 +33,6 @@ module.exports = merge(webpackBaseConfig, { @@ -38,7 +33,6 @@ module.exports = merge(webpackBaseConfig, {
inject: false
})
],
devServer: {
host: '127.0.0.1',
port: 8081,
@ -58,5 +52,4 @@ module.exports = merge(webpackBaseConfig, { @@ -58,5 +52,4 @@ module.exports = merge(webpackBaseConfig, {
}
}
}
});

7
01.web/webpack.prod.config.js

@ -6,8 +6,8 @@ const webpackBaseConfig = require('./webpack.base.config.js'); @@ -6,8 +6,8 @@ const webpackBaseConfig = require('./webpack.base.config.js');
const fs = require('fs');
fs.open('./src/config/env.js', 'w', function (err, fd) {
const buf = 'export default "development";';
//fs.write(fd, buf, 0, buf.length, 0, function (err, written, buffer){});
const buf = 'export default "production";';
// fs.write(fd, buf, 0, buf.length, 0, function (err, written, buffer){});
fs.write(fd, buf, 0, 'utf-8', function (err, written, buffer) { });
});
@ -41,6 +41,5 @@ module.exports = merge(webpackBaseConfig, { @@ -41,6 +41,5 @@ module.exports = merge(webpackBaseConfig, {
template: './src/template/index.ejs',
inject: false
})
],
]
});

86
02.php/api.php

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<?php
declare(strict_types=1);
//declare(strict_types=1);
/**
* 开启错误信息 如需要调试 可取消注释
@ -8,8 +8,6 @@ declare(strict_types=1); @@ -8,8 +8,6 @@ declare(strict_types=1);
ini_set('display_errors', '1');
error_reporting(E_ALL);
header('Content-Type:application/json; charset=utf-8');
define('BASE_PATH', __DIR__);
date_default_timezone_set('PRC');
@ -19,7 +17,7 @@ require_once BASE_PATH . '/app/core/controller.class.php'; @@ -19,7 +17,7 @@ require_once BASE_PATH . '/app/core/controller.class.php';
/**
* token
*/
define('MY_TOKEN', empty($_SERVER['HTTP_TOKEN']) ? '' : $_SERVER['HTTP_TOKEN']);
$token = empty($_SERVER['HTTP_TOKEN']) ? '' : $_SERVER['HTTP_TOKEN'];
/**
* 控制器
@ -32,49 +30,75 @@ $controller_path = BASE_PATH . '/app/controller/' . $controller_name . '.php'; / @@ -32,49 +30,75 @@ $controller_path = BASE_PATH . '/app/controller/' . $controller_name . '.php'; /
* 方法
*/
$action = empty($_GET['a']) ? '' : $_GET['a'];
define('MY_FUNCTION', $action);
/**
* 参数
* 接口类型
* 小程序还是web系统
*/
$type = isset($_GET['t']) ? $_GET['t'] : '';
/**
* 请求参数即Request Payload
* Content-Type: application/json
*/
$requestPayload = file_get_contents("php://input");
$requestPayload = !empty($requestPayload) ? json_decode($requestPayload, true) : [];
/**
* 获取文件信息
* 适用请求方式 fordata
* Content-Type: multipart/form-data;
*
* 示例数据
* 其中 file 为前端请求的自定义字段 使用时候要自行判断是否存在该键值
* {
* "file": {
* "name": "tmp_bda9c778201ffb47ebfea61617a16d1c564ca6d0b8ad52b8.jpg",
* "type": "image\/jpeg",
* "tmp_name": "\/tmp\/phpwxfAaU",
* "error": 0,
* "size": 166881
* }
* }
*/
// $files = $_FILES;
/**
* 检查控制器和方法是否存在并实例化
*/
if (file_exists($controller_path)) {
$controller = new $controller_perifx();
if (is_callable(array($controller, $action))) {
//检测守护进程是否开启
//检测守护进程状态
$state = FunDetectState();
if ($state == 0) {
$data['status'] = 0;
$data['code'] = 501;
$data['message'] = '后台程序响应超时';
echo json_encode($data);
return;
FunMessageExit(401, 0, '守护进程响应超时');
} else if ($state == 2) {
$data['status'] = 0;
$data['code'] = 501;
$data['message'] = '后台程序未启动';
echo json_encode($data);
return;
FunMessageExit(401, 0, '守护进程未启动');
}
//白名单检查
if ($type == 'mini') {
if (!in_array($action, unserialize(miniWhiteList))) {
FunCheckToken($token);
}
//检测token
if (MY_FUNCTION != 'Login') {
$data = FunCheckToken(MY_TOKEN);
if ($data['code'] != '200') {
$result = array(
'status' => '0',
'code' => $data['code'],
'message' => $data['message']
);
echo json_encode($result);
return;
} else if ($type == 'web') {
if (!in_array($action, unserialize(webWhiteList))) {
FunCheckToken($token);
}
} else {
FunMessageExit(401, 0, '无效的接口类型');
}
//检查token是否已注销
(new blacktoken())->CheckBlack();
//开始调用
$controller = new $controller_perifx();
if (is_callable(array($controller, $action))) {
//执行请求
echo json_encode($controller->$action($requestPayload));
$controller->$action();
} else {
FunMessageExit(401, 0, '无效的方法名');
}
} else {
FunMessageExit(401, 0, '无效的控制器名');
}

57
02.php/app/controller/blacktoken.class.php

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
<?php
class blacktoken extends controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
/**
* 将token加入黑名单
*/
function BlackToken()
{
$arr = explode('.', $this->token);
$this->database->insert('black_token', [
'token' => $this->token,
'start_time' => $arr[2],
'end_time' => $arr[3],
'insert_time' => date('Y-m-d H:i:s')
]);
}
/**
* 扫描黑名单中的token 发现过期的则删除
*
* 目的:不给搜索增加压力
*/
function CleanBlack()
{
$this->database->delete('black_token', [
'end_time[<]' => time()
]);
}
/**
* 检查token是否存在于黑名单
*/
function CheckBlack()
{
$result = $this->database->get('black_token', [
'token_id'
], [
'token' => $this->token
]);
if ($result != null) {
FunMessageExit(401, 0, 'token已注销');
}
}
}

169
02.php/app/controller/client.class.php

@ -1,169 +0,0 @@ @@ -1,169 +0,0 @@
<?php
declare(strict_types=1);
/*
* 与客户端信息相关
*/
class Clientinfo extends Controller
{
private $remotes_keys = [
'HTTP_X_FORWARDED_FOR',
'HTTP_CLIENT_IP',
'HTTP_X_REAL_IP',
'HTTP_X_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR',
'HTTP_X_CLUSTER_CLIENT_IP',
];
private $Config;
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
$this->Config = new Config();
}
//获取IP地址
function GetClientIp()
{
foreach ($this->remotes_keys as $key) {
if (array_key_exists($key, $_SERVER)) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
if ($this->isValid($ip)) {
return $ip;
}
}
}
}
return '127.0.0.1';
}
//获取操作系统类型
function GetClientOS()
{
$agent = $_SERVER['HTTP_USER_AGENT'];
$os = false;
if (preg_match('/win/i', $agent) && strpos($agent, '95')) {
$os = 'Windows 95';
} else if (preg_match('/win 9x/i', $agent) && strpos($agent, '4.90')) {
$os = 'Windows ME';
} else if (preg_match('/win/i', $agent) && preg_match('/98/i', $agent)) {
$os = 'Windows 98';
} else if (preg_match('/win/i', $agent) && preg_match('/nt 6.0/i', $agent)) {
$os = 'Windows Vista';
} else if (preg_match('/win/i', $agent) && preg_match('/nt 6.1/i', $agent)) {
$os = 'Windows 7';
} else if (preg_match('/win/i', $agent) && preg_match('/nt 6.2/i', $agent)) {
$os = 'Windows 8';
} else if (preg_match('/win/i', $agent) && preg_match('/nt 10.0/i', $agent)) {
$os = 'Windows 10'; #添加win10判断
} else if (preg_match('/win/i', $agent) && preg_match('/nt 5.1/i', $agent)) {
$os = 'Windows XP';
} else if (preg_match('/win/i', $agent) && preg_match('/nt 5/i', $agent)) {
$os = 'Windows 2000';
} else if (preg_match('/win/i', $agent) && preg_match('/nt/i', $agent)) {
$os = 'Windows NT';
} else if (preg_match('/win/i', $agent) && preg_match('/32/i', $agent)) {
$os = 'Windows 32';
} else if (preg_match('/linux/i', $agent)) {
$os = 'Linux';
} else if (preg_match('/unix/i', $agent)) {
$os = 'Unix';
} else if (preg_match('/sun/i', $agent) && preg_match('/os/i', $agent)) {
$os = 'SunOS';
} else if (preg_match('/ibm/i', $agent) && preg_match('/os/i', $agent)) {
$os = 'IBM OS/2';
} else if (preg_match('/Mac/i', $agent) && preg_match('/PC/i', $agent)) {
$os = 'Macintosh';
} else if (preg_match('/PowerPC/i', $agent)) {
$os = 'PowerPC';
} else if (preg_match('/AIX/i', $agent)) {
$os = 'AIX';
} else if (preg_match('/HPUX/i', $agent)) {
$os = 'HPUX';
} else if (preg_match('/NetBSD/i', $agent)) {
$os = 'NetBSD';
} else if (preg_match('/BSD/i', $agent)) {
$os = 'BSD';
} else if (preg_match('/OSF1/i', $agent)) {
$os = 'OSF1';
} else if (preg_match('/IRIX/i', $agent)) {
$os = 'IRIX';
} else if (preg_match('/FreeBSD/i', $agent)) {
$os = 'FreeBSD';
} else if (preg_match('/teleport/i', $agent)) {
$os = 'teleport';
} else if (preg_match('/flashget/i', $agent)) {
$os = 'flashget';
} else if (preg_match('/webzip/i', $agent)) {
$os = 'webzip';
} else if (preg_match('/offline/i', $agent)) {
$os = 'offline';
} else {
$os = '未知操作系统';
}
return $os;
}
//获取浏览器类型
function GetClientBrowser()
{
$sys = $_SERVER['HTTP_USER_AGENT']; //获取用户代理字符串
if (stripos($sys, "Firefox/") > 0) {
preg_match("/Firefox\/([^;)]+)+/i", $sys, $b);
$exp[0] = "Firefox";
$exp[1] = $b[1]; //获取火狐浏览器的版本号
} elseif (stripos($sys, "Maxthon") > 0) {
preg_match("/Maxthon\/([\d\.]+)/", $sys, $aoyou);
$exp[0] = "傲游";
$exp[1] = $aoyou[1];
} elseif (stripos($sys, "MSIE") > 0) {
preg_match("/MSIE\s+([^;)]+)+/i", $sys, $ie);
$exp[0] = "IE";
$exp[1] = $ie[1]; //获取IE的版本号
} elseif (stripos($sys, "OPR") > 0) {
preg_match("/OPR\/([\d\.]+)/", $sys, $opera);
$exp[0] = "Opera";
$exp[1] = $opera[1];
} elseif (stripos($sys, "Edge") > 0) {
//win10 Edge浏览器 添加了chrome内核标记 在判断Chrome之前匹配
preg_match("/Edge\/([\d\.]+)/", $sys, $Edge);
$exp[0] = "Edge";
$exp[1] = $Edge[1];
} elseif (stripos($sys, "Chrome") > 0) {
preg_match("/Chrome\/([\d\.]+)/", $sys, $google);
$exp[0] = "Chrome";
$exp[1] = $google[1]; //获取google chrome的版本号
} elseif (stripos($sys, 'rv:') > 0 && stripos($sys, 'Gecko') > 0) {
preg_match("/rv:([\d\.]+)/", $sys, $IE);
$exp[0] = "IE";
$exp[1] = $IE[1];
} else {
$exp[0] = "未知浏览器";
$exp[1] = "";
}
return $exp[0] . '(' . $exp[1] . ')';
}
//校验IP地址
private function isValid($ip)
{
if (
!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) && !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE)
) {
return false;
}
return true;
}
}

181
02.php/app/controller/common.class.php

@ -0,0 +1,181 @@ @@ -0,0 +1,181 @@
<?php
/**
* 登录注销等公共类
*/
class common extends controller
{
private $Svnuser;
private $Blacktoken;
private $Logs;
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
$this->Svnuser = new svnuser();
$this->Blacktoken = new blacktoken();
$this->Logs = new logs();
}
/**
* 登录
*/
function Login()
{
$codeResult = $this->database->get('verification_code', [
'end_time'
], [
'uuid' => $this->requestPayload['uuid'],
'code' => $this->requestPayload['code'],
]);
if ($codeResult == null) {
FunMessageExit(200, 0, '验证码错误', $codeResult);
}
if ($codeResult['end_time'] < time()) {
FunMessageExit(200, 0, '验证码过期');
}
FunCheckForm($this->requestPayload, [
'user_name' => ['type' => 'string', 'notNull' => true],
'user_pass' => ['type' => 'string', 'notNull' => true],
'user_role' => ['type' => 'string', 'notNull' => true],
]);
if ($this->requestPayload['user_role'] == 1) {
$result = $this->database->get('admin_users', [
'admin_user_id',
'admin_user_name',
'admin_user_phone',
'admin_user_email'
], [
'admin_user_name' => $this->requestPayload['user_name'],
'admin_user_password' => $this->requestPayload['user_pass']
]);
if ($result == null) {
FunMessageExit(200, 0, '账号密码错误');
}
} else if ($this->requestPayload['user_role'] == 2) {
//进行用户数据同步
$this->Svnuser->SyncUserToDb();
$result = $this->database->get('svn_users', [
'svn_user_id',
'svn_user_name',
'svn_user_pass',
'svn_user_status'
], [
'svn_user_name' => $this->requestPayload['user_name'],
'svn_user_pass' => $this->requestPayload['user_pass']
]);
if ($result == null) {
FunMessageExit(200, 0, '登陆失败');
}
if ($result['svn_user_status'] == 0) {
FunMessageExit(200, 0, '用户已过期');
}
}
$this->Logs->InsertLog(
'用户登录',
'登陆成功 '
. '账号:' . $this->requestPayload['user_name'] . ' '
. 'IP地址:' . $_SERVER["REMOTE_ADDR"],
$this->requestPayload['user_name']
);
FunMessageExit(200, 1, '登陆成功', [
'token' => FunCreateToken($this->requestPayload['user_role'], $this->requestPayload['user_name']),
'user_name' => $this->requestPayload['user_name'],
'user_role_name' => $this->requestPayload['user_role'] == 1 ? '管理人员' : 'SVN用户',
'user_role_id' => $this->requestPayload['user_role']
]);
}
/**
* 注销
*
* 注销操作为将用户尚未过期的token加入所谓黑名单
* 每次注销触发主动扫描黑名单 将名单中过期的token删除
* 目的:实现用户注销后尚未过期的token无法继续使用
*/
function Logout()
{
//清理过期token
$this->Blacktoken->CleanBlack();
//加入本token
$this->Blacktoken->BlackToken();
$this->Logs->InsertLog(
'用户注销',
'账号:' . $this->globalUserName . 'IP地址:' . $_SERVER["REMOTE_ADDR"],
$this->globalUserName
);
//退出
FunMessageExit();
}
/**
* 清除过期验证码
*/
private function Clean()
{
$this->database->delete('verification_code', [
'end_time[<]' => time()
]);
}
/**
* 获取验证码
*/
function GetVeryfyCode()
{
//清除过期验证码
$this->Clean();
//生成验证码
$code = FunGetRandStrL(4);
//生成唯一标识
$uuid = time() . FunGetRandStr() . FunGetRandStr();
//
$prefix = time();
//生效时间
$startTime = $prefix;
//有效时间为60s
$endTime = $prefix + 60;
//写入数据库
$this->database->insert('verification_code', [
'uuid' => $uuid,
'code' => $code,
'start_time' => $startTime,
'end_time' => $endTime,
'insert_time' => date('Y-m-d H:i:s')
]);
require_once BASE_PATH . '/extension/VerifyCode/VerifyCode.class.php';
$varification = new verification(134, 32, $code, BASE_PATH . '/data/test.png');
$imageString = $varification->CreateVerifacationImage();
//返回图片的base64编码
FunMessageExit(200, 1, 'success', [
'uuid' => $uuid,
'base64' => $imageString
]);
}
}

218
02.php/app/controller/config.class.php

@ -1,218 +0,0 @@ @@ -1,218 +0,0 @@
<?php
declare(strict_types=1);
/*
* 与配置信息操作相关
*/
class Config extends Controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
//从配置文件获取
public function Get($key)
{
$strContent = file_get_contents(BASE_PATH . '/config/auto.config.php');
return FunGetConfigValue($strContent, $key);
}
//向配置文件更新
public function Update($key, $value)
{
$strContent = file_get_contents(BASE_PATH . '/config/auto.config.php');
$result = FunUpdateConfigValue($strContent, $key, $value);
file_put_contents(BASE_PATH . '/config/auto.config.php', $result);
}
//设置管理员信息
public function SetManageSetting($requestPayload)
{
$manageUser = trim($requestPayload['manageUser']);
$managePass = trim($requestPayload['managePass']);
$manageEmail = trim($requestPayload['manageEmail']);
if (empty($manageUser) || empty($managePass) || empty($manageEmail)) {
$data['status'] = 0;
$data['message'] = '参数不完整或错误';
return $data;
}
$this->Update("MANAGE_USER", $manageUser);
$this->Update("MANAGE_PASS", $managePass);
$this->Update("MANAGE_EMAIL", $manageEmail);
$data['status'] = 1;
$data['message'] = '成功';
return $data;
}
//获取管理员信息
public function GetManageSetting($requestPayload)
{
$result = array(
"manageUser" => MANAGE_USER,
"managePass" => MANAGE_PASS,
"manageEmail" => MANAGE_EMAIL,
);
$data['status'] = 1;
$data['data'] = $result;
$data['message'] = '成功';
return $data;
}
//获取服务器基本信息
public function GetBasicSetting($requestPayload)
{
$all_mail_status = ALL_MAIL_STATUS == 1 ? true : false;
$result = array(
"server_ip" => SERVER_IP,
"server_domain" => SERVER_DOMAIN,
"svn_repository_path" => SVN_REPOSITORY_PATH,
"backup_path" => BACKUP_PATH,
"all_mail_status" => $all_mail_status,
"token" => SIGNATURE,
"logs" => LOG_PATH,
"svnserve" => SVN_SERVER_CONF,
"passwd" => SVN_SERVER_PASSWD,
"authz" => SVN_SERVER_AUTHZ
);
$data['status'] = 1;
$data['data'] = $result;
$data['message'] = '成功';
return $data;
}
//设置服务器基本信息
public function SetBasicSetting($requestPayload)
{
$server_ip = trim($requestPayload['server_ip']);
$token = trim($requestPayload['token']);
$server_domain = trim($requestPayload['server_domain']);
$all_mail_status = $requestPayload['all_mail_status'];
if (empty($server_ip) || empty($server_domain) || empty($token)) {
$data['status'] = 0;
$data['message'] = '参数不完整或错误';
return $data;
}
$this->Update("SERVER_IP", $server_ip);
$this->Update("SERVER_DOMAIN", $server_domain);
$this->Update("SIGNATURE", $token);
if ($all_mail_status) {
$this->Update("ALL_MAIL_STATUS", 1);
} else {
$this->Update("ALL_MAIL_STATUS", 0);
}
$data['status'] = 1;
$data['message'] = "成功";
return $data;
}
//更改版本库父文件夹后触发的操作
private function UpdateRepositoryParentPath($old_path, $new_path)
{
FunRequestReplyExec("mkdir $new_path");
$info = FunRequestReplyExec('ps auxf|grep -v "grep"|grep svnserve');
if ($info == ISNULL && !file_exists('/usr/bin/svnserve')) {
/*
* 没有安装过svn服务
*/
//移动仓库
$file_arr = scandir($old_path);
foreach ($file_arr as $file_item) {
if ($file_item != '.' && $file_item != '..') {
if (is_dir($old_path . '/' . $file_item)) {
$file_arr2 = scandir($old_path . '/' . $file_item);
foreach ($file_arr2 as $file_item2) {
if (($file_item2 == 'conf' || $file_item2 == 'db' || $file_item2 == 'hooks' || $file_item2 == 'locks')) {
FunRequestReplyExec('mv -b -f ' . $old_path . '/' . $file_item . ' ' . $new_path);
}
}
}
}
}
//检查仓库是否已经被移动
$file_arr = scandir($old_path);
foreach ($file_arr as $file_item) {
if ($file_item != '.' && $file_item != '..') {
if (is_dir($old_path . '/' . $file_item)) {
$file_arr2 = scandir($old_path . '/' . $file_item);
foreach ($file_arr2 as $file_item2) {
if (($file_item2 == 'conf' || $file_item2 == 'db' || $file_item2 == 'hooks' || $file_item2 == 'locks')) {
return false;
}
}
}
}
}
return true;
} else {
/*
* 安装过svn服务
*/
//停止服务
FunRequestReplyExec('systemctl stop svnserve');
//移动仓库
$file_arr = scandir($old_path);
foreach ($file_arr as $file_item) {
if ($file_item != '.' && $file_item != '..') {
if (is_dir($old_path . '/' . $file_item)) {
$file_arr2 = scandir($old_path . '/' . $file_item);
foreach ($file_arr2 as $file_item2) {
if (($file_item2 == 'conf' || $file_item2 == 'db' || $file_item2 == 'hooks' || $file_item2 == 'locks')) {
FunRequestReplyExec('mv -b -f ' . $old_path . '/' . $file_item . ' ' . $new_path);
}
}
}
}
}
//修改配置文件
FunRequestReplyExec('sed -i \'s/' . str_replace('/', '\/', $old_path) . '/' . str_replace('/', '\/', $new_path) . '/g\'' . ' /etc/sysconfig/svnserve'); //bug
//启动服务
FunRequestReplyExec('systemctl start svnserve');
//检查配置文件是否被正确修改
$file = fopen("/etc/sysconfig/svnserve", "r") or exit("无法打开文件!");
$file_content = [];
while (!feof($file)) {
array_push($file_content, fgets($file));
}
fclose($file);
foreach ($file_content as $key => $value) {
if (strstr($value, $old_path)) {
return false;
}
}
//检查仓库是否已经被移动
$file_arr = scandir($old_path);
foreach ($file_arr as $file_item) {
if ($file_item != '.' && $file_item != '..') {
if (is_dir($old_path . '/' . $file_item)) {
$file_arr2 = scandir($old_path . '/' . $file_item);
foreach ($file_arr2 as $file_item2) {
if (($file_item2 == 'conf' || $file_item2 == 'db' || $file_item2 == 'hooks' || $file_item2 == 'locks')) {
return false;
}
}
}
}
}
return true;
}
}
}

31
02.php/app/controller/crontab.class.php

@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
/*
* 与计划任务操作相关
*/
class Crontab extends Controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
$this->Config = new Config();
$this->svn_repository_path = SVN_REPOSITORY_PATH;
$this->backup_path = BACKUP_PATH;
}
//立即执行计划任务
function StartCrontab()
{
}
}

145
02.php/app/controller/firewall.class.php

@ -1,145 +0,0 @@ @@ -1,145 +0,0 @@
<?php
declare(strict_types=1);
/*
* 与防火墙操作相关
*/
class Firewall extends Controller {
function __construct() {
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
//高级设置 使svnserve服务的端口通过防火墙
function SetFirewallStatus($requestPayload) {
$action = $requestPayload['action'];
if (empty($action)) {
$data['status'] = 0;
$data['message'] = '参数不完整';
return $data;
}
switch ($action) {
case 'startFirewall':
FunRequestReplyExec('systemctl start firewalld');
FunRequestReplyExec('firewall-cmd --zone=public --add-port=80/tcp --permanent'); //启动的同时将80加入 使得web服务正常运行
FunRequestReplyExec('firewall-cmd --zone=public --add-port=3690/tcp --permanent'); //启动的同时将80加入 使得web服务正常运行
FunRequestReplyExec('firewall-cmd --reload');
break;
case 'restartFirewall':
FunRequestReplyExec('systemctl restart firewalld');
FunRequestReplyExec('firewall-cmd --zone=public --add-port=80/tcp --permanent'); //启动的同时将80加入 使得web服务正常运行
FunRequestReplyExec('firewall-cmd --zone=public --add-port=3690/tcp --permanent'); //启动的同时将80加入 使得web服务正常运行
FunRequestReplyExec('firewall-cmd --reload');
break;
case 'stopFirewall':
FunRequestReplyExec('systemctl stop firewalld');
break;
}
sleep(1);
$data['status'] = 1;
$data['message'] = '成功';
return $data;
}
//设置防火墙规则
function SetFirewallPolicy($requestPayload) {
$protocal = 'tcp';
$port = $requestPayload['port'];
$type = $requestPayload['type'] ? 'add' : 'remove';
if (empty($protocal) || empty($port) || empty($type)) {
$data['status'] = 0;
$data['message'] = '参数不完整';
return $data;
}
FunRequestReplyExec('firewall-cmd --zone=public --' . $type . '-port=' . $port . '/' . $protocal . ' --permanent');
FunRequestReplyExec('firewall-cmd --reload');
sleep(1);
$data['status'] = 1;
$data['message'] = '成功';
return $data;
}
//获取防火墙规则
function GetFirewallPolicy($requestPayload) {
//获取80 443 3690是否加入防火墙
$info = FunRequestReplyExec('ps auxf|grep -v "grep"|grep firewalld');
if ($info == ISNULL) {
$info = [];
$info['svn'] = false;
$info['http'] = false;
$info['https'] = false;
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $info;
return $data;
}
$info = [];
$result = trim(FunRequestReplyExec('firewall-cmd --query-port=80/tcp'));
if ($result == 'yes') {
$info['http'] = true;
} else {
$info['http'] = false;
}
$result = trim(FunRequestReplyExec('firewall-cmd --query-port=443/tcp'));
if ($result == 'yes') {
$info['https'] = true;
} else {
$info['https'] = false;
}
$result = trim(FunRequestReplyExec('firewall-cmd --query-port=3690/tcp'));
if ($result == 'yes') {
$info['svn'] = true;
} else {
$info['svn'] = false;
}
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $info;
return $data;
}
//获取防火墙状态
function GetFirewallStatus($requestPayload) {
$info = FunRequestReplyExec('ps auxf|grep -v "grep"|grep firewalld');
if ($info == ISNULL) {
$info = [];
$info['status'] = '已停止';
$info['type'] = 'warning';
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $info;
return $data;
}
$info = [];
$info['status'] = '运行中';
$info['type'] = 'success';
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $info;
return $data;
}
}

90
02.php/app/controller/logs.class.php

@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
<?php
class logs extends controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
/**
* 获取日志列表
*/
function GetLogList()
{
$pageSize = $this->requestPayload['pageSize'];
$currentPage = $this->requestPayload['currentPage'];
$searchKeyword = trim($this->requestPayload['searchKeyword']);
//分页
$begin = $pageSize * ($currentPage - 1);
$list = $this->database->select('logs', [
'log_id',
'log_type_name',
'log_content',
'log_add_user_name',
'log_add_time',
], [
'AND' => [
'OR' => [
'log_type_name[~]' => $searchKeyword,
'log_content[~]' => $searchKeyword,
'log_add_user_name[~]' => $searchKeyword,
'log_add_time[~]' => $searchKeyword,
],
],
'LIMIT' => [$begin, $pageSize]
]);
$total = $this->database->count('logs', [
'log_id'
], [
'AND' => [
'OR' => [
'log_type_name[~]' => $searchKeyword,
'log_content[~]' => $searchKeyword,
'log_add_user_name[~]' => $searchKeyword,
'log_add_time[~]' => $searchKeyword,
],
]
]);
FunMessageExit(200, 1, '成功', [
'data' => $list,
'total' => $total
]);
}
/**
* 清空日志
*/
function ClearLogs()
{
$this->database->delete('logs', [
'log_id[>]' => 0
]);
FunMessageExit();
}
/**
* 写入日志
*/
function InsertLog($log_type_name = '', $log_content = '', $log_add_user_name = '')
{
$this->database->insert('logs', [
'log_type_name' => $log_type_name,
'log_content' => $log_content,
'log_add_user_name' => $log_add_user_name,
'log_add_time' => date('Y-m-d H:i:s')
]);
}
}

166
02.php/app/controller/mail.class.php

@ -1,24 +1,7 @@ @@ -1,24 +1,7 @@
<?php
declare(strict_types=1);
/*
* 与邮件操作相关
*/
require BASE_PATH . '/extension/PHPMailer/src/Exception.php';
require BASE_PATH . '/extension/PHPMailer/src/PHPMailer.php';
require BASE_PATH . '/extension/PHPMailer/src/SMTP.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
class Mail extends Controller
class mail extends controller
{
private $Mail;
private $Config;
function __construct()
{
/*
@ -29,152 +12,5 @@ class Mail extends Controller @@ -29,152 +12,5 @@ class Mail extends Controller
/*
* 其它自定义操作
*/
// 实例化并传递 true 将启用异常
$this->Mail = new PHPMailer(true);
$this->Mail->setLanguage('zh_cn', BASE_PATH . '/extension/PHPMailer/language/'); //加载错误消息翻译包
$this->Config = new Config();
}
//用户操作触发邮件发送机制
function SendMail($send_title, $send_content)
{
//系统未开启邮件服务
if (ALL_MAIL_STATUS == "0") {
return;
}
//未添加邮件服务
$result = mail_host;
if (empty($result)) {
return;
}
//添加的邮件服务未启用
if (single_mail_status != "1") {
return;
}
//邮件服务器选项
$port = mail_port;
$host = mail_host;
$username = mail_user;
$password = mail_password;
$from = send_mail;
$to = MANAGE_EMAIL;
//设置选项
try {
//服务器配置
$this->Mail->SMTPDebug = SMTP::DEBUG_OFF; // 关闭debug模式
$this->Mail->isSMTP(); // 使用 SMTP
$this->Mail->Host = $host; // SMTP服务器
$this->Mail->SMTPAuth = true; // 允许 SMTP 认证
$this->Mail->Username = $username; // SMTP 用户名
$this->Mail->Password = $password; // SMTP 密码
$this->Mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // 允许tls协议
$this->Mail->Port = $port; // TCP 端口
//接收设置
$this->Mail->setFrom($from, '发送方:SvnAdmin'); //发件人
$this->Mail->addAddress($to); //收件人 名字可选 可添加多个收件人
$this->Mail->addReplyTo($from, '发送方:SvnAdmin'); //回复的时候回复给哪个邮箱 名字可选 建议和发件人一致
// $this->Mail->addCC('cc@example.com'); //抄送
// $this->Mail->addBCC('bcc@example.com'); //密送
//发送附件
// $this->Mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
// $this->Mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name
//内容设置
$this->Mail->isHTML(false); // 是否以HTML文档格式发送 发送后客户端可直接显示对应HTML内容
$this->Mail->Subject = $send_title;
$this->Mail->Body = $send_content;
// $this->Mail->AltBody = '如果邮件客户端不支持HTML则显示此内容';
$this->Mail->send();
} catch (Exception $e) {
// echo "邮件发送失败: {$mail->ErrorInfo}";
}
}
//发送测试邮件
function SendTestMail($requestPayload)
{
$host = trim($requestPayload['host']);
$port = trim($requestPayload['port']);
$username = trim($requestPayload['username']);
$password = trim($requestPayload['password']);
$from = trim($requestPayload['from']);
$to = trim($requestPayload['to']);
if (empty($host) || empty($port) || empty($username) || empty($password) || empty($from) || empty($to)) {
$data['status'] = 0;
$data['message'] = '参数不完整';
return $data;
}
//设置选项
try {
//服务器配置
$this->Mail->SMTPDebug = SMTP::DEBUG_OFF; // 关闭debug模式
$this->Mail->isSMTP(); // 使用 SMTP
$this->Mail->Host = $host; // SMTP服务器
$this->Mail->SMTPAuth = true; // 允许 SMTP 认证
$this->Mail->Username = $username; // SMTP 用户名
$this->Mail->Password = $password; // SMTP 密码
$this->Mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // 允许tls协议
$this->Mail->Port = $port; // TCP 端口
//接收设置
$this->Mail->setFrom($from, '发送方:SvnAdmin'); //发件人
$this->Mail->addAddress($to); //收件人 名字可选 可添加多个收件人
$this->Mail->addReplyTo($from, '发送方:SvnAdmin'); //回复的时候回复给哪个邮箱 名字可选 建议和发件人一致
// $this->Mail->addCC('cc@example.com'); //抄送
// $this->Mail->addBCC('bcc@example.com'); //密送
//发送附件
// $this->Mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
// $this->Mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name
//内容设置
$this->Mail->isHTML(false); // 是否以HTML文档格式发送 发送后客户端可直接显示对应HTML内容
$this->Mail->Subject = 'Svn Admin系统测试邮件';
$this->Mail->Body = '尊敬的用户,您好!此邮件为Svn Admin系统的测试邮件,当您收到此邮件,代表您的邮件服务器已经配置正确。';
// $this->Mail->AltBody = '如果邮件客户端不支持HTML则显示此内容';
$this->Mail->send();
$data['status'] = 1;
$data['message'] = '成功';
return $data;
} catch (Exception $e) {
$data['status'] = 0;
$data['message'] = '发送失败 ' . $this->Mail->ErrorInfo;
return $data;
}
}
//保存邮件设置
function SetMailInfo($requestPayload)
{
$this->Config->Update('mail_host', trim($requestPayload['host']));
$this->Config->Update('mail_port', trim($requestPayload['port']));
$this->Config->Update('mail_user', trim($requestPayload['username']));
$this->Config->Update('mail_password', trim($requestPayload['password']));
$this->Config->Update('send_mail', trim($requestPayload['from']));
$data['status'] = 1;
$data['message'] = '成功';
return $data;
}
//获取邮件配置
function GetMailInfo($requestPayload)
{
$data = array(
"protocol_type" => mail_protocol_type,
"smtp_host" => mail_host,
"smtp_port" => (int) mail_port,
"mail_ssl_port" => (int) mail_ssl_port,
"smtp_user" => mail_user,
"smtp_password" => mail_password,
"smtp_send_email" => send_mail,
"single_mail_status" => (int) single_mail_status,
"add_time" => "",
"ps" => ""
);
$data['status'] = 1;
$data['data'] = $data;
$data['message'] = '成功';
return $data;
}
}

115
02.php/app/controller/personal.class.php

@ -0,0 +1,115 @@ @@ -0,0 +1,115 @@
<?php
class personal extends controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
/**
* 管理人员修改自己的账号
*/
function EditAdminUserName()
{
if ($this->requestPayload['userName'] != $this->requestPayload['confirm']) {
FunMessageExit(200, 0, '输入不一致');
}
if (trim($this->requestPayload['userName']) == '') {
FunMessageExit(200, 0, '用户名不合法');
}
$info = $this->database->get('admin_users', [
'admin_user_name'
], [
'admin_user_name' => $this->requestPayload['userName']
]);
if ($info != null) {
FunMessageExit(200, 0, '与已有用户冲突');
}
$this->database->update('admin_users', [
'admin_user_name' => $this->requestPayload['userName']
], [
'admin_user_name' => $this->globalUserName
]);
FunMessageExit();
}
/**
* 管理人员修改自己的密码
*/
function EditAdminUserPass()
{
if ($this->requestPayload['password'] != $this->requestPayload['confirm']) {
FunMessageExit(200, 0, '输入不一致');
}
if (trim($this->requestPayload['password']) == '') {
FunMessageExit(200, 0, '密码不合法');
}
$this->database->update('admin_users', [
'admin_user_pass' => $this->requestPayload['password']
], [
'admin_user_name' => $this->globalUserName
]);
FunMessageExit();
}
/**
* SVN用户修改自己的密码
*/
function EditSvnUserPass()
{
if ($this->requestPayload['newPassword'] != $this->requestPayload['confirm']) {
FunMessageExit(200, 0, '输入不一致');
}
//获取SVN指定用户的密码
$result = FunGetPassByUser($this->globalPasswdContent, $this->globalUserName);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[users]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '用户不存在');
}
if (trim($this->requestPayload['newPassword']) == '') {
FunMessageExit(200, 0, '密码不合法');
}
if ($result != $this->requestPayload['oldPassword']) {
FunMessageExit(200, 0, '旧密码输入错误');
}
//修改SVN指定用户的密码
$result = FunUpdSvnUserPass($this->globalPasswdContent, $this->globalUserName, $this->requestPayload['newPassword']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[users]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '用户不存在');
}
FunShellExec('echo \'' . $result . '\' > ' . SVN_PASSWD_FILE);
$this->database->update('svn_users', [
'svn_user_pass' => $this->requestPayload['newPassword']
], [
'svn_user_name' => $this->globalUserName
]);
FunMessageExit();
}
}

16
02.php/app/controller/safe.class.php

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
<?php
class safe extends controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
}

238
02.php/app/controller/statistics.class.php

@ -0,0 +1,238 @@ @@ -0,0 +1,238 @@
<?php
/**
* 信息统计类
*/
class statistics extends controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
/**
* 获取状态
*
* 负载状态
* CPU使用率
* 内存使用率
*/
function GetSystemStatus()
{
/**
* ----------负载计算开始----------
*/
$laodavg = FunShellExec("cat /proc/loadavg | awk '{print $1,$2,$3}'");
$laodavgArray = explode(' ', $laodavg);
//获取CPU15分钟前到现在的负载平均值
$cpuLoad15Min = (float)trim($laodavgArray[2]);
//获取CPU5分钟前到现在的负载平均值
$cpuLoad5Min = (float)trim($laodavgArray[1]);
//获取CPU1分钟前到现在的负载平均值
$cpuLoad1Min = (float)trim($laodavgArray[0]);
//获取cpu总核数
$cpuCount = FunShellExec('grep -c "model name" /proc/cpuinfo');
$cpuCount = (int)trim($cpuCount);
//一分钟的平均负载 / (cpu总核数 * 2),超过100则为100 不超100为真实值取整
$percent = round($cpuLoad1Min / ($cpuCount * 2) * 100);
if ($percent > 100) {
$percent = 100;
}
/**
* ----------负载计算结束----------
*/
$data['load'] = [
'cpuLoad15Min' => $cpuLoad15Min,
'cpuLoad5Min' => $cpuLoad5Min,
'cpuLoad1Min' => $cpuLoad1Min,
'percent' => $percent,
'color' => FunGetColor($percent)['color'],
'title' => FunGetColor($percent)['title']
];
/**
* ----------cpu计算开始----------
*/
/**
* cpu使用率
*
* %Cpu(s): 0.0 us, 3.2 sy, 0.0 ni, 96.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
*
* us user CPU time 用户空间占用CPU百分比
* sy system CPU time 内核空间占用CPU百分比
* ni nice CPU 用户进程空间内改变过优先级的进程占用CPU百分比
* id idle 空闲CPU百分比
* wa iowait 等待输入输出的CPU时间百分比
* hi hardware 硬件中断
* si software 软件中断
* st steal 实时
*/
$topResult = FunShellExec('top -b -n 1 | grep Cpu');
preg_match('/ni,(.*?)id/', $topResult, $matches);
$id = 100 - (float)trim($matches[1]);
//cpu型号
$cpuModelArray = [];
$cpuModelName = FunShellExec("cat /proc/cpuinfo | grep 'model name' | uniq");
$explodeArray = explode("\n", trim($cpuModelName));
foreach ($explodeArray as $value) {
if (trim($value) != '') {
$tempArray = explode(':', $value);
array_push($cpuModelArray, trim($tempArray[1]));
}
}
//物理cpu个数
$cpuPhysical = FunShellExec("cat /proc/cpuinfo | grep 'physical id' | sort -u | wc -l");
$cpuPhysical = (int)trim($cpuPhysical);
//每个物理cpu的物理核心数
$cpuPhysicalCore = FunShellExec("cat /proc/cpuinfo | grep 'cpu cores' | wc -l");
$cpuPhysicalCore = (int)trim($cpuPhysicalCore);
//总物理核心数 = 物理cpu个数 * 每个物理cpu的物理核心数(每个物理cpu的物理核心数都一样吗?)
$cpuCore = $cpuPhysical * $cpuPhysicalCore;
//逻辑核心总数(线程总数)
$cpuProcessor = FunShellExec("cat /proc/cpuinfo | grep 'processor' | wc -l");
$cpuProcessor = (int)trim($cpuProcessor);
/**
* ----------cpu计算结束----------
*/
$data['cpu'] = [
'percent' => $id,
'cpu' => $cpuModelArray,
'cpuPhysical' => $cpuPhysical,
'cpuPhysicalCore' => $cpuPhysicalCore,
'cpuCore' => $cpuCore,
'cpuProcessor' => $cpuProcessor,
'color' => FunGetColor($id)['color']
];
/**
* ----------内存计算开始----------
*/
/**
* MemTotal 总内存
* MemFree 空闲内存
* MemAvailable 可用内存(MemFree + 可回收的内存),系统中有些内存虽然已被使用但是可以回收,比如cache、buffer、slab都有一部分可以回收
*/
//物理内存总量
$memTotal = FunShellExec("cat /proc/meminfo | grep 'MemTotal' | awk '{print $2}'");
$memTotal = (int)trim($memTotal);
//操作系统可用内存总量(没有使用空闲内存)
$memFree = FunShellExec("cat /proc/meminfo | grep 'MemAvailable' | awk '{print $2}'");
$memFree = (int)trim($memFree);
//操作系统已使用内存总量
$memUsed = $memTotal - $memFree;
//内存使用率
$percent = round($memUsed / $memTotal * 100);
/**
* ----------内存计算结束----------
*/
$data['mem'] = [
'memTotal' => round($memTotal / 1024),
'memUsed' => round($memUsed / 1024),
'memFree' => round($memFree / 1024),
'percent' => $percent,
'color' => FunGetColor($percent)['color']
];
FunMessageExit(200, 1, '成功', $data);
}
/**
* 获取硬盘
*
* 获取硬盘数量和每个硬盘的详细信息
*/
function GetDisk()
{
$rs = FunShellExec('df -lh | grep -E "^(/)"');
//将多个连续的空格换为一个
$result = preg_replace("/\s{2,}/", ' ', $rs);
//多个硬盘
$diskArray = explode("\n", $result);
$data = [];
//处理
foreach ($diskArray as $value) {
if (trim($value) != '') {
$diskInfo = explode(" ", $value);
array_push($data, [
'fileSystem' => $diskInfo[0],
'size' => $diskInfo[1],
'used' => $diskInfo[2],
'avail' => $diskInfo[3],
'percent' => (int)str_replace('%', '', $diskInfo[4]),
'mountedOn' => $diskInfo[5],
'color' => FunGetColor((int)str_replace('%', '', $diskInfo[4]))['color']
]);
}
}
FunMessageExit(200, 1, '成功', $data);
}
/**
* 获取统计
*
* 操作系统类型
* 仓库占用体积
* SVN仓库数量
* SVN用户数量
* SVN分组数量
* 计划任务数量
* 运行日志数量
*/
function GetSystemAnalysis()
{
//操作系统类型和版本
$os = FunShellExec("cat /etc/redhat-release");
//仓库占用体积
$repSize = FunFormatSize(FunGetDirSizeDu(SVN_REPOSITORY_PATH));
//SVN仓库数量
$repCount = count(FunGetSimpleRepList());
//SVN用户数量
$userCount = count(FunGetSvnUserList(SVN_PASSWD_FILE));
//SVN分组数量
$groupCount = count(FunGetSvnGroupList(SVN_AUTHZ_FILE));
//运行日志数量
$logCount = $this->database->count('logs', ['log_id[>]' => 0]);
FunMessageExit(200, 1, '成功', [
'os' => trim($os),
'repSize' => $repSize,
'repCount' => $repCount,
'repUser' => $userCount,
'repGroup' => $groupCount,
'logCount' => $logCount
]);
}
}

196
02.php/app/controller/subversion.class.php

@ -0,0 +1,196 @@ @@ -0,0 +1,196 @@
<?php
class subversion extends controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
/**
* 获取Subversion运行状态 用于页头提醒
*/
function GetStatus()
{
$result = FunShellExec("ps auxf | grep -v 'grep' | grep svnserve");
if (trim($result) == ISNULL) {
FunMessageExit(200, 0, '请注意 subversion服务并未以daemon方式运行! 如果非人为操作,请及时检查原因!');
} else {
FunMessageExit();
}
}
/**
* 获取Subversion的检出地址前缀
*
* 先从Subversion配置文件获取绑定端口和主机
* 然后与listen.json配置文件中的端口和主机进行对比和同步
*/
function GetCheckout()
{
$result = FunGetSubversionListen();
$checkoutHost = $result[$result['enable']];
if ($result['bindPort'] != '3690') {
$checkoutHost .= ':' . $result['bindPort'];
}
FunMessageExit(200, 1, '成功', [
'protocal' => 'svn://',
'prefix' => $checkoutHost
]);
}
/**
* 获取Subversion的详细信息
*/
function GetDetail()
{
//获取绑定主机、端口等信息
$bindInfo = FunGetSubversionListen();
//检测运行信息
$runInfo = FunShellExec('ps auxf|grep -v "grep"|grep svnserve');
//检测安装信息
$installInfo = file_exists('/usr/bin/svnserve');
//检测安装状态
//未知状态
$installInfo = -1;
if ($runInfo == ISNULL && !$installInfo) {
//未安装
$installed = 0;
} else if ($runInfo == ISNULL && $installInfo) {
//安装未启动
$installed = 1;
} else if ($runInfo != ISNULL && $installInfo) {
//运行中
$installed = 2;
}
//检测subversion版本
$version = '-';
if ($installed != 0) {
$versionInfo = FunShellExec('svnserve --version');
preg_match_all(REG_SUBVERSION_VERSION, $versionInfo, $versionInfoPreg);
if (array_key_exists(0, $versionInfoPreg[0])) {
$version = trim($versionInfoPreg[1][0]);
} else {
$version = '-';
}
}
FunMessageExit(200, 1, '成功', [
'version' => $version,
'installed' => $installed,
'bindPort' => $bindInfo['bindPort'],
'bindHost' => $bindInfo['bindHost'],
'manageHost' => $bindInfo['manageHost'],
'enable' => $bindInfo[$bindInfo['enable']],
'svnserveLog' => SVNSERVE_LOG_FILE
]);
}
/**
* 安装SVN
*/
function Install()
{
}
/**
* 卸载SVN
*/
function UnInstall()
{
}
/**
* 启动SVN
*/
function Start()
{
}
/**
* 停止SVN
*/
function Stop()
{
}
/**
* 修改svnserve的绑定端口
*/
function EditPort()
{
}
/**
* 修改svnserve的绑定主机
*/
function EditHost()
{
}
/**
* 修改管理系统主机名
*/
function EditManageHost()
{
}
/**
* 修改检出地址
*/
function EditEnable()
{
}
/**
* 查看svnserve运行日志
*/
function ViewSvnserveLog()
{
}
/**
* 获取配置文件列表
*/
function GetConfig()
{
FunMessageExit(200, 1, '成功', [
[
'key' => 'SVN仓库父目录',
'value' => SVN_REPOSITORY_PATH
],
[
'key' => 'svnserve环境变量文件',
'value' => SVNSERVE_ENV_FILE
],
[
'key' => 'SVN仓库权限配置文件',
'value' => SVN_CONF_FILE
],
[
'key' => 'authz文件',
'value' => SVN_AUTHZ_FILE
],
[
'key' => 'passwd文件',
'value' => SVN_PASSWD_FILE
],
[
'key' => '备份文件夹',
'value' => SVN_BACHUP_PATH
],
]);
}
}

16
02.php/app/controller/svnadmin.class.php

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
<?php
class svnadmin extends controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
}

491
02.php/app/controller/svngroup.class.php

@ -0,0 +1,491 @@ @@ -0,0 +1,491 @@
<?php
class svngroup extends controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
/**
* 将SVN分组数据同步到数据库
*
* 同时同步每个分组包含的用户数量
*/
function SyncGroupToDb()
{
$svnAndGroupList = FunGetSvnGroupUserAndGroupList($this->globalAuthzContent);
if ($svnAndGroupList == 0) {
FunMessageExit(200, 0, '文件格式错误(不存在[groups]标识)');
}
$svnGroupList = FunArrayColumn($svnAndGroupList, 'groupName');
$dbGroupPassList = $this->database->select('svn_groups', [
'svn_group_id',
'svn_group_name',
'svn_group_note',
'include_user_count',
'include_group_count'
]);
$combinArray = array_combine(FunArrayColumn($svnAndGroupList, 'groupName'), FunArrayColumn($svnAndGroupList, 'include'));
// FunMessageExit(200,0,'调试',$combinArray);
foreach ($dbGroupPassList as $key => $value) {
if (!in_array($value['svn_group_name'], $svnGroupList)) {
$this->database->delete('svn_groups', [
'svn_group_name' => $value['svn_group_name']
]);
} else {
//更新数量
$this->database->update('svn_groups', [
'include_user_count' => count($combinArray[$value['svn_group_name']]['users']),
'include_group_count' => count($combinArray[$value['svn_group_name']]['groups']),
], [
'svn_group_name' => $value['svn_group_name']
]);
}
}
foreach ($svnGroupList as $key => $value) {
if (!in_array($value, FunArrayColumn($dbGroupPassList, 'svn_group_name'))) {
$this->database->insert('svn_groups', [
'svn_group_name' => $value,
'include_user_count' => count($svnAndGroupList[$key]['include']['users']),
'include_group_count' => count($svnAndGroupList[$key]['include']['groups']),
'svn_group_note' => '',
]);
}
}
}
/**
* 获取所有的分组列表
*/
function GetAllGroupList()
{
$svnGroupList = FunGetSvnGroupList($this->globalAuthzContent);
if ($svnGroupList == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[groups]标识)');
} else {
$newArray = [];
foreach ($svnGroupList as $key => $value) {
array_push($newArray, [
'groupName' => $value
]);
}
FunMessageExit(200, 1, '成功', $newArray);
}
}
/**
* 获取带有分页的分组列表
*/
function GetGroupList()
{
//同步
$this->SyncGroupToDb();
$pageSize = $this->requestPayload['pageSize'];
$currentPage = $this->requestPayload['currentPage'];
$searchKeyword = trim($this->requestPayload['searchKeyword']);
//分页
$begin = $pageSize * ($currentPage - 1);
$list = $this->database->select('svn_groups', [
'svn_group_id',
'svn_group_name',
'svn_group_note',
'include_user_count',
'include_group_count'
], [
'AND' => [
'OR' => [
'svn_group_name[~]' => $searchKeyword,
'svn_group_note[~]' => $searchKeyword,
],
],
'LIMIT' => [$begin, $pageSize],
'ORDER' => [
$this->requestPayload['sortName'] => strtoupper($this->requestPayload['sortType'])
]
]);
$total = $this->database->count('svn_groups', [
'svn_group_id'
], [
'AND' => [
'OR' => [
'svn_group_name[~]' => $searchKeyword,
'svn_group_note[~]' => $searchKeyword,
],
],
]);
FunMessageExit(200, 1, '成功', [
'data' => $list,
'total' => $total
]);
}
/**
* 编辑分组备注信息
*/
function EditGroupNote()
{
$this->database->update('svn_groups', [
'svn_group_note' => $this->requestPayload['svn_group_note']
], [
'svn_group_name' => $this->requestPayload['svn_group_name']
]);
FunMessageExit();
}
/**
* 新建SVN分组
*/
function CreateGroup()
{
//检查分组名是否合法
FunCheckRepGroup($this->requestPayload['svn_group_name']);
//检查用户是否已存在
$result = FunAddSvnGroup($this->globalAuthzContent, $this->requestPayload['svn_group_name']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[groups]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '分组已存在');
}
//写入配置文件
FunShellExec('echo \'' . $result . '\' > ' . SVN_AUTHZ_FILE);
//写入数据库
$this->database->insert('svn_groups', [
'svn_group_name' => $this->requestPayload['svn_group_name'],
'include_user_count' => 0,
'include_group_count' => 0,
'svn_group_note' => ''
]);
FunMessageExit();
}
/**
* 删除SVN分组
*/
function DelGroup()
{
//从authz文件删除
$result = FunDelSvnGroup($this->globalAuthzContent, $this->requestPayload['svn_group_name']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[groups]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '分组不存在');
}
FunShellExec('echo \'' . $result . '\' > ' . SVN_AUTHZ_FILE);
//从数据库删除
$this->database->delete('svn_groups', [
'svn_group_name' => $this->requestPayload['svn_group_name']
]);
FunMessageExit();
}
/**
* 修改SVN分组的名称
*/
function EditGroupName()
{
//新分组名称是否合法
FunCheckRepGroup($this->requestPayload['groupNameNew']);
$svnGroupList = FunGetSvnGroupList($this->globalAuthzContent);
//旧分组是否存在
if (!in_array($this->requestPayload['groupNameOld'], $svnGroupList)) {
FunMessageExit(200, 0, '当前分组不存在');
}
//新分组名称是否冲突
if (in_array($this->requestPayload['groupNameNew'], $svnGroupList)) {
FunMessageExit(200, 0, '要修改的分组名称已经存在');
}
$result = FunUpdSvnGroup($this->globalAuthzContent, $this->requestPayload['groupNameOld'], $this->requestPayload['groupNameNew']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[groups]标识)');
}
FunShellExec('echo \'' . $result . '\' > ' . SVN_AUTHZ_FILE);
FunMessageExit();
}
/**
* 获取SVN分组的用户成员和分组成员
*/
function GetGroupMember()
{
$memberUserList = FunGetSvnUserListByGroup($this->globalAuthzContent, $this->requestPayload['svn_group_name']);
$memberGroupList = FunGetSvnGroupListByGroup($this->globalAuthzContent, $this->requestPayload['svn_group_name']);
$allGroupList = FunGetSvnGroupList($this->globalAuthzContent);
$allUserList = FunGetSvnUserList($this->globalPasswdContent);
if ($memberUserList == '0' || $memberGroupList == '0' || $allGroupList == '0' || $allUserList == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[groups]标识)');
}
if ($memberUserList == '1' || $memberGroupList == '1' || $allUserList == '1') {
FunMessageExit(200, 0, '分组不存在');
}
$group1 = [];
foreach ($allGroupList as $key => $value) {
if (in_array($value, $memberGroupList)) {
array_push($group1, [
'groupName' => $value,
'isMember' => true
]);
} else {
array_push($group1, [
'groupName' => $value,
'isMember' => false
]);
}
}
//排序
array_multisort(FunArrayColumn($group1, 'isMember'), SORT_DESC, $group1);
$group2 = [];
foreach ($allUserList as $key => $value) {
if (in_array($value['userName'], $memberUserList)) {
array_push($group2, [
'userName' => $value['userName'],
'isMember' => true,
'disabled' => $value['disabled']
]);
} else {
array_push($group2, [
'userName' => $value['userName'],
'isMember' => false,
'disabled' => $value['disabled']
]);
}
}
//排序
array_multisort(FunArrayColumn($group2, 'isMember'), SORT_DESC, $group2);
FunMessageExit(200, 1, '成功', [
'userList' => $group2,
'groupList' => $group1
]);
}
/**
* 将用户添加为SVN分组的成员
*/
function GroupAddUser()
{
$result = FunAddSvnGroupUser($this->globalAuthzContent, $this->requestPayload['svn_group_name'], $this->requestPayload['svn_user_name']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[groups]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '分组不存在');
}
if ($result == '2') {
FunMessageExit(200, 0, '要添加的用户已存在该分组');
}
FunShellExec('echo \'' . $result . '\' > ' . SVN_AUTHZ_FILE);
FunMessageExit();
}
/**
* 将用户从SVN分组的成员移除
*/
function GroupRemoveUser()
{
$result = FunDelSvnGroupUser($this->globalAuthzContent, $this->requestPayload['svn_group_name'], $this->requestPayload['svn_user_name']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[groups]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '分组不存在');
}
if ($result == '2') {
FunMessageExit(200, 0, '要删除的用户不在该分组');
}
FunShellExec('echo \'' . $result . '\' > ' . SVN_AUTHZ_FILE);
FunMessageExit();
}
/**
* 将分组添加为SVN分组的成员
*/
function GroupAddGroup()
{
$result = FunAddSvnGroupGroup($this->globalAuthzContent, $this->requestPayload['svn_group_name'], $this->requestPayload['svn_group_name_add']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[groups]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '分组不存在');
}
if ($result == '2') {
FunMessageExit(200, 0, '要添加的分组已存在该分组');
}
if ($result == '3') {
FunMessageExit(200, 0, '不能添加本身');
}
//检查是否存在分组循环嵌套问题
//获取分组所在的所有分组
$groupGroupList = $this->GetSvnGroupAllGroupList($this->requestPayload['svn_group_name']);
if (in_array($this->requestPayload['svn_group_name_add'], $groupGroupList)) {
FunMessageExit(200, 0, '存在分组循环嵌套的情况');
}
FunShellExec('echo \'' . $result . '\' > ' . SVN_AUTHZ_FILE);
FunMessageExit();
}
/**
* 将分组从SVN分组的成员移除
*/
function GroupRemoveGroup()
{
$result = FunDelSvnGroupGroup($this->globalAuthzContent, $this->requestPayload['svn_group_name'], $this->requestPayload['svn_group_name_del']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[groups]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '分组不存在');
}
if ($result == '2') {
FunMessageExit(200, 0, '要删除的分组不在该分组');
}
FunShellExec('echo \'' . $result . '\' > ' . SVN_AUTHZ_FILE);
FunMessageExit();
}
/**
* 获取用户所在的所有分组
*
* 包括直接包含关系 如
* group1=user1
*
* 和间接包含关系 如
* group1=user1
* group2=@group1
* group3=@group2
* group4=@group3
*/
function GetSvnUserAllGroupList($userName)
{
$authzContent = $this->globalAuthzContent;
//所有的分组列表
$allGroupList = FunGetSvnGroupList($authzContent);
//用户所在的分组列表
$userGroupList = FunGetSvnUserGroupList($authzContent, $userName);
//剩余的分组列表
$leftGroupList = array_diff($allGroupList, $userGroupList);
//循环匹配 直到匹配到与该用户相关的有权限的用户组为止
loop:
$userGroupListBack = $userGroupList;
foreach ($userGroupList as $group1) {
$newList = FunGetSvnGroupGroupList($authzContent, $group1);
foreach ($leftGroupList as $group2) {
if (in_array($group2, $newList)) {
array_push($userGroupList, $group2);
unset($leftGroupList[array_search($group2, $leftGroupList)]);
}
}
}
if ($userGroupList != $userGroupListBack) {
goto loop;
}
return $userGroupList;
}
/**
* 获取分组所在的所有分组
*
* 包括直接包含关系 如
* group2=@group1
*
* 和间接包含关系 如
* group2=@group1
* group3=@group2
* group4=@group3
*/
function GetSvnGroupAllGroupList($groupName)
{
$parentGroupName = $groupName;
$authzContent = $this->globalAuthzContent;
//所有的分组列表
$allGroupList = FunGetSvnGroupList($authzContent);
//分组所在的分组列表
$groupGroupList = FunGetSvnGroupGroupList($authzContent, $parentGroupName);
//剩余的分组列表
$leftGroupList = array_diff($allGroupList, $groupGroupList);
//循环匹配
loop:
$userGroupListBack = $groupGroupList;
foreach ($groupGroupList as $group1) {
$newList = FunGetSvnGroupGroupList($authzContent, $group1);
foreach ($leftGroupList as $group2) {
if (in_array($group2, $newList)) {
array_push($groupGroupList, $group2);
unset($leftGroupList[array_search($group2, $leftGroupList)]);
}
}
}
if ($groupGroupList != $userGroupListBack) {
goto loop;
}
return $groupGroupList;
}
}

1119
02.php/app/controller/svnrep.class.php

File diff suppressed because it is too large Load Diff

1704
02.php/app/controller/svnserve.class.php

File diff suppressed because it is too large Load Diff

291
02.php/app/controller/svnuser.class.php

@ -0,0 +1,291 @@ @@ -0,0 +1,291 @@
<?php
class svnuser extends controller
{
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
}
/**
* 将SVN用户数据同步到数据库
*
* 目的为维护用户启用状态和自定义备注信息
*/
function SyncUserToDb()
{
$svnUserPassList = FunGetSvnUserPassList($this->globalPasswdContent);
if ($svnUserPassList == 0) {
FunMessageExit(200, 0, '文件格式错误(不存在[users]标识)');
}
$dbUserPassList = $this->database->select('svn_users', [
'svn_user_id',
'svn_user_name',
'svn_user_pass',
'svn_user_status',
'svn_user_note'
]);
$combinArray1 = array_combine(FunArrayColumn($svnUserPassList, 'userName'), FunArrayColumn($svnUserPassList, 'disabled'));
$combinArray2 = array_combine(FunArrayColumn($svnUserPassList, 'userName'), FunArrayColumn($svnUserPassList, 'userPass'));
foreach ($dbUserPassList as $value) {
if (!in_array($value['svn_user_name'], FunArrayColumn($svnUserPassList, 'userName'))) {
$this->database->delete('svn_users', [
'svn_user_name' => $value['svn_user_name']
]);
} else {
//更新启用状态和密码
$this->database->update('svn_users', [
'svn_user_pass' => $combinArray2[$value['svn_user_name']],
'svn_user_status' => !$combinArray1[$value['svn_user_name']]
], [
'svn_user_name' => $value['svn_user_name']
]);
}
}
foreach ($svnUserPassList as $value) {
if (!in_array($value['userName'], FunArrayColumn($dbUserPassList, 'svn_user_name'))) {
$this->database->insert('svn_users', [
'svn_user_name' => $value['userName'],
'svn_user_pass' => $value['userPass'],
'svn_user_status' => !$value['disabled'],
'svn_user_note' => ''
]);
}
}
}
/**
* 获取全部的SVN用户
*
* 只包含用户名和启用状态
*/
function GetAllUserList()
{
$svnUserList = FunGetSvnUserList($this->globalPasswdContent);
if ($svnUserList == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[users]标识)');
} else {
FunMessageExit(200, 1, '成功', $svnUserList);
}
}
/**
* 获取带有分页的SVN用户
*
* 只包含用户名和启用状态
*/
function GetUserList()
{
//将SVN用户数据同步到数据库
$this->SyncUserToDb();
$pageSize = $this->requestPayload['pageSize'];
$currentPage = $this->requestPayload['currentPage'];
$searchKeyword = trim($this->requestPayload['searchKeyword']);
//分页
$begin = $pageSize * ($currentPage - 1);
$list = $this->database->select('svn_users', [
'svn_user_id',
'svn_user_name',
'svn_user_pass',
'svn_user_status',
'svn_user_note'
], [
'AND' => [
'OR' => [
'svn_user_name[~]' => $searchKeyword,
// 'svn_user_pass[~]' => $searchKeyword,
'svn_user_note[~]' => $searchKeyword,
],
],
'LIMIT' => [$begin, $pageSize],
'ORDER' => [
$this->requestPayload['sortName'] => strtoupper($this->requestPayload['sortType'])
]
]);
$total = $this->database->count('svn_users', [
'svn_user_id'
], [
'AND' => [
'OR' => [
'svn_user_name[~]' => $searchKeyword,
// 'svn_user_pass[~]' => $searchKeyword,
'svn_user_note[~]' => $searchKeyword,
],
],
]);
foreach ($list as $key => $value) {
$list[$key]['svn_user_status'] = $value['svn_user_status'] == '1' ? true : false;
}
FunMessageExit(200, 1, '成功', [
'data' => $list,
'total' => $total
]);
}
/**
* 启用SVN用户
*/
function EnableUser()
{
$result = FunEnabledUser($this->globalPasswdContent, $this->requestPayload['svn_user_name']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[users]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '要启用的用户不存在');
}
FunShellExec('echo \'' . $result . '\' > ' . SVN_PASSWD_FILE);
FunMessageExit();
}
/**
* 禁用SVN用户
*/
function DisableUser()
{
$result = FunDisabledUser($this->globalPasswdContent, $this->requestPayload['svn_user_name']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[users]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '要禁用的用户不存在');
}
FunShellExec('echo \'' . $result . '\' > ' . SVN_PASSWD_FILE);
FunMessageExit();
}
/**
* 修改SVN用户的备注信息
*/
function EditUserNote()
{
$this->database->update('svn_users', [
'svn_user_note' => $this->requestPayload['svn_user_note']
], [
'svn_user_name' => $this->requestPayload['svn_user_name']
]);
FunMessageExit();
}
/**
* 新建SVN用户
*/
function CreateUser()
{
//检查用户名是否合法
FunCheckRepUser($this->requestPayload['svn_user_name']);
//检查用户是否已存在
$result = FunAddSvnUser($this->globalPasswdContent, $this->requestPayload['svn_user_name'], $this->requestPayload['svn_user_pass']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[users]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '用户已存在');
}
//检查密码是否不为空
if (trim($this->requestPayload['svn_user_pass']) == '') {
FunMessageExit(200, 0, '密码不能为空');
}
//写入配置文件
FunShellExec('echo \'' . $result . '\' > ' . SVN_PASSWD_FILE);
//写入数据库
$this->database->insert('svn_users', [
'svn_user_name' => $this->requestPayload['svn_user_name'],
'svn_user_pass' => $this->requestPayload['svn_user_pass'],
'svn_user_status' => 1,
'svn_user_note' => ''
]);
FunMessageExit();
}
/**
* 修改SVN用户的密码
*/
function EditUserPass()
{
//检查用户是否已存在
$result = FunUpdSvnUserPass($this->globalPasswdContent, $this->requestPayload['svn_user_name'], $this->requestPayload['svn_user_pass'], !$this->requestPayload['svn_user_status']);
if ($result == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[users]标识)');
}
if ($result == '1') {
FunMessageExit(200, 0, '用户不存在 请刷新重试');
}
//检查密码是否不为空
if (trim($this->requestPayload['svn_user_pass']) == '') {
FunMessageExit(200, 0, '密码不能为空');
}
//写入配置文件
FunShellExec('echo \'' . $result . '\' > ' . SVN_PASSWD_FILE);
//写入数据库
$this->database->update('svn_users', [
'svn_user_pass' => $this->requestPayload['svn_user_pass'],
], [
'svn_user_name' => $this->requestPayload['svn_user_name']
]);
FunMessageExit();
}
/**
* 删除SVN用户
*/
function DelUser()
{
//从passwd文件中全局删除
$resultPasswd = FunDelSvnUserPasswd($this->globalPasswdContent, $this->requestPayload['svn_user_name'], !$this->requestPayload['svn_user_status']);
if ($resultPasswd == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[users]标识)');
}
if ($resultPasswd == '1') {
FunMessageExit(200, 0, '用户不存在');
}
//从authz文件中删除
$resultAuthz = FunDelUserAuthz($this->globalAuthzContent, $this->requestPayload['svn_user_name']);
if ($resultAuthz == '0') {
FunMessageExit(200, 0, '文件格式错误(不存在[users]标识)');
}
//从数据删除
$this->database->delete('svn_users', [
'svn_user_name' => $this->requestPayload['svn_user_name']
]);
FunShellExec('echo \'' . $resultAuthz . '\' > ' . SVN_AUTHZ_FILE);
FunShellExec('echo \'' . $resultPasswd . '\' > ' . SVN_PASSWD_FILE);
FunMessageExit();
}
}

328
02.php/app/controller/system.class.php

@ -1,328 +0,0 @@ @@ -1,328 +0,0 @@
<?php
declare(strict_types=1);
/*
* 与操作系统相关的方法的封装
*/
class System extends Controller
{
private $Config;
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
$this->Config = new Config();
}
//判断操作系统类型
function GetPlatform()
{
if (!PHP_OS == 'Linux') {
$data['status'] = 0;
$data['message'] = '当前操作系统不为Linux';
return $data;
}
if (file_exists('/etc/redhat-release')) {
$info = file_get_contents('/etc/redhat-release');
if (!strstr($info, 'CentOS') && (strstr($info, '8.') || strstr($info, '7.'))) {
$data['status'] = 0;
$data['message'] = '当前Linux操作系统版本不符合要求';
return $data;
}
$data['status'] = 1;
$data['message'] = '成功';
$data['platform'] = 'CentOS';
return $data;
} elseif (file_exists('etc/lsb-release')) {
$info = file_get_contents('etc/lsb-release');
if (1) {
$data['status'] = 0;
$data['message'] = '当前操作系统不受支持';
return $data;
}
$data['status'] = 1;
$data['message'] = '成功';
$data['platform'] = 'Ubuntu';
return $data;
} else {
$data['status'] = 0;
$data['message'] = '当前操作系统不受支持';
return $data;
}
}
//获取磁盘信息,如果有多块磁盘如何处理,可以只显示某个目录如根目录对应的磁盘容量
function GetDiskInfo($requestPayload)
{
$info['DiskTotal'] = round(disk_total_space(".") / 1024 / 1024 / 1024, 1);
$info['DiskFree'] = round(disk_free_space(".") / 1024 / 1024 / 1024, 1);
$info['DiskUsed'] = round($info['DiskTotal'] - $info['DiskFree'], 1);
$info['DiskPercent'] = ($info['DiskTotal'] != 0) ? round($info['DiskUsed'] / $info['DiskTotal'] * 100, 1) : 0;
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $info;
return $data;
}
//获取服务器运行时间
function GetServerUpTime($requestPayload)
{
$temp = file_get_contents('/proc/uptime');
$info = explode(" ", $temp);
$info = trim($info[0]); //系统自启动开始的秒数
$min = $info / 60;
$hours = $min / 60;
$days = floor($hours / 24);
$hours = floor($hours - ($days * 24));
$min = floor($min - ($days * 60 * 24) - ($hours * 60));
$info = $days . "天" . $hours . "小时" . $min . "分钟";
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $info;
return $data;
}
//计算CPU使用率
/*
* 第一行为CPU总情况 只需要第一行的值
* cpu 2032004 102648 238344 167130733 758440 1515917878 0
*
* user 2032004 从系统启动开始累计到当前时刻,用户态的CPU时间,不包含nice值为负进程
* nice 102648 从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间
* system 238344 从系统启动开始累计到当前时刻,核心时间
* idle 167130733 从系统启动开始累计到当前时刻,除IO等待时间以外其它等待时间
* iowait 758440 从系统启动开始累计到当前时刻,IO等待时间
* irq 1515917878 从系统启动开始累计到当前时刻,硬中断时间
* softirq 0 从系统启动开始累计到当前时刻,软中断时间
*/
//GetCPURate GetCPUInfo
function GetCPURate($requestPayload)
{
//第一次取值
$array = file('/proc/stat');
if (!$array)
return false;
$array = explode(' ', trim(str_replace('cpu', '', trim($array[0]))));
$total_time_1 = $array[0] + $array[1] + $array[2] + $array[3] + $array[4] + $array[5] + $array[6];
$fiee_time_1 = $array[3];
sleep(1);
//第二次取值
$array = file('/proc/stat');
if (!$array)
return false;
$array = explode(' ', trim(str_replace('cpu', '', trim($array[0]))));
$total_time_2 = $array[0] + $array[1] + $array[2] + $array[3] + $array[4] + $array[5] + $array[6];
$fiee_time_2 = $array[3];
//计算
$result['percent'] = round(round(1.00 - ($fiee_time_2 - $fiee_time_1) / ($total_time_2 - $total_time_1), 2) * 100, 1);
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $result;
return $data;
}
//获取内存信息
function GetMemInfo($requestPayload)
{
$array = file('/proc/meminfo');
if (!$array)
return false;
foreach ($array as $key => $value) {
$array[$key] = trim($value);
}
foreach ($array as $key => $value) {
$a = explode(':', $value);
$k = trim($a[0]);
$v = trim(str_replace('kB', '', trim($a[1])));
$info[$k] = $v;
}
$MemTotal = $info['MemTotal']; //总内存
$MemFree = $info['MemFree']; //空闲内存
$MeUsed = $MemTotal - $MemFree; //已使用内存
$Buffers = $info['Buffers']; //buffer
$Cached = $info['Cached']; //cache
$MemRealUsed = $MemTotal - $MemFree - $Buffers - $Cached; //真实已使用内存
$MemRealFree = $MemTotal - $MemRealUsed; //真实空闲内存
$MemAvailable = $info['MemAvailable'];
$result['total'] = round($MemTotal / 1024, 1);
$result['free'] = round($MemRealFree / 1024, 1);
$result['used'] = round($MemRealUsed / 1024, 1);
$result['percent'] = round($MemRealUsed / $MemTotal * 100, 1);
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $result;
return $data;
}
//获取系统平均负载,有问题未修复
function GetLoadAvg($requestPayload)
{
//获取系统总核心数
$array = file('/proc/cpuinfo');
if (!$array)
return false;
foreach ($array as $key => $value) {
if (strstr($value, "cpu cores")) {
$result['cpu_cores'] = trim((explode(":", $value))[1]);
break;
}
}
//获取平均负载
$array = file("/proc/loadavg");
if (!$array) {
return false;
}
$info = explode(" ", implode("", $array));
//负载百分比 = 最近一分钟负载/CPU核心数*100%
$result['minute_1_avg'] = '最近1分钟平均负载:' . round((float)$info[0], 2);
$result['minute_5_avg'] = '最近5分钟平均负载:' . round((float)$info[1], 2);
$result['minute_15_avg'] = '最近15分钟平均负载:' . round((float)$info[2], 2);
$result['avg_percent'] = round(($info[0] / $result['cpu_cores']) * 100, 2);
$result['avg_percent'] = $result['avg_percent'] >= 100 ? 100 : $result['avg_percent'];
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $result;
return $data;
}
//根据网卡名称获取实时网速 动态更新使用
function GetNetworkByName($requestPayload)
{
$network_name = $requestPayload['network_name'];
//获取时间 作为x坐标轴数据
$time = date("H:i:s");
$sleeptime = 1;
//获取时间差值
$info1 = $this->GetSingleNetwork($network_name);
sleep($sleeptime);
$info2 = $this->GetSingleNetwork($network_name);
//计算
$result = [];
foreach ($info1 as $key => $value) {
$result[$key]['name'] = $value['name'];
$result[$key]['data'][0]['ReceiveSpeed'] = ($info2[$key]['Receive']['bytes'] - $info1[$key]['Receive']['bytes']) / $sleeptime / 1024; //1s内的网络速度 单位 kbps
$result[$key]['data'][0]['TransmitSpeed'] = ($info2[$key]['Transmit']['bytes'] - $info1[$key]['Transmit']['bytes']) / $sleeptime / 1024; //1s内的网络速度 单位 kbps
$result[$key]['data'][0]['time'] = $time;
}
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $result;
return $data;
}
//获取网卡实时网速 第一次加载时使用
function GetNetwork($requestPayload)
{
//获取时间 作为x坐标轴数据
$time = date("H:i:s");
$sleeptime = 1;
//获取时间差值
$info1 = $this->GetSingleNetwork("");
sleep($sleeptime);
$info2 = $this->GetSingleNetwork("");
//计算
$result = [];
foreach ($info1 as $key => $value) {
// $result[$key]['name'] = $value['name'];
$result[$value['name']][0]['ReceiveSpeed'] = ($info2[$key]['Receive']['bytes'] - $info1[$key]['Receive']['bytes']) / $sleeptime / 1024; //1s内的网络速度 单位 kbps
$result[$value['name']][0]['TransmitSpeed'] = ($info2[$key]['Transmit']['bytes'] - $info1[$key]['Transmit']['bytes']) / $sleeptime / 1024; //1s内的网络速度 单位 kbps
$result[$value['name']][0]['time'] = $time;
}
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = $result;
return $data;
}
//获取单次网卡的流量
private function GetSingleNetwork($network_name)
{
/*
* bytes 接口发送或接收的数据的总字节数
* packets 接口发送或接收的数据包总数
* errs 由设备驱动程序检测到的发送或接收错误的总数
* drop 设备驱动程序丢弃的数据包总数
* fifo FIFO缓冲区错误的数量
* frame 分组帧错误的数量
* colls 接口上检测到的冲突数
* compressed 设备驱动程序发送或接收的压缩数据包数
* carrier 由设备驱动程序检测到的载波损耗的数量
* multicast 设备驱动程序发送或接收的多播帧数
*/
//$network_name为空表示获取除了本地回环外的所有网卡
$networklist = [];
$info = file("/proc/net/dev");
//删除不是网卡的元素
foreach ($info as $key => $value) {
if (strstr($value, 'Receive') || strstr($value, 'bytes')) {
unset($info[$key]);
continue;
}
$info[$key] = trim($info[$key]);
}
//格式化
$templist = [];
foreach ($info as $key => $value) {
$temp = explode(' ', $value);
foreach ($temp as $key2 => $value2) {
if ($value2 == '') {
unset($temp[$key2]);
continue;
}
$temp[$key2] = trim($temp[$key2]);
}
array_push($templist, array_values($temp));
}
$temp = [];
//格式化
foreach ($templist as $key => $value) {
//去除网卡名称中的冒号
$value[0] = str_replace(':', '', $value[0]);
//删除本地回环口lo的数据
// if ($value[0] == 'lo') {
// continue;
// }
//只保留特定的网卡
if ($network_name != '') {
if ($value[0] != $network_name) {
continue;
}
}
//网卡名称
$temp['name'] = $value[0];
//Receive 接收
$temp['Receive']['bytes'] = $value[1]; //总接收
//Transmit 发送
$temp['Transmit']['bytes'] = $value[9]; //总发送
//存入数组
array_push($networklist, $temp);
}
return $networklist;
}
}

25
02.php/app/controller/update.class.php

@ -1,12 +1,6 @@ @@ -1,12 +1,6 @@
<?php
declare(strict_types=1);
/*
* 与系统更新操作相关
*/
class Update extends Controller
class update extends controller
{
function __construct()
{
@ -18,23 +12,24 @@ class Update extends Controller @@ -18,23 +12,24 @@ class Update extends Controller
/*
* 其它自定义操作
*/
$this->Config = new Config();
// $this->Config = new Config();
}
/**
* 获取当前版本信息
*/
function GetVersionInfo($requestPayload)
function GetVersion()
{
$data['status'] = 1;
$data['message'] = '成功';
$data['data'] = array(
return [
'status' => 1,
'message' => '成功',
'data' => [
'current_verson' => VERSION,
'github' => 'https://github.com/witersen/svnAdminV2.0',
'gitee' => 'https://gitee.com/witersen/SvnAdminV2.0',
'author' => 'https://www.witersen.com'
);
return $data;
]
];
}
/**
@ -42,7 +37,7 @@ class Update extends Controller @@ -42,7 +37,7 @@ class Update extends Controller
*/
function CheckUpdate($requestPayload)
{
foreach (UPDATE_SERVER as $key => $value) {
foreach (unserialize(UPDATE_SERVER) as $key => $value) {
$versionInfo = FunCurlRequest($value);
if ($versionInfo != null) {
$versionInfo = json_decode($versionInfo, true);

109
02.php/app/controller/user.class.php

@ -1,109 +0,0 @@ @@ -1,109 +0,0 @@
<?php
declare(strict_types=1);
/*
* 与用户操作相关
*/
class User extends Controller
{
private $Mail;
function __construct()
{
/*
* 避免子类的构造函数覆盖父类的构造函数
*/
parent::__construct();
/*
* 其它自定义操作
*/
$this->Config = new Config();
$this->Mail = new Mail();
}
//用户登录
function Login($requestPayload)
{
$username = trim($requestPayload['username']);
$password = trim($requestPayload['password']);
if (empty($username) || empty($password)) {
$data['status'] = 0;
$data['message'] = '参数不完整';
return $data;
}
if ($username == MANAGE_USER) {
if ($password == MANAGE_PASS) {
$token = FunCreateToken($username);
//发送邮件
$time = date("Y-m-d-H-i-s");
$ip = $send_content = ""
. "登录用户:$username \n"
. "服务器已设置域名:" . SERVER_DOMAIN . " \n"
. "服务器已设置IP地址:" . SERVER_IP . " \n"
. "当前时间:$time";
$send_title = "SVN系统登录通知";
$this->Mail->SendMail($send_title, $send_content);
//返回成功信息
$data['status'] = 1;
$data['code'] = 200;
$data['username'] = $username;
$data['roleid'] = 1;
$data['rolename'] = '管理员';
$data['token'] = $token;
$data['message'] = '登录成功';
return $data;
} else {
$data['status'] = 0;
$data['message'] = '密码错误';
return $data;
}
}
$svn_user_list = FunGetSvnUserList($this->globalPasswdContent);
if (!in_array($username, array_column($svn_user_list, 'userName'))) {
$data['status'] = 0;
$data['message'] = '用户不存在';
return $data;
} else {
$svn_user_pass_list = FunGetSvnUserPassList($this->globalPasswdContent);
if ((array_column($svn_user_pass_list, 'userPass', 'userName'))[$username] == $password) {
$token = FunCreateToken($username);
//发送邮件
$time = date("Y-m-d-H-i-s");
$ip = $send_content = ""
. "登录用户:$username \n"
. "服务器已设置域名:" . SERVER_DOMAIN . " \n"
. "服务器已设置IP地址:" . SERVER_IP . " \n"
. "当前时间:$time";
$send_title = "SVN系统登录通知";
$this->Mail->SendMail($send_title, $send_content);
//返回成功信息
$data['status'] = 1;
$data['code'] = 200;
$data['userid'] = 0;
$data['username'] = $username;
$data['roleid'] = 2;
$data['rolename'] = '用户';
$data['token'] = $token;
$data['message'] = '登录成功';
return $data;
} else {
$data['status'] = 0;
$data['message'] = '密码错误';
return $data;
}
}
$data['status'] = 0;
$data['message'] = '用户不存在';
return $data;
}
}

126
02.php/app/core/controller.class.php

@ -1,37 +1,37 @@ @@ -1,37 +1,37 @@
<?php
declare(strict_types=1);
//declare(strict_types=1);
/*
* 控制器基类,所有的控制器都要继承此类
*/
//require model
// require_once BASE_PATH . '/app/model/connModel.class.php';
require_once BASE_PATH . '/config/auto.config.php';
require_once BASE_PATH . '/config/manual.config.php';
//require config
require_once BASE_PATH . '/config/api.config.php';
require_once BASE_PATH . '/config/curl.config.php';
require_once BASE_PATH . '/config/daemon.config.php';
require_once BASE_PATH . '/config/subversion.config.php';
require_once BASE_PATH . '/config/database.config.php';
require_once BASE_PATH . '/config/reg.config.php';
require_once BASE_PATH . '/config/sign.config.php';
require_once BASE_PATH . '/config/update.config.php';
require_once BASE_PATH . '/config/version.config.php';
//require controller
require_once BASE_PATH . '/app/controller/client.class.php';
require_once BASE_PATH . '/app/controller/config.class.php';
require_once BASE_PATH . '/app/controller/crontab.class.php';
require_once BASE_PATH . '/app/controller/firewall.class.php';
require_once BASE_PATH . '/app/controller/mail.class.php';
require_once BASE_PATH . '/app/controller/svnserve.class.php';
require_once BASE_PATH . '/app/controller/system.class.php';
require_once BASE_PATH . '/app/controller/user.class.php';
require_once BASE_PATH . '/app/controller/update.class.php';
//require model
require_once BASE_PATH . '/app/model/conn.model.php';
//require function
require_once BASE_PATH . '/app/function/array.function.php';
require_once BASE_PATH . '/app/function/color.function.php';
require_once BASE_PATH . '/app/function/config.function.php';
require_once BASE_PATH . '/app/function/curl.function.php';
require_once BASE_PATH . '/app/function/file.function.php';
require_once BASE_PATH . '/app/function/json.function.php';
require_once BASE_PATH . '/app/function/regular.function.php';
require_once BASE_PATH . '/app/function/return.function.php';
require_once BASE_PATH . '/app/function/socket.function.php';
require_once BASE_PATH . '/app/function/string.function.php';
require_once BASE_PATH . '/app/function/subversion.function.php';
require_once BASE_PATH . '/app/function/svnGroup.function.php';
require_once BASE_PATH . '/app/function/svnHooks.function.php';
require_once BASE_PATH . '/app/function/svnRep.function.php';
@ -39,30 +39,100 @@ require_once BASE_PATH . '/app/function/svnUser.function.php'; @@ -39,30 +39,100 @@ require_once BASE_PATH . '/app/function/svnUser.function.php';
require_once BASE_PATH . '/app/function/token.function.php';
require_once BASE_PATH . '/app/function/update.function.php';
//require controller
require_once BASE_PATH . '/app/controller/blacktoken.class.php';
require_once BASE_PATH . '/app/controller/common.class.php';
require_once BASE_PATH . '/app/controller/logs.class.php';
require_once BASE_PATH . '/app/controller/mail.class.php';
require_once BASE_PATH . '/app/controller/personal.class.php';
require_once BASE_PATH . '/app/controller/safe.class.php';
require_once BASE_PATH . '/app/controller/statistics.class.php';
require_once BASE_PATH . '/app/controller/subversion.class.php';
require_once BASE_PATH . '/app/controller/svnadmin.class.php';
require_once BASE_PATH . '/app/controller/svngroup.class.php';
require_once BASE_PATH . '/app/controller/svnrep.class.php';
require_once BASE_PATH . '/app/controller/svnuser.class.php';
require_once BASE_PATH . '/app/controller/update.class.php';
class Controller
//require extension
require_once BASE_PATH . '/extension/Download/download.class.php';
class controller
{
public $globalUserName;
public $globalUserRoleId;
public $token;
public $globalAuthzContent;
public $globalPasswdContent;
public $requestPayload;
public $files;
public $database;
function __construct()
{
$this->globalUserName = $this->GetUserInfoByToken(MY_TOKEN)["username"];
$this->globalUserRoleId = $this->globalUserName == MANAGE_USER ? 1 : 2;
$this->globalAuthzContent = file_exists(SVN_SERVER_AUTHZ) ? file_get_contents(SVN_SERVER_AUTHZ) : '';
$this->globalPasswdContent = file_exists(SVN_SERVER_PASSWD) ? file_get_contents(SVN_SERVER_PASSWD) : '';
/**
* token
*/
global $token;
$this->token = $token;
/**
* 用户身份
*/
$this->globalUserName = $this->GetUserNameByToken();
$this->globalUserRoleId = $this->GetUserRoleByToken();
/**
* SVN配置文件相关
*/
$this->globalAuthzContent = file_exists(SVN_AUTHZ_FILE) ? file_get_contents(SVN_AUTHZ_FILE) : '';
$this->globalPasswdContent = file_exists(SVN_PASSWD_FILE) ? file_get_contents(SVN_PASSWD_FILE) : '';
/**
* 请求载体相关
*/
global $requestPayload;
$this->requestPayload = $requestPayload;
/**
* 文件
*/
global $files;
$this->files = $files;
/**
* 数据库连接
*/
$this->database = (new conn())->GetConn();
}
/**
* 根据token获取用户角色id
*/
final function GetUserRoleByToken()
{
if (!isset($this->token) || empty($this->token)) {
return '';
}
$arr = explode('.', $this->token);
return $arr[0];
}
//根据token获取用户信息
final function GetUserInfoByToken($token)
/**
* 根据token获取用户名称
*/
final function GetUserNameByToken()
{
$explode = explode('.', $token);
$data = array(
"username" => $explode[0]
);
return $data;
if (!isset($this->token) || empty($this->token)) {
return '';
}
$arr = explode('.', $this->token);
return $arr[1];
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save