<template>
|
<div class="app-container">
|
<SearchPanel
|
v-model="queryParams"
|
:schema="searchSchema"
|
@search="handleQuery"
|
@reset="resetQuery"
|
>
|
<template #billStatus="{ item }">
|
<el-select v-model="queryParams[item.prop]" placeholder="请选择单据状态" clearable style="width: 100%">
|
<el-option v-for="dict in bill_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
</el-select>
|
</template>
|
<template #auditStatus="{ item }">
|
<el-select v-model="queryParams[item.prop]" placeholder="请选择计划状态" clearable style="width: 100%">
|
<el-option v-for="dict in project_management" :key="dict.value" :label="dict.label" :value="dict.value" />
|
</el-select>
|
</template>
|
<template #projectStage="{ item }">
|
<el-select v-model="queryParams[item.prop]" placeholder="请选择审核状态" clearable style="width: 100%">
|
<el-option v-for="dict in plan_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
</el-select>
|
</template>
|
</SearchPanel>
|
|
<div class="table-container">
|
<div class="table-actions">
|
<el-button style="background-color: #002FA7; color: #fff" @click="handleAdd">新增</el-button>
|
<!-- <el-dropdown split-button type="default" @command="handleGenerateBill" style="margin-left: 10px;">
|
生成单据
|
<template #dropdown>
|
<el-dropdown-menu>
|
<el-dropdown-item command="1">生成单据1</el-dropdown-item>
|
<el-dropdown-item command="2">生成单据2</el-dropdown-item>
|
</el-dropdown-menu>
|
</template>
|
</el-dropdown> -->
|
<el-button @click="handleSubmit">提交</el-button>
|
<el-button @click="handleAudit">审核</el-button>
|
<el-button @click="handleReverseAudit">反审核</el-button>
|
<el-button @click="handleDelete">删除</el-button>
|
</div>
|
|
<PIMTable
|
:column="columns"
|
:tableData="tableData"
|
:page="pagination"
|
:tableLoading="loading"
|
:isSelection="true"
|
@selection-change="handleSelectionChange"
|
@pagination="handlePagination"
|
>
|
<template #auditStatus="{ row }">
|
<dict-tag :options="project_management" :value="row.auditStatus" />
|
</template>
|
<template #projectStage="{ row }">
|
<dict-tag :options="plan_status" :value="row.projectStage" />
|
</template>
|
<template #action="{ row }">
|
<el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
|
<el-button link type="primary" @click="handleProgressReport(row)">进度汇报</el-button>
|
<el-button link type="primary" @click="handleDiscussProgress(row)">洽谈进展</el-button>
|
<el-button link type="primary" @click="handleDetail(row)">详情</el-button>
|
</template>
|
</PIMTable>
|
</div>
|
|
<FormDia ref="formDiaRef" @completed="getList" />
|
</div>
|
</template>
|
|
<script setup name="ProjectManagement">
|
import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
|
import SearchPanel from '@/components/SearchPanel/index.vue'
|
import PIMTable from '@/components/PIMTable/PIMTable.vue'
|
import FormDia from './components/formDia.vue'
|
import {
|
listProject,
|
delProject,
|
submitProject,
|
auditProject,
|
reverseAuditProject
|
} from '@/api/projectManagement/project'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
const { proxy } = getCurrentInstance()
|
const { bill_status, project_management, plan_status } = proxy.useDict('bill_status', 'project_management', 'plan_status')
|
|
const loading = ref(false)
|
const ids = ref([])
|
const tableData = ref([])
|
const formDiaRef = ref()
|
|
const data = reactive({
|
queryParams: {
|
projectNameOrCode: undefined,
|
customerName: undefined,
|
billStatus: undefined,
|
projectStage: undefined,
|
auditStatus: undefined,
|
salesperson: undefined,
|
pageNum: 1,
|
pageSize: 10
|
},
|
pagination: {
|
current: 1,
|
size: 10,
|
total: 0,
|
layout: 'total, sizes, prev, pager, next, jumper'
|
}
|
})
|
|
const { queryParams, pagination } = toRefs(data)
|
|
const searchSchema = [
|
{ prop: 'projectNameOrCode', label: '项目名称/编号', type: 'input', placeholder: '请输入项目名称/编号' },
|
{ prop: 'customerName', label: '客户名称', type: 'input', placeholder: '请输入客户名称' },
|
{ prop: 'billStatus', label: '单据状态', slot: 'billStatus' },
|
{ prop: 'projectStage', label: '计划状态', slot: 'projectStage' },
|
{ prop: 'auditStatus', label: '审核状态', slot: 'auditStatus' },
|
{ prop: 'salesperson', label: '业务人员', type: 'input', placeholder: '请输入业务人员' }
|
]
|
|
const columns = [
|
{ label: '单据编号', prop: 'billNo', align: 'center', width: '150' },
|
{ label: '项目名称', prop: 'projectName', align: 'center' },
|
{ label: '审核状态', prop: 'auditStatus', align: 'center', dataType: 'slot', slot: 'auditStatus' },
|
{ label: '客户名称', prop: 'customerName', align: 'center' },
|
{ label: '立项日期', prop: 'setupDate', align: 'center', width: '120' },
|
{ label: '项目来源', prop: 'projectSource', align: 'center' },
|
{ label: '项目分类', prop: 'projectClassification', align: 'center' },
|
{ label: '操作', prop: 'action', align: 'center', width: '250', dataType: 'slot', slot: 'action', fixed: 'right' }
|
]
|
|
function getList() {
|
loading.value = true
|
const params = {
|
noOrName: queryParams.value.projectNameOrCode,
|
clientName: queryParams.value.customerName,
|
salesmanName: queryParams.value.salesperson,
|
reviewStatus: queryParams.value.auditStatus,
|
stage: queryParams.value.projectStage,
|
current: queryParams.value.pageNum,
|
size: queryParams.value.pageSize
|
}
|
listProject(params)
|
.then(response => {
|
const records = response?.data?.records || response?.rows || response?.records || []
|
const billFilter = queryParams.value.billStatus
|
const filtered = billFilter === undefined || billFilter === null || billFilter === ''
|
? records
|
: records.filter(r => String(r.billStatus ?? r.status) === String(billFilter))
|
tableData.value = filtered.map(r => ({
|
id: r.id,
|
billNo: r.no ?? r.billNo,
|
projectName: r.title ?? r.projectName,
|
billStatus: r.billStatus ?? r.status,
|
auditStatus: r.reviewStatus ?? r.auditStatus,
|
projectStage: r.stage ?? r.projectStage,
|
customerName: r.clientName ?? r.customerName,
|
parentProject: r.parentTitle ?? r.parentName ?? r.parentProject,
|
setupDate: r.establishTime ?? r.setupDate,
|
projectType: r.planName ?? r.projectType,
|
projectSource: r.source ?? r.projectSource,
|
projectClassification: r.departmentName ?? r.projectClassification,
|
raw: r
|
}))
|
pagination.value.total = response?.total || response?.data?.total || 0
|
})
|
.finally(() => {
|
loading.value = false
|
})
|
}
|
|
function handleQuery() {
|
queryParams.value.pageNum = 1
|
pagination.value.current = 1
|
getList()
|
}
|
|
function resetQuery() {
|
queryParams.value = {
|
projectNameOrCode: undefined,
|
customerName: undefined,
|
billStatus: undefined,
|
projectStage: undefined,
|
auditStatus: undefined,
|
salesperson: undefined,
|
pageNum: 1,
|
pageSize: 10
|
}
|
handleQuery()
|
}
|
|
function handleSelectionChange(selection) {
|
ids.value = selection.map(item => item.id)
|
}
|
|
function handlePagination({ page, limit }) {
|
queryParams.value.pageNum = page
|
queryParams.value.pageSize = limit
|
pagination.value.current = page
|
pagination.value.size = limit
|
getList()
|
}
|
|
function handleAdd() {
|
formDiaRef.value?.openDialog({ operationType: 'add' })
|
}
|
|
function handleDelete() {
|
const delIds = ids.value
|
if (delIds.length === 0) {
|
ElMessage.warning('请选择要删除的数据项')
|
return
|
}
|
ElMessageBox.confirm('是否确认删除所选数据项?', '警告', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
.then(() => delProject(delIds))
|
.then(() => {
|
getList()
|
ElMessage.success('删除成功')
|
})
|
.catch(() => {})
|
}
|
|
function handleSubmit() {
|
const submitIds = ids.value
|
if (submitIds.length === 0) {
|
ElMessage.warning('请选择要提交的数据项')
|
return
|
}
|
ElMessageBox.confirm('是否确认提交所选数据项?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
.then(async () => {
|
await Promise.all(submitIds.map(id => submitProject({ id })))
|
})
|
.then(() => {
|
getList()
|
ElMessage.success('提交成功')
|
})
|
.catch(() => {})
|
}
|
|
function handleAudit() {
|
const auditIds = ids.value
|
if (auditIds.length === 0) {
|
ElMessage.warning('请选择要审核的数据项')
|
return
|
}
|
ElMessageBox.confirm('是否确认审核所选数据项?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
.then(async () => {
|
await Promise.all(auditIds.map(id => auditProject({ id })))
|
})
|
.then(() => {
|
getList()
|
ElMessage.success('审核成功')
|
})
|
.catch(() => {})
|
}
|
|
function handleReverseAudit() {
|
const reverseAuditIds = ids.value
|
if (reverseAuditIds.length === 0) {
|
ElMessage.warning('请选择要反审核的数据项')
|
return
|
}
|
ElMessageBox.confirm('是否确认反审核所选数据项?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
.then(async () => {
|
await Promise.all(reverseAuditIds.map(id => reverseAuditProject({ id })))
|
})
|
.then(() => {
|
getList()
|
ElMessage.success('反审核成功')
|
})
|
.catch(() => {})
|
}
|
|
function handleGenerateBill(command) {
|
ElMessage.info(`生成单据: ${command}`)
|
}
|
|
function handleProgressReport(row) {
|
formDiaRef.value?.openDialog({ operationType: 'view', row })
|
}
|
|
function handleDiscussProgress(row) {
|
formDiaRef.value?.openDialog({ operationType: 'view', row })
|
}
|
|
function handleDetail(row) {
|
formDiaRef.value?.openDialog({ operationType: 'view', row })
|
}
|
|
function handleEdit(row) {
|
formDiaRef.value?.openDialog({ operationType: 'edit', row })
|
}
|
|
onMounted(() => {
|
getList()
|
})
|
</script>
|
|
<style scoped lang="scss">
|
.app-container {
|
padding: 20px;
|
}
|
.table-container {
|
background-color: #fff;
|
padding: 20px;
|
border-radius: 4px;
|
}
|
.table-actions {
|
margin-bottom: 15px;
|
display: flex;
|
align-items: center;
|
gap: 10px;
|
}
|
</style>
|