This commit is contained in:
2024-06-17 18:44:39 +08:00
parent b6f56fe5d8
commit 12f0406a48
14 changed files with 143 additions and 121 deletions

View File

@@ -1,53 +0,0 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 4,
"id": "db3fdebd-b7cd-4a83-9f52-2b01691dfcbd",
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "ord() expected a character, but string of length 2 found",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0mTraceback (most recent call last)",
"Cell \u001b[1;32mIn[4], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;28;43mord\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m12\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m)\n",
"\u001b[1;31mTypeError\u001b[0m: ord() expected a character, but string of length 2 found"
]
}
],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "7a1670a0-01da-495a-a2b7-9dd635238477",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -8,7 +8,7 @@
<meta name="author" content="314298729@qq.com"> <meta name="author" content="314298729@qq.com">
<meta name="keywords" content="测试,管理,平台,测评,用例,FPGA,CPU,嵌入式,报告"> <meta name="keywords" content="测试,管理,平台,测评,用例,FPGA,CPU,嵌入式,报告">
<meta name="description" content="测试管理平台,服务内部,部分内容不对外开放"> <meta name="description" content="测试管理平台,服务内部,部分内容不对外开放">
<title>成都测试管理平台</title> <title>测试管理平台</title>
<style> <style>
html, html,
body, body,

View File

@@ -20,5 +20,14 @@ export default {
url: "system/dataDict/list?code=" + code, url: "system/dataDict/list?code=" + code,
method: "get" method: "get"
}) })
},
/**
* 获取项目一年内每月统计数据
*/
getChartData() {
return request({
url: "system/statistics/chart",
method: "get"
})
} }
} }

View File

@@ -0,0 +1,26 @@
import { request } from "@/api/request"
export default {
/**
* 获取当前用户的登录日志
* @returns 日志列表
*/
getLoginLog(params = {}) {
return request({
url: "/system/log/list",
method: "get",
params
})
},
/**
* 获取当前用户的登录日志
* @returns 日志列表
*/
getOperationLog(params = {}) {
return request({
url: "/system/log/operations",
method: "get",
params
})
}
}

View File

@@ -1,6 +1,6 @@
<template> <template>
<a-layout-footer class="flex items-center justify-center h-10 footer text-center"> <a-layout-footer class="flex items-center justify-center h-10 footer text-center">
<a-typography-title :heading="8"> 成都测试管理平台 </a-typography-title> <a-typography-title :heading="8"> 测试管理平台 </a-typography-title>
</a-layout-footer> </a-layout-footer>
</template> </template>

View File

@@ -9,7 +9,7 @@
:style="{ margin: 0, fontSize: '18px' }" :style="{ margin: 0, fontSize: '18px' }"
:heading="5" :heading="5"
> >
成都测试管理平台 测试管理平台
</a-typography-title> </a-typography-title>
<icon-menu-fold <icon-menu-fold
v-if="!topMenu && appStore.device === 'mobile'" v-if="!topMenu && appStore.device === 'mobile'"

View File

@@ -6,6 +6,7 @@ import useTabBarStore from "./modules/tab-bar"
import useFormStore from "./modules/form" import useFormStore from "./modules/form"
import useKeepAliveStore from "./modules/keepAlive" import useKeepAliveStore from "./modules/keepAlive"
import useTagStore from "./modules/tag" import useTagStore from "./modules/tag"
// 自己的仓库
import useTreeDataStore from "./project/treeData" import useTreeDataStore from "./project/treeData"
const pinia = createPinia() const pinia = createPinia()

View File

@@ -4,7 +4,7 @@ export function addEventListen(
handler: EventListenerOrEventListenerObject, handler: EventListenerOrEventListenerObject,
capture = false capture = false
) { ) {
if (target.addEventListener && typeof target.addEventListener === 'function') { if (target.addEventListener && typeof target.addEventListener === "function") {
target.addEventListener(event, handler, capture) target.addEventListener(event, handler, capture)
} }
} }
@@ -15,7 +15,7 @@ export function removeEventListen(
handler: EventListenerOrEventListenerObject, handler: EventListenerOrEventListenerObject,
capture = false capture = false
) { ) {
if (target.removeEventListener && typeof target.removeEventListener === 'function') { if (target.removeEventListener && typeof target.removeEventListener === "function") {
target.removeEventListener(event, handler, capture) target.removeEventListener(event, handler, capture)
} }
} }

View File

@@ -69,7 +69,7 @@ const modifyPassword = async (data) => {
Message.error("确认密码与新密码不一致") Message.error("确认密码与新密码不一致")
return return
} }
Message.success("修改密码成功!") Message.error("由于采用LDAP认证请联系内网管理员修改!")
// const response = await user.modifyPassword(data.values) // const response = await user.modifyPassword(data.values)
// if (response.success) { // if (response.success) {
// tool.local.clear() // tool.local.clear()

View File

@@ -34,7 +34,7 @@ const userInfo = reactive({
const modifyInfo = async (data) => { const modifyInfo = async (data) => {
// 注意要用values // 注意要用values
console.log(data.values); console.log(data.values)
Message.success("模拟请求成功,后续写接口") Message.error("由于采用LDAP登录无法修改!")
} }
</script> </script>

View File

@@ -23,25 +23,27 @@
</div> </div>
<div class="ma-content-block w-full lg:w-6/12 mt-3 p-4 ml-0 lg:ml-3"> <div class="ma-content-block w-full lg:w-6/12 mt-3 p-4 ml-0 lg:ml-3">
<a-tabs type="rounded"> <a-tabs type="rounded">
<a-tab-pane key="login-log" title="登录日志"> <a-tab-pane key="login-log" title="登录日志" v-loading="isDataLoading">
<a-timeline class="pl-5 mt-3"> <a-timeline class="pl-5 mt-3" v-if="loginLogList.length">
<a-timeline-item <a-timeline-item
:label="`地理位置;${item.ip_location},操作系统:${item.os}`" :label="`IP地址${item.ip},操作系统:${item.os}`"
v-for="(item, idx) in loginLogList" v-for="(item, idx) in loginLogList"
:key="idx" :key="idx"
> >
您于 {{ item.login_time }} 登录系统{{ item.message }} 您于 {{ item.create_datetime }} 登录系统浏览器{{ item.browser }}
</a-timeline-item> </a-timeline-item>
</a-timeline> </a-timeline>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="operation-log" title="操作日志"> <a-tab-pane key="operation-log" title="操作日志" v-loading="isLoading">
<a-timeline class="pl-5 mt-3"> <a-timeline class="pl-5 mt-3">
<a-timeline-item <a-timeline-item
:label="`地理位置;${item.ip_location},方式:${item.method}路由${item.router}`" :label="`IP地址${item.request_ip},方式:${item.request_method}系统${item.request_os},浏览器:${item.request_browser}`"
v-for="(item, idx) in operationLogList" v-for="(item, idx) in operationLogList"
:key="idx" :key="idx"
> >
您于 {{ item.created_at }} 执行 {{ item.service_name }} 您于 {{ item.create_datetime }} 请求 {{ item.request_path }}状态码{{
item.response_code
}}
</a-timeline-item> </a-timeline-item>
</a-timeline> </a-timeline>
</a-tab-pane> </a-tab-pane>
@@ -52,21 +54,35 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue" import { computed, ref } from "vue"
import MaUpload from "@cps/ma-upload/index.vue" import MaUpload from "@cps/ma-upload/index.vue"
import userInfomation from "./components/userInfo.vue" import userInfomation from "./components/userInfo.vue"
import editpassword from "./components/editpassword.vue" import editpassword from "./components/editpassword.vue"
import { useUserStore } from "@/store" import { useUserStore } from "@/store"
import logApi from "@/api/system/log"
import useFetchData from "@/hooks/fetchData"
const { loadingData, isDataLoading } = useFetchData([], logApi.getLoginLog)
const userStore = useUserStore() const userStore = useUserStore()
const loginLogList = ref([ const loginLogList = computed(() => {
{ ip_location: "成都", os: "window10", login_time: "2023-6-6", message: "更新了xxx项目" }, return loadingData.value.map((item) => {
{ ip_location: "成都", os: "window10", login_time: "2023-6-5", message: "更新了xxx项目" } item.create_datetime = item.create_datetime.split(".")[0].replace("T", " ")
]) return item
const operationLogList = ref([ })
{ ip_location: "四川省-成都市", method: "POST", router: "/demo/update", created_at: "2023-06-06 17:05:08",service_name:"问答历史" }, })
{ ip_location: "四川省-成都市", method: "POST", router: "/demo/update", created_at: "2023-06-06 17:05:08",service_name:"问答历史" }, // 操作日志不用hook
{ ip_location: "四川省-成都市", method: "POST", router: "/demo/update", created_at: "2023-06-06 17:05:08",service_name:"问答历史" }, const isLoading = ref(true)
]) const data = ref([])
logApi.getOperationLog().then((res) => {
data.value = res.data
isLoading.value = false
})
const operationLogList = computed(() => {
return data.value.map((item) => {
item.create_datetime = item.create_datetime.split(".")[0].replace("T", " ")
return item
})
})
</script> </script>
<style scoped> <style scoped>

View File

@@ -9,7 +9,6 @@
<a-link @click="viewDetail(record)">{{ record.title }}</a-link> <a-link @click="viewDetail(record)">{{ record.title }}</a-link>
</template> </template>
</a-table> </a-table>
<a-modal v-model:visible="detailVisible" fullscreen :footer="false"> <a-modal v-model:visible="detailVisible" fullscreen :footer="false">
<template #title>公告详情</template> <template #title>公告详情</template>
<a-typography :style="{ marginTop: '-30px' }"> <a-typography :style="{ marginTop: '-30px' }">

View File

@@ -1,25 +1,29 @@
<template> <template>
<div class="w-full lg:w-3/12 ma-content-block rounded-sm ml-0 lg:ml-3 p-3 mt-3"> <div class="w-full lg:w-3/12 ma-content-block rounded-sm ml-0 lg:ml-3 p-3 mt-3">
<div class="flex">成都测试管理平台相关</div> <div class="flex">测试管理平台相关</div>
<div class="block lg:grid lg:grid-cols-2 lg:gap-1 mt-3"> <div class="block lg:grid lg:grid-cols-2 lg:gap-2 mt-3">
<a-card type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false"> <a-card type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false">
<a-button type="outline" class="w-full">仓库地址</a-button> <a target="_blank" href="https://github.com/ks3356143/cdTestPlant3">
<a-button type="outline" class="w-full">前端仓库</a-button>
</a>
</a-card> </a-card>
<a-card type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false"> <a-card type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false">
<a-button type="outline" class="w-full">Gitee地址</a-button> <a href="https://github.com/ks3356143/cdtestplant_v1" target="_blank">
<a-button type="outline" class="w-full">后端仓库</a-button>
</a>
</a-card> </a-card>
<a-card type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false"> <a-card type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false">
<a-button type="outline" class="w-full">仓库地址</a-button> <a href="https://arco.design/vue/docs/pro/start" target="_blank">
<a-button type="outline" class="w-full">感谢ArcoDesign</a-button>
</a>
</a-card> </a-card>
<a-card type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false"> <a-card type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false">
<a-button type="outline" class="w-full">Gitee地址</a-button> <a href="https://doc.mineadmin.com/guide/" target="_blank">
</a-card> <a-button type="outline" class="w-full">感谢:MineAdmin</a-button>
<a-card type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false"> </a>
<a-button type="outline" class="w-full">仓库地址</a-button>
</a-card>
<a-card type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false">
<a-button type="outline" class="w-full">Gitee地址</a-button>
</a-card> </a-card>
<div class="mt-2">管理平台版本</div>
<a-tag class="mt-2" color="#0fc6c2">cdTestPlant V0.0.1</a-tag>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -1,12 +1,38 @@
<template> <template>
<div class="ma-content-block p-3 mt-3 bg-white"> <div class="ma-content-block p-3 mt-3 bg-white">
<ma-chart height="300px" :option="loginChartOptions" /> <a-spin class="chartContainer" :loading="isDataLoading" tip="图标数据加载中...">
<ma-chart height="300px" :option="loginChartOptions" v-if="!isDataLoading" />
</a-spin>
</div> </div>
</template> </template>
<script setup> <script setup>
import { nextTick, onMounted, ref } from "vue" import { computed, ref } from "vue"
import { graphic } from "echarts" import { graphic } from "echarts"
import fetchData from "@/hooks/fetchData"
import commonApi from "@/api/common"
// 传给hook的远程请求数据函数
async function fetchDataFunc() {
return await commonApi.getChartData()
}
const { loadingData, isDataLoading } = fetchData(
[
{ month: "1", count: 2 },
{ month: "2", count: 10 }
],
fetchDataFunc
)
// 计算属性将loadingData转为xAxis
const xAxisData = computed(() => {
return loadingData.value.map((item) => {
return item.month + "月"
})
})
const yAxisData = computed(() => {
return loadingData.value.map((item) => {
return item.count
})
})
function graphicFactory(side) { function graphicFactory(side) {
return { return {
@@ -22,38 +48,26 @@ function graphicFactory(side) {
} }
} }
const xAxis = ref([ const graphicElements = ref([graphicFactory({ left: "3%" }), graphicFactory({ right: 0 })])
"2022-07-06",
"2022-07-07",
"2022-07-08",
"2022-07-09",
"2022-07-10",
"2022-07-11",
"2022-07-12",
"2022-07-13",
"2022-07-14",
"2022-07-15"
])
const chartsData = ref([32, 56, 61, 89, 12, 33, 56, 92, 180, 25])
const graphicElements = ref([graphicFactory({ left: "2.6%" }), graphicFactory({ right: 0 })])
const loginChartOptions = ref({ const loginChartOptions = computed(() => ({
title: {
text: `项目每月统计-${new Date().getFullYear()}年份`
},
grid: { grid: {
left: "2.6%", left: "3%",
right: "0", right: "3%",
top: "10", top: "50",
bottom: "30" bottom: "30"
}, },
xAxis: { xAxis: {
type: "category", type: "category",
offset: 2, offset: 2,
data: xAxis.value, data: xAxisData.value,
boundaryGap: false, boundaryGap: true,
axisLabel: { axisLabel: {
color: "#4E5969", color: "#4E5969",
formatter(value, idx) { formatter(value, idx) {
if (idx === 0) return ""
if (idx === xAxis.value.length - 1) return ""
return `${value}` return `${value}`
} }
}, },
@@ -66,8 +80,7 @@ const loginChartOptions = ref({
splitLine: { splitLine: {
show: true, show: true,
interval: (idx) => { interval: (idx) => {
if (idx === 0) return false if (idx === xAxisData.value.length - 1) return false
if (idx === xAxis.value.length - 1) return false
return true return true
}, },
lineStyle: { lineStyle: {
@@ -117,10 +130,10 @@ const loginChartOptions = ref({
}, },
series: [ series: [
{ {
data: chartsData.value, data: yAxisData.value,
type: "line", type: "line",
smooth: true, smooth: true,
symbolSize: 12, symbolSize: 14,
emphasis: { emphasis: {
focus: "series", focus: "series",
itemStyle: { itemStyle: {
@@ -160,5 +173,12 @@ const loginChartOptions = ref({
} }
} }
] ]
}) }))
</script> </script>
<style lang="less" scoped>
.chartContainer {
width: 100%;
height: 300px;
}
</style>