设计需求、测试项、用例的上级hover显示

This commit is contained in:
2025-05-14 19:57:11 +08:00
parent 25b5576274
commit 70e719abbe
15 changed files with 260 additions and 32 deletions

View File

@@ -17,7 +17,14 @@
>
<template #title>{{ actionTitle }}</template>
<a-spin :loading="dataLoading" tip="加载中..." class="w-full">
<ma-form v-model="form" :columns="formColumns" :options="formOptions" ref="maFormRef">
<!-- 修改源码parentKey -->
<ma-form
v-model="form"
:columns="formColumns"
:parent-key="props.parentKey"
:options="formOptions"
ref="maFormRef"
>
<template v-for="slot in Object.keys($slots)" #[slot]="component">
<slot :name="slot" v-bind="component" />
</template>
@@ -35,6 +42,11 @@ import { useRouter } from "vue-router"
import tool from "@/utils/tool"
import { useFormStore } from "@/store/index"
// 2025年5月14日新增
const props = defineProps({
parentKey: { type: String, default: "" }
})
const formStore = useFormStore()
const router = useRouter()
const formOptions = ref({ showButtons: false })

View File

@@ -257,7 +257,8 @@
<ma-setting ref="crudSettingRef" @onChangeSearchHide="initSearchColumns()" @onChangeColumnHide="changeColumn" />
<!-- 修改源码透传ma-crud属性给ma-form -->
<ma-form ref="crudFormRef" @success="requestSuccess" v-bind="$attrs">
<!-- 修改源码传递parentKey值 -->
<ma-form ref="crudFormRef" @success="requestSuccess" v-bind="$attrs" :parent-key="props.parentKey">
<template v-for="(slot, index) in Object.keys($slots)" #[slot]="component" :key="index">
<slot :name="slot" v-bind="component" />
</template>
@@ -308,7 +309,9 @@ const props = defineProps({
options: { type: Object, default: {} },
crud: { type: Object, default: {} },
// 字段列设置
columns: { type: Array, default: [] }
columns: { type: Array, default: [] },
// ~~~2025年5月14日新增透传给ma-form字段
parentKey: { type: String, default: "" }
})
const loading = ref(true)

View File

@@ -61,7 +61,7 @@
</a-button>
</a-tooltip>
<a-button-group shape="round" size="mini">
<a-button type="primary" @click="moveUp(index)">
<a-button type="primary" @click="moveUp(index)">
<icon-arrow-rise />
</a-button>
<a-button type="primary" @click="moveDown(index)">

View File

@@ -63,12 +63,16 @@
</div>
</slot>
</a-form>
<!-- 修改源码判断是否传入parentKey -->
<template v-if="parentKey">
<ParentPreview :parent-key="parentKey"></ParentPreview>
</template>
</a-spin>
</div>
</template>
<script setup>
import { ref, watch, provide, onMounted, nextTick, getCurrentInstance } from "vue"
import { ref, watch, provide, onMounted, nextTick, getCurrentInstance, inject, computed } from "vue"
import { isNil, set, get, cloneDeep } from "lodash-es"
import defaultOptions from "./js/defaultOptions.js"
import {
@@ -94,11 +98,32 @@ const dictList = ref({})
const cascaderList = ref([])
const form = ref({})
// custom start
// 2025年5月14日新增功能hover查看上级节点
import ParentPreview from "@/views/project/ParentPreview/index.vue"
// 判断是否有
const formKey = computed(() => {
// 去掉双击被测件即key.split("").length > 1
if (form.value.key && form.value.key.split("-").length > 2) {
// 如果存在则取前面的
return form.value.key.slice(0, -2)
}
return ""
})
const parentKey = computed(() => {
return props.parentKey || formKey.value || ""
})
// custom end
const props = defineProps({
modelValue: { type: Object, default: {} },
columns: { type: Array },
options: { type: Object, default: {} }
options: { type: Object, default: {} },
// 2025年5月14日新增属性-非必须,后面根据非必须判断
parentKey: { type: String, default: "" }
})
const emit = defineEmits(["submit", "update:modelValue"])
watch(

View File

@@ -6,7 +6,7 @@
:title="props.title"
:layout="props.layout"
:bordered="props.bordered"
table-layout="fixed"
:table-layout="props.tableLayout"
:size="props.size"
:label-style="props.labelStyle"
:value-style="props.valueStyle"
@@ -105,7 +105,9 @@ const props = defineProps({
},
size: {
default: "large"
}
},
// 新增
tableLayout: { type: String, default: "fixed" }
})
watch(

View File

@@ -3,7 +3,7 @@ import { useDebounceFn } from '@vueuse/core'
import { useAppStore } from '@/store'
import { addEventListen, removeEventListen } from '@/utils/event'
const WIDTH = 992 // https://arco.design/vue/component/grid#responsivevalue
const WIDTH = 992
function queryDevice() {
const rect = document.body.getBoundingClientRect()

View File

@@ -0,0 +1,166 @@
<script lang="tsx">
import { computed, defineComponent, ref, Teleport } from "vue"
import { useRoute } from "vue-router"
import { Popover } from "@arco-design/web-vue"
import MaInfo from "@/components/ma-info/index.vue"
// 请求的API
import dutApi from "@/api/project/dut"
import designApi from "@/api/project/designDemand"
import demandApi from "@/api/project/testDemand"
// columns导入
import useDutColumn from "@/views/project/round/hooks/useColumn"
import useDesignColumn from "@/views/project/dut/hooks/useColumns"
import useDemandColumn from "@/views/project/design-demand/hooks/useColumns"
import Empty from "@/components/Empty/index.vue"
export default defineComponent({
name: "ParentPreview",
props: {
parentKey: { type: String, default: "" } // 在ma-form已经判断所以必然有值索引上级key
},
setup(props) {
const route = useRoute()
const project_id = route.query.id // 项目id
const hoverText = ref("")
const buttonLikeRef = ref<HTMLDivElement | null>(null)
const onMouseenter = () => {
// 进入时候注册事件
hoverText.value = "查看上级"
}
const onMouseleave = () => {
hoverText.value = ""
}
// ma-info变量
const dutOriginColumns = useDutColumn(undefined)
const dutColumns = computed(() => {
// 去掉上传源代码字段
const quUploadColumns = dutOriginColumns.value.filter((it) => it.dataIndex !== "upload")
// 判断是否为源代码被测件
return quUploadColumns
})
const designColumns = useDesignColumn(undefined)
const demandColumns = useDemandColumn(undefined)
// 根据parentKey判断是哪个级别节点
const keyLength = props.parentKey.split("-").length
// 储存ma-info的dom
let maInfoDom = <Empty></Empty>
// 处理异步请求的函数
const fetchNodeData = async (resPromise: Promise<any>, nodeType: string) => {
const res = await resPromise
switch (nodeType) {
case "dut":
const dutInfo = res.data
const dutInfoJudge = computed(() => {
if (dutInfo.type === "SO") {
// 计算注释率:注释行/总行数
dutInfo.comment_percent = (dutInfo.comment_lines / dutInfo.total_lines) * 100 + "%"
} else {
// 如果是非源代码被测件行数均填写:“不适用”
dutInfo.comment_lines = "不适用"
dutInfo.comment_percent = "不适用"
dutInfo.effective_lines = "不适用"
dutInfo.total_lines = "不适用"
}
return dutInfo
})
maInfoDom = (
<MaInfo columns={dutColumns.value} data={dutInfoJudge.value} tableLayout="auto"></MaInfo>
)
break
case "design":
maInfoDom = <MaInfo columns={designColumns.value} data={res.data} tableLayout="auto"></MaInfo>
break
case "demand":
maInfoDom = <MaInfo columns={demandColumns.value} data={res.data} tableLayout="auto"></MaInfo>
break
default:
break
}
}
switch (keyLength) {
case 2:
// 请求设计需求节点
fetchNodeData(dutApi.getDutOne({ project_id, key: props.parentKey }), "dut")
break
case 3:
// 请求测试项节点
fetchNodeData(designApi.getDesignDemandOne({ project_id, key: props.parentKey }), "design")
break
case 4:
// 请求用例节点
fetchNodeData(demandApi.getTestDemandOne({ project_id, key: props.parentKey }), "demand")
break
default:
break
}
return () => (
<Teleport to="body">
<Popover trigger="click" position="left">
{{
default: () => (
<div class="preview-container">
<div
class="button-like"
ref={buttonLikeRef}
onMouseenter={onMouseenter}
onMouseleave={onMouseleave}
>
<icon-find-replace />
{hoverText.value && <span class="ml-2">{hoverText.value}</span>}
</div>
</div>
),
content: () => (
<div
style={{
width: "600px"
}}
>
{maInfoDom}
</div>
)
}}
</Popover>
</Teleport>
)
}
})
</script>
<style scoped lang="less">
.preview-container {
position: fixed;
right: 80px;
top: 45%;
z-index: 10000;
}
.button-like {
width: 40px;
height: 40px;
font-size: 16px;
border-radius: 50%;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
cursor: pointer;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.8);
transition: all 0.1s;
overflow: hidden;
position: relative;
span {
white-space: nowrap;
}
}
.button-like:hover {
width: 120px;
border-radius: 22px;
}
.click-content {
min-width: 500px;
min-height: 300px;
background-color: #fff;
}
</style>

View File

@@ -6,6 +6,7 @@ import useOptions from "./useOptions"
import subFormHooks from "@/views/project/projPublicHooks/subFormHooks"
import useBeforeCancel from "@/views/project/projPublicHooks/useBeforeCancel"
import { cloneDeep } from "lodash-es"
import ParentPreview from "@/views/project/ParentPreview/index.vue"
const DemandSubForm = defineComponent({
name: "DemandSubFormForm",

View File

@@ -60,7 +60,7 @@ export default function (crudRef: Ref<InstanceType<typeof MaCrud>>) {
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} > ${td[round_key].title} > ${td[round_key].children[dut_key].title} > ${td[round_key].children[dut_key].children[design_key].title} > 测试项-`
return true
},
beforeOpenEdit: function (record) {
beforeOpenEdit: function (record: any) {
// 1.储存打开前form的content数据到ref中以便后续比较
beforeFormContent = cloneDeep(record.testContent)
// 2.处理标识

View File

@@ -2,7 +2,13 @@
<div class="ma-content-block lg:flex justify-between p-4">
<div class="lg:w-full w-full lg:ml-4 mt-5 lg:mt-0">
<!-- CRUD组件 -->
<ma-crud :options="crudOptions" :columns="crudColumns" ref="crudRef" @beforeCancel="handleBeforeCancel">
<ma-crud
:options="crudOptions"
:columns="crudColumns"
ref="crudRef"
@beforeCancel="handleBeforeCancel"
:parent-key="route.query.key"
>
<template #ident="{ record }">
{{ showType(record) }}
</template>
@@ -44,10 +50,13 @@
<script setup>
import { ref } from "vue"
import commonApi from "@/api/common"
import { useRoute } from "vue-router"
// hooks
import useCrudOpMore from "./hooks/useCrudOpMore"
import useColumn from "./hooks/useColumns"
import useRalateDemand from "./hooks/useRalateDemand"
// inits
const route = useRoute()
// refs
const crudRef = ref(null)
// 根据传参获取key分别为轮次、设计需求的key

View File

@@ -2,7 +2,7 @@
<div class="ma-content-block lg:flex justify-between p-4">
<div class="lg:w-full w-full lg:ml-4 mt-5 lg:mt-0">
<!-- CRUD组件 -->
<ma-crud :options="crudOptions" :columns="crudColumns" ref="crudRef">
<ma-crud :options="crudOptions" :columns="crudColumns" ref="crudRef" :parent-key="route.query.key">
<template #ident="{ record }">
{{ showType(record) }}
</template>

View File

@@ -2,7 +2,13 @@
<div class="ma-content-block lg:flex justify-between p-4">
<div class="lg:w-full w-full lg:ml-4 mt-5 lg:mt-0">
<!-- CRUD组件 -->
<ma-crud :options="crudOptions" :columns="crudColumns" ref="crudRef" @beforeCancel="handleBeforeCancel">
<ma-crud
:options="crudOptions"
:columns="crudColumns"
ref="crudRef"
@beforeCancel="handleBeforeCancel"
:parent-key="route.query.key"
>
<template #ident="{ record }">
{{ showType(record) }}
</template>
@@ -17,6 +23,8 @@ import { ref } from "vue"
import ProblemForm from "@/views/project/case/components/ProblemForm.vue"
import useCrudOpMore from "./hooks/useCrudOpMore"
import useColumn from "./hooks/useColumn"
import { useRoute } from "vue-router"
const route = useRoute()
const problemFormRef = ref(null)
const title = ref("问题单表单")
const crudRef = ref()