347 lines
7.7 KiB
Vue
347 lines
7.7 KiB
Vue
<template>
|
|
<el-dialog
|
|
:visible.sync="dialogVisible"
|
|
title="导入历史项目"
|
|
width="700px"
|
|
:close-on-click-modal="false"
|
|
@close="handleClose"
|
|
>
|
|
<div class="new-project-config">
|
|
<el-form
|
|
ref="configForm"
|
|
:model="configForm"
|
|
:rules="configRules"
|
|
label-width="100px"
|
|
label-position="right"
|
|
>
|
|
<el-form-item label="新项目名称" prop="newProjectName">
|
|
<el-input
|
|
v-model="configForm.newProjectName"
|
|
placeholder="请输入新项目名称"
|
|
maxlength="200"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="备注" prop="description">
|
|
<el-input
|
|
v-model="configForm.description"
|
|
type="textarea"
|
|
:rows="3"
|
|
maxlength="500"
|
|
show-word-limit
|
|
placeholder="请输入备注"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="流水时间">
|
|
<el-date-picker
|
|
v-model="configForm.dateRange"
|
|
type="daterange"
|
|
value-format="yyyy-MM-dd"
|
|
range-separator="至"
|
|
start-placeholder="开始日期"
|
|
end-placeholder="结束日期"
|
|
style="width: 100%"
|
|
/>
|
|
</el-form-item>
|
|
</el-form>
|
|
</div>
|
|
|
|
<el-divider />
|
|
|
|
<div class="project-list-section">
|
|
<div class="section-header">
|
|
<div class="section-title">历史项目列表</div>
|
|
<el-input
|
|
v-model="searchKeyword"
|
|
placeholder="搜索历史项目名称"
|
|
prefix-icon="el-icon-search"
|
|
clearable
|
|
size="small"
|
|
class="search-input"
|
|
@clear="loadHistoryProjects"
|
|
@keyup.enter.native="handleSearch"
|
|
>
|
|
<el-button slot="append" icon="el-icon-search" @click="handleSearch" />
|
|
</el-input>
|
|
</div>
|
|
|
|
<el-checkbox-group v-model="selectedProjectIds" class="project-checkbox-group">
|
|
<label
|
|
v-for="item in historyProjects"
|
|
:key="item.projectId"
|
|
class="project-item-wrapper"
|
|
>
|
|
<el-checkbox :label="item.projectId" class="project-checkbox">
|
|
<div class="project-item">
|
|
<div class="project-header">
|
|
<span class="name">{{ item.projectName }}</span>
|
|
<el-tag :type="getStatusType(item.status)" size="mini">{{ getStatusLabel(item.status) }}</el-tag>
|
|
</div>
|
|
<div class="project-info">
|
|
<span class="info-item">
|
|
<i class="el-icon-time"></i>
|
|
创建时间: {{ item.createTime || '-' }}
|
|
</span>
|
|
<span class="info-item">
|
|
<i class="el-icon-document"></i>
|
|
备注: {{ item.description || '-' }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</el-checkbox>
|
|
</label>
|
|
</el-checkbox-group>
|
|
|
|
<el-empty
|
|
v-if="historyProjects.length === 0"
|
|
description="暂无历史项目"
|
|
:image-size="100"
|
|
/>
|
|
</div>
|
|
|
|
<div slot="footer" class="dialog-footer">
|
|
<el-button @click="handleClose">取 消</el-button>
|
|
<el-button
|
|
type="primary"
|
|
:loading="submitting"
|
|
@click="handleSubmit"
|
|
>
|
|
<i v-if="!submitting" class="el-icon-download"></i>
|
|
导 入
|
|
</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script>
|
|
import { importFromHistory, listHistoryProjects } from '@/api/ccdiProject'
|
|
|
|
export default {
|
|
name: 'ImportHistoryDialog',
|
|
props: {
|
|
visible: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
submitting: false,
|
|
searchKeyword: '',
|
|
selectedProjectIds: [],
|
|
historyProjects: [],
|
|
configForm: {
|
|
newProjectName: '',
|
|
description: '',
|
|
dateRange: []
|
|
},
|
|
configRules: {
|
|
newProjectName: [
|
|
{ required: true, message: '请输入新项目名称', trigger: 'blur' }
|
|
],
|
|
description: [
|
|
{ max: 500, message: '备注长度不能超过500个字符', trigger: 'blur' }
|
|
]
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
dialogVisible: {
|
|
get() {
|
|
return this.visible
|
|
},
|
|
set(val) {
|
|
if (!val) {
|
|
this.handleClose()
|
|
}
|
|
}
|
|
}
|
|
},
|
|
watch: {
|
|
visible(val) {
|
|
if (val) {
|
|
this.loadHistoryProjects()
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
loadHistoryProjects() {
|
|
return listHistoryProjects({
|
|
projectName: this.searchKeyword || undefined
|
|
}).then(response => {
|
|
this.historyProjects = response.data || []
|
|
})
|
|
},
|
|
getStatusType(status) {
|
|
const statusMap = {
|
|
'0': 'primary',
|
|
'1': 'success',
|
|
'2': 'info',
|
|
'3': 'warning',
|
|
'4': 'danger'
|
|
}
|
|
return statusMap[status] || 'info'
|
|
},
|
|
getStatusLabel(status) {
|
|
const statusMap = {
|
|
'0': '进行中',
|
|
'1': '已完成',
|
|
'2': '已归档',
|
|
'3': '打标中',
|
|
'4': '打标失败'
|
|
}
|
|
return statusMap[status] || '未知'
|
|
},
|
|
handleSearch() {
|
|
this.loadHistoryProjects()
|
|
},
|
|
handleSubmit() {
|
|
if (this.selectedProjectIds.length === 0) {
|
|
this.$message.warning('请选择历史项目')
|
|
return
|
|
}
|
|
this.$refs.configForm.validate(async valid => {
|
|
if (!valid) {
|
|
return
|
|
}
|
|
this.submitting = true
|
|
try {
|
|
const response = await importFromHistory({
|
|
projectName: this.configForm.newProjectName,
|
|
description: this.configForm.description,
|
|
sourceProjectIds: this.selectedProjectIds,
|
|
startDate: this.configForm.dateRange[0] || '',
|
|
endDate: this.configForm.dateRange[1] || ''
|
|
})
|
|
this.$emit('submit', response.data)
|
|
} finally {
|
|
this.submitting = false
|
|
}
|
|
})
|
|
},
|
|
handleClose() {
|
|
this.$emit('close')
|
|
this.selectedProjectIds = []
|
|
this.searchKeyword = ''
|
|
this.historyProjects = []
|
|
this.configForm = {
|
|
newProjectName: '',
|
|
description: '',
|
|
dateRange: []
|
|
}
|
|
this.$refs.configForm?.resetFields()
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.new-project-config {
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.project-list-section {
|
|
margin-bottom: 16px;
|
|
|
|
.section-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: #303133;
|
|
}
|
|
|
|
.search-input {
|
|
width: 280px;
|
|
}
|
|
}
|
|
|
|
.project-checkbox-group {
|
|
width: 100%;
|
|
max-height: 320px;
|
|
overflow-y: auto;
|
|
|
|
&::-webkit-scrollbar {
|
|
width: 6px;
|
|
}
|
|
|
|
&::-webkit-scrollbar-thumb {
|
|
background-color: #dcdfe6;
|
|
border-radius: 3px;
|
|
}
|
|
}
|
|
|
|
.project-item-wrapper {
|
|
display: block;
|
|
margin-bottom: 12px;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
|
|
.project-checkbox {
|
|
display: block;
|
|
width: 100%;
|
|
|
|
:deep(.el-checkbox__label) {
|
|
width: calc(100% - 24px);
|
|
padding-left: 8px;
|
|
}
|
|
|
|
:deep(.el-checkbox__input) {
|
|
margin-top: 20px;
|
|
}
|
|
}
|
|
|
|
.project-item {
|
|
padding: 12px;
|
|
background-color: #f5f7fa;
|
|
border-radius: 8px;
|
|
|
|
.project-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 8px;
|
|
|
|
.name {
|
|
font-size: 15px;
|
|
font-weight: 500;
|
|
color: #303133;
|
|
}
|
|
}
|
|
|
|
.project-info {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 16px;
|
|
|
|
.info-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: 13px;
|
|
color: #909399;
|
|
}
|
|
}
|
|
}
|
|
|
|
.dialog-footer {
|
|
text-align: right;
|
|
|
|
.el-button + .el-button {
|
|
margin-left: 8px;
|
|
}
|
|
}
|
|
|
|
:deep(.el-empty) {
|
|
padding: 20px 0;
|
|
}
|
|
</style>
|