mirror of
https://github.com/snltty/linker.git
synced 2025-12-19 18:06:47 +08:00
196
This commit is contained in:
@@ -14,7 +14,7 @@ slug: /install/ikuai
|
||||
|
||||

|
||||
|
||||
先下载 <a href="/update-20241130.bin" target="_blank">update-20241130.bin</a> 和 <a href="https://www.ikuaios.com:555/i/%E5%8E%86%E5%8F%B2%E5%9B%BA%E4%BB%B6" target="_blank">iKuai-3.7.16</a>(如果ikuai版本不是`3.7.16`,还需要先升级为`3.7.16`)
|
||||
先下载 <a href="/update-20241130.bin" target="_blank">update-20241130.bin</a> 和 <a href="/iKuai-3.7.16-base.bin" target="_blank">iKuai-3.7.16</a>(如果ikuai版本不是`3.7.16`,还需要先升级为`3.7.16`)
|
||||
|
||||
然后依次上传`iKuai-3.7.16-base.bin`升级,重启,再上传`update-20241130.bin`升级,重启
|
||||
|
||||
|
||||
BIN
src/linker.doc.web/static/iKuai-3.7.16-base.bin
Normal file
BIN
src/linker.doc.web/static/iKuai-3.7.16-base.bin
Normal file
Binary file not shown.
@@ -1,19 +1,30 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import i18n from './lang';
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
import i18n from './lang';
|
||||
app.use(i18n);
|
||||
|
||||
import './assets/style.css'
|
||||
import router from './router'
|
||||
app.use(router);
|
||||
|
||||
import AccessShow from './views/components/accesss/AccessShow.vue';
|
||||
app.component('AccessShow', AccessShow);
|
||||
import AccessBoolean from './views/components/accesss/AccessBoolean.vue';
|
||||
app.component('AccessBoolean', AccessBoolean);
|
||||
import PhoneShow from './views/components/global/PhoneShow.vue';
|
||||
app.component('PhoneShow', PhoneShow);
|
||||
import PcShow from './views/components/global/PcShow.vue';
|
||||
app.component('PcShow', PcShow);
|
||||
|
||||
import './assets/style.css'
|
||||
import ElementPlus from 'element-plus';
|
||||
import 'element-plus/dist/index.css'
|
||||
import 'element-plus/theme-chalk/display.css'
|
||||
import 'element-plus/theme-chalk/dark/css-vars.css'
|
||||
app.use(ElementPlus, { size: 'default' });
|
||||
|
||||
app.use(ElementPlus, { size: 'default' }).use(router).mount('#app');
|
||||
app.mount('#app');
|
||||
|
||||
|
||||
app.directive('trim', {
|
||||
@@ -46,12 +57,10 @@ app.directive('trim', {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const ignoreErrors = [
|
||||
"ResizeObserver loop completed with undelivered notifications",
|
||||
"ResizeObserver loop limit exceeded"
|
||||
];
|
||||
|
||||
window.addEventListener('error', e => {
|
||||
let errorMsg = e.message;
|
||||
ignoreErrors.forEach(m => {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<slot :values="values"></slot>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { computed } from 'vue';
|
||||
|
||||
export default {
|
||||
props: ['value'],
|
||||
setup (props) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const values = computed(()=>props.value.split(',').reduce((json,item,index)=>{
|
||||
json[item] = globalData.value.hasAccess(item);
|
||||
return json;
|
||||
},{}) );
|
||||
|
||||
return {values}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
</style>
|
||||
21
src/linker.web/src/views/components/accesss/AccessShow.vue
Normal file
21
src/linker.web/src/views/components/accesss/AccessShow.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<slot v-if="show"></slot>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { computed } from 'vue';
|
||||
export default {
|
||||
props:['value'],
|
||||
setup (props) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const show = computed(()=>props.value.split(',').filter(c=>globalData.value.hasAccess(c)).length > 0 );
|
||||
|
||||
return {show}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
</style>
|
||||
@@ -62,14 +62,16 @@
|
||||
<el-table-column label="操作" width="54">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<el-popconfirm v-if="hasTunnelRemove" confirm-button-text="确认" cancel-button-text="取消"
|
||||
title="确定关闭此连接?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button type="danger" size="small"><el-icon>
|
||||
<Delete />
|
||||
</el-icon></el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<AccessShow value="TunnelRemove">
|
||||
<el-popconfirm confirm-button-text="确认" cancel-button-text="取消"
|
||||
title="确定关闭此连接?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button type="danger" size="small"><el-icon>
|
||||
<Delete />
|
||||
</el-icon></el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</AccessShow>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -149,7 +151,6 @@ export default {
|
||||
|
||||
const { t } = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const hasTunnelRemove = computed(() => globalData.value.hasAccess('TunnelRemove'));
|
||||
|
||||
const connections = useConnections();
|
||||
const forwardConnections = useForwardConnections();
|
||||
@@ -187,10 +188,6 @@ export default {
|
||||
}
|
||||
});
|
||||
const handleDel = (row) => {
|
||||
if (!hasTunnelRemove.value) {
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
row.removeFunc(row.RemoteMachineId).then(() => {
|
||||
ElMessage.success(t('common.oper'));
|
||||
}).catch(() => { });
|
||||
@@ -246,7 +243,7 @@ export default {
|
||||
})
|
||||
|
||||
return {
|
||||
state, handleDel, hasTunnelRemove,handlep2p, handleNode, handleConnect
|
||||
state, handleDel,handlep2p, handleNode, handleConnect
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,12 +34,10 @@
|
||||
</el-table-column>
|
||||
</template>
|
||||
<script>
|
||||
import { computed, ref } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import {Search} from '@element-plus/icons-vue'
|
||||
import UpdaterBtn from '../updater/UpdaterBtn.vue';
|
||||
import DeviceName from './DeviceName.vue';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
export default {
|
||||
@@ -48,15 +46,9 @@ export default {
|
||||
setup(props,{emit}) {
|
||||
|
||||
const t = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const hasExternal = computed(()=>globalData.value.hasAccess('ExternalShow'));
|
||||
const name = ref(sessionStorage.getItem('search-name') || '');
|
||||
|
||||
const handleExternal = (row)=>{
|
||||
if(!hasExternal.value) {
|
||||
ElMessage.success(t('common.access'));
|
||||
return;
|
||||
}
|
||||
row.showip=!row.showip;
|
||||
}
|
||||
const handleRefresh = ()=>{
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
<template>
|
||||
<div>
|
||||
<a href="javascript:;" @click="handleEdit" title="此客户端的设备名" class="a-line">
|
||||
<strong class="gateway" :class="{green:item.Connected}">{{item.MachineName || 'null' }}</strong>
|
||||
</a>
|
||||
|
||||
<strong class="self gateway" v-if="item.isSelf">(<el-icon size="16"><StarFilled /></el-icon>)</strong>
|
||||
<template v-if="tuntap.list[item.MachineId] && tuntap.list[item.MachineId].systems">
|
||||
<template v-for="system in tuntap.list[item.MachineId].systems">
|
||||
<span :title="tuntap.list[item.MachineId].SystemInfo">
|
||||
<img class="system" :src="`./${system}.svg`" />
|
||||
</span>
|
||||
</template>
|
||||
<AccessBoolean value="RenameSelf,RenameOther">
|
||||
<template #default="{values}">
|
||||
<div>
|
||||
<a href="javascript:;" @click="handleEdit(values)" title="此客户端的设备名" class="a-line">
|
||||
<strong class="gateway" :class="{green:item.Connected}">{{item.MachineName || 'null' }}</strong>
|
||||
</a>
|
||||
|
||||
<strong class="self gateway" v-if="item.isSelf">(<el-icon size="16"><StarFilled /></el-icon>)</strong>
|
||||
<template v-if="tuntap.list[item.MachineId] && tuntap.list[item.MachineId].systems">
|
||||
<template v-for="system in tuntap.list[item.MachineId].systems">
|
||||
<span :title="tuntap.list[item.MachineId].SystemInfo">
|
||||
<img class="system" :src="`./${system}.svg`" />
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</AccessBoolean>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -31,20 +35,18 @@ export default {
|
||||
const tuntap = useTuntap();
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const hasRenameSelf = computed(()=>globalData.value.hasAccess('RenameSelf'));
|
||||
const hasRenameOther = computed(()=>globalData.value.hasAccess('RenameOther'));
|
||||
const machineId = computed(() => globalData.value.config.Client.Id);
|
||||
const handleEdit = ()=>{
|
||||
const handleEdit = (access)=>{
|
||||
if(!props.config){
|
||||
return;
|
||||
}
|
||||
if(machineId.value === props.item.MachineId){
|
||||
if(!hasRenameSelf.value){
|
||||
if(!access.RenameSelf){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(!hasRenameOther.value){
|
||||
if(!access.RenameOther){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
@@ -55,7 +57,8 @@ export default {
|
||||
|
||||
|
||||
return {
|
||||
item:computed(()=>props.item),tuntap,handleEdit,accessLength:globalData.value.config.Client
|
||||
item:computed(()=>props.item),
|
||||
tuntap,handleEdit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
<a href="javascript:;" @click="state.showModes = true" class="mgr-1 delay a-line" :class="{red:state.nodes.length==0,green:state.nodes.length>0}">
|
||||
{{$t('server.sforwardNodes')}} : {{state.nodes.length}}
|
||||
</a>
|
||||
<WhiteList type="SForward" prefix="sfp->" v-if="state.super && hasWhiteList"></WhiteList>
|
||||
<AccessShow value="WhiteList">
|
||||
<WhiteList type="SForward" prefix="sfp->" v-if="state.super"></WhiteList>
|
||||
</AccessShow>
|
||||
<Nodes v-if="state.showModes" v-model="state.showModes" :data="state.nodes"></Nodes>
|
||||
<!-- <Status type="SForward"></Status> -->
|
||||
</div>
|
||||
@@ -26,7 +28,6 @@ export default {
|
||||
setup(props) {
|
||||
const {t} = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const hasWhiteList = computed(()=>globalData.value.hasAccess('WhiteList'));
|
||||
const state = reactive({
|
||||
super:computed(()=>globalData.value.signin.Super),
|
||||
type:props.type,
|
||||
@@ -55,7 +56,7 @@ export default {
|
||||
clearTimeout(state.timer);
|
||||
});
|
||||
|
||||
return {globalData,state,hasWhiteList}
|
||||
return {globalData,state}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -2,32 +2,23 @@
|
||||
<el-table-column prop="forward" :label="forward.show?$t('home.forward'):''" >
|
||||
<template #default="scope">
|
||||
<template v-if="forward.show && scope.row.Connected">
|
||||
<template v-if="scope.row.isSelf && (hasForwardShowSelf || hasForwardSelf)">
|
||||
<div class="nowrap">
|
||||
<ConnectionShow :data="connections.list[scope.row.MachineId]" :row="scope.row" transitionId="forward"></ConnectionShow>
|
||||
<a href="javascript:;" :class="{green:forward.list[scope.row.MachineId]>0 }" @click="handleEdit(scope.row.MachineId,scope.row.MachineName)">
|
||||
<span :class="{gateway:forward.list[scope.row.MachineId]>0}">{{$t('home.forwardPort')}}({{forward.list[scope.row.MachineId]>99 ? '99+' : forward.list[scope.row.MachineId]}})</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nowrap">
|
||||
<a href="javascript:;" :class="{green:sforward.list[scope.row.MachineId]>0}" @click="handleSEdit(scope.row.MachineId,scope.row.MachineName)">
|
||||
<span :class="{gateway:sforward.list[scope.row.MachineId]>0 }">{{$t('home.forwardServer')}}({{sforward.list[scope.row.MachineId]>99 ? '99+' : sforward.list[scope.row.MachineId]}})</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="hasForwardShowOther || hasForwardOther">
|
||||
<div class="nowrap">
|
||||
<ConnectionShow :data="connections.list[scope.row.MachineId]" :row="scope.row" transitionId="forward"></ConnectionShow>
|
||||
<a href="javascript:;" :class="{green:forward.list[scope.row.MachineId]>0}" @click="handleEdit(scope.row.MachineId,scope.row.MachineName)">
|
||||
<span :class="{gateway:forward.list[scope.row.MachineId]>0}">{{$t('home.forwardPort')}}({{forward.list[scope.row.MachineId]>99 ? '99+' : forward.list[scope.row.MachineId]}})</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nowrap">
|
||||
<a href="javascript:;" :class="{green:sforward.list[scope.row.MachineId]>0}" @click="handleSEdit(scope.row.MachineId,scope.row.MachineName)">
|
||||
<span :class="{gateway:sforward.list[scope.row.MachineId]>0 }">{{$t('home.forwardServer')}}({{sforward.list[scope.row.MachineId]>99 ? '99+' : sforward.list[scope.row.MachineId]}})</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
<AccessBoolean value="ForwardOther,ForwardSelf">
|
||||
<template #default="{values}">
|
||||
<template v-if="values.ForwardOther || (values.ForwardSelf && scope.row.isSelf)">
|
||||
<div class="nowrap">
|
||||
<ConnectionShow :data="connections.list[scope.row.MachineId]" :row="scope.row" transitionId="forward"></ConnectionShow>
|
||||
<a href="javascript:;" :class="{green:forward.list[scope.row.MachineId]>0}" @click="handleEdit(scope.row.MachineId,scope.row.MachineName,values)">
|
||||
<span :class="{gateway:forward.list[scope.row.MachineId]>0}">{{$t('home.forwardPort')}}({{forward.list[scope.row.MachineId]>99 ? '99+' : forward.list[scope.row.MachineId]}})</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nowrap">
|
||||
<a href="javascript:;" :class="{green:sforward.list[scope.row.MachineId]>0}" @click="handleSEdit(scope.row.MachineId,scope.row.MachineName,values)">
|
||||
<span :class="{gateway:sforward.list[scope.row.MachineId]>0 }">{{$t('home.forwardServer')}}({{sforward.list[scope.row.MachineId]>99 ? '99+' : sforward.list[scope.row.MachineId]}})</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</AccessBoolean>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -50,20 +41,16 @@ export default {
|
||||
const sforward = useSforward()
|
||||
const globalData = injectGlobalData();
|
||||
const machineId = computed(() => globalData.value.config.Client.Id);
|
||||
const hasForwardShowSelf = computed(()=>globalData.value.hasAccess('ForwardShowSelf'));
|
||||
const hasForwardShowOther = computed(()=>globalData.value.hasAccess('ForwardShowOther'));
|
||||
const hasForwardSelf = computed(()=>globalData.value.hasAccess('ForwardSelf'));
|
||||
const hasForwardOther = computed(()=>globalData.value.hasAccess('ForwardOther'));
|
||||
const connections = useForwardConnections();
|
||||
|
||||
const handleEdit = (_machineId,_machineName)=>{
|
||||
const handleEdit = (_machineId,_machineName,access)=>{
|
||||
if(machineId.value === _machineId){
|
||||
if(!hasForwardSelf.value){
|
||||
if(!access.ForwardSelf){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(!hasForwardOther.value){
|
||||
if(!access.ForwardOther){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
@@ -72,14 +59,14 @@ export default {
|
||||
forward.value.machineName = _machineName;
|
||||
forward.value.showEdit = true;
|
||||
}
|
||||
const handleSEdit = (_machineId,_machineName)=>{
|
||||
const handleSEdit = (_machineId,_machineName,access)=>{
|
||||
if(machineId.value === _machineId){
|
||||
if(!hasForwardSelf.value){
|
||||
if(!access.ForwardSelf){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(!hasForwardOther.value){
|
||||
if(!access.ForwardOther){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
@@ -93,7 +80,7 @@ export default {
|
||||
}
|
||||
|
||||
return {
|
||||
forward,sforward,hasForwardShowSelf,hasForwardShowOther,connections, handleEdit,handleSEdit,handleForwardRefresh
|
||||
forward,sforward,connections, handleEdit,handleSEdit,handleForwardRefresh
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
21
src/linker.web/src/views/components/global/PcShow.vue
Normal file
21
src/linker.web/src/views/components/global/PcShow.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<slot v-if="show"></slot>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { computed } from 'vue';
|
||||
|
||||
export default {
|
||||
setup () {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const show = computed(()=>globalData.value.isPhone == false);
|
||||
|
||||
return {show}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
</style>
|
||||
21
src/linker.web/src/views/components/global/PhoneShow.vue
Normal file
21
src/linker.web/src/views/components/global/PhoneShow.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<slot v-if="show"></slot>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { computed } from 'vue';
|
||||
export default {
|
||||
props:['value'],
|
||||
setup (props) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const show = computed(()=>globalData.value.isPhone);
|
||||
|
||||
return {show}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
</style>
|
||||
@@ -31,8 +31,7 @@
|
||||
</template>
|
||||
<template v-else>
|
||||
<a href="javascript:;" class="a-line" @click="handleEdit(scope.row, 'Password')">
|
||||
<template v-if="globalData.isPhone"><span>***</span></template>
|
||||
<template v-else><span>{{ scope.row.Password.replace(/.{1}/g,'*') }}</span></template>
|
||||
<template><span>***</span></template>
|
||||
</a>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
<el-icon class="right"><ArrowDown /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu v-if="hasGroup">
|
||||
<el-dropdown-item v-for="item in state.groups" @click="handleGroupChange(item.Id)">{{item.Name || '未知'}}</el-dropdown-item>
|
||||
<el-dropdown-item @click="state.showGroups = true">{{$t('status.group')}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
<AccessShow value="Group">
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="item in state.groups" @click="handleGroupChange(item.Id)">{{item.Name || '未知'}}</el-dropdown-item>
|
||||
<el-dropdown-item @click="state.showGroups = true">{{$t('status.group')}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</AccessShow>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<Groups v-if="state.showGroups" v-model="state.showGroups"></Groups>
|
||||
@@ -28,7 +30,6 @@ export default {
|
||||
setup(props) {
|
||||
const { t } = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const hasGroup = computed(()=>globalData.value.hasAccess('Group'));
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
connected: computed(() => globalData.value.signin.Connected),
|
||||
@@ -66,7 +67,7 @@ export default {
|
||||
});
|
||||
}
|
||||
return {
|
||||
config:props.config,hasGroup, state,handleGroupChange
|
||||
config:props.config,state,handleGroupChange
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,67 @@
|
||||
<template>
|
||||
<el-table-column :label="$t('home.oper')" fixed="right" width="75">
|
||||
<template #default="scope">
|
||||
<el-dropdown size="small" >
|
||||
<div class="dropdown">
|
||||
<span>{{$t('home.oper')}}</span>
|
||||
<el-icon class="el-icon--right">
|
||||
<ArrowDown />
|
||||
</el-icon>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<template v-if="scope.row.Connected">
|
||||
<el-dropdown-item v-if="scope.row.showReboot && hasReboot" @click="handleExit(scope.row.MachineId,scope.row.MachineName)"><el-icon><SwitchButton /></el-icon>{{$t('home.reboot')}}</el-dropdown-item>
|
||||
<el-dropdown-item v-if="handleShowAccess(scope.row,accessList[scope.row.MachineId] || '0')" @click="handleAccess(scope.row)"><el-icon><Flag /></el-icon>{{$t('home.access')}}</el-dropdown-item>
|
||||
<el-dropdown-item v-if="scope.row.isSelf && hasApiPassword" @click="handleApiPassword(scope.row)"><el-icon><HelpFilled /></el-icon>{{$t('home.managerApi')}}</el-dropdown-item>
|
||||
<el-dropdown-item v-else-if="hasApiPasswordOther" @click="handleApiPassword(scope.row)"><el-icon><HelpFilled /></el-icon> {{$t('home.managerApi')}}</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleStopwatch(scope.row.MachineId,scope.row.MachineName)"><el-icon><Platform /></el-icon>{{$t('home.messenger',[scope.row.MachineName])}}</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleStopwatch('',$t('home.server'))"><el-icon><Platform /></el-icon>{{$t('home.messengerServer')}}</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleRoutes(scope.row.MachineId,scope.row.MachineName)"><el-icon><Paperclip /></el-icon>{{$t('home.tuntapRoute')}}</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item v-if="scope.row.isSelf && hasFirewallSelf" @click="handleFirewall(scope.row.MachineId,scope.row.MachineName)"><el-icon><CircleCheck /></el-icon>{{$t('home.firewall')}}</el-dropdown-item>
|
||||
<el-dropdown-item v-else-if="hasFirewallOther" @click="handleFirewall(scope.row.MachineId,scope.row.MachineName)"><el-icon><CircleCheck /></el-icon>{{$t('home.firewall')}}</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item v-if="scope.row.isSelf && hasWakeupSelf" @click="handleWakeup(scope.row.MachineId,scope.row.MachineName)"><el-icon><VideoPlay /></el-icon>{{$t('home.wakeup')}}</el-dropdown-item>
|
||||
<el-dropdown-item v-else-if="hasWakeupOther" @click="handleWakeup(scope.row.MachineId,scope.row.MachineName)"><el-icon><VideoPlay /></el-icon>{{$t('home.wakeup')}}</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item v-if="hasTransport" @click="handleTransport(scope.row.MachineId,scope.row.MachineName)"><el-icon><Orange /></el-icon>{{$t('home.protocol')}}</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item v-if="scope.row.isSelf && hasActionSelf" @click="handleAction(scope.row.MachineId,scope.row.MachineName)"><el-icon><Lock /></el-icon>{{$t('home.action')}}</el-dropdown-item>
|
||||
<el-dropdown-item v-else-if="hasActionOther" @click="handleAction(scope.row.MachineId,scope.row.MachineName)"><el-icon><Lock /></el-icon>{{$t('home.action')}}</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item v-if="scope.row.isSelf && hasFlow" @click="handleFlow(scope.row.MachineId,scope.row.MachineName)"><el-icon><Histogram /></el-icon>{{$t('home.flowStatis')}}</el-dropdown-item>
|
||||
<el-dropdown-item v-else-if="hasFlow" @click="handleFlow(scope.row.MachineId,scope.row.MachineName)"><el-icon><Histogram /></el-icon>{{$t('home.flowStatis')}}</el-dropdown-item>
|
||||
<AccessBoolean value="Access">
|
||||
<template #default="{values}">
|
||||
<el-table-column :label="$t('home.oper')" fixed="right" width="75">
|
||||
<template #default="scope">
|
||||
<el-dropdown size="small" >
|
||||
<div class="dropdown">
|
||||
<span>{{$t('home.oper')}}</span>
|
||||
<el-icon class="el-icon--right">
|
||||
<ArrowDown />
|
||||
</el-icon>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<template v-if="scope.row.Connected">
|
||||
<AccessShow value="Reboot">
|
||||
<el-dropdown-item v-if="scope.row.showReboot" @click="handleExit(scope.row.MachineId,scope.row.MachineName)"><el-icon><SwitchButton /></el-icon>{{$t('home.reboot')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<el-dropdown-item v-if="handleShowAccess(scope.row,accessList[scope.row.MachineId] || '0',values)" @click="handleAccess(scope.row)"><el-icon><Flag /></el-icon>{{$t('home.access')}}</el-dropdown-item>
|
||||
<AccessShow value="ApiPassword">
|
||||
<el-dropdown-item v-if="scope.row.isSelf" @click="handleApiPassword(scope.row)"><el-icon><HelpFilled /></el-icon>{{$t('home.managerApi')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="ApiPasswordOther">
|
||||
<el-dropdown-item v-if="scope.row.isSelf==false" @click="handleApiPassword(scope.row)"><el-icon><HelpFilled /></el-icon> {{$t('home.managerApi')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<el-dropdown-item @click="handleStopwatch(scope.row.MachineId,scope.row.MachineName)"><el-icon><Platform /></el-icon>{{$t('home.messenger',[scope.row.MachineName])}}</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleStopwatch('',$t('home.server'))"><el-icon><Platform /></el-icon>{{$t('home.messengerServer')}}</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleRoutes(scope.row.MachineId,scope.row.MachineName)"><el-icon><Paperclip /></el-icon>{{$t('home.tuntapRoute')}}</el-dropdown-item>
|
||||
<AccessShow value="FirewallSelf">
|
||||
<el-dropdown-item v-if="scope.row.isSelf" @click="handleFirewall(scope.row.MachineId,scope.row.MachineName)"><el-icon><CircleCheck /></el-icon>{{$t('home.firewall')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="FirewallOther">
|
||||
<el-dropdown-item v-if="scope.row.isSelf==false" @click="handleFirewall(scope.row.MachineId,scope.row.MachineName)"><el-icon><CircleCheck /></el-icon>{{$t('home.firewall')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="WakeupSelf">
|
||||
<el-dropdown-item v-if="scope.row.isSelf" @click="handleWakeup(scope.row.MachineId,scope.row.MachineName)"><el-icon><VideoPlay /></el-icon>{{$t('home.wakeup')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="WakeupOther">
|
||||
<el-dropdown-item v-if="scope.row.isSelf==false" @click="handleWakeup(scope.row.MachineId,scope.row.MachineName)"><el-icon><VideoPlay /></el-icon>{{$t('home.wakeup')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="Transport">
|
||||
<el-dropdown-item @click="handleTransport(scope.row.MachineId,scope.row.MachineName)"><el-icon><Orange /></el-icon>{{$t('home.protocol')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="ActionSelf">
|
||||
<el-dropdown-item v-if="scope.row.isSelf" @click="handleAction(scope.row.MachineId,scope.row.MachineName)"><el-icon><Lock /></el-icon>{{$t('home.action')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="ActionOther">
|
||||
<el-dropdown-item v-if="scope.row.isSelf==false" @click="handleAction(scope.row.MachineId,scope.row.MachineName)"><el-icon><Lock /></el-icon>{{$t('home.action')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="Flow">
|
||||
<el-dropdown-item @click="handleFlow(scope.row.MachineId,scope.row.MachineName)"><el-icon><Histogram /></el-icon>{{$t('home.flowStatis')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
</template>
|
||||
<AccessShow value="Remove">
|
||||
<el-dropdown-item v-if="scope.row.showDel" @click="handleDel(scope.row.MachineId,scope.row.MachineName)"><el-icon><Delete /></el-icon> {{$t('home.delete')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
<el-dropdown-item v-if="scope.row.showDel && hasRemove" @click="handleDel(scope.row.MachineId,scope.row.MachineName)"><el-icon><Delete /></el-icon> {{$t('home.delete')}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</AccessBoolean>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -67,27 +89,8 @@ export default {
|
||||
const devices = useDevice();
|
||||
const allAccess = useAccess();
|
||||
const myAccess = computed(()=>globalData.value.config.Client.AccessBits);
|
||||
const hasAccess = computed(()=>globalData.value.hasAccess('Access'));
|
||||
const accessList = computed(()=>allAccess.value.list);
|
||||
|
||||
const hasReboot = computed(()=>globalData.value.hasAccess('Reboot'));
|
||||
const hasRemove = computed(()=>globalData.value.hasAccess('Remove'));
|
||||
|
||||
const hasApiPassword = computed(()=>globalData.value.hasAccess('SetApiPassword'));
|
||||
const hasApiPasswordOther = computed(()=>globalData.value.hasAccess('SetApiPasswordOther'));
|
||||
|
||||
const hasFirewallSelf = computed(()=>globalData.value.hasAccess('FirewallSelf'));
|
||||
const hasFirewallOther = computed(()=>globalData.value.hasAccess('FirewallOther'));
|
||||
|
||||
const hasWakeupSelf = computed(()=>globalData.value.hasAccess('WakeupSelf'));
|
||||
const hasWakeupOther = computed(()=>globalData.value.hasAccess('WakeupOther'));
|
||||
const hasTransport = computed(()=>globalData.value.hasAccess('Transport'));
|
||||
|
||||
const hasActionSelf = computed(()=>globalData.value.hasAccess('Action'));
|
||||
const hasActionOther = computed(()=>globalData.value.hasAccess('ActionOther'));
|
||||
|
||||
const hasFlow = computed(()=>globalData.value.hasAccess('Flow'));
|
||||
|
||||
const flow = useFlow();
|
||||
const oper = useOper();
|
||||
|
||||
@@ -114,11 +117,11 @@ export default {
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
const handleShowAccess = (row,rowAccess)=>{
|
||||
const handleShowAccess = (row,rowAccess,access)=>{
|
||||
let maxLength = Math.max(myAccess.value.length,rowAccess.length);
|
||||
let myValue = myAccess.value.padEnd(maxLength,'0').split('');
|
||||
let rowValue = rowAccess.padEnd(maxLength,'0').split('');
|
||||
return row.showAccess && hasAccess.value
|
||||
return row.showAccess && access.Access
|
||||
&& myValue.map((v,i)=>{
|
||||
return (rowValue[i] == '1' && v == '1') || rowValue[i] == '0';
|
||||
}).filter(c=>c).length > 0;
|
||||
@@ -182,10 +185,10 @@ export default {
|
||||
oper.value.showFlow = true;
|
||||
}
|
||||
|
||||
return {accessList,handleDel,handleExit,hasReboot,hasRemove,hasAccess,handleShowAccess,handleAccess,
|
||||
hasApiPassword,hasApiPasswordOther,handleApiPassword,handleStopwatch,handleRoutes,
|
||||
hasFirewallSelf,hasFirewallOther,handleFirewall,hasWakeupSelf,hasWakeupOther,handleWakeup,
|
||||
hasTransport,handleTransport,hasActionSelf,hasActionOther,handleAction,hasFlow,handleFlow
|
||||
return {accessList,handleDel,handleExit,handleShowAccess,handleAccess,
|
||||
handleApiPassword,handleStopwatch,handleRoutes,
|
||||
handleFirewall,handleWakeup,
|
||||
handleTransport,handleAction,handleFlow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +1,54 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex">
|
||||
<div class="flex-1">
|
||||
<ConnectionShow :data="connections.list[item.MachineId]" :row="item" transitionId="socks5"></ConnectionShow>
|
||||
<a href="javascript:;" class="a-line" @click="handleSocks5Port(socks5.list[item.MachineId])" title="此设备的socks5代理">
|
||||
<template v-if="socks5.list[item.MachineId].SetupError">
|
||||
<strong class="red" :title="socks5.list[item.MachineId].SetupError">
|
||||
socks5://*:{{ socks5.list[item.MachineId].Port }}
|
||||
</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="item.Connected &&socks5.list[item.MachineId].running">
|
||||
<strong class="green gateway">socks5://*:{{ socks5.list[item.MachineId].Port }}</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>socks5://*:{{ socks5.list[item.MachineId].Port }}</span>
|
||||
</template>
|
||||
</template>
|
||||
</a>
|
||||
</div>
|
||||
<template v-if="socks5.list[item.MachineId].loading">
|
||||
<div>
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-switch :model-value="item.Connected && socks5.list[item.MachineId].running" :loading="socks5.list[item.MachineId].loading" disabled @click="handleSocks5(socks5.list[item.MachineId])" size="small" inline-prompt active-text="😀" inactive-text="😣" >
|
||||
</el-switch>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<AccessBoolean value="Socks5ChangeSelf,Socks5ChangeOther,Socks5StatusSelf,Socks5StatusOther">
|
||||
<template #default="{values}">
|
||||
<div>
|
||||
<template v-for="(item1,index) in socks5.list[item.MachineId].Lans" :key="index">
|
||||
<template v-if="item1.Disabled">
|
||||
<div class="flex disable" title="已禁用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
<template v-else-if="item1.Exists">
|
||||
<div class="flex yellow" title="与其它设备填写IP、或本机局域网IP有冲突">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
<div class="flex">
|
||||
<div class="flex-1">
|
||||
<ConnectionShow :data="connections.list[item.MachineId]" :row="item" transitionId="socks5"></ConnectionShow>
|
||||
<a href="javascript:;" class="a-line" @click="handleSocks5Port(socks5.list[item.MachineId],values)" title="此设备的socks5代理">
|
||||
<template v-if="socks5.list[item.MachineId].SetupError">
|
||||
<strong class="red" :title="socks5.list[item.MachineId].SetupError">
|
||||
socks5://*:{{ socks5.list[item.MachineId].Port }}
|
||||
</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="item.Connected &&socks5.list[item.MachineId].running">
|
||||
<strong class="green gateway">socks5://*:{{ socks5.list[item.MachineId].Port }}</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>socks5://*:{{ socks5.list[item.MachineId].Port }}</span>
|
||||
</template>
|
||||
</template>
|
||||
</a>
|
||||
</div>
|
||||
<template v-if="socks5.list[item.MachineId].loading">
|
||||
<div>
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="flex green" title="正常使用" :class="{green:item.Connected &&socks5.list[item.MachineId].running}">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
<el-switch :model-value="item.Connected && socks5.list[item.MachineId].running" :loading="socks5.list[item.MachineId].loading" disabled @click="handleSocks5(socks5.list[item.MachineId],values)" size="small" inline-prompt active-text="😀" inactive-text="😣" >
|
||||
</el-switch>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<template v-for="(item1,index) in socks5.list[item.MachineId].Lans" :key="index">
|
||||
<template v-if="item1.Disabled">
|
||||
<div class="flex disable" title="已禁用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
<template v-else-if="item1.Exists">
|
||||
<div class="flex yellow" title="与其它设备填写IP、或本机局域网IP有冲突">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="flex green" title="正常使用" :class="{green:item.Connected &&socks5.list[item.MachineId].running}">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</AccessBoolean>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -65,23 +69,19 @@ export default {
|
||||
const socks5 = useSocks5();
|
||||
const globalData = injectGlobalData();
|
||||
const machineId = computed(() => globalData.value.config.Client.Id);
|
||||
const hasSocks5ChangeSelf = computed(()=>globalData.value.hasAccess('Socks5ChangeSelf'));
|
||||
const hasSocks5ChangeOther = computed(()=>globalData.value.hasAccess('Socks5ChangeOther'));
|
||||
const hasSocks5StatusSelf = computed(()=>globalData.value.hasAccess('Socks5StatusSelf'));
|
||||
const hasSocks5StatusOther = computed(()=>globalData.value.hasAccess('Socks5StatusOther'));
|
||||
const connections = useSocks5Connections();
|
||||
|
||||
const handleSocks5 = (socks5) => {
|
||||
const handleSocks5 = (socks5,access) => {
|
||||
if(!props.config){
|
||||
return;
|
||||
}
|
||||
if(machineId.value === socks5.MachineId){
|
||||
if(!hasSocks5StatusSelf.value){
|
||||
if(!access.Socks5StatusSelf){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(!hasSocks5StatusOther.value){
|
||||
if(!access.Socks5StatusOther){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
@@ -95,17 +95,17 @@ export default {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleSocks5Port = (socks5) => {
|
||||
const handleSocks5Port = (socks5,access) => {
|
||||
if(!props.config && machineId.value != socks5.MachineId){
|
||||
return;
|
||||
}
|
||||
if(machineId.value === socks5.MachineId){
|
||||
if(!hasSocks5ChangeSelf.value){
|
||||
if(!access.Socks5ChangeSelf){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(!hasSocks5ChangeOther.value){
|
||||
if(!access.Socks5ChangeOther){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,88 +1,92 @@
|
||||
<template>
|
||||
<div v-if="config && hasExport" class="status-export-wrap">
|
||||
<a href="javascript:;" :title="$t('status.export')" @click="state.show = true">
|
||||
<el-icon size="16"><Share /></el-icon>
|
||||
<span v-if="globalData.isPc">{{$t('status.export')}}</span>
|
||||
</a>
|
||||
<el-dialog class="options-center" :title="$t('status.export')" destroy-on-close v-model="state.show" center width="580" top="1vh">
|
||||
<div class="port-wrap">
|
||||
<div class="text">
|
||||
{{$t('status.exportText')}}
|
||||
</div>
|
||||
<div class="body">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="12"><el-checkbox :disabled="onlyNode" v-model="state.single" :label="$t('status.exportSingle')" /></el-col>
|
||||
<el-col :span="12">
|
||||
<div class="flex flex-nowrap">
|
||||
<span style="width: 11rem;">{{$t('status.exportName')}} : </span><el-input v-trim :disabled="!state.single" v-model="state.name" maxlength="32" show-word-limit></el-input>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<AccessShow value="Export">
|
||||
<div v-if="config" class="status-export-wrap">
|
||||
<a href="javascript:;" :title="$t('status.export')" @click="state.show = true">
|
||||
<el-icon size="16"><Share /></el-icon>
|
||||
<PcShow>
|
||||
<span>{{$t('status.export')}}</span>
|
||||
</PcShow>
|
||||
</a>
|
||||
<el-dialog class="options-center" :title="$t('status.export')" destroy-on-close v-model="state.show" center width="580" top="1vh">
|
||||
<div class="port-wrap">
|
||||
<div class="text">
|
||||
{{$t('status.exportText')}}
|
||||
</div>
|
||||
<div class="body">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="12"><el-checkbox :disabled="onlyNode" v-model="state.single" :label="$t('status.exportSingle')" /></el-col>
|
||||
<el-col :span="12">
|
||||
<div class="flex flex-nowrap">
|
||||
<span style="width: 11rem;">{{$t('status.exportName')}} : </span><el-input v-trim :disabled="!state.single" v-model="state.name" maxlength="32" show-word-limit></el-input>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<div class="flex flex-nowrap mgt-1">
|
||||
<span style="width: 11rem;">{{$t('status.exportWebport')}} : </span><el-input v-trim :disabled="onlyNode" v-model="state.webport"></el-input>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="flex flex-nowrap mgt-1">
|
||||
<span style="width: 11rem;">{{$t('status.exportApiPassword')}} : </span><el-input v-trim type="password" show-password :disabled="onlyNode" v-model="state.apipassword" maxlength="36" show-word-limit></el-input>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.relay" :label="$t('status.exportRelay')" /></el-col>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.updater" :label="$t('status.exportUpdater')" /></el-col>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.group" :label="$t('status.exportGroup')" /></el-col>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.server" :label="$t('status.exportServer')" /></el-col>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.super" :label="$t('status.exportSuper')" /></el-col>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.tunnel" :label="$t('status.exportTunnel')" /></el-col>
|
||||
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<div class="flex flex-nowrap mgt-1">
|
||||
<span style="width: 11rem;">{{$t('status.exportWebport')}} : </span><el-input v-trim :disabled="onlyNode" v-model="state.webport"></el-input>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="flex flex-nowrap mgt-1">
|
||||
<span style="width: 11rem;">{{$t('status.exportApiPassword')}} : </span><el-input v-trim type="password" show-password :disabled="onlyNode" v-model="state.apipassword" maxlength="36" show-word-limit></el-input>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.relay" :label="$t('status.exportRelay')" /></el-col>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.updater" :label="$t('status.exportUpdater')" /></el-col>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.group" :label="$t('status.exportGroup')" /></el-col>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.server" :label="$t('status.exportServer')" /></el-col>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.super" :label="$t('status.exportSuper')" /></el-col>
|
||||
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.tunnel" :label="$t('status.exportTunnel')" /></el-col>
|
||||
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<Access ref="accessDom" :machineid="machineId" :height="30"></Access>
|
||||
</el-card>
|
||||
</template>
|
||||
<Access ref="accessDom" :machineid="machineId" :height="30"></Access>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button plain @click="state.show = false" :loading="state.loading">{{$t('common.cancel') }}</el-button>
|
||||
<el-button type="default" plain @click="handleExport" :loading="state.loading">{{$t('status.exportDownload') }}</el-button>
|
||||
<el-button type="info" plain @click="handleCopy" :loading="state.loading">{{$t('status.exportCopy') }}</el-button>
|
||||
<el-button type="success" plain @click="handleSave" :loading="state.loading">{{$t('status.exportSave') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog class="options-center" :title="$t('status.export')" destroy-on-close v-model="state.showCopy" center width="580" top="1vh">
|
||||
<div class="port-wrap">
|
||||
<el-input v-trim v-model="state.copyContent" type="textarea" :rows="10" resize="none" readonly></el-input>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button plain @click="copyToClipboard">{{$t('status.exportCopy') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog class="options-center" :title="$t('status.export')" destroy-on-close v-model="state.showSave" center width="300" top="1vh">
|
||||
<div class="port-wrap">
|
||||
<div>
|
||||
<el-input v-trim v-model="state.saveServer" readonly></el-input>
|
||||
<template #footer>
|
||||
<el-button plain @click="state.show = false" :loading="state.loading">{{$t('common.cancel') }}</el-button>
|
||||
<el-button type="default" plain @click="handleExport" :loading="state.loading">{{$t('status.exportDownload') }}</el-button>
|
||||
<el-button type="info" plain @click="handleCopy" :loading="state.loading">{{$t('status.exportCopy') }}</el-button>
|
||||
<el-button type="success" plain @click="handleSave" :loading="state.loading">{{$t('status.exportSave') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog class="options-center" :title="$t('status.export')" destroy-on-close v-model="state.showCopy" center width="580" top="1vh">
|
||||
<div class="port-wrap">
|
||||
<el-input v-trim v-model="state.copyContent" type="textarea" :rows="10" resize="none" readonly></el-input>
|
||||
</div>
|
||||
<div style="margin-top:1rem">
|
||||
<el-input v-trim v-model="state.saveContent" readonly></el-input>
|
||||
<template #footer>
|
||||
<el-button plain @click="copyToClipboard">{{$t('status.exportCopy') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog class="options-center" :title="$t('status.export')" destroy-on-close v-model="state.showSave" center width="300" top="1vh">
|
||||
<div class="port-wrap">
|
||||
<div>
|
||||
<el-input v-trim v-model="state.saveServer" readonly></el-input>
|
||||
</div>
|
||||
<div style="margin-top:1rem">
|
||||
<el-input v-trim v-model="state.saveContent" readonly></el-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button plain @click="copySaveToClipboard">{{$t('status.exportCopy') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button plain @click="copySaveToClipboard">{{$t('status.exportCopy') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</AccessShow>
|
||||
</template>
|
||||
<script>
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
@@ -99,7 +103,6 @@ export default {
|
||||
|
||||
const { t } = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const hasExport = computed(()=>globalData.value.hasAccess('Export'));
|
||||
const onlyNode = computed(()=>globalData.value.config.Client.OnlyNode);
|
||||
const machineId = computed(()=>globalData.value.config.Client.Id);
|
||||
const state = reactive({
|
||||
@@ -128,10 +131,6 @@ export default {
|
||||
|
||||
|
||||
const getJson = ()=>{
|
||||
if(!hasExport.value){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
const access = accessDom.value.getValue();
|
||||
const json = {
|
||||
access:access[0],
|
||||
@@ -260,7 +259,7 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
return {globalData,config:props.config,onlyNode,hasExport,machineId, state,accessDom,
|
||||
return {globalData,config:props.config,onlyNode,machineId, state,accessDom,
|
||||
handleSave,handleExport,handleCopy,copyToClipboard,copySaveToClipboard};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,13 +7,17 @@
|
||||
<span>{{$t('status.support')}}</span>
|
||||
</a>
|
||||
<a href="javascript:;">©linker {{ self.Version }}</a>
|
||||
<a v-if="globalData.isPc" href="https://github.com/snltty/linker" target="_blank">Github</a>
|
||||
<a v-if="globalData.isPc" href="https://linker.snltty.com" target="_blank">{{$t('status.website')}}</a>
|
||||
<a v-if="globalData.isPc" href="https://linker-doc.snltty.com" target="_blank">{{$t('status.doc')}}</a>
|
||||
<PcShow>
|
||||
<a href="https://github.com/snltty/linker" target="_blank">Github</a>
|
||||
<a href="https://linker.snltty.com" target="_blank">{{$t('status.website')}}</a>
|
||||
<a href="https://linker-doc.snltty.com" target="_blank">{{$t('status.doc')}}</a>
|
||||
</PcShow>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="export"><Export :config="config"></Export></div>
|
||||
<div class="api" v-if="globalData.isPc"><Api :config="config"></Api></div>
|
||||
<PcShow>
|
||||
<div class="api"><Api :config="config"></Api></div>
|
||||
</PcShow>
|
||||
<div class="server"><Server :config="config"></Server></div>
|
||||
|
||||
<el-dialog v-model="state.showPay" :title="$t('status.support')" width="80%">
|
||||
@@ -35,7 +39,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import { computed, reactive } from 'vue';
|
||||
import Api from './Api.vue'
|
||||
import Server from './server/Index.vue'
|
||||
import Export from './Export.vue'
|
||||
@@ -52,7 +56,7 @@ export default {
|
||||
showPay:false
|
||||
});
|
||||
return {
|
||||
globalData,state,config:props.config,self
|
||||
state,config:props.config,self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,30 +2,28 @@
|
||||
<div class="status-server-wrap">
|
||||
<Groups :config="config"></Groups>
|
||||
<ServerVersion :config="config"></ServerVersion>
|
||||
<Flow v-if="config && hasFlow" :config="config"></Flow>
|
||||
<AccessShow value="Flow">
|
||||
<Flow v-if="config" :config="config"></Flow>
|
||||
</AccessShow>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { computed, reactive } from 'vue';
|
||||
import { reactive } from 'vue';
|
||||
import Groups from '../../groups/Index.vue';
|
||||
import Flow from './Flow.vue';
|
||||
import ServerVersion from './Version.vue';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
export default {
|
||||
components:{Groups,Flow,ServerVersion},
|
||||
props:['config'],
|
||||
setup(props) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const hasFlow = computed(()=>globalData.value.hasAccess('Flow'));
|
||||
|
||||
const state = reactive({
|
||||
show: false,
|
||||
loading: false
|
||||
});
|
||||
|
||||
return {
|
||||
config:props.config,hasFlow, state
|
||||
config:props.config,state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
<template>
|
||||
<a href="javascript:;" @click="handleUpdate" class="download" :title="updateText()" :class="updateColor()">
|
||||
<span>{{state.version}}</span>
|
||||
<template v-if="updaterServer.Version">
|
||||
<template v-if="updaterServer.Status == 1">
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="updaterServer.Status == 2">
|
||||
<el-icon size="14"><Download /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="updaterServer.Status == 3 || updaterServer.Status == 5">
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
<span class="progress" v-if="updaterServer.Length ==0">0%</span>
|
||||
<span class="progress" v-else>{{parseInt(updaterServer.Current/updaterServer.Length*100)}}%</span>
|
||||
</template>
|
||||
<template v-else-if="updaterServer.Status == 6">
|
||||
<el-icon size="14" class="yellow"><CircleCheck /></el-icon>
|
||||
</template>
|
||||
<AccessBoolean value="UpdateServer">
|
||||
<template #default="{values}">
|
||||
<a href="javascript:;" @click="handleUpdate(values)" class="download" :title="updateText()" :class="updateColor()">
|
||||
<span>{{state.version}}</span>
|
||||
<template v-if="updaterServer.Version">
|
||||
<template v-if="updaterServer.Status == 1">
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="updaterServer.Status == 2">
|
||||
<el-icon size="14"><Download /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="updaterServer.Status == 3 || updaterServer.Status == 5">
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
<span class="progress" v-if="updaterServer.Length ==0">0%</span>
|
||||
<span class="progress" v-else>{{parseInt(updaterServer.Current/updaterServer.Length*100)}}%</span>
|
||||
</template>
|
||||
<template v-else-if="updaterServer.Status == 6">
|
||||
<el-icon size="14" class="yellow"><CircleCheck /></el-icon>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-icon size="14"><Download /></el-icon>
|
||||
</template>
|
||||
</a>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-icon size="14"><Download /></el-icon>
|
||||
</template>
|
||||
</a>
|
||||
</AccessBoolean>
|
||||
</template>
|
||||
<script>
|
||||
import { injectGlobalData } from '@/provide';
|
||||
@@ -37,7 +41,6 @@ export default {
|
||||
|
||||
const { t } = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const hasUpdateServer = computed(()=>globalData.value.hasAccess('UpdateServer'));
|
||||
const updaterServer = ref({Version: '', Status: 0, Length: 0, Current: 0,Msg:[],DateTime:''});
|
||||
|
||||
const state = reactive({
|
||||
@@ -86,8 +89,8 @@ export default {
|
||||
const updateColor = ()=>{
|
||||
return state.version != updaterServer.value.Version ? 'yellow' :'green'
|
||||
}
|
||||
const handleUpdate = ()=>{
|
||||
if(!props.config || !hasUpdateServer.value){
|
||||
const handleUpdate = (access)=>{
|
||||
if(!props.config || !access.UpdateServer){
|
||||
return;
|
||||
}
|
||||
//未检测,检测中,下载中,解压中
|
||||
|
||||
@@ -1,31 +1,35 @@
|
||||
<template>
|
||||
<div>
|
||||
<slot>
|
||||
<el-button class="btn" size="small" @click="handleShowSync"><el-icon><Share /></el-icon></el-button>
|
||||
</slot>
|
||||
<el-dialog class="options-center" :title="$t('server.sync')" destroy-on-close v-model="state.showNames" width="54rem" top="2vh">
|
||||
<AccessBoolean value="Sync">
|
||||
<template #default="{values}">
|
||||
<div>
|
||||
<div class="t-c">
|
||||
{{ `${$t('server.sync')}【${$t(`server.async${state.name}`)}】${$t('server.asyncText')}` }}
|
||||
</div>
|
||||
<el-transfer class="src-tranfer mgt-1"
|
||||
v-model="state.srcIdValues"
|
||||
filterable
|
||||
:filter-method="srcFilterMethod"
|
||||
:data="state.srcIds"
|
||||
:titles="[$t('firewall.unselect'), $t('firewall.selected')]"
|
||||
:props="{
|
||||
key: 'MachineId',
|
||||
label: 'MachineName',
|
||||
}"
|
||||
/>
|
||||
<div class="t-c w-100 mgt-1">
|
||||
<el-button @click="state.showNames = false">{{$t('common.cancel')}}</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">{{$t('common.confirm')}}</el-button>
|
||||
<slot>
|
||||
<el-button class="btn" size="small" @click="handleShowSync(values)"><el-icon><Share /></el-icon></el-button>
|
||||
</slot>
|
||||
<el-dialog class="options-center" :title="$t('server.sync')" destroy-on-close v-model="state.showNames" width="54rem" top="2vh">
|
||||
<div>
|
||||
<div class="t-c">
|
||||
{{ `${$t('server.sync')}【${$t(`server.async${state.name}`)}】${$t('server.asyncText')}` }}
|
||||
</div>
|
||||
<el-transfer class="src-tranfer mgt-1"
|
||||
v-model="state.srcIdValues"
|
||||
filterable
|
||||
:filter-method="srcFilterMethod"
|
||||
:data="state.srcIds"
|
||||
:titles="[$t('firewall.unselect'), $t('firewall.selected')]"
|
||||
:props="{
|
||||
key: 'MachineId',
|
||||
label: 'MachineName',
|
||||
}"
|
||||
/>
|
||||
<div class="t-c w-100 mgt-1">
|
||||
<el-button @click="state.showNames = false">{{$t('common.cancel')}}</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">{{$t('common.confirm')}}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
</AccessBoolean>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -42,7 +46,6 @@ export default {
|
||||
setup (props) {
|
||||
const { t } = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const hasSync = computed(()=>globalData.value.hasAccess('Sync'));
|
||||
const state = reactive({
|
||||
name:props.name,
|
||||
loading:false,
|
||||
@@ -60,8 +63,8 @@ export default {
|
||||
state.showNames = false;
|
||||
});
|
||||
}
|
||||
const handleShowSync = ()=>{
|
||||
if(!hasSync.value){
|
||||
const handleShowSync = (access)=>{
|
||||
if(!access.Sync){
|
||||
ElMessage.success(t('common.access'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,43 +1,47 @@
|
||||
<template>
|
||||
<el-table-column prop="tunnel" :label="$t('home.tunnel')" width="86">
|
||||
<template #default="scope">
|
||||
<template v-if="tunnel.list[scope.row.MachineId]">
|
||||
<div>
|
||||
<template v-if="tunnel.list[scope.row.MachineId].Net.CountryCode">
|
||||
<img
|
||||
:title="`${tunnel.list[scope.row.MachineId].Net.CountryCode}、${tunnel.list[scope.row.MachineId].Net.City}`"
|
||||
class="system"
|
||||
:src="`https://unpkg.com/flag-icons@7.2.3/flags/4x3/${tunnel.list[scope.row.MachineId].Net.CountryCode.toLowerCase()}.svg`" />
|
||||
<AccessBoolean value="TunnelChangeSelf,TunnelChangeOther">
|
||||
<template #default="{values}">
|
||||
<el-table-column prop="tunnel" :label="$t('home.tunnel')" width="86">
|
||||
<template #default="scope">
|
||||
<template v-if="tunnel.list[scope.row.MachineId]">
|
||||
<div>
|
||||
<template v-if="tunnel.list[scope.row.MachineId].Net.CountryCode">
|
||||
<img
|
||||
:title="`${tunnel.list[scope.row.MachineId].Net.CountryCode}、${tunnel.list[scope.row.MachineId].Net.City}`"
|
||||
class="system"
|
||||
:src="`https://unpkg.com/flag-icons@7.2.3/flags/4x3/${tunnel.list[scope.row.MachineId].Net.CountryCode.toLowerCase()}.svg`" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<img title="?" class="system" src="/system.svg" />
|
||||
</template>
|
||||
<template v-if="tunnel.list[scope.row.MachineId].Net.Isp">
|
||||
<img
|
||||
:title="`${tunnel.list[scope.row.MachineId].Net.Isp}`"
|
||||
class="system" :src="netImg(tunnel.list[scope.row.MachineId].Net)" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<img title="?" class="system" src="/system.svg" />
|
||||
</template>
|
||||
<template v-if="tunnel.list[scope.row.MachineId].Net.Nat">
|
||||
<span class="nat" :title="tunnel.list[scope.row.MachineId].Net.Nat">{{ natMap[tunnel.list[scope.row.MachineId].Net.Nat] }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<img title="?" class="system" src="/system.svg" />
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<a href="javascript:;" class="a-line"
|
||||
:class="{yellow:tunnel.list[scope.row.MachineId].NeedReboot}"
|
||||
:title="$t('home.holeText')"
|
||||
@click="handleTunnel(tunnel.list[scope.row.MachineId],scope.row,values)">
|
||||
<span>{{$t('home.jump')}}:{{tunnel.list[scope.row.MachineId].RouteLevel}}+{{tunnel.list[scope.row.MachineId].RouteLevelPlus}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<img title="?" class="system" src="/system.svg" />
|
||||
</template>
|
||||
<template v-if="tunnel.list[scope.row.MachineId].Net.Isp">
|
||||
<img
|
||||
:title="`${tunnel.list[scope.row.MachineId].Net.Isp}`"
|
||||
class="system" :src="netImg(tunnel.list[scope.row.MachineId].Net)" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<img title="?" class="system" src="/system.svg" />
|
||||
</template>
|
||||
<template v-if="tunnel.list[scope.row.MachineId].Net.Nat">
|
||||
<span class="nat" :title="tunnel.list[scope.row.MachineId].Net.Nat">{{ natMap[tunnel.list[scope.row.MachineId].Net.Nat] }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<img title="?" class="system" src="/system.svg" />
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<a href="javascript:;" class="a-line"
|
||||
:class="{yellow:tunnel.list[scope.row.MachineId].NeedReboot}"
|
||||
:title="$t('home.holeText')"
|
||||
@click="handleTunnel(tunnel.list[scope.row.MachineId],scope.row)">
|
||||
<span>{{$t('home.jump')}}:{{tunnel.list[scope.row.MachineId].RouteLevel}}+{{tunnel.list[scope.row.MachineId].RouteLevelPlus}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</AccessBoolean>
|
||||
</template>
|
||||
<script>
|
||||
import { useTunnel } from './tunnel';
|
||||
@@ -54,8 +58,6 @@ export default {
|
||||
const t = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const machineId = computed(() => globalData.value.config.Client.Id);
|
||||
const hasTunnelChangeSelf = computed(()=>globalData.value.hasAccess('TunnelChangeSelf'));
|
||||
const hasTunnelChangeOther = computed(()=>globalData.value.hasAccess('TunnelChangeOther'));
|
||||
|
||||
const tunnel = useTunnel();
|
||||
const connections = useConnections();
|
||||
@@ -108,14 +110,14 @@ export default {
|
||||
return length;
|
||||
};
|
||||
|
||||
const handleTunnel = (_tunnel,row) => {
|
||||
const handleTunnel = (_tunnel,row,access) => {
|
||||
if(machineId.value === _tunnel.MachineId){
|
||||
if(!hasTunnelChangeSelf.value){
|
||||
if(!access.TunnelChangeSelf){
|
||||
ElMessage.success(t('common.access'));
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(!hasTunnelChangeOther.value){
|
||||
if(!access.TunnelChangeOther){
|
||||
ElMessage.success(t('common.access'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -25,21 +25,22 @@
|
||||
<p><span class="label">IP数量</span><span class="value">{{ state.values.Count }}</span></p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="Btns" v-if="hasLease">
|
||||
<div>
|
||||
<el-button @click="state.show = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSave">确认</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<AccessShow value="Lease">
|
||||
<el-form-item label="" prop="Btns">
|
||||
<div>
|
||||
<el-button @click="state.show = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSave">确认</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</AccessShow>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import {getNetwork,addNetwork,calcNetwork } from '@/apis/tuntap';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
import { Delete, Plus } from '@element-plus/icons-vue'
|
||||
export default {
|
||||
props: ['modelValue'],
|
||||
@@ -47,9 +48,6 @@ export default {
|
||||
components: {Delete,Plus},
|
||||
setup(props, { emit }) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const hasLease = computed(()=>globalData.value.hasAccess('Lease'));
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
const state = reactive({
|
||||
show: true,
|
||||
@@ -123,7 +121,7 @@ export default {
|
||||
})
|
||||
|
||||
return {
|
||||
state,hasLease, ruleFormRef, handleSave,handlePrefixLengthChange,handleClear
|
||||
state,ruleFormRef, handleSave,handlePrefixLengthChange,handleClear
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,77 +1,81 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex">
|
||||
<div class="flex-1">
|
||||
<ConnectionShow :data="connections.list[item.MachineId]" :row="item" transitionId="tuntap"></ConnectionShow>
|
||||
<a href="javascript:;" class="a-line" @click="handleTuntapIP(tuntap.list[item.MachineId])" title="虚拟网卡IP">
|
||||
<template v-if="item.Connected">
|
||||
<template v-if="tuntap.list[item.MachineId].SetupError">
|
||||
<strong class="red" :title="`setup ${tuntap.list[item.MachineId].SetupError}`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].Exists">
|
||||
<strong class="red" title="IP存在冲突,请使用新IP">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].Available == false">
|
||||
<strong class="disable" title="IP不生效,可能是设备不在线">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].NatError">
|
||||
<strong class="yellow" :title="`nat ${tuntap.list[item.MachineId].NatError}`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].AppNat && tuntap.list[item.MachineId].running">
|
||||
<strong class="app-nat" :title="`虚拟网卡IP\r\n应用层DNAT`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].running">
|
||||
<strong class="green gateway" :title="`虚拟网卡IP\r\n系统NAT`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<strong>{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<AccessBoolean value="TuntapChangeSelf,TuntapChangeOther,TuntapStatusSelf,TuntapStatusOther">
|
||||
<template #default="{values}">
|
||||
<div>
|
||||
<div class="flex">
|
||||
<div class="flex-1">
|
||||
<ConnectionShow :data="connections.list[item.MachineId]" :row="item" transitionId="tuntap"></ConnectionShow>
|
||||
<a href="javascript:;" class="a-line" @click="handleTuntapIP(tuntap.list[item.MachineId],values)" title="虚拟网卡IP">
|
||||
<template v-if="item.Connected">
|
||||
<template v-if="tuntap.list[item.MachineId].SetupError">
|
||||
<strong class="red" :title="`setup ${tuntap.list[item.MachineId].SetupError}`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].Exists">
|
||||
<strong class="red" title="IP存在冲突,请使用新IP">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].Available == false">
|
||||
<strong class="disable" title="IP不生效,可能是设备不在线">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].NatError">
|
||||
<strong class="yellow" :title="`nat ${tuntap.list[item.MachineId].NatError}`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].AppNat && tuntap.list[item.MachineId].running">
|
||||
<strong class="app-nat" :title="`虚拟网卡IP\r\n应用层DNAT`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].running">
|
||||
<strong class="green gateway" :title="`虚拟网卡IP\r\n系统NAT`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<strong>{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<strong class="disable" title="IP不生效,可能是设备不在线">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
</template>
|
||||
</a>
|
||||
</div>
|
||||
<template v-if="tuntap.list[item.MachineId].loading">
|
||||
<div>
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<strong class="disable" title="IP不生效,可能是设备不在线">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
<el-switch :model-value="item.Connected && tuntap.list[item.MachineId].running" :loading="tuntap.list[item.MachineId].loading" disabled @click="handleTuntap(tuntap.list[item.MachineId],values)" size="small" inline-prompt active-text="😀" inactive-text="😣" >
|
||||
</el-switch>
|
||||
</template>
|
||||
</a>
|
||||
</div>
|
||||
<template v-if="tuntap.list[item.MachineId].loading">
|
||||
<div>
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-switch :model-value="item.Connected && tuntap.list[item.MachineId].running" :loading="tuntap.list[item.MachineId].loading" disabled @click="handleTuntap(tuntap.list[item.MachineId])" size="small" inline-prompt active-text="😀" inactive-text="😣" >
|
||||
</el-switch>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<template v-for="(item1,index) in tuntap.list[item.MachineId].Lans" :key="index">
|
||||
<template v-if="tuntap.list[item.MachineId].Available == false">
|
||||
<div class="flex disable" title="IP不生效,可能是设备不在线">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
<div>
|
||||
<div>
|
||||
<template v-for="(item1,index) in tuntap.list[item.MachineId].Lans" :key="index">
|
||||
<template v-if="tuntap.list[item.MachineId].Available == false">
|
||||
<div class="flex disable" title="IP不生效,可能是设备不在线">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
<template v-else-if="item1.Disabled">
|
||||
<div class="flex disable" title="已禁用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
<template v-else-if="item1.Exists">
|
||||
<div class="flex yellow" title="与其它设备填写IP、或本机局域网IP有冲突、或与本机外网IP一致">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="flex green" title="正常使用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
<template v-if="tuntap.list[item.MachineId].Any">
|
||||
<div class="any green"><el-icon><Share /></el-icon></div>
|
||||
</template>
|
||||
<template v-else-if="item1.Disabled">
|
||||
<div class="flex disable" title="已禁用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
<template v-if="showDelay">
|
||||
<template v-if="tuntap.list[item.MachineId].Delay>=0 && tuntap.list[item.MachineId].Delay<=100">
|
||||
<div class="delay green">{{ tuntap.list[item.MachineId].Delay }}ms</div>
|
||||
</template>
|
||||
<template>
|
||||
<div class="delay yellow">{{ tuntap.list[item.MachineId].Delay }}ms</div>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="item1.Exists">
|
||||
<div class="flex yellow" title="与其它设备填写IP、或本机局域网IP有冲突、或与本机外网IP一致">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="flex green" title="正常使用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="tuntap.list[item.MachineId].Any">
|
||||
<div class="any green"><el-icon><Share /></el-icon></div>
|
||||
</template>
|
||||
<template v-if="showDelay">
|
||||
<template v-if="tuntap.list[item.MachineId].Delay>=0 && tuntap.list[item.MachineId].Delay<=100">
|
||||
<div class="delay green">{{ tuntap.list[item.MachineId].Delay }}ms</div>
|
||||
</template>
|
||||
<template>
|
||||
<div class="delay yellow">{{ tuntap.list[item.MachineId].Delay }}ms</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</AccessBoolean>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -91,25 +95,21 @@ export default {
|
||||
const tuntap = useTuntap();
|
||||
const globalData = injectGlobalData();
|
||||
const machineId = computed(() => globalData.value.config.Client.Id);
|
||||
const hasTuntapChangeSelf = computed(()=>globalData.value.hasAccess('TuntapChangeSelf'));
|
||||
const hasTuntapChangeOther = computed(()=>globalData.value.hasAccess('TuntapChangeOther'));
|
||||
const hasTuntapStatusSelf = computed(()=>globalData.value.hasAccess('TuntapStatusSelf'));
|
||||
const hasTuntapStatusOther = computed(()=>globalData.value.hasAccess('TuntapStatusOther'));
|
||||
const connections = useTuntapConnections();
|
||||
|
||||
|
||||
const showDelay = computed(()=>((globalData.value.config.Running.Tuntap || {Switch:0}).Switch & 2) == 2);
|
||||
const handleTuntap = (_tuntap) => {
|
||||
const handleTuntap = (_tuntap,access) => {
|
||||
if(!props.config){
|
||||
return;
|
||||
}
|
||||
if(machineId.value === _tuntap.MachineId){
|
||||
if(!hasTuntapStatusSelf.value){
|
||||
if(!access.TuntapStatusSelf){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(!hasTuntapStatusOther.value){
|
||||
if(!access.TuntapStatusOther){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
@@ -124,18 +124,18 @@ export default {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleTuntapIP = (_tuntap) => {
|
||||
const handleTuntapIP = (_tuntap,access) => {
|
||||
if(!props.config && machineId.value != _tuntap.MachineId){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
if(machineId.value === _tuntap.MachineId){
|
||||
if(!hasTuntapChangeSelf.value){
|
||||
if(!access.TuntapChangeSelf){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(!hasTuntapChangeOther.value){
|
||||
if(!access.TuntapChangeOther){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,33 @@
|
||||
<template>
|
||||
<a href="javascript:;" class="download" @click="handleUpdate()" :title="updaterText" :class="updaterColor">
|
||||
<span>
|
||||
<span>{{item.Version}}</span>
|
||||
<template v-if="updater.list[item.MachineId]">
|
||||
<template v-if="updater.list[item.MachineId].Status == 1">
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="updater.list[item.MachineId].Status == 2">
|
||||
<el-icon size="14"><Download /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="updater.list[item.MachineId].Status == 3 || updater.list[item.MachineId].Status == 5">
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
<span class="progress" v-if="updater.list[item.MachineId].Length ==0">0%</span>
|
||||
<span class="progress" v-else>{{parseInt(updater.list[item.MachineId].Current/updater.list[item.MachineId].Length*100)}}%</span>
|
||||
</template>
|
||||
<template v-else-if="updater.list[item.MachineId].Status == 6">
|
||||
<el-icon size="14" class="yellow"><CircleCheck /></el-icon>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-icon size="14"><Download /></el-icon>
|
||||
</template>
|
||||
</span>
|
||||
</a>
|
||||
<a href="javascript:;" class="download" title="检查更新" @click="handleCheck"><el-icon><Refresh /></el-icon></a>
|
||||
<AccessBoolean value="UpdateSelf,UpdateOther">
|
||||
<template #default="{values}">
|
||||
<a href="javascript:;" class="download" @click="handleUpdate(values)" :title="updaterText" :class="updaterColor">
|
||||
<span>
|
||||
<span>{{item.Version}}</span>
|
||||
<template v-if="updater.list[item.MachineId]">
|
||||
<template v-if="updater.list[item.MachineId].Status == 1">
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="updater.list[item.MachineId].Status == 2">
|
||||
<el-icon size="14"><Download /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="updater.list[item.MachineId].Status == 3 || updater.list[item.MachineId].Status == 5">
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
<span class="progress" v-if="updater.list[item.MachineId].Length ==0">0%</span>
|
||||
<span class="progress" v-else>{{parseInt(updater.list[item.MachineId].Current/updater.list[item.MachineId].Length*100)}}%</span>
|
||||
</template>
|
||||
<template v-else-if="updater.list[item.MachineId].Status == 6">
|
||||
<el-icon size="14" class="yellow"><CircleCheck /></el-icon>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-icon size="14"><Download /></el-icon>
|
||||
</template>
|
||||
</span>
|
||||
</a>
|
||||
<a href="javascript:;" class="download" title="检查更新" @click="handleCheck"><el-icon><Refresh /></el-icon></a>
|
||||
</template>
|
||||
</AccessBoolean>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -40,8 +44,6 @@ export default {
|
||||
setup (props) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const hasUpdateSelf = computed(()=>globalData.value.hasAccess('UpdateSelf'));
|
||||
const hasUpdateOther = computed(()=>globalData.value.hasAccess('UpdateOther'));
|
||||
const updater = useUpdater();
|
||||
const serverVersion = computed(()=>globalData.value.signin.Version);
|
||||
const updaterVersion = computed(()=>updater.value.current.Version);
|
||||
@@ -70,16 +72,16 @@ export default {
|
||||
: updater.value.list[props.item.MachineId] && updaterVersion.value != props.item.Version
|
||||
? 'yellow' :'green'
|
||||
})
|
||||
const handleUpdate = ()=>{
|
||||
const handleUpdate = (access)=>{
|
||||
updater.value.device = props.item;
|
||||
if(!props.config){
|
||||
return;
|
||||
}
|
||||
if(!hasUpdateSelf.value){
|
||||
if(!access.UpdateSelf){
|
||||
ElMessage.error('无权限');
|
||||
return;
|
||||
}
|
||||
if(props.item.MachineId != globalData.value.self.MachineId && !hasUpdateOther.value){
|
||||
if(props.item.MachineId != globalData.value.self.MachineId && !access.UpdateOther){
|
||||
ElMessage.error('无权限');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,32 +1,35 @@
|
||||
<template>
|
||||
<el-dialog class="options-center" title="更新" destroy-on-close v-model="state.show" width="40rem" top="2vh">
|
||||
<div class="updater-wrap t-c">
|
||||
<div class="t-l">
|
||||
<ul>
|
||||
<li v-for="item in state.msg">{{ item }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex mgt-1">
|
||||
<el-row class="w-100">
|
||||
<el-col :span="10">
|
||||
<el-select v-model="state.type" size="large">
|
||||
<el-option v-for="item in state.types" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
->
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-select v-model="state.version" size="large" filterable allow-create default-first-option>
|
||||
<el-option v-for="item in state.versions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="mgt-1 t-c">
|
||||
<el-button type="success" @click="handleUpdate" plain>确 定</el-button>
|
||||
</div>
|
||||
|
||||
<AccessBoolean value="UpdateSelf,UpdateOther">
|
||||
<template #default="{values}">
|
||||
<div class="t-l">
|
||||
<ul>
|
||||
<li v-for="item in state.msg">{{ item }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex mgt-1">
|
||||
<el-row class="w-100">
|
||||
<el-col :span="10">
|
||||
<el-select v-model="state.type" size="large">
|
||||
<el-option v-for="item in getTypes(values)" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
->
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-select v-model="state.version" size="large" filterable allow-create default-first-option>
|
||||
<el-option v-for="item in state.versions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="mgt-1 t-c">
|
||||
<el-button type="success" @click="handleUpdate(values)" plain>确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</AccessBoolean>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
@@ -43,26 +46,18 @@ export default {
|
||||
setup (props,{emit}) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const hasUpdateSelf = computed(()=>globalData.value.hasAccess('UpdateSelf'));
|
||||
const hasUpdateOther = computed(()=>globalData.value.hasAccess('UpdateOther'));
|
||||
const updater = useUpdater();
|
||||
const serverVersion = computed(()=>globalData.value.signin.Version);
|
||||
const updaterVersion = computed(()=>updater.value.current.Version);
|
||||
|
||||
const types = [
|
||||
{label:`仅【${updater.value.device.MachineName}】`,value:updater.value.device.MachineId},
|
||||
hasUpdateOther.value ? {label:`本组所有`,value:'g-all'} : {},
|
||||
hasUpdateOther.value ? {label:`本服务器所有`,value:'s-all'} : {},
|
||||
].filter(c=>c.value);
|
||||
const versions = [
|
||||
{label:`${updaterVersion.value}【最新版本】`,value:updaterVersion.value},
|
||||
{label:`${serverVersion.value}【服务器版本】`,value:serverVersion.value},
|
||||
].filter(c=>c.value);
|
||||
const state = reactive({
|
||||
show: true,
|
||||
type:types[0] || '',
|
||||
type:'',
|
||||
version:versions[0] || '',
|
||||
types:types,
|
||||
versions:versions,
|
||||
msg:[]
|
||||
});
|
||||
@@ -74,7 +69,19 @@ export default {
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
const handleUpdate = ()=>{
|
||||
|
||||
const getTypes = (access)=>{
|
||||
const types = [
|
||||
{label:`仅【${updater.value.device.MachineName}】`,value:updater.value.device.MachineId},
|
||||
access.UpdateOther.value ? {label:`本组所有`,value:'g-all'} : {},
|
||||
access.UpdateOther.value ? {label:`本服务器所有`,value:'s-all'} : {},
|
||||
].filter(c=>c.value);
|
||||
if(!state.type){
|
||||
state.type = types[0] || '';
|
||||
}
|
||||
return types;
|
||||
}
|
||||
const handleUpdate = (access)=>{
|
||||
const data = {
|
||||
MachineId:updater.value.device.MachineId,
|
||||
Version:state.version.value || state.version,
|
||||
@@ -97,7 +104,7 @@ export default {
|
||||
});
|
||||
|
||||
return {
|
||||
state,updater,handleUpdate
|
||||
state,getTypes,updater,handleUpdate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
<Install></Install>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
<div class="flex">
|
||||
<el-input v-trim style="width:20rem;" v-model="state.list.Host" @blur="handleSave" />
|
||||
<Sync class="mgl-1" name="SignInServer"></Sync>
|
||||
<span class="mgl-1" v-if="globalData.isPc">{{$t('server.messengerText')}}</span>
|
||||
<PcShow>
|
||||
<span class="mgl-1">{{$t('server.messengerText')}}</span>
|
||||
</PcShow>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="`${$t('server.messengerAddr')}1`">
|
||||
@@ -28,19 +30,14 @@
|
||||
<el-input v-trim :class="{success:state.super,error:state.super==false}" style="width:20rem;" type="password" show-password maxlength="36" v-model="state.list.SuperPassword" @blur="handleSave" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item :label="$t('server.messenger')" v-if="state.super && hasWhiteList">
|
||||
<div>
|
||||
<div class="flex">
|
||||
<WhiteList type="SignIn"></WhiteList>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item> -->
|
||||
<el-form-item></el-form-item>
|
||||
<el-form-item :label="$t('server.messengerUserId')">
|
||||
<div class="flex">
|
||||
<el-input v-trim style="width:20rem;" type="password" show-password maxlength="36" v-model="state.list.UserId" @blur="handleSave" />
|
||||
<Sync class="mgl-1" name="SignInUserId"></Sync>
|
||||
<span class="mgl-1" v-if="globalData.isPc">{{$t('server.messengerUserIdText')}}</span>
|
||||
<PcShow>
|
||||
<span class="mgl-1">{{$t('server.messengerUserIdText')}}</span>
|
||||
</PcShow>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item></el-form-item>
|
||||
@@ -74,7 +71,6 @@ export default {
|
||||
setup(props) {
|
||||
const {t} = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const hasWhiteList = computed(()=>globalData.value.hasAccess('WhiteList'));
|
||||
const state = reactive({
|
||||
list:globalData.value.config.Client.Server,
|
||||
height: computed(()=>globalData.value.height-90),
|
||||
@@ -99,7 +95,7 @@ export default {
|
||||
handleCheckKey();
|
||||
});
|
||||
|
||||
return {globalData,state,hasWhiteList,handleSave}
|
||||
return {globalData,state,handleSave}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
<template>
|
||||
<div class="servers-wrap scrollbar" >
|
||||
<Config v-if="hasConfig"></Config>
|
||||
<AccessShow value="Config">
|
||||
<Config></Config>
|
||||
</AccessShow>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { computed, reactive } from 'vue';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import Config from './Config.vue';
|
||||
export default {
|
||||
components:{Config},
|
||||
setup(props) {
|
||||
const globalData = injectGlobalData();
|
||||
const hasConfig = computed(()=>globalData.value.hasAccess('Config'))
|
||||
const state = reactive({});
|
||||
return {
|
||||
state,hasConfig
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<div class="image" v-if="globalData.isPc">
|
||||
<a href="javascript:;" @click="handleBg"><el-icon><PictureRounded /></el-icon></a>
|
||||
<input type="file" id="file-input">
|
||||
</div>
|
||||
<PcShow>
|
||||
<div class="image">
|
||||
<a href="javascript:;" @click="handleBg"><el-icon><PictureRounded /></el-icon></a>
|
||||
<input type="file" id="file-input">
|
||||
</div>
|
||||
</PcShow>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import {PictureRounded} from '@element-plus/icons-vue'
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { onMounted } from 'vue';
|
||||
@@ -15,7 +16,6 @@ export default {
|
||||
props:['name'],
|
||||
setup(props) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const key = `bg-${props.name}`;
|
||||
|
||||
const handleBg = ()=>{
|
||||
@@ -67,7 +67,7 @@ export default {
|
||||
})
|
||||
|
||||
return {
|
||||
globalData,handleBg
|
||||
handleBg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
<template>
|
||||
<div class="locale" v-if="globalData.isPc">
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
{{localeOptions[locale]}}
|
||||
<el-icon>
|
||||
<ArrowDown />
|
||||
</el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="(item,index) in localeOptions" @click="handleLocale(index)">{{item}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<PcShow>
|
||||
<div class="locale">
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
{{localeOptions[locale]}}
|
||||
<el-icon>
|
||||
<ArrowDown />
|
||||
</el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="(item,index) in localeOptions" @click="handleLocale(index)">{{item}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</PcShow>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {ArrowDown} from '@element-plus/icons-vue'
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { computed, ref} from 'vue';
|
||||
import { LOCALE_OPTIONS } from '@/lang'
|
||||
import useLocale from '@/lang/provide'
|
||||
@@ -26,7 +27,6 @@ export default {
|
||||
components:{ArrowDown},
|
||||
setup() {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const localeOptions = ref(LOCALE_OPTIONS);
|
||||
const { changeLocale, currentLocale } = useLocale()
|
||||
const locale = computed({
|
||||
@@ -41,7 +41,6 @@ export default {
|
||||
locale.value =index;
|
||||
}
|
||||
return {
|
||||
globalData,
|
||||
localeOptions,locale,handleLocale
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,91 +1,131 @@
|
||||
<template>
|
||||
<div class="menu flex-1">
|
||||
<ul class="flex" v-if="globalData.isPc">
|
||||
<li>
|
||||
<router-link :to="{name:'FullIndex'}"><img src="@/assets/shouye.svg"/><span>{{$t('head.home')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasConfig">
|
||||
<router-link :to="{name:'FullServers'}"><img src="@/assets/fuwuqi.svg"/><span>{{$t('head.server')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasTransport">
|
||||
<router-link :to="{name:'FullTransport'}"><img src="@/assets/dadong.svg"/><span>{{$t('head.protocol')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasAction">
|
||||
<router-link :to="{name:'FullAction'}"><img src="@/assets/login.svg"/><span>{{$t('head.action')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasFirewall">
|
||||
<router-link :to="{name:'FullFirewall'}"><img src="@/assets/anquan.svg"/><span>{{$t('head.firewall')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasWakeupSelf">
|
||||
<router-link :to="{name:'FullWakeup'}"><img src="@/assets/qidong.svg"/><span>{{$t('head.wakeup')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasLogger">
|
||||
<router-link :to="{name:'FullLogger'}"><img src="@/assets/rizhi.svg"/><span>{{$t('head.logger')}}</span></router-link>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="flex" v-else>
|
||||
<li v-if="route.name == 'FullIndex'">
|
||||
<router-link :to="{name:'FullIndex'}"><img src="@/assets/shouye.svg"/><span>{{$t('head.home')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasConfig && route.name == 'FullServers'">
|
||||
<router-link :to="{name:'FullServers'}"><img src="@/assets/fuwuqi.svg"/><span>{{$t('head.server')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasTransport && route.name == 'FullTransport'">
|
||||
<router-link :to="{name:'FullTransport'}"><img src="@/assets/dadong.svg"/><span>{{$t('head.protocol')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasAction && route.name == 'FullAction'">
|
||||
<router-link :to="{name:'FullAction'}"><img src="@/assets/login.svg"/><span>{{$t('head.action')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasFirewall && route.name == 'FullFirewall'">
|
||||
<router-link :to="{name:'FullFirewall'}"><img src="@/assets/anquan.svg"/><span>{{$t('head.firewall')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasWakeupSelf && route.name == 'FullWakeup'">
|
||||
<router-link :to="{name:'FullWakeup'}"><img src="@/assets/qidong.svg"/><span>{{$t('head.wakeup')}}</span></router-link>
|
||||
</li>
|
||||
<li v-if="hasLogger && route.name == 'FullLogger'">
|
||||
<router-link :to="{name:'FullLogger'}"><img src="@/assets/rizhi.svg"/> <span>{{$t('head.logger')}}</span></router-link>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0);" @click="refresh"><img src="@/assets/shuaxin2.svg"/><span>{{$t('head.refresh')}}</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="select" v-if="globalData.isPhone">
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link"><el-icon><Operation /></el-icon></span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu class="select-menu">
|
||||
<el-dropdown-item>
|
||||
<router-link :to="{name:'FullIndex'}"><img src="@/assets/shouye.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.home')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="hasConfig">
|
||||
<router-link :to="{name:'FullServers'}"><img src="@/assets/fuwuqi.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.server')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="hasTransport">
|
||||
<router-link :to="{name:'FullTransport'}"><img src="@/assets/dadong.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.protocol')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="hasAction">
|
||||
<router-link :to="{name:'FullAction'}"><img src="@/assets/login.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.action')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="hasFirewall">
|
||||
<router-link :to="{name:'FullFirewall'}"><img src="@/assets/anquan.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.firewall')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="hasWakeupSelf">
|
||||
<router-link :to="{name:'FullWakeup'}"><img src="@/assets/qidong.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.wakeup')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="hasLogger">
|
||||
<router-link :to="{name:'FullLogger'}"><img src="@/assets/rizhi.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.logger')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<PcShow>
|
||||
<ul class="flex">
|
||||
<li>
|
||||
<router-link :to="{name:'FullIndex'}"><img src="@/assets/shouye.svg"/><span>{{$t('head.home')}}</span></router-link>
|
||||
</li>
|
||||
<AccessShow value="Config">
|
||||
<li>
|
||||
<router-link :to="{name:'FullServers'}"><img src="@/assets/fuwuqi.svg"/><span>{{$t('head.server')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<AccessShow value="Transport">
|
||||
<li>
|
||||
<router-link :to="{name:'FullTransport'}"><img src="@/assets/dadong.svg"/><span>{{$t('head.protocol')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<AccessShow value="Action">
|
||||
<li>
|
||||
<router-link :to="{name:'FullAction'}"><img src="@/assets/login.svg"/><span>{{$t('head.action')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<AccessShow value="FirewallSelf">
|
||||
<li>
|
||||
<router-link :to="{name:'FullFirewall'}"><img src="@/assets/anquan.svg"/><span>{{$t('head.firewall')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<AccessShow value="WakeupSelf">
|
||||
<li>
|
||||
<router-link :to="{name:'FullWakeup'}"><img src="@/assets/qidong.svg"/><span>{{$t('head.wakeup')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<AccessShow value="LoggerShow">
|
||||
<li>
|
||||
<router-link :to="{name:'FullLogger'}"><img src="@/assets/rizhi.svg"/><span>{{$t('head.logger')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
</ul>
|
||||
</PcShow>
|
||||
<PhoneShow>
|
||||
<ul class="flex">
|
||||
<li v-if="route.name == 'FullIndex'">
|
||||
<router-link :to="{name:'FullIndex'}"><img src="@/assets/shouye.svg"/><span>{{$t('head.home')}}</span></router-link>
|
||||
</li>
|
||||
<AccessShow value="Config">
|
||||
<li v-if="route.name == 'FullServers'">
|
||||
<router-link :to="{name:'FullServers'}"><img src="@/assets/fuwuqi.svg"/><span>{{$t('head.server')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<AccessShow value="Transport">
|
||||
<li v-if="route.name == 'FullTransport'">
|
||||
<router-link :to="{name:'FullTransport'}"><img src="@/assets/dadong.svg"/><span>{{$t('head.protocol')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<AccessShow value="Action">
|
||||
<li v-if="route.name == 'FullAction'">
|
||||
<router-link :to="{name:'FullAction'}"><img src="@/assets/login.svg"/><span>{{$t('head.action')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<AccessShow value="FirewallSelf">
|
||||
<li v-if="route.name == 'FullFirewall'">
|
||||
<router-link :to="{name:'FullFirewall'}"><img src="@/assets/anquan.svg"/><span>{{$t('head.firewall')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<AccessShow value="WakeupSelf">
|
||||
<li v-if="route.name == 'FullWakeup'">
|
||||
<router-link :to="{name:'FullWakeup'}"><img src="@/assets/qidong.svg"/><span>{{$t('head.wakeup')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<AccessShow value="LoggerShow">
|
||||
<li v-if="route.name == 'FullLogger'">
|
||||
<router-link :to="{name:'FullLogger'}"><img src="@/assets/rizhi.svg"/> <span>{{$t('head.logger')}}</span></router-link>
|
||||
</li>
|
||||
</AccessShow>
|
||||
<li>
|
||||
<a href="javascript:void(0);" @click="refresh"><img src="@/assets/shuaxin2.svg"/><span>{{$t('head.refresh')}}</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</PhoneShow>
|
||||
</div>
|
||||
<PhoneShow>
|
||||
<div class="select">
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link"><el-icon><Operation /></el-icon></span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu class="select-menu">
|
||||
<el-dropdown-item>
|
||||
<router-link :to="{name:'FullIndex'}"><img src="@/assets/shouye.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.home')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
<AccessShow value="Config">
|
||||
<el-dropdown-item>
|
||||
<router-link :to="{name:'FullServers'}"><img src="@/assets/fuwuqi.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.server')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="Transport">
|
||||
<el-dropdown-item>
|
||||
<router-link :to="{name:'FullTransport'}"><img src="@/assets/dadong.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.protocol')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="Action">
|
||||
<el-dropdown-item>
|
||||
<router-link :to="{name:'FullAction'}"><img src="@/assets/login.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.action')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="FirewallSelf">
|
||||
<el-dropdown-item>
|
||||
<router-link :to="{name:'FullFirewall'}"><img src="@/assets/anquan.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.firewall')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="WakeupSelf">
|
||||
<el-dropdown-item>
|
||||
<router-link :to="{name:'FullWakeup'}"><img src="@/assets/qidong.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.wakeup')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<AccessShow value="LoggerShow">
|
||||
<el-dropdown-item>
|
||||
<router-link :to="{name:'FullLogger'}"><img src="@/assets/rizhi.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.logger')}}</router-link>
|
||||
</el-dropdown-item>
|
||||
</AccessShow>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</PhoneShow>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {Operation,ArrowDown} from '@element-plus/icons-vue'
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { computed} from 'vue';
|
||||
import Background from './Background.vue';
|
||||
import Theme from './Theme.vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
@@ -94,20 +134,12 @@ export default {
|
||||
setup() {
|
||||
|
||||
const route = useRoute();
|
||||
const globalData = injectGlobalData();
|
||||
const hasConfig = computed(()=>globalData.value.hasAccess('Config'));
|
||||
const hasLogger = computed(()=>globalData.value.hasAccess('LoggerShow'));
|
||||
const hasTransport = computed(()=>globalData.value.hasAccess('Transport'));
|
||||
const hasAction = computed(()=>globalData.value.hasAccess('Action'));
|
||||
const hasFirewall = computed(()=>globalData.value.hasAccess('FirewallSelf'));
|
||||
const hasWakeupSelf = computed(()=>globalData.value.hasAccess('WakeupSelf'));
|
||||
const refresh = () => {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
return {
|
||||
route,globalData,hasConfig,
|
||||
hasLogger,hasTransport,hasAction,hasFirewall,hasWakeupSelf,refresh
|
||||
route,refresh
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<div class="image" v-if="globalData.isPc">
|
||||
<a href="javascript:;" @click="changeMode('light')" v-if="state.mode == 'dark'"><el-icon><Moon /></el-icon></a>
|
||||
<a href="javascript:;" @click="changeMode('dark')" v-else><el-icon><Sunny /></el-icon></a>
|
||||
</div>
|
||||
<PcShow>
|
||||
<div class="image">
|
||||
<a href="javascript:;" @click="changeMode('light')" v-if="state.mode == 'dark'"><el-icon><Moon /></el-icon></a>
|
||||
<a href="javascript:;" @click="changeMode('dark')" v-else><el-icon><Sunny /></el-icon></a>
|
||||
</div>
|
||||
</PcShow>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import {Moon,Sunny} from '@element-plus/icons-vue'
|
||||
import { onMounted, reactive } from 'vue';
|
||||
export default {
|
||||
components:{Moon,Sunny},
|
||||
setup () {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const isSystemDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const isSystemLightMode = window.matchMedia('(prefers-color-scheme: light)').matches;
|
||||
const cacheMode = localStorage.getItem('theme-mode') || (isSystemDarkMode?'dark':'light');
|
||||
@@ -33,7 +33,7 @@ export default {
|
||||
setMode();
|
||||
})
|
||||
|
||||
return {globalData,state,changeMode}
|
||||
return {state,changeMode}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -10,20 +10,23 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item label="" label-width="0" v-if="globalData.isPc">
|
||||
<el-row class="w-100">
|
||||
<el-col :sm="12" :xs="24" v-if="globalData.isPc">
|
||||
<el-form-item label="管理端口" prop="web">
|
||||
<el-input v-trim v-model="state.form.web" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<el-form-item label="管理密码" prop="password">
|
||||
<el-input v-trim type="password" v-model="state.form.password" show-password maxlength="36" show-word-limit/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<PcShow>
|
||||
<el-form-item label="" label-width="0">
|
||||
<el-row class="w-100">
|
||||
<el-col :sm="12" :xs="24">
|
||||
<el-form-item label="管理端口" prop="web">
|
||||
<el-input v-trim v-model="state.form.web" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :sm="12" :xs="24">
|
||||
<el-form-item label="管理密码" prop="password">
|
||||
<el-input v-trim type="password" v-model="state.form.password" show-password maxlength="36" show-word-limit/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</PcShow>
|
||||
|
||||
<el-form-item label="" label-width="0">
|
||||
<el-row class="w-100">
|
||||
<el-col :sm="12" :xs="24">
|
||||
@@ -160,7 +163,7 @@ export default {
|
||||
}
|
||||
})
|
||||
|
||||
return { state,globalData, handleValidate, formDom };
|
||||
return { state,handleValidate, formDom };
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div class="t-c">
|
||||
<el-checkbox v-model="state.form.client" label="作为客户端" />
|
||||
<el-checkbox v-model="state.form.server" label="作为服务端" v-if="globalData.isPc" />
|
||||
<PcShow>
|
||||
<el-checkbox v-model="state.form.server" label="作为服务端"/>
|
||||
</PcShow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -42,10 +42,7 @@ export default {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const state = reactive({
|
||||
steps:computed(()=>['选择模式',
|
||||
globalData.value.isPc ? '服务端' : '',
|
||||
'客户端',
|
||||
'完成'])
|
||||
steps:computed(()=>['选择模式', globalData.value.isPc ? '服务端' : '','客户端','完成'])
|
||||
});
|
||||
|
||||
const currentDom = ref(null);
|
||||
@@ -78,7 +75,7 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
return { state,globalData,currentDom,step,handlePrev,handleNext,handleSave};
|
||||
return { state,currentDom,step,handlePrev,handleNext,handleSave};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,51 +1,55 @@
|
||||
<template>
|
||||
<div class="logger-setting-wrap flex flex-column h-100" ref="wrap">
|
||||
<el-tabs type="border-card" class="w-100">
|
||||
<el-tab-pane :label="$t('logger.list')" v-if="hasLogger">
|
||||
<div class="inner">
|
||||
<div class="head flex">
|
||||
<div>
|
||||
<el-select v-model="state.type" @change="loadData" size="small" class="mgr-1" style="width: 6rem;">
|
||||
<el-option :value="-1" label="all"></el-option>
|
||||
<el-option :value="0" label="debug"></el-option>
|
||||
<el-option :value="1" label="info"></el-option>
|
||||
<el-option :value="2" label="warning"></el-option>
|
||||
<el-option :value="3" label="error"></el-option>
|
||||
<el-option :value="4" label="fatal"></el-option>
|
||||
</el-select>
|
||||
<AccessShow value="LoggerShow">
|
||||
<el-tab-pane :label="$t('logger.list')">
|
||||
<div class="inner">
|
||||
<div class="head flex">
|
||||
<div>
|
||||
<el-select v-model="state.type" @change="loadData" size="small" class="mgr-1" style="width: 6rem;">
|
||||
<el-option :value="-1" label="all"></el-option>
|
||||
<el-option :value="0" label="debug"></el-option>
|
||||
<el-option :value="1" label="info"></el-option>
|
||||
<el-option :value="2" label="warning"></el-option>
|
||||
<el-option :value="3" label="error"></el-option>
|
||||
<el-option :value="4" label="fatal"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<el-button type="warning" size="small" :loading="state.loading" @click="clearData">{{$t('logger.clear')}}</el-button>
|
||||
<el-button size="small" :loading="state.loading" @click="loadData">{{$t('logger.refresh')}}</el-button>
|
||||
<span class="flex-1"></span>
|
||||
</div>
|
||||
<el-button type="warning" size="small" :loading="state.loading" @click="clearData">{{$t('logger.clear')}}</el-button>
|
||||
<el-button size="small" :loading="state.loading" @click="loadData">{{$t('logger.refresh')}}</el-button>
|
||||
<span class="flex-1"></span>
|
||||
</div>
|
||||
<div class="body flex-1 relative">
|
||||
<el-table stripe border :data="state.page.List" size="small" :height="`${state.height}px`" width="100%" @row-click="handleRowClick" :row-class-name="tableRowClassName">
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column prop="Type" :label="$t('logger.level')" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{state.types[scope.row.Type]}} </span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Time" :label="$t('logger.time')" width="160"></el-table-column>
|
||||
<el-table-column prop="content" :label="$t('logger.content')"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pages t-c">
|
||||
<div class="page-wrap">
|
||||
<el-pagination small :total="state.page.Count"
|
||||
v-model:currentPage="state.page.Page" :page-size="state.page.Size"
|
||||
:pager-count="globalData.isPc?7:3"
|
||||
:layout="globalData.isPc?'total,prev, pager, next':'prev, pager, next'"
|
||||
@current-change="handlePageChange" background
|
||||
>
|
||||
</el-pagination>
|
||||
<div class="body flex-1 relative">
|
||||
<el-table stripe border :data="state.page.List" size="small" :height="`${state.height}px`" width="100%" @row-click="handleRowClick" :row-class-name="tableRowClassName">
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column prop="Type" :label="$t('logger.level')" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{state.types[scope.row.Type]}} </span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Time" :label="$t('logger.time')" width="160"></el-table-column>
|
||||
<el-table-column prop="content" :label="$t('logger.content')"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pages t-c">
|
||||
<div class="page-wrap">
|
||||
<el-pagination small :total="state.page.Count"
|
||||
v-model:currentPage="state.page.Page" :page-size="state.page.Size"
|
||||
:pager-count="globalData.isPc?7:3"
|
||||
:layout="globalData.isPc?'total,prev, pager, next':'prev, pager, next'"
|
||||
@current-change="handlePageChange" background
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('common.setting')" v-if="hasLoggerLevel">
|
||||
<Setting></Setting>
|
||||
</el-tab-pane>
|
||||
</el-tab-pane>
|
||||
</AccessShow>
|
||||
<AccessShow value="LoggerLevel">
|
||||
<el-tab-pane :label="$t('common.setting')">
|
||||
<Setting></Setting>
|
||||
</el-tab-pane>
|
||||
</AccessShow>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<el-dialog class="options-center" title="" destroy-on-close v-model="state.show" width="98%" top="2vh">
|
||||
@@ -66,8 +70,6 @@ export default {
|
||||
components: { Setting },
|
||||
setup() {
|
||||
const globalData = injectGlobalData();
|
||||
const hasLogger = computed(()=>globalData.value.hasAccess('LoggerShow'));
|
||||
const hasLoggerLevel = computed(()=>globalData.value.hasAccess('LoggerLevel'));
|
||||
const wrap = ref(null);
|
||||
const state = reactive({
|
||||
loading: true,
|
||||
@@ -125,7 +127,7 @@ export default {
|
||||
});
|
||||
|
||||
return {
|
||||
globalData,hasLogger,hasLoggerLevel,wrap,state, loadData, clearData, tableRowClassName, handleRowClick,handlePageChange
|
||||
globalData,wrap,state, loadData, clearData, tableRowClassName, handleRowClick,handlePageChange
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
v1.9.6
|
||||
2025-11-08 00:05:36
|
||||
2025-11-08 18:05:11
|
||||
1. 一些累计更新,一些BUG修复
|
||||
2. 优化客户端数据同步,减少服务器流量
|
||||
3. 去除cdkey,改为发电解锁中继速度
|
||||
|
||||
Reference in New Issue
Block a user