前端大功能实现

This commit is contained in:
2024-05-11 18:11:56 +08:00
parent 4dab2b9866
commit 17776d5316
14 changed files with 483 additions and 80 deletions

View File

@@ -10,5 +10,16 @@ export default {
method: "get",
params
})
},
/**
* 操作日志删除
* @returns 后台返回的删除信息
*/
deleteOperationLogs(params = { day: 7 }) {
return request({
url: `/system/log/operation_delete`,
method: "get",
params
})
}
}

View File

@@ -44,4 +44,37 @@ export default {
data
})
},
/**
* 右键点击需求创建测试用例
* @returns 成功或失败信息
*/
createByDemand(params = {}) {
return request({
url: "/project/case/create_by_demand",
method: "post",
data: params
})
},
/**
* 拖拽大功能:拖拽测试用例到测试项节点,移动还是复制
* @returns 返回case的key用于刷新树状图的数据
*/
copyOrMoveCaseToDemand(params = {}) {
return request({
url: "/project/case/copy_or_move_to_demand",
method: "get",
params
})
},
/**
* 拖拽大功能:拖拽测试用例到用例节点(都是用例),移动还是复制
* @returns 返回case的key用于刷新树状图的数据
*/
copyOrMoveCaseByCase(params = {}) {
return request({
url: "/project/case/copy_or_move_by_case",
method: "get",
params
})
}
}

View File

@@ -56,4 +56,15 @@ export default {
data
})
},
/**
* 获取级联选择器所需要的复制功能级联design列表
* @returns data_list:三级级联列表
*/
getRelatedCasDesign(params = {}) {
return request({
url: "/project/designDemand/getRelatedDesign",
method: "get",
params
})
},
}

View File

@@ -76,5 +76,16 @@ export default {
method: "post",
data: params
})
},
/**
* 复制demand到指定design下面
* @returns 复制是否成功
*/
copyToDesign(params = {}) {
return request({
url: "/project/testDemand/copy_to_design",
method: "post",
data: params
})
}
}

View File

@@ -4,18 +4,29 @@
<!-- 这里主要在路由定义是否缓存页面 -->
<component :is="Component" v-if="route.meta.ignoreCache" :key="route.fullPath" />
<keep-alive v-else :include="cacheList">
<component :is="Component" :key="route.fullPath"></component>
<component :is="Component" ref="viewChild" :key="route.fullPath"></component>
</keep-alive>
</transition>
</router-view>
</template>
<script setup>
import { computed } from "vue"
import { computed, ref } from "vue"
import { useTabBarStore } from "@/store"
// 获取缓存列表
const tabBarStore = useTabBarStore()
const cacheList = computed(() => tabBarStore.getCacheList)
// 调用router-view组件的刷新方法
const viewChild = ref()
const refresh = () => {
try {
viewChild.value.refreshCrudTable()
} catch (err) {
console.log("无法找到router-view动态组件的刷新函数")
} finally {
}
}
defineExpose({ refresh })
</script>
<style lang="less" scoped></style>

View File

@@ -22,11 +22,15 @@
<a-tree
class="h-10/12 select-none"
:data="treeData"
size="small"
size="mini"
checkable
block-node
draggable
animation
auto-expand-parent
@select="pointNode"
@drop="ondrop"
:allow-drop="allowdrop"
:load-more="loadMore"
v-model:expanded-keys="expandedKeys"
v-model:selected-keys="selectedKeys"
@@ -34,6 +38,7 @@
showLine
ref="treeRef"
border
@contextmenu="displayRightMenu"
:default-selected-keys="[currentNode ? currentNode : route.query.key]"
>
<!-- 在轮次节点可以新增编辑删除复制 -->
@@ -81,6 +86,11 @@
/></a-tooltip>
</template>
</template>
<!-- 设计节点的图标 -->
<template #switcher-icon="node, { isLeaf }">
<IconDown v-if="!isLeaf" />
<IconFile v-if="isLeaf" />
</template>
<!-- 节点图标插槽 -->
<template #icon="props">
<template v-if="props.node.level === '1'"> [被测件] </template>
@@ -93,7 +103,7 @@
</a-layout-sider>
<a-layout class="layout-content myhcalc">
<a-layout-content class="work-area project-layout">
<PageLayout />
<PageLayout ref="routeViewRef" />
</a-layout-content>
</a-layout>
</a-layout>
@@ -122,6 +132,79 @@
:text="ptext"
@clickConfirm="handleModalConfirmClick"
></Progress>
<!-- 右键菜单 -->
<a-dropdown
v-model:popup-visible="popupVisible"
:popup-container="popupContainer"
position="bottom"
alignPoint
:style="{ display: 'block' }"
>
<div
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '300px',
backgroundColor: 'var(--color-fill-2)'
}"
></div>
<template #content>
<a-dgroup title="执行操作">
<a-doption @click="handleDoptionClickGreateCases">
<template #icon>
<icon-plus-circle />
</template>
根据测试子项生成所属用例
</a-doption>
</a-dgroup>
<a-dgroup title="复制">
<a-doption @click="handleDoptionClickCopyDemand">
<template #icon>
<icon-copy />
</template>
复制到设计需求下...
</a-doption>
</a-dgroup>
</template>
</a-dropdown>
<!-- 复制modal组件 -->
<!-- 关联的modal组件 -->
<a-modal v-model:visible="modalVisible" width="700px" draggable :on-before-ok="handleCopyDemand">
<template #title>复制到设计需求</template>
<div class="pb-3">选择复制到的节点:</div>
<a-cascader
:options="options"
allow-search
allow-clear
size="large"
placeholder="复制到选择的设计需求节点下"
:loading="cascaderLoading"
v-model:model-value="relatedCopyData"
/>
<div class="mt-3"><a-checkbox v-model="checkboxValue">是否复制用例</a-checkbox></div>
</a-modal>
<!-- 拖拽用例气泡提示 -->
<a-popconfirm
v-model:popup-visible="paoVisible"
ok-text="移动"
cancel-text="复制"
@ok="paoOk"
@cancel="paoCancel"
:popup-container="paoContainer"
content="选择移动/复制"
>
</a-popconfirm>
<a-popconfirm
v-model:popup-visible="pao2Visible"
ok-text="移动"
cancel-text="复制"
@ok="paoOk2"
@cancel="paoCancel2"
:popup-container="pao2Container"
content="选择移动/复制"
>
</a-popconfirm>
</template>
<script setup>
@@ -133,13 +216,18 @@ import projectApi from "@/api/project/project"
import roundApi from "@/api/project/round"
import dutApi from "@/api/project/dut"
import copyApi from "@/api/treeOperation/copy"
import { Message, Notification } from "@arco-design/web-vue"
import caseApi from "@/api/project/case"
import designApi from "@/api/project/designDemand"
import demandApi from "@/api/project/testDemand"
import { Message, Notification, Tr } from "@arco-design/web-vue"
import { useRoute } from "vue-router"
import { useRouter } from "vue-router"
import { useTreeDataStore } from "@/store"
import { storeToRefs } from "pinia"
import dayjs from "dayjs"
import Progress from "@/views/testmanage/projmanage/cpns/progress.vue"
// router-view里面组件的ref
const routeViewRef = ref()
/// 初始化round轮次数据
const treeDataStore = useTreeDataStore()
const route = useRoute()
@@ -459,7 +547,7 @@ const roundColumn = ref([
{
span: 12,
formList: [
{ title: "标识", dataIndex: "ident" },
{ title: "轮次标识", dataIndex: "ident", disabled: true },
{
title: "开始时间",
dataIndex: "beginTime",
@@ -614,27 +702,216 @@ const soDutColumn = ref([
title: "空行",
dataIndex: "black_line",
formType: "input-number",
rules: [{ required: true, message: "空行数必填" }],
rules: [{ required: true, message: "空行数必填" }]
},
{
title: "纯注释",
dataIndex: "comment_line",
formType: "input-number",
rules: [{ required: true, message: "纯注释数必填" }],
rules: [{ required: true, message: "纯注释数必填" }]
},
{
title: "混合行",
dataIndex: "mix_line",
formType: "input-number",
rules: [{ required: true, message: "混合行必填" }],
rules: [{ required: true, message: "混合行必填" }]
},
{
title: "纯代码",
dataIndex: "code_line",
formType: "input-number",
rules: [{ required: true, message: "纯代码行必填" }],
rules: [{ required: true, message: "纯代码行必填" }]
}
])
// 大功能:右键菜单实现
/// ~~~右键菜单弹出~~~
const popupVisible = ref(false)
/// 右键菜单的挂载容器
const popupContainer = ref()
/// 组件全局
const rightClickNode = { level: 3, isLeaf: false, nodekey: "", title: "" }
/// 紧点击测试项节点显示右键菜单
const displayRightMenu = (e) => {
const { proxy } = e.target.__vueParentComponent
const { level, isLeaf, nodekey, title } = proxy
if (level === 3) {
e.preventDefault()
// 首先将被右键点击的node储存到组件全局
rightClickNode.level = level
rightClickNode.isLeaf = isLeaf
rightClickNode.nodekey = nodekey
rightClickNode.title = title
// 将popup组件绑定到被右键点击的元素
popupContainer.value = e.target
popupVisible.value = true
}
}
/// 点击popup自动生成对应测试项的用例按钮处理函数
const handleDoptionClickGreateCases = async () => {
// 将project_id加入参数
rightClickNode.project_id = projectId.value
const res = await caseApi.createByDemand(rightClickNode)
routeViewRef.value.refresh()
}
/// 复制modal级联选择器的选项
const options = ref([])
const modalVisible = ref(false)
const relatedCopyData = ref(0)
const cascaderLoading = ref(false)
/// 点击popup复制测试项
const handleDoptionClickCopyDemand = async () => {
// 首先是要获取选项数据
cascaderLoading.value = true
modalVisible.value = true
// 请求后端给级联选择器数据
const res = await designApi.getRelatedCasDesign({ id: projectId.value }).catch((err) => {
Message.error("请求后端数据发生错误,请重试")
cascaderLoading.value = false
})
options.value = res.data
// 先获取当前右击的需求的key -> 然后找到所属design的nodekey
const currentDemandKey = rightClickNode.nodekey
const belongDesignKey = currentDemandKey.substring(0, currentDemandKey.lastIndexOf("-"))
// 默认赋值给demand的当前design直接点击确定可以复制到当前
options.value.forEach((item) => {
item.children.forEach((tem) => {
tem.children.forEach((design_obj) => {
if (belongDesignKey === design_obj.key) {
relatedCopyData.value = design_obj.value
}
})
})
})
cascaderLoading.value = false
// 将checkbox-depth参数设置为非勾选
checkboxValue.value = false
}
/// 点击复制modal弹窗确定按钮
const checkboxValue = ref(false)
const handleCopyDemand = async () => {
// 获取选择的design的id
const design_id = relatedCopyData.value
// 没有选取则直接返回false
if (!design_id) {
return false
}
// 这里进行复制的数据处理
const res = await demandApi.copyToDesign({
project_id: projectId.value,
design_id: design_id,
demand_key: rightClickNode.nodekey,
depth: checkboxValue.value
})
if ((res.code = 200)) {
// 注意必须传projectId否则返回空
treeDataStore.updateTestDemandTreeData(res.data, projectId.value)
Notification.success("复制成功,为避免重复,设置了(复制)字样,请手动修改...")
return true
} else {
Message.error("复制失败,服务器错误")
}
}
// ~~~~~~~~大功能:拖拽~~~~~~~~
const paoVisible = ref(false)
const paoContainer = ref(null)
const pao2Visible = ref(false)
const pao2Container = ref(null)
/// 储存被拖拽到的节点以及拖拽的节点
let dragNodeGlobal = null
let dropNodeGlobal = null
let dragDropPosition = 0
/// 节点在可释放目标释放的操作 - drapNode是被拖拽的节点dropNone是释放在哪个节点下dropPosition是释放的位置-1,0...
const ondrop = ({ e, dragNode, dropNode, dropPosition }) => {
const data = treeData.value // 1.这是整体的树数据
// 拖拽逻辑:
// 1.首先只能拖拽用例节点才能实现功能
if (dragNode.level === "4") {
// 2.1.如果是拖拽到测试项节点下
if (dropNode.level === "3") {
// 2.1.1.如果位置为0则放在了测试项里面,为1-1在测试上下都不处理
if (dropPosition === 0) {
// 判断用例是否已经测试项节点里面了
if (!dropNode.children || !dropNode.children.includes(dragNode)) {
// 不在测试项里面,则弹出提示是复制还是移动
dragNodeGlobal = dragNode
dropNodeGlobal = dropNode
paoContainer.value = e.target.parentElement
paoVisible.value = true
}
}
} else if (dropNode.level === "4") {
// 2.2.如果拖拽到测试用例节点,注意拖动到自己上下方不触发
// 2.2.1先要判断用例是否是同一个demand则是改变顺序
dragNodeGlobal = dragNode
dropNodeGlobal = dropNode
pao2Container.value = e.target.parentElement
pao2Visible.value = true
dragDropPosition = dropPosition
}
}
}
/// 只运行拖拽用例节点和测试项2种节点
const allowdrop = (options) => {
if (options.dropNode.level === "4" || options.dropNode.level === "3") {
return true
}
}
/// 拖拽后弹出气泡-移动
const paoOk = async () => {
const res = await caseApi.copyOrMoveCaseToDemand({
project_id: projectId.value,
case_key: dragNodeGlobal.key,
demand_key: dropNodeGlobal.key,
move: true
})
await treeDataStore.updateCaseTreeData(res.data.oldCaseKey, projectId.value)
await treeDataStore.updateCaseTreeData(res.data.newCaseKey, projectId.value)
routeViewRef.value.refresh()
Notification.success("移动用例成功")
}
/// 拖拽后弹出气泡-复制
const paoCancel = async () => {
const res = await caseApi.copyOrMoveCaseToDemand({
project_id: projectId.value,
case_key: dragNodeGlobal.key,
demand_key: dropNodeGlobal.key,
move: false
})
await treeDataStore.updateCaseTreeData(res.data.oldCaseKey, projectId.value)
await treeDataStore.updateCaseTreeData(res.data.newCaseKey, projectId.value)
routeViewRef.value.refresh()
Notification.success("复制用例成功")
}
/// 同级分2个气泡ok是移动cancel是复制
const paoOk2 = async () => {
const res = await caseApi.copyOrMoveCaseByCase({
project_id: projectId.value,
drag_key: dragNodeGlobal.key,
drop_key: dropNodeGlobal.key,
position: dragDropPosition,
move: true
})
await treeDataStore.updateCaseTreeData(res.data.old, projectId.value)
await treeDataStore.updateCaseTreeData(res.data.new, projectId.value)
routeViewRef.value.refresh()
Notification.success("移动用例成功")
}
const paoCancel2 = async () => {
const res = await caseApi.copyOrMoveCaseByCase({
project_id: projectId.value,
drag_key: dragNodeGlobal.key,
drop_key: dropNodeGlobal.key,
position: dragDropPosition,
move: false
})
await treeDataStore.updateCaseTreeData(res.data.old, projectId.value)
await treeDataStore.updateCaseTreeData(res.data.new, projectId.value)
routeViewRef.value.refresh()
Notification.success("复制用例成功")
}
</script>
<style lang="less" scoped>

View File

@@ -6,6 +6,14 @@
<template #create_datetime="{ record }">
{{ record.create_datetime.replace("T", " ") }}
</template>
<template #tableBeforeButtons>
<a-button type="primary" status="warning" @click="handleDeleteLogButton"
><template #icon> <icon-delete /> </template>删除7天前数据</a-button
>
<a-button type="primary" status="danger" @click="handleDeleteAllLogButton"
><template #icon> <icon-delete /> </template>删除全部日志</a-button
>
</template>
</ma-crud>
</div>
</div>
@@ -14,6 +22,7 @@
<script setup>
import { ref, reactive } from "vue"
import operationApi from "@/api/monitor/operationLog"
import { Message } from "@arco-design/web-vue"
const crudRef = ref()
const crudOptions = reactive({
@@ -31,6 +40,16 @@ const crudColumns = reactive([
{ title: "操作内容", dataIndex: "operate_des", align: "center" },
{ title: "时间", dataIndex: "create_datetime", align: "center", search: true, formType: "range" }
])
// 删除日志按钮事件处理函数
const handleDeleteLogButton = async () => {
const res = await operationApi.deleteOperationLogs() // 参数:{day:4}保留4天内的日志
Message.success(res.message)
}
const handleDeleteAllLogButton = async () => {
const res = await operationApi.deleteOperationLogs({ day: 0 }) // 0表示删除全部日志
crudRef.value.refresh()
Message.success(res.message)
}
</script>
<style lang="less" scoped></style>

View File

@@ -196,7 +196,7 @@ const columns = ref([
validateTrigger: "blur"
},
{
title: "标识",
title: "问题标识",
align: "center",
sortable: { sortDirections: ["ascend"] },
width: 140,

View File

@@ -98,6 +98,7 @@ const crudOptions = ref({
case: caseNumber
},
showIndex: false,
showTools: false,
rowSelection: { showCheckedAll: true },
searchColNumber: 3,
tablePagination: false,
@@ -201,7 +202,7 @@ const crudColumns = ref([
validateTrigger: "blur"
},
{
title: "标识",
title: "问题标识",
align: "center",
sortable: { sortDirections: ["ascend"] },
width: 140,

View File

@@ -141,9 +141,8 @@ const showType = (record) => {
let len = testTypeDict.value.data.length
for (let i = 0; i < len; i++) {
if (testTypeDict.value.data[i].key === record.testType) {
let key_string = parseInt(record.key.substring(record.key.lastIndexOf("-") + 1)) + 1
let item = testTypeDict.value.data[i]
return "XQ-" + record.ident + "-" + item.show_title + "-" + key_string.toString().padStart(3, "0")
return "XQ-" + item.show_title + "-" + record.ident
}
}
}
@@ -153,6 +152,7 @@ const crudOptions = ref({
add: { show: true, api: testDemandApi.save, text: "新增测试项" },
edit: { show: true, api: testDemandApi.update, text: "修改测试项" },
delete: { show: true, api: testDemandApi.delete },
showTools: false,
beforeOpenAdd: function () {
let key_split = route.query.key.split("-")
let round_key = key_split[0]
@@ -181,6 +181,9 @@ const crudOptions = ref({
},
afterDelete: (res, record) => {
let id = projectId.value
if (!record) {
record = { key: route.query.key + "-X" }
}
treeDataStore.updateTestDemandTreeData(record, id)
},
parameters: {
@@ -206,15 +209,15 @@ const crudColumns = ref([
dataIndex: "id"
},
{
title: "标识",
title: "测项标识",
width: 150,
dataIndex: "ident",
sortable: { sortDirections: ["ascend"] },
align: "center",
search: true,
addDisabled: true,
editDisabled: true,
validateTrigger: "blur"
validateTrigger: "blur",
placeholder: "请填写测试项的标识,注意标识不能重复",
commonRules: [{ required: true, message: "测试项标识必填" }]
},
{
title: "名称",
@@ -261,36 +264,7 @@ const crudColumns = ref([
}
},
{
title: "充分条件",
hide: true,
addDefaultValue: "覆盖需求相关功能",
dataIndex: "adequacy",
formType: "textarea",
maxLength: 256,
commonRules: [{ required: true, message: "充分性描述必填" }]
},
{
title: "终止条件",
hide: true,
dataIndex: "termination",
formType: "textarea",
showWordLimit: true,
maxLength: 1024,
addDefaultValue:
"1.测试正常终止:测试项分解的所有用例执行完毕,达到充分性要求,相关记录完整;\n2.测试异常终止:由于某些特殊原因导致该测试项分解的测试用例不能完全执行,无法执行的原因已记录",
commonRules: [{ required: true, message: "前提条件必填" }]
},
{
title: "前提条件",
hide: true,
addDefaultValue: "软件正常运行,外部接口通信正常",
dataIndex: "premise",
formType: "textarea",
maxLength: 256,
commonRules: [{ required: true, message: "前提条件必填" }]
},
{
title: "测试方法",
title: "测试手段",
align: "center",
dataIndex: "testMethod",
formType: "select",
@@ -298,24 +272,70 @@ const crudColumns = ref([
dict: { name: "testMethod", props: { label: "title", value: "key" }, translation: true }
},
{
title: "测试内容",
title: "充分性要求",
hide: true,
addDefaultValue: "覆盖需求相关功能",
dataIndex: "adequacy",
formType: "textarea",
maxLength: 256,
commonRules: [{ required: true, message: "充分性描述必填" }],
addDefaultValue:
"测试用例覆盖XX子项名称1、XX子项名称2、XX子项名称3子项要求的全部内容。\n所有用例执行完毕对于未执行的用例说明未执行原因。"
},
{
title: "测试子项",
hide: true,
dataIndex: "testContent",
commonRules: [{ required: true, message: "测试内容必填" }],
commonRules: [{ required: true, message: "测试方法是必填" }],
formType: "children-form",
type: "table",
formList: [
{
title: "测试分解",
dataIndex: "testXuQiu"
title: "子项名称",
dataIndex: "subName",
placeholder: "对应测试项描述标题,和测试方法的标题",
rules: [{ required: true, message: "测试子项名称必填" }],
onChange: (ev) => {
// 取出子项的对象数组
const subItemFormData = crudRef.value.getFormData().testContent
// 取出充分性条件字段字符串
const mapRes = subItemFormData.map((subItem) => subItem.subName)
crudRef.value.getFormData().adequacy = `测试用例覆盖${mapRes}子项要求的全部内容。\n所有用例执行完毕对于未执行的用例说明未执行原因。`
}
},
{
title: "预期",
dataIndex: "testYuQi"
title: "子项描述",
dataIndex: "subDesc",
placeholder: "对应大纲测试项表格的测试项描述",
rules: [{ required: true, message: "测试子项描述必填" }]
},
{
title: "条件",
dataIndex: "condition",
placeholder: "在什么环境和前置条件下"
},
{
title: "操作",
dataIndex: "operation",
placeholder: "通过xxx操作"
},
{
title: "观察",
dataIndex: "observe",
placeholder: "查看xxx内容"
},
{
title: "期望",
dataIndex: "expect",
placeholder: "xxx结果正确"
}
]
}
])
// 暴露给route-view的刷新表格函数
const refreshCrudTable = () => {
crudRef.value.refresh()
}
defineExpose({ refreshCrudTable })
</script>
<style lang="less" scoped>

View File

@@ -24,7 +24,7 @@ const crudRef = ref()
const roundNumber = route.query.key.split("-")[0]
const dutNumber = route.query.key.split("-")[1]
const projectId = ref(route.query.id)
// 显示标识是FT-{标识}-001大体思路是根据类型生成FT拼接标识和key的最后一位
// 5月8日修改设计需求标识就按SJ-FT-设计需求标识来
const demandTypeDict = ref([])
!(function () {
commonApi.getDict("demandType").then((res) => {
@@ -36,9 +36,8 @@ const showType = (record) => {
let len = demandTypeDict.value.data.length
for (let i = 0; i < len; i++) {
if (demandTypeDict.value.data[i].key === record.demandType) {
let key_string = parseInt(record.key.substring(record.key.lastIndexOf("-") + 1)) + 1
let item = demandTypeDict.value.data[i]
return "SJ-" + record.ident + "-" + item.show_title + "-" + key_string.toString().padStart(3, "0")
return "SJ-" + item.show_title + "-" + record.ident
}
}
}
@@ -46,7 +45,7 @@ const showType = (record) => {
const crudOptions = ref({
api: designDemandApi.getDesignDemandList,
add: { show: true, api: designDemandApi.save, text: "新增设计需求" },
edit: { show: true, api: designDemandApi.editDesignDemand,text:'编辑设计需求' },
edit: { show: true, api: designDemandApi.editDesignDemand, text: "编辑设计需求" },
delete: { show: true, api: designDemandApi.delete },
// 处理添加后函数
beforeOpenAdd: function () {
@@ -75,6 +74,9 @@ const crudOptions = ref({
},
afterDelete: (res, record) => {
let id = projectId.value
if (!record) {
record = { key: route.query.key + "-X" }
}
treeDataStore.updateDesignDemandTreeData(record, id)
},
parameters: {
@@ -90,7 +92,8 @@ const crudOptions = ref({
operationColumnAlign: "center",
formOption: {
width: 1200
}
},
showTools: false
})
const crudColumns = ref([
{
@@ -102,14 +105,15 @@ const crudColumns = ref([
validateTrigger: "blur"
},
{
title: "标识",
title: "设需标识",
align: "center",
sortable: { sortDirections: ["ascend"] },
width: 120,
dataIndex: "ident",
search: true,
commonRules: [{ required: true, message: "标识是必填" }],
validateTrigger: "blur"
validateTrigger: "blur",
placeholder: "请输入文档中设计需求的标识"
},
{
title: "需求名称",

View File

@@ -50,6 +50,9 @@ const crudOptions = ref({
},
afterDelete: (res, record) => {
let id = projectId.value
if (!record) {
record = { key: route.query.key + "-X" }
}
treeDataStore.updateDutTreeData(record, id)
},
edit: { show: true, api: dutApi.update, text: "编辑被测件" },
@@ -81,7 +84,7 @@ const crudColumns = ref([
validateTrigger: "blur"
},
{
title: "标识",
title: "测件标识",
width: 150,
sortable: { sortDirections: ["ascend"] },
align: "center",

View File

@@ -25,19 +25,10 @@ const designDemandNumber = route.query.key.split("-")[2]
const testDemandNumber = route.query.key.split("-")[3]
const crudRef = ref()
const projectId = ref(route.query.id)
// 标识显示字段
// 标识显示字段-用例比较特殊让后端返回了“FT”字样因为FT是在测试项里面标识的
const showType = (record) => {
let key_string = parseInt(record.key.substring(record.key.lastIndexOf("-") + 1)) + 1
let k_string_array = record.key.split("-")
let demand_key = parseInt(k_string_array.slice(-2)[0]) + 1
return (
"YL-" +
record.ident +
"-" +
demand_key.toString().padStart(3, "0") +
"-" +
key_string.toString().padStart(3, "0")
)
return "YL-" + record.testType + "-" + record.ident + "-" + key_string.toString().padStart(3, "0")
}
// crud设置
const crudOptions = ref({
@@ -83,6 +74,9 @@ const crudOptions = ref({
},
afterDelete: (res, record) => {
let id = projectId.value
if (!record) {
record = { key: route.query.key + "-X" }
}
treeDataStore.updateCaseTreeData(record, id)
},
parameters: {
@@ -93,6 +87,7 @@ const crudOptions = ref({
testDemand: testDemandNumber
},
showIndex: false,
showTools: false,
rowSelection: { showCheckedAll: true },
searchColNumber: 3,
tablePagination: false,
@@ -134,7 +129,7 @@ const crudColumns = ref([
fixed: "left"
},
{
title: "标识",
title: "用例标识",
dataIndex: "ident",
sortable: { sortDirections: ["ascend"] },
width: 140,
@@ -220,7 +215,8 @@ const crudColumns = ref([
{
title: "操作",
dataIndex: "operation",
formType: "editor"
formType: "editor",
height: 180
},
{
title: "预期",
@@ -230,8 +226,8 @@ const crudColumns = ref([
{
title: "结果",
dataIndex: "result",
formType: "editor"
formType: "editor",
height: 180
},
{
title: "是否通过",
@@ -250,6 +246,11 @@ const crudColumns = ref([
]
}
])
// 暴露刷新表格方法给外部
const refreshCrudTable = () => {
crudRef.value.refresh()
}
defineExpose({ refreshCrudTable })
</script>
<style lang="less" scoped></style>

View File

@@ -248,6 +248,7 @@ const crudOptions = ref({
operationColumn: true,
operationWidth: 500,
showIndex: false,
showTools: false,
// 处理弹窗的title
beforeOpenAdd: function () {
crudRef.value.crudFormRef.actionTitle = "项目"
@@ -377,8 +378,8 @@ const crudOptions = ref({
// CRUD-CLOMNS
const crudColumns = ref([
{
title: "标识",
width: 70,
title: "项目标识",
width: 90,
sortable: { sortDirections: ["ascend"] },
dataIndex: "ident",
search: true,