0099
This commit is contained in:
33
cdTMP/package-lock.json
generated
33
cdTMP/package-lock.json
generated
@@ -35,7 +35,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.195",
|
||||
"@types/node": "^22.5.1",
|
||||
"@types/node": "^22.5.2",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/qs": "^6.9.15",
|
||||
"@vitejs/plugin-vue": "^5.1.3",
|
||||
@@ -45,10 +45,10 @@
|
||||
"browserslist": "^4.23.0",
|
||||
"caniuse-lite": "^1.0.30001655",
|
||||
"eslint": "^9.9.1",
|
||||
"eslint-plugin-vue": "^9.27.0",
|
||||
"eslint-plugin-vue": "^9.28.0",
|
||||
"less": "^4.2.0",
|
||||
"less-loader": "^12.2.0",
|
||||
"postcss": "^8.4.42",
|
||||
"postcss": "^8.4.44",
|
||||
"prettier": "^3.3.3",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"typescript": "^5.5.3",
|
||||
@@ -1410,9 +1410,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.5.1",
|
||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.5.1.tgz",
|
||||
"integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==",
|
||||
"version": "22.5.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.5.2.tgz",
|
||||
"integrity": "sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -2747,9 +2747,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-vue": {
|
||||
"version": "9.27.0",
|
||||
"resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.27.0.tgz",
|
||||
"integrity": "sha512-5Dw3yxEyuBSXTzT5/Ge1X5kIkRTQ3nvBn/VwPwInNiZBSJOO/timWMUaflONnFBzU6NhB68lxnCda7ULV5N7LA==",
|
||||
"version": "9.28.0",
|
||||
"resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.28.0.tgz",
|
||||
"integrity": "sha512-ShrihdjIhOTxs+MfWun6oJWuk+g/LAhN+CiuOl/jjkG3l0F2AuK5NMTaWqyvBgkFtpYmyks6P4603mLmhNJW8g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -2758,7 +2758,7 @@
|
||||
"natural-compare": "^1.4.0",
|
||||
"nth-check": "^2.1.1",
|
||||
"postcss-selector-parser": "^6.0.15",
|
||||
"semver": "^7.6.0",
|
||||
"semver": "^7.6.3",
|
||||
"vue-eslint-parser": "^9.4.3",
|
||||
"xml-name-validator": "^4.0.0"
|
||||
},
|
||||
@@ -2785,10 +2785,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-vue/node_modules/semver": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.3.tgz",
|
||||
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
@@ -4349,9 +4350,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.42",
|
||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.42.tgz",
|
||||
"integrity": "sha512-hywKUQB9Ra4dR1mGhldy5Aj1X3MWDSIA1cEi+Uy0CjheLvP6Ual5RlwMCh8i/X121yEDLDIKBsrCQ8ba3FDMfQ==",
|
||||
"version": "8.4.44",
|
||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.44.tgz",
|
||||
"integrity": "sha512-Aweb9unOEpQ3ezu4Q00DPvvM2ZTUitJdNKeP/+uQgr1IBIqu574IaZoURId7BKtWMREwzKa9OgzPzezWGPWFQw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.195",
|
||||
"@types/node": "^22.5.1",
|
||||
"@types/node": "^22.5.2",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/qs": "^6.9.15",
|
||||
"@vitejs/plugin-vue": "^5.1.3",
|
||||
@@ -48,10 +48,10 @@
|
||||
"browserslist": "^4.23.0",
|
||||
"caniuse-lite": "^1.0.30001655",
|
||||
"eslint": "^9.9.1",
|
||||
"eslint-plugin-vue": "^9.27.0",
|
||||
"eslint-plugin-vue": "^9.28.0",
|
||||
"less": "^4.2.0",
|
||||
"less-loader": "^12.2.0",
|
||||
"postcss": "^8.4.42",
|
||||
"postcss": "^8.4.44",
|
||||
"prettier": "^3.3.3",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"typescript": "^5.5.3",
|
||||
|
||||
@@ -76,5 +76,17 @@ export default {
|
||||
method: "get",
|
||||
params
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 请求单个case信息
|
||||
* @params 传入case完整的key
|
||||
* @params 项目id
|
||||
*/
|
||||
getCaseOne(params = {}) {
|
||||
return request({
|
||||
url: "/project/getCaseOne",
|
||||
method: "get",
|
||||
params
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,11 +100,7 @@ const openContextMenu = async (ev, record) => {
|
||||
currentRow.value = record
|
||||
await nextTick(() => {
|
||||
const domHeight = document.querySelector(".ma-crud-contextmenu").offsetHeight
|
||||
if (document.body.offsetHeight - ev.pageY < domHeight) {
|
||||
top.value = ev.clientY - domHeight
|
||||
} else {
|
||||
top.value = ev.clientY
|
||||
}
|
||||
top.value = ev.clientY - domHeight
|
||||
left.value = ev.clientX
|
||||
})
|
||||
}
|
||||
@@ -145,7 +141,7 @@ defineExpose({
|
||||
background: var(--color-bg-2);
|
||||
border: 1px solid var(--color-border-2);
|
||||
padding: 7px 0;
|
||||
border-radius: 1px;
|
||||
border-radius: 4px;
|
||||
li .context-menu-item {
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
|
||||
@@ -36,6 +36,7 @@ import "tinymce/plugins/searchreplace" // 查找替换
|
||||
import "tinymce/plugins/table" // 表格
|
||||
// import "tinymce/plugins/visualblocks" //显示元素范围
|
||||
import "tinymce/plugins/visualchars" // 显示不可见字符
|
||||
import "tinymce/plugins/autoresize" // 自动调整高度
|
||||
import { storeToRefs } from "pinia"
|
||||
// import "tinymce/plugins/wordcount" // 字数统计
|
||||
|
||||
@@ -50,7 +51,7 @@ const props = defineProps({
|
||||
},
|
||||
plugins: {
|
||||
type: [String, Array],
|
||||
default: "searchreplace visualchars code table nonbreaking lists autosave"
|
||||
default: "searchreplace visualchars code table nonbreaking lists autosave autoresize"
|
||||
},
|
||||
toolbar: {
|
||||
type: [String, Array],
|
||||
@@ -142,6 +143,11 @@ const initConfig = reactive({
|
||||
toolbar: props.toolbar,
|
||||
skeletonScreen: true,
|
||||
branding: false,
|
||||
// autoresize插件和resize配置
|
||||
resize: true,
|
||||
min_height: 100,
|
||||
max_height: 600,
|
||||
autoresize_bottom_margin: 10,
|
||||
content_css:
|
||||
theme.value === "dark"
|
||||
? "/tinymce/skins/content/dark/content.css"
|
||||
|
||||
@@ -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>
|
||||
<ma-form-item
|
||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||
|
||||
@@ -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>
|
||||
<ma-form-item
|
||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import role from "./role"
|
||||
|
||||
// 该文件规定如何role不为对应值则删除dom
|
||||
// 用法:vue的指令 -> v-role="['admin']"即只允许userStore里面role属性为admin才能看见
|
||||
const checkRole = (el, binding) => {
|
||||
const { value } = binding
|
||||
|
||||
|
||||
@@ -2,10 +2,7 @@ import { useUserStore } from "@/store"
|
||||
|
||||
const role = (name) => {
|
||||
const userStore = useUserStore()
|
||||
return (
|
||||
(userStore.roles && userStore.roles.includes(name)) ||
|
||||
(userStore.roles && userStore.roles.includes("superAdmin"))
|
||||
)
|
||||
return (userStore.role && userStore.role.includes(name)) || (userStore.role && userStore.role.includes("admin"))
|
||||
}
|
||||
|
||||
export default role
|
||||
|
||||
52
cdTMP/src/hooks/workarea/currentCasePage.ts
Normal file
52
cdTMP/src/hooks/workarea/currentCasePage.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { ref, onMounted } from "vue"
|
||||
import { useRoute } from "vue-router"
|
||||
import caseApi from "@/api/project/case"
|
||||
import { Message } from "@arco-design/web-vue"
|
||||
/**
|
||||
* 用于在组件挂载时,根据route.key/project_id获取当前数据页面的case用例信息
|
||||
*/
|
||||
export default function () {
|
||||
// global
|
||||
const route = useRoute()
|
||||
// ref
|
||||
const tempCaseInfo = ref<any>(null)
|
||||
// 项目id和当前case的key
|
||||
const { id, key } = route.query
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const res = await caseApi.getCaseOne({ key, projectId: id })
|
||||
tempCaseInfo.value = res.data
|
||||
} catch (err) {
|
||||
Message.error("获取用例信息失败,请检查服务器")
|
||||
}
|
||||
})
|
||||
// hook里面判断函数:判断是否该用例未执行或未通过
|
||||
const caseIsNotPassedOrNotExe = function (): boolean {
|
||||
if (tempCaseInfo.value) {
|
||||
const testSteps: any[] = tempCaseInfo.value.testStep
|
||||
if (testSteps.length > 0) {
|
||||
return testSteps.some((it) => it.passed === "2")
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return {
|
||||
tempCaseInfo,
|
||||
caseIsNotPassedOrNotExe
|
||||
}
|
||||
}
|
||||
|
||||
// hook外面判断函数
|
||||
export const caseIsPassed = function (caseInfo: any): boolean {
|
||||
if (caseInfo) {
|
||||
const testSteps: any[] = caseInfo.testStep
|
||||
if (testSteps.length > 0) {
|
||||
return testSteps.some((it) => it.passed === "2")
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
>
|
||||
测试管理平台
|
||||
</a-typography-title>
|
||||
<a-typography-title :heading="6" class="version">V0.0.2</a-typography-title>
|
||||
<a-typography-title :heading="6" class="version">V0.0.3</a-typography-title>
|
||||
<icon-menu-fold
|
||||
v-if="!topMenu && appStore.device === 'mobile'"
|
||||
style="font-size: 22px; cursor: pointer"
|
||||
@@ -30,7 +30,7 @@
|
||||
<ul class="right-side">
|
||||
<li>
|
||||
<a-tooltip content="搜索-暂无">
|
||||
<a-button class="nav-btn" type="outline" :shape="'circle'">
|
||||
<a-button class="nav-btn" type="outline" :shape="'circle'" @click="handleTestBtn">
|
||||
<template #icon>
|
||||
<icon-search />
|
||||
</template>
|
||||
@@ -105,6 +105,15 @@ import { useRouter, useRoute } from "vue-router"
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const appStore = useAppStore()
|
||||
// ~~~测试开始~~~
|
||||
import { useUserStore } from "@/store"
|
||||
const userStore = useUserStore()
|
||||
const handleTestBtn = () => {
|
||||
console.log(userStore.$state)
|
||||
}
|
||||
|
||||
// ~~~测试结束~~~
|
||||
|
||||
// 切换暗黑主题
|
||||
const handleChangeTheme = () => {
|
||||
appStore.toggleTheme()
|
||||
|
||||
@@ -22,7 +22,7 @@ const DASHBOARD = {
|
||||
locale: "工作台",
|
||||
icon: "icon-dashboard",
|
||||
title: "工作台",
|
||||
ignoreCache: true,
|
||||
ignoreCache: true
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -43,7 +43,7 @@ const DASHBOARD = {
|
||||
component: () => import("@/views/dashboard/usermanage/index.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
roles: ["*"],
|
||||
roles: ["admin"], // 只有管理员admin才看得到
|
||||
locale: "用户管理",
|
||||
icon: "icon-user-group",
|
||||
title: "用户管理"
|
||||
|
||||
@@ -9,7 +9,8 @@ const TESTMANAGE = {
|
||||
icon: "icon-desktop",
|
||||
order: 1,
|
||||
locale: "日志监控",
|
||||
title: "日志监控"
|
||||
title: "日志监控",
|
||||
roles: ["admin"] // 只有role=admin的用户才看到该页面
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -18,7 +19,6 @@ const TESTMANAGE = {
|
||||
component: () => import("@/views/monitor/operationLog/index.vue"),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
roles: ["*"],
|
||||
locale: "数据操作日志",
|
||||
icon: "icon-file",
|
||||
title: "数据操作日志"
|
||||
|
||||
@@ -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