mirror of
https://github.com/snltty/linker.git
synced 2025-11-03 10:01:05 +08:00
增加模式
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project ver="10" name="cmonitor.viewer.client.win" libEmbed="true" icon="D:\desktop\cmonitor\cmonitor\favicon.ico" ui="win" output="cmonitor.viewer.client.win.exe" CompanyName="snltty" FileDescription="cmonitor.viewer.client.win" LegalCopyright="Copyright (C) snltty 2024" ProductName="cmonitor.viewer.client.win" InternalName="cmonitor.viewer.client.win" FileVersion="0.0.0.19" ProductVersion="0.0.0.19" publishDir="/dist/" dstrip="false">
|
||||
<project ver="10" name="cmonitor.viewer.client.win" libEmbed="true" icon="D:\desktop\cmonitor\cmonitor\favicon.ico" ui="win" output="cmonitor.viewer.client.win.exe" CompanyName="snltty" FileDescription="cmonitor.viewer.client.win" LegalCopyright="Copyright (C) snltty 2024" ProductName="cmonitor.viewer.client.win" InternalName="cmonitor.viewer.client.win" FileVersion="0.0.0.22" ProductVersion="0.0.0.22" publishDir="/dist/" dstrip="false">
|
||||
<file name="main.aardio" path="main.aardio" comment="main.aardio"/>
|
||||
<folder name="资源文件" path="res" embed="true"/>
|
||||
<folder name="窗体文件" path="dlg" comment="目录" embed="true"/>
|
||||
|
||||
Binary file not shown.
@@ -3,10 +3,12 @@ using cmonitor.viewer.server.win.Properties;
|
||||
using common.libs;
|
||||
using Microsoft.Win32;
|
||||
using RDPCOMAPILib;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Diagnostics;
|
||||
using System.Resources;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml;
|
||||
|
||||
namespace cmonitor.viewer.server.win
|
||||
{
|
||||
@@ -152,6 +154,16 @@ namespace cmonitor.viewer.server.win
|
||||
IRDPSRAPIInvitation invitation = session.Invitations.CreateInvitation(Guid.NewGuid().ToString(), "snltty", "snltty", 1024);
|
||||
string invitationString = invitation.ConnectionString;
|
||||
|
||||
/*
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
xmlDoc.LoadXml(invitationString);
|
||||
XmlElement newLNode = xmlDoc.CreateElement("L");
|
||||
newLNode.SetAttribute("P", "12345");
|
||||
newLNode.SetAttribute("N", "192.168.1.35");
|
||||
xmlDoc.DocumentElement["C"]["T"].AppendChild(newLNode);
|
||||
Debug.WriteLine(xmlDoc.OuterXml);
|
||||
*/
|
||||
|
||||
Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Cmonitor", "viewerConnectStr", invitationString);
|
||||
|
||||
notifyIcon.Icon = Icon.FromHandle(Resources.logo_share_green.GetHicon());
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>net7.0-windows;net8.0-windows</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
|
||||
<Nullable>disable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
||||
@@ -10,29 +10,15 @@ export const getActiveWindows = (name) => {
|
||||
export const activeTimesClear = (name) => {
|
||||
return sendWebsocketMsg('active/clear', name);
|
||||
}
|
||||
export const activeDisallow = (names, filenames, ids) => {
|
||||
export const activeDisallow = (names, filenames, ids1, ids2) => {
|
||||
return sendWebsocketMsg('active/disallow', {
|
||||
usernames: names, filenames, ids: ids || []
|
||||
devices: names, data: filenames, ids1: ids1 || [], ids2: ids2 || []
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export const activeAddGroup = (data) => {
|
||||
return sendWebsocketMsg('active/AddGroup', data);
|
||||
}
|
||||
export const activeDelGroup = (username, id) => {
|
||||
return sendWebsocketMsg('active/DeleteGroup', {
|
||||
username, id
|
||||
});
|
||||
}
|
||||
|
||||
export const activeAdd = (data) => {
|
||||
return sendWebsocketMsg('active/add', data);
|
||||
}
|
||||
export const activeDel = (username, groupid, id) => {
|
||||
return sendWebsocketMsg('active/del', {
|
||||
username, groupid, id
|
||||
});
|
||||
export const activeUpdate = (data) => {
|
||||
return sendWebsocketMsg('active/update', data);
|
||||
}
|
||||
|
||||
export const activeKill = (username, pid) => {
|
||||
|
||||
5
cmonitor.web/src/apis/devices.js
Normal file
5
cmonitor.web/src/apis/devices.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import { sendWebsocketMsg } from './request'
|
||||
|
||||
export const updateDevices = (data) => {
|
||||
return sendWebsocketMsg('devices/Update', data);
|
||||
}
|
||||
@@ -6,31 +6,16 @@ export const getRules = () => {
|
||||
export const addName = (data) => {
|
||||
return sendWebsocketMsg('hijack/addName', data);
|
||||
}
|
||||
|
||||
export const addProcessGroup = (data) => {
|
||||
return sendWebsocketMsg('hijack/addProcessGroup', data);
|
||||
}
|
||||
export const deleteProcessGroup = (data) => {
|
||||
return sendWebsocketMsg('hijack/deleteProcessGroup', data);
|
||||
}
|
||||
export const addProcess = (data) => {
|
||||
return sendWebsocketMsg('hijack/addProcess', data);
|
||||
}
|
||||
export const deleteProcess = (data) => {
|
||||
return sendWebsocketMsg('hijack/deleteProcess', data);
|
||||
export const updateProcess = (data) => {
|
||||
return sendWebsocketMsg('hijack/UpdateProcess', data);
|
||||
}
|
||||
|
||||
export const addRule = (data) => {
|
||||
return sendWebsocketMsg('hijack/AddRule', data);
|
||||
}
|
||||
export const deleteRule = (data) => {
|
||||
return sendWebsocketMsg('hijack/deleteRule', data);
|
||||
export const updateRule = (data) => {
|
||||
return sendWebsocketMsg('hijack/UpdateRule', data);
|
||||
}
|
||||
|
||||
export const updateDevices = (data) => {
|
||||
return sendWebsocketMsg('hijack/UpdateDevices', data);
|
||||
}
|
||||
|
||||
|
||||
export const setRules = (data) => {
|
||||
return sendWebsocketMsg('hijack/setRules', data);
|
||||
return sendWebsocketMsg('hijack/UseHijackRules', data);
|
||||
}
|
||||
10
cmonitor.web/src/apis/modes.js
Normal file
10
cmonitor.web/src/apis/modes.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import { sendWebsocketMsg } from './request'
|
||||
|
||||
export const updateModes = (data) => {
|
||||
return sendWebsocketMsg('modes/update', data);
|
||||
}
|
||||
export const useModes = (names, data, ids1, ids2, path) => {
|
||||
return sendWebsocketMsg(path, {
|
||||
devices: names, data: data, ids1: ids1, ids2: ids2
|
||||
});
|
||||
}
|
||||
8
cmonitor.web/src/apis/rule.js
Normal file
8
cmonitor.web/src/apis/rule.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import { sendWebsocketMsg } from './request'
|
||||
|
||||
export const getRules = () => {
|
||||
return sendWebsocketMsg('rule/info');
|
||||
}
|
||||
export const addName = (data) => {
|
||||
return sendWebsocketMsg('rule/addname', data);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import { sendWebsocketMsg } from './request'
|
||||
|
||||
export const getSetting = () => {
|
||||
return sendWebsocketMsg('setting/get');
|
||||
}
|
||||
export const saveSetting = (setting) => {
|
||||
return sendWebsocketMsg('setting/set', setting);
|
||||
}
|
||||
@@ -1,23 +1,9 @@
|
||||
import { sendWebsocketMsg } from './request'
|
||||
|
||||
|
||||
export const addGroup = (data) => {
|
||||
return sendWebsocketMsg('snatch/AddGroup', data);
|
||||
}
|
||||
export const delGroup = (username, id) => {
|
||||
return sendWebsocketMsg('snatch/DeleteGroup', {
|
||||
username, id
|
||||
});
|
||||
export const updateSnatch = (data) => {
|
||||
return sendWebsocketMsg('snatch/update', data);
|
||||
}
|
||||
|
||||
export const add = (data) => {
|
||||
return sendWebsocketMsg('snatch/add', data);
|
||||
}
|
||||
export const del = (username, groupid, id) => {
|
||||
return sendWebsocketMsg('snatch/del', {
|
||||
username, groupid, id
|
||||
});
|
||||
}
|
||||
|
||||
export const getQuestion = (name) => {
|
||||
return sendWebsocketMsg('snatch/getQuestion', name);
|
||||
@@ -25,18 +11,11 @@ export const getQuestion = (name) => {
|
||||
export const addQuestion = (question) => {
|
||||
return sendWebsocketMsg('snatch/addQuestion', question);
|
||||
}
|
||||
export const removeQuestion = (name) => {
|
||||
return sendWebsocketMsg('snatch/removeQuestion', name);
|
||||
}
|
||||
|
||||
|
||||
export const randomQuestion = (length) => {
|
||||
return sendWebsocketMsg('snatch/RandomQuestion', length);
|
||||
}
|
||||
|
||||
export const updateQuestion = (userName, items) => {
|
||||
return sendWebsocketMsg('snatch/UpdateQuestion', {
|
||||
userName, items
|
||||
});
|
||||
}
|
||||
|
||||
export const removeQuestion = (name) => {
|
||||
return sendWebsocketMsg('snatch/removeQuestion', name);
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
import { sendWebsocketMsg } from './request'
|
||||
|
||||
export const updateRegistryOptions = (names, keys, value) => {
|
||||
export const updateRegistryOptions = (names, keys) => {
|
||||
return sendWebsocketMsg('system/RegistryOptions', {
|
||||
names, registry: {
|
||||
keys: keys, value: value
|
||||
}
|
||||
devices: names, data: keys
|
||||
});
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
<script>
|
||||
import { computed, onMounted, reactive, watch } from 'vue';
|
||||
import { initWebsocket, subWebsocketState } from '../apis/request'
|
||||
import { getRules, addName } from '../apis/hijack'
|
||||
import { getRules, addName } from '../apis/rule'
|
||||
import { useRoute } from 'vue-router';
|
||||
import { injectGlobalData } from './provide';
|
||||
export default {
|
||||
@@ -41,6 +41,7 @@ export default {
|
||||
});
|
||||
localStorage.setItem('api', state.api);
|
||||
globalData.value.username = state.username;
|
||||
|
||||
const showSelectUsername = computed(() => !!!globalData.value.username && globalData.value.connected);
|
||||
const showPort = computed(() => globalData.value.connected == false && state.showPort);
|
||||
|
||||
@@ -54,8 +55,13 @@ export default {
|
||||
|
||||
const _getRules = () => {
|
||||
getRules().then((res) => {
|
||||
globalData.value.usernames = res;
|
||||
state.usernames = Object.keys(res);
|
||||
for (let j in res.Data) {
|
||||
for (let jj in res.Data[j]) {
|
||||
res.Data[j][jj] = JSON.parse(res.Data[j][jj]);
|
||||
}
|
||||
}
|
||||
globalData.value.usernames = res.Data;
|
||||
state.usernames = Object.keys(res.Data);
|
||||
}).catch(() => { });
|
||||
}
|
||||
const handleConnect = () => {
|
||||
|
||||
@@ -45,12 +45,11 @@ export default {
|
||||
checkAll: false,
|
||||
isIndeterminate: false
|
||||
});
|
||||
/*
|
||||
|
||||
watch(() => props.items, () => {
|
||||
state.checkList = props.items.map(c => c[props.label]);
|
||||
updateCheckAll(state.checkList);
|
||||
})
|
||||
*/
|
||||
|
||||
const handleCheckAllChange = (value) => {
|
||||
if (value) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<p>文件:【{{state.filename}}】</p>
|
||||
<p class="t-c">
|
||||
<el-select v-model="state.group" placeholder="选择一个分组" style="width:13rem">
|
||||
<el-option v-for="item in state.groups" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||
<el-option v-for="item in state.groups" :key="item.Name" :label="item.Name" :value="item.Name" />
|
||||
</el-select>
|
||||
</p>
|
||||
</div>
|
||||
@@ -23,7 +23,7 @@ import { computed, onMounted, watch } from '@vue/runtime-core';
|
||||
import { injectPluginState } from '../../provide'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { activeAdd } from '@/apis/active';
|
||||
import { activeUpdate } from '@/apis/active';
|
||||
export default {
|
||||
props: ['modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
@@ -34,15 +34,15 @@ export default {
|
||||
const globalData = injectGlobalData();
|
||||
const state = reactive({
|
||||
show: props.modelValue,
|
||||
group: 0,
|
||||
group: '',
|
||||
title: '',
|
||||
desc: '',
|
||||
filename: '',
|
||||
groups: computed(() => {
|
||||
let user = globalData.value.usernames[globalData.value.username];
|
||||
if (user) {
|
||||
if (user.Windows.length > 0 && state.group == 0) {
|
||||
state.group = user.Windows[0].ID;
|
||||
if (user.Windows.length > 0 && state.group == '') {
|
||||
state.group = user.Windows[0].Name;
|
||||
}
|
||||
return user.Windows;
|
||||
}
|
||||
@@ -80,25 +80,33 @@ export default {
|
||||
state.show = false;
|
||||
}
|
||||
const handleSubmit = () => {
|
||||
activeAdd({
|
||||
|
||||
const windows = globalData.value.usernames[globalData.value.username].Windows || [];
|
||||
const group = windows.filter(c => c.Name == state.group)[0];
|
||||
const items = group.List;
|
||||
const names = items.map(c => c.Name);
|
||||
|
||||
if (names.indexOf(state.filename) >= 0) {
|
||||
ElMessage.error('已存在同名');
|
||||
return;
|
||||
}
|
||||
items.push({ Name: state.filename, Desc: state.desc });
|
||||
globalData.value.usernames[globalData.value.username].Windows = windows;
|
||||
|
||||
activeUpdate({
|
||||
username: globalData.value.username,
|
||||
GroupID: state.group,
|
||||
Item: {
|
||||
ID: 0,
|
||||
Name: state.filename,
|
||||
Desc: state.desc
|
||||
}
|
||||
Data: windows
|
||||
}).then((error) => {
|
||||
if (!error) {
|
||||
ElMessage.success('操作成功');
|
||||
state.show = false;
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
state.show = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
ElMessage.error(`操作失败:${error}`);
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
}
|
||||
}).catch(() => {
|
||||
ElMessage.error('操作失败');
|
||||
});
|
||||
}).catch((e) => {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
<div class="flex-1"></div>
|
||||
<div class="Exes flex flex-column">
|
||||
<div class="private">
|
||||
<CheckBoxWrap ref="privateExes" :data="state.privateExes" :items="state.currentPrivate" label="ID" text="Name" title="私有窗口">
|
||||
<CheckBoxWrap ref="privateExes" :data="state.privateExes" :items="state.currentPrivate" label="Name" text="Name" title="私有窗口">
|
||||
</CheckBoxWrap>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="public">
|
||||
<CheckBoxWrap ref="publicExes" :data="state.publicExes" :items="state.currentPublic" label="ID" text="Name" title="公共窗口">
|
||||
<CheckBoxWrap ref="publicExes" :data="state.publicExes" :items="state.currentPublic" label="Name" text="Name" title="公共窗口">
|
||||
</CheckBoxWrap>
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<script>
|
||||
import { reactive, ref } from '@vue/reactivity';
|
||||
import { computed, onMounted, watch } from '@vue/runtime-core';
|
||||
import { computed, watch } from '@vue/runtime-core';
|
||||
import CheckBoxWrap from '../../boxs/CheckBoxWrap.vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { activeDisallow } from '@/apis/active'
|
||||
@@ -50,12 +50,16 @@ export default {
|
||||
show: props.modelValue,
|
||||
items: computed(() => {
|
||||
const devices = pluginState.value.activeWindow.devices;
|
||||
let ids = devices.reduce((arr, value) => {
|
||||
arr.push(...value.ActiveWindow.DisallowRunIds);
|
||||
let ids1 = devices.reduce((arr, value) => {
|
||||
arr.push(...value.ActiveWindow.DisallowRunIds1);
|
||||
return arr;
|
||||
}, []);
|
||||
state.currentPrivate = state.privateExes.filter(c => ids.indexOf(c.ID) >= 0);
|
||||
state.currentPublic = state.publicExes.filter(c => ids.indexOf(c.ID) >= 0);
|
||||
let ids2 = devices.reduce((arr, value) => {
|
||||
arr.push(...value.ActiveWindow.DisallowRunIds2);
|
||||
return arr;
|
||||
}, []);
|
||||
state.currentPrivate = state.privateExes.filter(c => ids1.indexOf(c.Name) >= 0);
|
||||
state.currentPublic = state.publicExes.filter(c => ids2.indexOf(c.Name) >= 0);
|
||||
return devices;
|
||||
}),
|
||||
privateExes: computed(() => user.value ? user.value.Windows : []),
|
||||
@@ -76,10 +80,10 @@ export default {
|
||||
const privateExes = ref(null);
|
||||
const publicExes = ref(null);
|
||||
const parseRule = () => {
|
||||
const _privateIds = privateExes.value.getData().map(c => c.ID);
|
||||
const _privateExes = state.privateExes.filter(c => _privateIds.indexOf(c.ID) >= 0);
|
||||
const _publicIds = publicExes.value.getData().map(c => c.ID);
|
||||
const _publicExes = state.publicExes.filter(c => _publicIds.indexOf(c.ID) >= 0);
|
||||
const _privateIds = privateExes.value.getData().map(c => c.Name);
|
||||
const _privateExes = state.privateExes.filter(c => _privateIds.indexOf(c.Name) >= 0);
|
||||
const _publicIds = publicExes.value.getData().map(c => c.Name);
|
||||
const _publicExes = state.publicExes.filter(c => _publicIds.indexOf(c.Name) >= 0);
|
||||
const exes = _privateExes.concat(_publicExes).reduce((data, item, index) => {
|
||||
let arr = item.List.reduce((val, item, index) => {
|
||||
val = val.concat(item.Name.split(','));
|
||||
@@ -94,7 +98,8 @@ export default {
|
||||
}, []);
|
||||
|
||||
return {
|
||||
ids: _privateIds.concat(_publicIds),
|
||||
ids1: _privateIds,
|
||||
ids2: _publicIds,
|
||||
exes: exes
|
||||
};
|
||||
}
|
||||
@@ -112,11 +117,12 @@ export default {
|
||||
}).then(() => {
|
||||
state.loading = true;
|
||||
const exes = parseRule();
|
||||
activeDisallow(_devices.map(c => c.MachineName), exes.exes, exes.ids).then((res) => {
|
||||
activeDisallow(_devices.map(c => c.MachineName), exes.exes, exes.ids1, exes.ids2).then((res) => {
|
||||
state.loading = false;
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.devices.filter(c => _devices.indexOf(c.MachineName) >= 0).forEach(device => {
|
||||
device.ActiveWindow.DisallowRunIds = exes.ids;
|
||||
device.ActiveWindow.DisallowRunIds1 = exes.ids1;
|
||||
device.ActiveWindow.DisallowRunIds2 = exes.ids2;
|
||||
});
|
||||
}).catch((e) => {
|
||||
state.loading = false;
|
||||
|
||||
99
cmonitor.web/src/views/device/plugins/active/Modes.vue
Normal file
99
cmonitor.web/src/views/device/plugins/active/Modes.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div class="absolute flex flex-column flex-nowrap">
|
||||
<div class="flex">
|
||||
<el-checkbox v-model="state.use">使用规则</el-checkbox>
|
||||
</div>
|
||||
<div class="flex flex-1">
|
||||
<div class="private">
|
||||
<CheckBoxWrap ref="privateExes" :data="state.privateExes" :items="state.ids1" label="Name" text="Name" title="私有窗口">
|
||||
</CheckBoxWrap>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="public">
|
||||
<CheckBoxWrap ref="publicExes" :data="state.publicExes" :items="state.ids2" label="Name" text="Name" title="公共窗口">
|
||||
</CheckBoxWrap>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive, ref } from '@vue/reactivity';
|
||||
import { computed, getCurrentInstance, inject, onMounted, watch } from '@vue/runtime-core';
|
||||
import CheckBoxWrap from '../../boxs/CheckBoxWrap.vue'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
label: '窗口',
|
||||
components: { CheckBoxWrap },
|
||||
setup(props, { emit }) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const user = computed(() => globalData.value.usernames[globalData.value.username]);
|
||||
const publicUserName = globalData.value.publicUserName;
|
||||
const publicUser = computed(() => globalData.value.usernames[publicUserName]);
|
||||
const usePublic = publicUser.value && globalData.value.username != publicUserName;
|
||||
const current = getCurrentInstance();
|
||||
const modeState = inject('mode-state');
|
||||
const state = reactive({
|
||||
use: false,
|
||||
privateExes: computed(() => user.value ? user.value.Windows : []),
|
||||
publicExes: computed(() => usePublic ? publicUser.value.Windows : []),
|
||||
ids1: [],
|
||||
ids2: [],
|
||||
});
|
||||
watch(() => modeState.value, () => {
|
||||
parseMode();
|
||||
});
|
||||
onMounted(() => { parseMode(); });
|
||||
const parseMode = () => {
|
||||
const json = JSON.parse(modeState.value)[current.type.label] || {};
|
||||
state.use = json.use || false;
|
||||
state.ids1 = (json.ids1 || []).map(c => { return { Name: c }; });
|
||||
state.ids2 = (json.ids2 || []).map(c => { return { Name: c }; });
|
||||
}
|
||||
|
||||
const privateExes = ref(null);
|
||||
const publicExes = ref(null);
|
||||
const parseRule = () => {
|
||||
const _privateIds = privateExes.value.getData().map(c => c.Name);
|
||||
const _privateExes = state.privateExes.filter(c => _privateIds.indexOf(c.Name) >= 0);
|
||||
const _publicIds = publicExes.value.getData().map(c => c.Name);
|
||||
const _publicExes = state.publicExes.filter(c => _publicIds.indexOf(c.Name) >= 0);
|
||||
const exes = _privateExes.concat(_publicExes).reduce((data, item, index) => {
|
||||
let arr = item.List.reduce((val, item, index) => {
|
||||
val = val.concat(item.Name.split(','));
|
||||
return val;
|
||||
}, []);
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i] && data.indexOf(arr[i]) == -1) {
|
||||
data.push(arr[i]);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}, []);
|
||||
|
||||
return {
|
||||
path: 'active/disallow',
|
||||
use: state.use,
|
||||
ids1: _privateIds,
|
||||
ids2: _publicIds,
|
||||
list: exes
|
||||
};
|
||||
}
|
||||
|
||||
const getData = () => {
|
||||
return parseRule();
|
||||
}
|
||||
|
||||
return {
|
||||
state, getData, privateExes, publicExes
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.private, .public {
|
||||
width: 49%;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
@@ -7,7 +7,8 @@ export default {
|
||||
Desc: '',
|
||||
Pid: 0,
|
||||
DisallowCount: 0,
|
||||
DisallowRunIds: [],
|
||||
DisallowRunIds1: [],
|
||||
DisallowRunIds2: [],
|
||||
WindowCount: 0,
|
||||
}
|
||||
}
|
||||
@@ -32,6 +33,7 @@ export default {
|
||||
item.ActiveWindow.Pid = report.ActiveWindow.Pid;
|
||||
item.ActiveWindow.DisallowCount = report.ActiveWindow.DisallowCount;
|
||||
item.ActiveWindow.WindowCount = report.ActiveWindow.WindowCount || 0;
|
||||
item.ActiveWindow.DisallowRunIds = report.ActiveWindow.Ids || [];
|
||||
item.ActiveWindow.DisallowRunIds1 = report.ActiveWindow.Ids1 || [];
|
||||
item.ActiveWindow.DisallowRunIds2 = report.ActiveWindow.Ids2 || [];
|
||||
}
|
||||
}
|
||||
@@ -9,28 +9,26 @@
|
||||
<el-table-column prop="Name" label="名称" />
|
||||
<el-table-column label="操作" width="110">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.ID > 1">
|
||||
<el-button size="small" @click="handleAdd(scope.row)">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-popconfirm title="删除不可逆,是否确定?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button size="small" type="danger">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
<el-button size="small" @click="handleAdd(scope.row)">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-popconfirm title="删除不可逆,是否确定?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button size="small" type="danger">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog :title="`${state.currentItem.ID==0?'添加项':'修改项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<el-dialog :title="`${state.currentItem.Name1?'修改项':'添加项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<div>
|
||||
<el-input v-model="state.currentItem.Name" size="large" placeholder="分组名称" />
|
||||
</div>
|
||||
@@ -46,7 +44,7 @@
|
||||
import { reactive } from '@vue/reactivity';
|
||||
import { computed } from '@vue/runtime-core';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { activeAddGroup, activeDelGroup } from '@/apis/active'
|
||||
import { activeUpdate } from '@/apis/active'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
setup() {
|
||||
@@ -54,14 +52,11 @@ export default {
|
||||
const globalData = injectGlobalData();;
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
currentItem: { ID: 0, Name: '' },
|
||||
currentItem: { Name: '', Name1: '' },
|
||||
showEdit: false,
|
||||
list: computed(() => {
|
||||
let user = globalData.value.usernames[globalData.value.username];
|
||||
if (user && user.Windows) {
|
||||
if (state.group == 0 && user.Windows.length > 0) {
|
||||
state.group = user.Windows[0].ID;
|
||||
}
|
||||
return user.Windows;
|
||||
}
|
||||
return [];
|
||||
@@ -69,18 +64,27 @@ export default {
|
||||
});
|
||||
|
||||
const handleAdd = (item) => {
|
||||
item = item || { Name: '', ID: 0 };
|
||||
item = item || { Name: '', Name1: '' };
|
||||
state.currentItem.Name = item.Name;
|
||||
state.currentItem.ID = item.ID;
|
||||
state.currentItem.Name1 = item.Name;
|
||||
state.showEdit = true;
|
||||
}
|
||||
const handleDel = (item) => {
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
}
|
||||
|
||||
const updateActiveGroup = () => {
|
||||
const windows = globalData.value.usernames[globalData.value.username].Windows || [];
|
||||
state.loading = true;
|
||||
activeDelGroup(globalData.value.username, item.ID).then((error) => {
|
||||
activeUpdate({
|
||||
username: globalData.value.username,
|
||||
Data: windows
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
state.showEdit = false;
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
}
|
||||
@@ -89,31 +93,33 @@ export default {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
const handleDel = (item) => {
|
||||
const windows = globalData.value.usernames[globalData.value.username].Windows || [];
|
||||
const names = windows.map(c => c.Name);
|
||||
windows.splice(names.indexOf(item.Name), 1);
|
||||
globalData.value.usernames[globalData.value.username].Windows = windows;
|
||||
updateActiveGroup();
|
||||
}
|
||||
const handleEditSubmit = () => {
|
||||
state.currentItem.Name = state.currentItem.Name.replace(/^\s|\s$/g, '');
|
||||
if (!state.currentItem.Name) {
|
||||
return;
|
||||
}
|
||||
state.loading = true;
|
||||
activeAddGroup({
|
||||
UserName: globalData.value.username,
|
||||
Group: state.currentItem
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
ElMessage.success('操作成功!');
|
||||
state.showEdit = false;
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
|
||||
const windows = globalData.value.usernames[globalData.value.username].Windows || [];
|
||||
const names = windows.map(c => c.Name);
|
||||
let index = names.indexOf(state.currentItem.Name1);
|
||||
if (index == -1) {
|
||||
if (names.indexOf(state.currentItem.Name) >= 0) {
|
||||
ElMessage.error('已存在同名');
|
||||
return;
|
||||
}
|
||||
}).catch((e) => {
|
||||
state.loading = false;
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
windows.push({ Name: state.currentItem.Name })
|
||||
} else {
|
||||
windows[index].Name = state.currentItem.Name;
|
||||
}
|
||||
globalData.value.usernames[globalData.value.username].Windows = windows;
|
||||
updateActiveGroup();
|
||||
}
|
||||
return { state, handleAdd, handleDel, handleEditCancel, handleEditSubmit }
|
||||
}
|
||||
|
||||
@@ -16,10 +16,9 @@
|
||||
|
||||
<script>
|
||||
import { reactive } from '@vue/reactivity';
|
||||
import { onMounted, watch } from '@vue/runtime-core';
|
||||
import { watch } from '@vue/runtime-core';
|
||||
import Groups from './Groups.vue'
|
||||
import Items from './Items.vue'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
props: ['modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
@@ -38,13 +37,10 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
|
||||
const handleCancel = () => {
|
||||
state.show = false;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
state, handleCancel
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="windows-items-wrap flex flex-nowrap flex-column">
|
||||
<div class="head t-c flex">
|
||||
<el-select v-model="state.group" placeholder="选择一个分组" style="width:13rem">
|
||||
<el-option v-for="item in state.groups" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||
<el-option v-for="item in state.groups" :key="item.Name" :label="item.Name" :value="item.Name" />
|
||||
</el-select>
|
||||
<span class="flex-1"></span>
|
||||
<el-button @click="handleAdd()">添加项</el-button>
|
||||
@@ -33,7 +33,7 @@
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog :title="`${state.currentItem.ID==0?'添加项':'修改项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<el-dialog :title="`${state.currentItem.Name1==0?'修改项':'添加项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<div>
|
||||
<p><el-input v-model="state.currentItem.Desc" size="large" placeholder="名称" /></p>
|
||||
<p style="padding-top:1rem"><el-input v-model="state.currentItem.Name" size="large" placeholder="规则" /></p>
|
||||
@@ -55,75 +55,57 @@
|
||||
import { reactive } from '@vue/reactivity';
|
||||
import { computed } from '@vue/runtime-core';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { activeAdd, activeDel } from '@/apis/active'
|
||||
import { activeUpdate } from '@/apis/active'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
setup() {
|
||||
const globalData = injectGlobalData();;
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
group: 0,
|
||||
currentItem: { ID: 0, Name: '', Desc: '' },
|
||||
group: '',
|
||||
currentItem: { Name: '', Name1: '', Desc: '' },
|
||||
showEdit: false,
|
||||
groups: computed(() => {
|
||||
let user = globalData.value.usernames[globalData.value.username];
|
||||
if (user && user.Windows) {
|
||||
if (state.group == 0 && user.Windows.length > 0) {
|
||||
state.group = user.Windows[0].ID;
|
||||
if (state.group == '' && user.Windows.length > 0) {
|
||||
state.group = user.Windows[0].Name;
|
||||
}
|
||||
return user.Windows;
|
||||
}
|
||||
return [];
|
||||
}),
|
||||
list: computed(() => {
|
||||
let group = state.groups.filter(c => c.ID == state.group)[0];
|
||||
let group = state.groups.filter(c => c.Name == state.group)[0];
|
||||
if (group) return group.List;
|
||||
return [];
|
||||
})
|
||||
});
|
||||
|
||||
const handleAdd = (item) => {
|
||||
item = item || { Name: '', ID: 0, Desc: '' };
|
||||
item = item || { Name: '', Name1: '', Desc: '' };
|
||||
state.currentItem.Name = item.Name;
|
||||
state.currentItem.Name1 = item.Name;
|
||||
state.currentItem.Desc = item.Desc;
|
||||
state.currentItem.ID = item.ID;
|
||||
state.showEdit = true;
|
||||
}
|
||||
const handleDel = (item) => {
|
||||
state.loading = true;
|
||||
activeDel(globalData.value.username, state.group, item.ID).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
}
|
||||
}).catch((e) => {
|
||||
state.loading = false;
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
}
|
||||
const handleEditSubmit = () => {
|
||||
state.currentItem.Name = state.currentItem.Name.replace(/^\s|\s$/g, '');
|
||||
if (!state.currentItem.Name) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updateActiveGroup = () => {
|
||||
const windows = globalData.value.usernames[globalData.value.username].Windows || [];
|
||||
state.loading = true;
|
||||
activeAdd({
|
||||
UserName: globalData.value.username,
|
||||
GroupID: state.group,
|
||||
Item: state.currentItem
|
||||
activeUpdate({
|
||||
username: globalData.value.username,
|
||||
Data: windows
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
ElMessage.success('操作成功!');
|
||||
state.showEdit = false;
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
}
|
||||
}).catch((e) => {
|
||||
@@ -131,6 +113,45 @@ export default {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
|
||||
const handleDel = (item) => {
|
||||
const windows = globalData.value.usernames[globalData.value.username].Windows || [];
|
||||
const group = windows.filter(c => c.Name == state.group)[0];
|
||||
const items = group.List;
|
||||
|
||||
const names = items.map(c => c.Name);
|
||||
items.splice(names.indexOf(item.Name), 1);
|
||||
|
||||
globalData.value.usernames[globalData.value.username].Windows = windows;
|
||||
|
||||
updateActiveGroup();
|
||||
}
|
||||
|
||||
const handleEditSubmit = () => {
|
||||
state.currentItem.Name = state.currentItem.Name.replace(/^\s|\s$/g, '');
|
||||
if (!state.currentItem.Name) {
|
||||
return;
|
||||
}
|
||||
|
||||
const windows = globalData.value.usernames[globalData.value.username].Windows || [];
|
||||
const group = windows.filter(c => c.Name == state.group)[0];
|
||||
const items = group.List;
|
||||
const names = items.map(c => c.Name);
|
||||
|
||||
let index = names.indexOf(state.currentItem.Name1);
|
||||
if (index == -1) {
|
||||
if (names.indexOf(state.currentItem.Name) >= 0) {
|
||||
ElMessage.error('已存在同名');
|
||||
return;
|
||||
}
|
||||
items.push({ Name: state.currentItem.Name, Desc: state.currentItem.Desc })
|
||||
} else {
|
||||
items[index].Name = state.currentItem.Name;
|
||||
items[index].Desc = state.currentItem.Desc;
|
||||
}
|
||||
globalData.value.usernames[globalData.value.username].Windows = windows;
|
||||
updateActiveGroup();
|
||||
}
|
||||
return { state, handleAdd, handleDel, handleEditCancel, handleEditSubmit }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +114,18 @@ export default {
|
||||
&>div {
|
||||
padding: 0.6rem 0;
|
||||
}
|
||||
|
||||
.item {
|
||||
padding: 0.6rem;
|
||||
|
||||
.subitem {
|
||||
padding: 0.2rem;
|
||||
|
||||
.label {
|
||||
margin-right: 0.6rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
import { reactive, ref } from '@vue/reactivity';
|
||||
import { computed, onMounted, watch } from '@vue/runtime-core';
|
||||
import CheckBoxWrap from '../../boxs/CheckBoxWrap.vue'
|
||||
import { updateDevices } from '../../../../apis/hijack'
|
||||
import { updateDevices } from '../../../../apis/devices'
|
||||
import { delDevice } from '../../../../apis/signin'
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
@@ -75,7 +75,7 @@ export default {
|
||||
state.loading = true;
|
||||
updateDevices({
|
||||
username: globalData.value.username,
|
||||
devices: _devices.map(c => c.MachineName)
|
||||
data: _devices.map(c => c.MachineName)
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
globalData.value.updateDeviceFlag = Date.now();
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
<div class="flex-1"></div>
|
||||
<div class="rules flex flex-column">
|
||||
<div class="private">
|
||||
<CheckBoxWrap ref="privateRules" :data="state.privateRules" :items="state.currentPrivate" label="ID" text="Name" title="私有限制"></CheckBoxWrap>
|
||||
<CheckBoxWrap ref="privateRules" :data="state.privateRules" :items="state.currentPrivate" label="Name" text="Name" title="私有限制"></CheckBoxWrap>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="public">
|
||||
<CheckBoxWrap ref="publicRules" :data="state.publicRules" :items="state.currentPublic" label="ID" text="Name" title="公共限制"></CheckBoxWrap>
|
||||
<CheckBoxWrap ref="publicRules" :data="state.publicRules" :items="state.currentPublic" label="Name" text="Name" title="公共限制"></CheckBoxWrap>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<script>
|
||||
import { reactive, ref } from '@vue/reactivity';
|
||||
import { computed, inject, onMounted, watch } from '@vue/runtime-core';
|
||||
import { computed, onMounted, watch } from '@vue/runtime-core';
|
||||
import CheckBoxWrap from '../../boxs/CheckBoxWrap.vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { setRules } from '../../../../apis/hijack'
|
||||
@@ -49,21 +49,24 @@ export default {
|
||||
const publicUserName = globalData.value.publicUserName;
|
||||
const publicUser = computed(() => globalData.value.usernames[publicUserName]);
|
||||
const usePublic = publicUser.value && globalData.value.username != publicUserName;
|
||||
|
||||
const state = reactive({
|
||||
show: props.modelValue,
|
||||
items: computed(() => {
|
||||
const devices = pluginState.value.hijack.devices;
|
||||
let ids = devices.reduce((arr, value) => {
|
||||
arr.push(...value.Hijack.RuleIds);
|
||||
let ids1 = devices.reduce((arr, value) => {
|
||||
arr.push(...value.Hijack.RuleIds1);
|
||||
return arr;
|
||||
}, []);
|
||||
state.currentPrivate = state.privateRules.filter(c => ids.indexOf(c.ID) >= 0);
|
||||
state.currentPublic = state.publicRules.filter(c => ids.indexOf(c.ID) >= 0);
|
||||
let ids2 = devices.reduce((arr, value) => {
|
||||
arr.push(...value.Hijack.RuleIds2);
|
||||
return arr;
|
||||
}, []);
|
||||
state.currentPrivate = state.privateRules.filter(c => ids1.indexOf(c.Name) >= 0);
|
||||
state.currentPublic = state.publicRules.filter(c => ids2.indexOf(c.Name) >= 0);
|
||||
return devices;
|
||||
}),
|
||||
privateRules: computed(() => user.value ? user.value.Rules : []),
|
||||
publicRules: computed(() => usePublic ? publicUser.value.Rules : []),
|
||||
privateRules: computed(() => user.value ? user.value.Processs : []),
|
||||
publicRules: computed(() => usePublic ? publicUser.value.Processs : []),
|
||||
loading: false,
|
||||
currentPrivate: [],
|
||||
currentPublic: [],
|
||||
@@ -81,23 +84,16 @@ export default {
|
||||
const privateRules = ref(null);
|
||||
const publicRules = ref(null);
|
||||
const parseRule = () => {
|
||||
const _privateRules = privateRules.value.getData().map(c => c.ID);
|
||||
const _publicRules = publicRules.value.getData().map(c => c.ID);
|
||||
const _privateRules = privateRules.value.getData().map(c => c.Name);
|
||||
const _publicRules = publicRules.value.getData().map(c => c.Name);
|
||||
const _user = user.value;
|
||||
const _publicUser = publicUser.value;
|
||||
|
||||
const publicList = _user.Rules.filter(c => _privateRules.indexOf(c.ID) >= 0).map(rule => {
|
||||
return _user.Processs.filter(c => rule.PrivateProcesss.indexOf(c.ID) >= 0);
|
||||
});
|
||||
const privateList = _publicUser.Rules.filter(c => _publicRules.indexOf(c.ID) >= 0).map(rule => {
|
||||
return _publicUser.Processs.filter(c => rule.PublicProcesss.indexOf(c.ID) >= 0);
|
||||
});
|
||||
const publicList = _user.Processs.filter(c => _privateRules.indexOf(c.Name) >= 0);
|
||||
const privateList = _publicUser.Processs.filter(c => _publicRules.indexOf(c.Name) >= 0);
|
||||
|
||||
const origin = publicList.concat(privateList).reduce((arr, value, index) => {
|
||||
arr = arr.concat(value.reduce((arr, value, index) => {
|
||||
arr = arr.concat(value.List);
|
||||
return arr;
|
||||
}, []));
|
||||
arr = arr.concat(value.List);
|
||||
return arr;
|
||||
}, []);
|
||||
const res = [];
|
||||
@@ -108,7 +104,8 @@ export default {
|
||||
});
|
||||
|
||||
return {
|
||||
ids: _privateRules.concat(_publicRules),
|
||||
ids1: _privateRules,
|
||||
ids2: _publicRules,
|
||||
list: {
|
||||
AllowProcesss: res.filter(c => c.DataType == 0 && c.AllowType == 0).map(c => c.Name),
|
||||
DeniedProcesss: res.filter(c => c.DataType == 0 && c.AllowType == 1).map(c => c.Name),
|
||||
@@ -136,9 +133,10 @@ export default {
|
||||
state.loading = true;
|
||||
const rules = parseRule();
|
||||
setRules({
|
||||
Devices: _devices.map(c => c.MachineName),
|
||||
Rules: rules.list,
|
||||
ids: rules.ids,
|
||||
devices: _devices.map(c => c.MachineName),
|
||||
data: rules.list,
|
||||
ids1: rules.ids1,
|
||||
ids2: rules.ids2,
|
||||
}).then((errorDevices) => {
|
||||
state.loading = false;
|
||||
if (errorDevices && errorDevices.length > 0) {
|
||||
@@ -146,7 +144,8 @@ export default {
|
||||
} else {
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.devices.filter(c => _devices.indexOf(c.MachineName) >= 0).forEach(device => {
|
||||
device.Hijack.RuleIds = rules.ids;
|
||||
device.Hijack.RuleIds1 = rules.ids1;
|
||||
device.Hijack.RuleIds2 = rules.ids2;
|
||||
});
|
||||
}
|
||||
}).catch((e) => {
|
||||
|
||||
116
cmonitor.web/src/views/device/plugins/hijack/Modes.vue
Normal file
116
cmonitor.web/src/views/device/plugins/hijack/Modes.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div class="rule-wrap absolute flex flex-column flex-nowrap">
|
||||
<div class="flex">
|
||||
<el-checkbox v-model="state.use">使用规则</el-checkbox>
|
||||
<el-checkbox v-model="state.domainKill">暴力强杀(关闭应用程序)</el-checkbox>
|
||||
</div>
|
||||
<div class="rules flex-1 flex">
|
||||
<div class="private">
|
||||
<CheckBoxWrap ref="privateRules" :data="state.privateRules" :items="state.ids1" label="Name" text="Name" title="私有限制"></CheckBoxWrap>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="public">
|
||||
<CheckBoxWrap ref="publicRules" :data="state.publicRules" :items="state.ids2" label="Name" text="Name" title="公共限制"></CheckBoxWrap>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive, ref } from '@vue/reactivity';
|
||||
import { computed, getCurrentInstance, inject, onMounted, watch } from '@vue/runtime-core';
|
||||
import CheckBoxWrap from '../../boxs/CheckBoxWrap.vue'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
label: '网络',
|
||||
components: { CheckBoxWrap },
|
||||
setup(props, { emit }) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const user = computed(() => globalData.value.usernames[globalData.value.username]);
|
||||
const publicUserName = globalData.value.publicUserName;
|
||||
const publicUser = computed(() => globalData.value.usernames[publicUserName]);
|
||||
const usePublic = publicUser.value && globalData.value.username != publicUserName;
|
||||
const current = getCurrentInstance();
|
||||
const modeState = inject('mode-state');
|
||||
const state = reactive({
|
||||
use: false,
|
||||
privateRules: computed(() => user.value ? user.value.Processs : []),
|
||||
publicRules: computed(() => usePublic ? publicUser.value.Processs : []),
|
||||
ids1: [],
|
||||
ids2: [],
|
||||
domainKill: false
|
||||
});
|
||||
watch(() => modeState.value, () => {
|
||||
parseMode();
|
||||
});
|
||||
onMounted(() => { parseMode(); });
|
||||
const parseMode = () => {
|
||||
const json = JSON.parse(modeState.value)[current.type.label] || { list: {} };
|
||||
state.use = json.use || false;
|
||||
state.ids1 = (json.ids1 || []).map(c => { return { Name: c }; });
|
||||
state.ids2 = (json.ids2 || []).map(c => { return { Name: c }; });
|
||||
state.domainKill = json.list.DomainKill || false;
|
||||
}
|
||||
|
||||
|
||||
const privateRules = ref(null);
|
||||
const publicRules = ref(null);
|
||||
const parseRule = () => {
|
||||
const _privateRules = privateRules.value.getData().map(c => c.Name);
|
||||
const _publicRules = publicRules.value.getData().map(c => c.Name);
|
||||
const _user = user.value;
|
||||
const _publicUser = publicUser.value;
|
||||
const publicList = _user.Processs.filter(c => _privateRules.indexOf(c.Name) >= 0);
|
||||
const privateList = _publicUser.Processs.filter(c => _publicRules.indexOf(c.Name) >= 0);
|
||||
|
||||
const origin = publicList.concat(privateList).reduce((arr, value, index) => {
|
||||
arr = arr.concat(value.List);
|
||||
return arr;
|
||||
}, []);
|
||||
const res = [];
|
||||
origin.forEach(element => {
|
||||
if (res.filter(c => c.Name == element.Name && c.DataType == element.DataType && c.AllowType == element.AllowType).length == 0) {
|
||||
res.push(element);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
path: 'hijack/usehijackrules',
|
||||
use: state.use,
|
||||
ids1: _privateRules,
|
||||
ids2: _publicRules,
|
||||
list: {
|
||||
AllowProcesss: res.filter(c => c.DataType == 0 && c.AllowType == 0).map(c => c.Name),
|
||||
DeniedProcesss: res.filter(c => c.DataType == 0 && c.AllowType == 1).map(c => c.Name),
|
||||
AllowDomains: res.filter(c => c.DataType == 1 && c.AllowType == 0).map(c => c.Name),
|
||||
DeniedDomains: res.filter(c => c.DataType == 1 && c.AllowType == 1).map(c => c.Name),
|
||||
AllowIPs: res.filter(c => c.DataType == 2 && c.AllowType == 0).map(c => c.Name),
|
||||
DeniedIPs: res.filter(c => c.DataType == 2 && c.AllowType == 1).map(c => c.Name),
|
||||
DomainKill: state.domainKill
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getData = () => {
|
||||
return parseRule();
|
||||
}
|
||||
|
||||
return {
|
||||
state, getData, globalData, privateRules, publicRules,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.rule-wrap {
|
||||
.rules {
|
||||
position: relative;
|
||||
|
||||
.private, .public {
|
||||
width: 49%;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -8,7 +8,8 @@ export default {
|
||||
Download: 0,
|
||||
DownloadText: '',
|
||||
Count: 0,
|
||||
RuleIds: [],
|
||||
RuleIds1: [],
|
||||
RuleIds2: [],
|
||||
DomainKill: false,
|
||||
}
|
||||
}
|
||||
@@ -73,7 +74,8 @@ export default {
|
||||
item.Hijack.Upload = report.Hijack.Upload;
|
||||
item.Hijack.Download = report.Hijack.Download;
|
||||
item.Hijack.Count = report.Hijack.Count;
|
||||
item.Hijack.RuleIds = report.Hijack.Ids;
|
||||
item.Hijack.RuleIds1 = report.Hijack.Ids1 || [];
|
||||
item.Hijack.RuleIds2 = report.Hijack.Ids2 || [];
|
||||
}
|
||||
|
||||
item.Hijack.DomainKill = report.Hijack.DomainKill || false;
|
||||
|
||||
@@ -9,28 +9,26 @@
|
||||
<el-table-column prop="Name" label="名称" />
|
||||
<el-table-column label="操作" width="110">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.ID > 1">
|
||||
<el-button size="small" @click="handleAdd(scope.row)">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-popconfirm title="删除不可逆,是否确定?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button size="small" type="danger">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
<el-button size="small" @click="handleAdd(scope.row)">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-popconfirm title="删除不可逆,是否确定?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button size="small" type="danger">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog :title="`${state.currentItem.ID==0?'添加项':'修改项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<el-dialog :title="`${state.currentItem.Name1==0?'修改项':'添加项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<div>
|
||||
<el-input v-model="state.currentItem.Name" size="large" placeholder="分组名称" />
|
||||
</div>
|
||||
@@ -46,7 +44,7 @@
|
||||
import { reactive } from '@vue/reactivity';
|
||||
import { computed } from '@vue/runtime-core';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { addProcessGroup, deleteProcessGroup } from '../../../../../apis/hijack'
|
||||
import { updateProcess } from '../../../../../apis/hijack'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
setup() {
|
||||
@@ -54,14 +52,11 @@ export default {
|
||||
const globalData = injectGlobalData();;
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
currentItem: { ID: 0, Name: '' },
|
||||
currentItem: { Name: '', Name1: '' },
|
||||
showEdit: false,
|
||||
list: computed(() => {
|
||||
let user = globalData.value.usernames[globalData.value.username];
|
||||
if (user && user.Processs) {
|
||||
if (state.group == 0 && user.Processs.length > 0) {
|
||||
state.group = user.Processs[0].ID;
|
||||
}
|
||||
return user.Processs;
|
||||
}
|
||||
return [];
|
||||
@@ -69,21 +64,27 @@ export default {
|
||||
});
|
||||
|
||||
const handleAdd = (item) => {
|
||||
item = item || { Name: '', ID: 0 };
|
||||
item = item || { Name: '', Name1: '' };
|
||||
state.currentItem.Name = item.Name;
|
||||
state.currentItem.ID = item.ID;
|
||||
state.currentItem.Name1 = item.Name;
|
||||
state.showEdit = true;
|
||||
}
|
||||
const handleDel = (item) => {
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
}
|
||||
|
||||
const updateProcessGroup = () => {
|
||||
const processs = globalData.value.usernames[globalData.value.username].Processs || [];
|
||||
state.loading = true;
|
||||
deleteProcessGroup({
|
||||
UserName: globalData.value.username,
|
||||
ID: item.ID
|
||||
updateProcess({
|
||||
username: globalData.value.username,
|
||||
Data: processs
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
state.showEdit = false;
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
}
|
||||
@@ -92,31 +93,33 @@ export default {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
const handleDel = (item) => {
|
||||
const processs = globalData.value.usernames[globalData.value.username].Processs || [];
|
||||
const names = processs.map(c => c.Name);
|
||||
processs.splice(names.indexOf(item.Name), 1);
|
||||
globalData.value.usernames[globalData.value.username].Processs = processs;
|
||||
updateProcessGroup();
|
||||
}
|
||||
const handleEditSubmit = () => {
|
||||
state.currentItem.Name = state.currentItem.Name.replace(/^\s|\s$/g, '');
|
||||
if (!state.currentItem.Name) {
|
||||
return;
|
||||
}
|
||||
state.loading = true;
|
||||
addProcessGroup({
|
||||
UserName: globalData.value.username,
|
||||
Group: state.currentItem
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
ElMessage.success('操作成功!');
|
||||
state.showEdit = false;
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
|
||||
const processs = globalData.value.usernames[globalData.value.username].Processs || [];
|
||||
const names = processs.map(c => c.Name);
|
||||
let index = names.indexOf(state.currentItem.Name1);
|
||||
if (index == -1) {
|
||||
if (names.indexOf(state.currentItem.Name) >= 0) {
|
||||
ElMessage.error('已存在同名');
|
||||
return;
|
||||
}
|
||||
}).catch((e) => {
|
||||
state.loading = false;
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
processs.push({ Name: state.currentItem.Name })
|
||||
} else {
|
||||
processs[index].Name = state.currentItem.Name;
|
||||
}
|
||||
globalData.value.usernames[globalData.value.username].Processs = processs;
|
||||
updateProcessGroup();
|
||||
}
|
||||
return { state, handleAdd, handleDel, handleEditCancel, handleEditSubmit }
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="process-items-wrap flex flex-nowrap flex-column">
|
||||
<div class="head t-c flex">
|
||||
<el-select v-model="state.group" placeholder="选择一个分组" style="width:13rem">
|
||||
<el-option v-for="item in state.groups" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||
<el-option v-for="item in state.groups" :key="item.Name" :label="item.Name" :value="item.Name" />
|
||||
</el-select>
|
||||
<span class="flex-1"></span>
|
||||
<el-button @click="handleAdd()">添加项</el-button>
|
||||
@@ -36,7 +36,7 @@
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog :title="`${state.currentItem.ID==0?'添加项':'修改项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<el-dialog :title="`${state.currentItem.Name1?'修改项':'添加项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<div>
|
||||
<div class="alert">
|
||||
<p>1、黑名单优先</p>
|
||||
@@ -69,28 +69,28 @@
|
||||
import { reactive } from '@vue/reactivity';
|
||||
import { computed, watch } from '@vue/runtime-core';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { addProcess, deleteProcess } from '../../../../../apis/hijack'
|
||||
import { updateProcess } from '../../../../../apis/hijack'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
setup() {
|
||||
const globalData = injectGlobalData();;
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
group: 0,
|
||||
currentItem: { ID: 0, Name: '', AllowType: 1, DataType: 0 },
|
||||
group: '',
|
||||
currentItem: { Name: '', Name1: '', AllowType: 1, DataType: 0 },
|
||||
showEdit: false,
|
||||
groups: computed(() => {
|
||||
let user = globalData.value.usernames[globalData.value.username];
|
||||
if (user && user.Processs) {
|
||||
if (state.group == 0 && user.Processs.length > 0) {
|
||||
state.group = user.Processs[0].ID;
|
||||
state.group = user.Processs[0].Name;
|
||||
}
|
||||
return user.Processs;
|
||||
}
|
||||
return [];
|
||||
}),
|
||||
list: computed(() => {
|
||||
let group = state.groups.filter(c => c.ID == state.group)[0];
|
||||
let group = state.groups.filter(c => c.Name == state.group)[0];
|
||||
if (group) return group.List;
|
||||
return [];
|
||||
})
|
||||
@@ -108,23 +108,29 @@ export default {
|
||||
}
|
||||
}
|
||||
const handleAdd = (item) => {
|
||||
item = item || { Name: '', ID: 0, AllowType: 1, DataType: 0 };
|
||||
item = item || { Name: '', Name1: '', AllowType: 1, DataType: 0 };
|
||||
state.currentItem.Name = item.Name;
|
||||
state.currentItem.ID = item.ID;
|
||||
state.currentItem.Name1 = item.Name;
|
||||
state.currentItem.AllowType = item.AllowType;
|
||||
state.currentItem.DataType = item.DataType;
|
||||
state.showEdit = true;
|
||||
}
|
||||
const handleDel = (item) => {
|
||||
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
}
|
||||
const updateProcessGroup = () => {
|
||||
const processs = globalData.value.usernames[globalData.value.username].Processs || [];
|
||||
state.loading = true;
|
||||
deleteProcess({
|
||||
UserName: globalData.value.username,
|
||||
GroupID: state.group,
|
||||
ID: item.ID
|
||||
updateProcess({
|
||||
username: globalData.value.username,
|
||||
Data: processs
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
state.showEdit = false;
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
}
|
||||
@@ -133,32 +139,51 @@ export default {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
|
||||
const handleDel = (item) => {
|
||||
const processs = globalData.value.usernames[globalData.value.username].Processs || [];
|
||||
const group = processs.filter(c => c.Name == state.group)[0];
|
||||
const items = group.List;
|
||||
|
||||
const names = items.map(c => c.Name);
|
||||
items.splice(names.indexOf(item.Name), 1);
|
||||
|
||||
globalData.value.usernames[globalData.value.username].Processs = processs;
|
||||
|
||||
updateProcessGroup();
|
||||
}
|
||||
|
||||
const handleEditSubmit = () => {
|
||||
state.currentItem.Name = state.currentItem.Name.replace(/^\s|\s$/g, '');
|
||||
if (!state.currentItem.Name) {
|
||||
return;
|
||||
}
|
||||
state.loading = true;
|
||||
addProcess({
|
||||
UserName: globalData.value.username,
|
||||
GroupID: state.group,
|
||||
Item: state.currentItem
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
ElMessage.success('操作成功!');
|
||||
state.showEdit = false;
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
|
||||
const processs = globalData.value.usernames[globalData.value.username].Processs || [];
|
||||
const group = processs.filter(c => c.Name == state.group)[0];
|
||||
const items = group.List;
|
||||
const names = items.map(c => c.Name);
|
||||
|
||||
let index = names.indexOf(state.currentItem.Name1);
|
||||
if (index == -1) {
|
||||
if (names.indexOf(state.currentItem.Name) >= 0) {
|
||||
ElMessage.error('已存在同名');
|
||||
return;
|
||||
}
|
||||
}).catch((e) => {
|
||||
state.loading = false;
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
items.push({
|
||||
Name: state.currentItem.Name,
|
||||
Desc: state.currentItem.Desc,
|
||||
AllowType: state.currentItem.AllowType,
|
||||
DataType: state.currentItem.DataType,
|
||||
})
|
||||
} else {
|
||||
items[index].Name = state.currentItem.Name;
|
||||
items[index].Desc = state.currentItem.Desc;
|
||||
items[index].AllowType = state.currentItem.AllowType;
|
||||
items[index].DataType = state.currentItem.DataType;
|
||||
}
|
||||
globalData.value.usernames[globalData.value.username].Processs = processs;
|
||||
updateProcessGroup();
|
||||
}
|
||||
return { state, handleNameChange, handleAdd, handleDel, handleEditCancel, handleEditSubmit }
|
||||
}
|
||||
|
||||
@@ -9,28 +9,26 @@
|
||||
<el-table-column prop="Name" label="名称" />
|
||||
<el-table-column label="操作" width="110">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.ID > 1">
|
||||
<el-button size="small" @click="handleAdd(scope.row)">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-popconfirm title="删除不可逆,是否确定?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button size="small" type="danger">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
<el-button size="small" @click="handleAdd(scope.row)">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-popconfirm title="删除不可逆,是否确定?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button size="small" type="danger">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog :title="`${state.currentItem.ID==0?'添加项':'修改项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<el-dialog :title="`${state.currentItem.Name1==0?'修改项':'添加项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<div>
|
||||
<el-input v-model="state.currentItem.Name" size="large" placeholder="分组名称" />
|
||||
</div>
|
||||
@@ -46,7 +44,7 @@
|
||||
import { reactive } from '@vue/reactivity';
|
||||
import { computed } from '@vue/runtime-core';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { addRule, deleteRule } from '../../../../../apis/hijack'
|
||||
import { updateRule } from '../../../../../apis/hijack'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
setup() {
|
||||
@@ -54,13 +52,13 @@ export default {
|
||||
const globalData = injectGlobalData();;
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
currentItem: { ID: 0, Name: '' },
|
||||
currentItem: { Name: '', Name1: '' },
|
||||
showEdit: false,
|
||||
list: computed(() => {
|
||||
let user = globalData.value.usernames[globalData.value.username];
|
||||
if (user && user.Rules) {
|
||||
if (state.group == 0 && user.Rules.length > 0) {
|
||||
state.group = user.Rules[0].ID;
|
||||
state.group = user.Rules[0].Name;
|
||||
}
|
||||
return user.Rules;
|
||||
}
|
||||
@@ -69,21 +67,28 @@ export default {
|
||||
});
|
||||
|
||||
const handleAdd = (item) => {
|
||||
item = item || { Name: '', ID: 0 };
|
||||
item = item || { Name: '', Name1: '' };
|
||||
state.currentItem.Name = item.Name;
|
||||
state.currentItem.ID = item.ID;
|
||||
state.currentItem.Name1 = item.Name;
|
||||
state.showEdit = true;
|
||||
}
|
||||
const handleDel = (item) => {
|
||||
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
}
|
||||
|
||||
const _updateRule = () => {
|
||||
const rules = globalData.value.usernames[globalData.value.username].Rules || [];
|
||||
state.loading = true;
|
||||
deleteRule({
|
||||
UserName: globalData.value.username,
|
||||
ID: item.ID
|
||||
updateRule({
|
||||
username: globalData.value.username,
|
||||
Data: rules
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
state.showEdit = false;
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
}
|
||||
@@ -92,32 +97,35 @@ export default {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
const handleDel = (item) => {
|
||||
const rules = globalData.value.usernames[globalData.value.username].Rules || [];
|
||||
const names = rules.map(c => c.Name);
|
||||
rules.splice(names.indexOf(item.Name), 1);
|
||||
globalData.value.usernames[globalData.value.username].Rules = rules;
|
||||
_updateRule();
|
||||
}
|
||||
const handleEditSubmit = () => {
|
||||
state.currentItem.Name = state.currentItem.Name.replace(/^\s|\s$/g, '');
|
||||
if (!state.currentItem.Name) {
|
||||
return;
|
||||
}
|
||||
state.loading = true;
|
||||
addRule({
|
||||
UserName: globalData.value.username,
|
||||
Rule: state.currentItem
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
ElMessage.success('操作成功!');
|
||||
state.showEdit = false;
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
|
||||
const rules = globalData.value.usernames[globalData.value.username].Rules || [];
|
||||
const names = rules.map(c => c.Name);
|
||||
let index = names.indexOf(state.currentItem.Name1);
|
||||
if (index == -1) {
|
||||
if (names.indexOf(state.currentItem.Name) >= 0) {
|
||||
ElMessage.error('已存在同名');
|
||||
return;
|
||||
}
|
||||
}).catch((e) => {
|
||||
state.loading = false;
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
rules.push({ Name: state.currentItem.Name })
|
||||
} else {
|
||||
rules[index].Name = state.currentItem.Name;
|
||||
}
|
||||
globalData.value.usernames[globalData.value.username].Rules = rules;
|
||||
_updateRule();
|
||||
}
|
||||
|
||||
return { state, handleAdd, handleDel, handleEditCancel, handleEditSubmit }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="head t-c flex">
|
||||
<div>
|
||||
<el-select v-model="state.group" placeholder="选择一个分组" style="width:13rem">
|
||||
<el-option v-for="item in state.groups" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||
<el-option v-for="item in state.groups" :key="item.Name" :label="item.Name" :value="item.Name" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
@@ -13,11 +13,11 @@
|
||||
</div>
|
||||
<div class="body flex flex-1">
|
||||
<div class="private">
|
||||
<CheckBoxWrap ref="privateProcess" :data="state.privateProcess" :items="state.privateProcessItems" label="ID" text="Name" title="私有程序组"></CheckBoxWrap>
|
||||
<CheckBoxWrap ref="privateProcess" :data="state.privateProcess" :items="state.privateProcessItems" label="Name" text="Name" title="私有程序组"></CheckBoxWrap>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="public">
|
||||
<CheckBoxWrap ref="publicProcess" :data="state.publicProcess" :items="state.publicProcessItems" label="ID" text="Name" title="公共程序组"></CheckBoxWrap>
|
||||
<CheckBoxWrap ref="publicProcess" :data="state.publicProcess" :items="state.publicProcessItems" label="Name" text="Name" title="公共程序组"></CheckBoxWrap>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,7 +27,7 @@
|
||||
import { computed, reactive, ref, watch } from 'vue';
|
||||
import CheckBoxWrap from '../../../boxs/CheckBoxWrap.vue'
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { addRule } from '../../../../../apis/hijack'
|
||||
import { updateRule } from '../../../../../apis/hijack'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
components: { CheckBoxWrap },
|
||||
@@ -41,11 +41,11 @@ export default {
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
group: 0,
|
||||
group: '',
|
||||
groups: computed(() => {
|
||||
if (user.value && user.value.Rules) {
|
||||
if (state.group == 0 && user.value.Rules.length > 0) {
|
||||
state.group = user.value.Rules[0].ID;
|
||||
if (state.group == '' && user.value.Rules.length > 0) {
|
||||
state.group = user.value.Rules[0].Name;
|
||||
}
|
||||
return user.value.Rules;
|
||||
}
|
||||
@@ -53,22 +53,23 @@ export default {
|
||||
}),
|
||||
rule: computed(() => {
|
||||
if (user && user.value.Rules) {
|
||||
let rule = user.value.Rules.filter(c => c.ID == state.group)[0];
|
||||
let rule = user.value.Rules.filter(c => c.Name == state.group)[0];
|
||||
if (rule) {
|
||||
console.log(rule);
|
||||
console.log(user.value.Processs.filter(c => rule.PrivateProcesss.indexOf(c.Name) >= 0));
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
return {
|
||||
ID: 0,
|
||||
Name: '',
|
||||
PrivateProcesss: [],
|
||||
PublicProcesss: [],
|
||||
}
|
||||
}),
|
||||
privateProcess: computed(() => user.value ? user.value.Processs : []),
|
||||
privateProcessItems: computed(() => user.value ? user.value.Processs.filter(c => state.rule.PrivateProcesss.indexOf(c.ID) >= 0) : []),
|
||||
privateProcessItems: computed(() => user.value ? user.value.Processs.filter(c => state.rule.PrivateProcesss.indexOf(c.Name) >= 0) : []),
|
||||
publicProcess: computed(() => usePublic ? publicUser.value.Processs : []),
|
||||
publicProcessItems: computed(() => usePublic ? publicUser.value.Processs.filter(c => state.rule.PublicProcesss.indexOf(c.ID) >= 0) : []),
|
||||
publicProcessItems: computed(() => usePublic ? publicUser.value.Processs.filter(c => state.rule.PublicProcesss.indexOf(c.Name) >= 0) : []),
|
||||
});
|
||||
watch(() => state.show, (val) => {
|
||||
if (!val) {
|
||||
@@ -78,36 +79,43 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const privateProcess = ref(null);
|
||||
const publicProcess = ref(null);
|
||||
|
||||
const handleSave = () => {
|
||||
let rule = user.value.Rules.filter(c => c.ID == state.group)[0];
|
||||
if (!rule) {
|
||||
ElMessage.error('未选择任何限制分组');
|
||||
return;
|
||||
}
|
||||
rule.PrivateProcesss = privateProcess.value.getData().map(c => c.ID);
|
||||
rule.PublicProcesss = publicProcess.value.getData().map(c => c.ID);
|
||||
|
||||
const _updateRule = () => {
|
||||
const rules = globalData.value.usernames[globalData.value.username].Rules || [];
|
||||
rules.forEach(element => {
|
||||
element.PrivateProcesss = element.PrivateProcesss.filter(c => typeof (c) != 'number');
|
||||
element.PublicProcesss = element.PublicProcesss.filter(c => typeof (c) != 'number');
|
||||
});
|
||||
state.loading = true;
|
||||
addRule({
|
||||
UserName: globalData.value.username,
|
||||
Rule: rule
|
||||
updateRule({
|
||||
username: globalData.value.username,
|
||||
Data: rules
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
ElMessage.success('操作成功');
|
||||
state.showEdit = false;
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
}
|
||||
}).catch(() => {
|
||||
}).catch((e) => {
|
||||
state.loading = false;
|
||||
ElMessage.error('操作失败');
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleSave = () => {
|
||||
let rule = user.value.Rules.filter(c => c.Name == state.group)[0];
|
||||
if (!rule) {
|
||||
ElMessage.error('未选择任何限制分组');
|
||||
return;
|
||||
}
|
||||
rule.PrivateProcesss = privateProcess.value.getData().map(c => c.Name);
|
||||
rule.PublicProcesss = publicProcess.value.getData().map(c => c.Name);
|
||||
_updateRule();
|
||||
}
|
||||
|
||||
return {
|
||||
state, handleSave, privateProcess, publicProcess
|
||||
|
||||
120
cmonitor.web/src/views/device/plugins/modes/ChooseDig.vue
Normal file
120
cmonitor.web/src/views/device/plugins/modes/ChooseDig.vue
Normal file
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<el-dialog class="options options-center" title="模式" destroy-on-close v-model="state.show" center :close-on-click-modal="false" align-center width="94%">
|
||||
<div class="modes-wrap flex">
|
||||
<div class="items">
|
||||
<CheckBoxWrap ref="devices" :data="globalData.devices" :items="state.items" label="MachineName" title="选择设备"></CheckBoxWrap>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="modes">
|
||||
<div class="inner absolute scrollbar">
|
||||
<template v-for="(item,index) in state.modes" :key="index">
|
||||
<div class="item">
|
||||
<div class="subitem flex">
|
||||
<span class="label flex-1">{{item.Name}}</span>
|
||||
<el-button @click="handleUseMode(item)">应用-{{item.Name}}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="handleCancel">取 消</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive, ref } from '@vue/reactivity';
|
||||
import { computed, onMounted, watch } from '@vue/runtime-core';
|
||||
import CheckBoxWrap from '../../boxs/CheckBoxWrap.vue'
|
||||
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
import { injectPluginState } from '../../provide';
|
||||
import { useModes } from '../../../../apis/modes';
|
||||
|
||||
export default {
|
||||
props: ['modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
components: { CheckBoxWrap },
|
||||
setup(props, { emit }) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const pluginState = injectPluginState();
|
||||
const devices = ref(null);
|
||||
const state = reactive({
|
||||
show: props.modelValue,
|
||||
items: computed(() => pluginState.value.modes.devices),
|
||||
modes: computed(() => (globalData.value.usernames[globalData.value.username] || {}).Modes || []),
|
||||
loading: false
|
||||
});
|
||||
watch(() => state.show, (val) => {
|
||||
if (!val) {
|
||||
setTimeout(() => {
|
||||
emit('update:modelValue', val);
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
|
||||
const handleCancel = () => {
|
||||
state.show = false;
|
||||
}
|
||||
const handleUseMode = (item) => {
|
||||
const devicesNames = devices.value.getData().map(c => c.MachineName);
|
||||
if (devicesNames.length == 0) {
|
||||
ElMessage.error('请选择设备');
|
||||
return;
|
||||
}
|
||||
const funcs = [];
|
||||
const json = JSON.parse(item.Data);
|
||||
for (let j in json) {
|
||||
if (json[j].use) {
|
||||
funcs.push(useModes(devicesNames, json[j].list, json[j].ids1, json[j].ids2, json[j].path));
|
||||
}
|
||||
}
|
||||
Promise.all(funcs).then(res => {
|
||||
ElMessage.success('设置成功');
|
||||
}).catch(() => {
|
||||
ElMessage.error('设置失败');
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
state, globalData, devices, handleCancel, handleUseMode
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.modes-wrap {
|
||||
height: 70vh;
|
||||
position: relative;
|
||||
|
||||
.items {
|
||||
height: 100%;
|
||||
width: 36%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.modes {
|
||||
height: 100%;
|
||||
width: 62%;
|
||||
position: relative;
|
||||
border: 1px solid #ddd;
|
||||
box-sizing: border-box;
|
||||
|
||||
.label {
|
||||
line-height: 3.2rem;
|
||||
}
|
||||
|
||||
.inner {
|
||||
padding: 0.6rem;
|
||||
|
||||
&>div {
|
||||
padding: 0.6rem 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -3,7 +3,7 @@
|
||||
<el-icon>
|
||||
<Help />
|
||||
</el-icon>
|
||||
<span>设置</span>
|
||||
<span>模式</span>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
@@ -15,7 +15,7 @@ export default {
|
||||
|
||||
const pluginState = injectPluginState();
|
||||
const handleSetting = () => {
|
||||
pluginState.value.setting.showSetting = true;
|
||||
pluginState.value.modes.showModesSetting = true;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<el-button size="small" plain dark @click="handleMode">模式<el-icon>
|
||||
<Help />
|
||||
</el-icon></el-button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
import { injectPluginState } from '../../provide';
|
||||
export default {
|
||||
setup() {
|
||||
|
||||
const pluginState = injectPluginState();
|
||||
const globalData = injectGlobalData();
|
||||
const handleMode = () => {
|
||||
pluginState.value.modes.devices = globalData.value.devices;
|
||||
pluginState.value.modes.showModes = true;
|
||||
}
|
||||
|
||||
return {
|
||||
handleMode
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped></style>
|
||||
@@ -1,14 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<ChooseDig v-if="pluginState.setting.showSetting" v-model="pluginState.setting.showSetting"></ChooseDig>
|
||||
<ChooseDig v-if="pluginState.modes.showModes" v-model="pluginState.modes.showModes"></ChooseDig>
|
||||
<SettingDig v-if="pluginState.modes.showModesSetting" v-model="pluginState.modes.showModesSetting"></SettingDig>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { injectPluginState } from '../../provide';
|
||||
import ChooseDig from './ChooseDig.vue'
|
||||
import SettingDig from './SettingDig.vue'
|
||||
export default {
|
||||
components: { ChooseDig },
|
||||
components: { ChooseDig, SettingDig },
|
||||
setup() {
|
||||
const pluginState = injectPluginState();
|
||||
return { pluginState }
|
||||
196
cmonitor.web/src/views/device/plugins/modes/SettingDig.vue
Normal file
196
cmonitor.web/src/views/device/plugins/modes/SettingDig.vue
Normal file
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<div class="modes-setting-wrap">
|
||||
<el-dialog class="options options-center" title="模式设置" destroy-on-close v-model="state.show" center :close-on-click-modal="false" align-center width="94%">
|
||||
<div class="modes-wrap flex flex-column flex-nowrap">
|
||||
<div class="head t-c">
|
||||
<el-select size="small" v-model="state.mode" placeholder="Select" style="width: 80px;margin-right:.6rem">
|
||||
<el-option v-for="item in state.items" :key="item.Name" :label="item.Name" :value="item.Name" />
|
||||
</el-select>
|
||||
<el-button size="small" @click="handleAdd">增加</el-button>
|
||||
<el-button size="small" @click="handleEdit">编辑</el-button>
|
||||
<el-popconfirm title="删除不可逆,确认吗?" @confirm="handleDelete">
|
||||
<template #reference>
|
||||
<el-button size="small" type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
|
||||
<el-button size="small" type="primary" @click="handleSave">保存</el-button>
|
||||
</div>
|
||||
<div class="plugins flex-1">
|
||||
<el-tabs type="border-card" class="absolute flex flex-column flxex-nowrap">
|
||||
<template v-for="(item,index) in commandModules" :key="index">
|
||||
<el-tab-pane :label="item.label" class="absolute">
|
||||
<component :ref="`mode-${item.label}`" :is="item"></component>
|
||||
</el-tab-pane>
|
||||
|
||||
</template>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="handleCancel">取 消</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive, ref } from '@vue/reactivity';
|
||||
import { computed, getCurrentInstance, provide, watch } from '@vue/runtime-core';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
import { updateModes } from '../../../../apis/modes';
|
||||
|
||||
export default {
|
||||
props: ['modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
components: {},
|
||||
setup(props, { emit }) {
|
||||
|
||||
const commandFiles = require.context('../../plugins/', true, /Modes\.vue/);
|
||||
const commandModules = commandFiles.keys().map(c => commandFiles(c).default);
|
||||
const current = getCurrentInstance();
|
||||
const globalData = injectGlobalData();
|
||||
const modeState = ref({});
|
||||
provide('mode-state', modeState);
|
||||
|
||||
const state = reactive({
|
||||
show: props.modelValue,
|
||||
loading: false,
|
||||
mode: '',
|
||||
mode1: '',
|
||||
items: computed(() => {
|
||||
const arr = globalData.value.usernames[globalData.value.username].Modes || [];
|
||||
if (arr.length > 0 && state.mode == '') {
|
||||
state.mode = arr[0].Name;
|
||||
}
|
||||
const value = (globalData.value.usernames[globalData.value.username].Modes || []).filter(c => c.Name == state.mode)[0] || { Data: '{}' };
|
||||
modeState.value = value.Data;
|
||||
return arr;
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
watch(() => state.show, (val) => {
|
||||
if (!val) {
|
||||
setTimeout(() => {
|
||||
emit('update:modelValue', val);
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
const handleCancel = () => {
|
||||
state.show = false;
|
||||
}
|
||||
const handleSubmit = () => {
|
||||
state.show = false;
|
||||
}
|
||||
|
||||
const edit = () => {
|
||||
const isEdit = state.mode1 != '';
|
||||
const title = isEdit ? `编辑【${state.mode1}】` : `增加新项`;
|
||||
ElMessageBox.prompt('输入名字', title, {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
inputValue: state.mode1
|
||||
}).then(({ value }) => {
|
||||
value = value.replace(/^\s|\s$/g, '');
|
||||
if (value) {
|
||||
|
||||
const modes = globalData.value.usernames[globalData.value.username].Modes;
|
||||
if (isEdit) {
|
||||
const mode = modes.filter(c => c.Name == state.mode1)[0];
|
||||
mode.Name = value;
|
||||
} else {
|
||||
modes.push({ Name: value, Data: '{}' });
|
||||
}
|
||||
state.mode = value;
|
||||
saveModes();
|
||||
}
|
||||
}).catch(() => { })
|
||||
}
|
||||
const handleAdd = () => {
|
||||
state.mode1 = '';
|
||||
edit();
|
||||
}
|
||||
const handleEdit = () => {
|
||||
state.mode1 = state.mode;
|
||||
edit();
|
||||
}
|
||||
const handleDelete = () => {
|
||||
const modes = globalData.value.usernames[globalData.value.username].Modes;
|
||||
const names = modes.map(c => c.Name);
|
||||
modes.splice(names.indexOf(state.mode), 1);
|
||||
state.mode = modes[0] || '';
|
||||
saveModes();
|
||||
}
|
||||
|
||||
const saveModes = () => {
|
||||
updateModes({
|
||||
username: globalData.value.username,
|
||||
Data: globalData.value.usernames[globalData.value.username].Modes
|
||||
}).then(() => {
|
||||
state.loading = false;
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
ElMessage.success('已操作')
|
||||
}).catch(() => {
|
||||
state.loading = false;
|
||||
ElMessage.error('操作失败')
|
||||
})
|
||||
}
|
||||
const handleSave = () => {
|
||||
if (!state.mode) {
|
||||
ElMessage.error('请选择一个模式');
|
||||
return;
|
||||
}
|
||||
const mode = globalData.value.usernames[globalData.value.username].Modes.filter(c => c.Name == state.mode)[0];
|
||||
if (!mode) {
|
||||
ElMessage.error('请选择一个模式');
|
||||
return;
|
||||
}
|
||||
|
||||
const json = {};
|
||||
for (let i = 0; i < commandModules.length; i++) {
|
||||
json[commandModules[i].label] = current.refs[`mode-${commandModules[i].label}`][0].getData();
|
||||
}
|
||||
mode.Data = JSON.stringify(json);
|
||||
|
||||
saveModes();
|
||||
}
|
||||
|
||||
return {
|
||||
state, globalData, commandModules, handleCancel, handleSubmit, handleAdd, handleEdit, handleDelete, handleSave
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus">
|
||||
.modes-setting-wrap {
|
||||
.el-tabs__content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="stylus" scoped>
|
||||
.modes-wrap {
|
||||
height: 70vh;
|
||||
position: relative;
|
||||
|
||||
.head {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.plugins {
|
||||
// border: 1px solid #ddd;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
.el-tab-pane {
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
14
cmonitor.web/src/views/device/plugins/modes/index.js
Normal file
14
cmonitor.web/src/views/device/plugins/modes/index.js
Normal file
@@ -0,0 +1,14 @@
|
||||
export default {
|
||||
field() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
state: {
|
||||
modes: {
|
||||
showModes: false,
|
||||
showModesSetting: false,
|
||||
devices: []
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
<template>
|
||||
<el-dialog class="options-center" title="设置" destroy-on-close v-model="state.show" center :close-on-click-modal="false" align-center width="94%">
|
||||
<div class="setting-wrap">
|
||||
<el-form ref="ruleFormRef" :model="state.form" :rules="state.rules" label-width="100px">
|
||||
<el-form-item label="报告延迟(ms)" prop="ReportDelay">
|
||||
<el-input-number size="large" v-model="state.form.ReportDelay" :min="17" :max="1000" controls-position="right" />
|
||||
</el-form-item>
|
||||
<el-form-item label="截屏延迟(ms)" prop="ScreenDelay">
|
||||
<el-input-number size="large" v-model="state.form.ScreenDelay" :min="17" :max="1000" controls-position="right" />
|
||||
</el-form-item>
|
||||
<el-form-item label="截屏缩放" prop="ScreenScale">
|
||||
<el-input-number size="large" v-model="state.form.ScreenScale" :min="0.1" :max="1" :step="0.1" controls-position="right" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="保存配置" prop="SaveSetting">
|
||||
<el-checkbox v-model="state.form.SaveSetting">保存限制配置</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item label="黑屏唤醒" prop="WakeUp">
|
||||
<el-checkbox v-model="state.form.WakeUp">黑屏时唤醒</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item label="声音峰值" prop="VolumeMasterPeak">
|
||||
<el-checkbox v-model="state.form.VolumeMasterPeak">报告声音峰值</el-checkbox>
|
||||
</el-form-item> -->
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="handleCancel">取 消</el-button>
|
||||
<el-button type="success" plain :loading="state.loading" @click="handleSubmit">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive, ref } from '@vue/reactivity';
|
||||
import { onMounted, watch } from '@vue/runtime-core';
|
||||
import CheckBoxWrap from '../../boxs/CheckBoxWrap.vue'
|
||||
import { getSetting, saveSetting } from '../../../../apis/setting'
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
export default {
|
||||
props: ['modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
components: { CheckBoxWrap },
|
||||
setup(props, { emit }) {
|
||||
const state = reactive({
|
||||
show: props.modelValue,
|
||||
loading: false,
|
||||
rules: [],
|
||||
form: {
|
||||
ReportDelay: 0,
|
||||
ScreenDelay: 0,
|
||||
ScreenScale: 0,
|
||||
SaveSetting: true,
|
||||
WakeUp: true,
|
||||
VolumeMasterPeak: true,
|
||||
}
|
||||
});
|
||||
watch(() => state.show, (val) => {
|
||||
if (!val) {
|
||||
setTimeout(() => {
|
||||
emit('update:modelValue', val);
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
|
||||
const loadData = () => {
|
||||
getSetting().then((res) => {
|
||||
state.form.ReportDelay = res.ReportDelay;
|
||||
state.form.ScreenDelay = res.ScreenDelay;
|
||||
state.form.ScreenScale = res.ScreenScale;
|
||||
state.form.SaveSetting = res.SaveSetting;
|
||||
state.form.WakeUp = res.WakeUp;
|
||||
state.form.VolumeMasterPeak = res.VolumeMasterPeak;
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
state.show = false;
|
||||
}
|
||||
const devices = ref(null);
|
||||
const handleSubmit = () => {
|
||||
state.loading = true;
|
||||
saveSetting(state.form).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.success('操作成功!');
|
||||
state.show = false;
|
||||
} else {
|
||||
ElMessage.error('操作失败!');
|
||||
}
|
||||
}).catch(() => {
|
||||
state.loading = false;
|
||||
ElMessage.error('操作失败!');
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
|
||||
return {
|
||||
state, devices, handleCancel, handleSubmit
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.setting-wrap {
|
||||
position: relative;
|
||||
padding: 2rem 5rem;
|
||||
}
|
||||
</style>
|
||||
@@ -1,12 +0,0 @@
|
||||
export default {
|
||||
field() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
state: {
|
||||
setting: {
|
||||
showSetting: false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <ChooseDig v-if="pluginState.setting.showSetting" v-model="pluginState.setting.showSetting"></ChooseDig> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { injectPluginState } from '../../provide';
|
||||
// import ChooseDig from './ChooseDig.vue'
|
||||
export default {
|
||||
components: {},
|
||||
setup() {
|
||||
|
||||
@@ -9,28 +9,26 @@
|
||||
<el-table-column prop="Name" label="名称" />
|
||||
<el-table-column label="操作" width="110">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.ID > 1">
|
||||
<el-button size="small" @click="handleAdd(scope.row)">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-popconfirm title="删除不可逆,是否确定?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button size="small" type="danger">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
<el-button size="small" @click="handleAdd(scope.row)">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-popconfirm title="删除不可逆,是否确定?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button size="small" type="danger">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog :title="`${state.currentItem.ID==0?'添加项':'修改项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<el-dialog :title="`${state.currentItem.Name1==0?'修改项':'添加项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||
<div>
|
||||
<el-input v-model="state.currentItem.Name" size="large" placeholder="分组名称" />
|
||||
</div>
|
||||
@@ -46,7 +44,7 @@
|
||||
import { reactive } from '@vue/reactivity';
|
||||
import { computed } from '@vue/runtime-core';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { addGroup, delGroup } from '@/apis/snatch'
|
||||
import { updateSnatch } from '@/apis/snatch'
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
setup() {
|
||||
@@ -54,13 +52,13 @@ export default {
|
||||
const globalData = injectGlobalData();;
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
currentItem: { ID: 0, Name: '' },
|
||||
currentItem: { Name: '', Name1: '' },
|
||||
showEdit: false,
|
||||
list: computed(() => {
|
||||
let user = globalData.value.usernames[globalData.value.username];
|
||||
if (user && user.Snatchs) {
|
||||
if (state.group == 0 && user.Snatchs.length > 0) {
|
||||
state.group = user.Snatchs[0].ID;
|
||||
if (state.group == '' && user.Snatchs.length > 0) {
|
||||
state.group = user.Snatchs[0].Name;
|
||||
}
|
||||
return user.Snatchs;
|
||||
}
|
||||
@@ -69,18 +67,27 @@ export default {
|
||||
});
|
||||
|
||||
const handleAdd = (item) => {
|
||||
item = item || { Name: '', ID: 0 };
|
||||
item = item || { Name: '', Name1: '' };
|
||||
state.currentItem.Name = item.Name;
|
||||
state.currentItem.ID = item.ID;
|
||||
state.currentItem.Name1 = item.Name;
|
||||
state.showEdit = true;
|
||||
}
|
||||
const handleDel = (item) => {
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
}
|
||||
|
||||
const updateSnatchGroup = () => {
|
||||
const snatchs = globalData.value.usernames[globalData.value.username].Snatchs || [];
|
||||
state.loading = true;
|
||||
delGroup(globalData.value.username, item.ID).then((error) => {
|
||||
updateSnatch({
|
||||
username: globalData.value.username,
|
||||
Data: snatchs
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
state.showEdit = false;
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
}
|
||||
@@ -89,32 +96,36 @@ export default {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
const handleDel = (item) => {
|
||||
const snatchs = globalData.value.usernames[globalData.value.username].Snatchs || [];
|
||||
const names = snatchs.map(c => c.Name);
|
||||
snatchs.splice(names.indexOf(item.Name), 1);
|
||||
globalData.value.usernames[globalData.value.username].Snatchs = snatchs;
|
||||
updateSnatchGroup();
|
||||
}
|
||||
const handleEditSubmit = () => {
|
||||
state.currentItem.Name = state.currentItem.Name.replace(/^\s|\s$/g, '');
|
||||
if (!state.currentItem.Name) {
|
||||
return;
|
||||
}
|
||||
state.loading = true;
|
||||
addGroup({
|
||||
UserName: globalData.value.username,
|
||||
Group: state.currentItem
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
ElMessage.success('操作成功!');
|
||||
state.showEdit = false;
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
|
||||
const snatchs = globalData.value.usernames[globalData.value.username].Snatchs || [];
|
||||
const names = snatchs.map(c => c.Name);
|
||||
let index = names.indexOf(state.currentItem.Name1);
|
||||
if (index == -1) {
|
||||
if (names.indexOf(state.currentItem.Name) >= 0) {
|
||||
ElMessage.error('已存在同名');
|
||||
return;
|
||||
}
|
||||
}).catch((e) => {
|
||||
state.loading = false;
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
snatchs.push({ Name: state.currentItem.Name })
|
||||
} else {
|
||||
snatchs[index].Name = state.currentItem.Name;
|
||||
}
|
||||
globalData.value.usernames[globalData.value.username].Snatchs = snatchs;
|
||||
updateSnatchGroup();
|
||||
}
|
||||
|
||||
|
||||
return { state, handleAdd, handleDel, handleEditCancel, handleEditSubmit }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="snatchs-items-wrap flex flex-nowrap flex-column">
|
||||
<div class="head t-c flex">
|
||||
<el-select v-model="state.group" placeholder="选择一个分组" style="width:13rem">
|
||||
<el-option v-for="item in state.groups" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||
<el-option v-for="item in state.groups" :key="item.Name" :label="item.Name" :value="item.Name" />
|
||||
</el-select>
|
||||
<span class="flex-1"></span>
|
||||
<el-button @click="handleAdd()">添加项</el-button>
|
||||
@@ -32,7 +32,7 @@
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog :title="`${state.currentItem.ID==0?'添加项':'修改项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="94%">
|
||||
<el-dialog :title="`${state.currentItem.Title1?'修改项':'添加项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="94%">
|
||||
<div>
|
||||
<el-form ref="formDom" :rules="state.rules" :model="state.currentItem" label-width="0">
|
||||
<el-form-item prop="Title">
|
||||
@@ -112,8 +112,8 @@ export default {
|
||||
const globalData = injectGlobalData();;
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
group: 0,
|
||||
currentItem: { ID: 0, Title: '', Cate: 1, Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Chance: 65535 },
|
||||
group: '',
|
||||
currentItem: { Title: '', Title1: '', Cate: 1, Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Chance: 65535 },
|
||||
rules: {
|
||||
Title: [
|
||||
{ required: true, message: '名称必填', trigger: 'blur' }
|
||||
@@ -139,15 +139,15 @@ export default {
|
||||
groups: computed(() => {
|
||||
let user = globalData.value.usernames[globalData.value.username];
|
||||
if (user && user.Snatchs) {
|
||||
if (state.group == 0 && user.Snatchs.length > 0) {
|
||||
state.group = user.Snatchs[0].ID;
|
||||
if (state.group == '' && user.Snatchs.length > 0) {
|
||||
state.group = user.Snatchs[0].Name;
|
||||
}
|
||||
return user.Snatchs;
|
||||
}
|
||||
return [];
|
||||
}),
|
||||
list: computed(() => {
|
||||
let group = state.groups.filter(c => c.ID == state.group)[0];
|
||||
let group = state.groups.filter(c => c.Name == state.group)[0];
|
||||
if (group) return group.List;
|
||||
return [];
|
||||
})
|
||||
@@ -159,23 +159,33 @@ export default {
|
||||
}
|
||||
}
|
||||
const handleAdd = (item) => {
|
||||
item = item || { ID: 0, Title: '', Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Chance: 65535 };
|
||||
item = item || { Title: '', Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Chance: 65535 };
|
||||
state.currentItem.Title = item.Title;
|
||||
state.currentItem.Title1 = item.Title;
|
||||
state.currentItem.Type = item.Type;
|
||||
state.currentItem.ID = item.ID;
|
||||
state.currentItem.Question = item.Question;
|
||||
state.currentItem.Options = item.Options;
|
||||
state.currentItem.Correct = item.Correct;
|
||||
state.currentItem.Chance = item.Chance;
|
||||
state.showEdit = true;
|
||||
}
|
||||
const handleDel = (item) => {
|
||||
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
}
|
||||
|
||||
const updateSnatchGroup = () => {
|
||||
const processs = globalData.value.usernames[globalData.value.username].Processs || [];
|
||||
state.loading = true;
|
||||
del(globalData.value.username, state.group, item.ID).then((error) => {
|
||||
updateProcess({
|
||||
username: globalData.value.username,
|
||||
Data: processs
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
state.showEdit = false;
|
||||
ElMessage.success('操作成功!');
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
}
|
||||
@@ -184,38 +194,46 @@ export default {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleEditCancel = () => {
|
||||
state.showEdit = false;
|
||||
}
|
||||
|
||||
const handleDel = (item) => {
|
||||
const snatchs = globalData.value.usernames[globalData.value.username].Snatchs || [];
|
||||
const group = snatchs.filter(c => c.Name == state.group)[0];
|
||||
const items = group.List;
|
||||
|
||||
const names = items.map(c => c.Title);
|
||||
items.splice(names.indexOf(item.Title), 1);
|
||||
|
||||
globalData.value.usernames[globalData.value.username].Snatchs = snatchs;
|
||||
|
||||
updateSnatchGroup();
|
||||
}
|
||||
const formDom = ref(null);
|
||||
const handleEditSubmit = () => {
|
||||
formDom.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
|
||||
state.loading = true;
|
||||
const snatchs = globalData.value.usernames[globalData.value.username].Snatchs || [];
|
||||
const group = snatchs.filter(c => c.Name == state.group)[0];
|
||||
const items = group.List;
|
||||
const names = items.map(c => c.Title);
|
||||
|
||||
let index = names.indexOf(state.currentItem.Title1);
|
||||
const json = JSON.parse(JSON.stringify(state.currentItem));
|
||||
json.Chance = +json.Chance;
|
||||
json.Type = +json.Type;
|
||||
json.Title = json.Title.replace(/^\s|\s$/g, '');
|
||||
json.Correct = json.Correct.replace(/^\s|\s$/g, '');
|
||||
add({
|
||||
UserName: globalData.value.username,
|
||||
GroupID: state.group,
|
||||
Item: json
|
||||
}).then((error) => {
|
||||
state.loading = false;
|
||||
if (error) {
|
||||
ElMessage.error(error);
|
||||
} else {
|
||||
ElMessage.success('操作成功!');
|
||||
state.showEdit = false;
|
||||
globalData.value.updateRuleFlag = Date.now();
|
||||
|
||||
if (index == -1) {
|
||||
if (names.indexOf(state.currentItem.Title) >= 0) {
|
||||
ElMessage.error('已存在同名');
|
||||
return;
|
||||
}
|
||||
}).catch((e) => {
|
||||
state.loading = false;
|
||||
ElMessage.error('操作失败!');
|
||||
});
|
||||
items.push({ Chance: +json.Chance, Type: +json.Type, Title: json.Title.replace(/^\s|\s$/g, ''), Correct: json.Correct.replace(/^\s|\s$/g, '') })
|
||||
} else {
|
||||
items[index].Chance = +json.Chance;
|
||||
items[index].Type = +json.Type;
|
||||
items[index].Title = json.Title.replace(/^\s|\s$/g, '');
|
||||
items[index].Correct = json.Correct.replace(/^\s|\s$/g, '');
|
||||
}
|
||||
globalData.value.usernames[globalData.value.username].Snatchs = snatchs;
|
||||
updateSnatchGroup();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<el-select v-model="state.group" placeholder="选择一个分组" style="width:13rem">
|
||||
<el-option v-for="item in state.groups" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||
<el-option v-for="item in state.groups" :key="item.Name" :label="item.Name" :value="item.Name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<el-select @change="handleItemChange" v-model="state.item" placeholder="选择一个模板" style="width:13rem">
|
||||
<el-option v-for="item in state.list" :key="item.ID" :label="item.Title" :value="item.ID" />
|
||||
<el-option v-for="item in state.list" :key="item.Title" :label="item.Title" :value="item.Title" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -98,9 +98,9 @@ export default {
|
||||
const pluginState = injectPluginState();
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
group: 0,
|
||||
item: 0,
|
||||
currentItem: { ID: 0, Cate: 1, Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Chance: 65535 },
|
||||
group: '',
|
||||
item: '',
|
||||
currentItem: { Cate: 1, Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Chance: 65535 },
|
||||
rules: {
|
||||
Question: [
|
||||
{ required: true, message: '内容必填', trigger: 'blur' }
|
||||
@@ -123,17 +123,17 @@ export default {
|
||||
let user = globalData.value.usernames[globalData.value.username];
|
||||
if (user && user.Snatchs) {
|
||||
if (state.group == 0 && user.Snatchs.length > 0) {
|
||||
state.group = user.Snatchs[0].ID;
|
||||
state.group = user.Snatchs[0].Name;
|
||||
}
|
||||
return user.Snatchs;
|
||||
}
|
||||
return [];
|
||||
}),
|
||||
list: computed(() => {
|
||||
let group = state.groups.filter(c => c.ID == state.group)[0];
|
||||
let group = state.groups.filter(c => c.Name == state.group)[0];
|
||||
if (group) {
|
||||
if (state.item == 0 && group.List.length > 0) {
|
||||
state.item = group.List[0].ID;
|
||||
state.item = group.List[0].Title;
|
||||
}
|
||||
return group.List;
|
||||
}
|
||||
@@ -147,10 +147,10 @@ export default {
|
||||
}
|
||||
}
|
||||
const handleItemChange = () => {
|
||||
const item = state.list.filter(c => c.ID == state.item)[0] || { ID: 0, Cate: 1, Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Chance: 65535 };
|
||||
const item = state.list.filter(c => c.Title == state.item)[0] || { Cate: 1, Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Chance: 65535 };
|
||||
state.currentItem.Cate = item.Cate;
|
||||
state.currentItem.Type = item.Type;
|
||||
state.currentItem.ID = item.ID;
|
||||
state.currentItem.Title = item.Title;
|
||||
state.currentItem.Question = item.Question;
|
||||
state.currentItem.Options = item.Options;
|
||||
state.currentItem.Correct = item.Correct;
|
||||
@@ -244,6 +244,16 @@ export default {
|
||||
handleRandom();
|
||||
}).catch(() => { });
|
||||
}
|
||||
const randomQuestion = (length) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const snatchs = globalData.value.usernames[globalData.value.username].Snatchs || [];
|
||||
const questions = snatchs.reduce((arr, current) => {
|
||||
arr = arr.concat(current.List);
|
||||
return arr;
|
||||
}, []).sort((a, b) => Math.random() - 0.5);
|
||||
resolve(questions.filter((value, index) => index < length));
|
||||
});
|
||||
}
|
||||
const handleRandom = () => {
|
||||
const names = pluginState.value.command.devices.map(c => c.MachineName);
|
||||
state.loading = true;
|
||||
|
||||
95
cmonitor.web/src/views/device/plugins/system/Modes.vue
Normal file
95
cmonitor.web/src/views/device/plugins/system/Modes.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="absolute flex flex-column flex-nowrap">
|
||||
<div class="head">
|
||||
<el-checkbox v-model="state.use">使用规则</el-checkbox>
|
||||
</div>
|
||||
<div class="body flex-1 scrollbar">
|
||||
<ul>
|
||||
<template v-for="(item,index) in state.options" :key="index">
|
||||
<li class="flex">
|
||||
<span class="label">{{item.label}}</span>
|
||||
<span class="flex-1"></span>
|
||||
<div class="options">
|
||||
<el-switch v-model="item.value" inline-prompt active-text="禁用" inactive-text="启用" size="large" />
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive } from '@vue/reactivity';
|
||||
import { getCurrentInstance, inject, onMounted, watch } from '@vue/runtime-core';
|
||||
import { injectGlobalData } from '@/views/provide';
|
||||
export default {
|
||||
label: '系统选项',
|
||||
setup(props, { emit }) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const current = getCurrentInstance();
|
||||
const modeState = inject('mode-state');
|
||||
const state = reactive({
|
||||
use: false,
|
||||
options: []
|
||||
});
|
||||
watch(() => modeState.value, () => {
|
||||
parseMode();
|
||||
});
|
||||
|
||||
const parseMode = () => {
|
||||
const json = JSON.parse(modeState.value)[current.type.label] || {};
|
||||
state.use = json.use || false;
|
||||
const list = (json.list || []).reduce((json, current) => {
|
||||
json[current.key] = current.value;
|
||||
return json;
|
||||
}, {});
|
||||
parseOptions(list);
|
||||
}
|
||||
const parseOptions = (list) => {
|
||||
const optionJson = globalData.value.allDevices.reduce((json, value, index) => {
|
||||
json = Object.assign(json, value.System.OptionKeys);
|
||||
return json;
|
||||
}, {});
|
||||
const keys = Object.keys(optionJson);
|
||||
const arr = keys.map(c => {
|
||||
const item = optionJson[c];
|
||||
return { key: c, label: item.Desc, index: item.Index, value: list[c] || false }
|
||||
}).filter(c => c.label).sort((a, b) => a.index - b.index);
|
||||
state.options = arr
|
||||
}
|
||||
|
||||
onMounted(() => { parseMode(); });
|
||||
|
||||
const getData = () => {
|
||||
return {
|
||||
path: 'system/registryoptions',
|
||||
use: state.use,
|
||||
ids1: state.options.filter(c => c.value).map(c => c.key),
|
||||
ids2: [],
|
||||
list: state.options.map(c => {
|
||||
return {
|
||||
key: c.key,
|
||||
value: c.value
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
state, getData
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.el-switch {
|
||||
--el-switch-on-color: rgba(255, 0, 0, 0.8) !important;
|
||||
}
|
||||
|
||||
.body {
|
||||
border: 1px solid #ddd;
|
||||
padding: 1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -47,7 +47,7 @@ export default {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
updateRegistryOptions([props.data.MachineName], [key], value).then((res) => {
|
||||
updateRegistryOptions([props.data.MachineName], [{ key: key, value: value }]).then((res) => {
|
||||
if (res) {
|
||||
ElMessage.success('操作成功');
|
||||
resolve();
|
||||
@@ -77,8 +77,11 @@ export default {
|
||||
const newValue = !shutdown.value;
|
||||
handleChange('NoClose', shutdown.value ? '确定启用关机按钮吗?' : '确定禁用关机按钮吗?', newValue).then(() => {
|
||||
updateRegistryOptions([props.data.MachineName], [
|
||||
'NoLogOff', 'DisableLockWorkstation', 'HideFastUserSwitching', 'DisableChangePassword'
|
||||
], newValue);
|
||||
{ key: 'NoLogOff', value: newValue },
|
||||
{ key: 'DisableLockWorkstation', value: newValue },
|
||||
{ key: 'HideFastUserSwitching', value: newValue },
|
||||
{ key: 'DisableChangePassword', value: newValue },
|
||||
]);
|
||||
}).catch(() => { });
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ export default {
|
||||
}
|
||||
|
||||
const handleOptionChange = (item) => {
|
||||
updateRegistryOptions(pluginState.value.system.devices.map(c => c.MachineName), [item.key], item.value).then(() => {
|
||||
updateRegistryOptions(pluginState.value.system.devices.map(c => c.MachineName), [{ key: item.key, value: item.value }]).then(() => {
|
||||
ElMessage.success('已执行');
|
||||
}).catch(() => {
|
||||
ElMessage.error('执行失败');
|
||||
@@ -119,7 +119,7 @@ export default {
|
||||
ElMessage.error('请选择一个设备');
|
||||
return;
|
||||
}
|
||||
updateRegistryOptions(pluginState.value.system.devices.map(c => c.MachineName), [item.key], value).then(() => {
|
||||
updateRegistryOptions(pluginState.value.system.devices.map(c => c.MachineName), [{ key: item.key, value: value }]).then(() => {
|
||||
ElMessage.success('已执行');
|
||||
}).catch(() => {
|
||||
ElMessage.error('执行失败');
|
||||
|
||||
@@ -51,9 +51,9 @@ export default {
|
||||
Server: pluginState.value.viewer.device,
|
||||
Clients: clients,
|
||||
}).then(() => {
|
||||
pluginState.viewer.showShare = false;
|
||||
pluginState.value.viewer.showShare = false;
|
||||
ElMessage.success('操作成功');
|
||||
}).catch(() => {
|
||||
}).catch((e) => {
|
||||
ElMessage.error('操作失败');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ export default {
|
||||
|
||||
update(item, report) {
|
||||
if (!report.Viewer) return;
|
||||
|
||||
|
||||
item.Viewer.share = report.Viewer.Value;
|
||||
item.Viewer.mode = ['client', 'server'][report.Viewer.Mode];
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="foot-options-wrap flex">
|
||||
<el-button size="default" plain dark @click="handleRefresh">
|
||||
<el-button size="small" plain dark @click="handleRefresh">
|
||||
<el-icon>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
@@ -19,7 +19,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<span class="flex-1"></span>
|
||||
<el-button size="default" plain dark @click="handleUpdate">{{username}}</el-button>
|
||||
<el-button size="small" plain dark @click="handleUpdate">{{username}}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -76,11 +76,11 @@ export default {
|
||||
|
||||
.options-btn {
|
||||
.el-button+.el-button {
|
||||
margin-left: 0.6rem;
|
||||
margin-left: 0.4rem;
|
||||
}
|
||||
|
||||
p {
|
||||
padding-top: 0.6rem;
|
||||
padding-top: 0.4rem;
|
||||
|
||||
&:nth-child(1) {
|
||||
padding: 0;
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace cmonitor.client
|
||||
SignInTask();
|
||||
tcpServer.OnDisconnected += (hashcode) =>
|
||||
{
|
||||
Logger.Instance.Info($"client disconnected");
|
||||
clientSignInState.PushNetworkDisabled();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using cmonitor.client.runningConfig;
|
||||
using cmonitor.client.report;
|
||||
using cmonitor.client.ruleConfig;
|
||||
using cmonitor.config;
|
||||
using cmonitor.libs;
|
||||
using cmonitor.startup;
|
||||
using common.libs;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Reflection;
|
||||
using cmonitor.server.ruleConfig;
|
||||
|
||||
namespace cmonitor.client
|
||||
{
|
||||
@@ -14,8 +14,6 @@ namespace cmonitor.client
|
||||
{
|
||||
public void AddClient(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<RuleConfig>();
|
||||
|
||||
serviceCollection.AddSingleton<ClientReportTransfer>();
|
||||
|
||||
serviceCollection.AddSingleton<ClientSignInState>();
|
||||
@@ -33,13 +31,13 @@ namespace cmonitor.client
|
||||
|
||||
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<RuleConfig>();
|
||||
|
||||
}
|
||||
|
||||
public void UseClient(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||
{
|
||||
Logger.Instance.Info($"start client");
|
||||
Logger.Instance.Info($"server ip {config.Server}");
|
||||
Logger.Instance.Info($"server ip {config.Client.ServerEP}");
|
||||
|
||||
Logger.Instance.Info($"start client report transfer");
|
||||
ClientReportTransfer report = serviceProvider.GetService<ClientReportTransfer>();
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace cmonitor.client.ruleConfig
|
||||
{
|
||||
public interface IRuleConfig
|
||||
{
|
||||
public T Get<T>(T defaultValue);
|
||||
public T Get<T>(string name, T defaultValue);
|
||||
public void Set<T>(T data);
|
||||
}
|
||||
}
|
||||
@@ -1,675 +0,0 @@
|
||||
using cmonitor.plugins.snatch.report;
|
||||
using common.libs.database;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace cmonitor.client.ruleConfig
|
||||
{
|
||||
|
||||
[Table("rule")]
|
||||
public sealed class RuleConfig
|
||||
{
|
||||
private readonly IConfigDataProvider<RuleConfig> configDataProvider;
|
||||
public RuleConfig() { }
|
||||
public RuleConfig(IConfigDataProvider<RuleConfig> configDataProvider)
|
||||
{
|
||||
this.configDataProvider = configDataProvider;
|
||||
RuleConfig config = configDataProvider.Load().Result ?? new RuleConfig
|
||||
{
|
||||
UserNames = new Dictionary<string, UserNameInfo> { { "snltty", DefaultUser() } }
|
||||
};
|
||||
UserNames = config.UserNames;
|
||||
MaxID = config.MaxID;
|
||||
Save();
|
||||
}
|
||||
|
||||
public Dictionary<string, UserNameInfo> UserNames { get; set; } = new Dictionary<string, UserNameInfo>();
|
||||
private uint maxid = 100;
|
||||
public uint MaxID
|
||||
{
|
||||
get => maxid; set
|
||||
{
|
||||
maxid = value;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly object lockObj = new object();
|
||||
private UserNameInfo DefaultUser()
|
||||
{
|
||||
return new UserNameInfo
|
||||
{
|
||||
Rules = new List<RulesInfo> { new RulesInfo { ID = 1, Name = "默认" } },
|
||||
Processs = new List<GroupInfo> { new GroupInfo { ID = 2, Name = "默认" } },
|
||||
Windows = new List<WindowGroupInfo> { new WindowGroupInfo { ID = 3, Name = "默认" } },
|
||||
Snatchs = new List<SnatchGroupInfo> { new SnatchGroupInfo { ID = 4, Name = "默认" } },
|
||||
Modes = "{}",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public string AddName(string name)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.ContainsKey(name) == false)
|
||||
{
|
||||
UserNames.Add(name, DefaultUser());
|
||||
}
|
||||
Save();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public string AddProcessGroup(UpdateGroupInfo updateGroupInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(updateGroupInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
if (userNameInfo.Processs.FirstOrDefault(c => c.Name == updateGroupInfo.Group.Name && c.ID != updateGroupInfo.Group.ID) != null)
|
||||
{
|
||||
return "已存在同名记录";
|
||||
}
|
||||
|
||||
//添加
|
||||
if (updateGroupInfo.Group.ID == 0)
|
||||
{
|
||||
updateGroupInfo.Group.ID = Interlocked.Increment(ref maxid);
|
||||
userNameInfo.Processs.Add(updateGroupInfo.Group);
|
||||
Save();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//修改
|
||||
GroupInfo old = userNameInfo.Processs.FirstOrDefault(c => c.ID == updateGroupInfo.Group.ID);
|
||||
if (old == null)
|
||||
{
|
||||
return "不存在记录,无法修改";
|
||||
}
|
||||
old.Name = updateGroupInfo.Group.Name;
|
||||
Save();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
public string AddProcess(UpdateItemInfo updateItem)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(updateItem.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
GroupInfo group = userNameInfo.Processs.FirstOrDefault(c => c.ID == updateItem.GroupID);
|
||||
if (group == null)
|
||||
{
|
||||
return "不存在此分组";
|
||||
}
|
||||
if (group.List.FirstOrDefault(c => c.Name == updateItem.Item.Name && c.ID != updateItem.Item.ID) != null)
|
||||
{
|
||||
return "已存在同名记录";
|
||||
}
|
||||
|
||||
//添加
|
||||
if (updateItem.Item.ID == 0)
|
||||
{
|
||||
updateItem.Item.ID = Interlocked.Increment(ref maxid);
|
||||
group.List.Add(updateItem.Item);
|
||||
Save();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//修改
|
||||
ItemInfo old = group.List.FirstOrDefault(c => c.ID == updateItem.Item.ID);
|
||||
if (old == null)
|
||||
{
|
||||
return "不存在记录,无法修改";
|
||||
}
|
||||
old.Name = updateItem.Item.Name;
|
||||
old.AllowType = updateItem.Item.AllowType;
|
||||
old.DataType = updateItem.Item.DataType;
|
||||
Save();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
public string DeleteProcessGroup(DeleteGroupInfo deleteGroupInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(deleteGroupInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
|
||||
userNameInfo.Processs.Remove(userNameInfo.Processs.FirstOrDefault(c => c.ID == deleteGroupInfo.ID));
|
||||
|
||||
Save();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
public string DeleteProcess(DeleteItemInfo deleteItemInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(deleteItemInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
GroupInfo group = userNameInfo.Processs.FirstOrDefault(c => c.ID == deleteItemInfo.GroupID);
|
||||
if (group == null)
|
||||
{
|
||||
return "不存在此分组";
|
||||
}
|
||||
|
||||
group.List.Remove(group.List.FirstOrDefault(c => c.ID == deleteItemInfo.ID));
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public string AddRule(UpdateRuleInfo updateRuleInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(updateRuleInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
if (userNameInfo.Rules.FirstOrDefault(c => c.Name == updateRuleInfo.Rule.Name && c.ID != updateRuleInfo.Rule.ID) != null)
|
||||
{
|
||||
return "已存在同名记录";
|
||||
}
|
||||
|
||||
//添加
|
||||
if (updateRuleInfo.Rule.ID == 0)
|
||||
{
|
||||
updateRuleInfo.Rule.ID = Interlocked.Increment(ref maxid);
|
||||
userNameInfo.Rules.Add(updateRuleInfo.Rule);
|
||||
Save();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//修改
|
||||
RulesInfo old = userNameInfo.Rules.FirstOrDefault(c => c.ID == updateRuleInfo.Rule.ID);
|
||||
if (old == null)
|
||||
{
|
||||
return "不存在记录,无法修改";
|
||||
}
|
||||
old.Name = updateRuleInfo.Rule.Name;
|
||||
old.PrivateProcesss = updateRuleInfo.Rule.PrivateProcesss;
|
||||
old.PublicProcesss = updateRuleInfo.Rule.PublicProcesss;
|
||||
Save();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
public string DeleteRule(DeleteRuleInfo deleteRuleInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(deleteRuleInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
|
||||
userNameInfo.Rules.Remove(userNameInfo.Rules.FirstOrDefault(c => c.ID == deleteRuleInfo.ID));
|
||||
Save();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public string UpdateDevices(UpdateDevicesInfo updatDevicesInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(updatDevicesInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
|
||||
userNameInfo.Devices = updatDevicesInfo.Devices;
|
||||
Save();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public string AddWindowGroup(UpdateWindowGroupInfo updateGroupInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(updateGroupInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
if (userNameInfo.Windows.FirstOrDefault(c => c.Name == updateGroupInfo.Group.Name && c.ID != updateGroupInfo.Group.ID) != null)
|
||||
{
|
||||
return "已存在同名记录";
|
||||
}
|
||||
|
||||
//添加
|
||||
if (updateGroupInfo.Group.ID == 0)
|
||||
{
|
||||
updateGroupInfo.Group.ID = Interlocked.Increment(ref maxid);
|
||||
userNameInfo.Windows.Add(updateGroupInfo.Group);
|
||||
Save();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//修改
|
||||
WindowGroupInfo old = userNameInfo.Windows.FirstOrDefault(c => c.ID == updateGroupInfo.Group.ID);
|
||||
if (old == null)
|
||||
{
|
||||
return "不存在记录,无法修改";
|
||||
}
|
||||
old.Name = updateGroupInfo.Group.Name;
|
||||
Save();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
public string DeleteWindowGroup(DeleteWindowGroupInfo deleteGroupInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(deleteGroupInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
|
||||
userNameInfo.Windows.Remove(userNameInfo.Windows.FirstOrDefault(c => c.ID == deleteGroupInfo.ID));
|
||||
|
||||
Save();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
public string AddWindow(AddWindowItemInfo updateItem)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(updateItem.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
WindowGroupInfo group = userNameInfo.Windows.FirstOrDefault(c => c.ID == updateItem.GroupID);
|
||||
if (group == null)
|
||||
{
|
||||
return "不存在此分组";
|
||||
}
|
||||
if (group.List.FirstOrDefault(c => c.Name == updateItem.Item.Name && c.ID != updateItem.Item.ID) != null)
|
||||
{
|
||||
return "已存在同名记录";
|
||||
}
|
||||
|
||||
//添加
|
||||
if (updateItem.Item.ID == 0)
|
||||
{
|
||||
updateItem.Item.ID = Interlocked.Increment(ref maxid);
|
||||
group.List.Add(updateItem.Item);
|
||||
Save();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//修改
|
||||
WindowItemInfo old = group.List.FirstOrDefault(c => c.ID == updateItem.Item.ID);
|
||||
if (old == null)
|
||||
{
|
||||
return "不存在记录,无法修改";
|
||||
}
|
||||
old.Name = updateItem.Item.Name;
|
||||
old.Desc = updateItem.Item.Desc;
|
||||
Save();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
public string DelWindow(DeletedWindowItemInfo deletedFileNameInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(deletedFileNameInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
WindowGroupInfo group = userNameInfo.Windows.FirstOrDefault(c => c.ID == deletedFileNameInfo.GroupID);
|
||||
if (group == null)
|
||||
{
|
||||
return "不存在此分组";
|
||||
}
|
||||
|
||||
group.List.Remove(group.List.FirstOrDefault(c => c.ID == deletedFileNameInfo.ID));
|
||||
Save();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public string AddSnatchGroup(UpdateSnatchGroupInfo updateGroupInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(updateGroupInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
if (userNameInfo.Windows.FirstOrDefault(c => c.Name == updateGroupInfo.Group.Name && c.ID != updateGroupInfo.Group.ID) != null)
|
||||
{
|
||||
return "已存在同名记录";
|
||||
}
|
||||
|
||||
//添加
|
||||
if (updateGroupInfo.Group.ID == 0)
|
||||
{
|
||||
updateGroupInfo.Group.ID = Interlocked.Increment(ref maxid);
|
||||
userNameInfo.Snatchs.Add(updateGroupInfo.Group);
|
||||
Save();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//修改
|
||||
SnatchGroupInfo old = userNameInfo.Snatchs.FirstOrDefault(c => c.ID == updateGroupInfo.Group.ID);
|
||||
if (old == null)
|
||||
{
|
||||
return "不存在记录,无法修改";
|
||||
}
|
||||
old.Name = updateGroupInfo.Group.Name;
|
||||
Save();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
public string DeleteSnatchGroup(DeleteSnatchGroupInfo deleteGroupInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(deleteGroupInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
|
||||
userNameInfo.Snatchs.Remove(userNameInfo.Snatchs.FirstOrDefault(c => c.ID == deleteGroupInfo.ID));
|
||||
|
||||
Save();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
public string AddSnatch(AddSnatchItemInfo updateItem)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(updateItem.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
SnatchGroupInfo group = userNameInfo.Snatchs.FirstOrDefault(c => c.ID == updateItem.GroupID);
|
||||
if (group == null)
|
||||
{
|
||||
return "不存在此分组";
|
||||
}
|
||||
if (group.List.FirstOrDefault(c => c.Title == updateItem.Item.Title && c.ID != updateItem.Item.ID) != null)
|
||||
{
|
||||
return "已存在同名记录";
|
||||
}
|
||||
|
||||
//添加
|
||||
if (updateItem.Item.ID == 0)
|
||||
{
|
||||
updateItem.Item.ID = Interlocked.Increment(ref maxid);
|
||||
group.List.Add(updateItem.Item);
|
||||
Save();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//修改
|
||||
SnatchItemInfo old = group.List.FirstOrDefault(c => c.ID == updateItem.Item.ID);
|
||||
if (old == null)
|
||||
{
|
||||
return "不存在记录,无法修改";
|
||||
}
|
||||
old.Type = updateItem.Item.Type;
|
||||
old.Title = updateItem.Item.Title;
|
||||
old.Question = updateItem.Item.Question;
|
||||
old.Options = updateItem.Item.Options;
|
||||
old.Correct = updateItem.Item.Correct;
|
||||
old.Chance = updateItem.Item.Chance;
|
||||
|
||||
Save();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
public string DelSnatch(DeletedSnatchItemInfo deletedFileNameInfo)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (UserNames.TryGetValue(deletedFileNameInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||
{
|
||||
return "不存在此管理用户";
|
||||
}
|
||||
SnatchGroupInfo group = userNameInfo.Snatchs.FirstOrDefault(c => c.ID == deletedFileNameInfo.GroupID);
|
||||
if (group == null)
|
||||
{
|
||||
return "不存在此分组";
|
||||
}
|
||||
|
||||
group.List.Remove(group.List.FirstOrDefault(c => c.ID == deletedFileNameInfo.ID));
|
||||
Save();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
public SnatchItemInfo[] SnatchRandom(int length)
|
||||
{
|
||||
return UserNames.Values
|
||||
.SelectMany(c => c.Snatchs)
|
||||
.SelectMany(c => c.List).OrderBy(c => Guid.NewGuid())
|
||||
.Where(c => c.Cate == SnatchCate.Question)
|
||||
.Where(c => c.Type == SnatchType.Select && c.Options.Any(c => c.Value) || c.Type == SnatchType.Input && string.IsNullOrWhiteSpace(c.Correct) == false)
|
||||
.Take(length).ToArray();
|
||||
}
|
||||
|
||||
|
||||
public string UpdateModes(UpdateModesInfo info)
|
||||
{
|
||||
if (UserNames.TryGetValue(info.UserName, out UserNameInfo userNameInfo))
|
||||
{
|
||||
userNameInfo.Modes = info.Modes;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
configDataProvider.Save(this).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class UserNameInfo
|
||||
{
|
||||
public List<RulesInfo> Rules { get; set; } = new List<RulesInfo>();
|
||||
public List<GroupInfo> Processs { get; set; } = new List<GroupInfo>();
|
||||
public List<string> Devices { get; set; } = new List<string>();
|
||||
public List<WindowGroupInfo> Windows { get; set; } = new List<WindowGroupInfo>();
|
||||
public List<SnatchGroupInfo> Snatchs { get; set; } = new List<SnatchGroupInfo>();
|
||||
|
||||
public string Modes { get; set; } = "{}";
|
||||
}
|
||||
public sealed class UpdateDevicesInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public List<string> Devices { get; set; } = new List<string>();
|
||||
}
|
||||
|
||||
|
||||
public sealed class RulesInfo
|
||||
{
|
||||
public uint ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public List<uint> PrivateProcesss { get; set; } = new List<uint>();
|
||||
public List<uint> PublicProcesss { get; set; } = new List<uint>();
|
||||
}
|
||||
public sealed class UpdateRuleInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public RulesInfo Rule { get; set; }
|
||||
}
|
||||
public sealed class DeleteRuleInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public uint ID { get; set; }
|
||||
}
|
||||
|
||||
public sealed class GroupInfo
|
||||
{
|
||||
public uint ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public List<ItemInfo> List { get; set; } = new List<ItemInfo>();
|
||||
}
|
||||
public sealed class UpdateGroupInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public GroupInfo Group { get; set; }
|
||||
}
|
||||
public sealed class DeleteGroupInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public uint ID { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ItemInfo
|
||||
{
|
||||
public uint ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DataType DataType { get; set; }
|
||||
public AllowType AllowType { get; set; }
|
||||
}
|
||||
public enum DataType
|
||||
{
|
||||
Process = 0,
|
||||
Domain = 1,
|
||||
IP = 2,
|
||||
}
|
||||
public enum AllowType
|
||||
{
|
||||
Allow = 0,
|
||||
Denied = 1
|
||||
}
|
||||
|
||||
public sealed class UpdateItemInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public uint GroupID { get; set; }
|
||||
public ItemInfo Item { get; set; }
|
||||
}
|
||||
public sealed class DeleteItemInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public uint GroupID { get; set; }
|
||||
public uint ID { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public sealed class WindowGroupInfo
|
||||
{
|
||||
public uint ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public List<WindowItemInfo> List { get; set; } = new List<WindowItemInfo>();
|
||||
}
|
||||
public sealed class UpdateWindowGroupInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public WindowGroupInfo Group { get; set; }
|
||||
}
|
||||
public sealed class DeleteWindowGroupInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public uint ID { get; set; }
|
||||
}
|
||||
public sealed class WindowItemInfo
|
||||
{
|
||||
public uint ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Desc { get; set; }
|
||||
}
|
||||
public sealed class AddWindowItemInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public uint GroupID { get; set; }
|
||||
public WindowItemInfo Item { get; set; }
|
||||
}
|
||||
public sealed class DeletedWindowItemInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public uint GroupID { get; set; }
|
||||
public uint ID { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public sealed class SnatchGroupInfo
|
||||
{
|
||||
public uint ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public List<SnatchItemInfo> List { get; set; } = new List<SnatchItemInfo>();
|
||||
}
|
||||
public sealed class UpdateSnatchGroupInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public SnatchGroupInfo Group { get; set; }
|
||||
}
|
||||
public sealed class DeleteSnatchGroupInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public uint ID { get; set; }
|
||||
}
|
||||
public sealed class AddSnatchItemInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public uint GroupID { get; set; }
|
||||
public SnatchItemInfo Item { get; set; }
|
||||
}
|
||||
public sealed class DeletedSnatchItemInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public uint GroupID { get; set; }
|
||||
public uint ID { get; set; }
|
||||
}
|
||||
public sealed class SnatchItemInfo
|
||||
{
|
||||
public uint ID { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
public SnatchCate Cate { get; set; } = SnatchCate.Question;
|
||||
public SnatchType Type { get; set; } = SnatchType.Select;
|
||||
/// <summary>
|
||||
/// 问题
|
||||
/// </summary>
|
||||
public string Question { get; set; }
|
||||
/// <summary>
|
||||
/// 选项数
|
||||
/// </summary>
|
||||
public List<SnatchItemOptionInfo> Options { get; set; }
|
||||
/// <summary>
|
||||
/// 答案
|
||||
/// </summary>
|
||||
public string Correct { get; set; }
|
||||
/// <summary>
|
||||
/// 最多答题次数
|
||||
/// </summary>
|
||||
public int Chance { get; set; }
|
||||
}
|
||||
public sealed class SnatchItemOptionInfo
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public bool Value { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public sealed class UpdateModesInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string Modes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
namespace cmonitor.client.ruleConfig
|
||||
{
|
||||
/*
|
||||
public sealed class RuleConfigJsonFile : IRuleConfig
|
||||
{
|
||||
private Dictionary<string, object> cache = new Dictionary<string, object>();
|
||||
|
||||
public RuleConfigJsonFile()
|
||||
{
|
||||
}
|
||||
|
||||
public T Get<T>(T defaultValue)
|
||||
{
|
||||
string name = nameof(T);
|
||||
return Get(name, defaultValue);
|
||||
|
||||
}
|
||||
|
||||
public T Get<T>(string name, T defaultValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (cache.TryGetValue(name, out object cacheValue))
|
||||
{
|
||||
return (T)cacheValue;
|
||||
}
|
||||
|
||||
string value = (Registry.GetValue(savePath, name, string.Empty)).ToString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
T data = value.DeJson<T>();
|
||||
cache[name] = data;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void Set<T>(T data)
|
||||
{
|
||||
try
|
||||
{
|
||||
string name = nameof(T);
|
||||
string value = data.ToJson();
|
||||
Registry.SetValue(savePath, name, value);
|
||||
cache[name] = data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Table("rule-config")]
|
||||
public sealed class RuleConfig
|
||||
{
|
||||
private readonly IConfigDataProvider<RuleConfig> configDataProvider;
|
||||
public RuleConfig() { }
|
||||
public RuleConfig(IConfigDataProvider<RuleConfig> configDataProvider)
|
||||
{
|
||||
this.configDataProvider = configDataProvider;
|
||||
RuleConfig config = configDataProvider.Load().Result ?? new RuleConfig
|
||||
{
|
||||
UserNames = new Dictionary<string, string> { { "snltty", "{}" } }
|
||||
};
|
||||
UserNames = config.UserNames;
|
||||
}
|
||||
|
||||
public Dictionary<string, string> UserNames { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
}*/
|
||||
}
|
||||
@@ -121,7 +121,7 @@ namespace cmonitor.config
|
||||
|
||||
public sealed class ConfigCommonInfo
|
||||
{
|
||||
public string[] Modes { get; set; } = new string[] { "client", /*"server"*/ };
|
||||
public string[] Modes { get; set; } = new string[] { "client", "server" };
|
||||
}
|
||||
public sealed class ConfigClientInfo
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using cmonitor.api;
|
||||
using cmonitor.client.ruleConfig;
|
||||
using cmonitor.plugins.active.messenger;
|
||||
using cmonitor.plugins.active.report;
|
||||
using cmonitor.plugins.signIn.messenger;
|
||||
using cmonitor.server;
|
||||
using cmonitor.server.ruleConfig;
|
||||
using common.libs;
|
||||
using common.libs.extends;
|
||||
using MemoryPack;
|
||||
@@ -14,8 +14,8 @@ namespace cmonitor.plugins.active
|
||||
{
|
||||
private readonly MessengerSender messengerSender;
|
||||
private readonly SignCaching signCaching;
|
||||
private readonly RuleConfig ruleConfig;
|
||||
public ActiveApiController(MessengerSender messengerSender, SignCaching signCaching, RuleConfig ruleConfig)
|
||||
private readonly IRuleConfig ruleConfig;
|
||||
public ActiveApiController(MessengerSender messengerSender, SignCaching signCaching, IRuleConfig ruleConfig)
|
||||
{
|
||||
this.messengerSender = messengerSender;
|
||||
this.signCaching = signCaching;
|
||||
@@ -72,8 +72,8 @@ namespace cmonitor.plugins.active
|
||||
public async Task<bool> Disallow(ApiControllerParamsInfo param)
|
||||
{
|
||||
DisallowInfo disallowInfo = param.Content.DeJson<DisallowInfo>();
|
||||
byte[] bytes = MemoryPackSerializer.Serialize(new ActiveDisallowInfo { FileNames = disallowInfo.FileNames, Ids = disallowInfo.Ids });
|
||||
foreach (string name in disallowInfo.UserNames)
|
||||
byte[] bytes = MemoryPackSerializer.Serialize(new ActiveDisallowInfo { FileNames = disallowInfo.Data, Ids1 = disallowInfo.Ids1, Ids2 = disallowInfo.Ids2 });
|
||||
foreach (string name in disallowInfo.Devices)
|
||||
{
|
||||
if (signCaching.Get(name, out SignCacheInfo cache) && cache.Connected)
|
||||
{
|
||||
@@ -92,7 +92,7 @@ namespace cmonitor.plugins.active
|
||||
public async Task<bool> Kill(ApiControllerParamsInfo param)
|
||||
{
|
||||
ActiveKillInfo activeKillInfo = param.Content.DeJson<ActiveKillInfo>();
|
||||
byte[] bytes = activeKillInfo.pid.ToBytes();
|
||||
byte[] bytes = activeKillInfo.Pid.ToBytes();
|
||||
if (signCaching.Get(activeKillInfo.UserName, out SignCacheInfo cache) && cache.Connected)
|
||||
{
|
||||
await messengerSender.SendOnly(new MessageRequestWrap
|
||||
@@ -107,34 +107,42 @@ namespace cmonitor.plugins.active
|
||||
return false;
|
||||
}
|
||||
|
||||
public string AddGroup(ApiControllerParamsInfo param)
|
||||
public string Update(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.AddWindowGroup(param.Content.DeJson<UpdateWindowGroupInfo>());
|
||||
}
|
||||
public string DeleteGroup(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.DeleteWindowGroup(param.Content.DeJson<DeleteWindowGroupInfo>());
|
||||
}
|
||||
public string Add(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.AddWindow(param.Content.DeJson<AddWindowItemInfo>());
|
||||
}
|
||||
public string Del(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.DelWindow(param.Content.DeJson<DeletedWindowItemInfo>());
|
||||
UpdateWindowGroupInfo model = param.Content.DeJson<UpdateWindowGroupInfo>();
|
||||
ruleConfig.Set(model.UserName,"Windows", model.Data);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class UpdateWindowGroupInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public List<WindowGroupInfo> Data { get; set; } = new List<WindowGroupInfo>();
|
||||
}
|
||||
public sealed class WindowGroupInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<WindowItemInfo> List { get; set; } = new List<WindowItemInfo>();
|
||||
}
|
||||
public sealed class WindowItemInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Desc { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public sealed class DisallowInfo
|
||||
{
|
||||
public string[] UserNames { get; set; }
|
||||
public string[] FileNames { get; set; }
|
||||
public uint[] Ids { get; set; }
|
||||
public string[] Devices { get; set; }
|
||||
public string[] Data { get; set; }
|
||||
public string[] Ids1 { get; set; }
|
||||
public string[] Ids2 { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ActiveKillInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public int pid { get; set; }
|
||||
public int Pid { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ namespace cmonitor.plugins.active.report
|
||||
public object GetReports(ReportType reportType)
|
||||
{
|
||||
ticks = DateTime.UtcNow.Ticks;
|
||||
report.Ids = activeConfig.Ids;
|
||||
report.Ids1 = activeConfig.Ids1;
|
||||
report.Ids2 = activeConfig.Ids2;
|
||||
if (reportType == ReportType.Full || report.Updated())
|
||||
{
|
||||
return report;
|
||||
@@ -141,7 +142,8 @@ namespace cmonitor.plugins.active.report
|
||||
public sealed partial class ActiveDisallowInfo
|
||||
{
|
||||
public string[] FileNames { get; set; } = Array.Empty<string>();
|
||||
public uint[] Ids { get; set; } = Array.Empty<uint>();
|
||||
public string[] Ids1 { get; set; } = Array.Empty<string>();
|
||||
public string[] Ids2 { get; set; } = Array.Empty<string>();
|
||||
}
|
||||
|
||||
public sealed class ActiveReportInfo : ReportInfo
|
||||
@@ -153,10 +155,11 @@ namespace cmonitor.plugins.active.report
|
||||
public int DisallowCount { get; set; }
|
||||
public int WindowCount { get; set; }
|
||||
|
||||
public uint[] Ids { get; set; }
|
||||
public string[] Ids1 { get; set; }
|
||||
public string[] Ids2 { get; set; }
|
||||
public override int HashCode()
|
||||
{
|
||||
return Title.GetHashCode() ^ Pid.GetHashCode() ^ DisallowCount.GetHashCode() ^ Ids.GetHashCode();
|
||||
return Title.GetHashCode() ^ Pid.GetHashCode() ^ DisallowCount.GetHashCode() ^ Ids1.GetHashCode() ^ Ids2.GetHashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
28
cmonitor/plugins/devices/HijackApiController.cs
Normal file
28
cmonitor/plugins/devices/HijackApiController.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using cmonitor.api;
|
||||
using cmonitor.server.ruleConfig;
|
||||
using common.libs.extends;
|
||||
|
||||
namespace cmonitor.plugins.devices
|
||||
{
|
||||
public sealed class DevicesApiController : IApiController
|
||||
{
|
||||
private readonly IRuleConfig ruleConfig;
|
||||
public DevicesApiController(IRuleConfig ruleConfig)
|
||||
{
|
||||
this.ruleConfig = ruleConfig;
|
||||
}
|
||||
|
||||
public string Update(ApiControllerParamsInfo param)
|
||||
{
|
||||
UpdateDevicesInfo model = param.Content.DeJson<UpdateDevicesInfo>();
|
||||
ruleConfig.Set(model.UserName, "Devices", model.Data);
|
||||
return string.Empty;
|
||||
}
|
||||
public sealed class UpdateDevicesInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public List<string> Data { get; set; } = new List<string>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,24 @@
|
||||
using cmonitor.config;
|
||||
using cmonitor.plugins.setting.messenger;
|
||||
using cmonitor.startup;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Reflection;
|
||||
|
||||
namespace cmonitor.plugins.setting
|
||||
namespace cmonitor.plugins.devices
|
||||
{
|
||||
public sealed class SettingStartup : IStartup
|
||||
public sealed class DevicesStartup : IStartup
|
||||
{
|
||||
public void AddClient(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<SettingClientMessenger>();
|
||||
|
||||
}
|
||||
|
||||
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<SettingApiController>();
|
||||
serviceCollection.AddSingleton<DevicesApiController>();
|
||||
}
|
||||
|
||||
public void UseClient(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void UseServer(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||
@@ -1,9 +1,9 @@
|
||||
using cmonitor.api;
|
||||
using cmonitor.client.ruleConfig;
|
||||
using cmonitor.plugins.hijack.messenger;
|
||||
using cmonitor.plugins.hijack.report;
|
||||
using cmonitor.plugins.signIn.messenger;
|
||||
using cmonitor.server;
|
||||
using cmonitor.server.ruleConfig;
|
||||
using common.libs.extends;
|
||||
using MemoryPack;
|
||||
|
||||
@@ -11,57 +11,72 @@ namespace cmonitor.plugins.hijack
|
||||
{
|
||||
public sealed class HijackApiController : IApiController
|
||||
{
|
||||
private readonly RuleConfig ruleConfig;
|
||||
private readonly IRuleConfig ruleConfig;
|
||||
private readonly SignCaching signCaching;
|
||||
private readonly MessengerSender messengerSender;
|
||||
public HijackApiController(RuleConfig ruleConfig, SignCaching signCaching, MessengerSender messengerSender)
|
||||
public HijackApiController(IRuleConfig ruleConfig, SignCaching signCaching, MessengerSender messengerSender)
|
||||
{
|
||||
this.ruleConfig = ruleConfig;
|
||||
this.signCaching = signCaching;
|
||||
this.messengerSender = messengerSender;
|
||||
}
|
||||
public Dictionary<string, UserNameInfo> Info(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.UserNames;
|
||||
}
|
||||
public string AddName(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.AddName(param.Content);
|
||||
}
|
||||
|
||||
public string AddProcessGroup(ApiControllerParamsInfo param)
|
||||
public string UpdateRule(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.AddProcessGroup(param.Content.DeJson<UpdateGroupInfo>());
|
||||
UpdateRuleInfo model = param.Content.DeJson<UpdateRuleInfo>();
|
||||
ruleConfig.Set(model.UserName,"Rules", model.Data);
|
||||
return string.Empty;
|
||||
}
|
||||
public string DeleteProcessGroup(ApiControllerParamsInfo param)
|
||||
public sealed class RulesInfo
|
||||
{
|
||||
return ruleConfig.DeleteProcessGroup(param.Content.DeJson<DeleteGroupInfo>());
|
||||
public string Name { get; set; }
|
||||
public List<string> PrivateProcesss { get; set; } = new List<string>();
|
||||
public List<string> PublicProcesss { get; set; } = new List<string>();
|
||||
}
|
||||
public string AddProcess(ApiControllerParamsInfo param)
|
||||
public sealed class UpdateRuleInfo
|
||||
{
|
||||
return ruleConfig.AddProcess(param.Content.DeJson<UpdateItemInfo>());
|
||||
}
|
||||
public string DeleteProcess(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.DeleteProcess(param.Content.DeJson<DeleteItemInfo>());
|
||||
public string UserName { get; set; }
|
||||
public List<RulesInfo> Data { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public string AddRule(ApiControllerParamsInfo param)
|
||||
public string UpdateProcess(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.AddRule(param.Content.DeJson<UpdateRuleInfo>());
|
||||
UpdateHijackInfo model = param.Content.DeJson<UpdateHijackInfo>();
|
||||
ruleConfig.Set(model.UserName, "Processs", model.Data);
|
||||
return string.Empty;
|
||||
}
|
||||
public string DeleteRule(ApiControllerParamsInfo param)
|
||||
public sealed class HijackGroupInfo
|
||||
{
|
||||
return ruleConfig.DeleteRule(param.Content.DeJson<DeleteRuleInfo>());
|
||||
public string Name { get; set; }
|
||||
public List<HijackItemInfo> List { get; set; } = new List<HijackItemInfo>();
|
||||
}
|
||||
public sealed class HijackItemInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public HijackDataType DataType { get; set; }
|
||||
public HijackAllowType AllowType { get; set; }
|
||||
}
|
||||
public enum HijackDataType
|
||||
{
|
||||
Process = 0,
|
||||
Domain = 1,
|
||||
IP = 2,
|
||||
}
|
||||
public enum HijackAllowType
|
||||
{
|
||||
Allow = 0,
|
||||
Denied = 1
|
||||
}
|
||||
public sealed class UpdateHijackInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public List<HijackGroupInfo> Data { get; set; }
|
||||
}
|
||||
|
||||
public string UpdateDevices(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.UpdateDevices(param.Content.DeJson<UpdateDevicesInfo>());
|
||||
}
|
||||
|
||||
public async Task<List<string>> SetRules(ApiControllerParamsInfo param)
|
||||
|
||||
public async Task<List<string>> UseHijackRules(ApiControllerParamsInfo param)
|
||||
{
|
||||
List<string> errorDevices = new List<string>();
|
||||
SetRuleParamInfo setRuleParamInfo = param.Content.DeJson<SetRuleParamInfo>();
|
||||
@@ -69,9 +84,9 @@ namespace cmonitor.plugins.hijack
|
||||
{
|
||||
byte[] bytes = MemoryPackSerializer.Serialize(new HijackSetRuleInfo
|
||||
{
|
||||
Rules = setRuleParamInfo.Rules,
|
||||
Ids = setRuleParamInfo.Ids,
|
||||
|
||||
Rules = setRuleParamInfo.Data,
|
||||
Ids1 = setRuleParamInfo.Ids1,
|
||||
Ids2 = setRuleParamInfo.Ids2,
|
||||
});
|
||||
for (int i = 0; i < setRuleParamInfo.Devices.Length; i++)
|
||||
{
|
||||
@@ -92,12 +107,12 @@ namespace cmonitor.plugins.hijack
|
||||
}
|
||||
return errorDevices;
|
||||
}
|
||||
|
||||
public sealed class SetRuleParamInfo
|
||||
{
|
||||
public string[] Devices { get; set; }
|
||||
public HijackRuleUpdateInfo Rules { get; set; }
|
||||
public uint[] Ids { get; set; }
|
||||
public HijackRuleUpdateInfo Data { get; set; }
|
||||
public string[] Ids1 { get; set; }
|
||||
public string[] Ids2 { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
/// </summary>
|
||||
public string[] DeniedIPs { get; set; } = Array.Empty<string>();
|
||||
|
||||
public uint[] HijackIds { get; set; } = Array.Empty<uint>();
|
||||
public string[] HijackIds1 { get; set; } = Array.Empty<string>();
|
||||
public string[] HijackIds2 { get; set; } = Array.Empty<string>();
|
||||
|
||||
public bool DomainKill { get; set; }
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ namespace cmonitor.plugins.hijack.report
|
||||
hijackConfig.DeniedIPs = config.DeniedIPs;
|
||||
hijackConfig.AllowIPs = config.AllowIPs;
|
||||
hijackConfig.DomainKill = config.DomainKill;
|
||||
hijackConfig.HijackIds = config.HijackIds;
|
||||
hijackConfig.HijackIds1 = config.HijackIds1;
|
||||
hijackConfig.HijackIds2 = config.HijackIds2;
|
||||
UpdateRules();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -61,7 +62,8 @@ namespace cmonitor.plugins.hijack.report
|
||||
hijackConfig.AllowIPs = info.Rules.AllowIPs;
|
||||
hijackConfig.DeniedIPs = info.Rules.DeniedIPs;
|
||||
hijackConfig.DomainKill = info.Rules.DomainKill;
|
||||
hijackConfig.HijackIds = info.Ids;
|
||||
hijackConfig.HijackIds1 = info.Ids1;
|
||||
hijackConfig.HijackIds2 = info.Ids2;
|
||||
|
||||
clientConfig.Set(hijackConfig);
|
||||
|
||||
@@ -81,7 +83,8 @@ namespace cmonitor.plugins.hijack.report
|
||||
hijackReportInfo.Upload = hijack.UdpSend + hijack.TcpSend;
|
||||
hijackReportInfo.Download = hijack.TcpReceive + hijack.UdpReceive;
|
||||
hijackReportInfo.Count = (ulong)(hijackConfig.AllowIPs.Length + hijackConfig.DeniedIPs.Length + hijackConfig.AllowDomains.Length + hijackConfig.DeniedDomains.Length + hijackConfig.AllowProcesss.Length + hijackConfig.DeniedProcesss.Length);
|
||||
hijackReportInfo.Ids = hijackConfig.HijackIds;
|
||||
hijackReportInfo.Ids1 = hijackConfig.HijackIds1;
|
||||
hijackReportInfo.Ids2 = hijackConfig.HijackIds2;
|
||||
hijackReportInfo.DomainKill = hijackConfig.DomainKill;
|
||||
|
||||
long _ticks = DateTime.UtcNow.Ticks;
|
||||
@@ -100,12 +103,13 @@ namespace cmonitor.plugins.hijack.report
|
||||
public ulong Download { get; set; }
|
||||
public ulong Count { get; set; }
|
||||
|
||||
public uint[] Ids { get; set; }
|
||||
public string[] Ids1 { get; set; }
|
||||
public string[] Ids2 { get; set; }
|
||||
public bool DomainKill { get; set; }
|
||||
|
||||
public override int HashCode()
|
||||
{
|
||||
return Upload.GetHashCode() ^ Download.GetHashCode() ^ Count.GetHashCode() ^ Ids.GetHashCode();
|
||||
return Upload.GetHashCode() ^ Download.GetHashCode() ^ Count.GetHashCode() ^ Ids1.GetHashCode() ^ Ids2.GetHashCode();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -114,7 +118,8 @@ namespace cmonitor.plugins.hijack.report
|
||||
public sealed partial class HijackSetRuleInfo
|
||||
{
|
||||
public HijackRuleUpdateInfo Rules { get; set; }
|
||||
public uint[] Ids { get; set; }
|
||||
public string[] Ids1 { get; set; }
|
||||
public string[] Ids2 { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -161,6 +161,9 @@ namespace cmonitor.plugins.hijack.report.hijack
|
||||
NFAPI.nf_udpPostSend(id, remoteAddress, buf, len, options);
|
||||
}
|
||||
|
||||
|
||||
private bool processWhiteAny = false;
|
||||
private bool processBlackAny = false;
|
||||
/// <summary>
|
||||
/// 设置进程列表
|
||||
/// </summary>
|
||||
@@ -169,7 +172,10 @@ namespace cmonitor.plugins.hijack.report.hijack
|
||||
public void SetProcess(string[] white, string[] black)
|
||||
{
|
||||
processWhite = white;
|
||||
processWhiteAny = white.Any(c => c == "*");
|
||||
|
||||
processBlack = black;
|
||||
processBlackAny = black.Any(c => c == "*");
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置域名列表
|
||||
@@ -205,20 +211,44 @@ namespace cmonitor.plugins.hijack.report.hijack
|
||||
domainIPs.Clear();
|
||||
foreach (string domain in domainWhite)
|
||||
{
|
||||
IPHostEntry entry = Dns.GetHostEntry(domain);
|
||||
foreach (var item in entry.AddressList)
|
||||
if (domain == "*")
|
||||
{
|
||||
domainIPs[IPAddress.Any] = AllowType.Allow;
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
IPHostEntry entry = Dns.GetHostEntry(domain);
|
||||
foreach (var item in entry.AddressList)
|
||||
{
|
||||
domainIPs[item] = AllowType.Allow;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
domainIPs[item] = AllowType.Allow;
|
||||
}
|
||||
}
|
||||
foreach (string domain in domainBlack)
|
||||
{
|
||||
IPHostEntry entry = Dns.GetHostEntry(domain);
|
||||
foreach (IPAddress item in entry.AddressList)
|
||||
if (domain == "*")
|
||||
{
|
||||
domainIPs[IPAddress.Any] = AllowType.Denied;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (domainIPs.ContainsKey(item) == false)
|
||||
domainIPs[item] = AllowType.Denied;
|
||||
try
|
||||
{
|
||||
IPHostEntry entry = Dns.GetHostEntry(domain);
|
||||
foreach (IPAddress item in entry.AddressList)
|
||||
{
|
||||
|
||||
if (domainIPs.ContainsKey(item) == false)
|
||||
domainIPs[item] = AllowType.Denied;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
KillProcessWithDomainBlack();
|
||||
@@ -292,14 +322,14 @@ namespace cmonitor.plugins.hijack.report.hijack
|
||||
{
|
||||
index += 2;
|
||||
}
|
||||
index += 2;//transID
|
||||
index += 2;//跳过transID
|
||||
ushort flag = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(index));
|
||||
index += 2;
|
||||
ushort quesions = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(index));
|
||||
index += 2;
|
||||
ushort answers = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(index));
|
||||
index += 2;
|
||||
index += 4; // au2 + ad2
|
||||
index += 4; //跳过 au 2字节 + ad 2字节
|
||||
|
||||
byte rcode = (byte)(flag & 0b1111);
|
||||
byte tc = (byte)(flag >> 9 & 0x01);
|
||||
@@ -332,22 +362,22 @@ namespace cmonitor.plugins.hijack.report.hijack
|
||||
{
|
||||
return null; //不是A查询
|
||||
}
|
||||
index += 2; //class
|
||||
index += 2; //跳过class
|
||||
|
||||
string domain = Encoding.UTF8.GetString(domainCache.Span.Slice(0, domainPosition));
|
||||
IPAddress[] ips = new IPAddress[answers];
|
||||
//answers
|
||||
for (int i = 0; i < answers; i++)
|
||||
{
|
||||
index += 2; //指针
|
||||
index += 2; //跳过指针
|
||||
type = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(index));
|
||||
index += 2;
|
||||
index += 2;//class
|
||||
index += 4;//timeLive
|
||||
index += 2;//跳过class
|
||||
index += 4;//跳过timeLive
|
||||
int dataLength = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(index));
|
||||
index += 2;
|
||||
|
||||
if (type == 1)
|
||||
if (type == 1) //是A回应,其它的不要
|
||||
{
|
||||
ips[i] = new IPAddress(span.Slice(index, dataLength));
|
||||
}
|
||||
@@ -394,7 +424,9 @@ namespace cmonitor.plugins.hijack.report.hijack
|
||||
}
|
||||
private unsafe bool DeniedIP(uint processId, IPAddress ip)
|
||||
{
|
||||
if (ip != null && domainIPs.TryGetValue(ip, out AllowType type))
|
||||
bool res = domainIPs.TryGetValue(IPAddress.Any, out AllowType type) && type == AllowType.Denied;
|
||||
|
||||
if (ip != null && domainIPs.TryGetValue(ip, out type))
|
||||
{
|
||||
if (type == AllowType.Denied && domainKill)
|
||||
{
|
||||
@@ -414,7 +446,7 @@ namespace cmonitor.plugins.hijack.report.hijack
|
||||
}
|
||||
return type == AllowType.Denied;
|
||||
}
|
||||
return false;
|
||||
return res;
|
||||
}
|
||||
private unsafe IPAddress ReadIPAddress(nint remoteAddress)
|
||||
{
|
||||
@@ -449,6 +481,9 @@ namespace cmonitor.plugins.hijack.report.hijack
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool res = processBlackAny;
|
||||
|
||||
processName = NFAPI.nf_getProcessName(processId);
|
||||
//白名单
|
||||
if (processWhite.Length > 0 && CheckName(processWhite, processName))
|
||||
@@ -456,17 +491,19 @@ namespace cmonitor.plugins.hijack.report.hijack
|
||||
return false;
|
||||
}
|
||||
//黑名单
|
||||
if (processBlack.Length > 0)
|
||||
if (processBlack.Length > 0 && CheckName(processBlack, processName))
|
||||
{
|
||||
return CheckName(processBlack, processName);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
private bool CheckName(string[] names, string path)
|
||||
{
|
||||
bool res = false;
|
||||
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
if (names[i].Length > path.Length) continue;
|
||||
@@ -484,7 +521,7 @@ namespace cmonitor.plugins.hijack.report.hijack
|
||||
{
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,26 +1,37 @@
|
||||
using cmonitor.api;
|
||||
using cmonitor.client.ruleConfig;
|
||||
using cmonitor.plugins.signIn.messenger;
|
||||
using cmonitor.server;
|
||||
using cmonitor.server.ruleConfig;
|
||||
using common.libs.extends;
|
||||
|
||||
namespace cmonitor.plugins.modes
|
||||
{
|
||||
public sealed class ModesApiController : IApiController
|
||||
{
|
||||
private readonly RuleConfig ruleConfig;
|
||||
private readonly SignCaching signCaching;
|
||||
private readonly MessengerSender messengerSender;
|
||||
public ModesApiController(RuleConfig ruleConfig, SignCaching signCaching, MessengerSender messengerSender)
|
||||
|
||||
private readonly IRuleConfig ruleConfig;
|
||||
public ModesApiController(IRuleConfig ruleConfig)
|
||||
{
|
||||
this.ruleConfig = ruleConfig;
|
||||
this.signCaching = signCaching;
|
||||
this.messengerSender = messengerSender;
|
||||
}
|
||||
|
||||
public string Update(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.UpdateModes(param.Content.DeJson<UpdateModesInfo>());
|
||||
UpdateModesInfo info = param.Content.DeJson<UpdateModesInfo>();
|
||||
ruleConfig.Set(info.UserName, "Modes", info.Data);
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public sealed class ModesInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Data { get; set; }
|
||||
}
|
||||
|
||||
public sealed class UpdateModesInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public List<ModesInfo> Data { get; set; } = new List<ModesInfo>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
cmonitor/plugins/rule/RuleApiController.cs
Normal file
24
cmonitor/plugins/rule/RuleApiController.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using cmonitor.api;
|
||||
using cmonitor.server.ruleConfig;
|
||||
|
||||
namespace cmonitor.plugins.rule
|
||||
{
|
||||
public sealed class RuleApiController : IApiController
|
||||
{
|
||||
private readonly IRuleConfig ruleConfig;
|
||||
public RuleApiController(IRuleConfig ruleConfig)
|
||||
{
|
||||
this.ruleConfig = ruleConfig;
|
||||
}
|
||||
|
||||
public RuleConfigInfo Info(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.Data;
|
||||
}
|
||||
public string AddName(ApiControllerParamsInfo param)
|
||||
{
|
||||
ruleConfig.AddUser(param.Content);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
cmonitor/plugins/rule/RuleStartup.cs
Normal file
28
cmonitor/plugins/rule/RuleStartup.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using cmonitor.config;
|
||||
using cmonitor.startup;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Reflection;
|
||||
|
||||
namespace cmonitor.plugins.rule
|
||||
{
|
||||
public sealed class RuleStartup : IStartup
|
||||
{
|
||||
public void AddClient(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<RuleApiController>();
|
||||
}
|
||||
|
||||
public void UseClient(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||
{
|
||||
}
|
||||
|
||||
public void UseServer(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using cmonitor.api;
|
||||
using cmonitor.config;
|
||||
using cmonitor.plugins.setting.messenger;
|
||||
using cmonitor.plugins.signIn.messenger;
|
||||
using cmonitor.server;
|
||||
using common.libs.extends;
|
||||
using MemoryPack;
|
||||
|
||||
namespace cmonitor.plugins.setting
|
||||
{
|
||||
public sealed class SettingApiController : IApiController
|
||||
{
|
||||
private readonly MessengerSender messengerSender;
|
||||
private readonly SignCaching signCaching;
|
||||
private readonly Config config;
|
||||
|
||||
public SettingApiController(MessengerSender messengerSender, SignCaching signCaching, Config config)
|
||||
{
|
||||
this.messengerSender = messengerSender;
|
||||
this.signCaching = signCaching;
|
||||
this.config = config;
|
||||
}
|
||||
public SettingInfo Get(ApiControllerParamsInfo param)
|
||||
{
|
||||
return new SettingInfo
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
public bool Set(ApiControllerParamsInfo param)
|
||||
{
|
||||
SettingInfo settingInfo = param.Content.DeJson<SettingInfo>();
|
||||
|
||||
byte[] bytes = MemoryPackSerializer.Serialize(settingInfo);
|
||||
foreach (var item in signCaching.Get())
|
||||
{
|
||||
if (item.Connected)
|
||||
{
|
||||
_ = messengerSender.SendOnly(new MessageRequestWrap
|
||||
{
|
||||
Connection = item.Connection,
|
||||
MessengerId = (ushort)SettingMessengerIds.Update,
|
||||
Payload = bytes
|
||||
});
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using cmonitor.config;
|
||||
using cmonitor.server;
|
||||
using MemoryPack;
|
||||
|
||||
namespace cmonitor.plugins.setting.messenger
|
||||
{
|
||||
public sealed class SettingClientMessenger : IMessenger
|
||||
{
|
||||
private Config config;
|
||||
public SettingClientMessenger(Config config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
[MessengerId((ushort)SettingMessengerIds.Update)]
|
||||
public void Update(IConnection connection)
|
||||
{
|
||||
SettingInfo settingInfo = MemoryPackSerializer.Deserialize<SettingInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
[MemoryPackable]
|
||||
public sealed partial class SettingShareInfo
|
||||
{
|
||||
public float ScreenScale { get; set; } = 0.2f;
|
||||
public int ScreenDelay { get; set; } = 30;
|
||||
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public sealed partial class SettingInfo
|
||||
{
|
||||
public int ReportDelay { get; set; } = 30;
|
||||
public float ScreenScale { get; set; } = 0.2f;
|
||||
public int ScreenDelay { get; set; } = 30;
|
||||
public bool SaveSetting { get; set; } = true;
|
||||
public bool WakeUp { get; set; } = true;
|
||||
public bool VolumeMasterPeak { get; set; } = true;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace cmonitor.plugins.setting.messenger
|
||||
{
|
||||
public enum SettingMessengerIds : ushort
|
||||
{
|
||||
Update = 1300,
|
||||
|
||||
None = 1399
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using cmonitor.api;
|
||||
using cmonitor.client.ruleConfig;
|
||||
using cmonitor.plugins.signIn.messenger;
|
||||
using cmonitor.plugins.snatch.messenger;
|
||||
using cmonitor.plugins.snatch.report;
|
||||
using cmonitor.server;
|
||||
using cmonitor.server.ruleConfig;
|
||||
using common.libs.extends;
|
||||
|
||||
namespace cmonitor.plugins.snatch
|
||||
@@ -11,11 +11,11 @@ namespace cmonitor.plugins.snatch
|
||||
public sealed class SnatchApiController : IApiController
|
||||
{
|
||||
private readonly MessengerSender messengerSender;
|
||||
private readonly RuleConfig ruleConfig;
|
||||
private readonly IRuleConfig ruleConfig;
|
||||
private readonly SignCaching signCaching;
|
||||
private readonly ISnatachCaching snatachCaching;
|
||||
|
||||
public SnatchApiController(RuleConfig ruleConfig, MessengerSender messengerSender, SignCaching signCaching, ISnatachCaching snatachCaching)
|
||||
public SnatchApiController(IRuleConfig ruleConfig, MessengerSender messengerSender, SignCaching signCaching, ISnatachCaching snatachCaching)
|
||||
{
|
||||
this.ruleConfig = ruleConfig;
|
||||
this.messengerSender = messengerSender;
|
||||
@@ -23,24 +23,13 @@ namespace cmonitor.plugins.snatch
|
||||
this.snatachCaching = snatachCaching;
|
||||
}
|
||||
|
||||
public string AddGroup(ApiControllerParamsInfo param)
|
||||
public string Update(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.AddSnatchGroup(param.Content.DeJson<UpdateSnatchGroupInfo>());
|
||||
UpdateSnatchGroupInfo model = param.Content.DeJson<UpdateSnatchGroupInfo>();
|
||||
ruleConfig.Set(model.UserName,"Snatchs", model.Data);
|
||||
return string.Empty;
|
||||
}
|
||||
public string DeleteGroup(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.DeleteSnatchGroup(param.Content.DeJson<DeleteSnatchGroupInfo>());
|
||||
}
|
||||
public string Add(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.AddSnatch(param.Content.DeJson<AddSnatchItemInfo>());
|
||||
}
|
||||
public string Del(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.DelSnatch(param.Content.DeJson<DeletedSnatchItemInfo>());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AnswerGroupInfo[] GetQuestion(ApiControllerParamsInfo param)
|
||||
{
|
||||
if (snatachCaching.Get(param.Content, out SnatchQuestionCacheInfo info))
|
||||
@@ -54,6 +43,7 @@ namespace cmonitor.plugins.snatch
|
||||
|
||||
return Array.Empty<AnswerGroupInfo>();
|
||||
}
|
||||
|
||||
public async Task<bool> AddQuestion(ApiControllerParamsInfo param)
|
||||
{
|
||||
SnatchQuestionCacheParamInfo info = param.Content.DeJson<SnatchQuestionCacheParamInfo>();
|
||||
@@ -78,10 +68,6 @@ namespace cmonitor.plugins.snatch
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public SnatchItemInfo[] RandomQuestion(ApiControllerParamsInfo param)
|
||||
{
|
||||
return ruleConfig.SnatchRandom(int.Parse(param.Content));
|
||||
}
|
||||
public async Task<bool> UpdateQuestion(ApiControllerParamsInfo param)
|
||||
{
|
||||
UpdateQuestionCacheParamInfo info = param.Content.DeJson<UpdateQuestionCacheParamInfo>();
|
||||
@@ -133,24 +119,62 @@ namespace cmonitor.plugins.snatch
|
||||
public string UserName { get; set; }
|
||||
public UpdateQuestionCacheParamItemInfo[] Items { get; set; }
|
||||
}
|
||||
|
||||
public sealed class UpdateQuestionCacheParamItemInfo
|
||||
{
|
||||
public string MachineName { get; set; }
|
||||
public SnatchQuestionInfo Question { get; set; }
|
||||
}
|
||||
|
||||
public sealed class SnatchQuestionCacheParamInfo
|
||||
{
|
||||
public SnatchQuestionCacheInfo Cache { get; set; }
|
||||
public SnatchQuestionInfo Question { get; set; }
|
||||
}
|
||||
|
||||
public sealed class AnswerGroupInfo
|
||||
{
|
||||
public SnatchQuestionInfo Question { get; set; }
|
||||
public SnatchAnswerInfo[] Answers { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public sealed class SnatchGroupInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<SnatchItemInfo> List { get; set; } = new List<SnatchItemInfo>();
|
||||
}
|
||||
public sealed class UpdateSnatchGroupInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public List<SnatchGroupInfo> Data { get; set; }
|
||||
}
|
||||
public sealed class SnatchItemInfo
|
||||
{
|
||||
public uint ID { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
public SnatchCate Cate { get; set; } = SnatchCate.Question;
|
||||
public SnatchType Type { get; set; } = SnatchType.Select;
|
||||
/// <summary>
|
||||
/// 问题
|
||||
/// </summary>
|
||||
public string Question { get; set; }
|
||||
/// <summary>
|
||||
/// 选项数
|
||||
/// </summary>
|
||||
public List<SnatchItemOptionInfo> Options { get; set; }
|
||||
/// <summary>
|
||||
/// 答案
|
||||
/// </summary>
|
||||
public string Correct { get; set; }
|
||||
/// <summary>
|
||||
/// 最多答题次数
|
||||
/// </summary>
|
||||
public int Chance { get; set; }
|
||||
}
|
||||
public sealed class SnatchItemOptionInfo
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public bool Value { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ namespace cmonitor.plugins.system
|
||||
{
|
||||
PasswordInfo info = param.Content.DeJson<PasswordInfo>();
|
||||
byte[] bytes = MemoryPackSerializer.Serialize(info.Input);
|
||||
for (int i = 0; i < info.Names.Length; i++)
|
||||
for (int i = 0; i < info.Devices.Length; i++)
|
||||
{
|
||||
if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected)
|
||||
if (signCaching.Get(info.Devices[i], out SignCacheInfo cache) && cache.Connected)
|
||||
{
|
||||
await messengerSender.SendOnly(new MessageRequestWrap
|
||||
{
|
||||
@@ -40,10 +40,10 @@ namespace cmonitor.plugins.system
|
||||
public async Task<bool> RegistryOptions(ApiControllerParamsInfo param)
|
||||
{
|
||||
RegistryInfo info = param.Content.DeJson<RegistryInfo>();
|
||||
byte[] bytes = MemoryPackSerializer.Serialize(info.Registry);
|
||||
for (int i = 0; i < info.Names.Length; i++)
|
||||
byte[] bytes = MemoryPackSerializer.Serialize(info.Data);
|
||||
for (int i = 0; i < info.Devices.Length; i++)
|
||||
{
|
||||
if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected)
|
||||
if (signCaching.Get(info.Devices[i], out SignCacheInfo cache) && cache.Connected)
|
||||
{
|
||||
await messengerSender.SendOnly(new MessageRequestWrap
|
||||
{
|
||||
@@ -61,13 +61,13 @@ namespace cmonitor.plugins.system
|
||||
|
||||
public sealed class RegistryInfo
|
||||
{
|
||||
public string[] Names { get; set; }
|
||||
public SystemOptionUpdateInfo Registry { get; set; }
|
||||
public string[] Devices { get; set; }
|
||||
public SystemOptionUpdateInfo[] Data { get; set; }
|
||||
}
|
||||
|
||||
public sealed class PasswordInfo
|
||||
{
|
||||
public string[] Names { get; set; }
|
||||
public string[] Devices { get; set; }
|
||||
public PasswordInputInfo Input { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace cmonitor.plugins.system.messenger
|
||||
[MessengerId((ushort)SystemMessengerIds.RegistryOptions)]
|
||||
public void RegistryOptions(IConnection connection)
|
||||
{
|
||||
SystemOptionUpdateInfo registryUpdateInfo = MemoryPackSerializer.Deserialize<SystemOptionUpdateInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
SystemOptionUpdateInfo[] registryUpdateInfo = MemoryPackSerializer.Deserialize<SystemOptionUpdateInfo[]>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
report.OptionUpdate(registryUpdateInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace cmonitor.plugins.system.report
|
||||
|
||||
public Dictionary<string, SystemOptionKeyInfo> OptionKeys();
|
||||
public string OptionValues();
|
||||
public void OptionUpdate(SystemOptionUpdateInfo optionUpdateInfo);
|
||||
public void OptionUpdate(SystemOptionUpdateInfo[] optionUpdateInfo);
|
||||
|
||||
public bool Password(PasswordInputInfo command);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
public void OptionUpdate(SystemOptionUpdateInfo registryUpdateInfo)
|
||||
public void OptionUpdate(SystemOptionUpdateInfo[] registryUpdateInfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
public void OptionUpdate(SystemOptionUpdateInfo registryUpdateInfo)
|
||||
public void OptionUpdate(SystemOptionUpdateInfo[] registryUpdateInfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace cmonitor.plugins.system.report
|
||||
return null;
|
||||
}
|
||||
|
||||
public void OptionUpdate(SystemOptionUpdateInfo registryUpdateInfo)
|
||||
public void OptionUpdate(SystemOptionUpdateInfo[] registryUpdateInfo)
|
||||
{
|
||||
system.OptionUpdate(registryUpdateInfo);
|
||||
}
|
||||
@@ -95,7 +95,7 @@ namespace cmonitor.plugins.system.report
|
||||
[MemoryPackable]
|
||||
public sealed partial class SystemOptionUpdateInfo
|
||||
{
|
||||
public string[] Keys { get; set; }
|
||||
public string Keys { get; set; }
|
||||
public bool Value { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using common.libs.winapis;
|
||||
using Microsoft.Win32;
|
||||
using monitor.plugins.system.report;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
|
||||
namespace cmonitor.plugins.system.report
|
||||
{
|
||||
@@ -74,7 +75,7 @@ namespace cmonitor.plugins.system.report
|
||||
if (restored)
|
||||
{
|
||||
reused |= registryOptionHelper.Reuse();
|
||||
OptionUpdate(new SystemOptionUpdateInfo { Keys = new string[] { "SoftwareSASGeneration" }, Value = false });
|
||||
OptionUpdate(new SystemOptionUpdateInfo[] { new SystemOptionUpdateInfo { Keys = "SoftwareSASGeneration", Value = false } });
|
||||
}
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
@@ -90,11 +91,11 @@ namespace cmonitor.plugins.system.report
|
||||
{
|
||||
return registryOptionHelper.GetValues();
|
||||
}
|
||||
public void OptionUpdate(SystemOptionUpdateInfo registryUpdateInfo)
|
||||
public void OptionUpdate(SystemOptionUpdateInfo[] registryUpdateInfo)
|
||||
{
|
||||
actions.Enqueue(() =>
|
||||
{
|
||||
registryOptionHelper.UpdateValue(registryUpdateInfo.Keys, registryUpdateInfo.Value);
|
||||
registryOptionHelper.UpdateValue(registryUpdateInfo);
|
||||
});
|
||||
}
|
||||
private void LoopTask()
|
||||
@@ -374,7 +375,7 @@ namespace cmonitor.plugins.system.report
|
||||
}
|
||||
return _allow;
|
||||
}
|
||||
public bool UpdateValue(string[] keys, bool value)
|
||||
public bool UpdateValue(SystemOptionUpdateInfo[] keys)
|
||||
{
|
||||
bool result = false;
|
||||
if (GetSid() == false)
|
||||
@@ -384,21 +385,23 @@ namespace cmonitor.plugins.system.report
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
IEnumerable<RegistryOptionInfo> info = Infos.Where(c => keys.Contains(c.Key));
|
||||
if (info.Any() == false)
|
||||
|
||||
foreach (SystemOptionUpdateInfo item in keys)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
foreach (RegistryOptionInfo item in info)
|
||||
{
|
||||
foreach (RegistryOptionPathInfo pathItem in item.Paths)
|
||||
RegistryOptionInfo info = Infos.FirstOrDefault(c => c.Key == item.Keys);
|
||||
if (info == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (RegistryOptionPathInfo pathItem in info.Paths)
|
||||
{
|
||||
string path = ReplaceRegistryPath(pathItem.Path);
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string setValue = value ? pathItem.DisallowValue : pathItem.AllowValue;
|
||||
string setValue = item.Value ? pathItem.DisallowValue : pathItem.AllowValue;
|
||||
try
|
||||
{
|
||||
object oldValue = Registry.GetValue(path, pathItem.Key, null);
|
||||
|
||||
@@ -9,8 +9,6 @@ namespace cmonitor.plugins.wlan.messenger
|
||||
public WlanClientMessenger(WlanReport wlanReport)
|
||||
{
|
||||
this.wlanReport = wlanReport;
|
||||
|
||||
Console.WriteLine(wlanReport == null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using cmonitor.client.report;
|
||||
using cmonitor.config;
|
||||
using common.libs;
|
||||
|
||||
namespace cmonitor.plugins.wlan.report
|
||||
{
|
||||
@@ -28,9 +29,11 @@ namespace cmonitor.plugins.wlan.report
|
||||
{
|
||||
if (wlan.Connected() == false)
|
||||
{
|
||||
Logger.Instance.Warning($"network offline reconnect it~");
|
||||
var wafis = wlan.WlanEnums();
|
||||
foreach (var wifi in wafis)
|
||||
{
|
||||
Logger.Instance.Warning($"network offline reconnect {wifi}~");
|
||||
bool res = await wlan.WlanConnect(wifi);
|
||||
if (res)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using common.libs.winapis;
|
||||
using ManagedNativeWifi;
|
||||
using ManagedNativeWifi;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace cmonitor.plugins.wlan.report
|
||||
{
|
||||
@@ -22,7 +22,10 @@ namespace cmonitor.plugins.wlan.report
|
||||
|
||||
public bool Connected()
|
||||
{
|
||||
return Wininet.InternetGetConnectedState(out int desc, 0);
|
||||
using Ping ping = new Ping();
|
||||
var replay = ping.Send("www.baidu.com", 1000);
|
||||
return replay.Status == IPStatus.Success;
|
||||
//return Wininet.InternetGetConnectedState(out int desc, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using cmonitor.config;
|
||||
using cmonitor.server.ruleConfig;
|
||||
using cmonitor.startup;
|
||||
using common.libs;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -17,6 +18,11 @@ namespace cmonitor.server
|
||||
|
||||
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<IRuleConfig, RuleConfigWindows>();
|
||||
// if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<IRuleConfig, RuleConfigWindows>();
|
||||
// else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<IRuleConfig, RuleConfigLinux>();
|
||||
// else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<IRuleConfig, RuleConfigMacOS>();
|
||||
|
||||
serviceCollection.AddSingleton<MessengerSender>();
|
||||
serviceCollection.AddSingleton<MessengerResolver>();
|
||||
serviceCollection.AddSingleton<TcpServer>();
|
||||
|
||||
20
cmonitor/server/ruleConfig/IRuleConfig.cs
Normal file
20
cmonitor/server/ruleConfig/IRuleConfig.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace cmonitor.server.ruleConfig
|
||||
{
|
||||
public interface IRuleConfig
|
||||
{
|
||||
public RuleConfigInfo Data { get; }
|
||||
|
||||
public void AddUser(string username);
|
||||
|
||||
public T Get<T>(string username,string key, T defaultValue);
|
||||
public void Set<T>(string username, string key, T data);
|
||||
}
|
||||
|
||||
[Table("rule")]
|
||||
public sealed class RuleConfigInfo
|
||||
{
|
||||
public Dictionary<string, Dictionary<string, string>> Data { get; set; } = new Dictionary<string, Dictionary<string, string>>();
|
||||
}
|
||||
}
|
||||
23
cmonitor/server/ruleConfig/RuleConfigLinux.cs
Normal file
23
cmonitor/server/ruleConfig/RuleConfigLinux.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace cmonitor.server.ruleConfig
|
||||
{
|
||||
public sealed class RuleConfigLinux : IRuleConfig
|
||||
{
|
||||
public RuleConfigInfo Data => null;
|
||||
|
||||
|
||||
public void AddUser(string username)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public T Get<T>(string username, string key, T defaultValue)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void Set<T>(string username, string key, T data)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
22
cmonitor/server/ruleConfig/RuleConfigMacOS.cs
Normal file
22
cmonitor/server/ruleConfig/RuleConfigMacOS.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace cmonitor.server.ruleConfig
|
||||
{
|
||||
public sealed class RuleConfigMacOS : IRuleConfig
|
||||
{
|
||||
public RuleConfigInfo Data => null;
|
||||
|
||||
public void AddUser(string username)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public T Get<T>(string username, string key, T defaultValue)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void Set<T>(string username, string key, T data)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
89
cmonitor/server/ruleConfig/RuleConfigWindows.cs
Normal file
89
cmonitor/server/ruleConfig/RuleConfigWindows.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using common.libs;
|
||||
using common.libs.database;
|
||||
using common.libs.extends;
|
||||
|
||||
namespace cmonitor.server.ruleConfig
|
||||
{
|
||||
//[SupportedOSPlatform("windows")]
|
||||
|
||||
public sealed class RuleConfigWindows : IRuleConfig
|
||||
{
|
||||
private readonly IConfigDataProvider<RuleConfigInfo> configDataProvider;
|
||||
private readonly RuleConfigInfo RuleConfigInfo;
|
||||
private Dictionary<string, Dictionary<string, object>> cache = new Dictionary<string, Dictionary<string, object>>();
|
||||
|
||||
public RuleConfigInfo Data => RuleConfigInfo;
|
||||
|
||||
|
||||
public RuleConfigWindows(IConfigDataProvider<RuleConfigInfo> configDataProvider)
|
||||
{
|
||||
this.configDataProvider = configDataProvider;
|
||||
RuleConfigInfo = configDataProvider.Load().Result ?? new RuleConfigInfo();
|
||||
}
|
||||
|
||||
public void AddUser(string username)
|
||||
{
|
||||
if (RuleConfigInfo.Data.ContainsKey(username))
|
||||
{
|
||||
return;
|
||||
}
|
||||
RuleConfigInfo.Data.Add(username,new Dictionary<string, string>());
|
||||
}
|
||||
|
||||
public T Get<T>(string username, string key, T defaultValue)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
if (cache.TryGetValue(username, out Dictionary<string, object> dic) && dic.TryGetValue(key, out object cacheValue))
|
||||
{
|
||||
return (T)cacheValue;
|
||||
}
|
||||
|
||||
if (RuleConfigInfo.Data.TryGetValue(username, out Dictionary<string, string> dicStr) && dicStr.TryGetValue(key, out string value))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value) == false)
|
||||
{
|
||||
T data = value.DeJson<T>();
|
||||
cache[username][key] = data;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Instance.Error(ex);
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void Set<T>(string username, string key, T data)
|
||||
{
|
||||
try
|
||||
{
|
||||
string value = data.ToJson();
|
||||
if (RuleConfigInfo.Data.TryGetValue(username, out Dictionary<string, string> dicStr) == false)
|
||||
{
|
||||
RuleConfigInfo.Data[username] = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
RuleConfigInfo.Data[username][key] = value;
|
||||
|
||||
if (cache.TryGetValue(username, out Dictionary<string, object> dic) == false)
|
||||
{
|
||||
cache[username] = new Dictionary<string, object>();
|
||||
}
|
||||
cache[username][key] = data;
|
||||
|
||||
configDataProvider.Save(RuleConfigInfo).Wait();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Instance.Error(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -13,4 +13,5 @@ dotnet publish ./cmonitor.snatch.win -c release -f net8.0-windows -r win-x64 -o
|
||||
dotnet publish ./cmonitor.llock.win -c release -f net8.0-windows -r win-x64 -o public/extends/ -p:PublishSingleFile=true --self-contained false
|
||||
dotnet publish ./cmonitor.message.win -c release -f net8.0-windows -r win-x64 -o public/extends/ -p:PublishSingleFile=true --self-contained false
|
||||
dotnet publish ./cmonitor.notify.win -c release -f net8.0-windows -r win-x64 -o public/extends/ -p:PublishSingleFile=true --self-contained false
|
||||
dotnet publish ./cmonitor.wallpaper.win -c release -f net8.0-windows -r win-x64 -o public/extends/ -p:PublishSingleFile=true --self-contained false
|
||||
dotnet publish ./cmonitor.wallpaper.win -c release -f net8.0-windows -r win-x64 -o public/extends/ -p:PublishSingleFile=true --self-contained false
|
||||
MSBuild.exe cmonitor.viewer.server.win /t:Publish /p:Configuration=Release /p:TargetFramework=net8.0-windows /p:PublishSingleFile=true /p:RuntimeIdentifier=win-x64 /p:PublishDir=../public/extends/
|
||||
Reference in New Issue
Block a user