Browse Source
feat(inspection): 新增费用明细和附件管理功能
feat(inspection): 新增费用明细和附件管理功能
- 实现费用明细表格展示、新增、编辑、删除功能 - 集成字典选择器用于费用类型选择 - 添加附件上传、下载、删除管理功能 - 实现申请单关联费用功能 - 新增待验货申请列表页面 - 添加多个页签组件用于展示不同业务信息master
10 changed files with 1387 additions and 358 deletions
-
66src/api/inspection/srmFee.js
-
266src/views/modules/inspection/com_feeDetailTab.vue
-
2src/views/modules/inspection/com_inspectionRequestAttachmentTab.vue
-
91src/views/modules/inspection/com_inspectionRequestFeeTab.vue
-
244src/views/modules/inspection/com_requestFeeTab.vue
-
128src/views/modules/inspection/inspectionPendingList.vue
-
118src/views/modules/inspection/inspectionRequestAudit.vue
-
160src/views/modules/inspection/inspectionRequestList.vue
-
142src/views/modules/inspection/inspectionScheduleList.vue
-
518src/views/modules/inspection/srmFeeList.vue
@ -0,0 +1,66 @@ |
|||||
|
import { createAPI } from '@/utils/httpRequest.js' |
||||
|
|
||||
|
/** |
||||
|
* 分页查询费用主记录列表 |
||||
|
*/ |
||||
|
export const searchFeeHeaderList = (data) => createAPI(`/inspection/fee/searchFeeHeaderList`, 'post', data) |
||||
|
|
||||
|
/** |
||||
|
* 根据费用单号查询主记录 |
||||
|
*/ |
||||
|
export const getFeeHeaderByNo = (params) => createAPI(`/inspection/fee/getFeeHeaderByNo`, 'post', params) |
||||
|
|
||||
|
/** |
||||
|
* 创建费用主记录 |
||||
|
*/ |
||||
|
export const createFeeHeader = (data) => createAPI(`/inspection/fee/createFeeHeader`, 'post', data) |
||||
|
|
||||
|
/** |
||||
|
* 更新费用主记录 |
||||
|
*/ |
||||
|
export const updateFeeHeader = (data) => createAPI(`/inspection/fee/updateFeeHeader`, 'post', data) |
||||
|
|
||||
|
/** |
||||
|
* 删除费用记录 |
||||
|
*/ |
||||
|
export const deleteFeeRecord = (params) => createAPI(`/inspection/fee/deleteFeeRecord`, 'post', params) |
||||
|
|
||||
|
/** |
||||
|
* 查询费用明细列表 |
||||
|
*/ |
||||
|
export const getFeeDetailList = (params) => createAPI(`/inspection/fee/getFeeDetailList`, 'post', params) |
||||
|
|
||||
|
/** |
||||
|
* 添加费用明细(单条) |
||||
|
*/ |
||||
|
export const addFeeDetail = (data) => createAPI(`/inspection/fee/addFeeDetail`, 'post', data) |
||||
|
|
||||
|
/** |
||||
|
* 更新费用明细 |
||||
|
*/ |
||||
|
export const updateFeeDetail = (data) => createAPI(`/inspection/fee/updateFeeDetail`, 'post', data) |
||||
|
|
||||
|
/** |
||||
|
* 删除费用明细 |
||||
|
*/ |
||||
|
export const deleteFeeDetail = (params) => createAPI(`/inspection/fee/deleteFeeDetail`, 'post', params) |
||||
|
|
||||
|
/** |
||||
|
* 查询关联的申请单列表 |
||||
|
*/ |
||||
|
export const getRequestFeeList = (params) => createAPI(`/inspection/fee/getRequestFeeList`, 'post', params) |
||||
|
|
||||
|
/** |
||||
|
* 添加关联申请单(批量) |
||||
|
*/ |
||||
|
export const addRequestFees = (data) => createAPI(`/inspection/fee/addRequestFees`, 'post', data) |
||||
|
|
||||
|
/** |
||||
|
* 删除关联申请单 |
||||
|
*/ |
||||
|
export const deleteRequestFee = (params) => createAPI(`/inspection/fee/deleteRequestFee`, 'post', params) |
||||
|
|
||||
|
/** |
||||
|
* 根据申请单号查询费用明细 |
||||
|
*/ |
||||
|
export const getFeeDetailByRequestNo = (data) => createAPI(`/inspection/fee/getFeeDetailByRequestNo`, 'post', data) |
||||
@ -0,0 +1,266 @@ |
|||||
|
<template> |
||||
|
<div class="fee-detail-tab"> |
||||
|
<div style="margin-bottom: 5px;"> |
||||
|
<el-button type="primary" size="small" @click="handleAdd">新增明细</el-button> |
||||
|
</div> |
||||
|
|
||||
|
<el-table |
||||
|
:data="detailList" |
||||
|
border |
||||
|
:height="tableHeight" |
||||
|
v-loading="loading" |
||||
|
style="width: 100%;"> |
||||
|
<el-table-column type="index" label="行号" header-align="center" align="center" width="60"/> |
||||
|
<el-table-column prop="feeType" label="费用类型" header-align="center" align="left" min-width="150"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span>{{ scope.row.feeType }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="amount" label="金额" header-align="center" align="right" width="120"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span>{{ scope.row.amount ? scope.row.amount.toFixed(2) : '0.00' }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="remark" label="备注" header-align="center" align="left" min-width="200"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span>{{ scope.row.remark }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="操作" header-align="center" align="center" width="150" fixed="right"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-link type="primary" @click="handleEdit(scope.row)" style="margin-right: 10px;">编辑</el-link> |
||||
|
<el-link type="danger" @click="handleDelete(scope.row)">删除</el-link> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
|
||||
|
<!-- 新增/编辑弹窗 --> |
||||
|
<el-dialog |
||||
|
:title="dialogTitle" |
||||
|
:visible.sync="dialogVisible" |
||||
|
width="500px" |
||||
|
custom-class="custom-dialog" |
||||
|
:close-on-click-modal="false"> |
||||
|
<el-form :model="formData" :rules="formRules" ref="formRef" label-position="top"> |
||||
|
<el-form-item label="费用类型" prop="feeType"> |
||||
|
<sys-dict-select |
||||
|
v-model="formData.feeType" |
||||
|
dict-type="fee_type" |
||||
|
placeholder="请选择费用类型" |
||||
|
width="50%" |
||||
|
filterable |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="金额" prop="amount"> |
||||
|
<el-input-number |
||||
|
v-model="formData.amount" |
||||
|
:min="0" |
||||
|
:precision="2" |
||||
|
style="width: 50%"> |
||||
|
</el-input-number> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="备注" prop="remark"> |
||||
|
<el-input |
||||
|
v-model="formData.remark" |
||||
|
type="textarea" |
||||
|
:rows="3" |
||||
|
placeholder="请输入备注"> |
||||
|
</el-input> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<span slot="footer" class="dialog-footer"> |
||||
|
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button> |
||||
|
<el-button @click="dialogVisible = false">取消</el-button> |
||||
|
</span> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { getFeeDetailList, addFeeDetail, updateFeeDetail, deleteFeeDetail } from '@/api/inspection/srmFee.js' |
||||
|
import SysDictSelect from '@/components/dict/SysDictSelect.vue' |
||||
|
|
||||
|
export default { |
||||
|
name: 'FeeDetailTab', |
||||
|
components: { |
||||
|
SysDictSelect |
||||
|
}, |
||||
|
props: { |
||||
|
feeData: { |
||||
|
type: Object, |
||||
|
default: () => ({}) |
||||
|
}, |
||||
|
tableHeight: { |
||||
|
type: Number, |
||||
|
default: 400 |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
detailList: [], |
||||
|
loading: false, |
||||
|
dialogVisible: false, |
||||
|
dialogTitle: '新增明细', |
||||
|
submitLoading: false, |
||||
|
formData: { |
||||
|
feeType: '', |
||||
|
amount: 0, |
||||
|
remark: '' |
||||
|
}, |
||||
|
formRules: { |
||||
|
feeType: [ |
||||
|
{ required: true, message: '请输入费用类型', trigger: 'blur' } |
||||
|
], |
||||
|
amount: [ |
||||
|
{ required: true, message: '请输入金额', trigger: 'blur' } |
||||
|
] |
||||
|
}, |
||||
|
currentEditRow: null |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
'feeData.feeNo': { |
||||
|
handler(newVal) { |
||||
|
if (newVal) { |
||||
|
this.loadDetailList() |
||||
|
} |
||||
|
}, |
||||
|
immediate: true |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 加载明细列表 |
||||
|
loadDetailList() { |
||||
|
if (!this.feeData.feeNo || !this.feeData.site) { |
||||
|
this.detailList = [] |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
this.loading = true |
||||
|
const params = { |
||||
|
site: this.feeData.site, |
||||
|
feeNo: this.feeData.feeNo |
||||
|
} |
||||
|
|
||||
|
getFeeDetailList(params).then(({ data }) => { |
||||
|
if (data.code === 0 && data.details) { |
||||
|
this.detailList = data.details |
||||
|
} else { |
||||
|
this.detailList = [] |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.detailList = [] |
||||
|
}).finally(() => { |
||||
|
this.loading = false |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 新增明细 |
||||
|
handleAdd() { |
||||
|
this.dialogTitle = '新增明细' |
||||
|
this.formData = { |
||||
|
feeType: '', |
||||
|
amount: 0, |
||||
|
remark: '' |
||||
|
} |
||||
|
this.currentEditRow = null |
||||
|
this.dialogVisible = true |
||||
|
this.$nextTick(() => { |
||||
|
if (this.$refs.formRef) { |
||||
|
this.$refs.formRef.clearValidate() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 编辑 |
||||
|
handleEdit(row) { |
||||
|
this.dialogTitle = '编辑明细' |
||||
|
this.formData = { |
||||
|
feeType: row.feeType, |
||||
|
amount: row.amount, |
||||
|
remark: row.remark |
||||
|
} |
||||
|
this.currentEditRow = row |
||||
|
this.dialogVisible = true |
||||
|
this.$nextTick(() => { |
||||
|
if (this.$refs.formRef) { |
||||
|
this.$refs.formRef.clearValidate() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 提交表单 |
||||
|
handleSubmit() { |
||||
|
this.$refs.formRef.validate((valid) => { |
||||
|
if (!valid) { |
||||
|
return false |
||||
|
} |
||||
|
this.submitLoading = true |
||||
|
const params = { |
||||
|
site: this.feeData.site, |
||||
|
feeNo: this.feeData.feeNo, |
||||
|
feeType: this.formData.feeType, |
||||
|
amount: this.formData.amount || 0, |
||||
|
remark: this.formData.remark || '', |
||||
|
createBy: this.$store.state.user.name, |
||||
|
updateBy: this.$store.state.user.name |
||||
|
} |
||||
|
// 编辑时传 itemNo |
||||
|
if (this.currentEditRow) { |
||||
|
params.itemNo = this.currentEditRow.itemNo |
||||
|
} |
||||
|
const apiCall = this.currentEditRow |
||||
|
? updateFeeDetail(params) |
||||
|
: addFeeDetail(params) |
||||
|
apiCall.then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.$message.success('保存成功') |
||||
|
this.dialogVisible = false |
||||
|
this.loadDetailList() |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '保存失败') |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.$message.error('保存失败') |
||||
|
}).finally(() => { |
||||
|
this.submitLoading = false |
||||
|
}) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 删除 |
||||
|
handleDelete(row) { |
||||
|
this.$confirm('确定要删除该明细吗?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
const params = { |
||||
|
site: this.$store.state.user.site, |
||||
|
feeNo: row.feeNo, |
||||
|
itemNo: row.itemNo |
||||
|
} |
||||
|
|
||||
|
deleteFeeDetail(params).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.$message.success('删除成功') |
||||
|
this.loadDetailList() |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '删除失败') |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.$message.error('删除失败') |
||||
|
}) |
||||
|
}).catch(() => {}) |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.custom-dialog .el-dialog__body { |
||||
|
min-height: 200px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,91 @@ |
|||||
|
<template> |
||||
|
<div class="fee-request-tab"> |
||||
|
<el-table |
||||
|
:data="feeDetailList" |
||||
|
border |
||||
|
:height="tableHeight" |
||||
|
v-loading="loading" |
||||
|
style="width: 100%;"> |
||||
|
<el-table-column type="index" label="行号" header-align="center" align="center" width="60"/> |
||||
|
<el-table-column prop="feeNo" label="费用单号" header-align="center" align="left" min-width="120"/> |
||||
|
<el-table-column prop="feeType" label="费用类型" header-align="center" align="left" min-width="120"/> |
||||
|
<el-table-column prop="amount" label="金额" header-align="center" align="right" width="120"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span>{{ scope.row.amount ? scope.row.amount.toFixed(2) : '0.00' }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="remark" label="备注" header-align="center" align="left" min-width="200"/> |
||||
|
<el-table-column prop="createBy" label="创建人" header-align="center" align="center" width="100"/> |
||||
|
<el-table-column prop="createDate" label="创建时间" header-align="center" align="center" width="160"/> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { getFeeDetailByRequestNo } from '@/api/inspection/srmFee.js' |
||||
|
|
||||
|
export default { |
||||
|
name: 'InspectionRequestFeeTab', |
||||
|
props: { |
||||
|
detailData: { |
||||
|
type: Object, |
||||
|
default: () => ({}) |
||||
|
}, |
||||
|
tableHeight: { |
||||
|
type: Number, |
||||
|
default: 400 |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
feeDetailList: [], |
||||
|
loading: false |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
'detailData.requestNo': { |
||||
|
handler(newVal) { |
||||
|
if (newVal) { |
||||
|
this.loadFeeDetailList() |
||||
|
} else { |
||||
|
this.feeDetailList = [] |
||||
|
} |
||||
|
}, |
||||
|
immediate: true |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
loadFeeDetailList() { |
||||
|
if (!this.detailData.requestNo || !this.detailData.site) { |
||||
|
this.feeDetailList = [] |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
this.loading = true |
||||
|
const params = { |
||||
|
site: this.detailData.site, |
||||
|
requestNo: this.detailData.requestNo, |
||||
|
feeNo: '' |
||||
|
} |
||||
|
|
||||
|
getFeeDetailByRequestNo(params).then(({ data }) => { |
||||
|
if (data.code === 0 && data.details) { |
||||
|
this.feeDetailList = data.details |
||||
|
} else { |
||||
|
this.feeDetailList = [] |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.feeDetailList = [] |
||||
|
}).finally(() => { |
||||
|
this.loading = false |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.fee-request-tab { |
||||
|
padding: 0px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,244 @@ |
|||||
|
<template> |
||||
|
<div class="request-fee-tab"> |
||||
|
<div style="margin-bottom: 2px;"> |
||||
|
<el-button type="primary" size="small" @click="handleAddRequest">添加申请单</el-button> |
||||
|
</div> |
||||
|
|
||||
|
<el-table |
||||
|
:data="requestFeeList" |
||||
|
border |
||||
|
:height="tableHeight" |
||||
|
v-loading="loading" |
||||
|
style="width: 100%;"> |
||||
|
<el-table-column type="index" label="序号" header-align="center" align="center" width="60"/> |
||||
|
<el-table-column prop="requestNo" label="申请单号" header-align="center" align="left" min-width="150"/> |
||||
|
<el-table-column prop="createBy" label="关联人" header-align="center" align="left" width="120"/> |
||||
|
<el-table-column prop="createDate" label="关联时间" header-align="center" align="center" width="160"> |
||||
|
<template slot-scope="scope"> |
||||
|
{{ scope.row.createDate | formatDate }} |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="操作" header-align="center" align="center" width="100" fixed="right"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-link type="danger" @click="handleDelete(scope.row)">删除</el-link> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
|
||||
|
<!-- 选择申请单弹窗 --> |
||||
|
<el-dialog |
||||
|
title="选择申请单" |
||||
|
:visible.sync="selectDialogVisible" |
||||
|
width="70%" |
||||
|
top="5vh"> |
||||
|
<el-form :inline="true" size="small"> |
||||
|
<el-form-item label="申请单号"> |
||||
|
<el-input v-model="searchRequestNo" placeholder="请输入申请单号" clearable></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" @click="searchRequests">查询</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
|
||||
|
<el-table |
||||
|
:data="availableRequests" |
||||
|
border |
||||
|
height="300" |
||||
|
@selection-change="handleSelectionChange" |
||||
|
v-loading="requestLoading"> |
||||
|
<el-table-column type="selection" width="55" align="center"/> |
||||
|
<el-table-column prop="requestNo" label="申请单号" header-align="center" align="left" min-width="150"/> |
||||
|
<el-table-column prop="supplierName" label="供应商名称" header-align="center" align="left" min-width="200"/> |
||||
|
<el-table-column prop="status" label="状态" header-align="center" align="center" width="100"/> |
||||
|
</el-table> |
||||
|
|
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="primary" @click="confirmAddRequests">确定</el-button> |
||||
|
<el-button @click="selectDialogVisible = false">取消</el-button> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { getRequestFeeList, addRequestFees, deleteRequestFee } from '@/api/inspection/srmFee.js' |
||||
|
import { searchInspectionRequestHeaderList } from '@/api/inspection/inspectionRequestHeader.js' |
||||
|
|
||||
|
export default { |
||||
|
name: 'RequestFeeTab', |
||||
|
props: { |
||||
|
feeData: { |
||||
|
type: Object, |
||||
|
default: () => ({}) |
||||
|
}, |
||||
|
tableHeight: { |
||||
|
type: Number, |
||||
|
default: 400 |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
requestFeeList: [], |
||||
|
loading: false, |
||||
|
selectDialogVisible: false, |
||||
|
availableRequests: [], |
||||
|
requestLoading: false, |
||||
|
selectedRequests: [], |
||||
|
searchRequestNo: '' |
||||
|
} |
||||
|
}, |
||||
|
filters: { |
||||
|
formatDate(value) { |
||||
|
if (!value) return '' |
||||
|
const date = new Date(value) |
||||
|
const year = date.getFullYear() |
||||
|
const month = String(date.getMonth() + 1).padStart(2, '0') |
||||
|
const day = String(date.getDate()).padStart(2, '0') |
||||
|
const hour = String(date.getHours()).padStart(2, '0') |
||||
|
const minute = String(date.getMinutes()).padStart(2, '0') |
||||
|
const second = String(date.getSeconds()).padStart(2, '0') |
||||
|
return `${year}-${month}-${day} ${hour}:${minute}:${second}` |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
'feeData.feeNo': { |
||||
|
handler(newVal) { |
||||
|
if (newVal) { |
||||
|
this.loadRequestFeeList() |
||||
|
} |
||||
|
}, |
||||
|
immediate: true |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 加载关联申请单列表 |
||||
|
loadRequestFeeList() { |
||||
|
if (!this.feeData.feeNo || !this.feeData.site) { |
||||
|
this.requestFeeList = [] |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
this.loading = true |
||||
|
const params = { |
||||
|
site: this.feeData.site, |
||||
|
feeNo: this.feeData.feeNo |
||||
|
} |
||||
|
|
||||
|
getRequestFeeList(params).then(({ data }) => { |
||||
|
if (data.code === 0 && data.requestFees) { |
||||
|
this.requestFeeList = data.requestFees |
||||
|
} else { |
||||
|
this.requestFeeList = [] |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.requestFeeList = [] |
||||
|
}).finally(() => { |
||||
|
this.loading = false |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 打开选择申请单弹窗 |
||||
|
handleAddRequest() { |
||||
|
this.selectDialogVisible = true |
||||
|
this.searchRequests() |
||||
|
}, |
||||
|
|
||||
|
// 查询可申请单 |
||||
|
searchRequests() { |
||||
|
this.requestLoading = true |
||||
|
|
||||
|
const params = { |
||||
|
page: 1, |
||||
|
limit: 100, |
||||
|
site: this.$store.state.user.site |
||||
|
} |
||||
|
|
||||
|
if (this.searchRequestNo) { |
||||
|
params.requestNo = this.searchRequestNo |
||||
|
} |
||||
|
|
||||
|
searchInspectionRequestHeaderList(params).then(({ data }) => { |
||||
|
if (data.code === 0 && data.page) { |
||||
|
// 过滤掉已经关联的申请单 |
||||
|
const existingRequestNos = this.requestFeeList.map(item => item.requestNo) |
||||
|
this.availableRequests = data.page.list.filter(item => !existingRequestNos.includes(item.requestNo)) |
||||
|
} else { |
||||
|
this.availableRequests = [] |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.availableRequests = [] |
||||
|
}).finally(() => { |
||||
|
this.requestLoading = false |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 选择变化 |
||||
|
handleSelectionChange(selection) { |
||||
|
this.selectedRequests = selection |
||||
|
}, |
||||
|
|
||||
|
// 确认添加 |
||||
|
confirmAddRequests() { |
||||
|
if (this.selectedRequests.length === 0) { |
||||
|
this.$message.warning('请至少选择一个申请单') |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
const requestNos = this.selectedRequests.map(item => item.requestNo) |
||||
|
|
||||
|
const params = { |
||||
|
site: this.feeData.site, |
||||
|
feeNo: this.feeData.feeNo, |
||||
|
currentUser: this.$store.state.user.name, |
||||
|
requestNos: requestNos |
||||
|
} |
||||
|
|
||||
|
addRequestFees(params).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.$message.success('添加成功') |
||||
|
this.selectDialogVisible = false |
||||
|
this.loadRequestFeeList() |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '添加失败') |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.$message.error('添加失败') |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 删除关联 |
||||
|
handleDelete(row) { |
||||
|
this.$confirm('确定要删除该关联吗?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
const params = { |
||||
|
site: row.site, |
||||
|
feeNo: row.feeNo, |
||||
|
requestNo: row.requestNo |
||||
|
} |
||||
|
|
||||
|
deleteRequestFee(params).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.$message.success('删除成功') |
||||
|
this.loadRequestFeeList() |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '删除失败') |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.$message.error('删除失败') |
||||
|
}) |
||||
|
}).catch(() => {}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.request-fee-tab { |
||||
|
padding-top: 0; |
||||
|
padding-left: 0; |
||||
|
|
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,518 @@ |
|||||
|
<template> |
||||
|
<div class="customer-css"> |
||||
|
<!-- 查询条件 --> |
||||
|
<el-form :inline="true" label-position="top" class="search-form-inline"> |
||||
|
<div class="search-row"> |
||||
|
<el-form-item label="费用单号" class="search-item"> |
||||
|
<el-input v-model="searchData.feeNo" style="width: 120px" @keyup.enter.native="getMainData"/> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="申请人" class="search-item" > |
||||
|
<el-input v-model="searchData.applyUser" style="width: 120px" @keyup.enter.native="getMainData"/> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="费用日期" class="search-item"> |
||||
|
<el-date-picker |
||||
|
v-model="searchData.feeDate" |
||||
|
type="date" |
||||
|
value-format="yyyy-MM-dd" |
||||
|
placeholder="选择日期" |
||||
|
style="width: 100%;"> |
||||
|
</el-date-picker> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label=" " class="search-item search-btn-item"> |
||||
|
<el-button type="primary" @click="getMainData" style="">查询</el-button> |
||||
|
<el-button @click="handleAdd" type="primary" style="margin-left: 2px">新增</el-button> |
||||
|
</el-form-item> |
||||
|
</div> |
||||
|
</el-form> |
||||
|
|
||||
|
<el-table |
||||
|
:height="height" |
||||
|
:data="mainDataList" |
||||
|
border |
||||
|
ref="mainTable" |
||||
|
highlight-current-row |
||||
|
@row-click="changeData" |
||||
|
v-loading="dataListLoading" |
||||
|
style="width: 100%;"> |
||||
|
<el-table-column |
||||
|
v-for="(item,index) in columnArray1" :key="index" |
||||
|
:sortable="item.columnSortable" |
||||
|
:prop="item.columnProp" |
||||
|
:header-align="item.headerAlign" |
||||
|
:show-overflow-tooltip="item.showOverflowTooltip" |
||||
|
:align="item.align" |
||||
|
:fixed="item.fixed==''?false:item.fixed" |
||||
|
:min-width="item.columnWidth" |
||||
|
:label="item.columnLabel"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column fixed="right" header-align="center" align="center" width="150" label="操作"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-link type="primary" style="cursor: pointer; margin-right: 10px;" @click="handleEdit(scope.row)">编辑</el-link> |
||||
|
<el-link type="danger" style="cursor: pointer;" @click="handleDelete(scope.row)">删除</el-link> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
|
||||
|
<!-- 分页插件 --> |
||||
|
<el-pagination style="margin-top: 0px" |
||||
|
@size-change="sizeChangeHandle" |
||||
|
@current-change="currentChangeHandle" |
||||
|
:current-page="pageIndex" |
||||
|
:page-sizes="[20, 50, 100, 200, 500]" |
||||
|
:page-size="pageSize" |
||||
|
:total="totalPage" |
||||
|
layout="total, sizes, prev, pager, next, jumper"> |
||||
|
</el-pagination> |
||||
|
|
||||
|
<!-- 详情页签 --> |
||||
|
<el-tabs v-model="activeTab" style="margin-top: 0px; width: 99%;" @tab-click="handleTabClick" class="customer-tab" type="border-card"> |
||||
|
<!-- 费用明细 --> |
||||
|
<el-tab-pane label="费用明细" name="detail"> |
||||
|
<fee-detail-tab ref="feeDetailTab" :fee-data="currentRow" :table-height="detailHeight" /> |
||||
|
</el-tab-pane> |
||||
|
<!-- 申请单清单 --> |
||||
|
<el-tab-pane label="申请单清单" name="request"> |
||||
|
<request-fee-tab ref="requestFeeTab" :fee-data="currentRow" :table-height="detailHeight" /> |
||||
|
</el-tab-pane> |
||||
|
</el-tabs> |
||||
|
|
||||
|
<!-- 新增弹窗 --> |
||||
|
<el-dialog |
||||
|
title="新增费用记录" |
||||
|
:visible.sync="addDialogVisible" |
||||
|
width="30%" |
||||
|
top="10vh" |
||||
|
:close-on-click-modal="false"> |
||||
|
<el-form :model="addFormData" :rules="addRules" ref="addFormData" label-width="100px" size="small" label-position="top"> |
||||
|
<el-form-item label="费用日期" prop="feeDate" > |
||||
|
<el-date-picker |
||||
|
v-model="addFormData.feeDate" |
||||
|
type="date" |
||||
|
value-format="yyyy-MM-dd" |
||||
|
placeholder="选择日期" |
||||
|
style="width: 50%"> |
||||
|
</el-date-picker> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="申请人" prop="applyUser"> |
||||
|
<el-input v-model="addFormData.applyUser" placeholder="请输入申请人" style="width: 50%"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="备注"> |
||||
|
<el-input |
||||
|
type="textarea" |
||||
|
v-model="addFormData.remark" |
||||
|
:autosize="{ minRows: 3, maxRows: 6 }" |
||||
|
placeholder="请输入备注"> |
||||
|
</el-input> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="primary" @click="handleSaveAdd">保存</el-button> |
||||
|
<el-button @click="addDialogVisible = false">取消</el-button> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { searchFeeHeaderList, createFeeHeader, updateFeeHeader, deleteFeeRecord } from '@/api/inspection/srmFee.js' |
||||
|
import FeeDetailTab from './com_feeDetailTab.vue' |
||||
|
import RequestFeeTab from './com_requestFeeTab.vue' |
||||
|
|
||||
|
export default { |
||||
|
name: 'SrmFeeList', |
||||
|
components: { |
||||
|
FeeDetailTab, |
||||
|
RequestFeeTab |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
functionId: this.$route.meta.menuId, |
||||
|
height: 400, |
||||
|
detailHeight: 400, |
||||
|
currentRow: {}, |
||||
|
activeTab: 'detail', |
||||
|
addDialogVisible: false, |
||||
|
addFormData: { |
||||
|
feeDate: '', |
||||
|
applyUser: '', |
||||
|
remark: '' |
||||
|
}, |
||||
|
addRules: { |
||||
|
feeDate: [ |
||||
|
{ required: true, message: '请选择费用日期', trigger: 'change' } |
||||
|
], |
||||
|
applyUser: [ |
||||
|
{ required: true, message: '请输入申请人', trigger: 'blur' } |
||||
|
] |
||||
|
}, |
||||
|
searchData: { |
||||
|
feeNo: '', |
||||
|
applyUser: '', |
||||
|
feeDate: '', |
||||
|
site: this.$store.state.user.site, |
||||
|
page: 1, |
||||
|
limit: 50 |
||||
|
}, |
||||
|
pageIndex: 1, |
||||
|
pageSize: 50, |
||||
|
totalPage: 0, |
||||
|
mainDataList: [], |
||||
|
dataListLoading: false, |
||||
|
columnArray1: [ |
||||
|
{ |
||||
|
userId: this.$store.state.user.name, |
||||
|
functionId: this.functionId, |
||||
|
serialNumber: 'FeeTable1FeeNo', |
||||
|
tableId: 'FeeTable1', |
||||
|
tableName: '费用管理', |
||||
|
columnProp: 'feeNo', |
||||
|
headerAlign: 'center', |
||||
|
align: 'left', |
||||
|
columnLabel: '费用单号', |
||||
|
columnWidth: '150', |
||||
|
columnHidden: false, |
||||
|
columnImage: false, |
||||
|
columnSortable: false, |
||||
|
sortLv: 0, |
||||
|
status: true, |
||||
|
fixed: false |
||||
|
}, |
||||
|
{ |
||||
|
userId: this.$store.state.user.name, |
||||
|
functionId: this.functionId, |
||||
|
serialNumber: 'FeeTable1FeeDate', |
||||
|
tableId: 'FeeTable1', |
||||
|
tableName: '费用管理', |
||||
|
columnProp: 'feeDate', |
||||
|
headerAlign: 'center', |
||||
|
align: 'center', |
||||
|
columnLabel: '费用日期', |
||||
|
columnWidth: '120', |
||||
|
columnHidden: false, |
||||
|
columnImage: false, |
||||
|
columnSortable: false, |
||||
|
sortLv: 0, |
||||
|
status: true, |
||||
|
fixed: false |
||||
|
}, |
||||
|
{ |
||||
|
userId: this.$store.state.user.name, |
||||
|
functionId: this.functionId, |
||||
|
serialNumber: 'FeeTable1TotalAmount', |
||||
|
tableId: 'FeeTable1', |
||||
|
tableName: '费用管理', |
||||
|
columnProp: 'totalAmount', |
||||
|
headerAlign: 'center', |
||||
|
align: 'right', |
||||
|
columnLabel: '总金额', |
||||
|
columnWidth: '120', |
||||
|
columnHidden: false, |
||||
|
columnImage: false, |
||||
|
columnSortable: false, |
||||
|
sortLv: 0, |
||||
|
status: true, |
||||
|
fixed: false |
||||
|
}, |
||||
|
{ |
||||
|
userId: this.$store.state.user.name, |
||||
|
functionId: this.functionId, |
||||
|
serialNumber: 'FeeTable1ApplyUser', |
||||
|
tableId: 'FeeTable1', |
||||
|
tableName: '费用管理', |
||||
|
columnProp: 'applyUser', |
||||
|
headerAlign: 'center', |
||||
|
align: 'left', |
||||
|
columnLabel: '申请人', |
||||
|
columnWidth: '100', |
||||
|
columnHidden: false, |
||||
|
columnImage: false, |
||||
|
columnSortable: false, |
||||
|
sortLv: 0, |
||||
|
status: true, |
||||
|
fixed: false |
||||
|
}, |
||||
|
{ |
||||
|
userId: this.$store.state.user.name, |
||||
|
functionId: this.functionId, |
||||
|
serialNumber: 'FeeTable1CreatedBy', |
||||
|
tableId: 'FeeTable1', |
||||
|
tableName: '费用管理', |
||||
|
columnProp: 'createdBy', |
||||
|
headerAlign: 'center', |
||||
|
align: 'left', |
||||
|
columnLabel: '创建人', |
||||
|
columnWidth: '100', |
||||
|
columnHidden: false, |
||||
|
columnImage: false, |
||||
|
columnSortable: false, |
||||
|
sortLv: 0, |
||||
|
status: true, |
||||
|
fixed: false |
||||
|
}, |
||||
|
{ |
||||
|
userId: this.$store.state.user.name, |
||||
|
functionId: this.functionId, |
||||
|
serialNumber: 'FeeTable1CreatedDate', |
||||
|
tableId: 'FeeTable1', |
||||
|
tableName: '费用管理', |
||||
|
columnProp: 'createdDate', |
||||
|
headerAlign: 'center', |
||||
|
align: 'center', |
||||
|
columnLabel: '创建时间', |
||||
|
columnWidth: '160', |
||||
|
columnHidden: false, |
||||
|
columnImage: false, |
||||
|
columnSortable: false, |
||||
|
sortLv: 0, |
||||
|
status: true, |
||||
|
fixed: false |
||||
|
}, |
||||
|
{ |
||||
|
userId: this.$store.state.user.name, |
||||
|
functionId: this.functionId, |
||||
|
serialNumber: 'FeeTable1Remark', |
||||
|
tableId: 'FeeTable1', |
||||
|
tableName: '费用管理', |
||||
|
columnProp: 'remark', |
||||
|
headerAlign: 'center', |
||||
|
align: 'left', |
||||
|
columnLabel: '备注', |
||||
|
columnWidth: '200', |
||||
|
columnHidden: false, |
||||
|
columnImage: false, |
||||
|
columnSortable: false, |
||||
|
sortLv: 0, |
||||
|
status: true, |
||||
|
fixed: false |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.$nextTick(() => { |
||||
|
this.height = (window.innerHeight - 220) / 2 |
||||
|
this.detailHeight = (window.innerHeight - 220) / 2 |
||||
|
this.getMainData() |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
// 查询数据 |
||||
|
getMainData() { |
||||
|
console.log('开始查询费用列表...') |
||||
|
this.searchData.limit = this.pageSize |
||||
|
this.searchData.page = this.pageIndex |
||||
|
|
||||
|
this.dataListLoading = true |
||||
|
console.log('设置 loading 为 true') |
||||
|
|
||||
|
searchFeeHeaderList(this.searchData).then(({ data }) => { |
||||
|
console.log('接口返回数据:', data) |
||||
|
if (data && data.code === 0) { |
||||
|
this.mainDataList = data.page.list || [] |
||||
|
|
||||
|
this.pageIndex = data.page.currPage |
||||
|
this.pageSize = data.page.pageSize |
||||
|
this.totalPage = data.page.totalCount |
||||
|
|
||||
|
this.$nextTick(() => { |
||||
|
if (this.$refs.mainTable) { |
||||
|
this.$refs.mainTable.clearSelection() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
// 判断是否有数据 |
||||
|
if (this.mainDataList.length > 0) { |
||||
|
this.$refs.mainTable.setCurrentRow(this.mainDataList[0]) |
||||
|
this.changeData(this.mainDataList[0]) |
||||
|
} else { |
||||
|
this.changeData(null) |
||||
|
} |
||||
|
} else { |
||||
|
console.error('查询失败:', data) |
||||
|
this.$message.error((data && data.msg) || '查询失败') |
||||
|
} |
||||
|
this.dataListLoading = false |
||||
|
console.log('设置 loading 为 false') |
||||
|
}).catch((error) => { |
||||
|
console.error('查询费用列表异常:', error) |
||||
|
this.$message.error('查询失败,请稍后重试') |
||||
|
this.dataListLoading = false |
||||
|
console.log('异常处理,设置 loading 为 false') |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 每页数 |
||||
|
sizeChangeHandle(val) { |
||||
|
this.pageSize = val |
||||
|
this.pageIndex = 1 |
||||
|
this.getMainData() |
||||
|
}, |
||||
|
|
||||
|
// 当前页 |
||||
|
currentChangeHandle(val) { |
||||
|
this.pageIndex = val |
||||
|
this.getMainData() |
||||
|
}, |
||||
|
|
||||
|
// 行点击事件 |
||||
|
changeData(row) { |
||||
|
this.currentRow = row ? JSON.parse(JSON.stringify(row)) : {} |
||||
|
}, |
||||
|
|
||||
|
// 页签点击事件 |
||||
|
handleTabClick(tab) { |
||||
|
if (tab.name === 'detail') { |
||||
|
this.$nextTick(() => { |
||||
|
if (this.$refs.feeDetailTab) { |
||||
|
this.$refs.feeDetailTab.loadDetailList() |
||||
|
} |
||||
|
}) |
||||
|
} else if (tab.name === 'request') { |
||||
|
this.$nextTick(() => { |
||||
|
if (this.$refs.requestFeeTab) { |
||||
|
this.$refs.requestFeeTab.loadRequestFeeList() |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 新增 |
||||
|
handleAdd() { |
||||
|
this.addDialogVisible = true |
||||
|
this.addFormData = { |
||||
|
feeDate: '', |
||||
|
applyUser: '', |
||||
|
remark: '' |
||||
|
} |
||||
|
if (this.$refs.addFormData) { |
||||
|
this.$refs.addFormData.clearValidate() |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 保存新增 |
||||
|
handleSaveAdd() { |
||||
|
this.$refs.addFormData.validate((valid) => { |
||||
|
if (valid) { |
||||
|
const params = { |
||||
|
site: this.$store.state.user.site, |
||||
|
feeDate: this.addFormData.feeDate, |
||||
|
applyUser: this.addFormData.applyUser, |
||||
|
remark: this.addFormData.remark, |
||||
|
createdBy: this.$store.state.user.name, |
||||
|
updateBy: this.$store.state.user.name |
||||
|
} |
||||
|
|
||||
|
createFeeHeader(params).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.$message.success('创建成功') |
||||
|
this.addDialogVisible = false |
||||
|
this.getMainData() |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '创建失败') |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.$message.error('创建失败') |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 编辑(切换到费用明细页签) |
||||
|
handleEdit(row) { |
||||
|
this.changeData(row) |
||||
|
this.activeTab = 'detail' |
||||
|
this.$nextTick(() => { |
||||
|
if (this.$refs.feeDetailTab) { |
||||
|
this.$refs.feeDetailTab.loadDetailList() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 删除 |
||||
|
handleDelete(row) { |
||||
|
this.$confirm('确定要删除该费用记录吗?删除后将同时删除明细和关联申请单。', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
const params = { |
||||
|
site: row.site, |
||||
|
feeNo: row.feeNo |
||||
|
} |
||||
|
|
||||
|
deleteFeeRecord(params).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.$message.success('删除成功') |
||||
|
this.getMainData() |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '删除失败') |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.$message.error('删除失败') |
||||
|
}) |
||||
|
}).catch(() => {}) |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
this.getMainData() |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.search-form-inline { |
||||
|
background: #fff; |
||||
|
} |
||||
|
|
||||
|
.search-row { |
||||
|
display: flex; |
||||
|
align-items: flex-end; |
||||
|
flex-wrap: nowrap; |
||||
|
gap: 15px; |
||||
|
} |
||||
|
|
||||
|
.search-item { |
||||
|
flex: none; |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
|
||||
|
.search-btn-item { |
||||
|
flex: none; |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
|
||||
|
.search-btn-item /deep/ .el-form-item__content { |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
.search-item /deep/ .el-form-item__label { |
||||
|
font-size: 13px; |
||||
|
color: #606266; |
||||
|
padding-bottom: 5px; |
||||
|
line-height: 1; |
||||
|
height: auto; |
||||
|
} |
||||
|
|
||||
|
.search-item /deep/ .el-form-item__content { |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
/deep/ .customer-tab .el-tabs__content { |
||||
|
padding: 5px !important; |
||||
|
} |
||||
|
|
||||
|
// 按钮样式(与 inspectionRequestList 保持一致) |
||||
|
.customer-bun-min { |
||||
|
padding: 7px 12px; |
||||
|
font-size: 12px; |
||||
|
border-radius: 3px; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue