Преглед изворни кода

通道管理:首页列表页/表格页已完成

vera_min пре 3 година
родитељ
комит
6841c5a9ff

+ 1 - 0
.env.development

@@ -5,5 +5,6 @@ ENV = 'development'
 #VITE_API_URL = 'http://101.200.198.249:8899/api/v1'
 VITE_IMG_URL = 'http://101.200.198.249:8899/'
 VITE_ASSESS_URL = 'http://zhgy.sagoo.cn/base-api/assess/v1'
+VITE_NETWORK_URL = 'http://zhgy.sagoo.cn:8899/api/v1/network'
 VITE_API_URL = 'http://sgadserver.wdeveloperw.xyz/api/v1'
 # VITE_IMG_URL = 'http://sgadserver.wdeveloperw.xyz/'

Разлика између датотеке није приказан због своје велике величине
+ 124 - 124
package-lock.json


+ 5 - 0
src/api/network/index.ts

@@ -0,0 +1,5 @@
+import { get, post, del, put } from '/@/utils/request_network';
+
+export default {
+  getList: (params?: object) => get('/tunnel/list', params)
+}

+ 106 - 0
src/utils/request_network.ts

@@ -0,0 +1,106 @@
+import axios from 'axios';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { Session } from '/@/utils/storage';
+
+// 配置新建一个 axios 实例
+const service = axios.create({
+	baseURL: import.meta.env.VITE_NETWORK_URL,
+	timeout: 50000,
+	headers: { 'Content-Type': 'application/json' },
+});
+
+// 添加请求拦截器
+service.interceptors.request.use(
+	(config) => {
+		// 在发送请求之前做些什么 token
+		if (Session.get('token')) {
+			// (<any>config.headers).common['Authorization'] = `Bearer ${Session.get('token')}`;
+		}
+		return config;
+	},
+	(error) => {
+		// 对请求错误做些什么
+		return Promise.reject(error);
+	}
+);
+
+// 添加响应拦截器
+service.interceptors.response.use(
+	(response) => {
+		// 对响应数据做点什么
+		const res = response.data;
+		const code = response.data.code
+		if (code === 401) {
+			ElMessageBox.alert('登录状态已过期,请重新登录', '提示', { confirmButtonText: '确定' })
+				.then(() => {
+					Session.clear(); // 清除浏览器全部临时缓存
+					window.location.href = '/'; // 去登录页
+				})
+				.catch(() => { });
+		} else if (code !== 0) {
+			ElMessage.error(res.message)
+			return Promise.reject(new Error(res.message))
+		} else {
+			// 分页的数据
+			if (res.data?.Total !== undefined) {
+				return {
+					list: res.data.Data,
+					total: res.data.Total,
+					page: res.data.currentPage,
+					...res.data,
+				}
+			}
+			if (res.data?.Data) {
+				return res.data.Data 
+			}
+			if (res.data?.Data === undefined) {
+				return res.data
+			}
+		}
+	},
+	(error) => {
+		// 对响应错误做点什么
+		if (error.message.indexOf('timeout') != -1) {
+			ElMessage.error('网络超时');
+		} else if (error.message == 'Network Error') {
+			ElMessage.error('网络连接错误');
+		} else {
+			if (error.response.data) ElMessage.error(error.response.statusText);
+			else ElMessage.error('接口路径找不到');
+		}
+		return Promise.reject(error);
+	}
+);
+
+// 导出 axios 实例
+export default service;
+
+export function get(url: string, params?: any): any {
+	return service({
+		url,
+		method: "get",
+		params
+	})
+}
+
+export function post(url: string, data?: any): any {
+	return service({
+		url,
+		method: "post",
+		data
+	})
+}
+export function put(url: string, data?: any): any {
+	return service({
+		url,
+		method: "put",
+		data
+	})
+}
+export function del(url: string, data?: any): any{
+	return service({
+		url,
+		method: "delete",
+		data
+	})
+}

+ 122 - 0
src/views/network/tunnel/component/list.vue

@@ -0,0 +1,122 @@
+<template>
+    <div>
+        <el-table v-loading="loading" border stripe :data="data" style="width: 100%">
+            <el-table-column align="center" prop="id" label="ID"/>
+            <el-table-column align="center" prop="server" label="服务器"/>
+            <el-table-column align="center" prop="name" label="名称"/>
+            <el-table-column align="center" prop="types" label="类型"/>
+            <el-table-column align="center" prop="addr" label="地址"/>
+            <el-table-column show-overflow-tooltip align="center" prop="createdAt" label="创建时间"/>
+            <el-table-column align="center" prop="last" label="最近上线"/>
+            <el-table-column align="center" prop="types" label="状态">
+                <template #default="scope">
+                    <el-tag v-if="!scope.row.status" class="ml-2" type="danger">离线</el-tag>
+                    <el-tag v-else class="ml-2" type="success">在线</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column align="center" label="操作" width="200">
+                <template #default="scope">
+                    <el-button size="small" type="text" @click="onRowDel(scope.row)">详情</el-button>
+
+                    <el-button size="small" type="text" @click="onOpenEditSign(scope.row)">编辑</el-button>
+                    <el-button size="small" type="text" @click="onRowDetail(scope.row)">更多</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <el-pagination
+            @size-change="onHandleSizeChange"
+            @current-change="onHandleCurrentChange"
+            class="mt15"
+            :pager-count="5"
+            :page-sizes="[10, 20, 30]"
+            v-model:current-page="param.page"
+            background
+            v-model:page-size="param.pageSize"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="total"
+        >
+        </el-pagination>
+    </div>
+    
+</template>
+
+<script lang="ts">
+import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue';
+import api from '/@/api/network';
+
+// 定义接口来定义对象的类型
+interface TableDataForm {
+	id: number;
+    server: string;
+	name: string;
+	
+}
+interface TableData {
+	data:  Array<TableDataForm>;
+    total: number;
+    loading: boolean;
+    param: {
+        page: number;
+        pageSize: number;
+    };
+}
+
+export default defineComponent({
+    name: 'tunnel',
+	props: {
+		// 输入框前置内容
+		queryForm: {
+			type: Object,
+			default: () => {},
+		},
+    },
+    setup(props, { emit }) {
+        const state = reactive<TableData>({
+			data: [],
+            total: 0,
+            loading: false,
+            param: {
+                page: 1,
+                pageSize: 10,
+            },
+            
+            
+		});
+        // 分页改变
+		const onHandleSizeChange = (val: number) => {
+			state.param.pageSize = val;
+		};
+		// 分页改变
+		const onHandleCurrentChange = (val: number) => {
+			state.param.page = val;
+		};
+        // 初始化表格数据
+		const initTableData = () => {
+            console.log(props.queryForm.title)
+            let params = {
+                OrderBy: props.queryForm.title,
+                pageNum: state.param.page,
+                PageSize: state.param.pageSize
+            }
+            api.getList(params).then((res: any) => {
+				console.log(res);
+                const { list, total, page } = res
+                state.data = list
+                state.total = total
+                state.param.page = page
+			});
+
+
+		};
+        // 页面加载时
+		onMounted(() => {
+			initTableData();
+		});
+        return {
+            onHandleSizeChange,
+            onHandleCurrentChange,
+            ...toRefs(state),
+        };
+    }
+});
+</script>

+ 185 - 0
src/views/network/tunnel/component/table.vue

@@ -0,0 +1,185 @@
+<template>
+    <div class="container">
+        <!-- <el-table v-loading="loading" border stripe :data="data" style="width: 100%">
+            <el-table-column align="center" prop="id" label="ID"/>
+            <el-table-column align="center" prop="server" label="服务器"/>
+            <el-table-column align="center" prop="name" label="名称"/>
+            <el-table-column align="center" prop="types" label="类型"/>
+            <el-table-column align="center" prop="addr" label="地址"/>
+            <el-table-column show-overflow-tooltip align="center" prop="createdAt" label="创建时间"/>
+            <el-table-column align="center" prop="last" label="最近上线"/>
+            <el-table-column align="center" prop="types" label="状态">
+                <template #default="scope">
+                    <el-tag v-if="!scope.row.status" class="ml-2" type="danger">离线</el-tag>
+                    <el-tag v-else class="ml-2" type="success">在线</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column align="center" label="操作" width="200">
+                <template #default="scope">
+                    <el-button size="small" type="text" @click="onRowDel(scope.row)">详情</el-button>
+
+                    <el-button size="small" type="text" @click="onOpenEditSign(scope.row)">编辑</el-button>
+                    <el-button size="small" type="text" @click="onRowDetail(scope.row)">更多</el-button>
+                </template>
+            </el-table-column>
+        </el-table> -->
+        <div class="content">
+            <!-- <section v-for="(item, index) in data" :key="index"> -->
+            <el-card class="item" shadow="hover" v-for="(item, index) in data" :key="index">
+                <div class="top-inner-wrap">
+                    <span>通道:{{item.id}}</span>
+                    <span class="more">更多
+                        <i class="fa fa-angle-down"></i>
+                        <!-- <ele-ArrowDown /> -->
+                    </span>
+                </div>
+                <div class="content-wrap">
+                    <div class="name-and-status">
+                        <span>{{item.name}}</span>
+                        [
+                        <span>{{item.status?'在线':'离线'}}</span>
+                        ]
+                    </div>
+                    <div class="">
+                        <span>{{item.types}}</span>
+                        <span style="margin-left: 6px;">{{item.name}}</span>
+                    </div>
+                    
+                </div>
+            </el-card>
+        </div>
+        <el-pagination
+            @size-change="onHandleSizeChange"
+            @current-change="onHandleCurrentChange"
+            class="mt15"
+            :pager-count="5"
+            :page-sizes="[10, 20, 30]"
+            v-model:current-page="param.page"
+            background
+            v-model:page-size="param.pageSize"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="total"
+        >
+        </el-pagination>
+    </div>
+    
+</template>
+
+<script lang="ts">
+import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue';
+import api from '/@/api/network';
+
+// 定义接口来定义对象的类型
+interface TableDataForm {
+	id: number;
+    server: string;
+	name: string;
+	
+}
+interface TableData {
+	data:  Array<TableDataForm>;
+    total: number;
+    loading: boolean;
+    param: {
+        page: number;
+        pageSize: number;
+    };
+}
+
+export default defineComponent({
+    name: 'tunnelTable',
+	props: {
+		// 输入框前置内容
+		queryForm: {
+			type: Object,
+			default: () => {},
+		},
+    },
+    setup(props, { emit }) {
+        const state = reactive<TableData>({
+			data: [],
+            total: 0,
+            loading: false,
+            param: {
+                page: 1,
+                pageSize: 10,
+            },
+            
+            
+		});
+        // 分页改变
+		const onHandleSizeChange = (val: number) => {
+			state.param.pageSize = val;
+		};
+		// 分页改变
+		const onHandleCurrentChange = (val: number) => {
+			state.param.page = val;
+		};
+        // 初始化表格数据
+		const initTableData = () => {
+            console.log(props.queryForm.title)
+            let params = {
+                OrderBy: props.queryForm.title,
+                pageNum: state.param.page,
+                PageSize: state.param.pageSize
+            }
+            api.getList(params).then((res: any) => {
+				console.log(res);
+                const { list, total, page } = res
+                state.data = list
+                state.total = total
+                state.param.page = page
+			});
+
+
+		};
+        // 页面加载时
+		onMounted(() => {
+			initTableData();
+		});
+        return {
+            onHandleSizeChange,
+            onHandleCurrentChange,
+            ...toRefs(state),
+        };
+    }
+});
+</script>
+
+<style lang="scss" scoped>
+.container {
+    width: 100%;
+    .content {
+        display: flex;
+        flex-flow: row wrap;
+        width: 100%;
+        .item {
+            width: calc((100% - 40px)/3);
+            cursor: pointer;
+            border-radius: 6px;
+            .top-inner-wrap {
+                font-size: 15px;
+                display: flex;
+                justify-content: space-between;
+                background: transparent;
+                border-bottom: 1px solid var(--el-card-border-color);
+                    // border: 1px solid var(--el-card-border-color);
+                .more {
+                    color: var(--el-color-primary);
+                }
+            }
+            .content-wrap {
+                .name-and-status {
+                    margin: 12px 0 8px 0;
+                }
+            }
+        }
+        .item:not(:nth-child(3n+1)) {
+            margin-left: 20px;
+        }
+        .item:nth-of-type(n+4) {
+            margin-top: 20px;
+        }
+    }
+}
+</style>

+ 105 - 5
src/views/network/tunnel/index.vue

@@ -1,8 +1,108 @@
 <template>
-    <div>
-        <h1>
-            通道管理页面
-        </h1>
+    <div class="container">
+        <el-card shadow="hover">
+            <div class="top-operate-wrap">
+                <div class="left">
+                    <el-button size="default" type="success" class="ml10">
+                        <el-icon>
+                            <ele-FolderAdd />
+                        </el-icon>
+                        新建
+                    </el-button>
+                    <el-input size="default" style="width: 200px;margin-left: 20px;" class="search-input" v-model="queryParams.title" placeholder="请输入搜索关键字" clearable>
+                    </el-input>
+                    <el-button type="primary" plain size="default">搜索</el-button>
+                </div>
+                <div class="right">  
+                    <el-button @click="index=1" :class="index==1?'active':''" size="default" class="fa fa-th"></el-button>
+                    <el-button @click="index=2" :class="index==2?'active':''" size="default" class="fa fa-list"></el-button>
+                </div>        
+            </div>
+            <!-- 页面主要内容 -->
+            <tempalte v-if="index==1">
+                <!-- table -->
+                <tableTunnel :queryForm="queryParams" />
+
+            </tempalte>
+
+            <tempalte v-if="index==2">
+                <!-- list -->
+                <listTunnel :queryForm="queryParams" />
+
+            </tempalte>
+
+        </el-card>
         
     </div>
-</template>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, onMounted, defineComponent, ref } from 'vue';
+import type { FormInstance, FormRules } from 'element-plus';
+import { ElMessage } from 'element-plus';
+
+import listTunnel from './component/list.vue';
+import tableTunnel from './component/table.vue';
+
+// import api from '/@/api/assess';
+
+
+// 定义接口来定义对象的类型
+interface RuleFormRow {
+    title: string;
+	
+}
+
+interface ItemState {
+	queryParams: RuleFormRow;
+    index: number;
+}
+
+export default defineComponent({
+    name: 'tunnalManage',
+    components: { listTunnel, tableTunnel },
+	setup() {
+		const state = reactive<ItemState>({
+            index: 1,
+			queryParams: {
+                title: ''
+			},
+		});
+        return {
+			...toRefs(state),
+		};
+    },
+    
+});
+</script>
+
+<style lang="scss" scoped>
+.container {
+    .top-operate-wrap {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 20px;
+        .left,
+        .right {
+            display: flex;
+            .el-button:nth-child(2) {
+                margin-left: 0;
+                border-top-left-radius: 0;
+                border-bottom-left-radius: 0;
+            }
+            .el-button:nth-child(1) {
+               border-top-right-radius: 0;
+                border-bottom-right-radius: 0;
+                border-right: none;
+            }
+            .active {
+                color: var(--el-button-hover-text-color);
+                border-color: var(--el-button-hover-border-color);
+                background-color: var(--el-button-hover-bg-color);
+                outline: 0;
+            }
+        }
+    }
+}
+</style>

Неке датотеке нису приказане због велике количине промена