Files
ccdi/ruoyi-ui/src/views/ccdiProject/components/ImportHistoryDialog.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>