This commit is contained in:
2023-06-15 20:13:46 +08:00
parent 09382319df
commit 95bf839308
83 changed files with 20351 additions and 185 deletions

View File

@@ -0,0 +1,14 @@
import { request } from "@/api/request"
export default {
/**
* 根据项目id、round、designDemand、testDemand信息请求详细case数据
* @returns 测试用例数据
*/
getCaseList(params = {}) {
return request({
url: `project/getCaseList`,
method: "get",
params
})
},
}

View File

@@ -0,0 +1,15 @@
import { request } from "@/api/request"
export default {
/**
* 根据项目id、round信息请求详细designDemand数据
* @returns 设计需求数组数据
*/
getDesignDemandList(params = {}) {
return request({
url: `project/getDesignDemandList`,
method: "get",
params
})
}
}

View File

@@ -0,0 +1,15 @@
import { request } from "@/api/request"
export default {
/**
* 根据项目id、round、designDemand、testDemand、case信息请求问题单列表
* @returns 属于case的问题单列表
*/
getProblemList(params = {}) {
return request({
url: `project/getProblemList`,
method: "get",
params
})
}
}

View File

@@ -1,5 +1,5 @@
import { request } from "@/api/request"
// 该api集合主要是tree动态加载项
export default {
/**
* 根据项目名确定round初始节点
@@ -11,14 +11,13 @@ export default {
method: "get"
})
},
/**
* 根据项目名、轮次round查询轮次下面的设计需求
* 根据项目名、树节点等级和key查找设计需求
* @returns 设计需求树状节点信息
*/
getDemandInfo(projectId, key, level) {
return request({
url: `project/getdemandInfo`,
url: `project/getDesignDemandInfo`,
method: "get",
params: {
projectId: projectId,
@@ -26,5 +25,50 @@ export default {
level: level
}
})
}
},
/**
* 根据项目名、树节点等级和key查找测试需求
* @returns 返回测试需求testDemand
*/
getTestInfo(projectId, key, level) {
return request({
url: `project/getTestdemandInfo`,
method: "get",
params: {
projectId: projectId,
key: key,
level: level
}
})
},
/**
* 根据项目名、树节点等级和key查找测试用例
* @returns 返回测试用例
*/
getCaseInfo(projectId, key, level) {
return request({
url: `project/getCaseInfo`,
method: "get",
params: {
projectId: projectId,
key: key,
level: level
}
})
},
/**
* 根据项目名、树节点等级和key查找问题单
* @returns 返回问题单problem
*/
getProblemInfo(projectId, key, level) {
return request({
url: `project/getProblemInfo`,
method: "get",
params: {
projectId: projectId,
key: key,
level: level
}
})
},
}

View File

@@ -0,0 +1,22 @@
import { request } from "@/api/request"
export default {
/**
* 根据项目id、round、designDemand信息请求详细testDemand数据
* @returns 测试需求数据
*/
getTestDemandList(params = {}) {
return request({
url: `project/getTestDemandList`,
method: "get",
params
})
},
// 修改测试项信息
editTestDemand(id, data = {}) {
return request({
url: `project/editTestDemand/` + id,
method: "post",
data
})
}
}

View File

@@ -242,7 +242,6 @@ import MaSetting from "./components/setting.vue"
import MaImport from "./components/import.vue"
import MaColumn from "./components/column.vue"
import MaContextMenu from "./components/contextMenu.vue"
import checkAuth from "@/directives/auth/auth"
import { Message } from "@arco-design/web-vue"
import { request } from "@/utils/request"
import tool from "@/utils/tool"
@@ -457,6 +456,9 @@ const requestHandle = async () => {
loading.value = true
isFunction(options.value.beforeRequest) && options.value.beforeRequest(requestParams.value)
if (isFunction(currentApi.value)) {
if (options.value.parameters) {
requestParams.value = { ...requestParams.value, ...options.value.parameters }
}
const response = config.parseResponseData(await currentApi.value(requestParams.value))
if (response.rows) {
tableData.value = response.rows

View File

@@ -1,26 +1,11 @@
<!--
- MineAdmin is committed to providing solutions for quickly building web applications
- Please view the LICENSE file that was distributed with this source code,
- For the full copyright and license information.
- Thank you very much for using MineAdmin.
-
- @Author X.Mo<root@imoi.cn>
- @Link https://gitee.com/xmo/mineadmin-vue
-->
<template>
<div>
<editor :key="editorKey" v-model="content" :init="initConfig" :id="props.id"></editor>
<a-modal v-model:visible="resourceVisible" :width="1080" :footer="false" draggable>
<template #title>资源选择器</template>
<ma-resource v-model="list" multiple ref="resource" />
</a-modal>
</div>
</template>
<script setup>
import { reactive, ref, watch, computed } from "vue"
import MaResource from "@cps/ma-resource/index.vue"
import { useAppStore } from "@/store"
import Editor from "@tinymce/tinymce-vue"
@@ -38,15 +23,10 @@ import "tinymce/plugins/charmap" //特殊字符
import "tinymce/plugins/code" //编辑源码
import "tinymce/plugins/codesample" //代码示例
import "tinymce/plugins/directionality" //文字方向
import "tinymce/plugins/emoticons" //表情
import "tinymce/plugins/fullscreen" //全屏
import "tinymce/plugins/help" //帮助
import "tinymce/plugins/image" //插入编辑图片
import "tinymce/plugins/importcss" //引入css
import "tinymce/plugins/insertdatetime" //插入日期时间
import "tinymce/plugins/link" //超链接
import "tinymce/plugins/lists" //列表插件
import "tinymce/plugins/media" //插入编辑媒体
import "tinymce/plugins/nonbreaking" //插入不间断空格
import "tinymce/plugins/pagebreak" //插入分页符
import "tinymce/plugins/preview" //预览
@@ -63,19 +43,18 @@ const appStore = useAppStore()
const props = defineProps({
modelValue: { type: String },
height: { type: Number, default: 400 },
height: { type: Number, default: 250 },
id: { type: String, default: () => "tinymce" + new Date().getTime().toString() },
plugins: {
type: [String, Array],
default:
"preview searchreplace autolink directionality visualblocks visualchars fullscreen link media template code codesample table charmap nonbreaking insertdatetime advlist lists wordcount autosave"
"preview searchreplace autolink directionality visualblocks visualchars template code codesample table charmap nonbreaking insertdatetime advlist lists wordcount autosave"
},
toolbar: {
type: [String, Array],
default:
"code undo redo restoredraft | paste pastetext | forecolor backcolor bold italic underline strikethrough link codesample | fullscreen preview | alignleft aligncenter alignright alignjustify outdent indent formatpainter | \
styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | table media \
charmap pagebreak insertdatetime | resource"
"code undo redo restoredraft | paste pastetext |bold italic underline strikethrough codesample | preview | alignleft alignjustify indent formatpainter | \
styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | charmap pagebreak insertdatetime"
}
})
@@ -91,14 +70,12 @@ let content = computed({
})
const list = ref([])
const resource = ref()
const resourceVisible = ref(false)
const initConfig = reactive({
menubar: false, // 菜单栏显隐
language_url: "/tinymce/i18n/zh_CN.js",
language: "zh_CN",
skin_url: appStore.mode === "light" ? "/tinymce/skins/ui/tinymce-5" : "/tinymce/skins/ui/tinymce-5-dark",
skin_url: "/tinymce/skins/ui/tinymce-5",
height: props.height,
toolbar_mode: "wrap",
plugins: props.plugins,
@@ -109,10 +86,6 @@ const initConfig = reactive({
editor.on("init", () => {
editor.getBody().style.fontSize = "14px"
})
editor.ui.registry.addButton("resource", {
text: "资源选择器",
onAction: () => (resourceVisible.value = true)
})
}
})
@@ -135,8 +108,6 @@ watch(
}
})
content.value = content.value ? content.value + tmp : tmp
resource.value.clearSelecteds()
resourceVisible.value = false
}
)
watch(

View File

@@ -55,6 +55,7 @@
</template>
<template v-for="(component, componentIndex) in viewFormList[itemIndex]" :key="componentIndex">
<component
style="line-height:32px;"
v-if="!containerItems.includes(component.formType)"
:is="getComponentName(component?.formType ?? 'input')"
:component="component"
@@ -172,11 +173,13 @@ if (props.component.type == "table") {
formList.map((item) => {
item["hideLabel"] = true
})
} else {
formModel.value[props.component.dataIndex].map((item, index) => {
if (index > 0) defaultOpenKeys.push(index)
})
}
// 默认不展开所有的collapse
// else {
// formModel.value[props.component.dataIndex].map((item, index) => {
// if (index > 0) defaultOpenKeys.push(index)
// })
// }
const addItem = async (data = {}) => {
let index = formModel.value[props.component.dataIndex].length

View File

@@ -1,12 +1,3 @@
<!--
- MineAdmin is committed to providing solutions for quickly building web applications
- Please view the LICENSE file that was distributed with this source code,
- For the full copyright and license information.
- Thank you very much for using MineAdmin.
-
- @Author X.Mo<root@imoi.cn>
- @Link https://gitee.com/xmo/mineadmin-vue
-->
<template>
<td
v-show="typeof props.component?.display == 'undefined' || props.component?.display === true"

View File

@@ -1,7 +1,7 @@
<template>
<a-layout class="layout">
<div class="navbar layout-navbar">
<NavBar :title="$route.query.name" />
<NavBar :title="projectInfo.name" />
</div>
<a-layout class="layout">
<a-layout class="layout layout-demo">
@@ -11,6 +11,10 @@
<a-input style="height: 32px"></a-input>
<a-button>搜索</a-button>
</a-input-group>
<a-input-group class="mb-2 w-full flex items-center justify-between" size="mini">
<a-button class="w-1/2" type="primary">增加轮次</a-button>
<a-button class="w-1/2" type="primary" status="danger">删除轮次</a-button>
</a-input-group>
<a-tree
:data="treeData"
size="small"
@@ -23,11 +27,11 @@
></a-tree>
</div>
</a-layout-sider>
</a-layout>
<a-layout class="layout-content">
<a-layout-content class="work-area">
<PageLayout />
</a-layout-content>
<a-layout class="layout-content">
<a-layout-content class="work-area project-layout">
<PageLayout />
</a-layout-content>
</a-layout>
</a-layout>
</a-layout>
</a-layout>
@@ -39,6 +43,7 @@ import NavBar from "@/layout/components/navbar.vue"
import PageLayout from "@/layout/page-layout.vue"
import projectApi from "@/api/project/project"
import { useRoute } from "vue-router"
import { useRouter } from "vue-router"
// 缩小后的menu菜单
const drawerVisible = ref(false)
provide("toggleDrawerMenu", () => {
@@ -47,26 +52,62 @@ provide("toggleDrawerMenu", () => {
// 树状
/// 初始化round轮次数据
const route = useRoute()
const router = useRouter()
const treeRef = ref()
const treeData = ref([])
const projectId = ref(route.query.id)
const projectInfo = ref({ ...route.query })
const projectId = ref(route.query.projectId)
onMounted(async () => {
const roundData = await projectApi.getRoundInfo(projectId)
treeData.value = roundData
})
/// 点击树状节点-参数传入为key的值
/// 点击树状节点-参数1:节点数组参数2:树node对象
const pointNode = (value, data) => {
console.log("点击的节点为:", value)
console.log(data.node)
if (data.node.level === "0") {
router.push({ name: "round", query: { ...projectInfo.value, key: data.node.key } })
}
if (data.node.level === "1") {
router.push({ name: "designDemand", query: { ...projectInfo.value, key: data.node.key } })
}
if (data.node.level === "2") {
router.push({ name: "testDemand", query: { ...projectInfo.value, key: data.node.key } })
}
if (data.node.level === "3") {
router.push({ name: "case", query: { ...projectInfo.value, key: data.node.key } })
}
}
/// 动态加载函数-参数当前节点点击下箭头
/// 动态加载函数-参数1:树node对象
const loadMore = (nodeData) => {
console.log("动态加载的节点为:", nodeData) // 输出点击节点的key,以及添加上去的level属性
return new Promise(async (resolve) => {
const res = await projectApi.getDemandInfo(route.query.id, nodeData.key, nodeData.level)
nodeData.children = res
resolve()
})
if (nodeData.level == "0") {
return new Promise(async (resolve) => {
const res = await projectApi.getDemandInfo(projectInfo.value.id, nodeData.key, nodeData.level)
nodeData.children = res
resolve()
})
}
if (nodeData.level == '1') {
return new Promise(async (resolve) => {
const res = await projectApi.getTestInfo(projectInfo.value.id, nodeData.key, nodeData.level)
nodeData.children = res
resolve()
})
}
if (nodeData.level == '2') {
return new Promise(async (resolve) => {
const res = await projectApi.getCaseInfo(projectInfo.value.id, nodeData.key, nodeData.level)
nodeData.children = res
resolve()
})
}
if (nodeData.level == '3') {
return new Promise(async (resolve) => {
const res = await projectApi.getProblemInfo(projectInfo.value.id, nodeData.key, nodeData.level)
nodeData.children = res
resolve()
})
}
}
</script>
@@ -74,6 +115,9 @@ const loadMore = (nodeData) => {
.tree {
height: 100%;
}
.layout {
display: flex;
}
.layout-demo :deep(.arco-layout-sider) {
width: 300px !important;
}
@@ -113,11 +157,18 @@ const loadMore = (nodeData) => {
overflow-y: hidden;
}
}
.layout-demo {
position: relative;
}
.layout-content {
position: absolute;
top: 60px;
left: 300px;
min-height: 100vh;
width: 100% - 300px;
overflow-y: auto;
background-color: var(--color-fill-2);
transition: padding 0.2s cubic-bezier(0.34, 0.69, 0.1, 1);
position: absolute;
}
</style>

View File

@@ -32,6 +32,52 @@ const router = createRouter({
locale: "项目工作区",
icon: "icon-home"
},
children: [
{
path: "round",
name: "round",
component: () => import("@/views/project/round/index.vue"),
meta: {
requiresAuth: true,
roles: ["*"],
locale: "轮次信息",
icon: "icon-arrow-right"
}
},
{
path: "designDemand",
name: "designDemand",
component: () => import("@/views/project/design-demand/index.vue"),
meta: {
requiresAuth: true,
roles: ["*"],
locale: "设计需求",
icon: "icon-arrow-right"
}
},
{
path: "testDemand",
name: "testDemand",
component: () => import("@/views/project/testDemand/index.vue"),
meta: {
requiresAuth: true,
roles: ["*"],
locale: "测试需求",
icon: "icon-arrow-right"
}
},
{
path: "case",
name: "case",
component: () => import("@/views/project/case/index.vue"),
meta: {
requiresAuth: true,
roles: ["*"],
locale: "测试用例",
icon: "icon-arrow-right"
}
},
]
},
// 后台管理的路由以及404和重定向路由

View File

@@ -0,0 +1,6 @@
import { defineStore } from "pinia"
const useProjectStore = defineStore("prjectStore", {
state: () => ({
projectInfo: {}
})
})

View File

@@ -0,0 +1,219 @@
<template>
<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"></ma-crud>
</div>
</div>
</template>
<script setup lang="jsx">
import { ref } from "vue"
import { useRoute, useRouter } from "vue-router"
import problemApi from "@/api/project/problem"
const route = useRoute()
const router = useRouter()
const roundNumber = route.query.key.split("-")[0]
const designDemandNumber = route.query.key.split("-")[1]
const testDemandNumber = route.query.key.split("-")[2]
const caseNumber = route.query.key.split("-")[3]
const crudOptions = ref({
api: problemApi.getProblemList,
parameters: {
projectId: route.query.id,
round: roundNumber,
designDemand: designDemandNumber,
testDemand: testDemandNumber,
case: caseNumber
},
showIndex: false,
rowSelection: { showCheckedAll: true },
add: { show: true },
edit: { show: true },
delete: { show: true },
searchColNumber: 3,
tablePagination: true,
operationColumn: true,
scroll:{ x: '100%', y: '100%' },
formOption: {
width: 1000
}
})
const crudColumns = ref([
{
title: "名称",
align: "left",
search: true,
dataIndex: "name",
commonRules: [{ required: true, message: "名称是必填" }],
validateTrigger: "blur"
},
{
title: "标识",
align: "center",
width: 140,
search: true,
dataIndex: "ident",
commonRules: [{ required: true, message: "标识是必填" }],
validateTrigger: "blur"
},
{
title: "缺陷状态",
align: "center",
width: 80,
search: true,
dataIndex: "status",
formType: "radio",
addDefaultValue: "2",
commonRules: [{ required: true, message: "缺陷状态是必填" }],
dict: {
name: "problemStatu",
translation: true,
props: { label: "title", value: "key" },
tagColors: { 1: "green", 2: "blue", 3: "#FF7D00", 4: "red" }
}
},
{
title: "缺陷类型",
align: "center",
width: 80,
dataIndex: "type",
search: true,
addDefaultValue: "3",
formType: "radio",
commonRules: [{ required: true, message: "缺陷类型必选" }],
dict: {
name: "problemType",
translation: true,
props: { label: "title", value: "key" }
}
},
{
title: "缺陷等级",
align: "center",
width: 80,
dataIndex: "grade",
search: true,
addDefaultValue: "1",
formType: "radio",
commonRules: [{ required: true, message: "缺陷等级必填" }],
dict: {
name: "problemGrade",
translation: true,
props: { label: "title", value: "key" }
}
},
{
title: "闭环方式",
align: "center",
width: 150,
dataIndex: "closeMethod",
addDefaultValue: "2",
search: true,
formType: "radio",
dict: {
name: "closeMethod",
translation: true,
props: { label: "title", value: "key" }
},
customRender: ({ record }) => {
// 判断是否具有1修改文档
if (!record.closeMethod.hasOwnProperty("0")) {
if (!record.closeMethod.hasOwnProperty("1")) {
return <a-tag size="small" bordered color="magenta">还未闭环</a-tag>
}
}
const tagObj = []
for (let item in record.closeMethod) {
if (item === "0") {
tagObj.push(<a-tag size="small" bordered color="blue">修改文档</a-tag>)
} else if (item === "1") {
tagObj.push(<a-tag size="small" bordered color="green">修改程序</a-tag>)
}
}
return <a-space size='mini'>{tagObj}</a-space>
}
},
{
title: "操作",
hide: true,
search: true,
dataIndex: "operation",
formType: "editor"
},
{
title: "期望结果",
hide: true,
dataIndex: "expect"
},
{
title: "问题结果",
hide: true,
dataIndex: "result",
formType: "editor"
},
{
title: "修改建议",
hide: true,
dataIndex: "suggest"
},
{
title: "提单人",
dataIndex: "postPerson",
search: true,
formType: "select",
commonRules: [{ required: true, message: "提单人必填" }],
dict: { url: "system/user/index", translation: true, props: { label: "name", value: "name" } }
},
{
title:'提单日期',
hide: true,
dataIndex:"postDate",
formType:'date'
},
{
title: "设计师上级",
hide: true,
dataIndex: "designerPerson",
formType: "select",
commonRules: [{ required: true, message: "提单人必填" }],
dict: { url: "system/user/index", translation: true, props: { label: "name", value: "name" } }
},
{
title:'提单日期',
hide: true,
dataIndex:"designDate",
formType:'date'
},
{
title: "验证人",
hide: true,
dataIndex: "verifyPerson",
formType: "select",
commonRules: [{ required: true, message: "提单人必填" }],
dict: { url: "system/user/index", translation: true, props: { label: "name", value: "name" } }
},
{
title:'验证日期',
hide: true,
dataIndex:"verifyDate",
formType:'date'
},
{
title: "撤销人",
hide: true,
dataIndex: "revokePerson",
formType: "select",
commonRules: [{ required: true, message: "提单人必填" }],
dict: { url: "system/user/index", translation: true, props: { label: "name", value: "name" } }
},
{
title:'撤销日期',
hide: true,
dataIndex:"revokeDate",
formType:'date'
},
])
</script>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,142 @@
<template>
<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"></ma-crud>
</div>
</div>
</template>
<script setup>
import { ref } from "vue"
import { useRoute, useRouter } from "vue-router"
import testDemandApi from "@/api/project/testDemand"
const route = useRoute()
const router = useRouter()
// 根据传参获取key分别为轮次、设计需求的key
const roundNumber = route.query.key.split("-")[0]
const designDemandNumber = route.query.key.split("-")[1]
// crud组件
const crudOptions = ref({
api: testDemandApi.getTestDemandList,
parameters: {
projectId: route.query.id,
round: roundNumber,
designDemand: designDemandNumber
},
showIndex: false,
rowSelection: { showCheckedAll: true },
add: { show: true },
edit: { show: true, api: testDemandApi.editTestDemand },
delete: { show: true },
searchColNumber: 3,
tablePagination: true,
operationColumn: true,
formOption: {
width: 1200
}
})
const crudColumns = ref([
{
title: "ID",
align: "center",
width: 50,
dataIndex: "id"
},
{
title: "标识",
dataIndex: "ident",
align: "center",
search: true,
commonRules: [{ required: true, message: "标识是必填" }],
validateTrigger: "blur"
},
{
title: "名称",
dataIndex: "name",
width: 120,
align: "center",
search: true,
commonRules: [{ required: true, message: "名称是必填" }],
validateTrigger: "blur"
},
{
title: "优先级",
dataIndex: "priority",
search: true,
formType: "radio",
align: "center",
addDefaultValue: "1",
dict: {
name: "priority",
props: { label: "title", value: "key" },
translation: true,
tagColors: { 1: "red", 2: "blue", 3: "green" }
}
},
{
title: "测试类型",
dataIndex: "testType",
search: true,
align: "center",
formType: "select",
sortable: { sortDirections: ["ascend", "descend"] },
addDefaultValue: "3",
maxLength: 200,
commonRules: [{ required: true, message: "测试类型必选" }],
dict: { name: "testType", translation: true, props: { label: "title", value: "key" } },
extra: "请保证测试类型选择正确"
},
{
title: "充分条件",
hide: true,
addDefaultValue:"覆盖需求相关功能",
dataIndex: "adequacy",
commonRules: [{ required: true, message: "充分性描述必填" }]
},
{
title: "终止条件",
hide: true,
dataIndex: "termination",
formType: "textarea",
showWordLimit: true,
maxLength: 200,
addDefaultValue:
"1.测试正常终止:测试项分解的所有用例执行完毕,达到充分性要求,相关记录完整;\n2.测试异常终止:由于某些特殊原因导致该测试项分解的测试用例不能完全执行,无法执行的原因已记录",
commonRules: [{ required: true, message: "前提条件必填" }]
},
{
title: "前提条件",
hide: true,
addDefaultValue:"软件正常运行,外部接口通信正常",
dataIndex: "premise",
commonRules: [{ required: true, message: "前提条件必填" }]
},
{
title: "测试方法",
align: "center",
dataIndex: "testMethod",
commonRules: [{ required: true, message: "测试方法必填" }]
},
{
title: "测试内容",
hide: true,
dataIndex:"testContent",
commonRules: [{ required: true, message: "测试内容必填" }],
formType: "children-form",
type: "table",
formList: [
{
title: "测试分解",
dataIndex: "testXuQiu"
},
{
title: "预期",
dataIndex: "testYuQi"
}
]
}
])
</script>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,81 @@
<template>
<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"></ma-crud>
</div>
</div>
</template>
<script setup>
import { ref } from "vue"
import { useRoute, useRouter } from "vue-router"
import designDemandApi from "@/api/project/designDemand"
const route = useRoute()
const router = useRouter()
// crud组件
const crudOptions = ref({
api: designDemandApi.getDesignDemandList,
parameters: {
projectId: route.query.id,
round: route.query.key
},
showIndex: false,
rowSelection: { showCheckedAll: true },
add: { show: true },
edit: { show: true },
delete: { show: true },
searchColNumber: 3,
tablePagination: true,
operationColumn: true,
formOption: {
width: 1200
}
})
const crudColumns = ref([
{
title: "ID",
width: 50,
dataIndex: "id",
search: true,
commonRules: [{ required: true, message: "标识是必填" }],
validateTrigger: "blur"
},
{
title: "标识",
width: 120,
dataIndex: "ident",
search: true,
commonRules: [{ required: true, message: "标识是必填" }],
validateTrigger: "blur"
},
{
title: "需求名称",
width: 150,
dataIndex: "name",
search: true,
commonRules: [{ required: true, message: "需求名称是必填" }],
validateTrigger: "blur"
},
{
title: "需求类型",
width: 150,
dataIndex: "demandType",
formType: "radio",
search: true,
dict: { name: "demandType", props: { label: "title", value: "key" }, translation: true },
commonRules: [{ required: true, message: "需求类型是必填" }],
validateTrigger: "blur"
},
{
title: "需求描述",
dataIndex: "description",
width: 300,
formType: "editor",
height: 300
}
])
</script>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,187 @@
<template>
<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"></ma-crud>
</div>
</div>
</template>
<script setup>
import { ref } from "vue"
import { useRoute, useRouter } from "vue-router"
import caseApi from "@/api/project/case"
const route = useRoute()
const router = useRouter()
const roundNumber = route.query.key.split("-")[0]
const designDemandNumber = route.query.key.split("-")[1]
const testDemandNumber = route.query.key.split("-")[2]
// crud设置
const crudOptions = ref({
api: caseApi.getCaseList,
parameters: {
projectId: route.query.id,
round: roundNumber,
designDemand: designDemandNumber,
testDemand: testDemandNumber
},
showIndex: false,
rowSelection: { showCheckedAll: true },
add: { show: true },
edit: { show: true },
delete: { show: true },
searchColNumber: 3,
tablePagination: true,
operationColumn: true,
formOption: {
width: 1200,
layout: [
{
formType: "grid",
cols: [
{ span: 12, formList: [{ dataIndex: "ident" }] },
{ span: 12, formList: [{ dataIndex: "name" }] }
]
},
{
formType: "card",
customClass: ["ml-10", "mb-3", "py-0", "px-0"],
title: "人员信息",
formList: [
{
formType: "grid",
cols: [
{ span: 8, formList: [{ dataIndex: "designPerson" }] },
{ span: 8, formList: [{ dataIndex: "testPerson" }] },
{ span: 8, formList: [{ dataIndex: "monitorPerson" }] }
]
}
]
}
]
}
})
const crudColumns = ref([
{
title: "ID",
width: 50,
align: "center",
dataIndex: "id",
fixed: "left"
},
{
title: "标识",
dataIndex: "ident",
width: 140,
align: "center",
search: true,
commonRules: [{ required: true, message: "标识是必填" }],
validateTrigger: "blur"
},
{
title: "名称",
dataIndex: "name",
width: 120,
align: "center",
search: true,
commonRules: [{ required: true, message: "名称是必填" }],
validateTrigger: "blur"
},
{
title: "设计人员",
width: 80,
dataIndex: "designPerson",
align: "center",
search: true,
formType: "select",
commonRules: [{ required: true, message: "设计人员必填" }],
dict: { url: "system/user/index", translation: true, props: { label: "name", value: "name" } }
},
{
title: "执行人员",
dataIndex: "testPerson",
width: 80,
align: "center",
search: true,
formType: "select",
commonRules: [{ required: true, message: "执行人员必填" }],
dict: { url: "system/user/index", translation: true, props: { label: "name", value: "name" } }
},
{
title: "审核人员",
dataIndex: "monitorPerson",
width: 80,
align: "center",
search: true,
formType: "select",
commonRules: [{ required: true, message: "审核人员必填" }],
dict: { url: "system/user/index", translation: true, props: { label: "name", value: "name" } }
},
{
title: "用例综述",
align: "center",
dataIndex: "summarize",
search: true
},
{
title: "用例初始化",
dataIndex: "initialization",
hide: true,
addDefaultValue: "软件正常启动,正常登录进软件"
},
{
title: "前提和约束",
dataIndex: "premise",
hide: true,
addDefaultValue: "软件正常启动,各界面显示工作正常"
},
{
title: "测试步骤",
dataIndex: "testStep",
hide: true,
addDefaultValue: [
{
operation: "",
expect: "",
result: "",
passed: "3",
status: "3"
}
],
formType: "children-form",
type: "group",
formList: [
{
title: "操作",
dataIndex: "operation",
formType: "editor"
},
{
title: "预期",
placeholder: "请输入预期结果",
dataIndex: "expect"
},
{
title: "结果",
dataIndex: "result",
formType: "editor"
},
{
title: "是否通过",
dataIndex: "passed",
formType: "radio",
dict: { name: "passType", props: { label: "title", value: "key" } }
},
{
title: "执行状态",
dataIndex: "status",
formType: "radio",
dict: { name: "execType", props: { label: "title", value: "key" } }
}
]
}
])
</script>
<style lang="less" scoped></style>

View File

@@ -21,7 +21,6 @@ const previewRef = ref(null)
// CRUD-OPTIONS
const crudRef = ref()
const crudOptions = ref({
showIndex: false,
rowSelection: { showCheckedAll: true },
api: projectApi.getPageList,
add: { show: true },