|
|
|
|
@@ -2,8 +2,44 @@
|
|
|
|
|
<div class="page-wrap">
|
|
|
|
|
<page-section :title="form.id ? '编辑用例' : '新建用例'">
|
|
|
|
|
<el-form ref="form" :model="form" :rules="rules" label-width="120px" size="small">
|
|
|
|
|
<el-form-item label="项目ID">
|
|
|
|
|
<el-input v-model="projectId" style="width: 200px;"></el-input>
|
|
|
|
|
<el-form-item label="产品" prop="productId">
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="form.productId"
|
|
|
|
|
filterable
|
|
|
|
|
clearable
|
|
|
|
|
placeholder="请选择产品"
|
|
|
|
|
style="width: 360px;"
|
|
|
|
|
@change="handleProductChange"
|
|
|
|
|
@focus="loadProductOptions">
|
|
|
|
|
<el-option v-for="item in productOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="项目" prop="projectId">
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="form.projectId"
|
|
|
|
|
filterable
|
|
|
|
|
clearable
|
|
|
|
|
placeholder="请选择项目"
|
|
|
|
|
style="width: 360px;"
|
|
|
|
|
:disabled="!form.productId"
|
|
|
|
|
@change="handleProjectChange">
|
|
|
|
|
<el-option v-for="item in projectOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="模块" prop="moduleId">
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="form.moduleId"
|
|
|
|
|
filterable
|
|
|
|
|
clearable
|
|
|
|
|
placeholder="请选择模块"
|
|
|
|
|
style="width: 360px;"
|
|
|
|
|
:disabled="!form.projectId"
|
|
|
|
|
@focus="loadModuleOptions">
|
|
|
|
|
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="用例编号">
|
|
|
|
|
<el-input v-model="form.caseKey" placeholder="不填则由后端自动生成"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="标题" prop="title">
|
|
|
|
|
<el-input v-model="form.title"></el-input>
|
|
|
|
|
@@ -23,19 +59,32 @@
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="类型">
|
|
|
|
|
<el-select v-model="form.case_type">
|
|
|
|
|
<el-select v-model="form.caseType">
|
|
|
|
|
<el-option label="功能" :value="1"></el-option>
|
|
|
|
|
<el-option label="性能" :value="2"></el-option>
|
|
|
|
|
<el-option label="安全" :value="3"></el-option>
|
|
|
|
|
<el-option label="接口" :value="4"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="状态">
|
|
|
|
|
<el-select v-model="form.status">
|
|
|
|
|
<el-option label="正常" :value="1"></el-option>
|
|
|
|
|
<el-option label="已废弃" :value="2"></el-option>
|
|
|
|
|
<el-option label="评审中" :value="3"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="是否自动化">
|
|
|
|
|
<el-select v-model="form.isAuto">
|
|
|
|
|
<el-option label="未实现" :value="0"></el-option>
|
|
|
|
|
<el-option label="已实现" :value="1"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="标签">
|
|
|
|
|
<el-input v-model="tagsText" placeholder="多个标签用逗号分隔"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button type="primary" :loading="saving" @click="submitForm">保存</el-button>
|
|
|
|
|
<el-button @click="$router.push('/test-platform/cases')">返回</el-button>
|
|
|
|
|
<el-button @click="backList">返回</el-button>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
</page-section>
|
|
|
|
|
@@ -44,7 +93,9 @@
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import PageSection from '@/components/TestPlatform/common/PageSection'
|
|
|
|
|
import { createCase, getCaseDetail, updateCase } from '@/api/caseApi'
|
|
|
|
|
import { createCase, getCaseDetail, getModuleTree, updateCase } from '@/api/caseApi'
|
|
|
|
|
import { getProductList } from '@/api/productApi'
|
|
|
|
|
import { getProjectDetail, getProjectList } from '@/api/projectApi'
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: 'CaseEditor',
|
|
|
|
|
@@ -52,59 +103,175 @@ export default {
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
saving: false,
|
|
|
|
|
projectId: this.$route.query.projectId || 1,
|
|
|
|
|
productOptions: [],
|
|
|
|
|
projectOptions: [],
|
|
|
|
|
moduleOptions: [],
|
|
|
|
|
form: {
|
|
|
|
|
productId: this.$route.query.productId ? Number(this.$route.query.productId) : '',
|
|
|
|
|
projectId: this.$route.query.projectId ? Number(this.$route.query.projectId) : '',
|
|
|
|
|
id: '',
|
|
|
|
|
moduleId: '',
|
|
|
|
|
caseKey: '',
|
|
|
|
|
title: '',
|
|
|
|
|
preconditions: '',
|
|
|
|
|
steps: [],
|
|
|
|
|
priority: 2,
|
|
|
|
|
case_type: 1,
|
|
|
|
|
tags: []
|
|
|
|
|
caseType: 1,
|
|
|
|
|
tags: [],
|
|
|
|
|
status: 1,
|
|
|
|
|
isAuto: 0
|
|
|
|
|
},
|
|
|
|
|
stepsText: '[]',
|
|
|
|
|
tagsText: '',
|
|
|
|
|
rules: {
|
|
|
|
|
productId: [{ required: true, message: '请选择产品', trigger: 'change' }],
|
|
|
|
|
projectId: [{ required: true, message: '请选择项目', trigger: 'change' }],
|
|
|
|
|
moduleId: [{ required: true, message: '请选择模块', trigger: 'change' }],
|
|
|
|
|
title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
|
|
|
|
|
steps: [{ required: true, message: '请输入步骤', trigger: 'change' }]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
loadProductOptions() {
|
|
|
|
|
if (this.productOptions && this.productOptions.length > 0) {
|
|
|
|
|
return Promise.resolve()
|
|
|
|
|
}
|
|
|
|
|
return getProductList({ pageNo: 1, pageSize: 1000, status: 1 }).then(res => {
|
|
|
|
|
const data = res && res.data ? res.data : res || {}
|
|
|
|
|
this.productOptions = data.items || data.list || data.data || []
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
this.productOptions = []
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
loadProjectOptions() {
|
|
|
|
|
if (!this.form.productId) {
|
|
|
|
|
this.projectOptions = []
|
|
|
|
|
return Promise.resolve()
|
|
|
|
|
}
|
|
|
|
|
return getProjectList({ pageNo: 1, pageSize: 1000, status: 1, productId: this.form.productId }).then(res => {
|
|
|
|
|
const data = res && res.data ? res.data : res || {}
|
|
|
|
|
this.projectOptions = data.items || data.list || data.data || []
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
this.projectOptions = []
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
loadModuleOptions() {
|
|
|
|
|
if (!this.form.projectId) {
|
|
|
|
|
this.moduleOptions = []
|
|
|
|
|
return Promise.resolve()
|
|
|
|
|
}
|
|
|
|
|
return getModuleTree({ projectId: this.form.projectId }).then(res => {
|
|
|
|
|
const data = (res && res.data) || res || {}
|
|
|
|
|
const list = data.list || data.items || []
|
|
|
|
|
this.moduleOptions = Array.isArray(list) ? list : []
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
this.moduleOptions = []
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
handleProductChange() {
|
|
|
|
|
this.form.projectId = ''
|
|
|
|
|
this.form.moduleId = ''
|
|
|
|
|
this.projectOptions = []
|
|
|
|
|
this.moduleOptions = []
|
|
|
|
|
this.loadProjectOptions()
|
|
|
|
|
},
|
|
|
|
|
handleProjectChange() {
|
|
|
|
|
this.form.moduleId = ''
|
|
|
|
|
this.moduleOptions = []
|
|
|
|
|
this.loadModuleOptions()
|
|
|
|
|
},
|
|
|
|
|
fetchDetail() {
|
|
|
|
|
const caseId = this.$route.query.caseId
|
|
|
|
|
if (!caseId) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
getCaseDetail(this.projectId, caseId).then(res => {
|
|
|
|
|
getCaseDetail(this.form.projectId, caseId).then(res => {
|
|
|
|
|
const data = (res && res.data) || res || {}
|
|
|
|
|
this.form = Object.assign({}, this.form, data)
|
|
|
|
|
this.stepsText = JSON.stringify(data.steps || [], null, 2)
|
|
|
|
|
this.tagsText = (data.tags || []).join(',')
|
|
|
|
|
this.form = Object.assign({}, this.form, {
|
|
|
|
|
id: data.id || caseId,
|
|
|
|
|
moduleId: data.moduleId || data.module_id || '',
|
|
|
|
|
caseKey: data.caseKey || data.case_key || '',
|
|
|
|
|
title: data.title || '',
|
|
|
|
|
preconditions: data.preconditions || '',
|
|
|
|
|
steps: data.steps || [],
|
|
|
|
|
priority: data.priority !== undefined ? data.priority : 2,
|
|
|
|
|
caseType: data.caseType || data.case_type || 1,
|
|
|
|
|
tags: data.tags || [],
|
|
|
|
|
status: data.status || 1,
|
|
|
|
|
isAuto: data.isAuto !== undefined ? data.isAuto : (data.is_auto !== undefined ? data.is_auto : 0)
|
|
|
|
|
})
|
|
|
|
|
this.stepsText = JSON.stringify(this.form.steps || [], null, 2)
|
|
|
|
|
this.tagsText = Array.isArray(this.form.tags) ? this.form.tags.join(',') : (this.form.tags || '')
|
|
|
|
|
if (this.form.projectId) {
|
|
|
|
|
this.loadModuleOptions()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
submitForm() {
|
|
|
|
|
let steps = []
|
|
|
|
|
try {
|
|
|
|
|
this.form.steps = JSON.parse(this.stepsText || '[]')
|
|
|
|
|
steps = JSON.parse(this.stepsText || '[]')
|
|
|
|
|
} catch (e) {
|
|
|
|
|
this.$message({ type: 'error', message: '步骤 JSON 格式错误' })
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
this.form.tags = this.tagsText ? this.tagsText.split(',').map(item => item.trim()).filter(Boolean) : []
|
|
|
|
|
const tags = this.tagsText ? this.tagsText.split(',').map(item => item.trim()).filter(Boolean) : []
|
|
|
|
|
const payload = this.cleanParams({
|
|
|
|
|
projectId: this.form.projectId,
|
|
|
|
|
moduleId: this.form.moduleId,
|
|
|
|
|
caseKey: this.form.caseKey,
|
|
|
|
|
title: this.form.title,
|
|
|
|
|
preconditions: this.form.preconditions,
|
|
|
|
|
steps,
|
|
|
|
|
priority: this.form.priority,
|
|
|
|
|
caseType: this.form.caseType,
|
|
|
|
|
tags,
|
|
|
|
|
status: this.form.status,
|
|
|
|
|
isAuto: this.form.isAuto
|
|
|
|
|
})
|
|
|
|
|
this.saving = true
|
|
|
|
|
const request = this.form.id || this.$route.query.caseId
|
|
|
|
|
? updateCase(this.projectId, this.form.id || this.$route.query.caseId, this.form)
|
|
|
|
|
: createCase(this.projectId, this.form)
|
|
|
|
|
const caseId = this.form.id || this.$route.query.caseId
|
|
|
|
|
const request = caseId ? updateCase(this.form.projectId, caseId, payload) : createCase(this.form.projectId, payload)
|
|
|
|
|
request.then(() => {
|
|
|
|
|
this.$message({ type: 'success', message: '保存成功' })
|
|
|
|
|
this.$router.push({ path: '/test-platform/cases', query: { projectId: this.projectId } })
|
|
|
|
|
this.backList()
|
|
|
|
|
}).finally(() => {
|
|
|
|
|
this.saving = false
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
cleanParams(params) {
|
|
|
|
|
return Object.keys(params).reduce((result, key) => {
|
|
|
|
|
if (params[key] !== '' && params[key] !== undefined && params[key] !== null) {
|
|
|
|
|
result[key] = params[key]
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}, {})
|
|
|
|
|
},
|
|
|
|
|
backList() {
|
|
|
|
|
this.$router.push({ path: '/test-platform/case', query: { productId: this.form.productId || undefined, projectId: this.form.projectId || undefined } })
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.fetchDetail()
|
|
|
|
|
this.loadProductOptions().then(() => {
|
|
|
|
|
if (this.form.projectId && !this.form.productId) {
|
|
|
|
|
return getProjectDetail(this.form.projectId).then(res => {
|
|
|
|
|
const data = res && res.data ? res.data : res || {}
|
|
|
|
|
const pid = data.productId || data.product_id || ''
|
|
|
|
|
if (pid) {
|
|
|
|
|
this.form.productId = pid
|
|
|
|
|
}
|
|
|
|
|
}).catch(() => {})
|
|
|
|
|
}
|
|
|
|
|
}).then(() => {
|
|
|
|
|
return this.loadProjectOptions()
|
|
|
|
|
}).then(() => {
|
|
|
|
|
if (this.form.projectId) {
|
|
|
|
|
return this.loadModuleOptions()
|
|
|
|
|
}
|
|
|
|
|
}).finally(() => {
|
|
|
|
|
this.fetchDetail()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|