文档片段全面改进,不使用render
This commit is contained in:
581
cdTMP/package-lock.json
generated
581
cdTMP/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "cdtmp",
|
"name": "cdtmp",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.4",
|
"version": "0.0.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
@@ -13,9 +13,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@arco-design/color": "^0.4.0",
|
"@arco-design/color": "^0.4.0",
|
||||||
"@arco-design/web-vue": "^2.57.0",
|
"@arco-design/web-vue": "^2.57.0",
|
||||||
"@tanstack/vue-query": "^5.71.1",
|
"@tanstack/vue-query": "^5.74.5",
|
||||||
"@tinymce/tinymce-vue": "^6.1.0",
|
"@tinymce/tinymce-vue": "^6.1.0",
|
||||||
"@vueuse/core": "^13.0.0",
|
"@vueuse/core": "^13.1.0",
|
||||||
"axios": "^1.8.4",
|
"axios": "^1.8.4",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"file2md5": "^1.3.0",
|
"file2md5": "^1.3.0",
|
||||||
@@ -23,39 +23,39 @@
|
|||||||
"mammoth": "^1.9.0",
|
"mammoth": "^1.9.0",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^3.0.1",
|
"pinia": "^3.0.2",
|
||||||
"pinyin-match": "^1.2.6",
|
"pinyin-match": "^1.2.6",
|
||||||
"postcss-import": "^16.1.0",
|
"postcss-import": "^16.1.0",
|
||||||
"qs": "^6.14.0",
|
"qs": "^6.14.0",
|
||||||
"tinymce": "^7.7.2",
|
"tinymce": "^7.8.0",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-color-kit": "^1.0.6",
|
"vue-color-kit": "^1.0.6",
|
||||||
"vue-data-ui": "^2.6.27",
|
"vue-data-ui": "^2.6.40",
|
||||||
"vue-router": "^4.5.0",
|
"vue-router": "^4.5.0",
|
||||||
"vuedraggable": "^2.24.3"
|
"vuedraggable": "^2.24.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4.1.0",
|
"@tailwindcss/postcss": "^4.1.4",
|
||||||
"@tailwindcss/vite": "^4.1.0",
|
"@tailwindcss/vite": "^4.1.4",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.13.17",
|
"@types/node": "^22.14.1",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/qs": "^6.9.18",
|
"@types/qs": "^6.9.18",
|
||||||
"@vitejs/plugin-vue": "^5.2.3",
|
"@vitejs/plugin-vue": "^5.2.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^4.1.2",
|
"@vitejs/plugin-vue-jsx": "^4.1.2",
|
||||||
"@vue/babel-plugin-jsx": "^1.4.0",
|
"@vue/babel-plugin-jsx": "^1.4.0",
|
||||||
"browserslist": "^4.24.4",
|
"browserslist": "^4.24.4",
|
||||||
"eslint": "^9.23.0",
|
"eslint": "^9.25.0",
|
||||||
"eslint-plugin-vue": "^10.0.0",
|
"eslint-plugin-vue": "^10.0.0",
|
||||||
"less": "^4.2.2",
|
"less": "^4.3.0",
|
||||||
"less-loader": "^12.2.0",
|
"less-loader": "^12.2.0",
|
||||||
"postcss": "^8.5.3",
|
"postcss": "^8.5.3",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"rollup-plugin-visualizer": "^5.14.0",
|
"rollup-plugin-visualizer": "^5.14.0",
|
||||||
"tailwindcss": "^4.1.0",
|
"tailwindcss": "^4.1.4",
|
||||||
"typescript": "^5.8.2",
|
"typescript": "^5.8.3",
|
||||||
"vite": "^6.2.4",
|
"vite": "^6.3.2",
|
||||||
"vue-eslint-parser": "^10.1.1"
|
"vue-eslint-parser": "^10.1.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,15 +308,4 @@ export default {
|
|||||||
params
|
params
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @returns 生成-主要战技指标
|
|
||||||
*/
|
|
||||||
createMainTech(params = {}) {
|
|
||||||
return request({
|
|
||||||
url: `/generate/create/mainTech`,
|
|
||||||
method: "get",
|
|
||||||
params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
15
cdTMP/src/api/generate/fragment.ts
Normal file
15
cdTMP/src/api/generate/fragment.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { request } from "@/api/request"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
/**
|
||||||
|
* 根据项目id和文档类型获取文档片段名称
|
||||||
|
* @returns 文档片段名称数组
|
||||||
|
*/
|
||||||
|
getFragmentByDocumentType(params: { id: number; documentType: string }) {
|
||||||
|
return request({
|
||||||
|
url: `/createfragment/get_fragments`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
13
cdTMP/src/api/generate/other.ts
Normal file
13
cdTMP/src/api/generate/other.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { request } from "@/api/request"
|
||||||
|
export default {
|
||||||
|
/**
|
||||||
|
* 获取当前项目非第一轮有几轮测试
|
||||||
|
*/
|
||||||
|
getHgRoundNumber(params: { id: number }) {
|
||||||
|
return request({
|
||||||
|
url: `/createfragment/get_round_exit`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,11 +4,11 @@ export default {
|
|||||||
* 如果缺少部分文件给与提示
|
* 如果缺少部分文件给与提示
|
||||||
* @returns 根据output_dir生成最终大纲文档
|
* @returns 根据output_dir生成最终大纲文档
|
||||||
*/
|
*/
|
||||||
createDagangSeiTai(params = {}) {
|
createDagangSeiTai(data = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: `/create/dgDocument`,
|
url: `/create/dgDocument`,
|
||||||
method: "get",
|
method: "post",
|
||||||
params,
|
data,
|
||||||
responseType: "blob"
|
responseType: "blob"
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -16,11 +16,11 @@ export default {
|
|||||||
* 如果缺少部分文件给与提示
|
* 如果缺少部分文件给与提示
|
||||||
* @returns 根据output_dir以及output_dir/sm中文档生成测试说明
|
* @returns 根据output_dir以及output_dir/sm中文档生成测试说明
|
||||||
*/
|
*/
|
||||||
createShuomingSeiTai(params = {}) {
|
createShuomingSeiTai(data = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: `/create/smDocument`,
|
url: `/create/smDocument`,
|
||||||
method: "get",
|
method: "post",
|
||||||
params,
|
data,
|
||||||
responseType: "blob"
|
responseType: "blob"
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -28,23 +28,11 @@ export default {
|
|||||||
* TODO:如果缺少部分文件给与提示
|
* TODO:如果缺少部分文件给与提示
|
||||||
* @returns 根据output_dir以及output_dir/JL中文档生成测试记录
|
* @returns 根据output_dir以及output_dir/JL中文档生成测试记录
|
||||||
*/
|
*/
|
||||||
createJiluSeiTai(params = {}) {
|
createJiluSeiTai(data = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: `/create/jlDocument`,
|
url: `/create/jlDocument`,
|
||||||
method: "get",
|
method: "post",
|
||||||
params,
|
data,
|
||||||
responseType: "blob"
|
|
||||||
})
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* TODO:如果缺少部分文件给与提示
|
|
||||||
* @returns 根据output_dir以及output_dir/bg中文档生成测评报告
|
|
||||||
*/
|
|
||||||
createBgDocument(params = {}) {
|
|
||||||
return request({
|
|
||||||
url: `/create/bgDocument`,
|
|
||||||
method: "get",
|
|
||||||
params,
|
|
||||||
responseType: "blob"
|
responseType: "blob"
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -52,11 +40,11 @@ export default {
|
|||||||
* TODO:如果缺少部分文件给与提示
|
* TODO:如果缺少部分文件给与提示
|
||||||
* @returns 根据output_dir以及output_dir/hsm中文档生成回归测试说明(特殊多个文件)
|
* @returns 根据output_dir以及output_dir/hsm中文档生成回归测试说明(特殊多个文件)
|
||||||
*/
|
*/
|
||||||
createHsmDocument(params = {}) {
|
createHsmDocument(data = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: `/create/hsmDocument`,
|
url: `/create/hsmDocument`,
|
||||||
method: "get",
|
method: "post",
|
||||||
params,
|
data,
|
||||||
responseType: "blob"
|
responseType: "blob"
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -64,11 +52,11 @@ export default {
|
|||||||
* TODO:如果缺少部分文件给与提示
|
* TODO:如果缺少部分文件给与提示
|
||||||
* @returns 根据output_dir以及output_dir/hjl中文档生成回归测试记录(特殊多个文件)
|
* @returns 根据output_dir以及output_dir/hjl中文档生成回归测试记录(特殊多个文件)
|
||||||
*/
|
*/
|
||||||
createHjlDocument(params = {}) {
|
createHjlDocument(data = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: `/create/hjlDocument`,
|
url: `/create/hjlDocument`,
|
||||||
method: "get",
|
method: "post",
|
||||||
params,
|
data,
|
||||||
responseType: "blob"
|
responseType: "blob"
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -76,11 +64,23 @@ export default {
|
|||||||
* TODO:生成最终问题单
|
* TODO:生成最终问题单
|
||||||
* @returns 返回是否正确生成问题单
|
* @returns 返回是否正确生成问题单
|
||||||
*/
|
*/
|
||||||
createWtdDocument(params = {}) {
|
createWtdDocument(data = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: `/create/wtdDocument`,
|
url: `/create/wtdDocument`,
|
||||||
method: "get",
|
method: "post",
|
||||||
params,
|
data,
|
||||||
|
responseType: "blob"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* TODO:如果缺少部分文件给与提示
|
||||||
|
* @returns 根据output_dir以及output_dir/bg中文档生成测评报告
|
||||||
|
*/
|
||||||
|
createBgDocument(data = {}) {
|
||||||
|
return request({
|
||||||
|
url: `/create/bgDocument`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
responseType: "blob"
|
responseType: "blob"
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -92,7 +92,7 @@ export default {
|
|||||||
return request({
|
return request({
|
||||||
url: `/create/cancel`,
|
url: `/create/cancel`,
|
||||||
method: "get",
|
method: "get",
|
||||||
params,
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,12 +41,28 @@ function createService() {
|
|||||||
return res.data
|
return res.data
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
const err = (text) => {
|
const err = async (text) => {
|
||||||
Message.error({
|
let content = ""
|
||||||
content:
|
// 在设置axios为responseType: "blob"时候,data为Blob对象,需要解析Blob
|
||||||
|
if (error.response && error.response.data instanceof Blob) {
|
||||||
|
try {
|
||||||
|
const text = await error.response.data.text()
|
||||||
|
content = JSON.parse(text).message && JSON.parse(text).message
|
||||||
|
if (!content) {
|
||||||
|
content = "未知Blob错误"
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Message.error("解析Blob失败")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 非Blob正常错误响应
|
||||||
|
content =
|
||||||
error.response && error.response.data && error.response.data.message
|
error.response && error.response.data && error.response.data.message
|
||||||
? error.response.data.message
|
? error.response.data.message
|
||||||
: text,
|
: text
|
||||||
|
}
|
||||||
|
Message.error({
|
||||||
|
content,
|
||||||
icon: () => h(IconFaceFrownFill)
|
icon: () => h(IconFaceFrownFill)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -58,6 +74,9 @@ function createService() {
|
|||||||
case 500:
|
case 500:
|
||||||
err("服务器内部错误")
|
err("服务器内部错误")
|
||||||
break
|
break
|
||||||
|
case 400:
|
||||||
|
err("服务器抛出逻辑错误")
|
||||||
|
break
|
||||||
case 401:
|
case 401:
|
||||||
err("登录状态已过期,需要重新登录")
|
err("登录状态已过期,需要重新登录")
|
||||||
// 清除本地localStorage
|
// 清除本地localStorage
|
||||||
|
|||||||
7
cdTMP/src/arco-design-types.d.ts
vendored
Normal file
7
cdTMP/src/arco-design-types.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import type { ArcoGlobalComponents } from "@arco-design/web-vue"
|
||||||
|
|
||||||
|
declare module "vue" {
|
||||||
|
export interface GlobalComponents extends ArcoGlobalComponents {
|
||||||
|
ASpace: (typeof import("@arco-design/web-vue"))["Space"]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,9 +5,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { ref } from "vue"
|
// 标准vue3.5+的默认值写法、结构写法、ts类型写法
|
||||||
const text = ref("暂无数据")
|
const { text = "暂无数据" } = defineProps<{ text?: string }>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|||||||
@@ -379,9 +379,4 @@ const refresh = () => {
|
|||||||
defineExpose({ deleteAction, recoveryAction })
|
defineExpose({ deleteAction, recoveryAction })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
:deep(.arco-image-img) {
|
|
||||||
object-fit: contain;
|
|
||||||
background-color: var(--color-fill-4);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
<!--
|
|
||||||
- @Author XXX
|
|
||||||
- @Link XXX
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<a-drawer :visible="visible" unmountOnClose :footer="false" :width="950" @cancel="onCancel">
|
<a-drawer :visible="visible" unmountOnClose :footer="false" :width="950" @cancel="onCancel">
|
||||||
<template #title>设置</template>
|
<template #title>设置</template>
|
||||||
|
|||||||
@@ -136,9 +136,9 @@
|
|||||||
<a-tooltip content="显隐搜索"
|
<a-tooltip content="显隐搜索"
|
||||||
><a-button shape="circle" @click="toggleSearch"><icon-search /></a-button
|
><a-button shape="circle" @click="toggleSearch"><icon-search /></a-button
|
||||||
></a-tooltip>
|
></a-tooltip>
|
||||||
<a-tooltip content="打印表格"
|
<!-- <a-tooltip content="打印表格"
|
||||||
><a-button shape="circle" @click="printTable"><icon-printer /></a-button
|
><a-button shape="circle" @click="printTable"><icon-printer /></a-button
|
||||||
></a-tooltip>
|
></a-tooltip> -->
|
||||||
<a-tooltip content="设置"
|
<a-tooltip content="设置"
|
||||||
><a-button shape="circle" @click="tableSetting"><icon-settings /></a-button
|
><a-button shape="circle" @click="tableSetting"><icon-settings /></a-button
|
||||||
></a-tooltip>
|
></a-tooltip>
|
||||||
@@ -809,9 +809,9 @@ const tabChange = async (value) => {
|
|||||||
await refresh()
|
await refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
const printTable = () => {
|
// const printTable = () => {
|
||||||
new Print(crudContentRef.value)
|
// new Print(crudContentRef.value)
|
||||||
}
|
// }
|
||||||
|
|
||||||
const openContextMenu = (ev, record) => {
|
const openContextMenu = (ev, record) => {
|
||||||
options.value?.contextMenu?.enabled === true && crudContextMenuRef.value.openContextMenu(ev, record)
|
options.value?.contextMenu?.enabled === true && crudContextMenuRef.value.openContextMenu(ev, record)
|
||||||
@@ -821,9 +821,9 @@ const execContextMenuCommand = async (args) => {
|
|||||||
const item = args.contextItem
|
const item = args.contextItem
|
||||||
const record = args.record
|
const record = args.record
|
||||||
switch (item.operation) {
|
switch (item.operation) {
|
||||||
case "print":
|
// case "print":
|
||||||
await printTable()
|
// await printTable()
|
||||||
break
|
// break
|
||||||
case "refresh":
|
case "refresh":
|
||||||
await refresh()
|
await refresh()
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -57,8 +57,11 @@ const props = defineProps({
|
|||||||
type: [String, Array],
|
type: [String, Array],
|
||||||
// 如果要取消粘贴只粘贴文本,需要用户加格式请加上pastetext
|
// 如果要取消粘贴只粘贴文本,需要用户加格式请加上pastetext
|
||||||
default:
|
default:
|
||||||
"code undo redo restoredraft | paste | bold | aligncenter alignleft alignjustify indent | \
|
"undo redo aligncenter alignleft indent styleselect formatselect fontselect fontsizeselect removeformat"
|
||||||
styleselect formatselect fontselect fontsizeselect | bullist numlist | removeformat"
|
|
||||||
|
// 下面是备份配置:
|
||||||
|
// default:"code undo redo restoredraft | paste | bold | aligncenter alignleft alignjustify indent | \
|
||||||
|
// styleselect formatselect fontselect fontsizeselect | bullist numlist | removeformat"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
162
cdTMP/src/components/ma-form/Customs/ChenDemandList.vue
Normal file
162
cdTMP/src/components/ma-form/Customs/ChenDemandList.vue
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
<template>
|
||||||
|
<div class="chen-demand-list">
|
||||||
|
<div class="arco-table arco-table-size-large arco-table-border arco-table-stripe arco-table-hover">
|
||||||
|
<div class="arco-table-container">
|
||||||
|
<table class="arco-table-element" cellpadding="0" cellspacing="0">
|
||||||
|
<thead>
|
||||||
|
<tr class="arco-table-tr">
|
||||||
|
<th class="arco-table-th" :width="20">
|
||||||
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
|
<a-tooltip content="添加步骤">
|
||||||
|
<a-button type="primary" size="mini" shape="round" @click="addItem">
|
||||||
|
新增步骤+
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="arco-table-th" :width="400">
|
||||||
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
|
<span class="arco-table-th-title">操作</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="arco-table-th" :width="310">
|
||||||
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
|
<span class="arco-table-th-title">预期</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- 根据subStep渲染 -->
|
||||||
|
<template
|
||||||
|
v-if="modelValue && modelValue.length > 0"
|
||||||
|
v-for="(stepItem, index) in modelValue"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<tr class="arco-table-tr">
|
||||||
|
<td class="arco-table-td">
|
||||||
|
<span class="arco-table-cell justify-center gap-1.5">
|
||||||
|
<!-- 删除单项按钮 -->
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
status="danger"
|
||||||
|
size="mini"
|
||||||
|
shape="round"
|
||||||
|
@click="deleteItem(index)"
|
||||||
|
:disabled="modelValue.length <= 1"
|
||||||
|
>
|
||||||
|
<template #icon><icon-close /></template>
|
||||||
|
</a-button>
|
||||||
|
<a-tooltip content="复制该项添加">
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
status="warning"
|
||||||
|
size="mini"
|
||||||
|
shape="round"
|
||||||
|
@click="copyItem(index)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<icon-copy />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-button-group shape="round" size="mini">
|
||||||
|
<a-button type="primary" @click="moveUp(index)">
|
||||||
|
<icon-arrow-rise />
|
||||||
|
</a-button>
|
||||||
|
<a-button type="primary" @click="moveDown(index)">
|
||||||
|
<icon-arrow-fall />
|
||||||
|
</a-button>
|
||||||
|
</a-button-group>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="arco-table-td">
|
||||||
|
<span class="arco-table-cell">
|
||||||
|
<a-textarea auto-size v-model="stepItem.operation"></a-textarea>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="arco-table-td">
|
||||||
|
<span class="arco-table-cell">
|
||||||
|
<a-textarea auto-size v-model="stepItem.expect"></a-textarea>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">
|
||||||
|
<div class="flex justify-center items-center p-2 border-1">
|
||||||
|
<a-alert>暂无测试子项条目,请添加</a-alert>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { type Ref, nextTick } from "vue"
|
||||||
|
|
||||||
|
// 辅助函数:当modelValue不是列表时候
|
||||||
|
function handleIsNotArray() {
|
||||||
|
if (Array.isArray(modelValue.value)) return
|
||||||
|
modelValue.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义value数据
|
||||||
|
interface ISubStep {
|
||||||
|
operation: string
|
||||||
|
expect: string
|
||||||
|
}
|
||||||
|
// 绑定外部数据,预期是列表,有operation、expect两个字段
|
||||||
|
const modelValue = defineModel() as unknown as Ref<ISubStep[]>
|
||||||
|
|
||||||
|
// 单纯新增 - modalValue新增一行
|
||||||
|
const addItem = async () => {
|
||||||
|
handleIsNotArray()
|
||||||
|
await nextTick() // 因为要等待modelValue值变化DOM渲染完毕
|
||||||
|
modelValue.value.push({ operation: "", expect: "" })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除指定行
|
||||||
|
const deleteItem = (index: number) => {
|
||||||
|
modelValue.value = modelValue.value.filter((_, idx) => idx !== index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制单项
|
||||||
|
const copyItem = (index: number) => {
|
||||||
|
const newItem = modelValue.value[index]
|
||||||
|
modelValue.value = [...modelValue.value, newItem]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数交换列表两个元素
|
||||||
|
function swapItems(idx1: number, idx2: number) {
|
||||||
|
const arr = modelValue.value
|
||||||
|
;[arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 向下移动
|
||||||
|
const moveDown = (index: number) => {
|
||||||
|
if (index === modelValue.value.length - 1) return
|
||||||
|
swapItems(index, index + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 向上移动
|
||||||
|
const moveUp = (index: number) => {
|
||||||
|
if (index === 0) return
|
||||||
|
swapItems(index, index - 1)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
:deep(.arco-form-item-content-flex) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
:deep(.arco-table-cell .arco-form-item) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,7 +1,3 @@
|
|||||||
<!--
|
|
||||||
- @Author XXX
|
|
||||||
- @Link XXX
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
@@ -236,7 +232,7 @@ function swapItems(idx1, idx2) {
|
|||||||
;[arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]]
|
;[arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改源码上移动和下移动
|
// 修改源码:上移动和下移动
|
||||||
const moveUp = (itemIndex) => {
|
const moveUp = (itemIndex) => {
|
||||||
const itemLength = formModel.value[props.component.dataIndex].length
|
const itemLength = formModel.value[props.component.dataIndex].length
|
||||||
// 如果是第一个,不做操作
|
// 如果是第一个,不做操作
|
||||||
@@ -290,9 +286,15 @@ onMounted(async () => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="less">
|
||||||
:deep(.arco-form-item-content-flex) {
|
:deep(.arco-form-item-content-flex) {
|
||||||
display: block;
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
.arco-radio-group {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-40%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
:deep(.arco-table-cell .arco-form-item) {
|
:deep(.arco-table-cell .arco-form-item) {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
<!--
|
|
||||||
- @Author XXX
|
|
||||||
- @Link XXX
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<td
|
<td
|
||||||
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
<!--
|
|
||||||
- @Author XXX
|
|
||||||
- @Link XXX
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<table
|
<table
|
||||||
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
<!--
|
|
||||||
- @Author XXX
|
|
||||||
- @Link XXX
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
@@ -68,7 +64,7 @@ const columns = inject("columns")
|
|||||||
const rv = async (ev, value = undefined) =>
|
const rv = async (ev, value = undefined) =>
|
||||||
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
//后端传入数字类型导致报错 Invalid prop: type check failed for prop "modelValue". Expected String with value "0", got Number with value 0
|
// 后端传入数字类型导致报错 Invalid prop: type check failed for prop "modelValue". Expected String with value "0", got Number with value 0
|
||||||
const toVal = ref(`${get(formModel.value, index)}`)
|
const toVal = ref(`${get(formModel.value, index)}`)
|
||||||
const value = ref()
|
const value = ref()
|
||||||
if (toVal.value != "undefined") {
|
if (toVal.value != "undefined") {
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
<!--
|
|
||||||
- @Author XXX
|
|
||||||
- @Link XXX
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="props.component.title"
|
:label="props.component.title"
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ const handleStdFormSubmit = async (data, done) => {
|
|||||||
}
|
}
|
||||||
dictList.value["standard"].push(newInfo)
|
dictList.value["standard"].push(newInfo)
|
||||||
// 清空当前数据
|
// 清空当前数据
|
||||||
stdFormData.value = initStdFormData
|
stdFormData.value = { ...initStdFormData }
|
||||||
Notification.success("添加成功,请回到输入框进行选择")
|
Notification.success("添加成功,请回到输入框进行选择")
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Notification.error("请求错误,请重试或在数据管理页面添加")
|
Notification.error("请求错误,请重试或在数据管理页面添加")
|
||||||
|
|||||||
53
cdTMP/src/components/ma-form/formItem/form-steptable.vue
Normal file
53
cdTMP/src/components/ma-form/formItem/form-steptable.vue
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 组件外部的 form-item -->
|
||||||
|
<ma-form-item
|
||||||
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
|
:component="props.component"
|
||||||
|
:custom-field="props.customField"
|
||||||
|
>
|
||||||
|
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
||||||
|
<!-- 调用自己开发的自定义组件,具体名称改成自己的 -->
|
||||||
|
<ChenDemandList v-model="value"></ChenDemandList>
|
||||||
|
</slot>
|
||||||
|
</ma-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// ~~~~start~~~~
|
||||||
|
import ChenDemandList from "../Customs/ChenDemandList.vue"
|
||||||
|
// ~~~~end~~~~
|
||||||
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
|
// 引入处理索引的函数
|
||||||
|
import { get, set } from "lodash-es"
|
||||||
|
// 引入 MaFormItem 组件
|
||||||
|
import MaFormItem from "./form-item.vue"
|
||||||
|
// 引入处理事件的函数
|
||||||
|
import { maEvent } from "../js/formItemMixin.js"
|
||||||
|
// 组件都需要定义以下的props
|
||||||
|
const props = defineProps({
|
||||||
|
component: Object,
|
||||||
|
customField: { type: String, default: undefined }
|
||||||
|
})
|
||||||
|
// form数据列表
|
||||||
|
const formModel = inject("formModel")
|
||||||
|
// 该组件在form数据的索引名称
|
||||||
|
const index = props.customField ?? props.component.dataIndex
|
||||||
|
// 该组件的表单数据
|
||||||
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
|
// 监听组件数据的改变
|
||||||
|
watch(
|
||||||
|
() => get(formModel.value, index),
|
||||||
|
(vl) => (value.value = vl)
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => value.value,
|
||||||
|
(v) => set(formModel.value, index, v)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 绑定组件事件
|
||||||
|
maEvent.handleCommonEvent(props.component, "onCreated")
|
||||||
|
onMounted(() => {
|
||||||
|
maEvent.handleCommonEvent(props.component, "onMounted")
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -1,7 +1,3 @@
|
|||||||
<!--
|
|
||||||
- @Author XXX
|
|
||||||
- @Link XXX
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<a-spin :loading="formLoading" :tip="options.loadingText" class="w-full ma-form-spin">
|
<a-spin :loading="formLoading" :tip="options.loadingText" class="w-full ma-form-spin">
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
测试管理平台
|
测试管理平台
|
||||||
</div>
|
</div>
|
||||||
</a-typography-title>
|
</a-typography-title>
|
||||||
<a-typography-title :heading="6" class="version">V0.0.4</a-typography-title>
|
<a-typography-title :heading="6" class="version">v{{ $version }}</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"
|
||||||
|
|||||||
@@ -191,7 +191,7 @@
|
|||||||
<!-- 关联的modal组件 -->
|
<!-- 关联的modal组件 -->
|
||||||
<a-modal v-model:visible="modalVisible" :width="700" draggable :on-before-ok="handleCopyDemand">
|
<a-modal v-model:visible="modalVisible" :width="700" draggable :on-before-ok="handleCopyDemand">
|
||||||
<template #title>复制到设计需求</template>
|
<template #title>复制到设计需求</template>
|
||||||
<div class="pb-3">选择复制到的节点:</div>
|
<div class="pb-3">选择复制到的节点(<span class="point">支持搜索</span>):</div>
|
||||||
<a-cascader
|
<a-cascader
|
||||||
:options="options"
|
:options="options"
|
||||||
allow-search
|
allow-search
|
||||||
@@ -432,4 +432,7 @@ const {
|
|||||||
.chen-node-title {
|
.chen-node-title {
|
||||||
cursor: help;
|
cursor: help;
|
||||||
}
|
}
|
||||||
|
.point {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -48,11 +48,6 @@ export default function useRoundMaForm(projectId: Ref<string>, handleSoDutExists
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: "速度等级",
|
|
||||||
dataIndex: "speedGrade",
|
|
||||||
placeholder: "请填入速度等级"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: "动态地点",
|
title: "动态地点",
|
||||||
dataIndex: "location",
|
dataIndex: "location",
|
||||||
@@ -82,11 +77,6 @@ export default function useRoundMaForm(projectId: Ref<string>, handleSoDutExists
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: "封装",
|
|
||||||
dataIndex: "package",
|
|
||||||
placeholder: "请填入封装"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: "质量等级",
|
title: "质量等级",
|
||||||
dataIndex: "grade",
|
dataIndex: "grade",
|
||||||
@@ -100,6 +90,7 @@ export default function useRoundMaForm(projectId: Ref<string>, handleSoDutExists
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
placeholder: "请填入质量等级",
|
placeholder: "请填入质量等级",
|
||||||
|
addDefaultValue: "1",
|
||||||
rules: [{ required: true, message: "质量等级必填" }]
|
rules: [{ required: true, message: "质量等级必填" }]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -110,7 +101,7 @@ export default function useRoundMaForm(projectId: Ref<string>, handleSoDutExists
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
formType: "card",
|
formType: "card",
|
||||||
title: "极端工况信息",
|
title: "极端工况信息(FPGA)",
|
||||||
customClass: ["mb-2", "pb-0"],
|
customClass: ["mb-2", "pb-0"],
|
||||||
bodyStyle: { paddingBottom: 0 },
|
bodyStyle: { paddingBottom: 0 },
|
||||||
formList: [
|
formList: [
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ for (const path in modules) {
|
|||||||
app.config.globalProperties.$tool = tool
|
app.config.globalProperties.$tool = tool
|
||||||
app.config.globalProperties.$title = import.meta.env.VITE_APP_TITLE
|
app.config.globalProperties.$title = import.meta.env.VITE_APP_TITLE
|
||||||
app.config.globalProperties.$url = import.meta.env.VITE_APP_BASE
|
app.config.globalProperties.$url = import.meta.env.VITE_APP_BASE
|
||||||
|
app.config.globalProperties.$version = packageJson.version
|
||||||
app.mount("#app")
|
app.mount("#app")
|
||||||
|
|
||||||
// show version tag in console
|
// show version tag in console
|
||||||
|
|||||||
@@ -66,8 +66,9 @@ const useUserStore = defineStore("user", {
|
|||||||
|
|
||||||
// login函数,传一个form信息
|
// login函数,传一个form信息
|
||||||
login(form) {
|
login(form) {
|
||||||
|
const form_data = { username: form.username, password: form.password }
|
||||||
return loginAPI
|
return loginAPI
|
||||||
.login(form)
|
.login(form_data)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.success === true) {
|
if (res.success === true) {
|
||||||
this.setToken(res.data.token)
|
this.setToken(res.data.token)
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 覆盖card组件actions的margin-top,原来为20px
|
// 覆盖card组件actions的margin-top,原来为20px
|
||||||
.arco-card-actions{
|
.arco-card-actions {
|
||||||
margin-top: 0px !important;
|
margin-top: 0px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 覆盖card组件,padding原来为16px
|
// 覆盖card组件,padding原来为16px
|
||||||
.arco-card-body{
|
.arco-card-body {
|
||||||
padding: 8px !important;
|
padding: 8px !important;
|
||||||
}
|
}
|
||||||
@@ -59,6 +59,9 @@ function createService() {
|
|||||||
case 500:
|
case 500:
|
||||||
err("服务器内部错误")
|
err("服务器内部错误")
|
||||||
break
|
break
|
||||||
|
case 400:
|
||||||
|
err("服务器抛出逻辑错误")
|
||||||
|
break
|
||||||
case 401:
|
case 401:
|
||||||
err("登录状态已过期,需要重新登录")
|
err("登录状态已过期,需要重新登录")
|
||||||
// 清楚本地localStorage
|
// 清楚本地localStorage
|
||||||
|
|||||||
@@ -5,3 +5,15 @@ export interface IDictData<T> {
|
|||||||
label: T
|
label: T
|
||||||
value: number
|
value: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产品文件的类型
|
||||||
|
*/
|
||||||
|
export type DocumentType =
|
||||||
|
| "测评大纲"
|
||||||
|
| "测试说明"
|
||||||
|
| "测试记录"
|
||||||
|
| "回归测试说明"
|
||||||
|
| "回归测试记录"
|
||||||
|
| "问题单"
|
||||||
|
| "测评报告"
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { Ref, computed } from "vue"
|
import { Ref, computed } from "vue"
|
||||||
|
import { storeToRefs } from "pinia"
|
||||||
|
import { useAppStore } from "@/store"
|
||||||
|
|
||||||
// 单个每月项目数量对象格式
|
// 单个每月项目数量对象格式
|
||||||
interface IData {
|
interface IData {
|
||||||
@@ -11,6 +13,9 @@ interface ResData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function useVueDataUI(data: Ref<ResData>) {
|
function useVueDataUI(data: Ref<ResData>) {
|
||||||
|
const appStore = useAppStore()
|
||||||
|
const { theme } = storeToRefs(appStore)
|
||||||
|
// 结构pinia储存的主体响应式变量
|
||||||
const initialData = [
|
const initialData = [
|
||||||
{
|
{
|
||||||
name: "项目数量",
|
name: "项目数量",
|
||||||
@@ -29,8 +34,10 @@ function useVueDataUI(data: Ref<ResData>) {
|
|||||||
}
|
}
|
||||||
return initialData
|
return initialData
|
||||||
})
|
})
|
||||||
|
// 暗黑模式识别(这是存在pinia的)
|
||||||
|
const darkMode = document.body.getAttribute("arco-theme")
|
||||||
const initialConfig = {
|
const initialConfig = {
|
||||||
theme: "",
|
theme: darkMode === "dark" ? "celebrationNight" : "",
|
||||||
responsive: false,
|
responsive: false,
|
||||||
customPalette: [],
|
customPalette: [],
|
||||||
downsample: { threshold: 500 },
|
downsample: { threshold: 500 },
|
||||||
@@ -108,7 +115,7 @@ function useVueDataUI(data: Ref<ResData>) {
|
|||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
bold: true,
|
bold: true,
|
||||||
textAlign: "left",
|
textAlign: "left",
|
||||||
paddingLeft: 0,
|
paddingLeft: 5,
|
||||||
paddingRight: 0,
|
paddingRight: 0,
|
||||||
subtitle: { color: "#CCCCCCff", text: "", fontSize: 16, bold: false },
|
subtitle: { color: "#CCCCCCff", text: "", fontSize: 16, bold: false },
|
||||||
show: true
|
show: true
|
||||||
@@ -168,7 +175,10 @@ function useVueDataUI(data: Ref<ResData>) {
|
|||||||
const countData = data.value.data.map((it) => it.count)
|
const countData = data.value.data.map((it) => it.count)
|
||||||
initialConfig.chart.grid.labels.yAxis.scaleMax = Math.max(...countData) ? Math.max(...countData) : 10
|
initialConfig.chart.grid.labels.yAxis.scaleMax = Math.max(...countData) ? Math.max(...countData) : 10
|
||||||
}
|
}
|
||||||
return initialConfig
|
return {
|
||||||
|
...initialConfig,
|
||||||
|
theme: theme.value === "dark" ? "celebrationNight" : ""
|
||||||
|
}
|
||||||
})
|
})
|
||||||
return { chartData, chartConfig }
|
return { chartData, chartConfig }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<div class="text-center leading-[32px]">管理平台版本:</div>
|
<div class="text-center leading-[32px]">管理平台版本:</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 leading-[32px]">
|
<div class="mt-2 leading-[32px]">
|
||||||
<a-tag class="w-fit h-[32px]" color="#0fc6c2">TestPlant V0.0.4</a-tag>
|
<a-tag class="w-fit h-[32px]" color="#0fc6c2">TestPlant v{{ $version }}</a-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -105,10 +105,10 @@ onMounted(async () => {
|
|||||||
width: 75px;
|
width: 75px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 65px;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
|
display: flex;
|
||||||
border-radius: 2px 0 0 2px;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<img class="w-[200px] h-[300px]" src="@/assets/img/ErrorLoad.svg" alt="" />
|
<img class="w-[200px] h-[300px]" src="@/assets/img/ErrorLoad.svg" alt="" />
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<VueUiXy :dataset="chartData" :config="chartConfig" />
|
<VueUiXy :dataset="chartData" :config="chartConfig" :style="{ padding: '10px' }" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
@@ -18,12 +18,14 @@ import commonApi from "@/api/common"
|
|||||||
import { VueUiXy } from "vue-data-ui"
|
import { VueUiXy } from "vue-data-ui"
|
||||||
import useVueDataUI from "@/views/dashboard/workplace/components/cpns/hooks/vueDataUI"
|
import useVueDataUI from "@/views/dashboard/workplace/components/cpns/hooks/vueDataUI"
|
||||||
import { useQuery } from "@tanstack/vue-query"
|
import { useQuery } from "@tanstack/vue-query"
|
||||||
|
|
||||||
// vue-query请求图表接口
|
// vue-query请求图表接口
|
||||||
const { isPending, data, isError } = useQuery({
|
const { isPending, data, isError } = useQuery({
|
||||||
queryKey: ["chart"],
|
queryKey: ["chart"],
|
||||||
queryFn: commonApi.getChartData,
|
queryFn: commonApi.getChartData,
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
})
|
})
|
||||||
|
|
||||||
// vue-data-ui图表
|
// vue-data-ui图表
|
||||||
const { chartData, chartConfig } = useVueDataUI(data)
|
const { chartData, chartConfig } = useVueDataUI(data)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -108,7 +108,6 @@ import { useUserStore } from "@/store"
|
|||||||
import { useRouter, useRoute } from "vue-router"
|
import { useRouter, useRoute } from "vue-router"
|
||||||
import userApi from "@/api/system/user"
|
import userApi from "@/api/system/user"
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
// 绑定登录form的数据
|
// 绑定登录form的数据
|
||||||
// const form = reactive({ username: "superAdmin", password: "admin123", code: "" })
|
// const form = reactive({ username: "superAdmin", password: "admin123", code: "" })
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { defineComponent } from "vue"
|
import { defineComponent, ref } from "vue"
|
||||||
import { TreeNodeData } from "@arco-design/web-vue"
|
import { TreeNodeData } from "@arco-design/web-vue"
|
||||||
import { useTreeDataStore } from "@/store"
|
import { useTreeDataStore } from "@/store"
|
||||||
import testDemandAPI from "@/api/project/testDemand"
|
import testDemandAPI from "@/api/project/testDemand"
|
||||||
import useOptions from "./useOptions"
|
import useOptions from "./useOptions"
|
||||||
import subFormHooks from "@/views/project/projPublicHooks/subFormHooks"
|
import subFormHooks from "@/views/project/projPublicHooks/subFormHooks"
|
||||||
|
import useBeforeCancel from "@/views/project/projPublicHooks/useBeforeCancel"
|
||||||
|
import { cloneDeep } from "lodash-es"
|
||||||
|
|
||||||
const DemandSubForm = defineComponent({
|
const DemandSubForm = defineComponent({
|
||||||
name: "DemandSubFormForm",
|
name: "DemandSubFormForm",
|
||||||
@@ -25,6 +27,8 @@ const DemandSubForm = defineComponent({
|
|||||||
// 设置表单名称
|
// 设置表单名称
|
||||||
title.value = nodeData.title!
|
title.value = nodeData.title!
|
||||||
const res = await testDemandAPI.getTestDemandOne({ project_id, key }) // **API变化**
|
const res = await testDemandAPI.getTestDemandOne({ project_id, key }) // **API变化**
|
||||||
|
// 得到数据时候将beforeFormContent搞定
|
||||||
|
beforeFormContent.value = cloneDeep(res.data.testContent)
|
||||||
// 更新表单
|
// 更新表单
|
||||||
formData.value = res.data // **属性变化**
|
formData.value = res.data // **属性变化**
|
||||||
formData.value.round = key.split("-")[0]
|
formData.value.round = key.split("-")[0]
|
||||||
@@ -38,10 +42,13 @@ const DemandSubForm = defineComponent({
|
|||||||
// out use
|
// out use
|
||||||
expose({ open })
|
expose({ open })
|
||||||
|
|
||||||
|
// hook-判断是否更变内容关闭-只用于测试项和测试用例
|
||||||
|
const beforeFormContent = ref<any>(undefined)
|
||||||
|
const { handleBeforeCancel } = useBeforeCancel(formData, beforeFormContent, visible)
|
||||||
// Dom
|
// Dom
|
||||||
return () => (
|
return () => (
|
||||||
// 注意v-model:visible是不能放在对象解构的
|
// 注意v-model:visible是不能放在对象解构的
|
||||||
<a-modal {...modalOptions} v-model:visible={visible.value}>
|
<a-modal {...modalOptions} v-model:visible={visible.value} on-before-cancel={handleBeforeCancel}>
|
||||||
{{
|
{{
|
||||||
title: () => <span>[设计需求]-{title.value}</span>,
|
title: () => <span>[设计需求]-{title.value}</span>,
|
||||||
default: () => (
|
default: () => (
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export default function (crudOrFormRef: any) {
|
|||||||
dict: { name: "testType", translation: true, props: { label: "title", value: "key" } },
|
dict: { name: "testType", translation: true, props: { label: "title", value: "key" } },
|
||||||
extra: "支持拼音搜索,例如:gn可以搜索出功能测试",
|
extra: "支持拼音搜索,例如:gn可以搜索出功能测试",
|
||||||
// 这是arco的属性,所以在ma-crud和ma-form可以直接使用arco属性和事件(事件+onXXX)
|
// 这是arco的属性,所以在ma-crud和ma-form可以直接使用arco属性和事件(事件+onXXX)
|
||||||
filterOption: function (inputValue, selectedOption) {
|
filterOption: function (inputValue: any, selectedOption: any) {
|
||||||
if (inputValue) {
|
if (inputValue) {
|
||||||
let matchRes = PinYinMatch.match(selectedOption.label, inputValue)
|
let matchRes = PinYinMatch.match(selectedOption.label, inputValue)
|
||||||
if (matchRes) {
|
if (matchRes) {
|
||||||
@@ -91,7 +91,7 @@ export default function (crudOrFormRef: any) {
|
|||||||
dataIndex: "testDesciption",
|
dataIndex: "testDesciption",
|
||||||
formType: "textarea",
|
formType: "textarea",
|
||||||
maxLength: 256,
|
maxLength: 256,
|
||||||
placeholder: "FPGA-老版本需填写!!!"
|
placeholder: "请填写整体测试项的描述"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "测试子项",
|
title: "测试子项",
|
||||||
@@ -99,53 +99,28 @@ export default function (crudOrFormRef: any) {
|
|||||||
dataIndex: "testContent",
|
dataIndex: "testContent",
|
||||||
commonRules: [{ required: true, message: "测试方法是必填的" }],
|
commonRules: [{ required: true, message: "测试方法是必填的" }],
|
||||||
formType: "children-form",
|
formType: "children-form",
|
||||||
|
type: "group",
|
||||||
formList: [
|
formList: [
|
||||||
{
|
{
|
||||||
title: "子项名称",
|
title: "子项名称",
|
||||||
dataIndex: "subName",
|
dataIndex: "subName",
|
||||||
placeholder: "对应测试项描述标题,和测试方法的标题",
|
placeholder: "对应测试项描述标题,和测试方法的标题",
|
||||||
rules: [{ required: true, message: "测试子项名称必填" }],
|
rules: [{ required: true, message: "测试子项名称必填" }],
|
||||||
onChange: (ev) => {
|
onChange: (ev: any) => {
|
||||||
// 取出子项的对象数组
|
// 取出子项的对象数组
|
||||||
const subItemFormData = crudOrFormRef.value.getFormData().testContent
|
const subItemFormData = crudOrFormRef.value.getFormData().testContent
|
||||||
// 取出充分性条件字段字符串
|
// 取出充分性条件字段字符串
|
||||||
const mapRes = subItemFormData.map((subItem) => subItem.subName)
|
const mapRes = subItemFormData.map((subItem: any) => subItem.subName)
|
||||||
crudOrFormRef.value.getFormData().adequacy = `测试用例覆盖${mapRes.join(
|
crudOrFormRef.value.getFormData().adequacy = `测试用例覆盖${mapRes.join(
|
||||||
"、"
|
"、"
|
||||||
)}子项要求的全部内容。\n所有用例执行完毕,对于未执行的用例说明未执行原因。`
|
)}子项要求的全部内容。\n所有用例执行完毕,对于未执行的用例说明未执行原因。`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "子项描述",
|
title: "操作与预期",
|
||||||
dataIndex: "subDesc",
|
dataIndex: "subStep",
|
||||||
formType: "textarea",
|
formType: "steptable"
|
||||||
placeholder: "对应大纲测试项表格的测试项描述,FPGA-老模版不用填写!!!"
|
|
||||||
// rules: [{ required: true, message: "测试子项描述必填" }]
|
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: "条件",
|
|
||||||
dataIndex: "condition",
|
|
||||||
formType: "textarea",
|
|
||||||
placeholder: "在什么环境和前置条件下"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "操作",
|
|
||||||
dataIndex: "operation",
|
|
||||||
formType: "textarea",
|
|
||||||
placeholder: "通过xxx操作"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "观察",
|
|
||||||
dataIndex: "observe",
|
|
||||||
formType: "textarea",
|
|
||||||
placeholder: "查看xxx内容"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "期望",
|
|
||||||
dataIndex: "expect",
|
|
||||||
formType: "textarea",
|
|
||||||
placeholder: "xxx结果正确"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|||||||
32
cdTMP/src/views/project/projPublicHooks/useBeforeCancel.ts
Normal file
32
cdTMP/src/views/project/projPublicHooks/useBeforeCancel.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { isEqual } from "lodash-es"
|
||||||
|
import { getCurrentInstance } from "vue"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 该hook为测试项子项和测试用例步骤设计,当其改变时候弹窗通知用户
|
||||||
|
*/
|
||||||
|
export default function useBeforeCancel(formData: any, beforeFormContent: any, visible: any) {
|
||||||
|
const app = getCurrentInstance()!.appContext.config.globalProperties
|
||||||
|
const handleBeforeCancel = () => {
|
||||||
|
if (!beforeFormContent.value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
const content = formData.value.testContent || formData.value.testStep
|
||||||
|
const iuEqualValue = isEqual(content, beforeFormContent.value)
|
||||||
|
!iuEqualValue &&
|
||||||
|
app.$modal.confirm({
|
||||||
|
title: "测试项步骤内容你已改动,是否保留您编写的测试项/测试用例步骤数据?",
|
||||||
|
content: "",
|
||||||
|
okText: "返回重新编辑",
|
||||||
|
cancelText: "取消",
|
||||||
|
simple: true,
|
||||||
|
onOk: () => {
|
||||||
|
visible.value = true
|
||||||
|
},
|
||||||
|
onCancel: () => {}
|
||||||
|
})
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
handleBeforeCancel
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
import { defineComponent } from "vue"
|
import { defineComponent, ref } from "vue"
|
||||||
import { Message, TreeNodeData } from "@arco-design/web-vue"
|
import { Message, TreeNodeData } from "@arco-design/web-vue"
|
||||||
import { useTreeDataStore } from "@/store"
|
import { useTreeDataStore } from "@/store"
|
||||||
import caseApi from "@/api/project/case"
|
import caseApi from "@/api/project/case"
|
||||||
import useOptions from "./useOptions"
|
import useOptions from "./useOptions"
|
||||||
import subFormHooks from "@/views/project/projPublicHooks/subFormHooks"
|
import subFormHooks from "@/views/project/projPublicHooks/subFormHooks"
|
||||||
|
import useBeforeCancel from "@/views/project/projPublicHooks/useBeforeCancel"
|
||||||
|
import { cloneDeep } from "lodash-es"
|
||||||
|
|
||||||
const CaseSubForm = defineComponent({
|
const CaseSubForm = defineComponent({
|
||||||
name: "DemandSubFormForm",
|
name: "DemandSubFormForm",
|
||||||
@@ -26,6 +28,8 @@ const CaseSubForm = defineComponent({
|
|||||||
title.value = nodeData.title!
|
title.value = nodeData.title!
|
||||||
// 注意这里因为case接口原因,这里需要projectId!!!!!!!!!!!!!!!
|
// 注意这里因为case接口原因,这里需要projectId!!!!!!!!!!!!!!!
|
||||||
const res = await caseApi.getCaseOne({ projectId: project_id, key }) // **API变化**
|
const res = await caseApi.getCaseOne({ projectId: project_id, key }) // **API变化**
|
||||||
|
// 得到数据时候将beforeFormContent搞定
|
||||||
|
beforeFormContent.value = cloneDeep(res.data.testStep)
|
||||||
// 更新表单
|
// 更新表单
|
||||||
formData.value = res.data // **属性变化**
|
formData.value = res.data // **属性变化**
|
||||||
formData.value.round = key.split("-")[0]
|
formData.value.round = key.split("-")[0]
|
||||||
@@ -41,10 +45,14 @@ const CaseSubForm = defineComponent({
|
|||||||
// out use
|
// out use
|
||||||
expose({ open })
|
expose({ open })
|
||||||
|
|
||||||
|
// hook-判断是否更变内容关闭-只用于测试项和测试用例
|
||||||
|
const beforeFormContent = ref<any>(undefined)
|
||||||
|
const { handleBeforeCancel } = useBeforeCancel(formData, beforeFormContent, visible)
|
||||||
|
|
||||||
// Dom
|
// Dom
|
||||||
return () => (
|
return () => (
|
||||||
// 注意v-model:visible是不能放在对象解构的
|
// 注意v-model:visible是不能放在对象解构的
|
||||||
<a-modal {...modalOptions} v-model:visible={visible.value}>
|
<a-modal {...modalOptions} v-model:visible={visible.value} on-before-cancel={handleBeforeCancel}>
|
||||||
{{
|
{{
|
||||||
title: () => <span>[设计需求]-{title.value}</span>,
|
title: () => <span>[设计需求]-{title.value}</span>,
|
||||||
default: () => (
|
default: () => (
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export default function (crudOrFormRef: any, problemFormRef?: any) {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
formType: "children-form",
|
formType: "children-form",
|
||||||
type: "group",
|
type: "group", // 注意这里可能改样式"group"/"table"
|
||||||
formList: [
|
formList: [
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<div class="hg-doc-upload-container">
|
||||||
|
<div v-if="roundNum === 0">
|
||||||
|
<a-alert type="warning">暂无回归测试轮次信息</a-alert>
|
||||||
|
</div>
|
||||||
|
<a-tabs v-else :default-active-key="1" type="line">
|
||||||
|
<a-tab-pane v-for="n in roundNum" :key="n" :title="`第${n + 1}轮${documentType}`">
|
||||||
|
<a-upload
|
||||||
|
:action="`/api/documentUpload/file?id=${projectId}&documentType=${documentType}&round_num=${n + 1}`"
|
||||||
|
:limit="1"
|
||||||
|
accept=".docx, application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
||||||
|
@error="uploadErrorHandle"
|
||||||
|
@before-upload="confirmUploadHandle"
|
||||||
|
>
|
||||||
|
<template #upload-button>
|
||||||
|
<a-button type="primary"><icon-upload />点击上传</a-button>
|
||||||
|
</template>
|
||||||
|
</a-upload>
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
/* 该组件是回归测试说明、回归测试记录上传逻辑组件 */
|
||||||
|
import { onMounted, ref } from "vue"
|
||||||
|
import otherApi from "@/api/generate/other"
|
||||||
|
import { Message, Modal } from "@arco-design/web-vue"
|
||||||
|
|
||||||
|
// props
|
||||||
|
const { projectId, documentType } = defineProps<{ projectId: number | null; documentType: string }>()
|
||||||
|
|
||||||
|
// 组件加载时候就请求后端,有几个轮次
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
if (!projectId) return
|
||||||
|
const {
|
||||||
|
data: { count }
|
||||||
|
} = await otherApi.getHgRoundNumber({ id: projectId })
|
||||||
|
// count为非第一轮其他轮次数量
|
||||||
|
roundNum.value = count
|
||||||
|
} catch (err) {
|
||||||
|
roundNum.value = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// ref - 定义非第一轮轮次数量
|
||||||
|
const roundNum = ref(0)
|
||||||
|
|
||||||
|
// 上传失败的事件 - 报错内容由后端定义(message字段)
|
||||||
|
const uploadErrorHandle = (fielItem: any) => {
|
||||||
|
const res = JSON.parse(fielItem.response)
|
||||||
|
if (res.message) {
|
||||||
|
Message.error(res.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上传弹窗事件
|
||||||
|
const confirmUploadHandle = (file: any) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: "请确认您上传的文件是带有文档片段的docx文档",
|
||||||
|
content: `${file.name}`,
|
||||||
|
onOk: () => resolve(true),
|
||||||
|
onCancel: () => reject("cancel")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "HgDocUpload"
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
283
cdTMP/src/views/testmanage/projmanage/GeneratorModal/index.vue
Normal file
283
cdTMP/src/views/testmanage/projmanage/GeneratorModal/index.vue
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 该组件是点击生成的弹出框 -->
|
||||||
|
<div class="create-modal-container">
|
||||||
|
<a-modal v-model:visible="visible" unmount-on-close render-to-body width="50%" hide-cancel :footer="false">
|
||||||
|
<template #title> {{ title }}上传下载 </template>
|
||||||
|
<a-list class="alist">
|
||||||
|
<template #header>上传您的{{ title }}:</template>
|
||||||
|
<a-list-item>
|
||||||
|
<!-- 文件上传:回归测试说明、回归测试记录 -->
|
||||||
|
<div v-if="title === '回归测试说明' || title === '回归测试记录'">
|
||||||
|
<HgDocUpload :project-id="projectId" :document-type="title" />
|
||||||
|
</div>
|
||||||
|
<!-- 文件上传:其他文档 -->
|
||||||
|
<div v-else>
|
||||||
|
<a-upload
|
||||||
|
:action="`/api/documentUpload/file?id=${projectId}&documentType=${title}`"
|
||||||
|
:limit="1"
|
||||||
|
accept=".docx, application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
||||||
|
@error="uploadErrorHandle"
|
||||||
|
@before-upload="confirmUploadHandle"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</a-list-item>
|
||||||
|
</a-list>
|
||||||
|
<!-- 文档片段覆盖选取 -->
|
||||||
|
<div v-if="fragmentList.length">
|
||||||
|
<a-list :loading="fragmentListPending" hoverable size="small">
|
||||||
|
<template #header>选取需要被覆盖的文档片段:</template>
|
||||||
|
<a-list-item>
|
||||||
|
<div class="buttonAndAlert">
|
||||||
|
<a-alert type="warning">首次生成请全勾选</a-alert>
|
||||||
|
<div class="button-list">
|
||||||
|
<a-button type="primary" status="success" @click="allCheckBtn">全勾选</a-button>
|
||||||
|
<a-button type="primary" status="warning" @click="allUnCheckBtn">全不勾选</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-list-item>
|
||||||
|
<a-list-item v-for="(frag, index) in fragmentList" :key="index">
|
||||||
|
<div class="fragment-item">
|
||||||
|
<div class="fragment-name">{{ frag.name }}</div>
|
||||||
|
<a-divider direction="vertical" />
|
||||||
|
<a-switch v-model="frag.isCover"></a-switch>
|
||||||
|
</div>
|
||||||
|
</a-list-item>
|
||||||
|
</a-list>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<a-list :loading="fragmentListPending" hoverable size="small">
|
||||||
|
<template #header>选取需要被覆盖的文档片段:</template>
|
||||||
|
<a-list-item>
|
||||||
|
<Empty text="未找到文档片段,请先下载" />
|
||||||
|
</a-list-item>
|
||||||
|
</a-list>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a-list class="alist">
|
||||||
|
<a-list-item>
|
||||||
|
<div class="button-list">
|
||||||
|
<a-button :loading="isGenerating" type="primary" @click="downloadHandle">
|
||||||
|
确认并下载
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</a-list-item>
|
||||||
|
</a-list>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
<Progress
|
||||||
|
:visible="progressVisible"
|
||||||
|
:isComplete="isComplete"
|
||||||
|
:text="title"
|
||||||
|
@clickConfirm="handleModalConfirmClick"
|
||||||
|
></Progress>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { DocumentType } from "@/utils/types/CommonType" // 产品文档类型
|
||||||
|
import { ref } from "vue"
|
||||||
|
import fragmentApi from "@/api/generate/fragment" // 获取某项目某测试文档的片段api
|
||||||
|
import Empty from "@/components/Empty/index.vue" // 空状态组件
|
||||||
|
import HgDocUpload from "@/views/testmanage/projmanage/GeneratorModal/HgDocUpload/index.vue"
|
||||||
|
import Progress from "@/views/testmanage/projmanage/cpns/progress.vue"
|
||||||
|
import { Message, Modal } from "@arco-design/web-vue"
|
||||||
|
import useGenerateSecond from "../hooks/useGenerateSecond"
|
||||||
|
import useSeitaiModal from "../hooks/useSeitaiModal"
|
||||||
|
|
||||||
|
// 定义覆盖文档片段每项类型
|
||||||
|
export interface IFragmentItem {
|
||||||
|
name: string
|
||||||
|
isCover: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~1.文档片段展示功能~~~~
|
||||||
|
const visible = ref(false) // v-model:显式隐藏modal
|
||||||
|
const title = ref("测评大纲") // modal的标题
|
||||||
|
const projectId = ref<number | null>(null) // 传入的项目id
|
||||||
|
const fragmentListPending = ref(false) // 片段列表请求的loading状态
|
||||||
|
// 定义文档片段储存
|
||||||
|
const fragmentList = ref<IFragmentItem[]>([])
|
||||||
|
|
||||||
|
// out:暴露出去的函数
|
||||||
|
const open = async (documentType: DocumentType, id: number) => {
|
||||||
|
projectId.value = id // 传入的项目id
|
||||||
|
title.value = documentType
|
||||||
|
visible.value = true
|
||||||
|
// 打开时清空fragmentList数据
|
||||||
|
fragmentList.value = []
|
||||||
|
// 打开时请求数据
|
||||||
|
fragmentListPending.value = true // 设置loading状态
|
||||||
|
// 请求片段列表数据
|
||||||
|
try {
|
||||||
|
const { data } = await fragmentApi.getFragmentByDocumentType({
|
||||||
|
id: projectId.value,
|
||||||
|
documentType
|
||||||
|
})
|
||||||
|
// 填充到fragmentList
|
||||||
|
fragmentList.value = data.map((it: string) => ({
|
||||||
|
name: it,
|
||||||
|
isCover: false
|
||||||
|
}))
|
||||||
|
fragmentListPending.value = false
|
||||||
|
} catch (err) {
|
||||||
|
fragmentListPending.value = false // 请求失败,关闭loading状态
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全勾选/全不勾选按钮
|
||||||
|
const allCheckBtn = () => {
|
||||||
|
fragmentList.value.forEach((item) => {
|
||||||
|
item.isCover = true // 全部勾选
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const allUnCheckBtn = () => {
|
||||||
|
fragmentList.value.forEach((item) => {
|
||||||
|
item.isCover = false // 全部不勾选
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~2.文件上传功能~~~~
|
||||||
|
// 上传失败的事件 - 报错内容由后端定义(message字段)
|
||||||
|
const uploadErrorHandle = (fielItem: any) => {
|
||||||
|
const res = JSON.parse(fielItem.response)
|
||||||
|
if (res.message) {
|
||||||
|
Message.error(res.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上传弹窗事件
|
||||||
|
const confirmUploadHandle = (file: any) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: "请确认您上传的文件是带有文档片段的docx文档",
|
||||||
|
content: `${file.name}`,
|
||||||
|
onOk: () => resolve(true),
|
||||||
|
onCancel: () => reject("cancel")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~3.产品文档下载功能~~~~
|
||||||
|
// 注意二段文档生成成功后,需要刷新片段列表数据(待完成)
|
||||||
|
const downloadHandle = async () => {
|
||||||
|
// 判断产品文档类型
|
||||||
|
const documentType = title.value
|
||||||
|
try {
|
||||||
|
// 二段文档异步请求
|
||||||
|
switch (documentType) {
|
||||||
|
case "测评大纲":
|
||||||
|
await createDgItem(projectId.value!)
|
||||||
|
break
|
||||||
|
case "测试说明":
|
||||||
|
await createSmItem(projectId.value!)
|
||||||
|
break
|
||||||
|
case "测试记录":
|
||||||
|
await createJLItem(projectId.value!)
|
||||||
|
break
|
||||||
|
case "回归测试说明":
|
||||||
|
await createHsmItem(projectId.value!)
|
||||||
|
break
|
||||||
|
case "回归测试记录":
|
||||||
|
await createHjlItem(projectId.value!)
|
||||||
|
break
|
||||||
|
case "问题单":
|
||||||
|
await createWtdItem(projectId.value!)
|
||||||
|
break
|
||||||
|
case "测评报告":
|
||||||
|
await createBgItem(projectId.value!)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// 生成最终产品文档请求 -> 添加当前用户取消选择的片段
|
||||||
|
switch (documentType) {
|
||||||
|
case "测评大纲":
|
||||||
|
await createSeitaiDagang(projectId.value!, documentType, fragmentList.value)
|
||||||
|
break
|
||||||
|
case "测试说明":
|
||||||
|
await createSeitaiShuoming(projectId.value!, documentType, fragmentList.value)
|
||||||
|
break
|
||||||
|
case "测试记录":
|
||||||
|
await createSeitaiJilu(projectId.value!, documentType, fragmentList.value)
|
||||||
|
break
|
||||||
|
case "回归测试说明":
|
||||||
|
await createSeitaiHsm(projectId.value!, documentType, fragmentList.value)
|
||||||
|
break
|
||||||
|
case "回归测试记录":
|
||||||
|
await createSeitaiHjl(projectId.value!, documentType, fragmentList.value)
|
||||||
|
break
|
||||||
|
case "问题单":
|
||||||
|
await createSeitaiWtd(projectId.value!, documentType, fragmentList.value)
|
||||||
|
break
|
||||||
|
case "测评报告":
|
||||||
|
await createSeitaiBaogao(projectId.value!, documentType, fragmentList.value)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// 为了方便直接关闭弹窗,这样用户可以使用open函数初始化
|
||||||
|
visible.value = false
|
||||||
|
} catch (err) {
|
||||||
|
// 总体出错处理,关闭弹窗
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// hook-二段文档函数
|
||||||
|
const {
|
||||||
|
isGenerating,
|
||||||
|
createDgItem,
|
||||||
|
createSmItem,
|
||||||
|
createJLItem,
|
||||||
|
createHsmItem,
|
||||||
|
createHjlItem,
|
||||||
|
createWtdItem,
|
||||||
|
createBgItem
|
||||||
|
} = useGenerateSecond()
|
||||||
|
|
||||||
|
// hook-生成产品文档
|
||||||
|
const {
|
||||||
|
visible: progressVisible,
|
||||||
|
isComplete,
|
||||||
|
handleModalConfirmClick,
|
||||||
|
createSeitaiDagang,
|
||||||
|
createSeitaiShuoming,
|
||||||
|
createSeitaiJilu,
|
||||||
|
createSeitaiHsm,
|
||||||
|
createSeitaiHjl,
|
||||||
|
createSeitaiWtd,
|
||||||
|
createSeitaiBaogao
|
||||||
|
} = useSeitaiModal()
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "GeneratorModal"
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.fragment-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
.fragment-name {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-list {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alist {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.buttonAndAlert {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -4,23 +4,31 @@ export default {
|
|||||||
/**
|
/**
|
||||||
* 生成最终产品文档的进度条模块
|
* 生成最终产品文档的进度条模块
|
||||||
*/
|
*/
|
||||||
async create_entire_doc(visible, isComplete, api, record_id, docName) {
|
async create_entire_doc(visible, isComplete, api, record_id, docName, fragmentList) {
|
||||||
visible.value = true
|
visible.value = true
|
||||||
isComplete.value = false
|
isComplete.value = false
|
||||||
const st = await api({ id: record_id }).catch((err) => {
|
try {
|
||||||
isComplete.value = true
|
const st = await api({ id: record_id, frag: fragmentList })
|
||||||
visible.value = false
|
// 动态生成文件名
|
||||||
})
|
const fileType = st.type
|
||||||
|
const fileExt = fileType.includes("zip") ? "zip" : "docx"
|
||||||
|
const fileName = `${docName}.${fileExt}`
|
||||||
// 下面是创建后Blob并触发下载
|
// 下面是创建后Blob并触发下载
|
||||||
const blob = new Blob([st], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" })
|
const blob = new Blob([st], {
|
||||||
|
type: fileType
|
||||||
|
})
|
||||||
const url = window.URL.createObjectURL(blob)
|
const url = window.URL.createObjectURL(blob)
|
||||||
const a = document.createElement("a")
|
const a = document.createElement("a")
|
||||||
a.href = url
|
a.href = url
|
||||||
a.download = `${docName}.docx` // 设置下载文件名
|
a.download = fileName // 设置文件名(动态)
|
||||||
a.click()
|
a.click()
|
||||||
window.URL.revokeObjectURL(url) // 释放 URL 对象
|
window.URL.revokeObjectURL(url) // 释放 URL 对象
|
||||||
// 上面是触发下载
|
// 上面是触发下载
|
||||||
isComplete.value = true
|
isComplete.value = true
|
||||||
Message.success("文档生成并下载成功!")
|
Message.success("文档生成并下载成功!")
|
||||||
|
} catch (err) {
|
||||||
|
isComplete.value = true
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ const useCrudInit = function () {
|
|||||||
rowSelection: { showCheckedAll: true },
|
rowSelection: { showCheckedAll: true },
|
||||||
api: projectApi.getPageList,
|
api: projectApi.getPageList,
|
||||||
add: { show: true, api: projectApi.save, text: "新增项目" },
|
add: { show: true, api: projectApi.save, text: "新增项目" },
|
||||||
edit: { show: true, api: projectApi.update, text: "编辑项目" }, // auth未空数组则所有都可以
|
edit: { show: true, api: projectApi.update, text: "编辑" }, // auth未空数组则所有都可以
|
||||||
delete: { show: true, api: projectApi.delete },
|
delete: { show: true, api: projectApi.delete },
|
||||||
searchColNumber: 3,
|
searchColNumber: 3,
|
||||||
tablePagination: false,
|
tablePagination: false,
|
||||||
operationColumn: true,
|
operationColumn: true,
|
||||||
operationWidth: 500,
|
operationWidth: 500,
|
||||||
showIndex: false,
|
showIndex: false,
|
||||||
operationColumnWidth: 280, // 操作列宽度
|
operationColumnWidth: 400, // 操作列宽度
|
||||||
operationColumnAlign: "center", // 操作列对齐方式
|
operationColumnAlign: "center", // 操作列对齐方式
|
||||||
afterDelete(response: any) {
|
afterDelete(response: any) {
|
||||||
crudRef.value.tableRef.selectAll(false)
|
crudRef.value.tableRef.selectAll(false)
|
||||||
@@ -37,17 +37,8 @@ const useCrudInit = function () {
|
|||||||
{
|
{
|
||||||
formType: "grid",
|
formType: "grid",
|
||||||
cols: [
|
cols: [
|
||||||
{ span: 8, formList: [{ dataIndex: "ident" }] },
|
{ span: 4, formList: [{ dataIndex: "ident" }] },
|
||||||
{ span: 8, formList: [{ dataIndex: "name" }] },
|
{ span: 8, formList: [{ dataIndex: "name" }] }
|
||||||
{ span: 8, formList: [{ dataIndex: "engin_model" }] }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
formType: "grid",
|
|
||||||
cols: [
|
|
||||||
{ span: 8, formList: [{ dataIndex: "section_system" }] },
|
|
||||||
{ span: 8, formList: [{ dataIndex: "sub_system" }] },
|
|
||||||
{ span: 8, formList: [{ dataIndex: "device" }] }
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -150,7 +141,7 @@ const useCrudInit = function () {
|
|||||||
{
|
{
|
||||||
title: "项目标识",
|
title: "项目标识",
|
||||||
align: "center",
|
align: "center",
|
||||||
width: 90,
|
width: 80,
|
||||||
sortable: { sortDirections: ["ascend"] },
|
sortable: { sortDirections: ["ascend"] },
|
||||||
dataIndex: "ident",
|
dataIndex: "ident",
|
||||||
search: true,
|
search: true,
|
||||||
@@ -163,28 +154,26 @@ const useCrudInit = function () {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "项目名称",
|
title: "项目名称",
|
||||||
width: 110,
|
width: 120,
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: "name",
|
dataIndex: "name",
|
||||||
search: true,
|
search: true,
|
||||||
commonRules: [{ required: true, message: "名称是必填" }]
|
commonRules: [{ required: true, message: "名称是必填" }]
|
||||||
},
|
},
|
||||||
{ title: "工程型号", dataIndex: "engin_model", hide: true },
|
|
||||||
{ title: "分系统", dataIndex: "section_system", hide: true },
|
|
||||||
{ title: "子系统", dataIndex: "sub_system", hide: true },
|
|
||||||
{ title: "设备名称", dataIndex: "device", hide: true },
|
|
||||||
{
|
{
|
||||||
title: "开始日期",
|
title: "开始日期",
|
||||||
dataIndex: "beginTime",
|
dataIndex: "beginTime",
|
||||||
align: "center",
|
align: "center",
|
||||||
commonRules: [{ required: true, message: "开始时间必填" }],
|
commonRules: [{ required: true, message: "开始时间必填" }],
|
||||||
formType: "date"
|
formType: "date",
|
||||||
|
width: 110
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "结束时间",
|
title: "结束时间",
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: "endTime",
|
dataIndex: "endTime",
|
||||||
formType: "date",
|
formType: "date",
|
||||||
|
width: 110,
|
||||||
extra: "注意:结束时间需要晚于最后一轮结束时间",
|
extra: "注意:结束时间需要晚于最后一轮结束时间",
|
||||||
commonRules: [
|
commonRules: [
|
||||||
{
|
{
|
||||||
@@ -212,7 +201,7 @@ const useCrudInit = function () {
|
|||||||
{
|
{
|
||||||
title: "责任人",
|
title: "责任人",
|
||||||
align: "center",
|
align: "center",
|
||||||
width: 70,
|
width: 50,
|
||||||
dataIndex: "duty_person",
|
dataIndex: "duty_person",
|
||||||
search: true,
|
search: true,
|
||||||
commonRules: [{ required: true, message: "责任人必选" }],
|
commonRules: [{ required: true, message: "责任人必选" }],
|
||||||
@@ -352,6 +341,7 @@ const useCrudInit = function () {
|
|||||||
align: "center",
|
align: "center",
|
||||||
addDefaultValue: "9",
|
addDefaultValue: "9",
|
||||||
search: true,
|
search: true,
|
||||||
|
width: 70,
|
||||||
commonRules: [{ required: true, message: "报告类型必填" }],
|
commonRules: [{ required: true, message: "报告类型必填" }],
|
||||||
// 字典-report_type
|
// 字典-report_type
|
||||||
formType: "radio",
|
formType: "radio",
|
||||||
@@ -371,7 +361,7 @@ const useCrudInit = function () {
|
|||||||
{
|
{
|
||||||
title: "依据标准",
|
title: "依据标准",
|
||||||
dataIndex: "standard",
|
dataIndex: "standard",
|
||||||
addDefaultValue: ["1", "2", "3", "4", "9"],
|
addDefaultValue: ["16", "2", "17", "3", "7", "4", "5", "6"],
|
||||||
maxTagCount: 20,
|
maxTagCount: 20,
|
||||||
commonRules: [{ required: true, message: "请至少选择一个" }],
|
commonRules: [{ required: true, message: "请至少选择一个" }],
|
||||||
hide: true,
|
hide: true,
|
||||||
@@ -510,6 +500,7 @@ const useCrudInit = function () {
|
|||||||
{
|
{
|
||||||
title: "状态",
|
title: "状态",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
width: 80,
|
||||||
dataIndex: "step",
|
dataIndex: "step",
|
||||||
search: true,
|
search: true,
|
||||||
formType: "radio",
|
formType: "radio",
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* 该文件是配合请求后端生成各文档的二段文档
|
||||||
|
*/
|
||||||
import { ref } from "vue"
|
import { ref } from "vue"
|
||||||
import dgGenerateApi from "@/api/generate/dgGenerate"
|
import dgGenerateApi from "@/api/generate/dgGenerate"
|
||||||
import smGenerateApi from "@/api/generate/smGenerate"
|
import smGenerateApi from "@/api/generate/smGenerate"
|
||||||
@@ -6,7 +9,6 @@ import bgGenerateApi from "@/api/generate/bgGenerate"
|
|||||||
import hsmGenerateApi from "@/api/generate/hsmGenerate"
|
import hsmGenerateApi from "@/api/generate/hsmGenerate"
|
||||||
import hjlGenerateApi from "@/api/generate/hjlGenerate"
|
import hjlGenerateApi from "@/api/generate/hjlGenerate"
|
||||||
import wtdGenerateApi from "@/api/generate/wtdGenerate"
|
import wtdGenerateApi from "@/api/generate/wtdGenerate"
|
||||||
import { Message } from "@arco-design/web-vue"
|
|
||||||
|
|
||||||
const useGenerateSecond = function () {
|
const useGenerateSecond = function () {
|
||||||
// refs
|
// refs
|
||||||
@@ -20,53 +22,10 @@ const useGenerateSecond = function () {
|
|||||||
const ishjlLoading = ref(false)
|
const ishjlLoading = ref(false)
|
||||||
const isWtdLoading = ref(false)
|
const isWtdLoading = ref(false)
|
||||||
// events
|
// events
|
||||||
// 记录生成二级文档
|
|
||||||
const createJLItem = async (record: any) => {
|
|
||||||
isGenerating.value = true
|
|
||||||
isJlloading.value = true
|
|
||||||
await jlGenerateApi.createJLcaserecord({ id: record.id }).finally(() => {
|
|
||||||
isGenerating.value = false
|
|
||||||
isJlloading.value = false
|
|
||||||
})
|
|
||||||
Message.success("记录-片段库生成成功,请查看output/jl文件夹")
|
|
||||||
}
|
|
||||||
// 说明生成二级文档
|
|
||||||
const createSmItem = async (record: any) => {
|
|
||||||
isGenerating.value = true
|
|
||||||
isSmLoading.value = true
|
|
||||||
const id = record.id
|
|
||||||
await Promise.all([
|
|
||||||
dgGenerateApi.createSoftComposition({ id }), // 生成测评对象 - 和大纲一样
|
|
||||||
dgGenerateApi.createFuncList({ id }), // 生成被测软件功能 - 和大纲重复
|
|
||||||
dgGenerateApi.createInterface({ id }), // 生成被测软件接口 - 和大纲重复 - 可能会删除
|
|
||||||
dgGenerateApi.createPerformance({ id }), // 生成被测软件性能 - 和大纲重复 - 可能会删除
|
|
||||||
dgGenerateApi.createBaseInformation({ id }), // 生成被测软件基本信息 - 和大纲重复 - 可能会删除
|
|
||||||
dgGenerateApi.createYiju({ id }), // 生成标准类引用文档 - 和大纲重复 - 可能会删除
|
|
||||||
smGenerateApi.createSMTechyiju({ id }), // 生成技术类引用文档列表 -> 在大纲基础上添加《测评大纲》
|
|
||||||
// 拆分软硬件环境
|
|
||||||
dgGenerateApi.createStaticEnvironment({ id }), // 生成-静态测试环境说明
|
|
||||||
dgGenerateApi.createStaticSoft({ id }), // 生成-静态软件项
|
|
||||||
dgGenerateApi.createStaticHard({ id }), // 生成-静态硬件和固件项
|
|
||||||
dgGenerateApi.createDynamicEnv({ id }), // 生成-动态测试环境说明
|
|
||||||
dgGenerateApi.createDynamicSoft({ id }), // 生成-动态软件项
|
|
||||||
dgGenerateApi.createDynamicHard({ id }), // 生成-动态硬件和固件项
|
|
||||||
dgGenerateApi.createTestData({ id }), // 生成-测评数据
|
|
||||||
dgGenerateApi.createEnvDiff({ id }), // 生成-环境差异性分析
|
|
||||||
// ~~~
|
|
||||||
smGenerateApi.createSMCaseList({ id }), // 生成用例全
|
|
||||||
smGenerateApi.createSMCaseBreifList({ id }), // 生成用例列表-那个表格
|
|
||||||
smGenerateApi.createSMTrack({ id }) // 生成说明追踪
|
|
||||||
]).finally(() => {
|
|
||||||
isGenerating.value = false
|
|
||||||
isSmLoading.value = false
|
|
||||||
})
|
|
||||||
Message.success("说明-片段库生成成功,请查看output/sm文件夹")
|
|
||||||
}
|
|
||||||
// 大纲生成二级文档
|
// 大纲生成二级文档
|
||||||
const createDgItem = async (e: any, record: any) => {
|
const createDgItem = async (id: number) => {
|
||||||
isGenerating.value = true
|
isGenerating.value = true
|
||||||
isDgLoading.value = true
|
isDgLoading.value = true
|
||||||
const id = record.id
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
dgGenerateApi.createTestDemand({ id }), // 生成第一轮测试项
|
dgGenerateApi.createTestDemand({ id }), // 生成第一轮测试项
|
||||||
dgGenerateApi.createYiju({ id }), // 生成依据文件
|
dgGenerateApi.createYiju({ id }), // 生成依据文件
|
||||||
@@ -97,19 +56,104 @@ const useGenerateSecond = function () {
|
|||||||
dgGenerateApi.createDynamicHard({ id }), // 生成-动态硬件和固件项
|
dgGenerateApi.createDynamicHard({ id }), // 生成-动态硬件和固件项
|
||||||
dgGenerateApi.createTestData({ id }), // 生成-测评数据
|
dgGenerateApi.createTestData({ id }), // 生成-测评数据
|
||||||
dgGenerateApi.createEnvDiff({ id }), // 生成-环境差异性分析
|
dgGenerateApi.createEnvDiff({ id }), // 生成-环境差异性分析
|
||||||
// ~~~~~~~~~
|
|
||||||
dgGenerateApi.createMainTech({ id }) // 生成-主要战技指标
|
|
||||||
]).finally(() => {
|
]).finally(() => {
|
||||||
isGenerating.value = false
|
isGenerating.value = false
|
||||||
isDgLoading.value = false
|
isDgLoading.value = false
|
||||||
})
|
})
|
||||||
Message.success("大纲-片段库文档生成成功,请查看output/dg文件夹")
|
}
|
||||||
|
// 说明生成二级文档
|
||||||
|
const createSmItem = async (id: number) => {
|
||||||
|
isGenerating.value = true
|
||||||
|
isSmLoading.value = true
|
||||||
|
await Promise.all([
|
||||||
|
dgGenerateApi.createSoftComposition({ id }), // 生成测评对象 - 和大纲一样
|
||||||
|
dgGenerateApi.createFuncList({ id }), // 生成被测软件功能 - 和大纲重复
|
||||||
|
dgGenerateApi.createInterface({ id }), // 生成被测软件接口 - 和大纲重复 - 可能会删除
|
||||||
|
dgGenerateApi.createPerformance({ id }), // 生成被测软件性能 - 和大纲重复 - 可能会删除
|
||||||
|
dgGenerateApi.createBaseInformation({ id }), // 生成被测软件基本信息 - 和大纲重复 - 可能会删除
|
||||||
|
dgGenerateApi.createYiju({ id }), // 生成标准类引用文档 - 和大纲重复 - 可能会删除
|
||||||
|
smGenerateApi.createSMTechyiju({ id }), // 生成技术类引用文档列表 -> 在大纲基础上添加《测评大纲》
|
||||||
|
// 拆分软硬件环境
|
||||||
|
dgGenerateApi.createStaticEnvironment({ id }), // 生成-静态测试环境说明
|
||||||
|
dgGenerateApi.createStaticSoft({ id }), // 生成-静态软件项
|
||||||
|
dgGenerateApi.createStaticHard({ id }), // 生成-静态硬件和固件项
|
||||||
|
dgGenerateApi.createDynamicEnv({ id }), // 生成-动态测试环境说明
|
||||||
|
dgGenerateApi.createDynamicSoft({ id }), // 生成-动态软件项
|
||||||
|
dgGenerateApi.createDynamicHard({ id }), // 生成-动态硬件和固件项
|
||||||
|
dgGenerateApi.createTestData({ id }), // 生成-测评数据
|
||||||
|
dgGenerateApi.createEnvDiff({ id }), // 生成-环境差异性分析
|
||||||
|
// ~~~
|
||||||
|
smGenerateApi.createSMCaseList({ id }), // 生成用例全
|
||||||
|
smGenerateApi.createSMCaseBreifList({ id }), // 生成用例列表-那个表格
|
||||||
|
smGenerateApi.createSMTrack({ id }) // 生成说明追踪
|
||||||
|
]).finally(() => {
|
||||||
|
isGenerating.value = false
|
||||||
|
isSmLoading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 记录生成二级文档
|
||||||
|
const createJLItem = async (id: number) => {
|
||||||
|
isGenerating.value = true
|
||||||
|
isJlloading.value = true
|
||||||
|
await jlGenerateApi.createJLcaserecord({ id }).finally(() => {
|
||||||
|
isGenerating.value = false
|
||||||
|
isJlloading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 回归测试说明二级文档
|
||||||
|
const createHsmItem = async (id: number) => {
|
||||||
|
isGenerating.value = true
|
||||||
|
ishsmLoading.value = true
|
||||||
|
await Promise.all([
|
||||||
|
hsmGenerateApi.deleteHSMFiles({ id }), // 先删除以前文件
|
||||||
|
hsmGenerateApi.createBasicInfo({ id }),
|
||||||
|
hsmGenerateApi.createDocSummary({ id }),
|
||||||
|
hsmGenerateApi.createJstech({ id }),
|
||||||
|
hsmGenerateApi.createChangePart({ id }),
|
||||||
|
hsmGenerateApi.createHdemand({ id }),
|
||||||
|
hsmGenerateApi.createCaseListDesc({ id }),
|
||||||
|
hsmGenerateApi.createCaseList({ id }),
|
||||||
|
hsmGenerateApi.createTrack({ id }),
|
||||||
|
// 拆分大纲软硬件环境
|
||||||
|
dgGenerateApi.createStaticEnvironment({ id }), // 生成-静态测试环境说明
|
||||||
|
dgGenerateApi.createStaticSoft({ id }), // 生成-静态软件项
|
||||||
|
dgGenerateApi.createStaticHard({ id }), // 生成-静态硬件和固件项
|
||||||
|
dgGenerateApi.createDynamicEnv({ id }), // 生成-动态测试环境说明
|
||||||
|
dgGenerateApi.createDynamicSoft({ id }), // 生成-动态软件项
|
||||||
|
dgGenerateApi.createDynamicHard({ id }), // 生成-动态硬件和固件项
|
||||||
|
dgGenerateApi.createTestData({ id }), // 生成-测评数据
|
||||||
|
dgGenerateApi.createEnvDiff({ id }) // 生成-环境差异性分析
|
||||||
|
]).finally(() => {
|
||||||
|
isGenerating.value = false
|
||||||
|
ishsmLoading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 回归测试记录二级文档
|
||||||
|
const createHjlItem = async (id: number) => {
|
||||||
|
isGenerating.value = true
|
||||||
|
ishjlLoading.value = true
|
||||||
|
await Promise.all([
|
||||||
|
hjlGenerateApi.deleteHJLFiles({ id }), // 先调用删除文件夹里面文件
|
||||||
|
hjlGenerateApi.createBasicInfo({ id }),
|
||||||
|
hjlGenerateApi.createCaseinfo({ id })
|
||||||
|
]).finally(() => {
|
||||||
|
isGenerating.value = false
|
||||||
|
ishjlLoading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 问题单二级文档
|
||||||
|
const createWtdItem = async (id: number) => {
|
||||||
|
isGenerating.value = true
|
||||||
|
isWtdLoading.value = true
|
||||||
|
await wtdGenerateApi.createWtdTable({ id }).finally(() => {
|
||||||
|
isGenerating.value = false
|
||||||
|
isWtdLoading.value = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// 报告生成二级文档
|
// 报告生成二级文档
|
||||||
const createBgItem = async (record: any) => {
|
const createBgItem = async (id: number) => {
|
||||||
isGenerating.value = true
|
isGenerating.value = true
|
||||||
isBgLoading.value = true
|
isBgLoading.value = true
|
||||||
const id = record.id
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
bgGenerateApi.deleteBGFiles({ id }), // 删除output/bg文件夹下文件
|
bgGenerateApi.deleteBGFiles({ id }), // 删除output/bg文件夹下文件
|
||||||
bgGenerateApi.createBgTechYiju({ id }),
|
bgGenerateApi.createBgTechYiju({ id }),
|
||||||
@@ -138,64 +182,7 @@ const useGenerateSecond = function () {
|
|||||||
isGenerating.value = false
|
isGenerating.value = false
|
||||||
isBgLoading.value = false
|
isBgLoading.value = false
|
||||||
})
|
})
|
||||||
Message.success("报告-片段库文档生成成功,请查看output/bg文件夹")
|
|
||||||
}
|
}
|
||||||
// 回归测试说明二级文档
|
|
||||||
const createHsmItem = async (record: any) => {
|
|
||||||
const id = record.id
|
|
||||||
isGenerating.value = true
|
|
||||||
ishsmLoading.value = true
|
|
||||||
await Promise.all([
|
|
||||||
hsmGenerateApi.deleteHSMFiles({ id }), // 先删除以前文件
|
|
||||||
hsmGenerateApi.createBasicInfo({ id }),
|
|
||||||
hsmGenerateApi.createDocSummary({ id }),
|
|
||||||
hsmGenerateApi.createJstech({ id }),
|
|
||||||
hsmGenerateApi.createChangePart({ id }),
|
|
||||||
hsmGenerateApi.createHdemand({ id }),
|
|
||||||
hsmGenerateApi.createCaseListDesc({ id }),
|
|
||||||
hsmGenerateApi.createCaseList({ id }),
|
|
||||||
hsmGenerateApi.createTrack({ id }),
|
|
||||||
// 拆分大纲软硬件环境
|
|
||||||
dgGenerateApi.createStaticEnvironment({ id }), // 生成-静态测试环境说明
|
|
||||||
dgGenerateApi.createStaticSoft({ id }), // 生成-静态软件项
|
|
||||||
dgGenerateApi.createStaticHard({ id }), // 生成-静态硬件和固件项
|
|
||||||
dgGenerateApi.createDynamicEnv({ id }), // 生成-动态测试环境说明
|
|
||||||
dgGenerateApi.createDynamicSoft({ id }), // 生成-动态软件项
|
|
||||||
dgGenerateApi.createDynamicHard({ id }), // 生成-动态硬件和固件项
|
|
||||||
dgGenerateApi.createTestData({ id }), // 生成-测评数据
|
|
||||||
dgGenerateApi.createEnvDiff({ id }) // 生成-环境差异性分析
|
|
||||||
]).finally(() => {
|
|
||||||
isGenerating.value = false
|
|
||||||
ishsmLoading.value = false
|
|
||||||
})
|
|
||||||
Message.success("回归说明-片段库文档生成成功,请查看output/hsm文件夹")
|
|
||||||
}
|
|
||||||
// 回归测试记录二级文档
|
|
||||||
const createHjlItem = async (record: any) => {
|
|
||||||
const id = record.id
|
|
||||||
isGenerating.value = true
|
|
||||||
ishjlLoading.value = true
|
|
||||||
await Promise.all([
|
|
||||||
hjlGenerateApi.deleteHJLFiles({ id }), // 先调用删除文件夹里面文件
|
|
||||||
hjlGenerateApi.createBasicInfo({ id }),
|
|
||||||
hjlGenerateApi.createCaseinfo({ id })
|
|
||||||
]).finally(() => {
|
|
||||||
isGenerating.value = false
|
|
||||||
ishjlLoading.value = false
|
|
||||||
})
|
|
||||||
Message.success("回归记录-片段库文档生成成功,请查看output/hjl文件夹")
|
|
||||||
}
|
|
||||||
// 问题单二级文档
|
|
||||||
const createWtdItem = async (record: any) => {
|
|
||||||
isGenerating.value = true
|
|
||||||
isWtdLoading.value = true
|
|
||||||
await wtdGenerateApi.createWtdTable({ id: record.id }).finally(() => {
|
|
||||||
isGenerating.value = false
|
|
||||||
isWtdLoading.value = false
|
|
||||||
})
|
|
||||||
Message.success("问题单-片段库文档生成成功,请查看output/wtd文件夹")
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isGenerating,
|
isGenerating,
|
||||||
isDgLoading,
|
isDgLoading,
|
||||||
|
|||||||
@@ -1,69 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* 生成产品文档按钮
|
||||||
|
*/
|
||||||
import { ref } from "vue"
|
import { ref } from "vue"
|
||||||
import hoosk from "./hooks"
|
import hoosk from "./hooks"
|
||||||
import seitaiGenerateApi from "@/api/generate/seitaiGenerate"
|
import seitaiGenerateApi from "@/api/generate/seitaiGenerate"
|
||||||
|
import type { IFragmentItem } from "@/views/testmanage/projmanage/GeneratorModal/index.vue"
|
||||||
|
|
||||||
const useSeitaiModal = function () {
|
const useSeitaiModal = function () {
|
||||||
// refs
|
// refs
|
||||||
const visible = ref(false)
|
const visible = ref(false) // Modal显隐
|
||||||
const isComplete = ref(false)
|
const isComplete = ref(false) // 是否生成完成
|
||||||
const ptext = ref("测评大纲")
|
|
||||||
// events
|
// events
|
||||||
const handleModalConfirmClick = () => {
|
const handleModalConfirmClick = () => {
|
||||||
visible.value = false
|
visible.value = false // 关闭Modal
|
||||||
}
|
}
|
||||||
// 生成文档
|
// 生成文档
|
||||||
// ~~~~~~~~测试说明生成文档~~~~~~~~
|
|
||||||
const createSeitaiShuoming = async (record: any) => {
|
|
||||||
ptext.value = "测试说明"
|
|
||||||
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createShuomingSeiTai, record.id, ptext.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ~~~~~~~~测试大纲生成文档~~~~~~~~
|
// ~~~~~~~~测试大纲生成文档~~~~~~~~
|
||||||
const createSeitaiDagang = async (record: any) => {
|
const createSeitaiDagang = async (id: number, ptext: string, fragmentList: IFragmentItem[]) => {
|
||||||
// 根据一系列文档生成大纲 - 这里有进度条组件、a-modal组件
|
// 根据一系列文档生成大纲 - 这里有进度条组件、a-modal组件
|
||||||
// 1.打开进度条组件
|
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createDagangSeiTai, id, ptext, fragmentList)
|
||||||
ptext.value = "测评大纲"
|
}
|
||||||
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createDagangSeiTai, record.id, ptext.value)
|
// ~~~~~~~~测试说明生成文档~~~~~~~~
|
||||||
|
const createSeitaiShuoming = async (id: number, ptext: string, fragmentList: IFragmentItem[]) => {
|
||||||
|
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createShuomingSeiTai, id, ptext, fragmentList)
|
||||||
}
|
}
|
||||||
// ~~~~~~~~记录生成文档~~~~~~~~
|
// ~~~~~~~~记录生成文档~~~~~~~~
|
||||||
const createSeitaiJilu = async (record: any) => {
|
const createSeitaiJilu = async (id: number, ptext: string, fragmentList: IFragmentItem[]) => {
|
||||||
ptext.value = "测试记录"
|
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createJiluSeiTai, id, ptext, fragmentList)
|
||||||
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createJiluSeiTai, record.id, ptext.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ~~~~~~~~报告生成文档~~~~~~~~
|
|
||||||
const createSeitaiBaogao = async (record: any) => {
|
|
||||||
ptext.value = "测评报告"
|
|
||||||
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createBgDocument, record.id, ptext.value)
|
|
||||||
}
|
}
|
||||||
// ~~~~~~~~回归测试说明~~~~~~~~
|
// ~~~~~~~~回归测试说明~~~~~~~~
|
||||||
const createSeitaiHsm = async (record: any) => {
|
const createSeitaiHsm = async (id: number, ptext: string, fragmentList: IFragmentItem[]) => {
|
||||||
ptext.value = "回归测试说明"
|
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createHsmDocument, id, ptext, fragmentList)
|
||||||
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createHsmDocument, record.id, ptext.value)
|
|
||||||
}
|
}
|
||||||
// ~~~~~~~~回归测试记录~~~~~~~~
|
// ~~~~~~~~回归测试记录~~~~~~~~
|
||||||
const createSeitaiHjl = async (record: any) => {
|
const createSeitaiHjl = async (id: number, ptext: string, fragmentList: IFragmentItem[]) => {
|
||||||
ptext.value = "回归测试记录"
|
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createHjlDocument, id, ptext, fragmentList)
|
||||||
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createHjlDocument, record.id, ptext.value)
|
|
||||||
}
|
}
|
||||||
// ~~~~~~~~问题单~~~~~~~~
|
// ~~~~~~~~问题单~~~~~~~~
|
||||||
const createSeitaiWtd = async (record: any) => {
|
const createSeitaiWtd = async (id: number, ptext: string, fragmentList: IFragmentItem[]) => {
|
||||||
ptext.value = "问题单"
|
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createWtdDocument, id, ptext, fragmentList)
|
||||||
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createWtdDocument, record.id, ptext.value)
|
}
|
||||||
|
// ~~~~~~~~报告生成文档~~~~~~~~
|
||||||
|
const createSeitaiBaogao = async (id: number, ptext: string, fragmentList: IFragmentItem[]) => {
|
||||||
|
hoosk.create_entire_doc(visible, isComplete, seitaiGenerateApi.createBgDocument, id, ptext, fragmentList)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
visible,
|
visible,
|
||||||
isComplete,
|
isComplete,
|
||||||
ptext,
|
|
||||||
handleModalConfirmClick,
|
handleModalConfirmClick,
|
||||||
createSeitaiShuoming,
|
|
||||||
createSeitaiDagang,
|
createSeitaiDagang,
|
||||||
|
createSeitaiShuoming,
|
||||||
createSeitaiJilu,
|
createSeitaiJilu,
|
||||||
createSeitaiBaogao,
|
|
||||||
createSeitaiHsm,
|
createSeitaiHsm,
|
||||||
createSeitaiHjl,
|
createSeitaiHjl,
|
||||||
createSeitaiWtd
|
createSeitaiWtd,
|
||||||
|
createSeitaiBaogao
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,89 +5,25 @@
|
|||||||
<!-- ma-crud组件 -->
|
<!-- ma-crud组件 -->
|
||||||
<ma-crud :options="crudOptions" :columns="crudColumns" ref="crudRef">
|
<ma-crud :options="crudOptions" :columns="crudColumns" ref="crudRef">
|
||||||
<template #operationBeforeExtend="{ record }">
|
<template #operationBeforeExtend="{ record }">
|
||||||
<a-popover title="文档生成组合按钮" trigger="click">
|
<a-popover title="点击配置生成文档" trigger="click">
|
||||||
<a-button type="primary" size="mini">
|
<a-button type="primary" size="mini">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-plus />
|
<icon-download />
|
||||||
</template>
|
</template>
|
||||||
文档生成
|
文档生成
|
||||||
</a-button>
|
</a-button>
|
||||||
<template #content>
|
<template #content>
|
||||||
<p>
|
<a-space direction="vertical" :size="0" align="start">
|
||||||
<a-link
|
<a-space direction="vertical" :size="0" align="start">
|
||||||
:disabled="isGenerating"
|
<a-link @click="openCreateModal('测评大纲', record.id)">测评大纲</a-link>
|
||||||
:loading="isDgLoading"
|
<a-link @click="openCreateModal('测试说明', record.id)">测试说明</a-link>
|
||||||
@click="createDgItem($event, record)"
|
<a-link @click="openCreateModal('测试记录', record.id)">测试记录</a-link>
|
||||||
>
|
<a-link @click="openCreateModal('回归测试说明', record.id)">回归测试说明</a-link>
|
||||||
大纲二段文档
|
<a-link @click="openCreateModal('回归测试记录', record.id)">回归测试记录</a-link>
|
||||||
</a-link>
|
<a-link @click="openCreateModal('问题单', record.id)">问题单</a-link>
|
||||||
</p>
|
<a-link @click="openCreateModal('测评报告', record.id)">测评报告</a-link>
|
||||||
<p>
|
</a-space>
|
||||||
<a-link :disabled="isGenerating" :loading="isSmLoading" @click="createSmItem(record)">
|
</a-space>
|
||||||
说明二段文档
|
|
||||||
</a-link>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" :loading="isJlloading" @click="createJLItem(record)">
|
|
||||||
记录二段文档
|
|
||||||
</a-link>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" :loading="isBgLoading" @click="createBgItem(record)">
|
|
||||||
报告二段文档
|
|
||||||
</a-link>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" :loading="ishsmLoading" @click="createHsmItem(record)">
|
|
||||||
回归说明二段文档
|
|
||||||
</a-link>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" :loading="ishjlLoading" @click="createHjlItem(record)">
|
|
||||||
回归记录二段文档
|
|
||||||
</a-link>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" :loading="isWtdLoading" @click="createWtdItem(record)">
|
|
||||||
问题单二段文档
|
|
||||||
</a-link>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" @click="createSeitaiDagang(record)">
|
|
||||||
<icon-eye />
|
|
||||||
[测试]生成最后大纲
|
|
||||||
</a-link>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" @click="createSeitaiShuoming(record)">
|
|
||||||
<icon-eye />[测试]生成最后说明
|
|
||||||
</a-link>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" @click="createSeitaiJilu(record)"
|
|
||||||
><icon-eye />[测试]生成最后记录</a-link
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" @click="createSeitaiBaogao(record)"
|
|
||||||
><icon-eye />[测试]生成测评报告</a-link
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" @click="createSeitaiHsm(record)"
|
|
||||||
><icon-eye />[测试]回归测试说明</a-link
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" @click="createSeitaiHjl(record)"
|
|
||||||
><icon-eye />[测试]回归测试记录</a-link
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a-link :disabled="isGenerating" @click="createSeitaiWtd(record)"
|
|
||||||
><icon-eye />[测试]生成问题单</a-link
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</template>
|
</template>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
<a-button @click="enterWorkPlant(record)" size="mini" status="warning" type="outline">
|
<a-button @click="enterWorkPlant(record)" size="mini" status="warning" type="outline">
|
||||||
@@ -95,70 +31,33 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
<a-link @click="previewRef.open(record)"><icon-eye />预览</a-link>
|
<a-link @click="previewRef.open(record)"><icon-eye />预览</a-link>
|
||||||
<a-link @click="handleFragmentClick(record)"><icon-file />片段</a-link>
|
<a-link @click="handleFragmentClick(record)"><icon-file />片段</a-link>
|
||||||
<a-link @click="handleBoardClick(record)"><icon-dashboard />项目看板</a-link>
|
<a-link @click="handleBoardClick(record)"><icon-dashboard />看板</a-link>
|
||||||
</template>
|
</template>
|
||||||
</ma-crud>
|
</ma-crud>
|
||||||
|
<GeneratorModal ref="generatorModalRef" />
|
||||||
</div>
|
</div>
|
||||||
<preview ref="previewRef" :columns="crudColumns"></preview>
|
<preview ref="previewRef" :columns="crudColumns"></preview>
|
||||||
<Progress
|
|
||||||
:visible="visible"
|
|
||||||
:isComplete="isComplete"
|
|
||||||
:text="ptext"
|
|
||||||
@clickConfirm="handleModalConfirmClick"
|
|
||||||
></Progress>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="jsx">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue"
|
import { ref } from "vue"
|
||||||
import { useRouter } from "vue-router"
|
import { useRouter } from "vue-router"
|
||||||
import preview from "./cpns/preview.vue"
|
import preview from "./cpns/preview.vue" // 项目详情预览组件
|
||||||
import Progress from "./cpns/progress.vue"
|
import useEnterWorkPlant from "./hooks/useEnterWorkPlant" // 进入工作区逻辑
|
||||||
import useEnterWorkPlant from "./hooks/useEnterWorkPlant"
|
|
||||||
import useSeitaiModal from "./hooks/useSeitaiModal"
|
|
||||||
import useGenerateSecond from "./hooks/useGenerateSecond"
|
|
||||||
import useCrudInit from "./hooks/useCrudInit"
|
import useCrudInit from "./hooks/useCrudInit"
|
||||||
|
import GeneratorModal from "./GeneratorModal/index.vue" // 生成文档Modal组件
|
||||||
|
import type { DocumentType } from "@/utils/types/CommonType" // 产品文档类型
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
// crud配置和字段信息定义
|
// crud配置和字段信息定义
|
||||||
const { crudRef, crudOptions, crudColumns } = useCrudInit()
|
const { crudRef, crudOptions, crudColumns } = useCrudInit()
|
||||||
// 点击进入工作区函数 - 每次点击后都清除localStorage中树状目录数据
|
// 点击进入工作区函数 - 每次点击后都清除localStorage中树状目录数据
|
||||||
const { enterWorkPlant } = useEnterWorkPlant()
|
const { enterWorkPlant } = useEnterWorkPlant()
|
||||||
// 生成最终文档事件,并且弹窗显隐和退出条件判断
|
|
||||||
const {
|
|
||||||
visible,
|
|
||||||
isComplete,
|
|
||||||
ptext,
|
|
||||||
handleModalConfirmClick,
|
|
||||||
createSeitaiShuoming,
|
|
||||||
createSeitaiDagang,
|
|
||||||
createSeitaiJilu,
|
|
||||||
createSeitaiBaogao,
|
|
||||||
createSeitaiHsm,
|
|
||||||
createSeitaiHjl,
|
|
||||||
createSeitaiWtd
|
|
||||||
} = useSeitaiModal()
|
|
||||||
// 用于生成二段文档按钮事件和禁用按钮ref
|
|
||||||
const {
|
|
||||||
isGenerating,
|
|
||||||
isDgLoading,
|
|
||||||
isSmLoading,
|
|
||||||
isBgLoading,
|
|
||||||
isJlloading,
|
|
||||||
ishsmLoading,
|
|
||||||
ishjlLoading,
|
|
||||||
isWtdLoading,
|
|
||||||
createJLItem,
|
|
||||||
createSmItem,
|
|
||||||
createDgItem,
|
|
||||||
createBgItem,
|
|
||||||
createHsmItem,
|
|
||||||
createHjlItem,
|
|
||||||
createWtdItem
|
|
||||||
} = useGenerateSecond()
|
|
||||||
|
|
||||||
// 其他功能
|
// 其他功能
|
||||||
// 1.跳转到项目看板页面
|
// 1.跳转到项目看板页面
|
||||||
const handleBoardClick = (record) => {
|
const handleBoardClick = (record: any) => {
|
||||||
router.push({
|
router.push({
|
||||||
name: "projBoard",
|
name: "projBoard",
|
||||||
params: {
|
params: {
|
||||||
@@ -167,7 +66,7 @@ const handleBoardClick = (record) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 2.跳转到项目所属文档片段
|
// 2.跳转到项目所属文档片段
|
||||||
const handleFragmentClick = (record) => {
|
const handleFragmentClick = (record: any) => {
|
||||||
router.push({
|
router.push({
|
||||||
name: "projFragment",
|
name: "projFragment",
|
||||||
params: {
|
params: {
|
||||||
@@ -178,14 +77,19 @@ const handleFragmentClick = (record) => {
|
|||||||
// 3.预览项目信息ref
|
// 3.预览项目信息ref
|
||||||
const previewRef = ref()
|
const previewRef = ref()
|
||||||
|
|
||||||
|
// 4.生成文档组件
|
||||||
|
const generatorModalRef = ref<InstanceType<typeof GeneratorModal> | null>(null) // GeneratorModal组件的ref
|
||||||
|
const openCreateModal = (documentType: DocumentType, id: number) => {
|
||||||
|
generatorModalRef.value!.open(documentType, id) // 打开弹出框
|
||||||
|
}
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "projmanage"
|
name: "projmanage"
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style scoped lang="less">
|
||||||
.msg-menu {
|
.msg-menu {
|
||||||
// border-right: 1px solid var(--color-border-2);
|
|
||||||
& li {
|
& li {
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
"ES2015"
|
"ES2015"
|
||||||
],
|
],
|
||||||
"types": [
|
"types": [
|
||||||
"vite/client"
|
"vite/client",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
|
|||||||
Reference in New Issue
Block a user