335 lines
9.9 KiB
Vue

<template>
<div class="page-container">
<el-card>
<template #header>
<div class="card-header">
<span>合同管理</span>
<el-button type="primary" @click="handleAdd">新增合同</el-button>
</div>
</template>
<el-form :inline="true" class="search-form">
<el-form-item label="合同名称">
<el-input v-model="searchForm.contractName" placeholder="请输入合同名称" />
</el-form-item>
<el-form-item label="合同状态">
<el-select v-model="searchForm.contractStatus" placeholder="请选择" clearable>
<el-option label="草稿" value="DRAFT" />
<el-option label="已签署" value="SIGNED" />
<el-option label="执行中" value="EXECUTING" />
<el-option label="已完成" value="COMPLETED" />
<el-option label="已终止" value="TERMINATED" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">查询</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
<el-table :data="tableData" border v-loading="loading">
<el-table-column prop="contractCode" label="合同编码" width="120" />
<el-table-column prop="contractName" label="合同名称" />
<el-table-column prop="contractStatus" label="合同状态" width="100">
<template #default="scope">
<el-tag :type="getStatusType(scope.row.contractStatus)">
{{ getStatusText(scope.row.contractStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="contractAmount" label="合同金额" width="120">
<template #default="scope">
{{ formatAmount(scope.row.contractAmount) }}
</template>
</el-table-column>
<el-table-column prop="signDate" label="签署日期" width="120" />
<el-table-column prop="effectiveDate" label="生效日期" width="120" />
<el-table-column label="操作" width="200" fixed="right">
<template #default="scope">
<el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
class="pagination"
v-model:current-page="page.current"
v-model:page-size="page.size"
:total="page.total"
layout="total, sizes, prev, pager, next"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-card>
<!-- 新增/编辑对话框 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="合同编码" prop="contractCode">
<el-input v-model="form.contractCode" placeholder="请输入合同编码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同名称" prop="contractName">
<el-input v-model="form.contractName" placeholder="请输入合同名称" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="合同金额" prop="contractAmount">
<el-input-number v-model="form.contractAmount" :precision="2" :min="0" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同类型">
<el-select v-model="form.contractType" placeholder="请选择" style="width: 100%">
<el-option label="销售合同" value="SALES" />
<el-option label="采购合同" value="PURCHASE" />
<el-option label="服务合同" value="SERVICE" />
<el-option label="其他" value="OTHER" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="签署日期">
<el-date-picker v-model="form.signDate" type="date" placeholder="选择日期" style="width: 100%" value-format="YYYY-MM-DD" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生效日期">
<el-date-picker v-model="form.effectiveDate" type="date" placeholder="选择日期" style="width: 100%" value-format="YYYY-MM-DD" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="到期日期">
<el-date-picker v-model="form.expiryDate" type="date" placeholder="选择日期" style="width: 100%" value-format="YYYY-MM-DD" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="签署地点">
<el-input v-model="form.signLocation" placeholder="请输入签署地点" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="付款条款">
<el-input v-model="form.paymentTerms" type="textarea" rows="2" placeholder="请输入付款条款" />
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" rows="2" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getContractList, createContract, updateContract, deleteContract } from '../../api/project'
const loading = ref(false)
const tableData = ref([])
const searchForm = reactive({
contractName: '',
contractStatus: ''
})
const page = reactive({
current: 1,
size: 10,
total: 0
})
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formRef = ref(null)
const form = reactive({
contractId: null,
contractCode: '',
contractName: '',
contractType: 'SALES',
contractAmount: 0,
signDate: '',
effectiveDate: '',
expiryDate: '',
signLocation: '',
paymentTerms: '',
remark: ''
})
const rules = {
contractCode: [{ required: true, message: '请输入合同编码', trigger: 'blur' }],
contractName: [{ required: true, message: '请输入合同名称', trigger: 'blur' }],
contractAmount: [{ required: true, message: '请输入合同金额', trigger: 'blur' }]
}
const fetchData = async () => {
loading.value = true
try {
const res = await getContractList({
current: page.current,
size: page.size,
contractName: searchForm.contractName,
contractStatus: searchForm.contractStatus
})
tableData.value = res.records
page.total = res.total
} catch (error) {
console.error('获取合同列表失败:', error)
} finally {
loading.value = false
}
}
const handleSearch = () => {
page.current = 1
fetchData()
}
const handleReset = () => {
searchForm.contractName = ''
searchForm.contractStatus = ''
handleSearch()
}
const handleAdd = () => {
dialogTitle.value = '新增合同'
resetForm()
dialogVisible.value = true
}
const handleEdit = (row) => {
dialogTitle.value = '编辑合同'
resetForm()
Object.assign(form, row)
dialogVisible.value = true
}
const resetForm = () => {
form.contractId = null
form.contractCode = ''
form.contractName = ''
form.contractType = 'SALES'
form.contractAmount = 0
form.signDate = ''
form.effectiveDate = ''
form.expiryDate = ''
form.signLocation = ''
form.paymentTerms = ''
form.remark = ''
}
const handleSubmit = async () => {
if (!formRef.value) return
await formRef.value.validate(async (valid) => {
if (valid) {
try {
if (form.contractId) {
await updateContract(form.contractId, form)
ElMessage.success('更新成功')
} else {
await createContract(form)
ElMessage.success('创建成功')
}
dialogVisible.value = false
fetchData()
} catch (error) {
console.error('保存失败:', error)
}
}
})
}
const handleDelete = (row) => {
ElMessageBox.confirm('确定要删除该合同吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
await deleteContract(row.contractId)
ElMessage.success('删除成功')
fetchData()
} catch (error) {
console.error('删除失败:', error)
}
})
}
const handleSizeChange = (val) => {
page.size = val
fetchData()
}
const handleCurrentChange = (val) => {
page.current = val
fetchData()
}
const getStatusType = (status) => {
const map = {
'DRAFT': 'info',
'SIGNED': 'warning',
'EXECUTING': 'primary',
'COMPLETED': 'success',
'TERMINATED': 'danger'
}
return map[status] || 'info'
}
const getStatusText = (status) => {
const map = {
'DRAFT': '草稿',
'SIGNED': '已签署',
'EXECUTING': '执行中',
'COMPLETED': '已完成',
'TERMINATED': '已终止'
}
return map[status] || status
}
const formatAmount = (amount) => {
if (!amount) return '¥0.00'
return '¥' + parseFloat(amount).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
}
onMounted(() => {
fetchData()
})
</script>
<style scoped>
.page-container {
padding: 20px;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.search-form {
margin-bottom: 20px;
}
.pagination {
margin-top: 20px;
justify-content: flex-end;
}
</style>