feat(oa/project/dispatch): 新增项目和合同的CRUD功能
重构项目调度页面: 1. 左侧项目列表新增增删改操作按钮 2. 合同模块新增工具栏和增删改功能 3. 实现完整的项目编辑弹窗,包含表单校验和字典数据绑定 4. 实现完整的合同编辑弹窗,支持甲乙双方信息填写 5. 补充对应的API调用和状态管理逻辑 6. 调整页面样式布局优化展示效果
This commit is contained in:
@@ -4,9 +4,16 @@
|
|||||||
<!-- ══════════════ 左栏:项目列表 ══════════════ -->
|
<!-- ══════════════ 左栏:项目列表 ══════════════ -->
|
||||||
<div class="panel-left">
|
<div class="panel-left">
|
||||||
<div class="left-header">
|
<div class="left-header">
|
||||||
<span class="left-title">项目列表</span>
|
<div class="left-header-row">
|
||||||
|
<span class="left-title">项目管理</span>
|
||||||
<span class="left-count">{{ projectList.length }} 个</span>
|
<span class="left-count">{{ projectList.length }} 个</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="left-actions">
|
||||||
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddProject">新增</el-button>
|
||||||
|
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="!activeProject" @click="handleEditProject">修改</el-button>
|
||||||
|
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="!activeProject" @click="handleDeleteProject">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="left-search">
|
<div class="left-search">
|
||||||
<el-input v-model="searchText" placeholder="编号 / 代号 / 名称" prefix-icon="el-icon-search" size="small" clearable @input="filterProjects" />
|
<el-input v-model="searchText" placeholder="编号 / 代号 / 名称" prefix-icon="el-icon-search" size="small" clearable @input="filterProjects" />
|
||||||
</div>
|
</div>
|
||||||
@@ -103,7 +110,18 @@
|
|||||||
<!-- ── 合同 ── -->
|
<!-- ── 合同 ── -->
|
||||||
<template v-else-if="activeTab === 'contract'">
|
<template v-else-if="activeTab === 'contract'">
|
||||||
<div class="section-title">合同记录</div>
|
<div class="section-title">合同记录</div>
|
||||||
<el-table :data="moduleData.contract" size="small" border stripe>
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddContract">新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="!contractSelectedRow" @click="handleEditContract">修改</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="!contractSelectedRow" @click="handleDeleteContract">删除</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-table :data="moduleData.contract" size="small" border stripe highlight-current-row @current-change="val => { contractSelectedRow = val }">
|
||||||
<el-table-column label="合同编号" prop="contractNum" width="140" />
|
<el-table-column label="合同编号" prop="contractNum" width="140" />
|
||||||
<el-table-column label="合同名称" prop="contractName" min-width="160" show-overflow-tooltip />
|
<el-table-column label="合同名称" prop="contractName" min-width="160" show-overflow-tooltip />
|
||||||
<el-table-column label="合同金额(元)" prop="contractPrice" width="120" align="right">
|
<el-table-column label="合同金额(元)" prop="contractPrice" width="120" align="right">
|
||||||
@@ -585,12 +603,223 @@
|
|||||||
<p>请从左侧选择一个项目</p>
|
<p>请从左侧选择一个项目</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- ══════════════ 项目编辑弹窗 ══════════════ -->
|
||||||
|
<el-dialog :title="projectTitle" :visible.sync="projectEditShow" width="70%" append-to-body @close="closeProjectDialog">
|
||||||
|
<el-form ref="projectFormRef" :model="projectForm" :rules="projectRules" label-width="100px">
|
||||||
|
<el-divider content-position="center">基本信息</el-divider>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-form-item label="项目名称" prop="projectName">
|
||||||
|
<el-input v-model="projectForm.projectName" placeholder="请输入项目名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="项目总金额" prop="funds">
|
||||||
|
<el-input v-model="projectForm.funds" placeholder="元" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="负责人" prop="functionary">
|
||||||
|
<el-input v-model="projectForm.functionary" placeholder="项目负责人" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="项目编号" prop="projectNum">
|
||||||
|
<el-input v-model="projectForm.projectNum" placeholder="项目编号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="项目代号" prop="projectCode">
|
||||||
|
<el-select v-model="projectForm.projectCodeType" placeholder="代号类型" style="width:45%" filterable>
|
||||||
|
<el-option v-for="dict in dict.type.sys_project_code" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
|
</el-select>
|
||||||
|
<el-input v-model="projectForm.projectCodeNumber" placeholder="序号" style="width:55%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="项目地址" prop="address">
|
||||||
|
<el-input v-model="projectForm.address" placeholder="项目地址" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="贸易类型">
|
||||||
|
<el-select v-model="projectForm.tradeType" placeholder="贸易类型" style="width:100%">
|
||||||
|
<el-option v-for="dict in dict.type.sys_trade_type" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="项目类型">
|
||||||
|
<el-select v-model="projectForm.projectType" placeholder="项目类型" style="width:100%">
|
||||||
|
<el-option v-for="dict in dict.type.sys_project_type" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="优先级">
|
||||||
|
<el-radio-group v-model="projectForm.projectGrade">
|
||||||
|
<el-radio-button v-for="dict in dict.type.sys_sort_grade" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-form-item label="项目周期">
|
||||||
|
<el-date-picker v-model="projectPeriod" value-format="yyyy-MM-dd HH:mm:ss" type="daterange" range-separator="至" start-placeholder="开始" end-placeholder="结束" style="width:100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="交货期" prop="delivery">
|
||||||
|
<el-input v-model="projectForm.delivery" placeholder="交货期" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="质保期" prop="guarantee">
|
||||||
|
<el-input v-model="projectForm.guarantee" placeholder="质保期" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="签约公司">
|
||||||
|
<el-select v-model="projectForm.signingCompany" placeholder="签约公司" style="width:100%" clearable>
|
||||||
|
<el-option v-for="dict in dict.type.signing_company" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="预付款" prop="prePay">
|
||||||
|
<el-input v-model="projectForm.prePay" placeholder="预付款金额" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="项目介绍">
|
||||||
|
<el-input v-model="projectForm.introduction" type="textarea" :rows="3" placeholder="项目介绍" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="projectForm.remark" type="textarea" :rows="2" placeholder="备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="附件">
|
||||||
|
<file-upload v-model="projectForm.accessory" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="closeProjectDialog">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="projectSubmitLoading" @click="submitProjectForm">保 存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- ══════════════ 合同编辑弹窗 ══════════════ -->
|
||||||
|
<el-dialog :title="contractTitle" :visible.sync="contractEditShow" width="65%" append-to-body @close="closeContractDialog">
|
||||||
|
<el-form ref="contractFormRef" :model="contractForm" label-width="100px">
|
||||||
|
<!-- 基本信息 -->
|
||||||
|
<el-divider content-position="left">基本信息</el-divider>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-form-item label="合同名称" prop="contractName">
|
||||||
|
<el-input v-model="contractForm.contractName" placeholder="合同名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="合同编号" prop="contractNum">
|
||||||
|
<el-input v-model="contractForm.contractNum" placeholder="合同编号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="合同金额(元)" prop="contractPrice">
|
||||||
|
<el-input v-model="contractForm.contractPrice" placeholder="合同金额" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="合同类型">
|
||||||
|
<el-select v-model="contractForm.contractType" placeholder="合同类型" style="width:100%">
|
||||||
|
<el-option label="项目合同" value="2" />
|
||||||
|
<el-option label="采购合同" value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="合同状态">
|
||||||
|
<el-input v-model="contractForm.contractStatus" placeholder="合同状态" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="签订日期 / 有效期">
|
||||||
|
<el-date-picker v-model="contractPeriod" value-format="yyyy-MM-dd" type="daterange" range-separator="至" start-placeholder="签订日期" end-placeholder="有效期" style="width:100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 甲方 -->
|
||||||
|
<el-divider content-position="left">甲方信息</el-divider>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="甲方单位">
|
||||||
|
<el-input v-model="contractForm.firstName" placeholder="甲方单位名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="甲方负责人">
|
||||||
|
<el-input v-model="contractForm.firstPerson" placeholder="负责人" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="甲方电话">
|
||||||
|
<el-input v-model="contractForm.firstPhone" placeholder="联系电话" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 乙方 -->
|
||||||
|
<el-divider content-position="left">乙方信息</el-divider>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="乙方单位">
|
||||||
|
<el-input v-model="contractForm.secondName" placeholder="乙方单位名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="乙方负责人">
|
||||||
|
<el-input v-model="contractForm.secondPerson" placeholder="负责人" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="乙方电话">
|
||||||
|
<el-input v-model="contractForm.secondPhone" placeholder="联系电话" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 其他 -->
|
||||||
|
<el-divider content-position="left">其他信息</el-divider>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="contractForm.remark" type="textarea" :rows="2" placeholder="备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="附件">
|
||||||
|
<file-upload v-model="contractForm.accessory" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="closeContractDialog">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="contractSubmitLoading" @click="submitContractForm">保 存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listProject, getProject } from '@/api/oa/project'
|
import { listProject, getProject, addProject, updateProject, delProject } from '@/api/oa/project'
|
||||||
import { listOaContract } from '@/api/oa/oaContract'
|
import { listOaContract, addOaContract, updateOaContract, delOaContract } from '@/api/oa/oaContract'
|
||||||
import { listFinancePro } from '@/api/oa/finance'
|
import { listFinancePro } from '@/api/oa/finance'
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
// /oa/cost/list1 支持 projectId 过滤(list 是全项目汇总,不能用)
|
// /oa/cost/list1 支持 projectId 过滤(list 是全项目汇总,不能用)
|
||||||
@@ -611,6 +840,7 @@ import { listReportSummary } from '@/api/oa/reportSummary'
|
|||||||
import { listFileOperationRecord } from '@/api/oa/fileOperationRecord'
|
import { listFileOperationRecord } from '@/api/oa/fileOperationRecord'
|
||||||
import { listFeedback } from '@/api/oa/feedback'
|
import { listFeedback } from '@/api/oa/feedback'
|
||||||
import { listOperationLog } from '@/api/oa/projectOperationLog'
|
import { listOperationLog } from '@/api/oa/projectOperationLog'
|
||||||
|
import FileUpload from '@/components/FileUpload/index.vue'
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [
|
||||||
{ key: 'info', label: '基本信息', icon: 'el-icon-office-building' },
|
{ key: 'info', label: '基本信息', icon: 'el-icon-office-building' },
|
||||||
@@ -655,6 +885,8 @@ function makePaging () { return { pageNum: 1, pageSize: 20, total: 0 } }
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ProjectDispatch',
|
name: 'ProjectDispatch',
|
||||||
|
components: { FileUpload },
|
||||||
|
dicts: ['sys_project_status', 'sys_project_type', 'sys_trade_type', 'sys_project_code', 'signing_company', 'sys_sort_grade'],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
MODULES,
|
MODULES,
|
||||||
@@ -667,7 +899,29 @@ export default {
|
|||||||
moduleData: {},
|
moduleData: {},
|
||||||
moduleLoading: {},
|
moduleLoading: {},
|
||||||
badgeCounts: {},
|
badgeCounts: {},
|
||||||
modulePaging: Object.fromEntries(MODULES.map(m => [m.key, makePaging()]))
|
modulePaging: Object.fromEntries(MODULES.map(m => [m.key, makePaging()])),
|
||||||
|
// ── 项目 CRUD ──
|
||||||
|
projectEditShow: false,
|
||||||
|
projectForm: {},
|
||||||
|
projectPeriod: [],
|
||||||
|
projectTitle: '',
|
||||||
|
projectSubmitLoading: false,
|
||||||
|
// ── 合同 CRUD ──
|
||||||
|
contractEditShow: false,
|
||||||
|
contractForm: {},
|
||||||
|
contractTitle: '',
|
||||||
|
contractSubmitLoading: false,
|
||||||
|
contractSelectedRow: null,
|
||||||
|
// 合同表单额外字段
|
||||||
|
contractPeriod: [],
|
||||||
|
// ── 表单校验规则 ──
|
||||||
|
projectRules: {
|
||||||
|
projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
|
||||||
|
projectNum: [{ required: true, message: '项目编号不能为空', trigger: 'blur' }],
|
||||||
|
functionary: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
|
||||||
|
address: [{ required: true, message: '项目地址不能为空', trigger: 'blur' }],
|
||||||
|
funds: [{ required: true, message: '项目总金额不能为空', trigger: 'blur' }]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -796,6 +1050,126 @@ export default {
|
|||||||
listOperationLog(cp).then(r => setCount('oplog', r)).catch(() => {})
|
listOperationLog(cp).then(r => setCount('oplog', r)).catch(() => {})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ── 项目 CRUD 方法 ──
|
||||||
|
handleAddProject () {
|
||||||
|
this.projectForm = {}
|
||||||
|
this.projectPeriod = []
|
||||||
|
this.projectTitle = '新增项目'
|
||||||
|
this.projectEditShow = true
|
||||||
|
},
|
||||||
|
handleEditProject () {
|
||||||
|
const p = this.activeProject
|
||||||
|
if (!p) { this.$message.warning('请先选择项目'); return }
|
||||||
|
getProject(p.projectId).then(res => {
|
||||||
|
this.projectForm = res.data || {}
|
||||||
|
this.projectPeriod = [this.projectForm.beginTime, this.projectForm.finishTime]
|
||||||
|
this.projectTitle = '编辑项目: ' + (res.data?.projectName || '')
|
||||||
|
this.projectEditShow = true
|
||||||
|
}).catch(() => { this.$message.error('获取项目详情失败') })
|
||||||
|
},
|
||||||
|
handleDeleteProject () {
|
||||||
|
const p = this.activeProject
|
||||||
|
if (!p) { this.$message.warning('请先选择项目'); return }
|
||||||
|
this.$confirm(`确定删除项目"${p.projectName}"?删除后不可恢复。`, '警告', {
|
||||||
|
confirmButtonText: '确定删除',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
return delProject(p.projectId)
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success('删除成功')
|
||||||
|
this.activeProject = null
|
||||||
|
this.loadProjects()
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
submitProjectForm () {
|
||||||
|
this.projectSubmitLoading = true
|
||||||
|
const payload = {
|
||||||
|
...this.projectForm,
|
||||||
|
beginTime: this.projectPeriod[0] || null,
|
||||||
|
finishTime: this.projectPeriod[1] || null,
|
||||||
|
projectCode: (this.projectForm.projectCodeType && this.projectForm.projectCodeNumber)
|
||||||
|
? this.projectForm.projectCodeType + '-' + this.projectForm.projectCodeNumber
|
||||||
|
: this.projectForm.projectCode || undefined
|
||||||
|
}
|
||||||
|
const isEdit = !!this.projectForm.projectId
|
||||||
|
const api = isEdit ? updateProject(payload) : addProject(payload)
|
||||||
|
api.then(() => {
|
||||||
|
this.$message.success(isEdit ? '修改成功' : '新增成功')
|
||||||
|
this.projectEditShow = false
|
||||||
|
this.loadProjects()
|
||||||
|
// 如果是编辑,刷新右侧详情
|
||||||
|
if (isEdit && this.activeProject) {
|
||||||
|
this.activeProject = { ...this.activeProject, ...payload }
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
this.$message.error('操作失败')
|
||||||
|
}).finally(() => {
|
||||||
|
this.projectSubmitLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
closeProjectDialog () {
|
||||||
|
this.projectEditShow = false
|
||||||
|
this.projectForm = {}
|
||||||
|
},
|
||||||
|
// ── 合同 CRUD 方法 ──
|
||||||
|
handleAddContract () {
|
||||||
|
if (!this.activeProject) { this.$message.warning('请先选择项目'); return }
|
||||||
|
this.contractForm = { projectId: this.activeProject.projectId, contractType: '2' }
|
||||||
|
this.contractPeriod = []
|
||||||
|
this.contractTitle = '新增合同'
|
||||||
|
this.contractEditShow = true
|
||||||
|
},
|
||||||
|
handleEditContract () {
|
||||||
|
const row = this.contractSelectedRow
|
||||||
|
if (!row) { this.$message.warning('请先选择一条合同记录'); return }
|
||||||
|
this.contractForm = { ...row }
|
||||||
|
this.contractPeriod = [row.signTime, row.validity]
|
||||||
|
this.contractTitle = '编辑合同: ' + (row.contractName || '')
|
||||||
|
this.contractEditShow = true
|
||||||
|
},
|
||||||
|
handleDeleteContract () {
|
||||||
|
const row = this.contractSelectedRow
|
||||||
|
if (!row) { this.$message.warning('请先选择一条合同记录'); return }
|
||||||
|
this.$confirm(`确定删除合同"${row.contractName}"?`, '警告', {
|
||||||
|
confirmButtonText: '确定删除',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
return delOaContract(row.contractId)
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success('删除成功')
|
||||||
|
this.contractSelectedRow = null
|
||||||
|
this.fetchModule('contract')
|
||||||
|
this.loadAllBadges()
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
submitContractForm () {
|
||||||
|
this.contractSubmitLoading = true
|
||||||
|
const payload = {
|
||||||
|
...this.contractForm,
|
||||||
|
projectId: this.activeProject?.projectId,
|
||||||
|
signTime: this.contractPeriod[0] || null,
|
||||||
|
validity: this.contractPeriod[1] || null
|
||||||
|
}
|
||||||
|
const isEdit = !!this.contractForm.contractId
|
||||||
|
const api = isEdit ? updateOaContract(payload) : addOaContract(payload)
|
||||||
|
api.then(() => {
|
||||||
|
this.$message.success(isEdit ? '修改成功' : '新增成功')
|
||||||
|
this.contractEditShow = false
|
||||||
|
this.contractSelectedRow = null
|
||||||
|
this.fetchModule('contract')
|
||||||
|
this.loadAllBadges()
|
||||||
|
}).catch(() => {
|
||||||
|
this.$message.error('操作失败')
|
||||||
|
}).finally(() => {
|
||||||
|
this.contractSubmitLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
closeContractDialog () {
|
||||||
|
this.contractEditShow = false
|
||||||
|
this.contractForm = {}
|
||||||
|
},
|
||||||
// ── 辅助 ──
|
// ── 辅助 ──
|
||||||
// sys_project_status 字典: '0'=进行中(primary), '1'=进度完成(success)
|
// sys_project_status 字典: '0'=进行中(primary), '1'=进度完成(success)
|
||||||
statusLabel (s) {
|
statusLabel (s) {
|
||||||
@@ -863,15 +1237,18 @@ export default {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.left-header {
|
.left-header {
|
||||||
padding: 14px 14px 8px;
|
padding: 10px 12px 8px;
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
gap: 6px;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
border-bottom: 1px solid #f0f0f0;
|
border-bottom: 1px solid #f0f0f0;
|
||||||
}
|
}
|
||||||
|
.left-header-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
.left-title { font-size: 14px; font-weight: 700; color: #303133; }
|
.left-title { font-size: 14px; font-weight: 700; color: #303133; }
|
||||||
.left-count { font-size: 12px; color: #909399; }
|
.left-count { font-size: 12px; color: #909399; }
|
||||||
|
.left-actions { display: flex; gap: 4px; margin-top: 6px; flex-wrap: wrap; }
|
||||||
.left-search { padding: 10px 10px 6px; flex-shrink: 0; }
|
.left-search { padding: 10px 10px 6px; flex-shrink: 0; }
|
||||||
.left-list { flex: 1; overflow-y: auto; }
|
.left-list { flex: 1; overflow-y: auto; }
|
||||||
.left-empty { text-align: center; color: #c0c4cc; padding: 40px 0; font-size: 13px; }
|
.left-empty { text-align: center; color: #c0c4cc; padding: 40px 0; font-size: 13px; }
|
||||||
@@ -1020,6 +1397,7 @@ export default {
|
|||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
border-left: 3px solid #409EFF;
|
border-left: 3px solid #409EFF;
|
||||||
}
|
}
|
||||||
|
.mb8 { margin-bottom: 8px; }
|
||||||
|
|
||||||
/* ══ 统计卡片(基本信息页底部) ══ */
|
/* ══ 统计卡片(基本信息页底部) ══ */
|
||||||
.stat-mini {
|
.stat-mini {
|
||||||
|
|||||||
Reference in New Issue
Block a user