0099
This commit is contained in:
@@ -132,7 +132,7 @@ const handleSubmit = async ({ values, errors }) => {
|
||||
...otherQuery // 将退出时的查询参数放入,这样就不会错误
|
||||
}
|
||||
})
|
||||
// 暂时加载LDAP数据
|
||||
// 加载LDAP数据/内网/暂定
|
||||
await userApi.loadLDAPUsers()
|
||||
} else {
|
||||
return
|
||||
|
||||
155
cdTMP/src/views/project/case/components/CaseForm/index.vue
Normal file
155
cdTMP/src/views/project/case/components/CaseForm/index.vue
Normal file
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
width="80%"
|
||||
draggable
|
||||
:okLoading="okLoading"
|
||||
:title="form.name ? form.name : '请填写用例名称'"
|
||||
:on-before-ok="handleOkBefore"
|
||||
>
|
||||
<a-spin :loading="loading" class="w-full h-full">
|
||||
<ma-form :columns="columnsOptions" v-model="form" :options="options" ref="maFormRef"></ma-form>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from "vue"
|
||||
import { type ICaseFormInData } from "../types"
|
||||
import caseApi from "@/api/project/case"
|
||||
import { Message } from "@arco-design/web-vue"
|
||||
|
||||
const visible = ref(false) // 显示和隐藏
|
||||
const loading = ref(false) // 整个modal的加载状态-根据请求case而定
|
||||
const okLoading = ref(false) // 提交按钮的loading状态
|
||||
const form = ref<any>({}) // 表单数据
|
||||
const maFormRef = ref<any>(null)
|
||||
|
||||
// 定义事件
|
||||
const emit = defineEmits(["caseUpdate"])
|
||||
|
||||
// event:点击modal的确定修改按钮
|
||||
const handleOkBefore = async () => {
|
||||
// 验证表单
|
||||
const validateRes = await maFormRef.value.validateForm()
|
||||
if (validateRes) {
|
||||
// 验证不通过
|
||||
return false
|
||||
} else {
|
||||
// 验证通过
|
||||
okLoading.value = true
|
||||
try {
|
||||
await caseApi.update(form.value.id, form.value)
|
||||
okLoading.value = false
|
||||
Message.success("修改用例成功")
|
||||
emit("caseUpdate", form.value)
|
||||
return true
|
||||
} catch (err) {
|
||||
okLoading.value = false
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 暴露组件方法
|
||||
const open = async (formData: ICaseFormInData): Promise<void> => {
|
||||
visible.value = true
|
||||
loading.value = true
|
||||
const res = await caseApi.getCaseList({ id: formData.id })
|
||||
form.value = res.data.items[0]
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
// options
|
||||
const options = ref({
|
||||
showButtons: false
|
||||
})
|
||||
|
||||
// columns
|
||||
const columnsOptions = reactive([
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ title: "用例标识", dataIndex: "ident", disabled: true }] },
|
||||
{
|
||||
span: 12,
|
||||
formList: [{ title: "用例名称", dataIndex: "name", rules: [{ required: true, message: "名称是必填" }] }]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
formType: "card",
|
||||
customClass: ["ml-5", "mb-3", "py-0", "px-0"],
|
||||
title: "人员信息",
|
||||
formList: [
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 8, formList: [{ title: "设计人员", dataIndex: "designPerson" }] },
|
||||
{ span: 8, formList: [{ title: "执行人员", dataIndex: "testPerson" }] },
|
||||
{ span: 8, formList: [{ title: "审核人员", dataIndex: "monitorPerson" }] }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [{ span: 24, formList: [{ title: "用例综述", dataIndex: "summarize" }] }]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [{ span: 24, formList: [{ title: "用例初始化", dataIndex: "initialization" }] }]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ title: "前提与约束", dataIndex: "premise" }] },
|
||||
{ span: 12, formList: [{ title: "执行时间", dataIndex: "exe_time", formType: "date" }] }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "测试步骤",
|
||||
dataIndex: "testStep",
|
||||
formType: "children-form",
|
||||
formList: [
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "operation",
|
||||
formType: "editor",
|
||||
height: 180
|
||||
},
|
||||
{
|
||||
title: "预期",
|
||||
placeholder: "请输入预期结果",
|
||||
dataIndex: "expect"
|
||||
},
|
||||
{
|
||||
title: "结果",
|
||||
dataIndex: "result",
|
||||
formType: "editor",
|
||||
height: 180
|
||||
},
|
||||
{
|
||||
title: "是否通过",
|
||||
dataIndex: "passed",
|
||||
formType: "radio",
|
||||
dict: { name: "passType", props: { label: "title", value: "key" } },
|
||||
rules: [{ required: true, message: "是否通过必填" }]
|
||||
},
|
||||
{
|
||||
title: "执行状态",
|
||||
dataIndex: "status",
|
||||
formType: "radio",
|
||||
dict: { name: "execType", props: { label: "title", value: "key" } },
|
||||
rules: [{ required: true, message: "执行状态必填" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
])
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -5,25 +5,38 @@
|
||||
<div>
|
||||
<a-list>
|
||||
<a-list-item v-for="(item, index) in transformData" :key="index">
|
||||
<a-descriptions :data="item.showData" :title="'用例名称:' + item.case" bordered :column="1" />
|
||||
<div class="text-base mb-2 flex items-center">
|
||||
<div class="flex-auto">用例名称:{{ item.case }}</div>
|
||||
<a-space>
|
||||
<div>
|
||||
<a-button type="primary" shape="round" @click="handleEditClick(item)"
|
||||
>修改用例</a-button
|
||||
>
|
||||
</div>
|
||||
</a-space>
|
||||
</div>
|
||||
<a-descriptions :data="item.showData" bordered :column="1" />
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
</div>
|
||||
<case-form ref="caseFormRef" @caseUpdate="handleCaseUpdate"></case-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue"
|
||||
import CaseForm from "./CaseForm/index.vue"
|
||||
import { type IRelatedCaseItem } from "./types"
|
||||
|
||||
const visible = ref(false)
|
||||
// 数据储存在这里
|
||||
const data = ref([])
|
||||
const data = ref<IRelatedCaseItem[]>([])
|
||||
// 转换为描述数据
|
||||
const transformData = computed(() => {
|
||||
return data.value.map((item) => {
|
||||
// 数组的每一项都要转为{ case:'xxx',showData:[{label:'xxx',value:'xxx2'}] }
|
||||
const showData = []
|
||||
const showData: { label: any; value: any }[] = []
|
||||
for (let key in item) {
|
||||
let showKey = key
|
||||
if (key === "case") continue
|
||||
@@ -42,18 +55,43 @@ const transformData = computed(() => {
|
||||
if (key === "demand_ident") {
|
||||
showKey = "测试项标识"
|
||||
}
|
||||
showData.push({
|
||||
label: showKey,
|
||||
value: item[key]
|
||||
})
|
||||
if (key !== "id") {
|
||||
showData.push({
|
||||
label: showKey,
|
||||
value: item[key]
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
id: item.id,
|
||||
case: item.case,
|
||||
showData
|
||||
}
|
||||
})
|
||||
})
|
||||
function open(caseList) {
|
||||
|
||||
// caseForm相关方法
|
||||
const caseFormRef = ref<InstanceType<typeof CaseForm> | null>(null)
|
||||
const handleEditClick = (item: any): void => {
|
||||
caseFormRef.value!.open(item)
|
||||
}
|
||||
|
||||
// 处理caseForm子组件的case信息更变事件
|
||||
const handleCaseUpdate = (successFormData: any) => {
|
||||
// 更新列表林的数据
|
||||
data.value = data.value.map((it) => {
|
||||
if (it.id === successFormData.id) {
|
||||
return {
|
||||
...it,
|
||||
case: successFormData.name
|
||||
}
|
||||
}
|
||||
return it
|
||||
})
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
function open(caseList: IRelatedCaseItem[]) {
|
||||
visible.value = true
|
||||
data.value = caseList
|
||||
}
|
||||
|
||||
@@ -40,10 +40,11 @@
|
||||
import { ref } from "vue"
|
||||
import problemApi from "@/api/project/problem"
|
||||
import problemSingleApi from "@/api/project/singleProblem"
|
||||
import { Notification } from "@arco-design/web-vue"
|
||||
import { Message, Notification } from "@arco-design/web-vue"
|
||||
import { useRoute } from "vue-router"
|
||||
import CaseModal from "./CaseModal.vue"
|
||||
import useTreeStore from "@/store/project/treeData"
|
||||
import { caseIsPassed } from "@/hooks/workarea/currentCasePage"
|
||||
const route = useRoute()
|
||||
const treeStore = useTreeStore()
|
||||
// 定义props
|
||||
@@ -63,9 +64,19 @@ const emits = defineEmits(["deleted", "relatedOrunrelated"])
|
||||
// ~~~定义关联的switch-值改变处理~~~ 该函数返回false或返回Promise[reject]则停止切换
|
||||
/// 定义个switch的加载loading属性
|
||||
const loading = ref(false)
|
||||
/// 储存打开时赋值的caseInfo
|
||||
const caseInfo = ref(null)
|
||||
const handleRelatedChange = async (record) => {
|
||||
// 因为switch绑定了record.related所以可以动态改变
|
||||
loading.value = true
|
||||
// 判断该用例是否是未通过,如果未执行或已通过则不允许关联问题单
|
||||
if (!caseIsPassed(caseInfo.value)) {
|
||||
Message.error("该用例没有缓存或无未通过步骤,请切换页面或设置未通过步骤后添加问题单!")
|
||||
loading.value = false
|
||||
record.related = !record.related
|
||||
crudRef.value.refresh()
|
||||
return false
|
||||
}
|
||||
const res = await problemApi
|
||||
.relateProblem({
|
||||
case_key: route.query.key,
|
||||
@@ -107,6 +118,8 @@ const open = (row) => {
|
||||
if (props.hasRelated === "relatedProblem") {
|
||||
crudRef.value.requestData() // 手动请求数据
|
||||
visible.value = true
|
||||
// 打开时赋值caseInfo
|
||||
caseInfo.value = row
|
||||
}
|
||||
}
|
||||
// crudOptions设置
|
||||
|
||||
24
cdTMP/src/views/project/case/components/types.ts
Normal file
24
cdTMP/src/views/project/case/components/types.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 接口:从后端请求关联的case信息类型
|
||||
*/
|
||||
export interface IRelatedCaseItem {
|
||||
id: number
|
||||
case: string
|
||||
demand: string
|
||||
demand_ident: string
|
||||
dut: string
|
||||
round: string
|
||||
}
|
||||
|
||||
interface IDescription {
|
||||
label: string
|
||||
value: string
|
||||
}
|
||||
/**
|
||||
* CaseForm传过来数据类型
|
||||
*/
|
||||
export interface ICaseFormInData {
|
||||
id: number
|
||||
case: string
|
||||
showData: IDescription[]
|
||||
}
|
||||
@@ -32,8 +32,12 @@ import problemApi from "@/api/project/problem"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import ProblemChoose from "./components/ProblemChoose.vue"
|
||||
import { Message } from "@arco-design/web-vue"
|
||||
import getCaseInfoHook from "@/hooks/workarea/currentCasePage"
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const route = useRoute()
|
||||
// hook-获取当前用例信息
|
||||
const { tempCaseInfo, caseIsNotPassedOrNotExe } = getCaseInfoHook()
|
||||
|
||||
// const router = useRouter()
|
||||
const roundNumber = route.query.key.split("-")[0]
|
||||
const dutNumber = route.query.key.split("-")[1]
|
||||
@@ -46,7 +50,7 @@ const problemchoose = ref()
|
||||
// ~~~~关联问题单逻辑~~~~
|
||||
//// 点击关联按钮
|
||||
const handleRelatedProblem = () => {
|
||||
problemchoose.value.open()
|
||||
problemchoose.value.open(tempCaseInfo.value)
|
||||
}
|
||||
//// 当关联a-modal删除一个问题单时,通知我刷新表格
|
||||
const related_reload = () => {
|
||||
@@ -62,7 +66,12 @@ const crudOptions = ref({
|
||||
// 列表选项卡配置
|
||||
tabs: {},
|
||||
beforeOpenAdd: function () {
|
||||
// 先判断是否已经有个问题单了,如果有则不让用户创建
|
||||
// 0.判断当前用例的是否为未通过/未执行
|
||||
if (!caseIsNotPassedOrNotExe()) {
|
||||
Message.error("该用例没有缓存或无未通过步骤,请切换页面或设置未通过步骤后添加问题单!")
|
||||
return false
|
||||
}
|
||||
// 1.先判断是否已经有个问题单了,如果有则不让用户创建问题单
|
||||
if (crudRef.value.getTableData().length >= 1) {
|
||||
Message.error("该用例已经存在问题单了,可在轮次树节点右键添加无关联问题单")
|
||||
return false
|
||||
@@ -389,7 +398,7 @@ const crudColumns = ref([
|
||||
title: "开发人员",
|
||||
hide: true,
|
||||
dataIndex: "designerPerson",
|
||||
formType: "input",
|
||||
formType: "input"
|
||||
},
|
||||
{
|
||||
title: "开发方日期",
|
||||
|
||||
@@ -156,7 +156,7 @@ const useCrudInit = function () {
|
||||
search: true,
|
||||
commonRules: [
|
||||
{ required: true, message: "标识是必填" },
|
||||
{ validator: validateBlank, message: "标识格式不正确" },
|
||||
{ validator: validateBlank, message: "标识格式不正确" }
|
||||
// { validator: validateWindowFileNameInput }
|
||||
],
|
||||
validateTrigger: "blur"
|
||||
@@ -243,7 +243,7 @@ const useCrudInit = function () {
|
||||
title: "软件类型",
|
||||
dataIndex: "soft_type",
|
||||
hide: true,
|
||||
search: true,
|
||||
search: false,
|
||||
formType: "select",
|
||||
dict: {
|
||||
data: [
|
||||
@@ -477,6 +477,21 @@ const useCrudInit = function () {
|
||||
props: { label: "title", value: "key" },
|
||||
tagColors: { 1: "green", 2: "blue", 3: "red", 4: "yellow" }
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "密级",
|
||||
align: "center",
|
||||
dataIndex: "secret",
|
||||
search: true,
|
||||
hide: true,
|
||||
formType: "radio",
|
||||
addDefaultValue: "1",
|
||||
addDisabled: true,
|
||||
dict: {
|
||||
name: "secret",
|
||||
translation: true,
|
||||
props: { label: "title", value: "key" }
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
|
||||
@@ -110,12 +110,14 @@
|
||||
|
||||
<script lang="jsx" setup>
|
||||
import { ref } from "vue"
|
||||
import { useRouter } from "vue-router"
|
||||
import preview from "./cpns/preview.vue"
|
||||
import Progress from "./cpns/progress.vue"
|
||||
import useEnterWorkPlant from "./hooks/useEnterWorkPlant"
|
||||
import useSeitaiModal from "./hooks/useSeitaiModal"
|
||||
import useGenerateSecond from "./hooks/useGenerateSecond"
|
||||
import useCrudInit from "./hooks/useCrudInit"
|
||||
const router = useRouter()
|
||||
// crud配置和字段信息定义
|
||||
const { crudRef, crudOptions, crudColumns } = useCrudInit()
|
||||
// 点击进入工作区函数 - 每次点击后都清除localStorage中树状目录数据
|
||||
|
||||
Reference in New Issue
Block a user