ks
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
<meta name="author" content="314298729@qq.com">
|
||||
<meta name="keywords" content="测试,管理,平台,测评,用例,FPGA,CPU,嵌入式,报告">
|
||||
<meta name="description" content="测试管理平台,服务内部,部分内容不对外开放">
|
||||
<title>成都测试管理平台</title>
|
||||
<title>测试管理平台</title>
|
||||
<style>
|
||||
html,
|
||||
body,
|
||||
|
||||
@@ -20,5 +20,14 @@ export default {
|
||||
url: "system/dataDict/list?code=" + code,
|
||||
method: "get"
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取项目一年内每月统计数据
|
||||
*/
|
||||
getChartData() {
|
||||
return request({
|
||||
url: "system/statistics/chart",
|
||||
method: "get"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
26
cdTMP/src/api/system/log.js
Normal file
26
cdTMP/src/api/system/log.js
Normal 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
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<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>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
:style="{ margin: 0, fontSize: '18px' }"
|
||||
:heading="5"
|
||||
>
|
||||
成都测试管理平台
|
||||
测试管理平台
|
||||
</a-typography-title>
|
||||
<icon-menu-fold
|
||||
v-if="!topMenu && appStore.device === 'mobile'"
|
||||
|
||||
@@ -6,6 +6,7 @@ import useTabBarStore from "./modules/tab-bar"
|
||||
import useFormStore from "./modules/form"
|
||||
import useKeepAliveStore from "./modules/keepAlive"
|
||||
import useTagStore from "./modules/tag"
|
||||
// 自己的仓库
|
||||
import useTreeDataStore from "./project/treeData"
|
||||
|
||||
const pinia = createPinia()
|
||||
|
||||
@@ -4,7 +4,7 @@ export function addEventListen(
|
||||
handler: EventListenerOrEventListenerObject,
|
||||
capture = false
|
||||
) {
|
||||
if (target.addEventListener && typeof target.addEventListener === 'function') {
|
||||
if (target.addEventListener && typeof target.addEventListener === "function") {
|
||||
target.addEventListener(event, handler, capture)
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ export function removeEventListen(
|
||||
handler: EventListenerOrEventListenerObject,
|
||||
capture = false
|
||||
) {
|
||||
if (target.removeEventListener && typeof target.removeEventListener === 'function') {
|
||||
if (target.removeEventListener && typeof target.removeEventListener === "function") {
|
||||
target.removeEventListener(event, handler, capture)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ const modifyPassword = async (data) => {
|
||||
Message.error("确认密码与新密码不一致")
|
||||
return
|
||||
}
|
||||
Message.success("修改密码成功!")
|
||||
Message.error("由于采用LDAP认证,请联系内网管理员修改!")
|
||||
// const response = await user.modifyPassword(data.values)
|
||||
// if (response.success) {
|
||||
// tool.local.clear()
|
||||
|
||||
@@ -34,7 +34,7 @@ const userInfo = reactive({
|
||||
|
||||
const modifyInfo = async (data) => {
|
||||
// 注意要用values
|
||||
console.log(data.values);
|
||||
Message.success("模拟请求成功,后续写接口")
|
||||
console.log(data.values)
|
||||
Message.error("由于采用LDAP登录无法修改!")
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -23,25 +23,27 @@
|
||||
</div>
|
||||
<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-tab-pane key="login-log" title="登录日志">
|
||||
<a-timeline class="pl-5 mt-3">
|
||||
<a-tab-pane key="login-log" title="登录日志" v-loading="isDataLoading">
|
||||
<a-timeline class="pl-5 mt-3" v-if="loginLogList.length">
|
||||
<a-timeline-item
|
||||
:label="`地理位置;${item.ip_location},操作系统:${item.os}`"
|
||||
:label="`IP地址:${item.ip},操作系统:${item.os}`"
|
||||
v-for="(item, idx) in loginLogList"
|
||||
:key="idx"
|
||||
>
|
||||
您于 {{ item.login_time }} 登录系统,{{ item.message }}
|
||||
您于 {{ item.create_datetime }} 登录系统,浏览器:{{ item.browser }}
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
</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-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"
|
||||
:key="idx"
|
||||
>
|
||||
您于 {{ item.created_at }} 执行了 {{ item.service_name }}
|
||||
您于 {{ item.create_datetime }} 请求了 {{ item.request_path }},状态码:{{
|
||||
item.response_code
|
||||
}}
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
</a-tab-pane>
|
||||
@@ -52,21 +54,35 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue"
|
||||
import { computed, ref } from "vue"
|
||||
import MaUpload from "@cps/ma-upload/index.vue"
|
||||
import userInfomation from "./components/userInfo.vue"
|
||||
import editpassword from "./components/editpassword.vue"
|
||||
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 loginLogList = ref([
|
||||
{ ip_location: "成都", os: "window10", login_time: "2023-6-6", message: "更新了xxx项目" },
|
||||
{ ip_location: "成都", os: "window10", login_time: "2023-6-5", message: "更新了xxx项目" }
|
||||
])
|
||||
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:"问答历史" },
|
||||
{ ip_location: "四川省-成都市", method: "POST", router: "/demo/update", created_at: "2023-06-06 17:05:08",service_name:"问答历史" },
|
||||
])
|
||||
const loginLogList = computed(() => {
|
||||
return loadingData.value.map((item) => {
|
||||
item.create_datetime = item.create_datetime.split(".")[0].replace("T", " ")
|
||||
return item
|
||||
})
|
||||
})
|
||||
// 操作日志不用hook
|
||||
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>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
<a-link @click="viewDetail(record)">{{ record.title }}</a-link>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<a-modal v-model:visible="detailVisible" fullscreen :footer="false">
|
||||
<template #title>公告详情</template>
|
||||
<a-typography :style="{ marginTop: '-30px' }">
|
||||
|
||||
@@ -1,25 +1,29 @@
|
||||
<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="flex">成都测试管理平台相关</div>
|
||||
<div class="block lg:grid lg:grid-cols-2 lg:gap-1 mt-3">
|
||||
<div class="flex">测试管理平台相关</div>
|
||||
<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-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 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 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 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 type="rounded-sm text-center" class="w-full" :body-style="{ padding: 0 }" :bordered="false">
|
||||
<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 href="https://doc.mineadmin.com/guide/" target="_blank">
|
||||
<a-button type="outline" class="w-full">感谢:MineAdmin</a-button>
|
||||
</a>
|
||||
</a-card>
|
||||
<div class="mt-2">管理平台版本</div>
|
||||
<a-tag class="mt-2" color="#0fc6c2">cdTestPlant V0.0.1</a-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,12 +1,38 @@
|
||||
<template>
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { nextTick, onMounted, ref } from "vue"
|
||||
import { computed, ref } from "vue"
|
||||
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) {
|
||||
return {
|
||||
@@ -22,38 +48,26 @@ function graphicFactory(side) {
|
||||
}
|
||||
}
|
||||
|
||||
const xAxis = ref([
|
||||
"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 graphicElements = ref([graphicFactory({ left: "3%" }), graphicFactory({ right: 0 })])
|
||||
|
||||
const loginChartOptions = ref({
|
||||
const loginChartOptions = computed(() => ({
|
||||
title: {
|
||||
text: `项目每月统计-${new Date().getFullYear()}年份`
|
||||
},
|
||||
grid: {
|
||||
left: "2.6%",
|
||||
right: "0",
|
||||
top: "10",
|
||||
left: "3%",
|
||||
right: "3%",
|
||||
top: "50",
|
||||
bottom: "30"
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
offset: 2,
|
||||
data: xAxis.value,
|
||||
boundaryGap: false,
|
||||
data: xAxisData.value,
|
||||
boundaryGap: true,
|
||||
axisLabel: {
|
||||
color: "#4E5969",
|
||||
formatter(value, idx) {
|
||||
if (idx === 0) return ""
|
||||
if (idx === xAxis.value.length - 1) return ""
|
||||
return `${value}`
|
||||
}
|
||||
},
|
||||
@@ -66,8 +80,7 @@ const loginChartOptions = ref({
|
||||
splitLine: {
|
||||
show: true,
|
||||
interval: (idx) => {
|
||||
if (idx === 0) return false
|
||||
if (idx === xAxis.value.length - 1) return false
|
||||
if (idx === xAxisData.value.length - 1) return false
|
||||
return true
|
||||
},
|
||||
lineStyle: {
|
||||
@@ -117,10 +130,10 @@ const loginChartOptions = ref({
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: chartsData.value,
|
||||
data: yAxisData.value,
|
||||
type: "line",
|
||||
smooth: true,
|
||||
symbolSize: 12,
|
||||
symbolSize: 14,
|
||||
emphasis: {
|
||||
focus: "series",
|
||||
itemStyle: {
|
||||
@@ -160,5 +173,12 @@ const loginChartOptions = ref({
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}))
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.chartContainer {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user