结算和合同管理模块开发
This commit is contained in:
parent
872fc0e443
commit
519a395fc7
|
|
@ -0,0 +1,38 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 合同管理 - 查询列表
|
||||
export function listContractAPI(query) {
|
||||
return request({
|
||||
url: '/contract/getContractList',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
})
|
||||
}
|
||||
|
||||
// 合同管理 - 新增
|
||||
export function addContractAPI(data) {
|
||||
return request({
|
||||
url: '/contract/addContract',
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
// 合同管理 - 修改
|
||||
export function updateContractAPI(data) {
|
||||
return request({
|
||||
url: '/contract/updateContract',
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
// 合同管理 - 删除
|
||||
export function delContractAPI(data) {
|
||||
return request({
|
||||
url: '/contract/delContract',
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 结算管理 - 查询列表
|
||||
export function listSettlementAPI(query) {
|
||||
return request({
|
||||
url: '/settlement/getSettlementList',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
})
|
||||
}
|
||||
|
||||
// 结算管理 - 查询详情
|
||||
export function getSettlementDetailAPI(settlementId) {
|
||||
return request({
|
||||
url: `/settlement/getSettlementDetail`,
|
||||
method: 'GET',
|
||||
params: {
|
||||
settlementId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 结算管理 - 新增
|
||||
export function addSettlementAPI(data) {
|
||||
return request({
|
||||
url: '/settlement/addSettlement',
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
// 结算管理 - 修改
|
||||
export function updateSettlementAPI(data) {
|
||||
return request({
|
||||
url: '/settlement/updateSettlement',
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
// 结算管理 - 删除
|
||||
export function delSettlementAPI(data) {
|
||||
return request({
|
||||
url: '/settlement/delSettlement',
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
// 结算管理 - 获取合同下拉列表
|
||||
export function getContractSelectAPI(query) {
|
||||
return request({
|
||||
url: '/contract/getContractListAll',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
})
|
||||
}
|
||||
|
||||
// 结算管理 - 获取计划列表(用于选择计划弹框)
|
||||
export function getPlanListForSelectAPI(query) {
|
||||
return request({
|
||||
url: '/settlement/getMonthPlanSelect',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
})
|
||||
}
|
||||
|
||||
// 结算管理 - 下载统计表
|
||||
export function downloadSettlementStatisticAPI(query) {
|
||||
return request({
|
||||
url: '/settlement/downloadStatistic',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
responseType: 'blob',
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -117,6 +117,22 @@ export const constantRoutes = [
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/settlement/settlementEdit',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/settlementManage/edit.vue'),
|
||||
name: 'SettlementEdit',
|
||||
meta: {
|
||||
title: '结算管理',
|
||||
activeMenu: '/settlement', // 保持左侧高亮在列表菜单
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
|
|
|
|||
|
|
@ -0,0 +1,179 @@
|
|||
<template>
|
||||
<el-form
|
||||
size="large"
|
||||
label-width="auto"
|
||||
:model="formData"
|
||||
ref="formRef"
|
||||
:rules="rules"
|
||||
class="add-and-edit-form"
|
||||
>
|
||||
<!-- 运检站 -->
|
||||
<el-form-item label="运检站" prop="inspectionStationId">
|
||||
<el-select
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
placeholder="请选择运检站"
|
||||
@change="handleInspectionStationChange"
|
||||
v-model="formData.inspectionStationId"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in inspectionStationOptions"
|
||||
:key="item.id"
|
||||
:value="item.id"
|
||||
:label="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 合同承揽时间 -->
|
||||
<el-form-item label="合同承揽时间" prop="contractPeriod">
|
||||
<el-date-picker
|
||||
type="year"
|
||||
style="width: 100%"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择合同承揽时间"
|
||||
v-model="formData.contractPeriod"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 合同名称 -->
|
||||
<el-form-item label="合同名称" prop="contractName">
|
||||
<el-input
|
||||
clearable
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
placeholder="请输入合同名称"
|
||||
v-model.trim="formData.contractName"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 合同编号 -->
|
||||
<el-form-item label="合同编号" prop="contractCode">
|
||||
<el-input
|
||||
clearable
|
||||
maxlength="50"
|
||||
show-word-limit
|
||||
placeholder="请输入合同编号"
|
||||
v-model.trim="formData.contractCode"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 合同状态 -->
|
||||
<el-form-item label="合同状态" prop="contractStatus">
|
||||
<el-select
|
||||
clearable
|
||||
style="width: 100%"
|
||||
placeholder="请选择合同状态"
|
||||
v-model="formData.contractStatus"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dictOptions"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 备注 -->
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
type="textarea"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
placeholder="请输入备注"
|
||||
v-model="formData.remark"
|
||||
:autosize="{ minRows: 4, maxRows: 8 }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row class="common-btn-row">
|
||||
<ComButton plain type="info" @click="handleCancel">取消</ComButton>
|
||||
<ComButton @click="handleSave">保存</ComButton>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script setup name="AddAndEditForm">
|
||||
import { ref } from 'vue'
|
||||
import ComButton from '@/components/ComButton/index.vue'
|
||||
|
||||
const props = defineProps({
|
||||
formData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
dictOptions: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
inspectionStationOptions: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['save', 'cancel'])
|
||||
|
||||
const formRef = ref(null)
|
||||
|
||||
const rules = {
|
||||
inspectionStationId: [{ required: true, message: '请选择运检站', trigger: 'change' }],
|
||||
contractPeriod: [{ required: true, message: '请选择合同承揽时间', trigger: 'change' }],
|
||||
contractName: [{ required: true, message: '请输入合同名称', trigger: 'blur' }],
|
||||
contractCode: [{ required: true, message: '请输入合同编号', trigger: 'blur' }],
|
||||
contractStatus: [{ required: true, message: '请选择合同状态', trigger: 'change' }],
|
||||
}
|
||||
|
||||
// 运检站选择变化处理
|
||||
const handleInspectionStationChange = (value) => {
|
||||
if (value) {
|
||||
// 根据选中的 id 找到对应的运检站名称
|
||||
const selectedStation = props.inspectionStationOptions.find((item) => item.id === value)
|
||||
if (selectedStation) {
|
||||
props.formData.inspectionStationName = selectedStation.value
|
||||
}
|
||||
} else {
|
||||
// 清空时也清空名称
|
||||
props.formData.inspectionStationName = ''
|
||||
}
|
||||
}
|
||||
|
||||
// 保存
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
await formRef.value.validate()
|
||||
emit('save')
|
||||
} catch (error) {
|
||||
console.error('表单校验失败:', error)
|
||||
return Promise.reject(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 取消
|
||||
const handleCancel = () => {
|
||||
emit('cancel')
|
||||
}
|
||||
|
||||
// 暴露校验方法和重置方法给父组件
|
||||
defineExpose({
|
||||
validate: () => formRef.value.validate(),
|
||||
resetFields: () => formRef.value.resetFields(),
|
||||
clearValidate: () => formRef.value.clearValidate(),
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.add-and-edit-form {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.common-btn-row {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import { reactive } from 'vue'
|
||||
|
||||
export default {
|
||||
formColumns: [
|
||||
{
|
||||
type: 'input',
|
||||
prop: 'inspectionStationName',
|
||||
placeholder: '请输入运检站名称',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
prop: 'contractName',
|
||||
placeholder: '请输入合同名称',
|
||||
},
|
||||
],
|
||||
tableColumns: [
|
||||
{
|
||||
prop: 'inspectionStationName',
|
||||
label: '运检站',
|
||||
},
|
||||
{
|
||||
prop: 'contractPeriod',
|
||||
label: '合同承揽时间',
|
||||
},
|
||||
{
|
||||
prop: 'contractName',
|
||||
label: '合同名称',
|
||||
},
|
||||
{
|
||||
prop: 'contractCode',
|
||||
label: '合同编号',
|
||||
},
|
||||
{
|
||||
prop: 'contractStatus',
|
||||
label: '合同状态',
|
||||
slot: 'contractStatus', // 使用插槽显示字典值
|
||||
},
|
||||
{
|
||||
prop: 'remark',
|
||||
label: '备注',
|
||||
width: '200',
|
||||
showOverflowTooltip: true,
|
||||
},
|
||||
],
|
||||
|
||||
dialogConfig: reactive({
|
||||
outerVisible: false,
|
||||
outerTitle: '新建合同',
|
||||
outerWidth: '720px',
|
||||
minHeight: '400px',
|
||||
maxHeight: '80vh',
|
||||
}),
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 合同管理 -->
|
||||
<ComTable
|
||||
ref="comTableRef"
|
||||
:form-columns="formColumns"
|
||||
:table-columns="tableColumns"
|
||||
:load-data="listContractAPI"
|
||||
:show-toolbar="true"
|
||||
:show-action="true"
|
||||
:action-columns="actionColumns"
|
||||
>
|
||||
<!-- 工具栏插槽 -->
|
||||
<template #toolbar>
|
||||
<ComButton
|
||||
type="primary"
|
||||
v-hasPermi="['contract:add']"
|
||||
icon="Plus"
|
||||
@click="onHandleAdd"
|
||||
>新建</ComButton
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- 合同状态列插槽 -->
|
||||
<template #contractStatus="{ row }">
|
||||
<dict-tag :options="contract_satus" :value="row.contractStatus" />
|
||||
</template>
|
||||
</ComTable>
|
||||
|
||||
<ComDialog :dialog-config="dialogConfig" @closeDialogOuter="onCloseDialogOuter">
|
||||
<template #outerContent>
|
||||
<AddAndEditForm
|
||||
ref="addAndEditFormRef"
|
||||
:form-data="addAndEditForm"
|
||||
:dict-options="contract_satus"
|
||||
:inspection-station-options="inspectionStationOptions"
|
||||
@save="onHandleSave"
|
||||
@cancel="onHandleCancel"
|
||||
/>
|
||||
</template>
|
||||
</ComDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="contractManage">
|
||||
import { ref, nextTick } from 'vue'
|
||||
import {
|
||||
listContractAPI,
|
||||
addContractAPI,
|
||||
delContractAPI,
|
||||
updateContractAPI,
|
||||
} from '@/api/contractManage/contract'
|
||||
import { getCurrentInstance } from 'vue'
|
||||
import { useOptions } from '@/hooks/useOptions'
|
||||
import { getInspectionStationSelectAPI } from '@/api/common'
|
||||
import config from './config'
|
||||
import ComTable from '@/components/ComTable/index.vue'
|
||||
import ComButton from '@/components/ComButton/index.vue'
|
||||
import ComDialog from '@/components/ComDialog/index.vue'
|
||||
import AddAndEditForm from './components/addAndEditForm.vue'
|
||||
|
||||
const { formColumns, tableColumns, dialogConfig } = config
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const addAndEditFormRef = ref(null)
|
||||
const comTableRef = ref(null)
|
||||
const editId = ref(null)
|
||||
|
||||
// 获取字典数据
|
||||
const { contract_satus } = proxy.useDict('contract_satus')
|
||||
|
||||
// 获取运检站选项
|
||||
const { options: inspectionStationOptions } = useOptions(
|
||||
'inspectionStationOptions',
|
||||
getInspectionStationSelectAPI,
|
||||
{},
|
||||
)
|
||||
|
||||
// 定义初始表单数据函数
|
||||
const getInitFormData = () => ({
|
||||
inspectionStationId: '', // 运检站id
|
||||
inspectionStationName: '', // 运检站名称
|
||||
contractPeriod: '', // 合同承揽时间
|
||||
contractName: '', // 合同名称
|
||||
contractCode: '', // 合同编号
|
||||
contractStatus: '', // 合同状态
|
||||
remark: '', // 备注
|
||||
})
|
||||
|
||||
const addAndEditForm = ref(getInitFormData())
|
||||
|
||||
const actionColumns = [
|
||||
{
|
||||
label: '编辑',
|
||||
type: 'primary',
|
||||
link: true,
|
||||
permission: ['contract:edit'],
|
||||
handler: (row) => {
|
||||
const {
|
||||
contractId,
|
||||
inspectionStationId,
|
||||
inspectionStationName,
|
||||
contractPeriod,
|
||||
contractName,
|
||||
contractCode,
|
||||
contractStatus,
|
||||
remark,
|
||||
} = row
|
||||
editId.value = contractId
|
||||
dialogConfig.outerTitle = '编辑合同'
|
||||
dialogConfig.outerVisible = true
|
||||
// 使用 nextTick 确保在弹框渲染、表单组件挂载后再赋值
|
||||
nextTick(() => {
|
||||
addAndEditForm.value.inspectionStationId = inspectionStationId + '' || ''
|
||||
addAndEditForm.value.inspectionStationName = inspectionStationName || ''
|
||||
addAndEditForm.value.contractPeriod = contractPeriod || ''
|
||||
addAndEditForm.value.contractName = contractName || ''
|
||||
addAndEditForm.value.contractCode = contractCode || ''
|
||||
addAndEditForm.value.contractStatus = contractStatus || ''
|
||||
addAndEditForm.value.remark = remark || ''
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
type: 'danger',
|
||||
link: true,
|
||||
permission: ['contract:remove'],
|
||||
handler: (row) => {
|
||||
proxy.$modal.confirm('是否确认删除该合同?').then(async () => {
|
||||
const result = await delContractAPI({
|
||||
contractId: row.contractId,
|
||||
})
|
||||
if (result.code === 200) {
|
||||
proxy.$modal.msgSuccess('删除成功')
|
||||
comTableRef.value?.refresh() // 刷新表格
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
// 新增
|
||||
const onHandleAdd = () => {
|
||||
editId.value = null
|
||||
dialogConfig.outerTitle = '新建合同'
|
||||
dialogConfig.outerVisible = true
|
||||
// 重置表单数据
|
||||
addAndEditForm.value = getInitFormData()
|
||||
// 清除之前的校验信息
|
||||
nextTick(() => {
|
||||
addAndEditFormRef.value?.clearValidate()
|
||||
})
|
||||
}
|
||||
|
||||
// 取消
|
||||
const onHandleCancel = () => {
|
||||
addAndEditFormRef.value?.resetFields() // 重置表单
|
||||
dialogConfig.outerVisible = false
|
||||
}
|
||||
|
||||
// 保存
|
||||
const onHandleSave = async () => {
|
||||
try {
|
||||
await addAndEditFormRef.value.validate()
|
||||
const API = editId.value ? updateContractAPI : addContractAPI
|
||||
const params = JSON.parse(JSON.stringify(addAndEditForm.value))
|
||||
editId.value ? (params.contractId = editId.value) : null
|
||||
|
||||
const result = await API(params)
|
||||
if (result.code === 200) {
|
||||
proxy.$modal.msgSuccess(editId.value ? '编辑成功' : '新增成功')
|
||||
addAndEditFormRef.value.resetFields() // 重置表单
|
||||
dialogConfig.outerVisible = false
|
||||
comTableRef.value?.refresh() // 刷新表格
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('表单校验失败或请求错误:', error)
|
||||
// 必须抛出错误或返回 Promise.reject(),ComButton 才能捕获并结束 loading 状态
|
||||
return Promise.reject(error)
|
||||
}
|
||||
}
|
||||
|
||||
const onCloseDialogOuter = (visible) => {
|
||||
dialogConfig.outerVisible = visible
|
||||
if (!visible) {
|
||||
addAndEditFormRef.value?.resetFields()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
<template>
|
||||
<ComDialog :dialog-config="dialogConfig" @closeDialogOuter="onCloseDialogOuter">
|
||||
<template #outerContent>
|
||||
<div class="plan-select-dialog">
|
||||
<!-- 搜索栏 -->
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" class="search-form">
|
||||
<el-form-item label="综合查询:">
|
||||
<el-input
|
||||
v-model="queryParams.keyWord"
|
||||
placeholder="输入内容"
|
||||
clearable
|
||||
style="width: 300px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery"
|
||||
>查询</el-button
|
||||
>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
v-loading="loading"
|
||||
:data="planList"
|
||||
@selection-change="handleSelectionChange"
|
||||
border
|
||||
height="400px"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column prop="inspectionStationName" label="运检站" align="center" />
|
||||
<el-table-column
|
||||
prop="projectName"
|
||||
label="项目名称"
|
||||
align="center"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="workContent"
|
||||
label="工作任务"
|
||||
align="center"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row class="common-btn-row">
|
||||
<ComButton plain type="info" @click="handleCancel">取消</ComButton>
|
||||
<ComButton type="primary" @click="handleConfirm">确定</ComButton>
|
||||
</el-row>
|
||||
</template>
|
||||
</ComDialog>
|
||||
</template>
|
||||
|
||||
<script setup name="PlanSelectDialog">
|
||||
import { ref, reactive, watch, nextTick } from 'vue'
|
||||
import { getPlanListForSelectAPI } from '@/api/settlementManage/settlement'
|
||||
import ComDialog from '@/components/ComDialog/index.vue'
|
||||
import ComButton from '@/components/ComButton/index.vue'
|
||||
|
||||
const props = defineProps({
|
||||
dialogConfig: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
selectedPlanIds: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['confirm', 'close'])
|
||||
|
||||
const queryRef = ref(null)
|
||||
const tableRef = ref(null)
|
||||
const loading = ref(false)
|
||||
const planList = ref([])
|
||||
const selectedPlans = ref([])
|
||||
|
||||
const queryParams = reactive({
|
||||
keyWord: '',
|
||||
})
|
||||
|
||||
// 监听弹框打开,重置数据
|
||||
watch(
|
||||
() => props.dialogConfig.outerVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
queryParams.keyWord = ''
|
||||
selectedPlans.value = []
|
||||
// 清除表格选中状态
|
||||
if (tableRef.value) {
|
||||
tableRef.value.clearSelection()
|
||||
}
|
||||
getList()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 查询列表
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const response = await getPlanListForSelectAPI(queryParams)
|
||||
if (response.code === 200) {
|
||||
planList.value = response?.data || []
|
||||
// 数据加载完成后,设置已选中的项
|
||||
nextTick(() => {
|
||||
setSelectedRows()
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取计划列表失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 设置已选中的行(用于编辑时回显)
|
||||
const setSelectedRows = () => {
|
||||
if (!tableRef.value || !props.selectedPlanIds || props.selectedPlanIds.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
planList.value.forEach((row) => {
|
||||
// 根据monthPlanId或planId匹配
|
||||
const isSelected = props.selectedPlanIds.some((id) => id === row.monthlyPlanId)
|
||||
if (isSelected) {
|
||||
tableRef.value.toggleRowSelection(row, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleQuery = () => {
|
||||
getList()
|
||||
}
|
||||
|
||||
// 重置
|
||||
const resetQuery = () => {
|
||||
queryParams.keyWord = ''
|
||||
selectedPlans.value = []
|
||||
// 清除表格选中状态
|
||||
if (tableRef.value) {
|
||||
tableRef.value.clearSelection()
|
||||
}
|
||||
getList()
|
||||
}
|
||||
|
||||
// 选择变化
|
||||
const handleSelectionChange = (selection) => {
|
||||
selectedPlans.value = selection
|
||||
}
|
||||
|
||||
// 确定
|
||||
const handleConfirm = () => {
|
||||
emit('confirm', selectedPlans.value)
|
||||
props.dialogConfig.outerVisible = false
|
||||
}
|
||||
|
||||
// 取消
|
||||
const handleCancel = () => {
|
||||
emit('close')
|
||||
props.dialogConfig.outerVisible = false
|
||||
}
|
||||
|
||||
// 关闭弹框
|
||||
const onCloseDialogOuter = (visible) => {
|
||||
props.dialogConfig.outerVisible = visible
|
||||
if (!visible) {
|
||||
resetQuery()
|
||||
}
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
getList,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.plan-select-dialog {
|
||||
.search-form {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.common-btn-row {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
import { reactive } from 'vue'
|
||||
|
||||
export default {
|
||||
formColumns: [
|
||||
{
|
||||
type: 'select',
|
||||
prop: 'contractId',
|
||||
placeholder: '请输入所属合同',
|
||||
options: [], // 动态从字典获取
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
prop: 'contractCode',
|
||||
placeholder: '请输入合同编号',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
prop: 'projectSettlementName',
|
||||
placeholder: '请输入项目结算名称',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
prop: 'settlementStatus',
|
||||
placeholder: '请选择合同或项目状态',
|
||||
options: [], // 动态从字典获取
|
||||
},
|
||||
],
|
||||
tableColumns: [
|
||||
{
|
||||
prop: 'inspectionStationName',
|
||||
label: '运检站',
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'contractCode',
|
||||
label: '合同编号',
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'contractName',
|
||||
label: '所属合同',
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'projectSettlementName',
|
||||
label: '项目结算名称',
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'planCount',
|
||||
label: '执行计划数量',
|
||||
formatter: (row) => {
|
||||
return row.executionPlanList.length || ''
|
||||
},
|
||||
},
|
||||
{
|
||||
prop: 'estimatedAmount',
|
||||
label: '合同预估金额(万元)',
|
||||
width: '140',
|
||||
formatter: (row) => {
|
||||
return row.estimatedAmount ? (row.estimatedAmount / 10000 / 100).toFixed(2) : '0.00'
|
||||
},
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'contractStatus',
|
||||
label: '合同或项目状态',
|
||||
slot: 'contractStatus', // 使用插槽显示字典值
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'settlementBatch',
|
||||
label: '结算批次',
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'settlementPayment',
|
||||
label: '结算款-价',
|
||||
formatter: (row) => {
|
||||
// 金额从分转换为元,保留2位小数
|
||||
return row.settlementPayment ? (row.settlementPayment / 100).toFixed(2) : '0.00'
|
||||
},
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'settlementTax',
|
||||
label: '结算款-税',
|
||||
formatter: (row) => {
|
||||
return row.settlementTax ? (row.settlementTax / 100).toFixed(2) : '0.00'
|
||||
},
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'approvedSettlement',
|
||||
label: '审定结算-价',
|
||||
formatter: (row) => {
|
||||
return row.approvedSettlement ? (row.approvedSettlement / 100).toFixed(2) : '0.00'
|
||||
},
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'approvedSettlementTax',
|
||||
label: '审定结算-税',
|
||||
formatter: (row) => {
|
||||
return row.approvedSettlementTax ? (row.approvedSettlementTax / 100).toFixed(2) : '0.00'
|
||||
},
|
||||
width: '140',
|
||||
},
|
||||
{
|
||||
prop: 'settlementDataNumber',
|
||||
label: '结算资料编号',
|
||||
width: '140',
|
||||
},
|
||||
],
|
||||
|
||||
dialogConfig: reactive({
|
||||
outerVisible: false,
|
||||
outerTitle: '新建结算',
|
||||
outerWidth: '720px',
|
||||
minHeight: '400px',
|
||||
maxHeight: '80vh',
|
||||
}),
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,185 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 结算管理 -->
|
||||
<ComTable
|
||||
ref="comTableRef"
|
||||
:form-columns="formColumns"
|
||||
:table-columns="tableColumns"
|
||||
:load-data="listSettlementAPI"
|
||||
:show-toolbar="true"
|
||||
:show-action="true"
|
||||
:action-columns="actionColumns"
|
||||
>
|
||||
<!-- 工具栏插槽 -->
|
||||
<template #toolbar>
|
||||
<ComButton
|
||||
type="primary"
|
||||
v-hasPermi="['settlement:add']"
|
||||
icon="Plus"
|
||||
@click="onHandleAdd"
|
||||
>新建</ComButton
|
||||
>
|
||||
<ComButton
|
||||
plain
|
||||
type="info"
|
||||
icon="Download"
|
||||
@click="onDownloadStatistic"
|
||||
v-hasPermi="['settlement:download']"
|
||||
>下载统计表</ComButton
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- 合同状态列插槽 -->
|
||||
<template #contractStatus="{ row }">
|
||||
<dict-tag :options="contract_satus" :value="row.settlementStatus" />
|
||||
</template>
|
||||
</ComTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="settlementManage">
|
||||
import { ref, computed, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import {
|
||||
listSettlementAPI,
|
||||
delSettlementAPI,
|
||||
downloadSettlementStatisticAPI,
|
||||
getContractSelectAPI,
|
||||
} from '@/api/settlementManage/settlement'
|
||||
import { download } from '@/utils/request'
|
||||
import config from './config'
|
||||
import ComTable from '@/components/ComTable/index.vue'
|
||||
import ComButton from '@/components/ComButton/index.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const comTableRef = ref(null)
|
||||
const contractList = ref([])
|
||||
|
||||
// 获取字典数据
|
||||
const { contract_satus } = proxy.useDict('contract_satus')
|
||||
|
||||
// 动态构建搜索表单配置,添加字典选项
|
||||
const formColumns = computed(() => {
|
||||
return config.formColumns.map((column) => {
|
||||
if (column.prop === 'settlementStatus') {
|
||||
return {
|
||||
...column,
|
||||
options: contract_satus.value || [],
|
||||
}
|
||||
}
|
||||
|
||||
if (column.prop === 'contractId') {
|
||||
return {
|
||||
...column,
|
||||
options: contractList.value || [],
|
||||
}
|
||||
}
|
||||
return column
|
||||
})
|
||||
})
|
||||
|
||||
const { tableColumns } = config
|
||||
|
||||
const actionColumns = [
|
||||
{
|
||||
label: '详情',
|
||||
type: 'primary',
|
||||
link: true,
|
||||
permission: ['settlement:detail'],
|
||||
handler: (row) => {
|
||||
router.push({
|
||||
path: '/settlement/settlementEdit/index',
|
||||
query: {
|
||||
id: row.settlementId,
|
||||
mode: 'detail',
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
type: 'primary',
|
||||
link: true,
|
||||
permission: ['settlement:edit'],
|
||||
handler: (row) => {
|
||||
router.push({
|
||||
path: '/settlement/settlementEdit/index',
|
||||
query: {
|
||||
id: row.settlementId,
|
||||
mode: 'edit',
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
type: 'danger',
|
||||
link: true,
|
||||
permission: ['settlement:remove'],
|
||||
handler: (row) => {
|
||||
proxy.$modal.confirm('是否确认删除该结算?').then(async () => {
|
||||
const result = await delSettlementAPI({
|
||||
settlementId: row.settlementId,
|
||||
})
|
||||
if (result.code === 200) {
|
||||
proxy.$modal.msgSuccess('删除成功')
|
||||
comTableRef.value?.refresh() // 刷新表格
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
// 新增
|
||||
const onHandleAdd = () => {
|
||||
router.push({
|
||||
path: '/settlement/settlementEdit/index',
|
||||
query: {
|
||||
mode: 'add',
|
||||
contractId: null,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 下载统计表
|
||||
const onDownloadStatistic = async () => {
|
||||
try {
|
||||
const formData = comTableRef.value?.getFormData() || {}
|
||||
const response = await downloadSettlementStatisticAPI(formData)
|
||||
// 创建下载链接
|
||||
const blob = new Blob([response], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
})
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = `结算统计表_${new Date().getTime()}.xlsx`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
proxy.$modal.msgSuccess('下载成功')
|
||||
} catch (error) {
|
||||
console.error('下载失败:', error)
|
||||
proxy.$modal.msgError('下载失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 获取合同列表
|
||||
const getContractList = async () => {
|
||||
const response = await getContractSelectAPI({})
|
||||
if (response.code === 200) {
|
||||
contractList.value = response.rows.map((item) => ({
|
||||
label: item.contractName,
|
||||
value: item.contractId,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getContractList()
|
||||
})
|
||||
</script>
|
||||
|
||||
Loading…
Reference in New Issue