Compare commits

..

25 Commits
dev ... v2.5.7

Author SHA1 Message Date
李佳航
e5a7ed8980 Merge pull request #162 from dromara/dev
Dev
2026-01-23 12:34:32 +08:00
李佳航
5162b99e3e Merge pull request #155 from dromara/dev
Dev
2025-12-15 10:14:47 +08:00
李佳航
fbf4299a61 Merge pull request #150 from dromara/dev
🔨 替换换行符.
2025-11-12 00:35:52 +08:00
李佳航
d9c8923b6d Merge pull request #149 from dromara/dev
Dev
2025-11-12 00:19:03 +08:00
李佳航
d8818c3ec2 Merge pull request #143 from dromara/dev
Dev
2025-10-21 17:04:29 +08:00
李佳航
b3daacbd8f Merge pull request #141 from dromara/dev
🚀 升级版本.
2025-10-08 10:00:02 +08:00
李佳航
bd76eb255d Merge pull request #140 from dromara/dev
Dev
2025-10-08 09:56:44 +08:00
李佳航
876e763fcc Merge pull request #139 from dromara/dev
Dev
2025-09-27 19:35:47 +08:00
李佳航
6774376418 Merge pull request #138 from dromara/dev
🔨 修改样式.
2025-09-25 01:40:40 +08:00
李佳航
cb59390fed Merge pull request #137 from dromara/dev
Dev
2025-09-25 00:59:39 +08:00
李佳航
670e40f6f0 Merge pull request #135 from dromara/dev
✏️ 修改 issues 模板.
2025-09-11 23:22:05 +08:00
李佳航
a8de5ab713 Merge pull request #134 from dromara/dev
🚑 修改 docker 配置.
2025-09-11 21:30:29 +08:00
李佳航
8d46e1d44d Merge pull request #133 from dromara/dev
🔨 修改 tsc.
2025-09-11 20:44:36 +08:00
李佳航
ca4ec20e49 Merge pull request #132 from dromara/dev
Dev
2025-09-11 20:38:27 +08:00
lijiahangmax
a0a7240191 Merge remote-tracking branch 'origin/main' 2025-08-01 12:29:14 +08:00
lijiahangmax
2b52697cdc merge dev into main
merge

Created-by: lijiahangmax
Commit-by: lijiahangmax;2022521971;autoscope;qq_23961285;hailan1024;muzi_teacher;haobo96
Merged-by: lijiahangmax
Description: update: 更新文件 README.md
update: 更新文件 README.md
merge dev into dev
update: 更新文件 README.md
merge dev into dev
...

See merge request: dromara/orion-visor!24
2025-08-01 12:25:53 +08:00
李佳航
5ab3f168d8 Merge pull request #129 from dromara/dev
✏️ 修改文档.
2025-07-19 18:52:13 +08:00
李佳航
e214fbde5c Merge pull request #128 from dromara/dev
Dev
2025-07-13 18:32:17 +08:00
李佳航
0d0eadc3bf Merge pull request #127 from dromara/dev
🐳 修改 docker 配置.
2025-07-10 15:17:18 +08:00
李佳航
edcc2cf0c8 Merge pull request #126 from dromara/dev
🐳 修改 docker 配置.
2025-07-10 14:51:48 +08:00
李佳航
7d35f839df Merge pull request #125 from dromara/dev
🐳 修改 docker 配置.
2025-07-10 14:30:21 +08:00
李佳航
f1a4e049ca Merge pull request #124 from dromara/dev
Dev
2025-07-10 03:50:05 +08:00
李佳航
3895476ff8 Merge pull request #123 from dromara/dev
🚀 优化 CI 速度.
2025-07-09 16:55:41 +08:00
李佳航
964c1daa2c Merge pull request #122 from dromara/dev
🚀 优化 CI 速度.
2025-07-09 16:51:47 +08:00
李佳航
9d06f0ae87 Merge pull request #121 from dromara/dev
Dev
2025-07-09 16:32:33 +08:00
43 changed files with 190 additions and 119 deletions

169
docker-compose-bt.yml Normal file
View File

@@ -0,0 +1,169 @@
# https://github.com/aaPanel/appstore/tree/main/apps/orion_visor
services:
orion-ui:
image: registry.cn-hangzhou.aliyuncs.com/orionsec/orion-visor-ui:latest
ports:
- ${HOST_IP}:${WEB_HTTP_PORT}:80
environment:
NGINX_SERVICE_HOST: ${NGINX_SERVICE_HOST:-orion-service}
NGINX_SERVICE_PORT: ${NGINX_SERVICE_PORT:-9200}
restart: unless-stopped
depends_on:
orion-service:
condition: service_healthy
networks:
- baota_net
orion-service:
image: registry.cn-hangzhou.aliyuncs.com/orionsec/orion-visor-service:${VERSION}
privileged: true
ports:
- "9200:9200"
environment:
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
MYSQL_HOST: orion-mysql
MYSQL_PORT: ${MYSQL_PORT:-3306}
MYSQL_DATABASE: ${MYSQL_DATABASE:-orion_visor}
MYSQL_USER: ${MYSQL_USER:-orion}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-Data@123456}
REDIS_HOST: orion-redis
REDIS_PASSWORD: ${REDIS_PASSWORD:-Data@123456}
REDIS_DATABASE: ${REDIS_DATABASE:-0}
REDIS_DATA_VERSION: ${REDIS_DATA_VERSION:-1}
INFLUXDB_ENABLED: true
INFLUXDB_HOST: orion-influxdb
INFLUXDB_PORT: ${INFLUXDB_PORT:-8086}
INFLUXDB_ORG: ${INFLUXDB_ORG:-orion-visor}
INFLUXDB_BUCKET: ${INFLUXDB_BUCKET:-metrics}
INFLUXDB_TOKEN: ${INFLUXDB_TOKEN:-Data@123456}
GUACD_HOST: orion-guacd
GUACD_PORT: ${GUACD_PORT:-4822}
GUACD_DRIVE_PATH: ${GUACD_DRIVE_PATH:-/drive}
SECRET_KEY: ${SECRET_KEY:-uQeacXV8b3isvKLK}
API_EXPOSE_TOKEN: ${API_EXPOSE_TOKEN:-pmqeHOyZaumHm0Wt}
API_IP_HEADERS: ${API_IP_HEADERS:-X-Forwarded-For,X-Real-IP}
# 这里需要改为具体的服务地址 (宿主机ip)
API_HOST: ${HOST_IP}
# 若 API_HOST 不满足, 可以修改这里 http://<ip>:<port>/orion-visor/api
API_URL: ${API_URL:-}
API_CORS: ${API_CORS:-true}
DEMO_MODE: ${DEMO_MODE:-false}
volumes:
- ${APP_PATH}/service/root-orion:/root/orion
ulimits:
nofile:
soft: 65536
hard: 65536
restart: unless-stopped
healthcheck:
test: [ "CMD", "curl", "http://127.0.0.1:9200/orion-visor/api/server/bootstrap/health" ]
interval: 15s
timeout: 300s
retries: 15
start_period: 3s
depends_on:
orion-mysql:
condition: service_healthy
orion-redis:
condition: service_healthy
orion-influxdb:
condition: service_healthy
labels:
createdBy: "bt_apps"
networks:
- baota_net
orion-mysql:
image: registry.cn-hangzhou.aliyuncs.com/orionsec/orion-visor-mysql:${VERSION}
privileged: true
environment:
- MYSQL_DATABASE=${MYSQL_DATABASE:-orion_visor}
- MYSQL_USER=${MYSQL_USER:-orion}
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-Data@123456}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-Data@123456}
volumes:
- ${APP_PATH}/mysql/var-lib-mysql:/var/lib/mysql
- ${APP_PATH}/mysql/var-lib-mysql-files:/var/lib/mysql-files
restart: unless-stopped
healthcheck:
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/3306" ]
interval: 15s
timeout: 60s
retries: 15
start_period: 3s
labels:
createdBy: "bt_apps"
networks:
- baota_net
orion-redis:
image: registry.cn-hangzhou.aliyuncs.com/orionsec/orion-visor-redis:${VERSION}
privileged: true
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD:-Data@123456}
volumes:
- ${APP_PATH}/redis/data:/data
command: sh -c "redis-server /usr/local/redis.conf --requirepass $${REDIS_PASSWORD}"
restart: unless-stopped
healthcheck:
test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]
interval: 15s
timeout: 60s
retries: 15
start_period: 3s
labels:
createdBy: "bt_apps"
networks:
- baota_net
orion-influxdb:
image: registry.cn-hangzhou.aliyuncs.com/orionsec/orion-visor-influxdb:latest
privileged: true
ports:
- "8086:8086"
environment:
DOCKER_INFLUXDB_INIT_MODE: setup
DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUXDB_ADMIN_USERNAME:-admin}
DOCKER_INFLUXDB_INIT_PASSWORD: ${INFLUXDB_ADMIN_PASSWORD:-Data@123456}
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: ${INFLUXDB_TOKEN:-Data@123456}
DOCKER_INFLUXDB_INIT_ORG: ${INFLUXDB_ORG:-orion-visor}
DOCKER_INFLUXDB_INIT_BUCKET: ${INFLUXDB_BUCKET:-metrics}
volumes:
- ${APP_PATH}/influxdb/data:/var/lib/influxdb2
- ${APP_PATH}/influxdb/config:/etc/influxdb2
restart: unless-stopped
healthcheck:
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/8086" ]
interval: 15s
timeout: 5s
retries: 10
start_period: 10s
networks:
- baota_net
orion-guacd:
image: registry.cn-hangzhou.aliyuncs.com/orionsec/orion-visor-guacd:latest
ports:
- "4822:4822"
environment:
GUACD_LOG_LEVEL: info
GUACD_LOG_FILE: /var/log/guacd.log
volumes:
- ${APP_PATH}/guacd/drive:${GUACD_DRIVE_PATH:-/drive}
- ${APP_PATH}/guacd/var-logs:/var/log
- ${APP_PATH}/guacd/local-guacamole-lib:/usr/local/guacamole/lib
- ${APP_PATH}/guacd/local-guacamole-extensions:/usr/local/guacamole/extensions
restart: unless-stopped
healthcheck:
test: [ "CMD", "nc", "-vz", "localhost", "4822" ]
interval: 15s
timeout: 5s
retries: 10
start_period: 10s
networks:
- baota_net
networks:
baota_net:
external: true

View File

@@ -135,8 +135,6 @@
}
handleClose();
return true;
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -139,8 +139,6 @@
}
handleClose();
return true;
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -25,7 +25,6 @@ package org.dromara.visor.module.infra.service.impl;
import cn.orionsec.kit.lang.define.wrapper.DataGrid;
import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists;
import cn.orionsec.kit.lang.utils.collect.Sets;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -113,22 +112,21 @@ public class DictValueServiceImpl implements DictValueService {
Long id = Assert.notNull(request.getId(), ErrorMessage.ID_MISSING);
DictValueDO record = dictValueDAO.selectById(id);
Assert.notNull(record, ErrorMessage.CONFIG_ABSENT);
// 查询 key 是否存在
DictKeyDO oldDictKey = dictKeyDAO.selectById(record.getKeyId());
DictKeyDO newDictKey = dictKeyDAO.selectById(request.getKeyId());
String key = Assert.notNull(newDictKey, ErrorMessage.CONFIG_ABSENT).getKeyName();
// 查询 dictKey 是否存在
DictKeyDO dictKey = dictKeyDAO.selectById(request.getKeyId());
String key = Assert.notNull(dictKey, ErrorMessage.CONFIG_ABSENT).getKeyName();
// 转换
DictValueDO updateRecord = DictValueConvert.MAPPER.to(request);
// 查询数据是否冲突
this.checkDictValuePresent(updateRecord);
// 更新
OperatorLogs.add(OperatorLogs.KEY_NAME, newDictKey.getKeyName());
OperatorLogs.add(OperatorLogs.KEY_NAME, dictKey.getKeyName());
OperatorLogs.add(OperatorLogs.VALUE, this.getDictValueJson(updateRecord));
updateRecord.setKeyName(key);
int effect = dictValueDAO.updateById(updateRecord);
log.info("DictValueService-updateDictValueById effect: {}", effect);
// 删除缓存
RedisStrings.delete(Sets.of(DictCacheKeyDefine.DICT_VALUE.format(key), DictCacheKeyDefine.DICT_VALUE.format(oldDictKey.getKeyName())));
RedisStrings.delete(DictCacheKeyDefine.DICT_VALUE.format(key));
// 记录历史归档
this.checkRecordHistory(updateRecord, record);
return effect;

View File

@@ -23,9 +23,9 @@
package org.dromara.visor.module.monitor.enums;
import lombok.Getter;
import org.apache.commons.collections4.map.HashedMap;
import org.dromara.visor.module.monitor.constant.MetricsConst;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -129,7 +129,7 @@ public enum MeasurementEnum {
MeasurementEnum(String measurement, boolean hasTags, Consumer<BiConsumer<String, Class<?>>> register) {
this.measurement = measurement;
this.hasTags = hasTags;
this.fields = new HashMap<>();
this.fields = new HashedMap<>();
register.accept(this.fields::put);
}

View File

@@ -4,8 +4,7 @@
:loading="loading"
:multiple="multiple"
placeholder="请选择主机"
allow-clear
allow-search />
allow-clear />
</template>
<script lang="ts">

View File

@@ -4,8 +4,7 @@
:loading="loading"
:multiple="multiple"
placeholder="请选择监控项"
allow-clear
allow-search />
allow-clear />
</template>
<script lang="ts">
@@ -39,7 +38,7 @@
// 初始化选项
const initOptions = async () => {
setLoading(true);
setLoading(true);
try {
const hosts = await cacheStore.loadHosts(props.type);
optionData.value = hosts.filter(s => !props.status || s.status === props.status)

View File

@@ -6,22 +6,7 @@
:disabled="loading"
:filter-option="labelFilter"
:allow-create="allowCreate"
placeholder="请选择配置项">
<!-- label -->
<template #label="{ data }">
<span class="option-wrapper">
<span class="label">{{ data.label }}</span>
<span class="code">{{ data.value }}</span>
</span>
</template>
<!-- 选项 -->
<template #option="{ data }">
<span class="option-wrapper">
<span class="label">{{ data.label }}</span>
<span class="code">{{ data.value }}</span>
</span>
</template>
</a-select>
placeholder="请选择配置项" />
</template>
<script lang="ts">
@@ -97,18 +82,5 @@
</script>
<style lang="less" scoped>
.option-wrapper {
display: flex;
align-items: center;
width: 100%;
.label {
margin-right: 8px;
}
.code {
font-size: 12px;
color: var(--color-text-3);
}
}
</style>

View File

@@ -127,8 +127,6 @@
// 清空
handlerClear();
emits('updated');
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -71,15 +71,17 @@ export function dateFormat(date = new Date(), pattern = YMD_HMS) {
};
let reg = /(y+)/;
if (reg.test(pattern)) {
const match = reg.exec(pattern)![1];
// @ts-ignore
const match = reg.exec(pattern)[1];
pattern = pattern.replace(match, (date.getFullYear() + '').substring(4 - match.length));
}
for (const k in o) {
let reg = new RegExp('(' + k + ')');
if (reg.test(pattern)) {
const match = reg.exec(pattern)![1];
const value = o[k as keyof typeof o];
pattern = pattern.replace(match, match.length === 1 ? String(value) : ('00' + value).slice(-match.length));
// @ts-ignore
const match = reg.exec(pattern)[1];
// @ts-ignore
pattern = pattern.replace(match, (match.length === 1) ? o[k] : ('00' + o[k]).substring(('' + o[k]).length));
}
}
return pattern;
@@ -150,7 +152,7 @@ export const resetObject = (obj: any, ignore: string[] = []) => {
export const objectTruthKeyCount = (obj: any, ignore: string[] = []) => {
return Object.keys(obj)
.filter(s => !ignore.includes(s))
.reduce(function(acc, curr) {
.reduce(function (acc, curr) {
const currVal = obj[curr];
return acc + ~~(currVal !== undefined && currVal !== null && currVal?.length !== 0 && currVal !== '');
}, 0);
@@ -197,7 +199,7 @@ export function detectZoom() {
* 获取唯一的 UUID
*/
export function getUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);

View File

@@ -137,8 +137,6 @@
// 无数据
Message.warning('当前条件未查询到数据');
}
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -182,8 +182,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -232,8 +232,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -3,7 +3,7 @@
<a-result class="result" status="403" subtitle="您没有访问该资源的权限" />
<a-space>
<a-button type="primary" @click="() => logout()">重新登录</a-button>
<a-button type="primary" @click="router.push({ name: DEFAULT_ROUTE_NAME })">返回工作台</a-button>
<a-button type="primary" @click="router.push(DEFAULT_ROUTE_NAME)">返回工作台</a-button>
</a-space>
</div>
</template>

View File

@@ -3,7 +3,7 @@
<a-result class="result" status="404" subtitle="糟糕! 页面不见了!" />
<a-space>
<a-button type="primary" @click="() => logout()">重新登录</a-button>
<a-button type="primary" @click="router.push({ name: DEFAULT_ROUTE_NAME })">返回工作台</a-button>
<a-button type="primary" @click="router.push(DEFAULT_ROUTE_NAME)">返回工作台</a-button>
</a-space>
</div>
</template>

View File

@@ -129,8 +129,6 @@
// 无数据
Message.warning('当前条件未查询到数据');
}
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -124,8 +124,6 @@
// 无数据
Message.warning('当前条件未查询到数据');
}
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -357,8 +357,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -79,8 +79,6 @@
Message.success('修改成功');
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -225,8 +225,6 @@
Message.success('已开始执行');
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -281,8 +281,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -128,8 +128,6 @@
// 无数据
Message.warning('当前条件未查询到数据');
}
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -175,8 +175,6 @@
// 无数据
Message.warning('当前条件未查询到数据');
}
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -104,8 +104,6 @@
emits('handled', { ...formModel.value });
handleClose();
return true;
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -150,8 +150,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -397,8 +397,6 @@
}
handleClose();
return true;
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -152,8 +152,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -134,8 +134,6 @@
emits('updated');
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -73,8 +73,6 @@
// 清空
handlerClear();
return true;
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -227,8 +227,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -204,8 +204,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -249,8 +249,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -211,8 +211,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -104,8 +104,6 @@
}
handleClose();
return true;
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -122,8 +122,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -126,8 +126,6 @@
}
handleClose();
return true;
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -127,8 +127,6 @@
extra: value as string
});
Message.success('保存成功');
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -161,8 +161,6 @@
// 无数据
Message.warning('当前条件未查询到数据');
}
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -122,8 +122,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -105,8 +105,6 @@
Message.success('分配成功');
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -146,8 +146,6 @@
}
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -93,8 +93,6 @@
Message.success('修改成功');
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}

View File

@@ -90,8 +90,6 @@
Message.success('修改成功');
// 清空
handlerClear();
} catch (e) {
return false;
} finally {
setLoading(false);
}