0.0.2
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "cdtmp",
|
"name": "cdtmp",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import qs, { stringify } from "qs"
|
|||||||
import { h } from "vue"
|
import { h } from "vue"
|
||||||
import { IconFaceFrownFill } from "@arco-design/web-vue/dist/arco-vue-icon"
|
import { IconFaceFrownFill } from "@arco-design/web-vue/dist/arco-vue-icon"
|
||||||
|
|
||||||
// createService
|
// 创建axios实例,添加请求和响应拦截器,返回该axios实例
|
||||||
function createService() {
|
function createService() {
|
||||||
// 创建axios实例
|
// 创建axios实例
|
||||||
const service = axios.create()
|
const service = axios.create()
|
||||||
@@ -21,7 +21,6 @@ function createService() {
|
|||||||
// 实例的response响应拦截器
|
// 实例的response响应拦截器
|
||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(res) => {
|
(res) => {
|
||||||
// 如果发现响应头有文件传输扩展,或者响应头为application/json,或者直接status=200
|
|
||||||
if (
|
if (
|
||||||
(res.headers["content-disposition"] || !/^application\/json/.test(res.headers["content-type"])) &&
|
(res.headers["content-disposition"] || !/^application\/json/.test(res.headers["content-type"])) &&
|
||||||
res.status === 200
|
res.status === 200
|
||||||
@@ -33,17 +32,15 @@ function createService() {
|
|||||||
res.data.message = "服务器内部错误"
|
res.data.message = "服务器内部错误"
|
||||||
res.data.success = false
|
res.data.success = false
|
||||||
} else if (res.data.code && res.data.code !== 200) {
|
} else if (res.data.code && res.data.code !== 200) {
|
||||||
|
// 如果data里面code字段不为200
|
||||||
Message.error({
|
Message.error({
|
||||||
content: res.data.message,
|
content: res.data.message,
|
||||||
// 注意奇怪的用法
|
|
||||||
icon: () => h(IconFaceFrownFill)
|
icon: () => h(IconFaceFrownFill)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return res.data
|
return res.data
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
// 其实基本逻辑是有message写message
|
|
||||||
// 没用message再去找默认的response的status
|
|
||||||
const err = (text) => {
|
const err = (text) => {
|
||||||
Message.error({
|
Message.error({
|
||||||
content:
|
content:
|
||||||
@@ -79,6 +76,7 @@ function createService() {
|
|||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
err("未知错误!")
|
err("未知错误!")
|
||||||
|
break
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err("请求超时,服务器无响应!")
|
err("请求超时,服务器无响应!")
|
||||||
@@ -96,7 +94,6 @@ function createService() {
|
|||||||
function createRequest(service) {
|
function createRequest(service) {
|
||||||
return function (config) {
|
return function (config) {
|
||||||
const env = import.meta.env
|
const env = import.meta.env
|
||||||
// localStorage获取token信息
|
|
||||||
const token = tool.local.get(env.VITE_APP_TOKEN_PREFIX)
|
const token = tool.local.get(env.VITE_APP_TOKEN_PREFIX)
|
||||||
const configDefault = {
|
const configDefault = {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -108,12 +105,7 @@ function createRequest(service) {
|
|||||||
baseURL: env.VITE_APP_OPEN_PROXY === "true" ? env.VITE_APP_PROXY_PREFIX : env.VITE_APP_BASE_URL,
|
baseURL: env.VITE_APP_OPEN_PROXY === "true" ? env.VITE_APP_PROXY_PREFIX : env.VITE_APP_BASE_URL,
|
||||||
data: {}
|
data: {}
|
||||||
}
|
}
|
||||||
// option是configDefault和传入的config合并
|
|
||||||
const option = Object.assign(configDefault, config)
|
const option = Object.assign(configDefault, config)
|
||||||
// lodash的isEmpty函数可以判断对象属性是否为空/数组是否为空->为空则返回true
|
|
||||||
// qs中stringfy作用是urlencode
|
|
||||||
// { c: 'b', a: 'd' } -> 'c=b&a=d'
|
|
||||||
// 如果有params就转为urlencode样子
|
|
||||||
if (!isEmpty(option.params)) {
|
if (!isEmpty(option.params)) {
|
||||||
option.url = option.url + "?" + stringify(option.params)
|
option.url = option.url + "?" + stringify(option.params)
|
||||||
option.params = {}
|
option.params = {}
|
||||||
@@ -122,7 +114,5 @@ function createRequest(service) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上面两个函数一个为增加实例拦截器,一个是传入实例后请求
|
|
||||||
export const service = createService()
|
export const service = createService()
|
||||||
// 返回的是一个函数,这个函数传入config然后添加上默认config然后发出实例的请求
|
|
||||||
export const request = createRequest(service)
|
export const request = createRequest(service)
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<!-- add:on-before-cancel -->
|
||||||
<component
|
<component
|
||||||
:is="componentName"
|
:is="componentName"
|
||||||
v-model:visible="dataVisible"
|
v-model:visible="dataVisible"
|
||||||
:on-before-ok="submit"
|
:on-before-ok="submit"
|
||||||
|
:on-before-cancel="beforeCancel"
|
||||||
@cancel="close"
|
@cancel="close"
|
||||||
ok-text="保存"
|
ok-text="保存"
|
||||||
cancel-text="关闭"
|
cancel-text="关闭"
|
||||||
@@ -46,7 +48,7 @@ const dataVisible = ref(false)
|
|||||||
const form = ref({})
|
const form = ref({})
|
||||||
const actionTitle = ref("")
|
const actionTitle = ref("")
|
||||||
const dataLoading = ref(true)
|
const dataLoading = ref(true)
|
||||||
const emit = defineEmits(["success", "error"])
|
const emit = defineEmits(["success", "error", "beforeCancel"])
|
||||||
|
|
||||||
provide("form", toRaw(form))
|
provide("form", toRaw(form))
|
||||||
|
|
||||||
@@ -134,6 +136,11 @@ const open = () => {
|
|||||||
dataVisible.value = true
|
dataVisible.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ~~~~addMethod~~~~
|
||||||
|
const beforeCancel = () => {
|
||||||
|
emit("beforeCancel")
|
||||||
|
return true
|
||||||
|
}
|
||||||
const close = () => {
|
const close = () => {
|
||||||
dataVisible.value = false
|
dataVisible.value = false
|
||||||
formColumns.value = []
|
formColumns.value = []
|
||||||
|
|||||||
@@ -140,7 +140,7 @@
|
|||||||
class="ma-crud-table-tr"
|
class="ma-crud-table-tr"
|
||||||
:class="
|
:class="
|
||||||
isFunction(options.rowCustomClass)
|
isFunction(options.rowCustomClass)
|
||||||
? options.rowCustomClass(record, rowIndex) ?? []
|
? (options.rowCustomClass(record, rowIndex) ?? [])
|
||||||
: options.rowCustomClass
|
: options.rowCustomClass
|
||||||
"
|
"
|
||||||
@contextmenu.prevent="openContextMenu($event, record)"
|
@contextmenu.prevent="openContextMenu($event, record)"
|
||||||
@@ -215,7 +215,7 @@
|
|||||||
|
|
||||||
<ma-setting ref="crudSettingRef" />
|
<ma-setting ref="crudSettingRef" />
|
||||||
|
|
||||||
<ma-form ref="crudFormRef" @success="requestSuccess">
|
<ma-form ref="crudFormRef" @success="requestSuccess" v-bind="$attrs">
|
||||||
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
||||||
<slot :name="slot" v-bind="component" />
|
<slot :name="slot" v-bind="component" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
>
|
>
|
||||||
测试管理平台
|
测试管理平台
|
||||||
</a-typography-title>
|
</a-typography-title>
|
||||||
<a-typography-title :heading="6" class="version">V0.0.1</a-typography-title>
|
<a-typography-title :heading="6" class="version">V0.0.2</a-typography-title>
|
||||||
<icon-menu-fold
|
<icon-menu-fold
|
||||||
v-if="!topMenu && appStore.device === 'mobile'"
|
v-if="!topMenu && appStore.device === 'mobile'"
|
||||||
style="font-size: 22px; cursor: pointer"
|
style="font-size: 22px; cursor: pointer"
|
||||||
@@ -22,9 +22,7 @@
|
|||||||
<div class="center-side flex items-center justify-center font-bold text-lg">
|
<div class="center-side flex items-center justify-center font-bold text-lg">
|
||||||
<template v-if="title">
|
<template v-if="title">
|
||||||
<a-typography-title :style="{ margin: 0, fontSize: '1.1rem', fontWeight: 'bold' }" :heading="4">
|
<a-typography-title :style="{ margin: 0, fontSize: '1.1rem', fontWeight: 'bold' }" :heading="4">
|
||||||
项目名称:{{ $route.query.ident }}-{{ title }}- key的值为:{{
|
项目名称:{{ $route.query.ident }}-{{ title }}
|
||||||
route.query.key ? route.query.key : "无key值"
|
|
||||||
}}
|
|
||||||
</a-typography-title>
|
</a-typography-title>
|
||||||
</template>
|
</template>
|
||||||
<Menu v-if="topMenu"></Menu>
|
<Menu v-if="topMenu"></Menu>
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ const router = createRouter({
|
|||||||
component: () => import("@/views/project/round/index.vue"),
|
component: () => import("@/views/project/round/index.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
ignoreCache: true,
|
||||||
roles: ["*"],
|
roles: ["*"],
|
||||||
locale: "轮次信息",
|
locale: "轮次信息",
|
||||||
icon: "icon-arrow-right"
|
icon: "icon-arrow-right"
|
||||||
@@ -51,6 +52,7 @@ const router = createRouter({
|
|||||||
component: () => import("@/views/project/dut/index.vue"),
|
component: () => import("@/views/project/dut/index.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
ignoreCache: true,
|
||||||
roles: ["*"],
|
roles: ["*"],
|
||||||
locale: "被测件信息",
|
locale: "被测件信息",
|
||||||
icon: "icon-arrow-right"
|
icon: "icon-arrow-right"
|
||||||
@@ -62,6 +64,7 @@ const router = createRouter({
|
|||||||
component: () => import("@/views/project/design-demand/index.vue"),
|
component: () => import("@/views/project/design-demand/index.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
ignoreCache: true,
|
||||||
roles: ["*"],
|
roles: ["*"],
|
||||||
locale: "设计需求",
|
locale: "设计需求",
|
||||||
icon: "icon-arrow-right"
|
icon: "icon-arrow-right"
|
||||||
@@ -73,6 +76,7 @@ const router = createRouter({
|
|||||||
component: () => import("@/views/project/testDemand/index.vue"),
|
component: () => import("@/views/project/testDemand/index.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
ignoreCache: true,
|
||||||
roles: ["*"],
|
roles: ["*"],
|
||||||
locale: "测试需求",
|
locale: "测试需求",
|
||||||
icon: "icon-arrow-right"
|
icon: "icon-arrow-right"
|
||||||
@@ -84,6 +88,7 @@ const router = createRouter({
|
|||||||
component: () => import("@/views/project/case/index.vue"),
|
component: () => import("@/views/project/case/index.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
ignoreCache: true,
|
||||||
roles: ["*"],
|
roles: ["*"],
|
||||||
locale: "测试用例",
|
locale: "测试用例",
|
||||||
icon: "icon-arrow-right"
|
icon: "icon-arrow-right"
|
||||||
@@ -95,6 +100,7 @@ const router = createRouter({
|
|||||||
component: () => import("@/views/project/problem/index.vue"),
|
component: () => import("@/views/project/problem/index.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
ignoreCache: true,
|
||||||
roles: ["*"],
|
roles: ["*"],
|
||||||
locale: "问题单详情",
|
locale: "问题单详情",
|
||||||
icon: "icon-arrow-right"
|
icon: "icon-arrow-right"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</a-card>
|
</a-card>
|
||||||
<div class="mt-2">管理平台版本</div>
|
<div class="mt-2">管理平台版本</div>
|
||||||
<a-tag class="mt-2" color="#0fc6c2">TestManagePlant V0.0.1</a-tag>
|
<a-tag class="mt-2" color="#0fc6c2">TestManagePlant V0.0.2</a-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
43
cdTMP/src/views/datamanage/dictmanage/DataList/index.vue
Normal file
43
cdTMP/src/views/datamanage/dictmanage/DataList/index.vue
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal v-model:visible="visible" width="80%" draggable :footer="false">
|
||||||
|
<template #title>维护数据字典 →【{{ currentRow.name }}】</template>
|
||||||
|
<!-- crud组件 -->
|
||||||
|
<div class="lg:w-full w-full lg:mt-0">
|
||||||
|
<ma-crud :options="crudOptions" :columns="columns" ref="crudRef">
|
||||||
|
<!-- 排序列 -->
|
||||||
|
<template #sort="{ record }">
|
||||||
|
<a-input-number
|
||||||
|
:default-value="record.sort"
|
||||||
|
mode="button"
|
||||||
|
@change="changeSort($event, record.id)"
|
||||||
|
:min="0"
|
||||||
|
:max="1000"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<!-- 状态列 -->
|
||||||
|
<template #status="{ record }">
|
||||||
|
<a-switch
|
||||||
|
:checked-value="1"
|
||||||
|
unchecked-value="2"
|
||||||
|
@change="changeStatus($event, record.id)"
|
||||||
|
:default-checked="record.status == 1"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</ma-crud>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue"
|
||||||
|
import useCrudRef from "./useCrudRef"
|
||||||
|
import useOpenChangeModal from "./useOpenChangeModal"
|
||||||
|
|
||||||
|
const currentRow = ref({ id: undefined, name: undefined }) // 当前选择的行
|
||||||
|
const { crudRef, crudOptions, columns } = useCrudRef(currentRow)
|
||||||
|
const { visible, changeSort, changeStatus, open } = useOpenChangeModal(crudRef, currentRow)
|
||||||
|
// 暴露自己的open方法
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
120
cdTMP/src/views/datamanage/dictmanage/DataList/useCrudRef.ts
Normal file
120
cdTMP/src/views/datamanage/dictmanage/DataList/useCrudRef.ts
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import { ref, type Ref } from "vue"
|
||||||
|
import dictApi from "@/api/system/dict"
|
||||||
|
/**
|
||||||
|
* 定义crud的ref以及其
|
||||||
|
*/
|
||||||
|
export default function useCrudRef(currentRow: Ref<{ id: number | string; name: string }>) {
|
||||||
|
const crudRef = ref()
|
||||||
|
// crud选项
|
||||||
|
const crudOptions = ref({
|
||||||
|
autoRequest: false,
|
||||||
|
api: dictApi.getDictItemAll,
|
||||||
|
showIndex: false,
|
||||||
|
rowSelection: { showCheckedAll: true },
|
||||||
|
operationColumn: true,
|
||||||
|
operationWidth: 160,
|
||||||
|
operationColumnAlign: "center",
|
||||||
|
showTools: false,
|
||||||
|
beforeAdd: (form: any) => {
|
||||||
|
form.id = currentRow.value?.id
|
||||||
|
},
|
||||||
|
add: { show: true, api: dictApi.saveDictItem },
|
||||||
|
edit: { show: true, api: dictApi.updateDictItemData },
|
||||||
|
delete: { show: true, api: dictApi.realDeleteItem },
|
||||||
|
afterDelete(response) {
|
||||||
|
crudRef.value.tableRef.selectAll(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// crudColumns
|
||||||
|
const columns = ref([
|
||||||
|
{ title: "ID", dataIndex: "id", addDisplay: false, editDisplay: false, width: 50, hide: true },
|
||||||
|
{
|
||||||
|
title: "字典标签",
|
||||||
|
align: "center",
|
||||||
|
dataIndex: "title",
|
||||||
|
search: true,
|
||||||
|
width: 150,
|
||||||
|
commonRules: [{ required: true, message: "字典标签必填" }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "字段缩写",
|
||||||
|
dataIndex: "show_title",
|
||||||
|
align: "center",
|
||||||
|
search: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "字典键值",
|
||||||
|
align: "center",
|
||||||
|
dataIndex: "key",
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
search: true,
|
||||||
|
commonRules: [{ required: true, message: "字典键值必填" }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "排序",
|
||||||
|
align: "center",
|
||||||
|
dataIndex: "sort",
|
||||||
|
formType: "input-number",
|
||||||
|
addDefaultValue: 1,
|
||||||
|
width: 130,
|
||||||
|
min: 0,
|
||||||
|
max: 1000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "状态",
|
||||||
|
align: "center",
|
||||||
|
dataIndex: "status",
|
||||||
|
search: true,
|
||||||
|
addDefaultValue: "1",
|
||||||
|
formType: "radio",
|
||||||
|
dict: { name: "data_status", props: { label: "title", value: "key" } },
|
||||||
|
width: 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "备注",
|
||||||
|
align: "center",
|
||||||
|
dataIndex: "remark",
|
||||||
|
hide: true,
|
||||||
|
formType: "textarea"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "更新时间",
|
||||||
|
align: "center",
|
||||||
|
dataIndex: "update_datetime",
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
search: true,
|
||||||
|
formType: "range",
|
||||||
|
width: 110
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "文档名称",
|
||||||
|
dataIndex: "doc_name",
|
||||||
|
align: "center",
|
||||||
|
search: false,
|
||||||
|
placeholder: "如果不是标准则不填"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "发布日期",
|
||||||
|
dataIndex: "publish_date",
|
||||||
|
align: "center",
|
||||||
|
search: false,
|
||||||
|
placeholder: "如果不是标准则不填"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "标准来源",
|
||||||
|
dataIndex: "source",
|
||||||
|
align: "center",
|
||||||
|
search: false,
|
||||||
|
placeholder: "如果不是标准则不填"
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
return {
|
||||||
|
crudRef,
|
||||||
|
crudOptions,
|
||||||
|
columns
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import { ref, type Ref } from "vue"
|
||||||
|
import dictApi from "@/api/system/dict"
|
||||||
|
import { Message } from "@arco-design/web-vue"
|
||||||
|
import MaCrud from "@/components/ma-crud/index.vue"
|
||||||
|
/**
|
||||||
|
* 1.打开该modal方法/改变状态/改变排序
|
||||||
|
*/
|
||||||
|
export default function useOpenChangeModal(crudRef: Ref<InstanceType<typeof MaCrud>>, currentRow: Ref<any>) {
|
||||||
|
// refs
|
||||||
|
const visible = ref(false)
|
||||||
|
// 事件处理
|
||||||
|
const changeSort = async (value: number, id: number): Promise<void> => {
|
||||||
|
const response = await dictApi.numberOperation({ id, numberName: "sort", numberValue: value })
|
||||||
|
response.success && Message.success(response.message)
|
||||||
|
crudRef.value.refresh()
|
||||||
|
}
|
||||||
|
const changeStatus = async (status: number | string, id: number): Promise<void> => {
|
||||||
|
const response = await dictApi.changeItemStatus({ id, status })
|
||||||
|
if (response.success) {
|
||||||
|
Message.success(response.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 定义该open方法并暴露给组件外部
|
||||||
|
// 打开a-modal事件
|
||||||
|
const open = (row: Ref<any>) => {
|
||||||
|
currentRow.value = row
|
||||||
|
// 调用固定方法请求数据
|
||||||
|
crudRef.value.requestParams = { id: currentRow.value.id }
|
||||||
|
crudRef.value.requestData()
|
||||||
|
visible.value = true
|
||||||
|
// 判断如果是行数据的code值为standard则不显示‘文档名称’‘发布来源’‘发布日期’,且表单也不显示
|
||||||
|
// columnService可以动态设置表格列的属性!!!
|
||||||
|
const columnService = crudRef.value.getColumnService()
|
||||||
|
if (currentRow.value.code === "standard") {
|
||||||
|
columnService.get("doc_name").setAttr("hide", false)
|
||||||
|
columnService.get("publish_date").setAttr("hide", false)
|
||||||
|
columnService.get("source").setAttr("hide", false)
|
||||||
|
columnService.get("doc_name").setAttr("addDisplay", true)
|
||||||
|
columnService.get("publish_date").setAttr("addDisplay", true)
|
||||||
|
columnService.get("source").setAttr("addDisplay", true)
|
||||||
|
columnService.get("doc_name").setAttr("editDisplay", true)
|
||||||
|
columnService.get("publish_date").setAttr("editDisplay", true)
|
||||||
|
columnService.get("source").setAttr("editDisplay", true)
|
||||||
|
} else {
|
||||||
|
columnService.get("doc_name").setAttr("hide", true)
|
||||||
|
columnService.get("publish_date").setAttr("hide", true)
|
||||||
|
columnService.get("source").setAttr("hide", true)
|
||||||
|
columnService.get("doc_name").setAttr("addDisplay", false)
|
||||||
|
columnService.get("publish_date").setAttr("addDisplay", false)
|
||||||
|
columnService.get("source").setAttr("addDisplay", false)
|
||||||
|
columnService.get("doc_name").setAttr("editDisplay", false)
|
||||||
|
columnService.get("publish_date").setAttr("editDisplay", false)
|
||||||
|
columnService.get("source").setAttr("editDisplay", false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
visible,
|
||||||
|
changeSort,
|
||||||
|
changeStatus,
|
||||||
|
open
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,197 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-modal v-model:visible="visible" width="auto" draggable :footer="false">
|
|
||||||
<template #title>维护数据字典 →【{{ currentRow.name }}】</template>
|
|
||||||
<!-- crud组件 -->
|
|
||||||
<div class="lg:w-full w-full lg:mt-0">
|
|
||||||
<ma-crud :options="crudOptions" :columns="columns" ref="crudRef">
|
|
||||||
<!-- 排序列 -->
|
|
||||||
<template #sort="{ record }">
|
|
||||||
<a-input-number
|
|
||||||
:default-value="record.sort"
|
|
||||||
mode="button"
|
|
||||||
@change="changeSort($event, record.id)"
|
|
||||||
:min="0"
|
|
||||||
:max="1000"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<!-- 状态列 -->
|
|
||||||
<template #status="{ record }">
|
|
||||||
<a-switch
|
|
||||||
:checked-value="1"
|
|
||||||
unchecked-value="2"
|
|
||||||
@change="changeStatus($event, record.id)"
|
|
||||||
:default-checked="record.status == 1"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</ma-crud>
|
|
||||||
</div>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref } from "vue"
|
|
||||||
import dictApi from "@/api/system/dict"
|
|
||||||
import { Message } from "@arco-design/web-vue"
|
|
||||||
|
|
||||||
const crudRef = ref()
|
|
||||||
const visible = ref(false)
|
|
||||||
const currentRow = ref({ id: undefined, name: undefined })
|
|
||||||
|
|
||||||
// 改变dictItem的sort字段
|
|
||||||
const changeSort = async (value, id) => {
|
|
||||||
const response = await dictApi.numberOperation({ id, numberName: "sort", numberValue: value })
|
|
||||||
response.success && Message.success(response.message)
|
|
||||||
crudRef.value.refresh()
|
|
||||||
}
|
|
||||||
// 改变dictItem状态
|
|
||||||
const changeStatus = async (status, id) => {
|
|
||||||
const response = await dictApi.changeItemStatus({ id, status })
|
|
||||||
if (response.success) {
|
|
||||||
Message.success(response.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 打开a-modal事件
|
|
||||||
const open = (row) => {
|
|
||||||
currentRow.value = row
|
|
||||||
// 调用固定方法请求数据
|
|
||||||
crudRef.value.requestParams = { id: currentRow.value.id }
|
|
||||||
crudRef.value.requestData()
|
|
||||||
visible.value = true
|
|
||||||
// 判断如果是行数据的code值为standard则不显示‘文档名称’‘发布来源’‘发布日期’,且表单也不显示
|
|
||||||
// columnService可以动态设置表格列的属性!!!
|
|
||||||
const columnService = crudRef.value.getColumnService()
|
|
||||||
if (currentRow.value.code === "standard") {
|
|
||||||
columnService.get("doc_name").setAttr("hide", false)
|
|
||||||
columnService.get("publish_date").setAttr("hide", false)
|
|
||||||
columnService.get("source").setAttr("hide", false)
|
|
||||||
columnService.get("doc_name").setAttr("addDisplay", true)
|
|
||||||
columnService.get("publish_date").setAttr("addDisplay", true)
|
|
||||||
columnService.get("source").setAttr("addDisplay", true)
|
|
||||||
columnService.get("doc_name").setAttr("editDisplay", true)
|
|
||||||
columnService.get("publish_date").setAttr("editDisplay", true)
|
|
||||||
columnService.get("source").setAttr("editDisplay", true)
|
|
||||||
} else {
|
|
||||||
columnService.get("doc_name").setAttr("hide", true)
|
|
||||||
columnService.get("publish_date").setAttr("hide", true)
|
|
||||||
columnService.get("source").setAttr("hide", true)
|
|
||||||
columnService.get("doc_name").setAttr("addDisplay", false)
|
|
||||||
columnService.get("publish_date").setAttr("addDisplay", false)
|
|
||||||
columnService.get("source").setAttr("addDisplay", false)
|
|
||||||
columnService.get("doc_name").setAttr("editDisplay", false)
|
|
||||||
columnService.get("publish_date").setAttr("editDisplay", false)
|
|
||||||
columnService.get("source").setAttr("editDisplay", false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// crud选项
|
|
||||||
const crudOptions = ref({
|
|
||||||
autoRequest: false,
|
|
||||||
api: dictApi.getDictItemAll,
|
|
||||||
showIndex: false,
|
|
||||||
rowSelection: { showCheckedAll: true },
|
|
||||||
operationColumn: true,
|
|
||||||
operationWidth: 160,
|
|
||||||
operationColumnAlign: "center",
|
|
||||||
showTools: false,
|
|
||||||
beforeAdd: (form) => {
|
|
||||||
form.id = currentRow.value?.id
|
|
||||||
},
|
|
||||||
add: { show: true, api: dictApi.saveDictItem },
|
|
||||||
edit: { show: true, api: dictApi.updateDictItemData },
|
|
||||||
delete: { show: true, api: dictApi.realDeleteItem },
|
|
||||||
afterDelete(response) {
|
|
||||||
crudRef.value.tableRef.selectAll(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// crudColumns
|
|
||||||
const columns = ref([
|
|
||||||
{ title: "ID", dataIndex: "id", addDisplay: false, editDisplay: false, width: 50, hide: true },
|
|
||||||
{
|
|
||||||
title: "字典标签",
|
|
||||||
align: "center",
|
|
||||||
dataIndex: "title",
|
|
||||||
search: true,
|
|
||||||
width: 150,
|
|
||||||
commonRules: [{ required: true, message: "字典标签必填" }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "字段缩写",
|
|
||||||
dataIndex: "show_title",
|
|
||||||
align: "center",
|
|
||||||
search: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "字典键值",
|
|
||||||
align: "center",
|
|
||||||
dataIndex: "key",
|
|
||||||
addDisplay: false,
|
|
||||||
editDisplay: false,
|
|
||||||
search: true,
|
|
||||||
commonRules: [{ required: true, message: "字典键值必填" }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "排序",
|
|
||||||
align: "center",
|
|
||||||
dataIndex: "sort",
|
|
||||||
formType: "input-number",
|
|
||||||
addDefaultValue: 1,
|
|
||||||
width: 130,
|
|
||||||
min: 0,
|
|
||||||
max: 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "状态",
|
|
||||||
align: "center",
|
|
||||||
dataIndex: "status",
|
|
||||||
search: true,
|
|
||||||
addDefaultValue: "1",
|
|
||||||
formType: "radio",
|
|
||||||
dict: { name: "data_status", props: { label: "title", value: "key" } },
|
|
||||||
width: 70
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "备注",
|
|
||||||
align: "center",
|
|
||||||
dataIndex: "remark",
|
|
||||||
hide: true,
|
|
||||||
formType: "textarea"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "更新时间",
|
|
||||||
align: "center",
|
|
||||||
dataIndex: "update_datetime",
|
|
||||||
addDisplay: false,
|
|
||||||
editDisplay: false,
|
|
||||||
search: true,
|
|
||||||
formType: "range",
|
|
||||||
width: 110
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "文档名称",
|
|
||||||
dataIndex: "doc_name",
|
|
||||||
align: "center",
|
|
||||||
search: false,
|
|
||||||
placeholder: "如果不是标准则不填"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "发布日期",
|
|
||||||
dataIndex: "publish_date",
|
|
||||||
align: "center",
|
|
||||||
search: false,
|
|
||||||
placeholder: "如果不是标准则不填"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "标准来源",
|
|
||||||
dataIndex: "source",
|
|
||||||
align: "center",
|
|
||||||
search: false,
|
|
||||||
placeholder: "如果不是标准则不填"
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
// 暴露自己的open方法
|
|
||||||
defineExpose({ open })
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
|
||||||
@@ -32,88 +32,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="jsx">
|
<script setup lang="jsx">
|
||||||
import { ref } from "vue"
|
import DataList from "./DataList/index.vue"
|
||||||
import dictApi from "@/api/system/dict"
|
import useDictCrud from "./useDictCrud"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import useDataListRef from "./useDataListRef"
|
||||||
import DataList from "./dataList.vue"
|
// 1.useDictCrud
|
||||||
|
const { crudRef, changeStatus, crudOptions, crudColumns } = useDictCrud()
|
||||||
const crudRef = ref()
|
// 2.dataList.vue界面打开和ref定义
|
||||||
const datalistRef = ref()
|
const { datalistRef, openDictList } = useDataListRef()
|
||||||
|
|
||||||
// 打开datalist页面
|
|
||||||
const openDictList = async (row) => {
|
|
||||||
datalistRef.value.open(row)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 点击切换status
|
|
||||||
const changeStatus = async (status, id) => {
|
|
||||||
const response = await dictApi.changeStatus({ id, status })
|
|
||||||
if (response.success) {
|
|
||||||
Message.success(response.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const crudOptions = ref({
|
|
||||||
api: dictApi.getDictIndex,
|
|
||||||
showIndex: false,
|
|
||||||
operationColumnAlign: "center",
|
|
||||||
rowSelection: { showCheckedAll: true },
|
|
||||||
searchColNumber: 4,
|
|
||||||
tablePagination: false,
|
|
||||||
operationColumn: true,
|
|
||||||
showTools: false,
|
|
||||||
afterDelete(response) {
|
|
||||||
crudRef.value.tableRef.selectAll(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const crudColumns = ref([
|
|
||||||
{ title: "ID", dataIndex: "id", addDisplay: false, editDisplay: false, width: 50, hide: true },
|
|
||||||
{
|
|
||||||
title: "字典备注",
|
|
||||||
dataIndex: "remark",
|
|
||||||
search: true,
|
|
||||||
width: 220,
|
|
||||||
align: "center",
|
|
||||||
commonRules: [{ required: true, message: "字典备注必填" }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "字典标识",
|
|
||||||
dataIndex: "code",
|
|
||||||
search: true,
|
|
||||||
width: 260,
|
|
||||||
align: "center",
|
|
||||||
commonRules: [{ required: true, message: "字典标识必填" }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "状态",
|
|
||||||
dataIndex: "status",
|
|
||||||
search: true,
|
|
||||||
formType: "radio",
|
|
||||||
align: "center",
|
|
||||||
dict: { name: "data_status", props: { label: "title", value: "key" } },
|
|
||||||
addDefaultValue: "1",
|
|
||||||
width: 180
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "字典名称",
|
|
||||||
dataIndex: "name",
|
|
||||||
hide: true,
|
|
||||||
formType: "textarea",
|
|
||||||
align: "center"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "更新时间",
|
|
||||||
dataIndex: "update_datetime",
|
|
||||||
addDisplay: false,
|
|
||||||
editDisplay: false,
|
|
||||||
align: "center",
|
|
||||||
search: true,
|
|
||||||
formType: "range",
|
|
||||||
width: 180
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "dictmanage"
|
name: "dictmanage"
|
||||||
})
|
})
|
||||||
|
|||||||
15
cdTMP/src/views/datamanage/dictmanage/useDataListRef.ts
Normal file
15
cdTMP/src/views/datamanage/dictmanage/useDataListRef.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { ref } from "vue"
|
||||||
|
/**
|
||||||
|
* 该hook仅定义dataList的ref以及调用open函数
|
||||||
|
*/
|
||||||
|
export default function useDataListRef() {
|
||||||
|
const datalistRef = ref()
|
||||||
|
// 打开datalist页面
|
||||||
|
const openDictList = async (row: object) => {
|
||||||
|
datalistRef.value.open(row)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
datalistRef,
|
||||||
|
openDictList
|
||||||
|
}
|
||||||
|
}
|
||||||
89
cdTMP/src/views/datamanage/dictmanage/useDictCrud.ts
Normal file
89
cdTMP/src/views/datamanage/dictmanage/useDictCrud.ts
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import { ref } from "vue"
|
||||||
|
import dictApi from "@/api/system/dict"
|
||||||
|
import { Message } from "@arco-design/web-vue"
|
||||||
|
/**
|
||||||
|
* dict主页面展示配置以及ref定义
|
||||||
|
*/
|
||||||
|
export default function useDictCrud() {
|
||||||
|
// refs
|
||||||
|
const crudRef = ref()
|
||||||
|
// 事件函数
|
||||||
|
const changeStatus = async (status: string, id: number) => {
|
||||||
|
// 点击切换status
|
||||||
|
try {
|
||||||
|
const response = await dictApi.changeStatus({ id, status })
|
||||||
|
if (response.success) {
|
||||||
|
Message.success(response.message)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// crud定义
|
||||||
|
const crudOptions = ref({
|
||||||
|
api: dictApi.getDictIndex,
|
||||||
|
showIndex: false,
|
||||||
|
operationColumnAlign: "center",
|
||||||
|
rowSelection: { showCheckedAll: true },
|
||||||
|
searchColNumber: 4,
|
||||||
|
tablePagination: false,
|
||||||
|
operationColumn: true,
|
||||||
|
showTools: false,
|
||||||
|
afterDelete() {
|
||||||
|
crudRef.value.tableRef.selectAll(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const crudColumns = ref([
|
||||||
|
{ title: "ID", dataIndex: "id", addDisplay: false, editDisplay: false, width: 50, hide: true },
|
||||||
|
{
|
||||||
|
title: "字典备注",
|
||||||
|
dataIndex: "remark",
|
||||||
|
search: true,
|
||||||
|
width: 220,
|
||||||
|
align: "center",
|
||||||
|
commonRules: [{ required: true, message: "字典备注必填" }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "字典标识",
|
||||||
|
dataIndex: "code",
|
||||||
|
search: true,
|
||||||
|
width: 260,
|
||||||
|
align: "center",
|
||||||
|
commonRules: [{ required: true, message: "字典标识必填" }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "状态",
|
||||||
|
dataIndex: "status",
|
||||||
|
search: true,
|
||||||
|
hide: true,
|
||||||
|
formType: "radio",
|
||||||
|
align: "center",
|
||||||
|
dict: { name: "data_status", props: { label: "title", value: "key" } },
|
||||||
|
addDefaultValue: "1",
|
||||||
|
width: 180
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "字典名称",
|
||||||
|
dataIndex: "name",
|
||||||
|
hide: true,
|
||||||
|
formType: "textarea",
|
||||||
|
align: "center"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "更新时间",
|
||||||
|
dataIndex: "update_datetime",
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
align: "center",
|
||||||
|
search: true,
|
||||||
|
formType: "range",
|
||||||
|
width: 180
|
||||||
|
}
|
||||||
|
])
|
||||||
|
return {
|
||||||
|
crudRef,
|
||||||
|
changeStatus,
|
||||||
|
crudOptions,
|
||||||
|
crudColumns
|
||||||
|
}
|
||||||
|
}
|
||||||
274
cdTMP/src/views/project/design-demand/hooks/useCrudRef.ts
Normal file
274
cdTMP/src/views/project/design-demand/hooks/useCrudRef.ts
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
import { ref, getCurrentInstance } from "vue"
|
||||||
|
import PinYinMatch from "pinyin-match"
|
||||||
|
import { useTreeDataStore } from "@/store"
|
||||||
|
import { useRoute } from "vue-router"
|
||||||
|
import testDemandApi from "@/api/project/testDemand"
|
||||||
|
import { isEqual, cloneDeep } from "lodash"
|
||||||
|
interface ITestContent {
|
||||||
|
subName: string
|
||||||
|
subDesc: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1.配置crud以及全组件使用变量
|
||||||
|
* 2.另外包含一个测试项是否保留数据的功能,含一个ref以及一个事件处理函数
|
||||||
|
*/
|
||||||
|
export default function useCrudRef() {
|
||||||
|
// global
|
||||||
|
const treeDataStore = useTreeDataStore()
|
||||||
|
const route = useRoute()
|
||||||
|
// variable
|
||||||
|
const roundNumber = (route.query.key as string)!.split("-")[0]
|
||||||
|
const dutNumber = (route.query.key as string)!.split("-")[1]
|
||||||
|
const designDemandNumber = (route.query.key as string)!.split("-")[2]
|
||||||
|
// refs
|
||||||
|
const projectId = ref(route.query.id)
|
||||||
|
const crudRef = ref()
|
||||||
|
// 处理弹窗关闭事件:处理用户数据是否保留
|
||||||
|
|
||||||
|
const app = getCurrentInstance()!.appContext.config.globalProperties
|
||||||
|
let beforeFormContent: ITestContent[] | undefined = undefined
|
||||||
|
const handleBeforeCancel = () => {
|
||||||
|
if (!beforeFormContent) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const iuEqualValue = isEqual(crudRef.value.getFormData().testContent, beforeFormContent)
|
||||||
|
!iuEqualValue &&
|
||||||
|
app.$modal.confirm({
|
||||||
|
title: "测试项步骤内容你已改动,是否保留您编写的测试项/测试用例步骤数据?",
|
||||||
|
content: "",
|
||||||
|
okText: "保留",
|
||||||
|
cancelText: "恢复原数据",
|
||||||
|
simple: true,
|
||||||
|
onOk: () => null,
|
||||||
|
onCancel: () => {
|
||||||
|
crudRef.value.refresh()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 配置
|
||||||
|
// crud组件
|
||||||
|
const crudOptions = ref({
|
||||||
|
api: testDemandApi.getTestDemandList,
|
||||||
|
add: { show: true, api: testDemandApi.save, text: "新增测试项" },
|
||||||
|
edit: { show: true, api: testDemandApi.update, text: "修改测试项" },
|
||||||
|
delete: { show: true, api: testDemandApi.delete },
|
||||||
|
showTools: false,
|
||||||
|
beforeOpenAdd: function () {
|
||||||
|
// 1.新增则将form的content数据变为undifined以便判断
|
||||||
|
beforeFormContent = undefined
|
||||||
|
// 2.设置标识
|
||||||
|
let key_split = (route.query.key as string)!.split("-")
|
||||||
|
let round_key = key_split[0]
|
||||||
|
let dut_key = key_split[1]
|
||||||
|
let design_key = key_split[2]
|
||||||
|
let td = treeDataStore.treeData
|
||||||
|
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) {
|
||||||
|
// 1.储存打开前form的content数据到ref中,以便后续比较
|
||||||
|
beforeFormContent = cloneDeep(record.testContent)
|
||||||
|
// 2.处理标识
|
||||||
|
let key_split = (route.query.key as string)!.split("-")
|
||||||
|
let round_key = key_split[0]
|
||||||
|
let dut_key = key_split[1]
|
||||||
|
let design_key = key_split[2]
|
||||||
|
let td = treeDataStore.treeData
|
||||||
|
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} >测试项[${record.name}]-`
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
afterAdd: (res) => {
|
||||||
|
let id = projectId.value
|
||||||
|
treeDataStore.updateTestDemandTreeData(res.data, id)
|
||||||
|
},
|
||||||
|
afterEdit: (res) => {
|
||||||
|
let id = projectId.value
|
||||||
|
treeDataStore.updateTestDemandTreeData(res.data, id)
|
||||||
|
},
|
||||||
|
afterDelete: (res, record) => {
|
||||||
|
let id = projectId.value
|
||||||
|
if (!record) {
|
||||||
|
record = { key: route.query.key + "-X" }
|
||||||
|
}
|
||||||
|
treeDataStore.updateTestDemandTreeData(record, id)
|
||||||
|
// 清空选择
|
||||||
|
crudRef.value.tableRef.selectAll(false)
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
projectId: route.query.id,
|
||||||
|
round: roundNumber,
|
||||||
|
dut: dutNumber,
|
||||||
|
designDemand: designDemandNumber
|
||||||
|
},
|
||||||
|
showIndex: false,
|
||||||
|
rowSelection: { showCheckedAll: true },
|
||||||
|
searchColNumber: 3,
|
||||||
|
tablePagination: false,
|
||||||
|
operationColumn: true,
|
||||||
|
operationColumnAlign: "center",
|
||||||
|
formOption: {
|
||||||
|
width: 1200,
|
||||||
|
layout: [
|
||||||
|
{
|
||||||
|
formType: "grid",
|
||||||
|
cols: [
|
||||||
|
{ span: 12, formList: [{ dataIndex: "ident" }] },
|
||||||
|
{ span: 12, formList: [{ dataIndex: "name" }] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formType: "grid",
|
||||||
|
cols: [{ span: 24, formList: [{ dataIndex: "priority" }] }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formType: "grid",
|
||||||
|
cols: [
|
||||||
|
{ span: 12, formList: [{ dataIndex: "testType" }] },
|
||||||
|
{ span: 12, formList: [{ dataIndex: "testMethod" }] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const crudColumns = ref([
|
||||||
|
{
|
||||||
|
title: "ID",
|
||||||
|
align: "center",
|
||||||
|
hide: true,
|
||||||
|
dataIndex: "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "测项标识",
|
||||||
|
width: 150,
|
||||||
|
dataIndex: "ident",
|
||||||
|
sortable: { sortDirections: ["ascend"] },
|
||||||
|
align: "center",
|
||||||
|
search: true,
|
||||||
|
validateTrigger: "blur",
|
||||||
|
placeholder: "请填写测试项的标识,注意标识不能重复",
|
||||||
|
commonRules: [{ required: true, message: "测试项标识必填" }],
|
||||||
|
openPrepend: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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: "4",
|
||||||
|
maxLength: 200,
|
||||||
|
commonRules: [{ required: true, message: "测试类型必选" }],
|
||||||
|
dict: { name: "testType", translation: true, props: { label: "title", value: "key" } },
|
||||||
|
extra: "请保证测试类型选择正确",
|
||||||
|
// 这是arco的属性,所以在ma-crud和ma-form可以直接使用arco属性和事件(事件+onXXX)
|
||||||
|
filterOption: function (inputValue, selectedOption) {
|
||||||
|
if (inputValue) {
|
||||||
|
let matchRes = PinYinMatch.match(selectedOption.label, inputValue)
|
||||||
|
if (matchRes) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "测试手段",
|
||||||
|
align: "center",
|
||||||
|
dataIndex: "testMethod",
|
||||||
|
formType: "select",
|
||||||
|
multiple: true,
|
||||||
|
dict: { name: "testMethod", props: { label: "title", value: "key" }, translation: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "充分性要求",
|
||||||
|
hide: true,
|
||||||
|
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: "测试方法是必填的" }],
|
||||||
|
formType: "children-form",
|
||||||
|
formList: [
|
||||||
|
{
|
||||||
|
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.join(
|
||||||
|
"、"
|
||||||
|
)}子项要求的全部内容。\n所有用例执行完毕,对于未执行的用例说明未执行原因。`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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结果正确"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
return {
|
||||||
|
projectId,
|
||||||
|
crudRef,
|
||||||
|
crudOptions,
|
||||||
|
crudColumns,
|
||||||
|
handleBeforeCancel
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
import { ref, computed, type Ref } from "vue"
|
||||||
|
import testDemandApi from "@/api/project/testDemand"
|
||||||
|
import { Message } from "@arco-design/web-vue"
|
||||||
|
import { useRoute } from "vue-router"
|
||||||
|
/**
|
||||||
|
* 关联测试项弹窗,并提供事件处理函数
|
||||||
|
*/
|
||||||
|
export default function useRalateDemand(projectId: Ref<string>) {
|
||||||
|
// global
|
||||||
|
const route = useRoute()
|
||||||
|
const roundNumber = (route.query.key as string)!.split("-")[0]
|
||||||
|
const dutNumber = (route.query.key as string)!.split("-")[1]
|
||||||
|
const designDemandNumber = (route.query.key as string)!.split("-")[2]
|
||||||
|
// refs
|
||||||
|
const visible = ref(false) // 弹窗显示隐藏
|
||||||
|
const relatedData: Ref<any[]> = ref([]) // 已关联数据
|
||||||
|
const options = ref<any>([]) // 级联cascade组件options
|
||||||
|
const cascaderLoading = ref(false) // 级联的加载圈
|
||||||
|
const computedRelatedData = computed(() => {
|
||||||
|
const labelResultList: any[] = []
|
||||||
|
options.value.forEach((item: any) => {
|
||||||
|
if (item.children) {
|
||||||
|
item.children.forEach((child: any) => {
|
||||||
|
if (relatedData.value.includes(child.value)) {
|
||||||
|
labelResultList.push(child.label)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return labelResultList
|
||||||
|
})
|
||||||
|
// 点击关联测试项-button
|
||||||
|
const handleOpenRelationCSX = async () => {
|
||||||
|
// 请求接口获取数据
|
||||||
|
cascaderLoading.value = true
|
||||||
|
visible.value = true
|
||||||
|
// 点击进入时清除关联
|
||||||
|
relatedData.value = []
|
||||||
|
const res = await testDemandApi.getRelatedTestDemand({ id: projectId.value, round: roundNumber })
|
||||||
|
options.value = res.data
|
||||||
|
// 找出本设计需求design对应已关联的测试项
|
||||||
|
const res_exist = await testDemandApi.getExistRelatedTestDemand({
|
||||||
|
project_id: projectId.value,
|
||||||
|
roundNumber,
|
||||||
|
dutNumber,
|
||||||
|
designDemandNumber
|
||||||
|
})
|
||||||
|
relatedData.value = res_exist.data
|
||||||
|
cascaderLoading.value = false
|
||||||
|
}
|
||||||
|
// 点击关联确定按钮
|
||||||
|
const handleRelatedOk = async () => {
|
||||||
|
// 获取级联数据
|
||||||
|
const relationDestItemIds = relatedData.value
|
||||||
|
if (relationDestItemIds.length > 0) {
|
||||||
|
const res = await testDemandApi.solveRelatedTestDemand({
|
||||||
|
data: relationDestItemIds,
|
||||||
|
project_id: projectId.value,
|
||||||
|
roundNumber,
|
||||||
|
dutNumber,
|
||||||
|
designDemandNumber
|
||||||
|
})
|
||||||
|
if (res.code == 200) {
|
||||||
|
Message.success(res.message)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const res = await testDemandApi.solveRelatedTestDemand({
|
||||||
|
data: [],
|
||||||
|
project_id: projectId.value,
|
||||||
|
roundNumber,
|
||||||
|
dutNumber,
|
||||||
|
designDemandNumber
|
||||||
|
})
|
||||||
|
if (res.code == 200) {
|
||||||
|
Message.success(res.message)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
visible,
|
||||||
|
relatedData,
|
||||||
|
options,
|
||||||
|
cascaderLoading,
|
||||||
|
computedRelatedData,
|
||||||
|
handleOpenRelationCSX,
|
||||||
|
handleRelatedOk
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="ma-content-block lg:flex justify-between p-4">
|
<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">
|
<div class="lg:w-full w-full lg:ml-4 mt-5 lg:mt-0">
|
||||||
<!-- CRUD组件 -->
|
<!-- CRUD组件 -->
|
||||||
<ma-crud :options="crudOptions" :columns="crudColumns" ref="crudRef">
|
<ma-crud :options="crudOptions" :columns="crudColumns" ref="crudRef" @beforeCancel="handleBeforeCancel">
|
||||||
<template #ident="{ record }">
|
<template #ident="{ record }">
|
||||||
{{ showType(record) }}
|
{{ showType(record) }}
|
||||||
</template>
|
</template>
|
||||||
@@ -42,94 +42,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from "vue"
|
import { ref } from "vue"
|
||||||
import { useRoute } from "vue-router"
|
|
||||||
import testDemandApi from "@/api/project/testDemand"
|
|
||||||
import { useTreeDataStore } from "@/store"
|
|
||||||
import commonApi from "@/api/common"
|
import commonApi from "@/api/common"
|
||||||
import PinYinMatch from "pinyin-match"
|
// hooks
|
||||||
import { Message } from "@arco-design/web-vue"
|
import useCrudRef from "./hooks/useCrudRef"
|
||||||
|
import useRalateDemand from "./hooks/useRalateDemand"
|
||||||
|
|
||||||
const treeDataStore = useTreeDataStore()
|
|
||||||
const route = useRoute()
|
|
||||||
const crudRef = ref()
|
|
||||||
// 根据传参获取key,分别为轮次、设计需求的key
|
// 根据传参获取key,分别为轮次、设计需求的key
|
||||||
const roundNumber = route.query.key.split("-")[0]
|
const { projectId, crudRef, crudOptions, crudColumns, handleBeforeCancel } = useCrudRef()
|
||||||
const dutNumber = route.query.key.split("-")[1]
|
// 关联弹窗、关联的事件处理
|
||||||
const designDemandNumber = route.query.key.split("-")[2]
|
const { visible, relatedData, options, cascaderLoading, computedRelatedData, handleOpenRelationCSX, handleRelatedOk } =
|
||||||
const projectId = ref(route.query.id)
|
useRalateDemand(projectId)
|
||||||
// ~~~~~关联相关变量和函数~~~~~
|
|
||||||
// 定义关联弹窗变量函数
|
|
||||||
const visible = ref(false)
|
|
||||||
const relatedData = ref([])
|
|
||||||
const computedRelatedData = computed(() => {
|
|
||||||
const labelResultList = []
|
|
||||||
options.value.forEach((item) => {
|
|
||||||
if (item.children) {
|
|
||||||
item.children.forEach((child) => {
|
|
||||||
if (relatedData.value.includes(child.value)) {
|
|
||||||
labelResultList.push(child.label)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return labelResultList
|
|
||||||
})
|
|
||||||
// 定义cascader的加载圈
|
|
||||||
const cascaderLoading = ref(false)
|
|
||||||
// 点击关联测试项-button
|
|
||||||
const handleOpenRelationCSX = async () => {
|
|
||||||
// 请求接口获取数据
|
|
||||||
cascaderLoading.value = true
|
|
||||||
visible.value = true
|
|
||||||
// 点击进入时清除关联
|
|
||||||
relatedData.value = []
|
|
||||||
const res = await testDemandApi.getRelatedTestDemand({ id: projectId.value, round: roundNumber })
|
|
||||||
options.value = res.data
|
|
||||||
// 找出本设计需求design对应已关联的测试项
|
|
||||||
const res_exist = await testDemandApi.getExistRelatedTestDemand({
|
|
||||||
project_id: projectId.value,
|
|
||||||
roundNumber,
|
|
||||||
dutNumber,
|
|
||||||
designDemandNumber
|
|
||||||
})
|
|
||||||
relatedData.value = res_exist.data
|
|
||||||
cascaderLoading.value = false
|
|
||||||
}
|
|
||||||
// 点击关联确定按钮
|
|
||||||
const handleRelatedOk = async () => {
|
|
||||||
// 获取级联数据
|
|
||||||
const relationDestItemIds = relatedData.value
|
|
||||||
if (relationDestItemIds.length > 0) {
|
|
||||||
const res = await testDemandApi.solveRelatedTestDemand({
|
|
||||||
data: relationDestItemIds,
|
|
||||||
project_id: projectId.value,
|
|
||||||
roundNumber,
|
|
||||||
dutNumber,
|
|
||||||
designDemandNumber
|
|
||||||
})
|
|
||||||
if (res.code == 200) {
|
|
||||||
Message.success(res.message)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const res = await testDemandApi.solveRelatedTestDemand({
|
|
||||||
data: [],
|
|
||||||
project_id: projectId.value,
|
|
||||||
roundNumber,
|
|
||||||
dutNumber,
|
|
||||||
designDemandNumber
|
|
||||||
})
|
|
||||||
if (res.code == 200) {
|
|
||||||
Message.success(res.message)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// 级联cascade组件options
|
|
||||||
const options = ref([])
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
// 标识显示字段
|
// 标识显示字段
|
||||||
const testTypeDict = ref([])
|
const testTypeDict = ref([])
|
||||||
@@ -147,204 +70,12 @@ const showType = (record) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// crud组件
|
|
||||||
const crudOptions = ref({
|
|
||||||
api: testDemandApi.getTestDemandList,
|
|
||||||
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]
|
|
||||||
let dut_key = key_split[1]
|
|
||||||
let design_key = key_split[2]
|
|
||||||
let td = treeDataStore.treeData
|
|
||||||
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) {
|
|
||||||
let key_split = route.query.key.split("-")
|
|
||||||
let round_key = key_split[0]
|
|
||||||
let dut_key = key_split[1]
|
|
||||||
let design_key = key_split[2]
|
|
||||||
let td = treeDataStore.treeData
|
|
||||||
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} >测试项[${record.name}]-`
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
afterAdd: (res) => {
|
|
||||||
let id = projectId.value
|
|
||||||
treeDataStore.updateTestDemandTreeData(res.data, id)
|
|
||||||
},
|
|
||||||
afterEdit: (res) => {
|
|
||||||
let id = projectId.value
|
|
||||||
treeDataStore.updateTestDemandTreeData(res.data, id)
|
|
||||||
},
|
|
||||||
afterDelete: (res, record) => {
|
|
||||||
let id = projectId.value
|
|
||||||
if (!record) {
|
|
||||||
record = { key: route.query.key + "-X" }
|
|
||||||
}
|
|
||||||
treeDataStore.updateTestDemandTreeData(record, id)
|
|
||||||
// 清空选择
|
|
||||||
crudRef.value.tableRef.selectAll(false)
|
|
||||||
},
|
|
||||||
parameters: {
|
|
||||||
projectId: route.query.id,
|
|
||||||
round: roundNumber,
|
|
||||||
dut: dutNumber,
|
|
||||||
designDemand: designDemandNumber
|
|
||||||
},
|
|
||||||
showIndex: false,
|
|
||||||
rowSelection: { showCheckedAll: true },
|
|
||||||
searchColNumber: 3,
|
|
||||||
tablePagination: false,
|
|
||||||
operationColumn: true,
|
|
||||||
operationColumnAlign: "center",
|
|
||||||
formOption: {
|
|
||||||
width: 1200
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const crudColumns = ref([
|
|
||||||
{
|
|
||||||
title: "ID",
|
|
||||||
align: "center",
|
|
||||||
hide: true,
|
|
||||||
dataIndex: "id"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "测项标识",
|
|
||||||
width: 150,
|
|
||||||
dataIndex: "ident",
|
|
||||||
sortable: { sortDirections: ["ascend"] },
|
|
||||||
align: "center",
|
|
||||||
search: true,
|
|
||||||
validateTrigger: "blur",
|
|
||||||
placeholder: "请填写测试项的标识,注意标识不能重复",
|
|
||||||
commonRules: [{ required: true, message: "测试项标识必填" }],
|
|
||||||
openPrepend: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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: "4",
|
|
||||||
maxLength: 200,
|
|
||||||
commonRules: [{ required: true, message: "测试类型必选" }],
|
|
||||||
dict: { name: "testType", translation: true, props: { label: "title", value: "key" } },
|
|
||||||
extra: "请保证测试类型选择正确",
|
|
||||||
// 这是arco的属性,所以在ma-crud和ma-form可以直接使用arco属性和事件(事件+onXXX)
|
|
||||||
filterOption: function (inputValue, selectedOption) {
|
|
||||||
if (inputValue) {
|
|
||||||
let matchRes = PinYinMatch.match(selectedOption.label, inputValue)
|
|
||||||
if (matchRes) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "测试手段",
|
|
||||||
align: "center",
|
|
||||||
dataIndex: "testMethod",
|
|
||||||
formType: "select",
|
|
||||||
multiple: true,
|
|
||||||
dict: { name: "testMethod", props: { label: "title", value: "key" }, translation: true }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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: "测试方法是必填的" }],
|
|
||||||
formType: "children-form",
|
|
||||||
formList: [
|
|
||||||
{
|
|
||||||
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.join(
|
|
||||||
"、"
|
|
||||||
)}子项要求的全部内容。\n所有用例执行完毕,对于未执行的用例说明未执行原因。`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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的刷新表格函数
|
// 暴露给route-view的刷新表格函数
|
||||||
const refreshCrudTable = () => {
|
const refreshCrudTable = () => {
|
||||||
crudRef.value.refresh()
|
crudRef.value.refresh()
|
||||||
}
|
}
|
||||||
defineExpose({ refreshCrudTable })
|
defineExpose({ refreshCrudTable })
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "designDemand"
|
name: "designDemand"
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="ma-content-block lg:flex justify-between p-4">
|
<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">
|
<div class="lg:w-full w-full lg:ml-4 mt-5 lg:mt-0">
|
||||||
<!-- CRUD组件 -->
|
<!-- CRUD组件 -->
|
||||||
<ma-crud :options="crudOptions" :columns="crudColumns" ref="crudRef">
|
<ma-crud :options="crudOptions" :columns="crudColumns" ref="crudRef" @beforeCancel="handleBeforeCancel">
|
||||||
<template #ident="{ record }">
|
<template #ident="{ record }">
|
||||||
{{ showType(record) }}
|
{{ showType(record) }}
|
||||||
</template>
|
</template>
|
||||||
@@ -13,11 +13,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="jsx">
|
<script setup lang="jsx">
|
||||||
import { ref } from "vue"
|
import { ref, getCurrentInstance } from "vue"
|
||||||
import { useRoute } from "vue-router"
|
import { useRoute } from "vue-router"
|
||||||
import caseApi from "@/api/project/case"
|
import caseApi from "@/api/project/case"
|
||||||
import { useTreeDataStore } from "@/store"
|
import { useTreeDataStore } from "@/store"
|
||||||
import ProblemForm from "@/views/project/case/components/ProblemForm.vue"
|
import ProblemForm from "@/views/project/case/components/ProblemForm.vue"
|
||||||
|
import { isEqual, cloneDeep } from "lodash"
|
||||||
const problemFormRef = ref(null)
|
const problemFormRef = ref(null)
|
||||||
const title = ref("问题单表单")
|
const title = ref("问题单表单")
|
||||||
const treeDataStore = useTreeDataStore()
|
const treeDataStore = useTreeDataStore()
|
||||||
@@ -34,7 +35,29 @@ const showType = (record) => {
|
|||||||
return "YL-" + record.testType + "-" + record.ident + "-" + key_string.toString().padStart(3, "0")
|
return "YL-" + record.testType + "-" + record.ident + "-" + key_string.toString().padStart(3, "0")
|
||||||
}
|
}
|
||||||
|
|
||||||
// crud设置
|
// crud设置以及是否保留step数据事件函数
|
||||||
|
const app = getCurrentInstance().appContext.config.globalProperties
|
||||||
|
let beforeFormStep = undefined
|
||||||
|
const handleBeforeCancel = () => {
|
||||||
|
if (!beforeFormStep) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log(beforeFormStep)
|
||||||
|
crudRef.value.getFormData().testStep
|
||||||
|
const iuEqualValue = isEqual(crudRef.value.getFormData().testStep, beforeFormStep)
|
||||||
|
!iuEqualValue &&
|
||||||
|
app.$modal.confirm({
|
||||||
|
title: "测试项步骤内容你已改动,是否保留您编写的测试项/测试用例步骤数据?",
|
||||||
|
content: "",
|
||||||
|
okText: "保留",
|
||||||
|
cancelText: "恢复原数据",
|
||||||
|
simple: true,
|
||||||
|
onOk: () => null,
|
||||||
|
onCancel: () => {
|
||||||
|
crudRef.value.refresh()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
const crudOptions = ref({
|
const crudOptions = ref({
|
||||||
api: caseApi.getCaseList,
|
api: caseApi.getCaseList,
|
||||||
add: { show: true, api: caseApi.save, text: "新增用例" },
|
add: { show: true, api: caseApi.save, text: "新增用例" },
|
||||||
@@ -44,6 +67,9 @@ const crudOptions = ref({
|
|||||||
isDbClickEdit: false, // 关闭双击编辑
|
isDbClickEdit: false, // 关闭双击编辑
|
||||||
// 处理新增删除后树状图显示
|
// 处理新增删除后树状图显示
|
||||||
beforeOpenAdd: function () {
|
beforeOpenAdd: function () {
|
||||||
|
// 1.新增则将form的content数据变为undifined以便判断
|
||||||
|
beforeFormStep = undefined
|
||||||
|
// 2.标识处理
|
||||||
let key_split = route.query.key.split("-")
|
let key_split = route.query.key.split("-")
|
||||||
let round_key = key_split[0]
|
let round_key = key_split[0]
|
||||||
let dut_key = key_split[1]
|
let dut_key = key_split[1]
|
||||||
@@ -57,6 +83,9 @@ const crudOptions = ref({
|
|||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
beforeOpenEdit: function (record) {
|
beforeOpenEdit: function (record) {
|
||||||
|
// 1.储存打开前form的content数据到ref中,以便后续比较
|
||||||
|
beforeFormStep = cloneDeep(record.testStep)
|
||||||
|
// 2.标识处理
|
||||||
let key_split = route.query.key.split("-")
|
let key_split = route.query.key.split("-")
|
||||||
let round_key = key_split[0]
|
let round_key = key_split[0]
|
||||||
let dut_key = key_split[1]
|
let dut_key = key_split[1]
|
||||||
|
|||||||
Reference in New Issue
Block a user