Compare commits
No commits in common. "dev_1.0.3" and "master" have entirely different histories.
139
docx/prompt.md
139
docx/prompt.md
|
|
@ -1,139 +0,0 @@
|
||||||
你是一个资深 Java 后端工程师,请在当前 Spring Boot(Java8)项目中实现一个完整的 MCP Server,并加入“AI 自动选 Tool(RAG + Tool Routing)”能力。
|
|
||||||
|
|
||||||
# 一、基础 MCP 能力(必须实现)
|
|
||||||
|
|
||||||
1. 提供统一入口:
|
|
||||||
POST /mcp
|
|
||||||
|
|
||||||
2. 实现 JSON-RPC 2.0:
|
|
||||||
|
|
||||||
* initialize
|
|
||||||
* tools/list
|
|
||||||
* tools/call
|
|
||||||
|
|
||||||
3. 返回格式:
|
|
||||||
{
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"id": "...",
|
|
||||||
"result": ...
|
|
||||||
}
|
|
||||||
|
|
||||||
# 二、流式能力(必须)
|
|
||||||
|
|
||||||
1. 禁止使用 SseEmitter
|
|
||||||
2. 使用 HttpServletResponse + OutputStream
|
|
||||||
3. 实现 chunked streaming(write + flush)
|
|
||||||
|
|
||||||
# 三、Tool 注册中心(必须)
|
|
||||||
|
|
||||||
实现:
|
|
||||||
|
|
||||||
* McpToolRegistry
|
|
||||||
* register / get / list
|
|
||||||
|
|
||||||
Tool结构:
|
|
||||||
|
|
||||||
* name
|
|
||||||
* description(非常重要,用于向量检索)
|
|
||||||
* inputSchema
|
|
||||||
* handler
|
|
||||||
|
|
||||||
# 四、RAG Tool 检索模块(新增重点)
|
|
||||||
|
|
||||||
实现一个 ToolRetriever 组件:
|
|
||||||
|
|
||||||
1. 构建向量索引(简化实现):
|
|
||||||
|
|
||||||
* 使用内存存储 List<ToolEmbedding>
|
|
||||||
* ToolEmbedding:
|
|
||||||
|
|
||||||
* toolName
|
|
||||||
* description
|
|
||||||
* embedding(double[])
|
|
||||||
|
|
||||||
2. 提供方法:
|
|
||||||
List<McpTool> retrieve(String query, int topK)
|
|
||||||
|
|
||||||
3. embedding 实现(简化):
|
|
||||||
|
|
||||||
* 可使用:
|
|
||||||
|
|
||||||
* 简单 TF-IDF
|
|
||||||
* 或 mock embedding(字符串相似度)
|
|
||||||
* 不依赖外部服务(保证可运行)
|
|
||||||
|
|
||||||
# 五、Tool Router(核心)
|
|
||||||
|
|
||||||
实现 ToolRouter:
|
|
||||||
|
|
||||||
流程:
|
|
||||||
|
|
||||||
1. 接收用户问题 query
|
|
||||||
2. 调用 ToolRetriever → 获取 topK tools
|
|
||||||
3. 构建 prompt(只包含候选 tools)
|
|
||||||
4. 返回候选 tools 给上层(或直接选)
|
|
||||||
|
|
||||||
要求:
|
|
||||||
|
|
||||||
* 不允许返回全部 tools
|
|
||||||
* 默认 topK = 3~5
|
|
||||||
|
|
||||||
# 六、tools/call 升级(关键)
|
|
||||||
|
|
||||||
当 method = tools/call 时:
|
|
||||||
|
|
||||||
1. 如果请求未指定 tool:
|
|
||||||
|
|
||||||
* 自动触发 ToolRouter
|
|
||||||
* 选出最优 tool
|
|
||||||
|
|
||||||
2. 如果指定 tool:
|
|
||||||
|
|
||||||
* 直接执行
|
|
||||||
|
|
||||||
# 七、默认内置工具
|
|
||||||
|
|
||||||
实现:
|
|
||||||
|
|
||||||
1. hello
|
|
||||||
输入:name
|
|
||||||
输出:hello xxx
|
|
||||||
|
|
||||||
2. meeting.summary
|
|
||||||
输入:text
|
|
||||||
输出:模拟总结
|
|
||||||
|
|
||||||
# 八、架构分层(必须)
|
|
||||||
|
|
||||||
* controller
|
|
||||||
* service
|
|
||||||
* registry
|
|
||||||
* retriever(新增)
|
|
||||||
* router(新增)
|
|
||||||
|
|
||||||
# 九、扩展能力(必须预留)
|
|
||||||
|
|
||||||
1. 支持替换为真实向量数据库(如 Milvus / ES)
|
|
||||||
2. 支持 embedding API(OpenAI / 本地模型)
|
|
||||||
3. 支持多 MCP Server(未来扩展)
|
|
||||||
|
|
||||||
# 十、输出要求
|
|
||||||
|
|
||||||
1. 输出完整代码:
|
|
||||||
|
|
||||||
* McpController
|
|
||||||
* McpService
|
|
||||||
* McpToolRegistry
|
|
||||||
* ToolRetriever
|
|
||||||
* ToolRouter
|
|
||||||
* ToolEmbedding
|
|
||||||
* ToolInitializer
|
|
||||||
* McpRequest
|
|
||||||
|
|
||||||
2. 代码必须:
|
|
||||||
|
|
||||||
* 可运行
|
|
||||||
* 无伪代码
|
|
||||||
* 包含必要注释
|
|
||||||
* 代码生成目录在ruoyi-sip/src/main/java/com/ruoyi/sip/llm
|
|
||||||
3. 不要解释,只输出代码
|
|
||||||
|
|
@ -6,4 +6,3 @@ ENV = 'production'
|
||||||
|
|
||||||
# 若依管理系统/生产环境
|
# 若依管理系统/生产环境
|
||||||
VUE_APP_BASE_API = '/prod-api'
|
VUE_APP_BASE_API = '/prod-api'
|
||||||
VUE_APP_SERVICE_HOST = 'wb.oms.unisspace.com'
|
|
||||||
|
|
|
||||||
|
|
@ -28,20 +28,18 @@
|
||||||
"axios": "0.28.1",
|
"axios": "0.28.1",
|
||||||
"clipboard": "2.0.8",
|
"clipboard": "2.0.8",
|
||||||
"core-js": "3.37.1",
|
"core-js": "3.37.1",
|
||||||
"decimal.js": "10.4.2",
|
|
||||||
"echarts": "5.4.0",
|
"echarts": "5.4.0",
|
||||||
"element-ui": "2.15.14",
|
"element-ui": "2.15.14",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
"fuse.js": "6.4.3",
|
"fuse.js": "6.4.3",
|
||||||
"highlight.js": "9.18.5",
|
"highlight.js": "9.18.5",
|
||||||
"html2canvas": "^1.4.1",
|
|
||||||
"js-beautify": "1.13.0",
|
"js-beautify": "1.13.0",
|
||||||
"js-cookie": "3.0.1",
|
"js-cookie": "3.0.1",
|
||||||
"jsencrypt": "3.0.0-rc.1",
|
"jsencrypt": "3.0.0-rc.1",
|
||||||
"jspdf": "^2.5.1",
|
|
||||||
"jszip": "^3.10.1",
|
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"quill": "2.0.2",
|
"quill": "2.0.2",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
|
"jspdf": "^2.5.1",
|
||||||
"screenfull": "5.0.2",
|
"screenfull": "5.0.2",
|
||||||
"sortablejs": "1.10.2",
|
"sortablejs": "1.10.2",
|
||||||
"splitpanes": "2.4.1",
|
"splitpanes": "2.4.1",
|
||||||
|
|
@ -50,7 +48,8 @@
|
||||||
"vue-cropper": "0.5.5",
|
"vue-cropper": "0.5.5",
|
||||||
"vue-router": "3.4.9",
|
"vue-router": "3.4.9",
|
||||||
"vuedraggable": "2.24.3",
|
"vuedraggable": "2.24.3",
|
||||||
"vuex": "3.6.0"
|
"vuex": "3.6.0",
|
||||||
|
"decimal.js": "10.4.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "4.4.6",
|
"@vue/cli-plugin-babel": "4.4.6",
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询审批任务列表
|
|
||||||
export function listApprovalTask(query) {
|
|
||||||
const { pageNum, pageSize, orderByColumn, isAsc, ...body } = query
|
|
||||||
return request({
|
|
||||||
url: '/approve/task/vue/list',
|
|
||||||
method: 'post',
|
|
||||||
params: { pageNum, pageSize, orderByColumn, isAsc },
|
|
||||||
data: body
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取审批任务数量统计
|
|
||||||
export function getApprovalTaskTotal() {
|
|
||||||
return request({
|
|
||||||
url: '/approve/task/vue/total',
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增流程确认记录
|
|
||||||
export function addTodoConfirm(data) {
|
|
||||||
return request({
|
|
||||||
url: '/approve/task/vue/confirm',
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询报价单列表
|
|
||||||
export function listQuotation(query) {
|
|
||||||
return request({
|
|
||||||
url: '/quotation/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询报价单详细
|
|
||||||
export function getQuotation(id) {
|
|
||||||
return request({
|
|
||||||
url: '/quotation/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增报价单
|
|
||||||
export function addQuotation(data) {
|
|
||||||
return request({
|
|
||||||
url: '/quotation/insert',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改报价单
|
|
||||||
export function updateQuotation(data) {
|
|
||||||
return request({
|
|
||||||
url: '/quotation/update',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除报价单
|
|
||||||
export function delQuotation(id) {
|
|
||||||
return request({
|
|
||||||
url: '/quotation/remove/batch/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function exportSingleQuotation(id) {
|
|
||||||
return request({
|
|
||||||
url: '/quotation/export/single/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { tansParams } from '@/utils/ruoyi'
|
|
||||||
|
|
||||||
// 查询制造商信息列表
|
// 查询制造商信息列表
|
||||||
export function listVendor(query) {
|
export function listVendor(query) {
|
||||||
|
|
@ -49,9 +48,7 @@ export function exportVendor(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/vendor/export',
|
url: '/system/vendor/export',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: query,
|
params: query
|
||||||
transformRequest: [(params) => tansParams(params)],
|
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 按SN码查询库存数据
|
|
||||||
export function listInventoryInfoByProductSn(query) {
|
|
||||||
return request({
|
|
||||||
url: '/sip/dataProcess/inventoryInfoByProductSn',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询项目管理列表
|
|
||||||
export function listProject(query) {
|
|
||||||
return request({
|
|
||||||
url: '/sip/project/vue/list',
|
|
||||||
method: 'post',
|
|
||||||
data: query,
|
|
||||||
headers: { 'Content-Type': 'multipart/form-data' },
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 项目转移负责人
|
|
||||||
export function transferProject(data) {
|
|
||||||
return request({
|
|
||||||
url: '/sip/dataProcess/projectTransfer',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询财务计收列表
|
|
||||||
export function listCharge(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/charge/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询财务计收详细
|
|
||||||
export function getCharge(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/charge/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增财务计收
|
|
||||||
export function addCharge(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/charge',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改财务计收
|
|
||||||
export function updateCharge(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/charge',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function revokeCharge(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/charge/revoke',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除财务计收
|
|
||||||
export function delCharge(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/charge/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function applyChargeBiz(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/charge/applyBiz' ,
|
|
||||||
method: 'put',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function returnApplyBiz(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/charge/returnApplyBiz' ,
|
|
||||||
method: 'put',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function applyCharge(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/charge/apply' ,
|
|
||||||
method: 'put',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
import {tansParams} from "@/utils/ruoyi"
|
|
||||||
|
|
||||||
// 查询销售收票单列表
|
|
||||||
export function listInvoice(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询销售收票单详细
|
|
||||||
export function getInvoice(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询销售收票单附件
|
|
||||||
export function getInvoiceAttachments(id, params) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/invoice/attachment/${id}`,
|
|
||||||
method: 'get',
|
|
||||||
params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上传销售收票单附件
|
|
||||||
export function uploadInvoiceAttachment(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/uploadReceipt',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data'
|
|
||||||
},
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 申请红冲
|
|
||||||
export function redRush(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/applyRefund/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 申请红冲 (提交表单)
|
|
||||||
export function applyRefund(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/applyRefund',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 退回销售收票单
|
|
||||||
export function returnInvoice(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/return/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增销售收票单
|
|
||||||
export function addInvoice(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receivable/mergeAndInitiateInvoice',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询销售收票单产品明细
|
|
||||||
export function getInvoiceProducts(code) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/product/' + code,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 申请开票
|
|
||||||
export function applyInvoice(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/apply',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 撤销销售收票单
|
|
||||||
export function revokeInvoice(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/revoke/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询开票审批列表
|
|
||||||
export function listInvoiceApprove(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/approve/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询已审批开票列表
|
|
||||||
export function listInvoiceApproved(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/approved/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询开票单详细
|
|
||||||
export function getInvoiceDetail(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询收票待审批列表
|
|
||||||
export function listInvoiceReceiptApprove(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/approve/list',
|
|
||||||
method: 'post',
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询收票已审批列表
|
|
||||||
export function listInvoiceReceiptApproved(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/approved/list',
|
|
||||||
method: 'post',
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询收票详情
|
|
||||||
export function getInvoiceReceipt(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询收票附件
|
|
||||||
export function getInvoiceReceiptAttachments(id,params) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/attachment/' + id,
|
|
||||||
method: 'get',
|
|
||||||
params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询核销记录列表
|
|
||||||
export function listInvoiceWriteOff(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/writeoff/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询核销详情
|
|
||||||
export function getInvoiceWriteoff(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/writeoff/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除核销记录
|
|
||||||
export function delInvoiceWriteoff(ids) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/invoice/writeoff/' + ids,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询采购应付单列表
|
|
||||||
export function listPayable(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payable/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: { 'Content-Type': 'multipart/form-data' },
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询采购应付单详情
|
|
||||||
export function getPayable(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payable/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询付款计划列表
|
|
||||||
export function getPaymentPlan(payableBillId) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/payable/plan/${payableBillId}`,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新付款计划
|
|
||||||
export function updatePaymentPlan(payableBillId, data) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/payable/plan/${payableBillId}`,
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并并发起付款
|
|
||||||
export function mergeAndInitiatePayment(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payable/mergeAndInitiatePayment',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并并发起收票
|
|
||||||
export function mergeAndInitiateReceipt(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payable/mergeAndInitiateReceipt',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// [PLACEHOLDER] 查询收票计划列表 - Endpoint to be confirmed by user
|
|
||||||
export function getReceivingTicketPlan(payableBillId) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/ticket/plan/${payableBillId}`,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// [PLACEHOLDER] 更新收票计划 - Endpoint to be confirmed by user
|
|
||||||
export function updateReceivingTicketPlan(payableBillId, data) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/ticket/plan/${payableBillId}`,
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 同步付款计划至发票计划
|
|
||||||
export function syncToTicketPlan(payableBillId) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/payable/plan/sync/${payableBillId}`,
|
|
||||||
method: 'post'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,210 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
import { tansParams } from "@/utils/ruoyi"
|
|
||||||
|
|
||||||
// 查询付款单列表
|
|
||||||
export function listPayment(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: tansParams(query)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function exportPayment(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/export',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: tansParams(query)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询付款单详细
|
|
||||||
export function getPayment(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询付款单附件
|
|
||||||
export function getPaymentAttachments(id, params) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/payment/attachment/${id}`,
|
|
||||||
method: 'get',
|
|
||||||
params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function deleteFile(id) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/payment/attachment/${id}`,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上传付款单附件
|
|
||||||
export function uploadPaymentAttachment(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/uploadReceipt',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data'
|
|
||||||
},
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 退回付款单
|
|
||||||
export function returnPayment(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/returnPayment/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增付款单
|
|
||||||
export function addPaymentFromPayable(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payable/mergeAndInitiatePayment',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function addPayment(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/add',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function handleRevoke(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/revoke',
|
|
||||||
method: 'post',
|
|
||||||
data: {id: id},
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 申请付款
|
|
||||||
export function applyPaymentApi(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/applyPayment',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 申请退款
|
|
||||||
export function applyRefund(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/applyRefund',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function deletePayment(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/remove',
|
|
||||||
method: 'post',
|
|
||||||
params:{ids:id},
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function applyRefundApprove(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/applyRefundApprove',
|
|
||||||
method: 'post',
|
|
||||||
data: {id: id},
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询应付单列表 (用于新增付款单-非预付)
|
|
||||||
export function listPayableBills(query) {
|
|
||||||
return request({
|
|
||||||
url: 'finance/payable/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询采购订单列表 (用于新增付款单-预付)
|
|
||||||
export function listOrders(query) {
|
|
||||||
return request({
|
|
||||||
url: '/project/order/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询付款审批列表
|
|
||||||
export function listPaymentApprove(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/approve/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: tansParams(query)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询已审批付款列表
|
|
||||||
export function listPaymentApproved(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/approved/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: tansParams(query)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询付款单列表 (核销专用)
|
|
||||||
export function listPaymentForWriteOff(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/write-off/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: tansParams(query)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 手工匹配核销
|
|
||||||
export function manualWriteOff(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/writeoff',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增付款单
|
|
||||||
export function updatePaymentBill(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/updatePaymentBill',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
import {tansParams} from "@/utils/ruoyi";
|
|
||||||
|
|
||||||
// 查询付款退款待审批列表
|
|
||||||
export function listPaymentRefundApprove(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/approve/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询付款退款已审批列表
|
|
||||||
export function listPaymentRefundApproved(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payment/approved/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询付款退款详情
|
|
||||||
export function getPaymentRefund(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/paymentRefund/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
import {tansParams} from "@/utils/ruoyi"
|
|
||||||
|
|
||||||
// 查询收票单列表
|
|
||||||
export function listReceipt(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询收票单详细
|
|
||||||
export function getReceipt(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询收票单附件
|
|
||||||
export function getReceiptAttachments(id, params) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/ticket/attachment/${id}`,
|
|
||||||
method: 'get',
|
|
||||||
params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上传收票单附件
|
|
||||||
export function uploadReceiptAttachment(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/uploadReceipt',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data'
|
|
||||||
},
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 退回收票单
|
|
||||||
export function redRush(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/applyRefund/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function returnReceipt(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/return/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增收票单
|
|
||||||
export function addReceipt(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/payable/mergeAndInitiateReceipt',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 撤销收票单
|
|
||||||
export function revokeReceipt(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/revoke/' + id,
|
|
||||||
method: 'put'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 申请红冲(带附件)
|
|
||||||
export function applyRedRush(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticket/applyRefund',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data'
|
|
||||||
},
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 查询收款审批列表
|
|
||||||
export function listReceiptApprove(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/approve/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询已审批收款列表
|
|
||||||
export function listReceiptApproved(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/approved/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询收款单详细
|
|
||||||
export function getReceiptDetail(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询销售应收单列表
|
|
||||||
export function listReceivable(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receivable/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: { 'Content-Type': 'multipart/form-data' },
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询销售应收单详情
|
|
||||||
export function getReceivable(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receivable/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询收款计划列表
|
|
||||||
export function getReceiptPlan(receivableBillId) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/receivable/plan/${receivableBillId}`,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新收款计划
|
|
||||||
export function updateReceiptPlan(receivableBillId, data) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/receivable/plan/${receivableBillId}`,
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并并发起收款
|
|
||||||
export function mergeAndInitiateReceipt(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receivable/mergeAndInitiateReceipt',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading:true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并并发起开票
|
|
||||||
export function mergeAndInitiateInvoice(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receivable/mergeAndInitiateInvoice',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading:true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询开票计划列表
|
|
||||||
export function getInvoicePlan(receivableBillId) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/receivable/invoice/plan/${receivableBillId}`,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新开票计划
|
|
||||||
export function updateInvoicePlan(receivableBillId, data) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/receivable/invoice/plan/${receivableBillId}`,
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 同步收款计划至开票计划
|
|
||||||
export function syncToInvoicePlan(receivableBillId) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/receivable/plan/sync/${receivableBillId}`,
|
|
||||||
method: 'post'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询销售核销记录列表
|
|
||||||
export function listReceivableWriteOff(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receivable/writeoff/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询销售核销详情
|
|
||||||
export function getReceivableWriteOff(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receivable/writeoff/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除销售核销记录
|
|
||||||
export function delReceivableWriteOff(ids) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receivable/writeoff/' + ids,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,130 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
import {tansParams} from "@/utils/ruoyi"
|
|
||||||
|
|
||||||
// 查询收款单列表
|
|
||||||
export function listReceive(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询收款单详细
|
|
||||||
export function getReceive(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询收款单附件
|
|
||||||
export function getReceiveAttachments(id, params) {
|
|
||||||
return request({
|
|
||||||
url: `/finance/receipt/attachment/${id}`,
|
|
||||||
method: 'get',
|
|
||||||
params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上传收款单附件
|
|
||||||
export function uploadReceiveAttachment(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/uploadReceipt',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data'
|
|
||||||
},
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 申请红冲
|
|
||||||
export function redRush(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/applyRefund/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 退回收款单
|
|
||||||
export function returnReceive(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/returnReceivable/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增收款单 (Calls Receivable Merge Logic)
|
|
||||||
export function mergeReceivable(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receivable/mergeAndInitiateReceipt',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function addReceipt(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/insert',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function applyReceipt(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/applyReceipt',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 申请退款
|
|
||||||
export function submitRefund(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/applyRefund',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询收款单列表 (核销专用)
|
|
||||||
export function listReceiptForWriteOff(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/write-off/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
data: tansParams(query)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 手工匹配核销
|
|
||||||
export function manualReceiptWriteOff(data) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receivable/writeoff',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 撤销收款单
|
|
||||||
export function revokeReceipt(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/receipt/revoke',
|
|
||||||
method: 'post',
|
|
||||||
data: {id: id},
|
|
||||||
needLoading: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询项目报表列表
|
|
||||||
export function listReport(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/report/list',
|
|
||||||
method: 'post',
|
|
||||||
headers: { 'Content-Type': 'multipart/form-data' },
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询供货商维度报表列表
|
|
||||||
export function listSupplierReport(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/report/listSupplier',
|
|
||||||
method: 'post',
|
|
||||||
headers: { 'Content-Type': 'multipart/form-data' },
|
|
||||||
data: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询核销记录列表
|
|
||||||
export function listWriteOff(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/writeoff/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function listTicketWriteOff(query) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticketWriteoff/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询核销详情
|
|
||||||
export function getWriteOff(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/writeoff/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function getTicketWriteoff(id) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticketWriteoff/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除核销记录
|
|
||||||
export function delWriteOff(ids) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/writeoff/' + ids,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function delTicketWriteoff(ids) {
|
|
||||||
return request({
|
|
||||||
url: '/finance/ticketWriteoff/' + ids,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -17,14 +17,6 @@ export function listCompletedFlows(data) {
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 按业务单号查询待办记录(查看申请详情用)
|
|
||||||
export function listApplyFlows(data) {
|
|
||||||
return request({
|
|
||||||
url: '/flow/todo/apply-list',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 通用审批
|
// 通用审批
|
||||||
export function approveTask(data) {
|
export function approveTask(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|
|
||||||
|
|
@ -52,15 +52,6 @@ export function recallDelivery(id) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交出库撤回审批(跨天发货记录)
|
|
||||||
export function recallApply(id, reason, amountChanged) {
|
|
||||||
return request({
|
|
||||||
url: '/inventory/delivery/vue/recall/apply',
|
|
||||||
method: 'post',
|
|
||||||
data: {id, reason, amountChanged}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出采购合同
|
// 导出采购合同
|
||||||
export function exportDelivery(query) {
|
export function exportDelivery(query) {
|
||||||
return request({
|
return request({
|
||||||
|
|
|
||||||
|
|
@ -71,23 +71,6 @@ export function recallExecution(id) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交撤单审批申请
|
|
||||||
export function recallExecutionApply(id, reason, amountChanged) {
|
|
||||||
return request({
|
|
||||||
url: '/inventory/execution/vue/recall/apply',
|
|
||||||
method: 'post',
|
|
||||||
data: { id, reason, amountChanged }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function exportExecution(data) {
|
|
||||||
return request({
|
|
||||||
url: `/inventory/execution/vue/export`,
|
|
||||||
method: 'post',
|
|
||||||
data: { data },
|
|
||||||
headers: { 'Content-Type': 'multipart/form-data' },
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询出库预览信息
|
// 查询出库预览信息
|
||||||
export function getCheckOutPreview(data) {
|
export function getCheckOutPreview(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|
|
||||||
|
|
@ -85,30 +85,3 @@ export function getOuterLog(query) {
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询在途库存
|
|
||||||
export function getPurchaseStock(query) {
|
|
||||||
return request({
|
|
||||||
url: '/inventory/info/vue/purchase-stock',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询锁单
|
|
||||||
export function getBindOrder(query) {
|
|
||||||
return request({
|
|
||||||
url: '/inventory/info/vue/bind-order',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询在库现存
|
|
||||||
export function getInventoryInner(query) {
|
|
||||||
return request({
|
|
||||||
url: '/inventory/info/vue/inventory-inner',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,6 @@ export function getInner(id) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询入库单产品信息列表
|
|
||||||
export function listInnerInventoryInfo(id, query) {
|
|
||||||
return request({
|
|
||||||
url: `${VUE_APP_API_URL}/${id}/inventory-info/list`,
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增入库单信息
|
// 新增入库单信息
|
||||||
export function addInner(data) {
|
export function addInner(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|
|
||||||
|
|
@ -79,14 +79,6 @@ export function exportDownloadTemplate() {
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 下载带列表数据的发货导入模板
|
|
||||||
export function exportDownloadTemplateData(data) {
|
|
||||||
return request({
|
|
||||||
url: '/inventory/outer/importTemplateData',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function importSnData(formData) {
|
export function importSnData(formData) {
|
||||||
return request({
|
return request({
|
||||||
url: '/inventory/outer/vue/importData',
|
url: '/inventory/outer/vue/importData',
|
||||||
|
|
@ -97,13 +89,3 @@ export function importSnData(formData) {
|
||||||
data: formData
|
data: formData
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export function assignDeliverySnData(formData) {
|
|
||||||
return request({
|
|
||||||
url: '/inventory/outer/vue/assignDeliveryData',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data'
|
|
||||||
},
|
|
||||||
data: formData
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,5 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
function createLoginFormData(data) {
|
|
||||||
const formData = new FormData()
|
|
||||||
Object.keys(data).forEach(key => formData.append(key, data[key]))
|
|
||||||
return formData
|
|
||||||
}
|
|
||||||
|
|
||||||
// 登录方法 - 基于 Session 认证,使用 FormData 格式
|
// 登录方法 - 基于 Session 认证,使用 FormData 格式
|
||||||
export function login(username, password, code, rememberMe) {
|
export function login(username, password, code, rememberMe) {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
|
|
@ -15,40 +9,6 @@ export function login(username, password, code, rememberMe) {
|
||||||
formData.append('rememberMe', rememberMe || false)
|
formData.append('rememberMe', rememberMe || false)
|
||||||
return request({
|
return request({
|
||||||
url: '/login',
|
url: '/login',
|
||||||
headers: {
|
|
||||||
isToken: false,
|
|
||||||
'Content-Type': 'multipart/form-data',
|
|
||||||
repeatSubmit: false,
|
|
||||||
allowWarning: true
|
|
||||||
},
|
|
||||||
method: 'post',
|
|
||||||
data: formData
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function resetLoginPwd(data) {
|
|
||||||
const formData = createLoginFormData({
|
|
||||||
username: data.username,
|
|
||||||
newPassword: data.newPassword,
|
|
||||||
confirmPassword: data.confirmPassword,
|
|
||||||
emailCode: data.emailCode
|
|
||||||
})
|
|
||||||
return request({
|
|
||||||
url: '/login/resetPwd',
|
|
||||||
headers: {
|
|
||||||
isToken: false,
|
|
||||||
'Content-Type': 'multipart/form-data',
|
|
||||||
repeatSubmit: false
|
|
||||||
},
|
|
||||||
method: 'post',
|
|
||||||
data: formData
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function sendResetPwdEmailCode(username) {
|
|
||||||
const formData = createLoginFormData({ username })
|
|
||||||
return request({
|
|
||||||
url: '/login/sendResetPwdEmailCode',
|
|
||||||
headers: {
|
headers: {
|
||||||
isToken: false,
|
isToken: false,
|
||||||
'Content-Type': 'multipart/form-data',
|
'Content-Type': 'multipart/form-data',
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ export function delOrder(id) {
|
||||||
export function exportOrder(query) {
|
export function exportOrder(query) {
|
||||||
return request({
|
return request({
|
||||||
url: `${baseURL}/export`,
|
url: `${baseURL}/export`,
|
||||||
method: 'get',
|
method: 'post',
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,28 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
function normalizeSerialNumbers(input) {
|
// 查询产品信息
|
||||||
const values = Array.isArray(input) ? input : [input]
|
export function getProductInfo(serialNumber) {
|
||||||
return [...new Set(values
|
|
||||||
.map(item => (item || '').toString().trim())
|
|
||||||
.filter(Boolean))]
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildQueryPayload(input) {
|
|
||||||
const serialNumbers = normalizeSerialNumbers(input)
|
|
||||||
return {
|
|
||||||
serialNumber: serialNumbers[0] || '',
|
|
||||||
serialNumbers
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getProductInfo(serialNumberOrNumbers) {
|
|
||||||
return request({
|
return request({
|
||||||
url: '/manage/service/product',
|
url: '/manage/service/product',
|
||||||
method: 'post',
|
method: 'get',
|
||||||
data: buildQueryPayload(serialNumberOrNumbers)
|
params: { serialNumber }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOrderInfo(serialNumberOrNumbers) {
|
// 查询相关合同信息
|
||||||
|
export function getOrderInfo(serialNumber) {
|
||||||
return request({
|
return request({
|
||||||
url: '/manage/service/order',
|
url: '/manage/service/order',
|
||||||
method: 'post',
|
method: 'get',
|
||||||
data: buildQueryPayload(serialNumberOrNumbers)
|
params: { serialNumber }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getWarrantyInfo(serialNumberOrNumbers) {
|
// 查询标准保修信息
|
||||||
|
export function getWarrantyInfo(serialNumber) {
|
||||||
return request({
|
return request({
|
||||||
url: '/manage/service/query',
|
url: '/manage/service/query',
|
||||||
method: 'post',
|
method: 'get',
|
||||||
data: buildQueryPayload(serialNumberOrNumbers)
|
params: { serialNumber }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { tansParams } from '@/utils/ruoyi'
|
|
||||||
|
|
||||||
// 查询项目管理列表
|
// 查询项目管理列表
|
||||||
export function listProject(query) {
|
export function listProject(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/sip/project/vue/list',
|
url: '/sip/project/vue/list',
|
||||||
method: 'post',
|
method: 'get',
|
||||||
data: query,
|
params: query
|
||||||
headers: { 'Content-Type': 'multipart/form-data' },
|
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,34 +49,6 @@ export function exportProject(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/sip/project/vue/export',
|
url: '/sip/project/vue/export',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: query,
|
params: query
|
||||||
transformRequest: [(params) => tansParams(params)],
|
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 项目收藏
|
|
||||||
export function addCollect(data) {
|
|
||||||
return request({
|
|
||||||
url: '/project/collect/add',
|
|
||||||
method: 'post',
|
|
||||||
data: data,
|
|
||||||
needLoading:true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function editJoinTrial(data) {
|
|
||||||
return request({
|
|
||||||
url: '/sip/project/vue/joinTrial',
|
|
||||||
method: 'put',
|
|
||||||
data: data,
|
|
||||||
needLoading:true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function exportSingle(id) {
|
|
||||||
return request({
|
|
||||||
url: `/sip/project/vue/joinTrial/export/${id}`,
|
|
||||||
method: 'get',
|
|
||||||
needLoading:true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,48 +85,3 @@ export function updateFinanceStatus(id, status) {
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询产品配货备货明细
|
|
||||||
export function productMatchList(orderCode) {
|
|
||||||
return request({
|
|
||||||
url: '/project/order/vue/productMatchList',
|
|
||||||
method: 'get',
|
|
||||||
params: { orderCode }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询产品配备货绑定信息
|
|
||||||
export function productMatchBindList(orderCode, productCode, params = {}) {
|
|
||||||
return request({
|
|
||||||
url: '/project/order/vue/productMatchBindList',
|
|
||||||
method: 'get',
|
|
||||||
params: { orderCode, productCode, ...params }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存订单关联采购单
|
|
||||||
export function savePurchaseOrderMap(data) {
|
|
||||||
return request({
|
|
||||||
url: '/project/order/vue/purchaseOrderMap',
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询采购单SN码列表
|
|
||||||
export function purchaseSnList(purchaseNo, orderCode, productCode) {
|
|
||||||
return request({
|
|
||||||
url: '/project/order/vue/purchaseSnList',
|
|
||||||
method: 'get',
|
|
||||||
params: { purchaseNo, orderCode, productCode }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 订单绑定SN码
|
|
||||||
export function bindOrderSnCodes(orderCode, productCode, purchaseNo, orderId, purchaseId, productSnList) {
|
|
||||||
return request({
|
|
||||||
url: '/project/order/vue/bindOrderSnCodes',
|
|
||||||
method: 'post',
|
|
||||||
data: { orderCode, productCode, purchaseNo, orderId, purchaseId, productSnList }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -106,16 +106,6 @@ export function recallPurchaseorder(id) {
|
||||||
method: 'put'
|
method: 'put'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export function exportPurchaseorder(data) {
|
|
||||||
return request({
|
|
||||||
url: '/sip/purchaseorder/export',
|
|
||||||
method: 'get',
|
|
||||||
params: data,
|
|
||||||
// headers: { 'Content-Type': 'multipart/form-data' },
|
|
||||||
needLoading: true
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询已审批采购单主表列表
|
// 查询已审批采购单主表列表
|
||||||
export function listApprovedPurchaseorder(query) {
|
export function listApprovedPurchaseorder(query) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { tansParams } from '@/utils/ruoyi'
|
|
||||||
|
|
||||||
// 查询办事处信息列表
|
// 查询办事处信息列表
|
||||||
export function listAgent(query) {
|
export function listAgent(query) {
|
||||||
|
|
@ -49,8 +48,6 @@ export function exportAgent(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/agent/vue/export',
|
url: '/system/agent/vue/export',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: query,
|
params: query
|
||||||
transformRequest: [(params) => tansParams(params)],
|
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询公司信息列表
|
|
||||||
export function listCompanyInfo(query) {
|
|
||||||
return request({
|
|
||||||
url: '/sip/companyInfo/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询公司信息详细
|
|
||||||
export function getCompanyInfo(id) {
|
|
||||||
return request({
|
|
||||||
url: '/sip/companyInfo/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增公司信息
|
|
||||||
export function addCompanyInfo(data) {
|
|
||||||
return request({
|
|
||||||
url: '/sip/companyInfo',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改公司信息
|
|
||||||
export function updateCompanyInfo(data) {
|
|
||||||
return request({
|
|
||||||
url: '/sip/companyInfo',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除公司信息
|
|
||||||
export function delCompanyInfo(id) {
|
|
||||||
return request({
|
|
||||||
url: '/sip/companyInfo/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { tansParams } from '@/utils/ruoyi'
|
|
||||||
|
|
||||||
// 查询客户信息列表
|
// 查询客户信息列表
|
||||||
export function listCustomer(query) {
|
export function listCustomer(query) {
|
||||||
|
|
@ -49,8 +48,6 @@ export function exportCustomer(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/customer/vue/export',
|
url: '/system/customer/vue/export',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: query,
|
params: query
|
||||||
transformRequest: [(params) => tansParams(params)],
|
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { tansParams } from '@/utils/ruoyi'
|
|
||||||
|
|
||||||
// 查询产品管理列表
|
// 查询产品管理列表
|
||||||
export function listProduct(query) {
|
export function listProduct(query) {
|
||||||
|
|
@ -49,9 +48,7 @@ export function exportProduct(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/product/export',
|
url: '/system/product/export',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: query,
|
params: query
|
||||||
transformRequest: [(params) => tansParams(params)],
|
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { parseStrEmpty } from "@/utils/ruoyi";
|
import { parseStrEmpty } from "@/utils/ruoyi";
|
||||||
|
|
||||||
// 鏌ヨ鐢ㄦ埛鍒楄〃
|
// 查询用户列表
|
||||||
export function listUser(query) {
|
export function listUser(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/list',
|
url: '/system/user/list',
|
||||||
|
|
@ -10,7 +10,7 @@ export function listUser(query) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鏌ヨ鐢ㄦ埛璇︾粏
|
// 查询用户详细
|
||||||
export function getUser(userId) {
|
export function getUser(userId) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/' + parseStrEmpty(userId),
|
url: '/system/user/' + parseStrEmpty(userId),
|
||||||
|
|
@ -18,7 +18,7 @@ export function getUser(userId) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鏂板鐢ㄦ埛
|
// 新增用户
|
||||||
export function addUser(data) {
|
export function addUser(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/add',
|
url: '/system/user/add',
|
||||||
|
|
@ -30,7 +30,7 @@ export function addUser(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 淇敼鐢ㄦ埛
|
// 修改用户
|
||||||
export function updateUser(data) {
|
export function updateUser(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user',
|
url: '/system/user',
|
||||||
|
|
@ -39,7 +39,7 @@ export function updateUser(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鍒犻櫎鐢ㄦ埛
|
// 删除用户
|
||||||
export function delUser(userId) {
|
export function delUser(userId) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/' + userId,
|
url: '/system/user/' + userId,
|
||||||
|
|
@ -47,7 +47,7 @@ export function delUser(userId) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鐢ㄦ埛瀵嗙爜閲嶇疆
|
// 用户密码重置
|
||||||
export function resetUserPwd(data) {
|
export function resetUserPwd(data) {
|
||||||
|
|
||||||
return request({
|
return request({
|
||||||
|
|
@ -60,7 +60,7 @@ export function resetUserPwd(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鐢ㄦ埛鐘舵€佷慨鏀?
|
// 用户状态修改
|
||||||
export function changeUserStatus(userId, status) {
|
export function changeUserStatus(userId, status) {
|
||||||
const data = {
|
const data = {
|
||||||
userId,
|
userId,
|
||||||
|
|
@ -76,7 +76,7 @@ export function changeUserStatus(userId, status) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鏌ヨ鐢ㄦ埛涓汉淇℃伅
|
// 查询用户个人信息
|
||||||
export function getUserProfile() {
|
export function getUserProfile() {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/profile/vue',
|
url: '/system/user/profile/vue',
|
||||||
|
|
@ -84,7 +84,7 @@ export function getUserProfile() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 淇敼鐢ㄦ埛涓汉淇℃伅
|
// 修改用户个人信息
|
||||||
export function updateUserProfile(data) {
|
export function updateUserProfile(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/profile',
|
url: '/system/user/profile',
|
||||||
|
|
@ -93,7 +93,7 @@ export function updateUserProfile(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鐢ㄦ埛瀵嗙爜閲嶇疆
|
// 用户密码重置
|
||||||
export function updateUserPwd(data) {
|
export function updateUserPwd(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/profile/resetPwd',
|
url: '/system/user/profile/resetPwd',
|
||||||
|
|
@ -103,7 +103,7 @@ export function updateUserPwd(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鐢ㄦ埛澶村儚涓婁紶
|
// 用户头像上传
|
||||||
export function uploadAvatar(data) {
|
export function uploadAvatar(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/profile/updateAvatar',
|
url: '/system/user/profile/updateAvatar',
|
||||||
|
|
@ -113,20 +113,7 @@ export function uploadAvatar(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUserBotProfile() {
|
// 查询授权角色
|
||||||
return request({
|
|
||||||
url: '/system/user/profile/bot',
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generateUserBotProfile() {
|
|
||||||
return request({
|
|
||||||
url: '/system/user/profile/bot/generate',
|
|
||||||
method: 'post'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 鏌ヨ鎺堟潈瑙掕壊
|
|
||||||
export function getAuthRole(userId) {
|
export function getAuthRole(userId) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/vue/authRole/' + userId,
|
url: '/system/user/vue/authRole/' + userId,
|
||||||
|
|
@ -134,7 +121,7 @@ export function getAuthRole(userId) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 淇濆瓨鎺堟潈瑙掕壊
|
// 保存授权角色
|
||||||
export function updateAuthRole(data) {
|
export function updateAuthRole(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/authRole',
|
url: '/system/user/authRole',
|
||||||
|
|
@ -143,7 +130,7 @@ export function updateAuthRole(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋?
|
// 查询部门下拉树结构
|
||||||
export function deptTreeSelect() {
|
export function deptTreeSelect() {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/deptTree',
|
url: '/system/user/deptTree',
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { tansParams } from '@/utils/ruoyi'
|
|
||||||
|
|
||||||
// 查询仓库基础信息列表
|
// 查询仓库基础信息列表
|
||||||
export function listInfo(query) {
|
export function listInfo(query) {
|
||||||
|
|
@ -49,8 +48,6 @@ export function exportInfo(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/warehouse/info/export',
|
url: '/warehouse/info/export',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: query,
|
params: query
|
||||||
transformRequest: [(params) => tansParams(params)],
|
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 152 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
|
|
@ -104,18 +104,6 @@
|
||||||
margin-left: 1px;
|
margin-left: 1px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 固定列覆盖层:强制不透明背景 + 提升层级,防止横向滚动时内容穿透固定列
|
|
||||||
.el-table__fixed,
|
|
||||||
.el-table__fixed-right {
|
|
||||||
background-color: #fff;
|
|
||||||
z-index: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-table__fixed .el-table__cell,
|
|
||||||
.el-table__fixed-right .el-table__cell {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 表单布局 **/
|
/** 表单布局 **/
|
||||||
|
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<el-dialog :visible.sync="pdfPreviewVisible" width="80%" append-to-body top="5vh" title="PDF预览">
|
|
||||||
<iframe :src="currentPdfUrl" width="100%" height="600px" frameborder="0"></iframe>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="imagePreviewVisible" width="60%" append-to-body top="5vh" title="图片预览">
|
|
||||||
<img :src="currentImageUrl" style="width: 100%;max-height: 60vh" />
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import request from '@/utils/request';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "GlobalFilePreview",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
pdfPreviewVisible: false,
|
|
||||||
currentPdfUrl: '',
|
|
||||||
imagePreviewVisible: false,
|
|
||||||
currentImageUrl: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
isPdf(filePath) {
|
|
||||||
return filePath && filePath.toLowerCase().endsWith('.pdf');
|
|
||||||
},
|
|
||||||
getImageUrl(resource) {
|
|
||||||
return process.env.VUE_APP_BASE_API + "/common/download/resource?resource=" + resource;
|
|
||||||
},
|
|
||||||
handlePreview(attachment) {
|
|
||||||
if (!attachment) return;
|
|
||||||
if (this.isPdf(attachment.filePath)) {
|
|
||||||
request({
|
|
||||||
url: '/common/download/resource',
|
|
||||||
method: 'get',
|
|
||||||
params: { resource: attachment.filePath },
|
|
||||||
responseType: 'blob'
|
|
||||||
}).then(res => {
|
|
||||||
const blob = new Blob([res.data], { type: 'application/pdf' });
|
|
||||||
this.currentPdfUrl = URL.createObjectURL(blob);
|
|
||||||
this.pdfPreviewVisible = true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.currentImageUrl = this.getImageUrl(attachment.filePath);
|
|
||||||
this.imagePreviewVisible = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
downloadFile(attachment){
|
|
||||||
if (attachment){
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = process.env.VUE_APP_BASE_API + "/common/download/resource?resource=" +attachment.filePath;
|
|
||||||
link.download = attachment.fileName || 'file';
|
|
||||||
link.style.display = 'none';
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -183,8 +183,4 @@ export default {
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
margin: 3px auto;
|
margin: 3px auto;
|
||||||
}
|
}
|
||||||
.el-dropdown-menu{
|
|
||||||
max-height: 400px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
<logo v-if="showLogo" :collapse="isCollapse" />
|
<logo v-if="showLogo" :collapse="isCollapse" />
|
||||||
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
|
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
|
||||||
<el-menu
|
<el-menu
|
||||||
ref="sideMenu"
|
|
||||||
:default-active="activeMenu"
|
:default-active="activeMenu"
|
||||||
:collapse="isCollapse"
|
:collapse="isCollapse"
|
||||||
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
|
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
|
||||||
|
|
@ -12,8 +11,6 @@
|
||||||
:active-text-color="settings.theme"
|
:active-text-color="settings.theme"
|
||||||
:collapse-transition="false"
|
:collapse-transition="false"
|
||||||
mode="vertical"
|
mode="vertical"
|
||||||
@open="handleMenuOpen"
|
|
||||||
@close="handleMenuClose"
|
|
||||||
>
|
>
|
||||||
<sidebar-item
|
<sidebar-item
|
||||||
v-for="(route, index) in sidebarRouters"
|
v-for="(route, index) in sidebarRouters"
|
||||||
|
|
@ -27,7 +24,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import pathLib from 'path'
|
|
||||||
import { mapGetters, mapState } from "vuex"
|
import { mapGetters, mapState } from "vuex"
|
||||||
import Logo from "./Logo"
|
import Logo from "./Logo"
|
||||||
import SidebarItem from "./SidebarItem"
|
import SidebarItem from "./SidebarItem"
|
||||||
|
|
@ -56,55 +52,6 @@ export default {
|
||||||
isCollapse() {
|
isCollapse() {
|
||||||
return !this.sidebar.opened
|
return !this.sidebar.opened
|
||||||
}
|
}
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 监听菜单折叠事件:当折叠"进销存管理"时同步折叠"出库管理"子菜单
|
|
||||||
handleMenuClose(index) {
|
|
||||||
// 在一级路由中找到当前折叠的菜单
|
|
||||||
const closedRoute = this.sidebarRouters.find(route => route.path === index)
|
|
||||||
if (!closedRoute || !closedRoute.children || !closedRoute.children.length) return
|
|
||||||
|
|
||||||
// 找到直属子级中名为"出库管理"的子菜单
|
|
||||||
const outerRoute = closedRoute.children.find(
|
|
||||||
child => !child.hidden && child.meta && child.meta.title === '出库管理'
|
|
||||||
)
|
|
||||||
if (!outerRoute) return
|
|
||||||
|
|
||||||
// 计算"出库管理"在 el-menu 中注册的 index(与展开逻辑保持一致)
|
|
||||||
const outerBasePath = pathLib.resolve(index, outerRoute.path)
|
|
||||||
const outerIndex = pathLib.resolve(outerBasePath, outerRoute.path)
|
|
||||||
|
|
||||||
if (this.$refs.sideMenu) {
|
|
||||||
this.$refs.sideMenu.close(outerIndex)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 监听菜单展开事件:当展开的菜单含有"出库管理"子菜单时同步将其展开
|
|
||||||
handleMenuOpen(index) {
|
|
||||||
// 在一级路由中找到当前展开的菜单
|
|
||||||
const openedRoute = this.sidebarRouters.find(route => route.path === index)
|
|
||||||
if (!openedRoute || !openedRoute.children || !openedRoute.children.length) return
|
|
||||||
|
|
||||||
// 找到直属子级中名为"出库管理"且自身含子项的子菜单
|
|
||||||
const outerRoute = openedRoute.children.find(
|
|
||||||
child => !child.hidden && child.meta && child.meta.title === '出库管理'
|
|
||||||
)
|
|
||||||
if (!outerRoute) return
|
|
||||||
|
|
||||||
// 计算"出库管理"对应的 el-menu index
|
|
||||||
// SidebarItem 渲染嵌套菜单时:
|
|
||||||
// 先将 basePath 设为 path.resolve(parentPath, child.path)
|
|
||||||
// 再以新 basePath 计算 el-submenu :index = path.resolve(basePath, child.path)
|
|
||||||
// 因此需要对 child.path 做两次 resolve 才能与注册 index 对齐
|
|
||||||
const outerBasePath = pathLib.resolve(index, outerRoute.path)
|
|
||||||
const outerIndex = pathLib.resolve(outerBasePath, outerRoute.path)
|
|
||||||
|
|
||||||
// 延迟 300ms 展开,确保 el-submenu 子组件已完成挂载并向 el-menu 注册
|
|
||||||
setTimeout(() => {
|
|
||||||
if (this.$refs.sideMenu) {
|
|
||||||
this.$refs.sideMenu.open(outerIndex)
|
|
||||||
}
|
|
||||||
}, 300)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import './permission' // permission control
|
||||||
import { getDicts } from "@/api/system/dict/data"
|
import { getDicts } from "@/api/system/dict/data"
|
||||||
import { getConfigKey } from "@/api/system/config"
|
import { getConfigKey } from "@/api/system/config"
|
||||||
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"
|
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"
|
||||||
import { formatCurrency } from "@/utils"
|
|
||||||
// 分页组件
|
// 分页组件
|
||||||
import Pagination from "@/components/Pagination"
|
import Pagination from "@/components/Pagination"
|
||||||
// 自定义表格工具组件
|
// 自定义表格工具组件
|
||||||
|
|
@ -43,7 +42,6 @@ import DictData from '@/components/DictData'
|
||||||
Vue.prototype.getDicts = getDicts
|
Vue.prototype.getDicts = getDicts
|
||||||
Vue.prototype.getConfigKey = getConfigKey
|
Vue.prototype.getConfigKey = getConfigKey
|
||||||
Vue.prototype.parseTime = parseTime
|
Vue.prototype.parseTime = parseTime
|
||||||
Vue.prototype.formatCurrency = formatCurrency
|
|
||||||
Vue.prototype.resetForm = resetForm
|
Vue.prototype.resetForm = resetForm
|
||||||
Vue.prototype.addDateRange = addDateRange
|
Vue.prototype.addDateRange = addDateRange
|
||||||
Vue.prototype.selectDictLabel = selectDictLabel
|
Vue.prototype.selectDictLabel = selectDictLabel
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,12 @@ import NProgress from 'nprogress'
|
||||||
import 'nprogress/nprogress.css'
|
import 'nprogress/nprogress.css'
|
||||||
import { isPathMatch } from '@/utils/validate'
|
import { isPathMatch } from '@/utils/validate'
|
||||||
import { isRelogin } from '@/utils/request'
|
import { isRelogin } from '@/utils/request'
|
||||||
import { isServiceHost } from '@/utils/serviceHost'
|
|
||||||
|
|
||||||
NProgress.configure({ showSpinner: false })
|
NProgress.configure({ showSpinner: false })
|
||||||
|
|
||||||
const whiteList = ['/login', '/register', '/manage/service','/system/vendor/query','/system/partner/query']
|
const whiteList = ['/login', '/register', '/manage/service','/system/vendor/query','/system/partner/query']
|
||||||
|
|
||||||
const isWhiteList = (path) => {
|
const isWhiteList = (path) => {
|
||||||
if (path === '/' && isServiceHost()) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return whiteList.some(pattern => isPathMatch(pattern, path))
|
return whiteList.some(pattern => isPathMatch(pattern, path))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,13 @@ const baseURL = process.env.VUE_APP_BASE_API
|
||||||
let downloadLoadingInstance
|
let downloadLoadingInstance
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
download(name, isDelete = true) {
|
name(name, isDelete = true) {
|
||||||
var url = baseURL + "/common/download?fileName=" + encodeURIComponent(name) + "&delete=" + isDelete
|
var url = baseURL + "/common/download?fileName=" + encodeURIComponent(name) + "&delete=" + isDelete
|
||||||
axios({
|
axios({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url: url,
|
url: url,
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
|
headers: { 'Authorization': 'Bearer ' + getToken() }
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
const isBlob = blobValidate(res.data)
|
const isBlob = blobValidate(res.data)
|
||||||
if (isBlob) {
|
if (isBlob) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Router from 'vue-router'
|
import Router from 'vue-router'
|
||||||
import { isServiceHost } from '@/utils/serviceHost'
|
|
||||||
|
|
||||||
Vue.use(Router)
|
Vue.use(Router)
|
||||||
|
|
||||||
|
|
@ -63,10 +62,10 @@ export const constantRoutes = [
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: isServiceHost() ? '/admin-root' : '',
|
path: '',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: isServiceHost() ? undefined : 'index',
|
redirect: 'index',
|
||||||
children: isServiceHost() ? [] : [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/index'),
|
component: () => import('@/views/index'),
|
||||||
|
|
@ -95,46 +94,6 @@ export const constantRoutes = [
|
||||||
component: () => import('@/views/approve/approved_order/index'),
|
component: () => import('@/views/approve/approved_order/index'),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'paymentLog',
|
|
||||||
component: () => import('@/views/approve/finance/payment/approved/index'),
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'paymentRedLog',
|
|
||||||
component: () => import('@/views/approve/finance/paymentRefund/approved/index'),
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'invoiceRedLog',
|
|
||||||
component: () => import('@/views/approve/finance/invoiceRed/approved/index'),
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'invoiceLog',
|
|
||||||
component: () => import('@/views/approve/finance/invoiceReceipt/approved/index'),
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'receiptLog',
|
|
||||||
component: () => import('@/views/approve/finance/receipt/approved/index.vue'),
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'receiptRefoundLog',
|
|
||||||
component: () => import('@/views/approve/finance/receiptRefound/approved/index.vue'),
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'receivableInvoiceLog',
|
|
||||||
component: () => import('@/views/approve/finance/receivableInvoice/approved/index.vue'),
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'receivableInvoiceRefundLog',
|
|
||||||
component: () => import('@/views/approve/finance/receivableInvoiceRefund/approved/index.vue'),
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -153,11 +112,6 @@ export const constantRoutes = [
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
path: isServiceHost() ? '/' : '/service-host-root',
|
|
||||||
component: () => import('@/views/manage/service/index'),
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/manage/service',
|
path: '/manage/service',
|
||||||
component: () => import('@/views/manage/service/index'),
|
component: () => import('@/views/manage/service/index'),
|
||||||
|
|
@ -210,31 +164,6 @@ export const dynamicRoutes = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/finance',
|
|
||||||
component: Layout,
|
|
||||||
redirect: 'noRedirect',
|
|
||||||
name: 'Finance',
|
|
||||||
meta: {
|
|
||||||
title: '财务管理',
|
|
||||||
icon: 'money'
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'payment',
|
|
||||||
component: () => import('@/views/finance/payment/index'),
|
|
||||||
name: 'Payment',
|
|
||||||
meta: { title: '付款单', icon: 'form' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'charge',
|
|
||||||
component: () => import('@/views/finance/charge/index'),
|
|
||||||
name: 'Charge',
|
|
||||||
meta: { title: '财务计收', icon: 'money' },
|
|
||||||
permissions: ['finance:charge:list']
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/inventory/execution',
|
path: '/inventory/execution',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ const user = {
|
||||||
const rememberMe = userInfo.rememberMe
|
const rememberMe = userInfo.rememberMe
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
login(username, password, code, rememberMe).then(res => {
|
login(username, password, code, rememberMe).then(res => {
|
||||||
resolve(res)
|
resolve()
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
reject(error)
|
reject(error)
|
||||||
})
|
})
|
||||||
|
|
@ -60,16 +60,17 @@ const user = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
GetInfo({ commit }) {
|
GetInfo({ commit, state }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
getInfo().then(res => {
|
getInfo().then(res => {
|
||||||
|
// 后端返回的数据在 res.data 中
|
||||||
const data = res.data || res
|
const data = res.data || res
|
||||||
const user = data.user
|
const user = data.user
|
||||||
let avatar = user.avatar? '/common/download/resource?resource='+encodeURIComponent(user.avatar) : ""
|
let avatar = user.avatar? '/common/download/resource?resource='+encodeURIComponent(user.avatar) : ""
|
||||||
if (!isHttp(avatar)) {
|
if (!isHttp(avatar)) {
|
||||||
avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar
|
avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar
|
||||||
}
|
}
|
||||||
if (data.roles && data.roles.length > 0) {
|
if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
|
||||||
commit('SET_ROLES', data.roles)
|
commit('SET_ROLES', data.roles)
|
||||||
commit('SET_PERMISSIONS', data.permissions)
|
commit('SET_PERMISSIONS', data.permissions)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -81,11 +82,13 @@ const user = {
|
||||||
commit('SET_NAME', user.loginName)
|
commit('SET_NAME', user.loginName)
|
||||||
commit('SET_NICK_NAME', user.userName)
|
commit('SET_NICK_NAME', user.userName)
|
||||||
commit('SET_AVATAR', avatar)
|
commit('SET_AVATAR', avatar)
|
||||||
|
/* 初始密码提示 */
|
||||||
if(data.isDefaultModifyPwd) {
|
if(data.isDefaultModifyPwd) {
|
||||||
MessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
MessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
||||||
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
|
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
|
/* 过期密码提示 */
|
||||||
if(!data.isDefaultModifyPwd && data.isPasswordExpired) {
|
if(!data.isDefaultModifyPwd && data.isPasswordExpired) {
|
||||||
MessageBox.confirm('您的密码已过期,请尽快修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
MessageBox.confirm('您的密码已过期,请尽快修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
||||||
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
|
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
|
||||||
|
|
@ -99,7 +102,7 @@ const user = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// 退出系统 - 基于 Session 认证
|
// 退出系统 - 基于 Session 认证
|
||||||
LogOut({ commit }) {
|
LogOut({ commit, state }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
logout().then(() => {
|
logout().then(() => {
|
||||||
commit('SET_ROLES', [])
|
commit('SET_ROLES', [])
|
||||||
|
|
|
||||||
|
|
@ -19,17 +19,17 @@ export function toFixed(value, dp = DEFAULT_DP) {
|
||||||
|
|
||||||
// 加法
|
// 加法
|
||||||
export function add(a, b, dp = DEFAULT_DP) {
|
export function add(a, b, dp = DEFAULT_DP) {
|
||||||
return D(a).plus(D(b)).toDecimalPlaces(dp).toNumber()
|
return D(a).plus(b).toDecimalPlaces(dp).toNumber()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 减法
|
// 减法
|
||||||
export function sub(a, b, dp = DEFAULT_DP) {
|
export function sub(a, b, dp = DEFAULT_DP) {
|
||||||
return D(a).minus(D(b)).toDecimalPlaces(dp).toNumber()
|
return D(a).minus(b).toDecimalPlaces(dp).toNumber()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 乘法
|
// 乘法
|
||||||
export function mul(a, b, dp = DEFAULT_DP) {
|
export function mul(a, b, dp = DEFAULT_DP) {
|
||||||
return D(a).times(D(b)).toDecimalPlaces(dp).toNumber()
|
return D(a).times(b).toDecimalPlaces(dp).toNumber()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 除法
|
// 除法
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,7 @@ export function formatDate(cellValue) {
|
||||||
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
|
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
|
||||||
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
|
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
|
||||||
}
|
}
|
||||||
export function formatCurrency(value) {
|
|
||||||
if (value == null) return '0.00';
|
|
||||||
return Number(value).toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2});
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @param {number} time
|
* @param {number} time
|
||||||
* @param {string} option
|
* @param {string} option
|
||||||
|
|
|
||||||
|
|
@ -110,8 +110,6 @@ service.interceptors.response.use(res => {
|
||||||
} else if (code === 601) {
|
} else if (code === 601) {
|
||||||
Message({ message: msg, type: 'warning' })
|
Message({ message: msg, type: 'warning' })
|
||||||
return Promise.reject('error')
|
return Promise.reject('error')
|
||||||
} else if (code === 301 && res.config.headers && res.config.headers.allowWarning) {
|
|
||||||
return res.data
|
|
||||||
} else if (code !== 200) {
|
} else if (code !== 200) {
|
||||||
Notification.error({ title: msg })
|
Notification.error({ title: msg })
|
||||||
return Promise.reject('error')
|
return Promise.reject('error')
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
const serviceHosts = (process.env.VUE_APP_SERVICE_HOST || '')
|
|
||||||
.split(',')
|
|
||||||
.map(host => host.trim().toLowerCase())
|
|
||||||
.filter(Boolean)
|
|
||||||
|
|
||||||
export function isServiceHost(hostname) {
|
|
||||||
const currentHost = (hostname || (typeof window !== 'undefined' ? window.location.hostname : '') || '')
|
|
||||||
.trim()
|
|
||||||
.toLowerCase()
|
|
||||||
|
|
||||||
return currentHost !== '' && serviceHosts.includes(currentHost)
|
|
||||||
}
|
|
||||||
|
|
@ -1,359 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-dialog
|
|
||||||
title="订单撤回审批"
|
|
||||||
:visible="dialogVisible"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
width="80%"
|
|
||||||
top="5vh"
|
|
||||||
append-to-body
|
|
||||||
@update:visible="handleVisibleChange"
|
|
||||||
>
|
|
||||||
<div v-loading="loading" style="max-height: 70vh; overflow-y: auto;">
|
|
||||||
<div class="approve-container">
|
|
||||||
<ApproveLayout ref="approveLayout" title="紫光汇智信息技术有限公司">
|
|
||||||
<template #default>
|
|
||||||
<div style="display: flex;align-items: center;justify-content: center;">
|
|
||||||
<span style="margin-left: 10px;color: black;font-size: 30px">
|
|
||||||
紫光汇智信息技术有限公司订单撤回审批
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<el-form ref="orderForm" :model="order" label-width="120px" class="mb20">
|
|
||||||
<h3 class="section-title">订单信息</h3>
|
|
||||||
<order-info-display
|
|
||||||
:order-data.sync="order"
|
|
||||||
/>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<h3 class="section-title">配置信息</h3>
|
|
||||||
<config-info
|
|
||||||
:order-data="order"
|
|
||||||
class="mb20"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #footer>
|
|
||||||
<p>{{ order.projectCode }}-{{ order.orderCode }}-Rev.{{ order.versionCode }}</p>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
|
|
||||||
<!-- 撤单信息 -->
|
|
||||||
<el-form label-width="120px" class="mb20">
|
|
||||||
<h3 class="section-title">撤单信息</h3>
|
|
||||||
<el-form-item label="撤单原因:">
|
|
||||||
<el-input :value="reason" readonly type="textarea" :rows="2" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="金额是否变化:">
|
|
||||||
<el-input :value="amountChanged || '—'" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="出库状态:">
|
|
||||||
<dict-tag :options="dict.type.execution_outer_status" :value="order.outerStatus"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="发货状态:">
|
|
||||||
<dict-tag :options="dict.type.execution_delivery_status" :value="order.deliveryStatus"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="签收状态:">
|
|
||||||
<dict-tag :options="dict.type.execution_sign_status" :value="order.signStatus"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<!-- 流转过程 -->
|
|
||||||
<el-tabs v-model="activeTab" class="approve-tabs">
|
|
||||||
<el-tab-pane label="流转过程" name="process">
|
|
||||||
<div class="process-container">
|
|
||||||
<el-tabs :value="activeVersionTab" @input="handleVersionTabChange" type="card" v-if="uniqueVersions.length > 0">
|
|
||||||
<el-tab-pane
|
|
||||||
v-for="version in uniqueVersions"
|
|
||||||
:key="version"
|
|
||||||
:label="'版本号Rev.' + version"
|
|
||||||
:name="version">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item
|
|
||||||
v-for="log in groupedApproveLogs[version]"
|
|
||||||
:key="log.id"
|
|
||||||
:timestamp="log.approveTime"
|
|
||||||
placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }}</p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="getStatusTagType(log.approveStatus)" size="small">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
<div v-else>暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer" v-if="showApprove && taskId">
|
|
||||||
<el-button @click="handleVisibleChange(false)">取 消</el-button>
|
|
||||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳 回</el-button>
|
|
||||||
<el-button type="primary" @click="openOpinionDialog('approve')">同 意</el-button>
|
|
||||||
</span>
|
|
||||||
<span slot="footer" class="dialog-footer" v-else>
|
|
||||||
<el-button @click="handleVisibleChange(false)">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<!-- 审批意见对话框 -->
|
|
||||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="500px" append-to-body :close-on-click-modal="false" :close-on-press-escape="false">
|
|
||||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
|
||||||
<el-form-item label="审批意见" prop="approveOpinion">
|
|
||||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见" :disabled="submitLoading"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="opinionDialogVisible = false" :disabled="submitLoading">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="showConfirmDialog" :loading="submitLoading">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getOrder } from '@/api/approve/order/index'
|
|
||||||
import { listCompletedFlows, listApplyFlows, approveTask } from '@/api/flow'
|
|
||||||
import ConfigInfo from '@/views/approve/order/ConfigInfo.vue'
|
|
||||||
import ApproveLayout from '@/views/approve/ApproveLayout.vue'
|
|
||||||
import OrderInfoDisplay from '@/views/project/order/components/OrderInfoDisplay.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'OrderRebackDetail',
|
|
||||||
dicts: ['execution_outer_status', 'execution_delivery_status', 'execution_sign_status'],
|
|
||||||
components: {
|
|
||||||
ApproveLayout,
|
|
||||||
OrderInfoDisplay,
|
|
||||||
ConfigInfo
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 订单id,用于获取订单详情
|
|
||||||
orderId: {
|
|
||||||
type: [Number, String],
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
// 合同编号(流程businessKey),用于查询审批流转记录
|
|
||||||
orderCode: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
processKey: {
|
|
||||||
type: String,
|
|
||||||
default: 'order_reback'
|
|
||||||
},
|
|
||||||
// 当前审批任务id,为空表示仅查看
|
|
||||||
taskId: {
|
|
||||||
type: [Number, String],
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
// 是否显示审批按钮(由父组件控制,如当前用户是否为审批人)
|
|
||||||
showApprove: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
dialogVisible: false,
|
|
||||||
loading: false,
|
|
||||||
order: {},
|
|
||||||
logs: [],
|
|
||||||
reason: '',
|
|
||||||
amountChanged: '',
|
|
||||||
activeTab: 'process',
|
|
||||||
activeVersionTab: null,
|
|
||||||
confirmDialogTitle: '',
|
|
||||||
opinionDialogVisible: false,
|
|
||||||
currentApproveType: null,
|
|
||||||
submitLoading: false,
|
|
||||||
opinionForm: { approveOpinion: '' },
|
|
||||||
opinionRules: {
|
|
||||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 获取所有唯一的版本号
|
|
||||||
uniqueVersions() {
|
|
||||||
if (!this.logs || this.logs.length === 0) return []
|
|
||||||
const versions = [...new Set(this.logs.map(log => log.extendField1))].filter(v => v !== null && v !== undefined && v !== '')
|
|
||||||
return versions.sort((a, b) => b - a) // 降序排列
|
|
||||||
},
|
|
||||||
// 按版本号分组的审批记录
|
|
||||||
groupedApproveLogs() {
|
|
||||||
if (!this.logs || this.logs.length === 0) return {}
|
|
||||||
return this.logs.reduce((acc, log) => {
|
|
||||||
const version = log.extendField1
|
|
||||||
if (!acc[version]) acc[version] = []
|
|
||||||
acc[version].push(log)
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible(val) {
|
|
||||||
this.dialogVisible = val
|
|
||||||
if (val) {
|
|
||||||
this.loadDetail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 同步弹窗显隐到父组件,避免直接修改 prop
|
|
||||||
handleVisibleChange(val) {
|
|
||||||
this.dialogVisible = val
|
|
||||||
this.$emit('update:visible', val)
|
|
||||||
},
|
|
||||||
// 加载订单详情、撤单原因、流转意见
|
|
||||||
loadDetail() {
|
|
||||||
this.loading = true
|
|
||||||
this.order = {}
|
|
||||||
this.logs = []
|
|
||||||
this.reason = ''
|
|
||||||
this.amountChanged = ''
|
|
||||||
this.activeVersionTab = null
|
|
||||||
if (!this.orderId) {
|
|
||||||
this.loading = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
getOrder(this.orderId).then(response => {
|
|
||||||
const data = response.data || {}
|
|
||||||
this.order = data.projectOrderInfo || {}
|
|
||||||
const businessKey = this.order.orderCode || this.orderCode
|
|
||||||
this.loadFlows(businessKey)
|
|
||||||
}).catch(error => {
|
|
||||||
console.error('获取订单详情失败: ', error)
|
|
||||||
this.$modal.msgError('获取订单详情失败!')
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
loadFlows(businessKey) {
|
|
||||||
const processKeyList = this.processKey ? [this.processKey] : ['order_reback']
|
|
||||||
listCompletedFlows({ businessKey: businessKey, processKeyList }).then(res => {
|
|
||||||
this.logs = res.data || []
|
|
||||||
// 撤单原因存储于流程记录的扩展字段 extendField2,金额是否变化存储于 extendField3(extendField1 为订单版本号)
|
|
||||||
const applyLog = this.logs.find(log => log.extendField2)
|
|
||||||
if (applyLog) {
|
|
||||||
this.reason = applyLog.extendField2
|
|
||||||
this.amountChanged = applyLog.extendField3 || ''
|
|
||||||
} else {
|
|
||||||
// 审批中首节点已办表可能无记录,从待办表补充查询
|
|
||||||
listApplyFlows({ businessKey: businessKey, processKey: this.processKey }).then(todoRes => {
|
|
||||||
const todoList = todoRes.data || []
|
|
||||||
const apply = todoList.find(item => item.extendField2)
|
|
||||||
this.reason = apply ? apply.extendField2 : ''
|
|
||||||
this.amountChanged = apply ? (apply.extendField3 || '') : ''
|
|
||||||
}).catch(() => {})
|
|
||||||
}
|
|
||||||
if (this.uniqueVersions.length > 0) {
|
|
||||||
this.activeVersionTab = String(this.uniqueVersions[0])
|
|
||||||
}
|
|
||||||
this.loading = false
|
|
||||||
}).catch(() => {
|
|
||||||
this.logs = []
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
openOpinionDialog(type) {
|
|
||||||
this.currentApproveType = type
|
|
||||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批'
|
|
||||||
this.opinionForm.approveOpinion = ''
|
|
||||||
this.opinionDialogVisible = true
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.opinionForm && this.$refs.opinionForm.clearValidate()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showConfirmDialog() {
|
|
||||||
this.$refs.opinionForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
this.opinionDialogVisible = false
|
|
||||||
this.submitApproval()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
submitApproval() {
|
|
||||||
this.submitLoading = true
|
|
||||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0
|
|
||||||
const params = {
|
|
||||||
businessKey: this.order.orderCode || this.orderCode,
|
|
||||||
processKey: this.processKey,
|
|
||||||
taskId: this.taskId,
|
|
||||||
variables: {
|
|
||||||
comment: this.opinionForm.approveOpinion,
|
|
||||||
approveBtn: approveBtn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
approveTask(params).then(() => {
|
|
||||||
this.submitLoading = false
|
|
||||||
this.$modal.msgSuccess(this.confirmDialogTitle + '成功')
|
|
||||||
this.handleVisibleChange(false)
|
|
||||||
this.$emit('success')
|
|
||||||
}).catch(error => {
|
|
||||||
this.submitLoading = false
|
|
||||||
console.error('审批失败: ', error)
|
|
||||||
this.$modal.msgError('审批失败!' + (error.msg || error.message))
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getStatusTagType(status) {
|
|
||||||
const typeMap = {
|
|
||||||
'1': 'info', // 提交审批
|
|
||||||
'2': 'danger', // 驳回
|
|
||||||
'3': 'success' // 批准
|
|
||||||
}
|
|
||||||
return typeMap[String(status)] || 'info'
|
|
||||||
},
|
|
||||||
// 内层版本Tab切换:仅接受日志中存在的版本号,避免空值/非法值回写造成渲染循环
|
|
||||||
handleVersionTabChange(val) {
|
|
||||||
if (val !== null && val !== undefined && val !== '' && this.uniqueVersions.includes(val)) {
|
|
||||||
this.activeVersionTab = val
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
const textMap = { '1': '提交审批', '2': '驳回', '3': '批准' }
|
|
||||||
return textMap[String(status)] || '提交审批'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.section-title {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mb20 {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tab样式 */
|
|
||||||
.approve-tabs {
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 流转过程容器 */
|
|
||||||
.process-container {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 审批意见弹窗样式 */
|
|
||||||
::v-deep .el-dialog__body {
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,312 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-dialog
|
|
||||||
title="出库撤回审批"
|
|
||||||
:visible="dialogVisible"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
width="80%"
|
|
||||||
top="5vh"
|
|
||||||
append-to-body
|
|
||||||
destroy-on-close
|
|
||||||
@update:visible="handleVisibleChange"
|
|
||||||
>
|
|
||||||
<div v-loading="loading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<el-form label-width="110px">
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="出库单号:">
|
|
||||||
<el-input :value="form.outerCode" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="物流单号:">
|
|
||||||
<el-input :value="form.logisticsCode" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="物流公司:">
|
|
||||||
<el-input :value="form.logisticsCompany" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="仓库:">
|
|
||||||
<el-input :value="form.warehouseName" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="发货时间:">
|
|
||||||
<el-input :value="form.deliveryTime" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="发货数量:">
|
|
||||||
<el-input :value="form.quantity" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="收货地址:">
|
|
||||||
<el-input :value="form.notifierAddress" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="撤回原因:">
|
|
||||||
<el-input :value="reason" readonly type="textarea" :rows="2" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="金额是否变化:">
|
|
||||||
<el-input :value="amountChanged || '—'" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-divider content-position="left">SN码列表</el-divider>
|
|
||||||
<el-table v-loading="snLoading" :data="snList" border size="mini">
|
|
||||||
<el-table-column type="index" label="序号" align="center" width="60" />
|
|
||||||
<el-table-column label="SN码" align="center" prop="productSn"/>
|
|
||||||
<el-table-column label="授权码" align="center" prop="licenseKey"/>
|
|
||||||
<el-table-column label="产品编码" align="center" prop="productCode"/>
|
|
||||||
<el-table-column label="产品型号" align="center" prop="model"/>
|
|
||||||
<el-table-column label="描述" align="center" prop="productDesc"/>
|
|
||||||
<el-table-column label="仓库" align="center" prop="warehouseName"/>
|
|
||||||
</el-table>
|
|
||||||
<pagination v-show="snTotal>0" :total="snTotal" :page.sync="snQueryParams.pageNum" :limit.sync="snQueryParams.pageSize" @pagination="getSnList"/>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="log in logs" :key="log.id" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }}</p>
|
|
||||||
<p><b>审批状态:</b>
|
|
||||||
<el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag>
|
|
||||||
</p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!logs || logs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer" v-if="showApprove && taskId">
|
|
||||||
<el-button @click="handleVisibleChange(false)">取 消</el-button>
|
|
||||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳 回</el-button>
|
|
||||||
<el-button type="primary" @click="openOpinionDialog('approve')">同 意</el-button>
|
|
||||||
</span>
|
|
||||||
<span slot="footer" class="dialog-footer" v-else>
|
|
||||||
<el-button @click="handleVisibleChange(false)">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<!-- 审批意见对话框 -->
|
|
||||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="30%" append-to-body>
|
|
||||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
|
||||||
<el-form-item label="审批意见" prop="approveOpinion">
|
|
||||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="opinionDialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="showConfirmDialog()">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getDelivery, listProductSn } from '@/api/inventory/delivery'
|
|
||||||
import { listCompletedFlows, listApplyFlows, approveTask } from '@/api/flow'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'OuterRebackDetail',
|
|
||||||
props: {
|
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 发货记录id,用于获取发货详情与SN码列表
|
|
||||||
deliveryId: {
|
|
||||||
type: [Number, String],
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
// 出库单号,用于查询审批流转记录
|
|
||||||
outerCode: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
processKey: {
|
|
||||||
type: String,
|
|
||||||
default: 'outer_reback'
|
|
||||||
},
|
|
||||||
// 当前审批任务id,为空表示仅查看
|
|
||||||
taskId: {
|
|
||||||
type: [Number, String],
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
// 是否显示审批按钮(由父组件控制,如当前用户是否为审批人)
|
|
||||||
showApprove: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
dialogVisible: false,
|
|
||||||
loading: false,
|
|
||||||
form: {},
|
|
||||||
logs: [],
|
|
||||||
reason: '',
|
|
||||||
amountChanged: '',
|
|
||||||
// SN码列表
|
|
||||||
snLoading: false,
|
|
||||||
snList: [],
|
|
||||||
snTotal: 0,
|
|
||||||
snQueryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
deliveryId: null,
|
|
||||||
// 不按状态/出库单过滤:撤回后的SN已还原为入库状态且outer_code被清空
|
|
||||||
inventoryStatus: null,
|
|
||||||
outerCode: null,
|
|
||||||
warehouseId: null,
|
|
||||||
productSnList: []
|
|
||||||
},
|
|
||||||
confirmDialogTitle: '',
|
|
||||||
opinionDialogVisible: false,
|
|
||||||
currentApproveType: null,
|
|
||||||
opinionForm: { approveOpinion: '' },
|
|
||||||
opinionRules: {
|
|
||||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible(val) {
|
|
||||||
this.dialogVisible = val
|
|
||||||
if (val) {
|
|
||||||
this.loadDetail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 同步弹窗显隐到父组件,避免直接修改 prop
|
|
||||||
handleVisibleChange(val) {
|
|
||||||
this.dialogVisible = val
|
|
||||||
this.$emit('update:visible', val)
|
|
||||||
},
|
|
||||||
// 加载发货详情、撤回原因、流转意见、SN码列表
|
|
||||||
loadDetail() {
|
|
||||||
this.loading = true
|
|
||||||
this.form = {}
|
|
||||||
this.logs = []
|
|
||||||
this.reason = ''
|
|
||||||
this.amountChanged = ''
|
|
||||||
this.snList = []
|
|
||||||
this.snTotal = 0
|
|
||||||
if (!this.deliveryId) {
|
|
||||||
this.loading = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
getDelivery(this.deliveryId).then(response => {
|
|
||||||
this.form = response.data || {}
|
|
||||||
// SN码列表查询参数(与发货单详情一致:不传 outer_code)
|
|
||||||
this.snQueryParams.deliveryId = this.deliveryId
|
|
||||||
this.snQueryParams.warehouseId = this.form.warehouseId
|
|
||||||
this.snQueryParams.productSnList = this.form.productSnList
|
|
||||||
this.getSnList()
|
|
||||||
const businessKey = this.form.outerCode || this.outerCode
|
|
||||||
this.loadFlows(businessKey)
|
|
||||||
}).catch(error => {
|
|
||||||
console.error('获取发货记录详情失败: ', error)
|
|
||||||
this.$modal.msgError('获取发货记录详情失败!')
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 查询关联SN码列表
|
|
||||||
getSnList() {
|
|
||||||
this.snLoading = true
|
|
||||||
listProductSn(this.snQueryParams).then(res => {
|
|
||||||
this.snList = res.rows
|
|
||||||
this.snTotal = res.total
|
|
||||||
this.snLoading = false
|
|
||||||
}).catch(() => {
|
|
||||||
this.snLoading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
loadFlows(businessKey) {
|
|
||||||
const processKeyList = this.processKey ? [this.processKey] : ['outer_reback']
|
|
||||||
listCompletedFlows({ businessKey: businessKey, processKeyList }).then(res => {
|
|
||||||
this.logs = res.data || []
|
|
||||||
// 申请说明存储于流程发起记录的扩展字段 extend_field1,金额是否变化存储于 extend_field3
|
|
||||||
const applyLog = this.logs.find(log => log.extendField1)
|
|
||||||
if (applyLog) {
|
|
||||||
this.reason = applyLog.extendField1
|
|
||||||
this.amountChanged = applyLog.extendField3 || ''
|
|
||||||
} else {
|
|
||||||
// 审批中首节点已办表可能无记录,从待办表补充查询
|
|
||||||
listApplyFlows({ businessKey: businessKey, processKey: this.processKey }).then(todoRes => {
|
|
||||||
const todoList = todoRes.data || []
|
|
||||||
const apply = todoList.find(item => item.extendField1)
|
|
||||||
this.reason = apply ? apply.extendField1 : ''
|
|
||||||
this.amountChanged = apply ? (apply.extendField3 || '') : ''
|
|
||||||
}).catch(() => {})
|
|
||||||
}
|
|
||||||
this.loading = false
|
|
||||||
}).catch(() => {
|
|
||||||
this.logs = []
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
openOpinionDialog(type) {
|
|
||||||
this.currentApproveType = type
|
|
||||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批'
|
|
||||||
this.opinionForm.approveOpinion = ''
|
|
||||||
this.opinionDialogVisible = true
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.opinionForm && this.$refs.opinionForm.clearValidate()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showConfirmDialog() {
|
|
||||||
this.$refs.opinionForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
this.opinionDialogVisible = false
|
|
||||||
this.submitApproval()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
submitApproval() {
|
|
||||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0
|
|
||||||
const params = {
|
|
||||||
businessKey: this.form.outerCode || this.outerCode,
|
|
||||||
processKey: this.processKey,
|
|
||||||
taskId: this.taskId,
|
|
||||||
variables: {
|
|
||||||
comment: this.opinionForm.approveOpinion,
|
|
||||||
approveBtn: approveBtn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
approveTask(params).then(() => {
|
|
||||||
this.$modal.msgSuccess(this.confirmDialogTitle + '成功')
|
|
||||||
this.handleVisibleChange(false)
|
|
||||||
this.$emit('success')
|
|
||||||
}).catch(error => {
|
|
||||||
console.error('审批失败: ', error)
|
|
||||||
this.$modal.msgError('审批失败!' + (error.msg || error.message))
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
const textMap = { '1': '提交审批', '2': '驳回', '3': '批准' }
|
|
||||||
return textMap[String(status)] || '提交审批'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -49,22 +49,6 @@
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="产品编码" prop="productCode">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.productCode"
|
|
||||||
placeholder="请输入产品编码"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="产品型号" prop="productModel">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.productModel"
|
|
||||||
placeholder="请输入产品型号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
|
@ -88,18 +72,13 @@
|
||||||
<el-table-column label="项目名称" align="center" prop="projectName" />
|
<el-table-column label="项目名称" align="center" prop="projectName" />
|
||||||
<el-table-column label="项目编号" align="center" prop="projectCode" />
|
<el-table-column label="项目编号" align="center" prop="projectCode" />
|
||||||
<el-table-column label="客户名称" align="center" prop="customerName" />
|
<el-table-column label="客户名称" align="center" prop="customerName" />
|
||||||
<el-table-column label="订单金额" align="center" prop="actualPurchaseAmount" >
|
<el-table-column label="订单金额" align="center" prop="actualPurchaseAmount" />
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ formatCurrency(scope.row.actualPurchaseAmount || scope.row.shipmentAmount) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="汇智负责人" align="center" prop="dutyName" />
|
<el-table-column label="汇智负责人" align="center" prop="dutyName" />
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode">
|
<el-table-column label="审批节点" align="center" prop="approveNode">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ scope.row.approveNode || '-' }}</span>
|
<span>{{ scope.row.approveNode || '-' }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="提交时间" align="center" prop="approveTime" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -148,7 +127,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { listOrder } from "@/api/approve/order/orderLog";
|
import { listOrder } from "@/api/approve/order/orderLog";
|
||||||
import ApproveDialog from '../order/Approve.vue';
|
import ApproveDialog from '../order/Approve.vue';
|
||||||
import {formatCurrency} from "../../../utils";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ApprovedOrder",
|
name: "ApprovedOrder",
|
||||||
|
|
@ -175,12 +153,10 @@ export default {
|
||||||
orderCode: null,
|
orderCode: null,
|
||||||
projectName: null,
|
projectName: null,
|
||||||
projectCode: null,
|
projectCode: null,
|
||||||
productCode: null,
|
|
||||||
productModel: null,
|
|
||||||
customerName: null,
|
customerName: null,
|
||||||
dutyName: null,
|
dutyName: null,
|
||||||
approveNode: null,
|
approveNode: null,
|
||||||
orderByColumn:'t1.approveTime desc, t1.id',
|
orderByColumn:'t7.todo_approve_time',
|
||||||
isAsc: 'desc'
|
isAsc: 'desc'
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -189,7 +165,6 @@ export default {
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatCurrency,
|
|
||||||
/** 查询订单列表 */
|
/** 查询订单列表 */
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
|
||||||
|
|
@ -1,259 +0,0 @@
|
||||||
function escapeHtml(value) {
|
|
||||||
return String(value == null ? "" : value)
|
|
||||||
.replace(/&/g, "&")
|
|
||||||
.replace(/</g, "<")
|
|
||||||
.replace(/>/g, ">")
|
|
||||||
.replace(/"/g, """)
|
|
||||||
.replace(/'/g, "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatCurrency(value) {
|
|
||||||
const num = Number(value);
|
|
||||||
if (Number.isNaN(num)) {
|
|
||||||
return "0.00";
|
|
||||||
}
|
|
||||||
return num.toFixed(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getProductTypeLabel(value) {
|
|
||||||
const map = {
|
|
||||||
"1": "软件",
|
|
||||||
"2": "电子计算机",
|
|
||||||
"3": "信息系统服务"
|
|
||||||
};
|
|
||||||
return map[String(value)] || "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertCurrency(money) {
|
|
||||||
const cnNums = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"];
|
|
||||||
const cnIntRadice = ["", "拾", "佰", "仟"];
|
|
||||||
const cnIntUnits = ["", "万", "亿", "兆"];
|
|
||||||
const cnDecUnits = ["角", "分", "毫", "厘"];
|
|
||||||
const cnInteger = "整";
|
|
||||||
const cnIntLast = "元";
|
|
||||||
|
|
||||||
let integerNum;
|
|
||||||
let decimalNum;
|
|
||||||
let chineseStr = "";
|
|
||||||
let parts;
|
|
||||||
|
|
||||||
if (money === "") return "";
|
|
||||||
money = parseFloat(money);
|
|
||||||
if (money >= 999999999999) return "";
|
|
||||||
if (money === 0) return cnNums[0] + cnIntLast + cnInteger;
|
|
||||||
|
|
||||||
let prefix = "";
|
|
||||||
if (money < 0) {
|
|
||||||
prefix = "(负数)";
|
|
||||||
money = Math.abs(money);
|
|
||||||
}
|
|
||||||
|
|
||||||
money = money.toString();
|
|
||||||
if (money.indexOf(".") === -1) {
|
|
||||||
integerNum = money;
|
|
||||||
decimalNum = "";
|
|
||||||
} else {
|
|
||||||
parts = money.split(".");
|
|
||||||
integerNum = parts[0];
|
|
||||||
decimalNum = parts[1].substr(0, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parseInt(integerNum, 10) > 0) {
|
|
||||||
let zeroCount = 0;
|
|
||||||
const intLen = integerNum.length;
|
|
||||||
for (let i = 0; i < intLen; i++) {
|
|
||||||
const n = integerNum.substr(i, 1);
|
|
||||||
const p = intLen - i - 1;
|
|
||||||
const q = Math.floor(p / 4);
|
|
||||||
const m = p % 4;
|
|
||||||
if (n === "0") {
|
|
||||||
zeroCount++;
|
|
||||||
} else {
|
|
||||||
if (zeroCount > 0) chineseStr += cnNums[0];
|
|
||||||
zeroCount = 0;
|
|
||||||
chineseStr += cnNums[parseInt(n, 10)] + cnIntRadice[m];
|
|
||||||
}
|
|
||||||
if (m === 0 && zeroCount < 4) chineseStr += cnIntUnits[q];
|
|
||||||
}
|
|
||||||
chineseStr += cnIntLast;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decimalNum !== "") {
|
|
||||||
const decLen = decimalNum.length;
|
|
||||||
for (let i = 0; i < decLen; i++) {
|
|
||||||
const n = decimalNum.substr(i, 1);
|
|
||||||
if (n !== "0") chineseStr += cnNums[Number(n)] + cnDecUnits[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chineseStr === "") chineseStr += cnNums[0] + cnIntLast + cnInteger;
|
|
||||||
else if (decimalNum === "") chineseStr += cnInteger;
|
|
||||||
return prefix + chineseStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getInvoiceTypeLabel(invoiceType) {
|
|
||||||
const map = {
|
|
||||||
"1": "增值税专用发票",
|
|
||||||
"2": "增值税普通发票",
|
|
||||||
"3": "电子发票"
|
|
||||||
};
|
|
||||||
return map[String(invoiceType)] || (invoiceType || "");
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildItemRows(items) {
|
|
||||||
if (!items || items.length === 0) {
|
|
||||||
return `
|
|
||||||
<tr>
|
|
||||||
<td class="cell center" colspan="12" style="height: 28px;">暂无明细</td>
|
|
||||||
</tr>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return items.map((item) => `
|
|
||||||
<tr>
|
|
||||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">${escapeHtml(getProductTypeLabel(item.productType))}</td>
|
|
||||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">${escapeHtml(item.productName)}</td>
|
|
||||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${escapeHtml(item.productModel)}</td>
|
|
||||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${escapeHtml(item.unit)}</td>
|
|
||||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${escapeHtml(item.quantity)}</td>
|
|
||||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${formatCurrency(item.price)}</td>
|
|
||||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">${formatCurrency(item.allPrice)}</td>
|
|
||||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${escapeHtml(item.taxRate)}</td>
|
|
||||||
<td class="cell center" align="center" style="text-align: center; mso-horizontal-align: center;">${formatCurrency(item.taxAmount)}</td>
|
|
||||||
</tr>
|
|
||||||
`).join("");
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildSummaryRow(items) {
|
|
||||||
let allPriceTotal = 0;
|
|
||||||
let taxTotal = 0;
|
|
||||||
(items || []).forEach((item) => {
|
|
||||||
allPriceTotal += Number(item.allPrice) || 0;
|
|
||||||
taxTotal += Number(item.taxAmount) || 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
return `
|
|
||||||
<tr>
|
|
||||||
<td class="cell center bold" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="8">合计</td>
|
|
||||||
<td class="cell center bold" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">¥${allPriceTotal.toFixed(2)}</td>
|
|
||||||
<td class="cell center bold" align="center" style="text-align: center; mso-horizontal-align: center;">-</td>
|
|
||||||
<td class="cell center bold" align="center" style="text-align: center; mso-horizontal-align: center;">¥${taxTotal.toFixed(2)}</td>
|
|
||||||
</tr>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildInvoiceExcelHtml(invoice) {
|
|
||||||
const detailItems = invoice.detailItemList || [];
|
|
||||||
const totalAmountNumber = detailItems.reduce((sum, item) => sum + (Number(item.allPrice) || 0), 0).toFixed(2);
|
|
||||||
const totalAmountChinese = convertCurrency(totalAmountNumber);
|
|
||||||
const invoiceTypeLabel = getInvoiceTypeLabel(invoice.invoiceType);
|
|
||||||
|
|
||||||
return `<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8" />
|
|
||||||
<!--[if gte mso 9]><xml>
|
|
||||||
<x:ExcelWorkbook>
|
|
||||||
<x:ExcelWorksheets>
|
|
||||||
<x:ExcelWorksheet>
|
|
||||||
<x:Name>开票信息</x:Name>
|
|
||||||
<x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions>
|
|
||||||
</x:ExcelWorksheet>
|
|
||||||
</x:ExcelWorksheets>
|
|
||||||
</x:ExcelWorkbook>
|
|
||||||
</xml><![endif]-->
|
|
||||||
<style>
|
|
||||||
table { border-collapse: collapse; width: 1200px; font-family: "Microsoft YaHei", Arial, sans-serif; color: #8B4513; }
|
|
||||||
td { border: 1px solid #8B4513; padding: 6px; font-size: 12px; vertical-align: middle; mso-vertical-align: middle; mso-wrap-style: none; }
|
|
||||||
.no-border { border: none !important; }
|
|
||||||
.title { font-size: 26px; font-weight: bold; text-align: center; border: none !important; padding: 12px 0; }
|
|
||||||
.sub-title { font-size: 18px; font-weight: bold; text-align: center; border: none !important; padding-bottom: 8px; }
|
|
||||||
.label { width: 120px; font-weight: bold; text-align: center; }
|
|
||||||
.center { text-align: center; mso-horizontal-align: center; }
|
|
||||||
.right { text-align: right; mso-horizontal-align: right; }
|
|
||||||
.bold { font-weight: bold; }
|
|
||||||
.section-head { font-weight: bold; text-align: center; background: #f8f5f0; }
|
|
||||||
.cell { height: 26px; }
|
|
||||||
.total-main { font-weight: bold; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<colgroup>
|
|
||||||
<col style="width:100px;" />
|
|
||||||
<col style="width:100px;" />
|
|
||||||
<col style="width:100px;" />
|
|
||||||
<col style="width:100px;" />
|
|
||||||
<col style="width:80px;" />
|
|
||||||
<col style="width:80px;" />
|
|
||||||
<col style="width:80px;" />
|
|
||||||
<col style="width:100px;" />
|
|
||||||
<col style="width:100px;" />
|
|
||||||
<col style="width:100px;" />
|
|
||||||
<col style="width:80px;" />
|
|
||||||
<col style="width:100px;" />
|
|
||||||
</colgroup>
|
|
||||||
<tr>
|
|
||||||
<td class="no-border" colspan="2"></td>
|
|
||||||
<td class="title" colspan="8">电子发票(${escapeHtml(invoiceTypeLabel)})</td>
|
|
||||||
<td class="no-border" colspan="2" style="text-align: left; vertical-align: middle;">
|
|
||||||
<div><span class="bold">发票号码:</span>----------</div>
|
|
||||||
<div><span class="bold">开票日期:</span>----------</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="section-head" colspan="2" rowspan="2">购买方信息</td>
|
|
||||||
<td class="label" colspan="4">名称:${escapeHtml(invoice.buyerName)}</td>
|
|
||||||
<td class="section-head" colspan="2" rowspan="2">销售方信息</td>
|
|
||||||
<td class="label" colspan="4">名称:${escapeHtml(invoice.sellerName)}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="label" colspan="4">纳税人识别号:${escapeHtml(invoice.buyerCreditCode)}</td>
|
|
||||||
<td class="label" colspan="4">纳税人识别号:${escapeHtml(invoice.sellerCreditCode)}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="section-head" colspan="2">税收大类</td>
|
|
||||||
<td class="section-head" colspan="2">项目名称</td>
|
|
||||||
<td class="section-head">规格型号</td>
|
|
||||||
<td class="section-head">单位</td>
|
|
||||||
<td class="section-head">数量</td>
|
|
||||||
<td class="section-head">单价</td>
|
|
||||||
<td class="section-head" colspan="2">金额</td>
|
|
||||||
<td class="section-head">税率%</td>
|
|
||||||
<td class="section-head">税额</td>
|
|
||||||
</tr>
|
|
||||||
${buildItemRows(detailItems)}
|
|
||||||
${buildSummaryRow(detailItems)}
|
|
||||||
<tr>
|
|
||||||
<td class="label total-main" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">价税合计(大写)</td>
|
|
||||||
<td class="total-main center" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="6">⊗ ${escapeHtml(totalAmountChinese)}</td>
|
|
||||||
<td class="label total-main" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">(小写)</td>
|
|
||||||
<td class="total-main center" align="center" style="text-align: center; mso-horizontal-align: center;" colspan="2">¥${formatCurrency(totalAmountNumber)}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="label" colspan="2">备注</td>
|
|
||||||
<td colspan="10">${escapeHtml(invoice.remark)}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="label" colspan="2">信息说明</td>
|
|
||||||
<td colspan="10">${escapeHtml(invoice.informationNote)}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function exportInvoiceInfoToExcel(invoiceData, fileName) {
|
|
||||||
const content = buildInvoiceExcelHtml(invoiceData || {});
|
|
||||||
const blob = new Blob(["\ufeff", content], {
|
|
||||||
type: "application/vnd.ms-excel;charset=utf-8;"
|
|
||||||
});
|
|
||||||
const url = URL.createObjectURL(blob);
|
|
||||||
const link = document.createElement("a");
|
|
||||||
link.href = url;
|
|
||||||
link.download = fileName || "开票单.xls";
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
URL.revokeObjectURL(url);
|
|
||||||
}
|
|
||||||
|
|
@ -1,213 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="收票编号" prop="receiptNo">
|
|
||||||
<el-input v-model="queryParams.receiptNo" placeholder="请输入收票编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="供应商" prop="vendorName">
|
|
||||||
<el-input v-model="queryParams.vendorName" placeholder="请输入供应商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="invoiceReceiptList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="收票编号" align="center" prop="ticketBillCode" />
|
|
||||||
<el-table-column label="供应商" align="center" prop="vendorName" />
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 详情对话框 -->
|
|
||||||
<el-dialog title="收票单详情" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="收票单详情">
|
|
||||||
<invoice-receipt-detail :data="form"></invoice-receipt-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span> {{ form.ticketBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listInvoiceReceiptApproved, getInvoiceReceipt } from "@/api/finance/invoiceReceipt";
|
|
||||||
import { listCompletedFlows } from "@/api/flow";
|
|
||||||
import InvoiceReceiptDetail from "../components/InvoiceReceiptDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "InvoiceReceiptApproved",
|
|
||||||
components: { InvoiceReceiptDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
invoiceReceiptList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
receiptNo: null,
|
|
||||||
vendorName: null,
|
|
||||||
processKey: 'fianance_ticket',
|
|
||||||
projectName: null,
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
currentInvoiceReceiptId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listInvoiceReceiptApproved(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.invoiceReceiptList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
handleView(row) {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.currentInvoiceReceiptId = row.id;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getInvoiceReceipt(this.currentInvoiceReceiptId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.ticketBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
listCompletedFlows({ businessKey: businessKey }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `收票单-${this.form.receiptBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,138 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="invoice-receipt-detail">
|
|
||||||
<div style="text-align: center;font-weight:bold;font-size: 25px;">收票申请单</div>
|
|
||||||
<el-descriptions title="收票单信息" :column="3" border>
|
|
||||||
<el-descriptions-item label="采购-收票单编号">{{ data.ticketBillCode }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="制造商名称">{{ data.vendorName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="票据类型">
|
|
||||||
<dict-tag :options="dict.type.finance_invoice_type" :value="data.ticketType"/>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="含税总价(元)">{{ formatCurrency(data.totalPriceWithTax) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="未税总价(元)">{{ formatCurrency(data.totalPriceWithoutTax) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="税额(元)">{{ formatCurrency(data.taxAmount) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="预计收票时间">{{ data.ticketTime }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="制造商开票时间">{{ data.vendorTicketTime }}</el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label="备注" :span="3">{{ data.remark }}</el-descriptions-item>-->
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-show="data.detailList && data.detailList.length>0">
|
|
||||||
<div class="el-descriptions__title">发票明细列表</div>
|
|
||||||
<el-table :data="data.detailList" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="payableBillCode" label="采购-应付单编号" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="productType" label="产品类型" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.product_type" :value="scope.row.productType"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="totalPriceWithTax" label="含税总价" align="center" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"></el-table-column>
|
|
||||||
<el-table-column prop="paymentAmount" label="本次收票金额" align="center" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"></el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-if="attachments && attachments.length > 0">
|
|
||||||
<div class="el-descriptions__title">附件信息</div>
|
|
||||||
<el-table :data="attachments" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column prop="fileName" label="附件名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createByName" label="上传人" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createTime" label="上传时间" align="center"></el-table-column>
|
|
||||||
<el-table-column label="操作" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handlePreview(scope.row)">预览</el-button>
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-download" @click="handleDownload(scope.row)">下载</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="pdfPreviewVisible" width="80%" append-to-body top="5vh" title="PDF预览">
|
|
||||||
<iframe :src="currentPdfUrl" width="100%" height="600px" frameborder="0"></iframe>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="imagePreviewVisible" width="60%" append-to-body top="5vh" title="图片预览">
|
|
||||||
<img :src="currentImageUrl" style="width: 100%;" />
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getInvoiceReceiptAttachments } from "@/api/finance/invoiceReceipt";
|
|
||||||
import request from '@/utils/request';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "InvoiceReceiptDetail",
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dicts: ['finance_invoice_type', 'product_type'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
attachments: [],
|
|
||||||
pdfPreviewVisible: false,
|
|
||||||
currentPdfUrl: '',
|
|
||||||
imagePreviewVisible: false,
|
|
||||||
currentImageUrl: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
'data.id': {
|
|
||||||
handler(val) {
|
|
||||||
if (val) {
|
|
||||||
this.fetchAttachments(val);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
fetchAttachments(id) {
|
|
||||||
getInvoiceReceiptAttachments(id,{ type: 'ticket' }).then(response => {
|
|
||||||
this.attachments = (response.data || []).filter(item => item.delFlag !== '2');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
isPdf(filePath) {
|
|
||||||
return filePath && filePath.toLowerCase().endsWith('.pdf');
|
|
||||||
},
|
|
||||||
getImageUrl(resource) {
|
|
||||||
return process.env.VUE_APP_BASE_API + "/common/download/resource?resource=" + resource;
|
|
||||||
},
|
|
||||||
handlePreview(row) {
|
|
||||||
if (this.isPdf(row.filePath)) {
|
|
||||||
request({
|
|
||||||
url: '/common/download/resource',
|
|
||||||
method: 'get',
|
|
||||||
params: { resource: row.filePath },
|
|
||||||
responseType: 'blob'
|
|
||||||
}).then(res => {
|
|
||||||
const blob = new Blob([res.data], { type: 'application/pdf' });
|
|
||||||
this.currentPdfUrl = URL.createObjectURL(blob);
|
|
||||||
this.pdfPreviewVisible = true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.currentImageUrl = this.getImageUrl(row.filePath);
|
|
||||||
this.imagePreviewVisible = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleDownload(row) {
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = this.getImageUrl(row.filePath);
|
|
||||||
link.download = row.fileName || 'attachment';
|
|
||||||
link.style.display = 'none';
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.invoice-receipt-detail {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,302 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="收票编号" prop="receiptNo">
|
|
||||||
<el-input v-model="queryParams.receiptNo" placeholder="请输入收票编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="供应商" prop="vendorName">
|
|
||||||
<el-input v-model="queryParams.vendorName" placeholder="请输入供应商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
size="mini"
|
|
||||||
@click="toApproved()"
|
|
||||||
>审批历史</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="invoiceReceiptList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="收票编号" align="center" prop="ticketBillCode" />
|
|
||||||
<el-table-column label="制造商" align="center" prop="vendorName" />
|
|
||||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<!-- <el-table-column label="登记人" align="center" prop="createUserName" />-->
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(scope.row)">审批</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 审批详情主对话框 -->
|
|
||||||
<el-dialog title="收票单审批" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="收票单详情">
|
|
||||||
<invoice-receipt-detail :data="form"></invoice-receipt-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span>{{ form.ticketBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b><el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="openOpinionDialog('approve')">同意</el-button>
|
|
||||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳回</el-button>
|
|
||||||
<el-button @click="detailDialogVisible = false">取 消</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 审批意见对话框 -->
|
|
||||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="30%" append-to-body>
|
|
||||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
|
||||||
<el-form-item label="审批意见" prop="approveOpinion">
|
|
||||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="opinionDialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="showConfirmDialog()">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listInvoiceReceiptApprove, getInvoiceReceipt } from "@/api/finance/invoiceReceipt";
|
|
||||||
import { approveTask, listCompletedFlows } from "@/api/flow";
|
|
||||||
import InvoiceReceiptDetail from "./components/InvoiceReceiptDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "InvoiceReceiptApprove",
|
|
||||||
components: { InvoiceReceiptDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
invoiceReceiptList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
receiptNo: null,
|
|
||||||
vendorName: null,
|
|
||||||
processKey: 'fianance_ticket',
|
|
||||||
projectName: null,
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
opinionDialogVisible: false,
|
|
||||||
confirmDialogTitle: '',
|
|
||||||
currentApproveType: '',
|
|
||||||
opinionForm: {
|
|
||||||
approveOpinion: ''
|
|
||||||
},
|
|
||||||
opinionRules: {
|
|
||||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
|
||||||
},
|
|
||||||
processKey: 'fianance_ticket',
|
|
||||||
taskId: null,
|
|
||||||
currentInvoiceReceiptId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listInvoiceReceiptApprove(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.invoiceReceiptList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
toApproved() {
|
|
||||||
this.$router.push( '/approve/invoiceLog' )
|
|
||||||
},
|
|
||||||
handleApprove(row) {
|
|
||||||
this.resetDetailForm();
|
|
||||||
this.currentInvoiceReceiptId = row.id;
|
|
||||||
this.taskId = row.taskId;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getInvoiceReceipt(this.currentInvoiceReceiptId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.ticketBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetDetailForm() {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
let keys = [];
|
|
||||||
if(this.processKey) keys.push(this.processKey);
|
|
||||||
|
|
||||||
listCompletedFlows({ businessKey: businessKey, processKeyList: keys }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openOpinionDialog(type) {
|
|
||||||
this.currentApproveType = type;
|
|
||||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批';
|
|
||||||
this.opinionDialogVisible = true;
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if(this.$refs.opinionForm) this.$refs.opinionForm.clearValidate();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showConfirmDialog() {
|
|
||||||
this.$refs.opinionForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
this.opinionDialogVisible = false;
|
|
||||||
this.submitApproval();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
submitApproval() {
|
|
||||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0;
|
|
||||||
const params = {
|
|
||||||
businessKey: this.form.ticketBillCode,
|
|
||||||
processKey: this.processKey,
|
|
||||||
taskId: this.taskId,
|
|
||||||
variables: {
|
|
||||||
comment: this.opinionForm.approveOpinion,
|
|
||||||
approveBtn: approveBtn
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
approveTask(params).then(() => {
|
|
||||||
this.$modal.msgSuccess(this.confirmDialogTitle + "成功");
|
|
||||||
this.detailDialogVisible = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
if (!status) {
|
|
||||||
return '提交审批'
|
|
||||||
}
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `收票单-${this.form.ticketBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,214 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="收票编号" prop="receiptNo">
|
|
||||||
<el-input v-model="queryParams.receiptNo" placeholder="请输入收票编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="供应商" prop="vendorName">
|
|
||||||
<el-input v-model="queryParams.vendorName" placeholder="请输入供应商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="invoiceReceiptList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="收票编号" align="center" prop="ticketBillCode" />
|
|
||||||
<el-table-column label="供应商" align="center" prop="vendorName" />
|
|
||||||
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 详情对话框 -->
|
|
||||||
<el-dialog title="红冲发票详情" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="红冲发票详情">
|
|
||||||
<invoice-red-detail :data="form"></invoice-red-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span> {{ form.ticketBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listInvoiceReceiptApproved, getInvoiceReceipt } from "@/api/finance/invoiceReceipt";
|
|
||||||
import { listCompletedFlows } from "@/api/flow";
|
|
||||||
import InvoiceRedDetail from "../components/InvoiceRedDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "InvoiceRedApproved",
|
|
||||||
components: { InvoiceRedDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
invoiceReceiptList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
receiptNo: null,
|
|
||||||
vendorName: null,
|
|
||||||
processKey: 'finance_ticket_refound',
|
|
||||||
projectName: null,
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
currentInvoiceReceiptId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listInvoiceReceiptApproved(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.invoiceReceiptList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
handleView(row) {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.currentInvoiceReceiptId = row.id;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getInvoiceReceipt(this.currentInvoiceReceiptId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.ticketBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
listCompletedFlows({ businessKey: businessKey }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `红冲发票-${this.form.receiptBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="invoice-red-detail">
|
|
||||||
<div style="text-align: center;font-weight:bold;font-size: 25px;">红冲收票申请单</div>
|
|
||||||
<el-descriptions title="红冲发票信息" :column="3" border>
|
|
||||||
<el-descriptions-item label="采购-收票单编号">{{ data.ticketBillCode }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="制造商名称">{{ data.vendorName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="票据类型">
|
|
||||||
<dict-tag :options="dict.type.finance_invoice_type" :value="data.ticketType"/>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="含税总价(元)"><span style="color: red">{{ formatCurrency(data.totalPriceWithTax) }} </span></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="未税总价(元)"><span style="color: red">{{ formatCurrency(data.totalPriceWithTax) }}</span></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="税额(元)"><span style="color: red">{{ formatCurrency(data.taxAmount) }} </span></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="收票时间">{{ data.ticketTime }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="制造商开票时间">{{ data.vendorTicketTime }}</el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label="备注" :span="3">{{ data.remark }}</el-descriptions-item>-->
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-show="data.detailList && data.detailList.length>0">
|
|
||||||
<div class="el-descriptions__title">发票明细列表</div>
|
|
||||||
<el-table :data="data.detailList" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="payableBillCode" label="采购-应付单编号" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="productType" label="产品类型" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.product_type" :value="scope.row.productType"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="totalPriceWithTax" label="含税总价" align="center" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"></el-table-column>
|
|
||||||
<el-table-column prop="paymentAmount" label="本次红冲金额" align="center" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"></el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-if="attachments && attachments.length > 0">
|
|
||||||
<div class="el-descriptions__title">附件信息</div>
|
|
||||||
<el-table :data="attachments" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column prop="fileName" label="附件名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createByName" label="上传人" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createTime" label="上传时间" align="center"></el-table-column>
|
|
||||||
<el-table-column label="操作" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handlePreview(scope.row)">预览</el-button>
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-download" @click="handleDownload(scope.row)">下载</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="pdfPreviewVisible" width="80%" append-to-body top="5vh" title="PDF预览">
|
|
||||||
<iframe :src="currentPdfUrl" width="100%" height="600px" frameborder="0"></iframe>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="imagePreviewVisible" width="60%" append-to-body top="5vh" title="图片预览">
|
|
||||||
<img :src="currentImageUrl" style="width: 100%;" />
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getInvoiceReceiptAttachments } from "@/api/finance/invoiceReceipt";
|
|
||||||
import request from '@/utils/request';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "InvoiceRedDetail",
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dicts: ['finance_invoice_type', 'product_type'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
attachments: [],
|
|
||||||
pdfPreviewVisible: false,
|
|
||||||
currentPdfUrl: '',
|
|
||||||
imagePreviewVisible: false,
|
|
||||||
currentImageUrl: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
'data.id': {
|
|
||||||
handler(val) {
|
|
||||||
if (val) {
|
|
||||||
this.fetchAttachments(val);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
fetchAttachments(id) {
|
|
||||||
// 保持调用 invoiceReceipt 的附件接口,因为接口一致
|
|
||||||
getInvoiceReceiptAttachments(id,{ type: 'ticket' }).then(response => {
|
|
||||||
this.attachments = (response.data || []).filter(item => item.delFlag !== '2');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
isPdf(filePath) {
|
|
||||||
return filePath && filePath.toLowerCase().endsWith('.pdf');
|
|
||||||
},
|
|
||||||
getImageUrl(resource) {
|
|
||||||
return process.env.VUE_APP_BASE_API + "/common/download/resource?resource=" + resource;
|
|
||||||
},
|
|
||||||
handlePreview(row) {
|
|
||||||
if (this.isPdf(row.filePath)) {
|
|
||||||
request({
|
|
||||||
url: '/common/download/resource',
|
|
||||||
method: 'get',
|
|
||||||
params: { resource: row.filePath },
|
|
||||||
responseType: 'blob'
|
|
||||||
}).then(res => {
|
|
||||||
const blob = new Blob([res.data], { type: 'application/pdf' });
|
|
||||||
this.currentPdfUrl = URL.createObjectURL(blob);
|
|
||||||
this.pdfPreviewVisible = true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.currentImageUrl = this.getImageUrl(row.filePath);
|
|
||||||
this.imagePreviewVisible = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleDownload(row) {
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = this.getImageUrl(row.filePath);
|
|
||||||
link.download = row.fileName || 'attachment';
|
|
||||||
link.style.display = 'none';
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.invoice-red-detail {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,304 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="收票编号" prop="receiptNo">
|
|
||||||
<el-input v-model="queryParams.receiptNo" placeholder="请输入收票编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="供应商" prop="vendorName">
|
|
||||||
<el-input v-model="queryParams.vendorName" placeholder="请输入供应商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
size="mini"
|
|
||||||
@click="toApproved()"
|
|
||||||
>审批历史</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="invoiceReceiptList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="收票编号" align="center" prop="ticketBillCode" />
|
|
||||||
<el-table-column label="供应商" align="center" prop="vendorName" />
|
|
||||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)">
|
|
||||||
|
|
||||||
</el-table-column>
|
|
||||||
<!-- <el-table-column label="登记人" align="center" prop="createUserName" />-->
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(scope.row)">审批</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 审批详情主对话框 -->
|
|
||||||
<el-dialog title="红冲发票审批" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="红冲发票详情">
|
|
||||||
<invoice-red-detail :data="form"></invoice-red-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span> {{ form.ticketBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="openOpinionDialog('approve')">同意</el-button>
|
|
||||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳回</el-button>
|
|
||||||
<el-button @click="detailDialogVisible = false">取 消</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 审批意见对话框 -->
|
|
||||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="30%" append-to-body>
|
|
||||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
|
||||||
<el-form-item label="审批意见" prop="approveOpinion">
|
|
||||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="opinionDialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="showConfirmDialog()">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listInvoiceReceiptApprove, getInvoiceReceipt } from "@/api/finance/invoiceReceipt";
|
|
||||||
import { approveTask, listCompletedFlows } from "@/api/flow";
|
|
||||||
import InvoiceRedDetail from "./components/InvoiceRedDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "InvoiceRedApprove",
|
|
||||||
components: { InvoiceRedDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
invoiceReceiptList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
receiptNo: null,
|
|
||||||
vendorName: null,
|
|
||||||
processKey: 'finance_ticket_refound',
|
|
||||||
projectName: null,
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
opinionDialogVisible: false,
|
|
||||||
confirmDialogTitle: '',
|
|
||||||
currentApproveType: '',
|
|
||||||
opinionForm: {
|
|
||||||
approveOpinion: ''
|
|
||||||
},
|
|
||||||
opinionRules: {
|
|
||||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
|
||||||
},
|
|
||||||
processKey: 'finance_ticket_refound',
|
|
||||||
taskId: null,
|
|
||||||
currentInvoiceReceiptId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listInvoiceReceiptApprove(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.invoiceReceiptList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
toApproved() {
|
|
||||||
this.$router.push( '/approve/invoiceRedLog' )
|
|
||||||
},
|
|
||||||
handleApprove(row) {
|
|
||||||
this.resetDetailForm();
|
|
||||||
this.currentInvoiceReceiptId = row.id;
|
|
||||||
this.taskId = row.taskId;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getInvoiceReceipt(this.currentInvoiceReceiptId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.ticketBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetDetailForm() {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
let keys = [];
|
|
||||||
if(this.processKey) keys.push(this.processKey);
|
|
||||||
|
|
||||||
listCompletedFlows({ businessKey: businessKey, processKeyList: keys }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openOpinionDialog(type) {
|
|
||||||
this.currentApproveType = type;
|
|
||||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批';
|
|
||||||
this.opinionDialogVisible = true;
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if(this.$refs.opinionForm) this.$refs.opinionForm.clearValidate();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showConfirmDialog() {
|
|
||||||
this.$refs.opinionForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
this.opinionDialogVisible = false;
|
|
||||||
this.submitApproval();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
submitApproval() {
|
|
||||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0;
|
|
||||||
const params = {
|
|
||||||
businessKey: this.form.ticketBillCode,
|
|
||||||
processKey: this.processKey,
|
|
||||||
taskId: this.taskId,
|
|
||||||
variables: {
|
|
||||||
comment: this.opinionForm.approveOpinion,
|
|
||||||
approveBtn: approveBtn
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
approveTask(params).then(() => {
|
|
||||||
this.$modal.msgSuccess(this.confirmDialogTitle + "成功");
|
|
||||||
this.detailDialogVisible = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
if (!status) {
|
|
||||||
return '提交审批'
|
|
||||||
}
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `红冲发票-${this.form.ticketBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,215 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="付款编号" prop="paymentNo">
|
|
||||||
<el-input v-model="queryParams.paymentNo" placeholder="请输入付款编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="制造商" prop="manufacturer">
|
|
||||||
<el-input v-model="queryParams.manufacturer" placeholder="请输入制造商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="paymentList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="付款编号" align="center" prop="paymentBillCode" />
|
|
||||||
<el-table-column label="制造商" align="center" prop="vendorName" />
|
|
||||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 详情对话框 -->
|
|
||||||
<el-dialog title="付款单详情" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="付款单详情">
|
|
||||||
<payment-detail :data="form"></payment-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span> {{ form.paymentBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b><el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listPaymentApproved, getPayment } from "@/api/finance/payment";
|
|
||||||
import { listCompletedFlows } from "@/api/flow";
|
|
||||||
import PaymentDetail from "../components/PaymentDetail"; // Relative path adjustment
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "PaymentApproved",
|
|
||||||
components: { PaymentDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
paymentList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
paymentNo: null,
|
|
||||||
manufacturer: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_payment',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
currentPaymentId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listPaymentApproved(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.paymentList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
handleView(row) {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.currentPaymentId = row.id;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getPayment(this.currentPaymentId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.paymentBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
listCompletedFlows({ businessKey: businessKey }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `付款单-${this.form.paymentBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,284 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="payment-detail">
|
|
||||||
<div style="text-align: center;font-weight:bold;font-size: 25px;">付款申请单</div>
|
|
||||||
<el-descriptions title="付款单信息" :column="3" border>
|
|
||||||
<el-descriptions-item label="采购-付款单编号">{{ data.paymentBillCode }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="制造商名称">{{ data.vendorName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="付款条件">
|
|
||||||
{{data.payType==='0'?'入库付款':'出库付款'}}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="付款周期">
|
|
||||||
{{data.payConfigDay}}天
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="含税总价(元)">{{ formatCurrency(data.totalPriceWithTax) }}</el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label="未税总价(元)">{{ data.totalPriceWithoutTax }}</el-descriptions-item>-->
|
|
||||||
<!-- <el-descriptions-item label="税额(元)">{{ data.taxAmount }}</el-descriptions-item>-->
|
|
||||||
<el-descriptions-item label="支付方式">
|
|
||||||
<dict-tag :options="dict.type.payment_method" :value="data.paymentMethod"/>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行账号">{{ data.payBankNumber }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="账户名称">{{ data.payName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行开户行">{{ data.payBankOpenAddress }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行行号">{{ data.bankNumber }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item span="2"></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="其它特别说明" :span="3">{{ data.remark }}</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" >
|
|
||||||
<div class="el-descriptions__title">应付单信息</div>
|
|
||||||
<el-table :data="data.payableDetails" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
|
||||||
<el-table-column label="采购单号" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<div class="purchase-no-cell">
|
|
||||||
<el-link
|
|
||||||
v-for="(purchaseItem, index) in getPurchaseNoList(scope.row.purchaseNo)"
|
|
||||||
:key="`${scope.$index}-${purchaseItem.purchaseNo}-${purchaseItem.purchaseId || ''}-${index}`"
|
|
||||||
type="primary"
|
|
||||||
:underline="false"
|
|
||||||
class="purchase-no-link"
|
|
||||||
@click="handleViewPruchaseDetail(scope.row, purchaseItem)"
|
|
||||||
>
|
|
||||||
{{ purchaseItem.purchaseNo }}
|
|
||||||
</el-link>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="采购-应付单编号" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button type="text" @click="handleViewPayable(scope.row)">{{ scope.row.payableBillCode }}</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="项目名称" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<a @click="handleViewProject(scope.row)" class="link-type">{{ scope.row.projectName }}</a>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="productCode" label="产品编码" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="model" label="产品型号" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="productName" label="产品名称" align="center"></el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;">
|
|
||||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
|
||||||
<div class="el-descriptions__title">附件信息</div>
|
|
||||||
<el-button type="success" size="mini" icon="el-icon-download" :loading="zipDownloading" @click="handleDownloadAllAttachments">一键下载附件</el-button>
|
|
||||||
</div>
|
|
||||||
<el-table :data="data.fileList" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column prop="fileName" label="附件名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createTime" label="上传时间" align="center"></el-table-column>
|
|
||||||
<el-table-column label="操作" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handlePreview(scope.row)">预览</el-button>
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-download" @click="handleDownload(scope.row)">下载</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="pdfPreviewVisible" width="80%" append-to-body top="5vh" title="PDF预览">
|
|
||||||
<iframe :src="currentPdfUrl" width="100%" height="600px" frameborder="0"></iframe>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="imagePreviewVisible" width="60%" append-to-body top="5vh" title="图片预览">
|
|
||||||
<img :src="currentImageUrl" style="width: 100%;" />
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<edit-form :visible.sync="payableVisible" :data="selectedPayableRow" :z-index="2000" @close="payableVisible = false" />
|
|
||||||
<project-detail-drawer :visible.sync="projectDrawerVisible" :project-id="currentProjectId" />
|
|
||||||
|
|
||||||
<el-drawer
|
|
||||||
title="采购单详情"
|
|
||||||
:visible.sync="showPruchaseDetailDrawer"
|
|
||||||
direction="rtl"
|
|
||||||
size="80%"
|
|
||||||
append-to-body
|
|
||||||
:modal-append-to-body="true"
|
|
||||||
:z-index="pruchaseDrawerZIndex"
|
|
||||||
>
|
|
||||||
<ApproveLayout title="采购单详情" v-if="showPruchaseDetailDrawer">
|
|
||||||
<purchase-order-detail-view
|
|
||||||
ref="pruchaseDetailView"
|
|
||||||
:order-data="pruchaseDetailOrderData"
|
|
||||||
@close="showPruchaseDetailDrawer = false"
|
|
||||||
>
|
|
||||||
</purchase-order-detail-view>
|
|
||||||
<template #footer>
|
|
||||||
<span>采购单编号: {{ pruchaseDetailOrderData ? pruchaseDetailOrderData.purchaseNo : '' }}</span>
|
|
||||||
<span v-if="pruchaseDetailOrderData"> | 版本号: {{ pruchaseDetailOrderData.version }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</el-drawer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import request from '@/utils/request';
|
|
||||||
import JSZip from 'jszip';
|
|
||||||
import { saveAs } from 'file-saver';
|
|
||||||
import { getPurchaseorder } from "@/api/sip/purchaseorder";
|
|
||||||
import {formatCurrency} from "@/utils";
|
|
||||||
import EditForm from "@/views/finance/payable/components/EditForm.vue";
|
|
||||||
import ProjectDetailDrawer from "@/views/project/info/ProjectDetailDrawer.vue";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout.vue";
|
|
||||||
import PurchaseOrderDetailView from "@/views/purchaseorder/components/PurchaseOrderDetailView.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "PaymentDetail",
|
|
||||||
components: { EditForm, ProjectDetailDrawer, ApproveLayout, PurchaseOrderDetailView },
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dicts: ['payment_bill_type', 'product_type','payment_method'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
attachments: [],
|
|
||||||
zipDownloading: false,
|
|
||||||
pdfPreviewVisible: false,
|
|
||||||
currentPdfUrl: '',
|
|
||||||
imagePreviewVisible: false,
|
|
||||||
currentImageUrl: '',
|
|
||||||
payableVisible: false,
|
|
||||||
selectedPayableRow: {},
|
|
||||||
projectDrawerVisible: false,
|
|
||||||
currentProjectId: null,
|
|
||||||
showPruchaseDetailDrawer: false,
|
|
||||||
pruchaseDetailOrderData: null,
|
|
||||||
pruchaseDrawerZIndex: 5000
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
formatCurrency,
|
|
||||||
|
|
||||||
isPdf(filePath) {
|
|
||||||
return filePath && filePath.toLowerCase().endsWith('.pdf');
|
|
||||||
},
|
|
||||||
getImageUrl(resource) {
|
|
||||||
return process.env.VUE_APP_BASE_API + "/common/download/resource?resource=" + resource;
|
|
||||||
},
|
|
||||||
handlePreview(row) {
|
|
||||||
if (this.isPdf(row.filePath)) {
|
|
||||||
// PDF Preview logic
|
|
||||||
request({
|
|
||||||
url: '/common/download/resource',
|
|
||||||
method: 'get',
|
|
||||||
params: { resource: row.filePath },
|
|
||||||
responseType: 'blob'
|
|
||||||
}).then(res => {
|
|
||||||
const blob = new Blob([res.data], { type: 'application/pdf' });
|
|
||||||
this.currentPdfUrl = URL.createObjectURL(blob);
|
|
||||||
this.pdfPreviewVisible = true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Image Preview
|
|
||||||
this.currentImageUrl = this.getImageUrl(row.filePath);
|
|
||||||
this.imagePreviewVisible = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleDownload(row) {
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = this.getImageUrl(row.filePath);
|
|
||||||
link.download = row.fileName || 'attachment';
|
|
||||||
link.style.display = 'none';
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
},
|
|
||||||
async handleDownloadAllAttachments() {
|
|
||||||
const files = Array.isArray(this.data.fileList) ? this.data.fileList : [];
|
|
||||||
if (files.length === 0) {
|
|
||||||
this.$modal.msgWarning('暂无可下载的附件');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.zipDownloading = true;
|
|
||||||
this.$modal.loading('正在打包附件,请稍候...');
|
|
||||||
try {
|
|
||||||
const zip = new JSZip();
|
|
||||||
for (const row of files) {
|
|
||||||
const blob = await request({
|
|
||||||
url: '/common/download/resource',
|
|
||||||
method: 'get',
|
|
||||||
params: { resource: row.filePath },
|
|
||||||
responseType: 'blob',
|
|
||||||
timeout: 0
|
|
||||||
}).then(res => res.data);
|
|
||||||
zip.file(row.fileName || 'file', blob);
|
|
||||||
}
|
|
||||||
const content = await zip.generateAsync({ type: 'blob' });
|
|
||||||
saveAs(content, (this.data.paymentBillCode || '付款申请单附件') + '.zip');
|
|
||||||
this.$modal.msgSuccess('下载成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('附件打包下载失败', error);
|
|
||||||
this.$modal.msgError('附件下载失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.zipDownloading = false;
|
|
||||||
this.$modal.closeLoading();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleViewPayable(row) {
|
|
||||||
row.id = row.payableBillId;
|
|
||||||
this.selectedPayableRow = row;
|
|
||||||
this.payableVisible = true;
|
|
||||||
},
|
|
||||||
handleViewProject(row) {
|
|
||||||
this.currentProjectId = row.projectId;
|
|
||||||
this.projectDrawerVisible = true;
|
|
||||||
},
|
|
||||||
getPurchaseNoList(purchaseNo) {
|
|
||||||
return (purchaseNo || '')
|
|
||||||
.split(',')
|
|
||||||
.map(item => item.trim())
|
|
||||||
.filter(Boolean)
|
|
||||||
.map(item => {
|
|
||||||
const splitIndex = item.lastIndexOf('__');
|
|
||||||
if (splitIndex === -1) {
|
|
||||||
return { purchaseNo: item, purchaseId: null };
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
purchaseNo: item.substring(0, splitIndex),
|
|
||||||
purchaseId: item.substring(splitIndex + 2)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleViewPruchaseDetail(row, purchaseItem) {
|
|
||||||
this.pruchaseDrawerZIndex += 2;
|
|
||||||
const purchaseId = purchaseItem && purchaseItem.purchaseId ? purchaseItem.purchaseId : (row.purchaseId || row.purchaseOrderId);
|
|
||||||
if (purchaseId) {
|
|
||||||
getPurchaseorder(purchaseId).then(response => {
|
|
||||||
this.pruchaseDetailOrderData = response.data;
|
|
||||||
this.showPruchaseDetailDrawer = true;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.pruchaseDetailOrderData = {
|
|
||||||
purchaseNo: (purchaseItem && purchaseItem.purchaseNo) || row.purchaseNo || '',
|
|
||||||
version: row.version || ''
|
|
||||||
};
|
|
||||||
this.showPruchaseDetailDrawer = true;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.payment-detail {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purchase-no-cell {
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purchase-no-link {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,314 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="付款编号" prop="paymentNo">
|
|
||||||
<el-input v-model="queryParams.paymentNo" placeholder="请输入付款编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="制造商" prop="manufacturer">
|
|
||||||
<el-input v-model="queryParams.manufacturer" placeholder="请输入制造商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
size="mini"
|
|
||||||
@click="toApproved()"
|
|
||||||
>审批历史</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="paymentList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="付款编号" align="center" prop="paymentBillCode" />
|
|
||||||
<el-table-column label="制造商" align="center" prop="vendorName" />
|
|
||||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)" />
|
|
||||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(scope.row)">审批</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 审批详情主对话框 -->
|
|
||||||
<el-dialog title="付款单审批" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="付款单详情">
|
|
||||||
<payment-detail :data="form"></payment-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span>付款编号: {{ form.paymentBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b>
|
|
||||||
|
|
||||||
<el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="openOpinionDialog('approve')">同意</el-button>
|
|
||||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳回</el-button>
|
|
||||||
<el-button @click="detailDialogVisible = false">取 消</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 审批意见对话框 -->
|
|
||||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="30%" append-to-body>
|
|
||||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
|
||||||
<el-form-item label="审批意见" prop="approveOpinion">
|
|
||||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="opinionDialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="showConfirmDialog()">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listPaymentApprove, getPayment } from "@/api/finance/payment";
|
|
||||||
import { approveTask, listCompletedFlows } from "@/api/flow";
|
|
||||||
import PaymentDetail from "./components/PaymentDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "PaymentApprove",
|
|
||||||
components: { PaymentDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
paymentList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
paymentNo: null,
|
|
||||||
manufacturer: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_payment',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
opinionDialogVisible: false,
|
|
||||||
confirmDialogTitle: '',
|
|
||||||
currentApproveType: '',
|
|
||||||
opinionForm: {
|
|
||||||
approveOpinion: ''
|
|
||||||
},
|
|
||||||
opinionRules: {
|
|
||||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
|
||||||
},
|
|
||||||
processKey: 'finance_payment',
|
|
||||||
taskId: null,
|
|
||||||
currentPaymentId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listPaymentApprove(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.paymentList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
toApproved() {
|
|
||||||
this.$router.push( '/approve/paymentLog' )
|
|
||||||
},
|
|
||||||
handleApprove(row) {
|
|
||||||
this.resetDetailForm();
|
|
||||||
this.currentPaymentId = row.id;
|
|
||||||
this.taskId = row.taskId;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getPayment(this.currentPaymentId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.paymentBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetDetailForm() {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
// Assuming processKeyList might be generic or specific, using generic fetch for now
|
|
||||||
// Usually need to know the specific process key. For payment, it might be 'payment_approval' etc.
|
|
||||||
// However, listCompletedFlows logic in reference used specific keys.
|
|
||||||
// If I don't know the key, maybe I can omit it or guess.
|
|
||||||
// The reference used `processKeyList: ['purchase_order_online']`.
|
|
||||||
// I will use a generic one or try to find it.
|
|
||||||
// If row.processKey is available I can use that.
|
|
||||||
let keys = [];
|
|
||||||
console.log(this.processKey)
|
|
||||||
if(this.processKey) keys.push(this.processKey);
|
|
||||||
|
|
||||||
listCompletedFlows({ businessKey: businessKey, processKeyList: keys }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openOpinionDialog(type) {
|
|
||||||
this.currentApproveType = type;
|
|
||||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批';
|
|
||||||
this.opinionDialogVisible = true;
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if(this.$refs.opinionForm) this.$refs.opinionForm.clearValidate();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showConfirmDialog() {
|
|
||||||
this.$refs.opinionForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
this.opinionDialogVisible = false;
|
|
||||||
this.submitApproval();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
submitApproval() {
|
|
||||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0;
|
|
||||||
const params = {
|
|
||||||
businessKey: this.form.paymentBillCode,
|
|
||||||
processKey: this.processKey,
|
|
||||||
taskId: this.taskId,
|
|
||||||
variables: {
|
|
||||||
comment: this.opinionForm.approveOpinion,
|
|
||||||
approveBtn: approveBtn
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
approveTask(params).then(() => {
|
|
||||||
this.$modal.msgSuccess(this.confirmDialogTitle + "成功");
|
|
||||||
this.detailDialogVisible = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
if (!status) {
|
|
||||||
return '提交审批'
|
|
||||||
}
|
|
||||||
// Map status codes to text
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `付款单-${this.form.paymentBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,219 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="付款编号" prop="paymentNo">
|
|
||||||
<el-input v-model="queryParams.paymentNo" placeholder="请输入付款编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="制造商" prop="manufacturer">
|
|
||||||
<el-input v-model="queryParams.manufacturer" placeholder="请输入制造商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="paymentList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="付款编号" align="center" prop="paymentBillCode" />
|
|
||||||
<el-table-column label="制造商" align="center" prop="vendorName" />
|
|
||||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" >
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span style="color: red">{{ formatCurrency(scope.row.totalPriceWithTax) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 详情对话框 -->
|
|
||||||
<el-dialog title="付款单详情" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="付款单详情">
|
|
||||||
<payment-detail :data="form"></payment-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span> {{ form.paymentBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listPaymentApproved, getPayment } from "@/api/finance/payment";
|
|
||||||
import { listCompletedFlows } from "@/api/flow";
|
|
||||||
import PaymentDetail from "../components/PaymentRefundDetail.vue"; // Relative path adjustment
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "PaymentApproved",
|
|
||||||
components: { PaymentDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
paymentList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
paymentNo: null,
|
|
||||||
manufacturer: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_refund',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
currentPaymentId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listPaymentApproved(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.paymentList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
handleView(row) {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.currentPaymentId = row.id;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getPayment(this.currentPaymentId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.paymentBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
listCompletedFlows({ businessKey: businessKey }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `付款单-${this.form.paymentBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="payment-refund-detail">
|
|
||||||
<div style="text-align: center;font-weight:bold;font-size: 25px;">退款申请单</div>
|
|
||||||
<el-descriptions title="付款单信息" :column="3" border>
|
|
||||||
<el-descriptions-item label="采购付款单编号">{{ data.paymentBillCode }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="制造商名称">{{ data.vendorName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="付款条件">
|
|
||||||
{{data.payType==='0'?'入库付款':'出库付款'}}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="付款周期">
|
|
||||||
{{data.payConfigDay}}天
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="含税总价(元)"><span style="color: red">{{ formatCurrency(data.totalPriceWithTax) }}</span></el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label="未税总价(元)"><span style="color: red">{{ data.totalPriceWithoutTax }}</span></el-descriptions-item>-->
|
|
||||||
<!-- <el-descriptions-item label="税额(元)"><span style="color: red">{{ data.taxAmount }}</span></el-descriptions-item>-->
|
|
||||||
<el-descriptions-item label="支付方式">
|
|
||||||
<dict-tag :options="dict.type.payment_method" :value="data.paymentMethod"/>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行账号">{{ data.payBankNumber }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="账户名称">{{ data.payName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行开户行">{{ data.payBankOpenAddress }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行行号" span="1">{{ data.bankNumber }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item span="2"></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="其它特别说明" span="3">{{ data.remark }}</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" >
|
|
||||||
<div class="el-descriptions__title">应付单信息</div>
|
|
||||||
<el-table :data="data.payableDetails" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="payableBillCode" label="采购应付单编号" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="productType" label="产品类型" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.product_type" :value="scope.row.productType"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- Note: Product Type is requested but not present in reference DetailDrawer.vue. Omitting for safety or need to ask. -->
|
|
||||||
<el-table-column prop="totalPriceWithTax" label="含税总价" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="paymentAmount" label="本次付款金额" align="center"></el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {formatCurrency} from "@/utils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "PaymentRefundDetail",
|
|
||||||
methods: {formatCurrency},
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dicts: ['payment_bill_type', 'payment_method','product_type']
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.payment-refund-detail {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,315 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="付款编号" prop="paymentNo">
|
|
||||||
<el-input v-model="queryParams.paymentNo" placeholder="请输入付款编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="制造商" prop="manufacturer">
|
|
||||||
<el-input v-model="queryParams.manufacturer" placeholder="请输入制造商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
size="mini"
|
|
||||||
@click="toApproved()"
|
|
||||||
>审批历史</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="paymentList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="付款编号" align="center" prop="paymentBillCode" />
|
|
||||||
<el-table-column label="制造商" align="center" prop="vendorName" />
|
|
||||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" >
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span style="color: red">{{ formatCurrency(scope.row.totalPriceWithTax) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(scope.row)">审批</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 审批详情主对话框 -->
|
|
||||||
<el-dialog title="付款单审批" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="付款单详情">
|
|
||||||
<payment-detail :data="form"></payment-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span>付款编号: {{ form.paymentBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="openOpinionDialog('approve')">同意</el-button>
|
|
||||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳回</el-button>
|
|
||||||
<el-button @click="detailDialogVisible = false">取 消</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 审批意见对话框 -->
|
|
||||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="30%" append-to-body>
|
|
||||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
|
||||||
<el-form-item label="审批意见" prop="approveOpinion">
|
|
||||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="opinionDialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="showConfirmDialog()">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listPaymentApprove, getPayment } from "@/api/finance/payment";
|
|
||||||
import { approveTask, listCompletedFlows } from "@/api/flow";
|
|
||||||
import PaymentDetail from "./components/PaymentRefundDetail.vue";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "PaymentApprove",
|
|
||||||
components: { PaymentDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
paymentList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
paymentNo: null,
|
|
||||||
manufacturer: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_refund',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
opinionDialogVisible: false,
|
|
||||||
confirmDialogTitle: '',
|
|
||||||
currentApproveType: '',
|
|
||||||
opinionForm: {
|
|
||||||
approveOpinion: ''
|
|
||||||
},
|
|
||||||
opinionRules: {
|
|
||||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
|
||||||
},
|
|
||||||
processKey: 'finance_refund',
|
|
||||||
taskId: null,
|
|
||||||
currentPaymentId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listPaymentApprove(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.paymentList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
toApproved() {
|
|
||||||
this.$router.push( '/approve/paymentRedLog' )
|
|
||||||
},
|
|
||||||
handleApprove(row) {
|
|
||||||
this.resetDetailForm();
|
|
||||||
this.currentPaymentId = row.id;
|
|
||||||
this.taskId = row.taskId;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getPayment(this.currentPaymentId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.paymentBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetDetailForm() {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
// Assuming processKeyList might be generic or specific, using generic fetch for now
|
|
||||||
// Usually need to know the specific process key. For payment, it might be 'payment_approval' etc.
|
|
||||||
// However, listCompletedFlows logic in reference used specific keys.
|
|
||||||
// If I don't know the key, maybe I can omit it or guess.
|
|
||||||
// The reference used `processKeyList: ['purchase_order_online']`.
|
|
||||||
// I will use a generic one or try to find it.
|
|
||||||
// If row.processKey is available I can use that.
|
|
||||||
let keys = [];
|
|
||||||
console.log(this.processKey)
|
|
||||||
if(this.processKey) keys.push(this.processKey);
|
|
||||||
|
|
||||||
listCompletedFlows({ businessKey: businessKey, processKeyList: keys }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openOpinionDialog(type) {
|
|
||||||
this.currentApproveType = type;
|
|
||||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批';
|
|
||||||
this.opinionDialogVisible = true;
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if(this.$refs.opinionForm) this.$refs.opinionForm.clearValidate();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showConfirmDialog() {
|
|
||||||
this.$refs.opinionForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
this.opinionDialogVisible = false;
|
|
||||||
this.submitApproval();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
submitApproval() {
|
|
||||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0;
|
|
||||||
const params = {
|
|
||||||
businessKey: this.form.paymentBillCode,
|
|
||||||
processKey: this.processKey,
|
|
||||||
taskId: this.taskId,
|
|
||||||
variables: {
|
|
||||||
comment: this.opinionForm.approveOpinion,
|
|
||||||
approveBtn: approveBtn
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
approveTask(params).then(() => {
|
|
||||||
this.$modal.msgSuccess(this.confirmDialogTitle + "成功");
|
|
||||||
this.detailDialogVisible = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
if (!status) {
|
|
||||||
return '提交审批'
|
|
||||||
}
|
|
||||||
// Map status codes to text
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `付款单-${this.form.paymentBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
import html2canvas from 'html2canvas';
|
|
||||||
import jsPDF from 'jspdf';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出指定DOM元素为PDF
|
|
||||||
* @param {HTMLElement} element - 要导出的DOM元素
|
|
||||||
* @param {string} fileName - 导出的文件名
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
export async function exportElementToPDF(element, fileName) {
|
|
||||||
const disabledElements = [];
|
|
||||||
try {
|
|
||||||
// 移除所有输入框的 disabled 属性,以便在PDF中正确显示
|
|
||||||
element.querySelectorAll('input:disabled, textarea:disabled').forEach(el => {
|
|
||||||
disabledElements.push(el);
|
|
||||||
el.disabled = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 使用html2canvas捕获内容
|
|
||||||
const canvas = await html2canvas(element, {
|
|
||||||
scale: 2, // 提高清晰度
|
|
||||||
useCORS: true, // 允许跨域图片
|
|
||||||
logging: false, // 关闭日志
|
|
||||||
backgroundColor: '#F8F5F0' // 设置背景色
|
|
||||||
});
|
|
||||||
|
|
||||||
// 计算PDF页面尺寸
|
|
||||||
const imgWidth = 210; // A4纸宽度(mm)
|
|
||||||
const pageHeight = 297; // A4纸高度(mm)
|
|
||||||
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
|
||||||
let heightLeft = imgHeight;
|
|
||||||
|
|
||||||
// 创建PDF
|
|
||||||
const pdf = new jsPDF('p', 'mm', 'a4');
|
|
||||||
let position = 0;
|
|
||||||
|
|
||||||
// 将canvas转换为图片
|
|
||||||
const imgData = canvas.toDataURL('image/jpeg');
|
|
||||||
|
|
||||||
// 添加第一页
|
|
||||||
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
|
|
||||||
heightLeft -= pageHeight;
|
|
||||||
|
|
||||||
// 如果内容超过一页,添加更多页
|
|
||||||
while (heightLeft > 0) {
|
|
||||||
position = heightLeft - imgHeight;
|
|
||||||
pdf.addPage();
|
|
||||||
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
|
|
||||||
heightLeft -= pageHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存PDF
|
|
||||||
pdf.save(fileName);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
// 恢复之前移除的 disabled 属性
|
|
||||||
disabledElements.forEach(el => {
|
|
||||||
el.disabled = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,215 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="收款编号" prop="receiptBillCode">
|
|
||||||
<el-input v-model="queryParams.receiptBillCode" placeholder="请输入收款编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="进货商" prop="partnerName">
|
|
||||||
<el-input v-model="queryParams.partnerName" placeholder="请输入进货商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="receiptList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="收款编号" align="center" prop="receiptBillCode" />
|
|
||||||
<el-table-column label="客户" align="center" prop="partnerName" />
|
|
||||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 详情对话框 -->
|
|
||||||
<el-dialog title="收款单详情" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="收款单详情">
|
|
||||||
<receipt-detail :data="form"></receipt-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span>{{ form.receiptBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listReceiptApproved, getReceiptDetail } from "@/api/finance/receipt";
|
|
||||||
import { listCompletedFlows } from "@/api/flow";
|
|
||||||
import ReceiptDetail from "../components/ReceiptDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceiptApproved",
|
|
||||||
components: { ReceiptDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
receiptList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
receiptBillCode: null,
|
|
||||||
partnerName: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_receipt_approve',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
currentReceiptId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listReceiptApproved(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.receiptList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
handleView(row) {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.currentReceiptId = row.id;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getReceiptDetail(this.currentReceiptId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.receiptBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
listCompletedFlows({ businessKey: businessKey }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `收款单-${this.form.receiptBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="receipt-detail">
|
|
||||||
<div style="text-align: center;font-weight:bold;font-size: 25px;">收款申请单</div>
|
|
||||||
<el-descriptions title="收款单信息" :column="3" border>
|
|
||||||
<el-descriptions-item label="销售-收款单编号">{{ data.receiptBillCode }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item :span="2" label="进货商名称">{{ data.partnerName }}</el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label="收款单类型">-->
|
|
||||||
<!-- <dict-tag :options="dict.type.receipt_bill_type" :value="data.receiptBillType"/>-->
|
|
||||||
<!-- </el-descriptions-item>-->
|
|
||||||
<el-descriptions-item label="含税总价(元)">{{ formatCurrency(data.totalPriceWithTax) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="未税总价(元)">{{ formatCurrency(data.totalPriceWithoutTax) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="税额(元)">{{ formatCurrency(data.taxAmount) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="支付方式">
|
|
||||||
<dict-tag :options="dict.type.payment_method" :value="data.receiptMethod"/>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行账号">{{ data.receiptBankNumber }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="账户名称">{{ data.receiptAccountName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行开户行">{{ data.receiptBankOpenAddress }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行行号">{{ data.bankNumber }}</el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label="备注" :span="3">{{ data.remark }}</el-descriptions-item>-->
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-show="data.detailDTOList && data.detailDTOList.length>0">
|
|
||||||
<div class="el-descriptions__title">应收单列表</div>
|
|
||||||
<el-table :data="data.detailDTOList" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="receivableBillCode" label="销售-应收单编号" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="productType" label="产品类型" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.product_type" :value="scope.row.productType"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="totalPriceWithTax" label="含税总价" align="center" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"></el-table-column>
|
|
||||||
<el-table-column prop="receiptAmount" label="本次收款金额" align="center" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"></el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-if="attachments && attachments.length > 0">
|
|
||||||
<div class="el-descriptions__title">附件信息</div>
|
|
||||||
<el-table :data="attachments" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column prop="fileName" label="附件名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createByName" label="上传人" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createTime" label="上传时间" align="center"></el-table-column>
|
|
||||||
<el-table-column label="操作" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handlePreview(scope.row)">预览</el-button>
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-download" @click="handleDownload(scope.row)">下载</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="pdfPreviewVisible" width="80%" append-to-body top="5vh" title="PDF预览">
|
|
||||||
<iframe :src="currentPdfUrl" width="100%" height="600px" frameborder="0"></iframe>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="imagePreviewVisible" width="60%" append-to-body top="5vh" title="图片预览">
|
|
||||||
<img :src="currentImageUrl" style="width: 100%;" />
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import request from '@/utils/request';
|
|
||||||
import {getInvoiceAttachments} from "@/api/finance/invoice";
|
|
||||||
import {getReceiptAttachments} from "@/api/finance/receipt";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceiptDetail",
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dicts: ['receipt_bill_type', 'product_type','payment_method'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
attachments: [],
|
|
||||||
pdfPreviewVisible: false,
|
|
||||||
currentPdfUrl: '',
|
|
||||||
imagePreviewVisible: false,
|
|
||||||
currentImageUrl: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
'data.id': {
|
|
||||||
handler(val) {
|
|
||||||
if (val) {
|
|
||||||
this.fetchAttachments(val);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
fetchAttachments(id) {
|
|
||||||
getReceiptAttachments(id,{type: "receipt"}).then(response => {
|
|
||||||
this.attachments = (response.data || []).filter(item => item.delFlag !== '2');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
isPdf(filePath) {
|
|
||||||
return filePath && filePath.toLowerCase().endsWith('.pdf');
|
|
||||||
},
|
|
||||||
getImageUrl(resource) {
|
|
||||||
return process.env.VUE_APP_BASE_API + "/common/download/resource?resource=" + resource;
|
|
||||||
},
|
|
||||||
handlePreview(row) {
|
|
||||||
if (this.isPdf(row.filePath)) {
|
|
||||||
// PDF Preview logic
|
|
||||||
request({
|
|
||||||
url: '/common/download/resource',
|
|
||||||
method: 'get',
|
|
||||||
params: { resource: row.filePath },
|
|
||||||
responseType: 'blob'
|
|
||||||
}).then(res => {
|
|
||||||
const blob = new Blob([res.data], { type: 'application/pdf' });
|
|
||||||
this.currentPdfUrl = URL.createObjectURL(blob);
|
|
||||||
this.pdfPreviewVisible = true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Image Preview
|
|
||||||
this.currentImageUrl = this.getImageUrl(row.filePath);
|
|
||||||
this.imagePreviewVisible = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleDownload(row) {
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = this.getImageUrl(row.filePath);
|
|
||||||
link.download = row.fileName || 'attachment';
|
|
||||||
link.style.display = 'none';
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.receipt-detail {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,302 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="收款编号" prop="receiptBillCode">
|
|
||||||
<el-input v-model="queryParams.receiptBillCode" placeholder="请输入收款编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="进货商" prop="partnerName">
|
|
||||||
<el-input v-model="queryParams.partnerName" placeholder="请输入进货商名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
size="mini"
|
|
||||||
@click="toApproved()"
|
|
||||||
>审批历史</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="receiptList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="收款编号" align="center" prop="receiptBillCode" />
|
|
||||||
<el-table-column label="进货商" align="center" prop="partnerName" />
|
|
||||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime, '{y}-{m}-{d}') }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(scope.row)">审批</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 审批详情主对话框 -->
|
|
||||||
<el-dialog title="收款单审批" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="收款单详情">
|
|
||||||
<receipt-detail :data="form"></receipt-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span>{{ form.receiptBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="openOpinionDialog('approve')">同意</el-button>
|
|
||||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳回</el-button>
|
|
||||||
<el-button @click="detailDialogVisible = false">取 消</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 审批意见对话框 -->
|
|
||||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="30%" append-to-body>
|
|
||||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
|
||||||
<el-form-item label="审批意见" prop="approveOpinion">
|
|
||||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="opinionDialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="showConfirmDialog()">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listReceiptApprove, getReceiptDetail } from "@/api/finance/receipt";
|
|
||||||
import { approveTask, listCompletedFlows } from "@/api/flow";
|
|
||||||
import ReceiptDetail from "./components/ReceiptDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceiptApprove",
|
|
||||||
components: { ReceiptDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
receiptList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
receiptBillCode: null,
|
|
||||||
partnerName: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_receipt_approve',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
opinionDialogVisible: false,
|
|
||||||
confirmDialogTitle: '',
|
|
||||||
currentApproveType: '',
|
|
||||||
opinionForm: {
|
|
||||||
approveOpinion: ''
|
|
||||||
},
|
|
||||||
opinionRules: {
|
|
||||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
|
||||||
},
|
|
||||||
processKey: 'finance_receipt_approve',
|
|
||||||
taskId: null,
|
|
||||||
currentReceiptId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listReceiptApprove(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.receiptList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
toApproved() {
|
|
||||||
this.$router.push( '/approve/receiptLog' )
|
|
||||||
},
|
|
||||||
handleApprove(row) {
|
|
||||||
this.resetDetailForm();
|
|
||||||
this.currentReceiptId = row.id;
|
|
||||||
this.taskId = row.taskId;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getReceiptDetail(this.currentReceiptId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.receiptBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetDetailForm() {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
let keys = [];
|
|
||||||
if(this.processKey) keys.push(this.processKey);
|
|
||||||
|
|
||||||
listCompletedFlows({ businessKey: businessKey, processKeyList: keys }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openOpinionDialog(type) {
|
|
||||||
this.currentApproveType = type;
|
|
||||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批';
|
|
||||||
this.opinionDialogVisible = true;
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if(this.$refs.opinionForm) this.$refs.opinionForm.clearValidate();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showConfirmDialog() {
|
|
||||||
this.$refs.opinionForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
this.opinionDialogVisible = false;
|
|
||||||
this.submitApproval();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
submitApproval() {
|
|
||||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0;
|
|
||||||
const params = {
|
|
||||||
businessKey: this.form.receiptBillCode,
|
|
||||||
processKey: this.processKey,
|
|
||||||
taskId: this.taskId,
|
|
||||||
variables: {
|
|
||||||
comment: this.opinionForm.approveOpinion,
|
|
||||||
approveBtn: approveBtn
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
approveTask(params).then(() => {
|
|
||||||
this.$modal.msgSuccess(this.confirmDialogTitle + "成功");
|
|
||||||
this.detailDialogVisible = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
if (!status) {
|
|
||||||
return '提交审批'
|
|
||||||
}
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `收款单-${this.form.receiptBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,215 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="收款编号" prop="receiptBillCode">
|
|
||||||
<el-input v-model="queryParams.receiptBillCode" placeholder="请输入收款编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="进货商" prop="partnerName">
|
|
||||||
<el-input v-model="queryParams.partnerName" placeholder="请输入进货商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="receiptList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="收款编号" align="center" prop="receiptBillCode" />
|
|
||||||
<el-table-column label="客户" align="center" prop="partnerName" />
|
|
||||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)" />
|
|
||||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 详情对话框 -->
|
|
||||||
<el-dialog title="收款单详情" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="收款单详情">
|
|
||||||
<receipt-detail :data="form"></receipt-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span> {{ form.receiptBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listReceiptApproved, getReceiptDetail } from "@/api/finance/receipt";
|
|
||||||
import { listCompletedFlows } from "@/api/flow";
|
|
||||||
import ReceiptDetail from "../components/ReceiptDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceiptRefoundApproved",
|
|
||||||
components: { ReceiptDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
receiptList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
receiptBillCode: null,
|
|
||||||
partnerName: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_receipt_refound',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
currentReceiptId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listReceiptApproved(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.receiptList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
handleView(row) {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.currentReceiptId = row.id;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getReceiptDetail(this.currentReceiptId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.receiptBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
listCompletedFlows({ businessKey: businessKey }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `收款单-${this.form.receiptBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,134 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="receipt-detail">
|
|
||||||
<div style="text-align: center;font-weight:bold;font-size: 25px;">退款申请单</div>
|
|
||||||
<el-descriptions title="收款单信息" :column="3" border>
|
|
||||||
<el-descriptions-item label="销售-收款单编号">{{ data.receiptBillCode }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item :span="2" label="进货商名称">{{ data.partnerName }}</el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label="收款单类型">-->
|
|
||||||
<!-- <dict-tag :options="dict.type.receipt_bill_type" :value="data.receiptBillType"/>-->
|
|
||||||
<!-- </el-descriptions-item>-->
|
|
||||||
<el-descriptions-item label="含税总价(元)"><span style="color: red">{{ formatCurrency(data.totalPriceWithTax) }}</span></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="未税总价(元)"><span style="color: red">{{ formatCurrency(data.totalPriceWithoutTax) }}</span></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="税额(元)"><span style="color: red">{{ formatCurrency(data.taxAmount) }}</span></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="支付方式">
|
|
||||||
<dict-tag :options="dict.type.payment_method" :value="data.receiptMethod"/>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行账号">{{ data.receiptBankNumber }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="账户名称">{{ data.receiptAccountName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行开户行">{{ data.receiptBankOpenAddress }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="银行行号">{{ data.bankNumber }}</el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label="备注" :span="3">{{ data.remark }}</el-descriptions-item>-->
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-show="data.detailDTOList && data.detailDTOList.length>0">
|
|
||||||
<div class="el-descriptions__title">应收单列表</div>
|
|
||||||
<el-table :data="data.detailDTOList" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="receivableBillCode" label="销售-应收单编号" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="productType" label="产品类型" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.product_type" :value="scope.row.productType"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="totalPriceWithTax" label="含税总价" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="receiptAmount" label="本次收款金额" align="center"></el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-if="attachments && attachments.length > 0">
|
|
||||||
<div class="el-descriptions__title">附件信息</div>
|
|
||||||
<el-table :data="attachments" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column prop="fileName" label="附件名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createByName" label="上传人" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createTime" label="上传时间" align="center"></el-table-column>
|
|
||||||
<el-table-column label="操作" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handlePreview(scope.row)">预览</el-button>
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-download" @click="handleDownload(scope.row)">下载</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="pdfPreviewVisible" width="80%" append-to-body top="5vh" title="PDF预览">
|
|
||||||
<iframe :src="currentPdfUrl" width="100%" height="600px" frameborder="0"></iframe>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="imagePreviewVisible" width="60%" append-to-body top="5vh" title="图片预览">
|
|
||||||
<img :src="currentImageUrl" style="width: 100%;" />
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import request from '@/utils/request';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceiptRefoundDetail",
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dicts: ['receipt_bill_type', 'product_type','payment_method'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
attachments: [],
|
|
||||||
pdfPreviewVisible: false,
|
|
||||||
currentPdfUrl: '',
|
|
||||||
imagePreviewVisible: false,
|
|
||||||
currentImageUrl: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
isPdf(filePath) {
|
|
||||||
return filePath && filePath.toLowerCase().endsWith('.pdf');
|
|
||||||
},
|
|
||||||
getImageUrl(resource) {
|
|
||||||
return process.env.VUE_APP_BASE_API + "/common/download/resource?resource=" + resource;
|
|
||||||
},
|
|
||||||
handlePreview(row) {
|
|
||||||
if (this.isPdf(row.filePath)) {
|
|
||||||
// PDF Preview logic
|
|
||||||
request({
|
|
||||||
url: '/common/download/resource',
|
|
||||||
method: 'get',
|
|
||||||
params: { resource: row.filePath },
|
|
||||||
responseType: 'blob'
|
|
||||||
}).then(res => {
|
|
||||||
const blob = new Blob([res.data], { type: 'application/pdf' });
|
|
||||||
this.currentPdfUrl = URL.createObjectURL(blob);
|
|
||||||
this.pdfPreviewVisible = true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Image Preview
|
|
||||||
this.currentImageUrl = this.getImageUrl(row.filePath);
|
|
||||||
this.imagePreviewVisible = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleDownload(row) {
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = this.getImageUrl(row.filePath);
|
|
||||||
link.download = row.fileName || 'attachment';
|
|
||||||
link.style.display = 'none';
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.receipt-detail {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,306 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="收款编号" prop="receiptBillCode">
|
|
||||||
<el-input v-model="queryParams.receiptBillCode" placeholder="请输入收款编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="进货商" prop="partnerName">
|
|
||||||
<el-input v-model="queryParams.partnerName" placeholder="请输入进货商名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
size="mini"
|
|
||||||
@click="toApproved()"
|
|
||||||
>审批历史</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="receiptList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="收款编号" align="center" prop="receiptBillCode" />
|
|
||||||
<el-table-column label="进货商" align="center" prop="partnerName" />
|
|
||||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" >
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span style="color: red">{{ formatCurrency(scope.row.totalPriceWithTax) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime, '{y}-{m}-{d}') }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(scope.row)">审批</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 审批详情主对话框 -->
|
|
||||||
<el-dialog title="收款单审批" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="收款单详情">
|
|
||||||
<receipt-detail :data="form"></receipt-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span>{{ form.receiptBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b><el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="openOpinionDialog('approve')">同意</el-button>
|
|
||||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳回</el-button>
|
|
||||||
<el-button @click="detailDialogVisible = false">取 消</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 审批意见对话框 -->
|
|
||||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="30%" append-to-body>
|
|
||||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
|
||||||
<el-form-item label="审批意见" prop="approveOpinion">
|
|
||||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="opinionDialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="showConfirmDialog()">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listReceiptApprove, getReceiptDetail } from "@/api/finance/receipt";
|
|
||||||
import { approveTask, listCompletedFlows } from "@/api/flow";
|
|
||||||
import ReceiptDetail from "./components/ReceiptDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceiptRefoundApprove",
|
|
||||||
components: { ReceiptDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
receiptList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
receiptBillCode: null,
|
|
||||||
partnerName: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_receipt_refound',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
opinionDialogVisible: false,
|
|
||||||
confirmDialogTitle: '',
|
|
||||||
currentApproveType: '',
|
|
||||||
opinionForm: {
|
|
||||||
approveOpinion: ''
|
|
||||||
},
|
|
||||||
opinionRules: {
|
|
||||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
|
||||||
},
|
|
||||||
processKey: 'finance_receipt_refound',
|
|
||||||
taskId: null,
|
|
||||||
currentReceiptId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listReceiptApprove(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.receiptList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
toApproved() {
|
|
||||||
this.$router.push( '/approve/receiptRefoundLog' )
|
|
||||||
},
|
|
||||||
handleApprove(row) {
|
|
||||||
this.resetDetailForm();
|
|
||||||
this.currentReceiptId = row.id;
|
|
||||||
this.taskId = row.taskId;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getReceiptDetail(this.currentReceiptId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.receiptBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetDetailForm() {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
let keys = [];
|
|
||||||
if(this.processKey) keys.push(this.processKey);
|
|
||||||
|
|
||||||
listCompletedFlows({ businessKey: businessKey, processKeyList: keys }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openOpinionDialog(type) {
|
|
||||||
this.currentApproveType = type;
|
|
||||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批';
|
|
||||||
this.opinionDialogVisible = true;
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if(this.$refs.opinionForm) this.$refs.opinionForm.clearValidate();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showConfirmDialog() {
|
|
||||||
this.$refs.opinionForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
this.opinionDialogVisible = false;
|
|
||||||
this.submitApproval();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
submitApproval() {
|
|
||||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0;
|
|
||||||
const params = {
|
|
||||||
businessKey: this.form.receiptBillCode,
|
|
||||||
processKey: this.processKey,
|
|
||||||
taskId: this.taskId,
|
|
||||||
variables: {
|
|
||||||
comment: this.opinionForm.approveOpinion,
|
|
||||||
approveBtn: approveBtn
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
approveTask(params).then(() => {
|
|
||||||
this.$modal.msgSuccess(this.confirmDialogTitle + "成功");
|
|
||||||
this.detailDialogVisible = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
if (!status) {
|
|
||||||
return '提交审批'
|
|
||||||
}
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `收款单-${this.form.receiptBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,240 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="开票编号" prop="invoiceBillCode">
|
|
||||||
<el-input v-model="queryParams.invoiceBillCode" placeholder="请输入开票编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="客户" prop="partnerName">
|
|
||||||
<el-input v-model="queryParams.partnerName" placeholder="请输入客户" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="invoiceList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="开票编号" align="center" prop="invoiceBillCode" />
|
|
||||||
<el-table-column label="客户" align="center" prop="partnerName" />
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)" />
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 详情对话框 -->
|
|
||||||
<el-dialog title="开票单详情" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-document"
|
|
||||||
style="margin-right: 10px;"
|
|
||||||
@click="exportExcel"
|
|
||||||
:loading="excelExporting"
|
|
||||||
>导出Excel</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="开票单详情">
|
|
||||||
<receivable-invoice-detail :data="form"></receivable-invoice-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span>{{ form.invoiceBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listInvoiceApproved, getInvoiceDetail } from "@/api/finance/invoice";
|
|
||||||
import { listCompletedFlows } from "@/api/flow";
|
|
||||||
import ReceivableInvoiceDetail from "../components/ReceivableInvoiceDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
import { exportInvoiceInfoToExcel } from "@/views/approve/finance/invoiceExcelUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceivableInvoiceApproved",
|
|
||||||
components: { ReceivableInvoiceDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
invoiceList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
invoiceBillCode: null,
|
|
||||||
partnerName: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_invoice_approve',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
currentInvoiceId: null,
|
|
||||||
pdfExporting: false,
|
|
||||||
excelExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listInvoiceApproved(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.invoiceList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
handleView(row) {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.currentInvoiceId = row.id;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getInvoiceDetail(this.currentInvoiceId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.invoiceBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
listCompletedFlows({ businessKey: businessKey }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `开票单-${this.form.invoiceBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
exportExcel() {
|
|
||||||
if (!this.form || !this.form.invoiceBillCode) {
|
|
||||||
this.$modal.msgWarning("暂无可导出的开票信息");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.excelExporting = true;
|
|
||||||
try {
|
|
||||||
const fileName = `开票单-${this.form.invoiceBillCode || ""}.xls`;
|
|
||||||
exportInvoiceInfoToExcel(this.form, fileName);
|
|
||||||
this.$modal.msgSuccess("Excel导出成功");
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Excel导出失败:", error);
|
|
||||||
this.$modal.msgError("Excel导出失败,请稍后重试");
|
|
||||||
} finally {
|
|
||||||
this.excelExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,170 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="invoice-detail">
|
|
||||||
<div style="text-align: center;font-weight:bold;font-size: 25px;">开票申请单</div>
|
|
||||||
<el-descriptions title="开票单信息" :column="3" border>
|
|
||||||
<el-descriptions-item label="销售-开票单编号">{{ data.invoiceBillCode }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item :span="2" label="进货商">{{ data.partnerName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="含税总价(元)">{{ formatCurrency(data.totalPriceWithTax) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="未税总价(元)">{{ formatCurrency(data.totalPriceWithoutTax) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="税额(元)">{{ formatCurrency(data.taxAmount) }}</el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label="银行账号">{{ data.buyerBankAccount }}</el-descriptions-item>-->
|
|
||||||
<!-- <el-descriptions-item label="账户名称">{{ data.buyerName }}</el-descriptions-item>-->
|
|
||||||
<!-- <el-descriptions-item label="银行开户行">{{ data.buyerBank }}</el-descriptions-item>-->
|
|
||||||
<!-- <el-descriptions-item label="银行行号">{{ data.bankNumber }}</el-descriptions-item> -->
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;">
|
|
||||||
<div class="el-descriptions__title">发票信息</div>
|
|
||||||
<invoice-info-view :data="data" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-show="data.detailDTOList && data.detailDTOList.length>0">
|
|
||||||
<div class="el-descriptions__title">应收单列表</div>
|
|
||||||
<el-table :data="data.detailDTOList" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="receivableBillCode" label="销售-应收单编号" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="productType" label="产品类型" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.product_type" :value="scope.row.productType"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="totalPriceWithTax" label="含税总价" align="center" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"></el-table-column>
|
|
||||||
<el-table-column prop="receiptAmount" label="本次开票金额" align="center" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"></el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-if="excelList && excelList.length > 0">
|
|
||||||
<div class="el-descriptions__title">附件信息</div>
|
|
||||||
<el-table :data="excelList" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column prop="fileName" label="附件名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createUserName" label="上传信息" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createTime" label="生成时间" align="center"></el-table-column>
|
|
||||||
<el-table-column label="操作" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-download" @click="handleDownload(scope.row)">下载</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <div class="section" style="margin-top: 20px;" v-if="attachments && attachments.length > 0">-->
|
|
||||||
<!-- <div class="el-descriptions__title">附件信息</div>-->
|
|
||||||
<!-- <el-table :data="attachments" border style="width: 100%; margin-top: 10px;">-->
|
|
||||||
<!-- <el-table-column prop="fileName" label="附件名称" align="center"></el-table-column>-->
|
|
||||||
<!-- <el-table-column prop="createUserName" label="上传人" align="center"></el-table-column>-->
|
|
||||||
<!-- <el-table-column prop="createTime" label="上传时间" align="center"></el-table-column>-->
|
|
||||||
<!-- <el-table-column label="操作" align="center">-->
|
|
||||||
<!-- <template slot-scope="scope">-->
|
|
||||||
<!-- <el-button size="mini" type="text" icon="el-icon-view" @click="handlePreview(scope.row)">预览</el-button>-->
|
|
||||||
<!-- <el-button size="mini" type="text" icon="el-icon-download" @click="handleDownload(scope.row)">下载</el-button>-->
|
|
||||||
<!-- </template>-->
|
|
||||||
<!-- </el-table-column>-->
|
|
||||||
<!-- </el-table>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
|
|
||||||
<!-- <el-dialog :visible.sync="pdfPreviewVisible" width="80%" append-to-body top="5vh" title="PDF预览">-->
|
|
||||||
<!-- <iframe :src="currentPdfUrl" width="100%" height="600px" frameborder="0"></iframe>-->
|
|
||||||
<!-- </el-dialog>-->
|
|
||||||
|
|
||||||
<!-- <el-dialog :visible.sync="imagePreviewVisible" width="60%" append-to-body top="5vh" title="图片预览">-->
|
|
||||||
<!-- <img :src="currentImageUrl" style="width: 100%;" />-->
|
|
||||||
<!-- </el-dialog>-->
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getInvoiceAttachments } from "@/api/finance/invoice";
|
|
||||||
import request from '@/utils/request';
|
|
||||||
import InvoiceInfoView from '@/views/finance/invoice/components/InvoiceInfoView';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceivableInvoiceDetail",
|
|
||||||
components: { InvoiceInfoView },
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dicts: ['product_type'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
attachments: [],
|
|
||||||
excelList: [],
|
|
||||||
pdfPreviewVisible: false,
|
|
||||||
currentPdfUrl: '',
|
|
||||||
imagePreviewVisible: false,
|
|
||||||
currentImageUrl: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
data: {
|
|
||||||
handler(val) {
|
|
||||||
if (val && val.updateTime) {
|
|
||||||
this.excelList = [{
|
|
||||||
fileName: '电子发票--购买方公司信息.xlsx',
|
|
||||||
createUserName: '系统生成',
|
|
||||||
createTime: val.updateTime,
|
|
||||||
isSystemGenerated: true
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate: true,
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
isPdf(filePath) {
|
|
||||||
return filePath && filePath.toLowerCase().endsWith('.pdf');
|
|
||||||
},
|
|
||||||
getImageUrl(resource) {
|
|
||||||
return process.env.VUE_APP_BASE_API + "/common/download/resource?resource=" + resource;
|
|
||||||
},
|
|
||||||
handlePreview(row) {
|
|
||||||
if (this.isPdf(row.filePath)) {
|
|
||||||
request({
|
|
||||||
url: '/common/download/resource',
|
|
||||||
method: 'get',
|
|
||||||
params: { resource: row.filePath },
|
|
||||||
responseType: 'blob'
|
|
||||||
}).then(res => {
|
|
||||||
const blob = new Blob([res.data], { type: 'application/pdf' });
|
|
||||||
this.currentPdfUrl = URL.createObjectURL(blob);
|
|
||||||
this.pdfPreviewVisible = true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.currentImageUrl = this.getImageUrl(row.filePath);
|
|
||||||
this.imagePreviewVisible = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleDownload(row) {
|
|
||||||
if (row.isSystemGenerated) {
|
|
||||||
request({
|
|
||||||
url: '/finance/invoice/export/' + this.data.invoiceBillCode,
|
|
||||||
method: 'get'
|
|
||||||
}).then(res => {
|
|
||||||
window.location.href = process.env.VUE_APP_BASE_API + "/common/download?fileName=" + encodeURIComponent(res.msg) + "&delete=true";
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = this.getImageUrl(row.filePath);
|
|
||||||
link.download = row.fileName || 'attachment';
|
|
||||||
link.style.display = 'none';
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.invoice-detail {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,327 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="开票编号" prop="invoiceBillCode">
|
|
||||||
<el-input v-model="queryParams.invoiceBillCode" placeholder="请输入开票编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="进货商" prop="partnerName">
|
|
||||||
<el-input v-model="queryParams.partnerName" placeholder="请输入进货商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
size="mini"
|
|
||||||
@click="toApproved()"
|
|
||||||
>审批历史</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="invoiceList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="开票编号" align="center" prop="invoiceBillCode" />
|
|
||||||
<el-table-column label="进货商" align="center" prop="partnerName" />
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime, '{y}-{m}-{d}') }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(scope.row)">审批</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 审批详情主对话框 -->
|
|
||||||
<el-dialog title="开票单审批" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-document"
|
|
||||||
style="margin-right: 10px;"
|
|
||||||
@click="exportExcel"
|
|
||||||
:loading="excelExporting"
|
|
||||||
>导出Excel</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="开票单详情">
|
|
||||||
<receivable-invoice-detail :data="form"></receivable-invoice-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span>{{ form.invoiceBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="openOpinionDialog('approve')">同意</el-button>
|
|
||||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳回</el-button>
|
|
||||||
<el-button @click="detailDialogVisible = false">取 消</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 审批意见对话框 -->
|
|
||||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="30%" append-to-body>
|
|
||||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
|
||||||
<el-form-item label="审批意见" prop="approveOpinion">
|
|
||||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="opinionDialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="showConfirmDialog()">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listInvoiceApprove, getInvoiceDetail } from "@/api/finance/invoice";
|
|
||||||
import { approveTask, listCompletedFlows } from "@/api/flow";
|
|
||||||
import ReceivableInvoiceDetail from "./components/ReceivableInvoiceDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
import { exportInvoiceInfoToExcel } from "@/views/approve/finance/invoiceExcelUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceivableInvoiceApprove",
|
|
||||||
components: { ReceivableInvoiceDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
invoiceList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
invoiceBillCode: null,
|
|
||||||
partnerName: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_invoice_approve',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
opinionDialogVisible: false,
|
|
||||||
confirmDialogTitle: '',
|
|
||||||
currentApproveType: '',
|
|
||||||
opinionForm: {
|
|
||||||
approveOpinion: ''
|
|
||||||
},
|
|
||||||
opinionRules: {
|
|
||||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
|
||||||
},
|
|
||||||
processKey: 'finance_invoice_approve',
|
|
||||||
taskId: null,
|
|
||||||
currentInvoiceId: null,
|
|
||||||
pdfExporting: false,
|
|
||||||
excelExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listInvoiceApprove(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.invoiceList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
toApproved() {
|
|
||||||
this.$router.push('/approve/receivableInvoiceLog')
|
|
||||||
},
|
|
||||||
handleApprove(row) {
|
|
||||||
this.resetDetailForm();
|
|
||||||
this.currentInvoiceId = row.id;
|
|
||||||
this.taskId = row.taskId;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getInvoiceDetail(this.currentInvoiceId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.invoiceBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetDetailForm() {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
let keys = [];
|
|
||||||
if(this.processKey) keys.push(this.processKey);
|
|
||||||
|
|
||||||
listCompletedFlows({ businessKey: businessKey, processKeyList: keys }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openOpinionDialog(type) {
|
|
||||||
this.currentApproveType = type;
|
|
||||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批';
|
|
||||||
this.opinionDialogVisible = true;
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if(this.$refs.opinionForm) this.$refs.opinionForm.clearValidate();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showConfirmDialog() {
|
|
||||||
this.$refs.opinionForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
this.opinionDialogVisible = false;
|
|
||||||
this.submitApproval();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
submitApproval() {
|
|
||||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0;
|
|
||||||
const params = {
|
|
||||||
businessKey: this.form.invoiceBillCode,
|
|
||||||
processKey: this.processKey,
|
|
||||||
taskId: this.taskId,
|
|
||||||
variables: {
|
|
||||||
comment: this.opinionForm.approveOpinion,
|
|
||||||
approveBtn: approveBtn
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
approveTask(params).then(() => {
|
|
||||||
this.$modal.msgSuccess(this.confirmDialogTitle + "成功");
|
|
||||||
this.detailDialogVisible = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
if (!status) {
|
|
||||||
return '提交审批'
|
|
||||||
}
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `开票单-${this.form.invoiceBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
exportExcel() {
|
|
||||||
if (!this.form || !this.form.invoiceBillCode) {
|
|
||||||
this.$modal.msgWarning("暂无可导出的开票信息");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.excelExporting = true;
|
|
||||||
try {
|
|
||||||
const fileName = `开票单-${this.form.invoiceBillCode || ""}.xls`;
|
|
||||||
exportInvoiceInfoToExcel(this.form, fileName);
|
|
||||||
this.$modal.msgSuccess("Excel导出成功");
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Excel导出失败:", error);
|
|
||||||
this.$modal.msgError("Excel导出失败,请稍后重试");
|
|
||||||
} finally {
|
|
||||||
this.excelExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,217 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="开票编号" prop="invoiceBillCode">
|
|
||||||
<el-input v-model="queryParams.invoiceBillCode" placeholder="请输入开票编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="客户" prop="partnerName">
|
|
||||||
<el-input v-model="queryParams.partnerName" placeholder="请输入客户" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="invoiceList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="开票编号" align="center" prop="invoiceBillCode" />
|
|
||||||
<el-table-column label="客户" align="center" prop="partnerName" />
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span :style="scope.row.totalPriceWithTax < 0 ? 'color: red' : ''">{{ formatCurrency(scope.row.totalPriceWithTax) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 详情对话框 -->
|
|
||||||
<el-dialog title="开票单详情" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="开票单详情">
|
|
||||||
<receivable-invoice-detail :data="form"></receivable-invoice-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span>{{ form.invoiceBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listInvoiceApproved, getInvoiceDetail } from "@/api/finance/invoice";
|
|
||||||
import { listCompletedFlows } from "@/api/flow";
|
|
||||||
import ReceivableInvoiceDetail from "../components/ReceivableInvoiceDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceivableInvoiceRefundApproved",
|
|
||||||
components: { ReceivableInvoiceDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
invoiceList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
invoiceBillCode: null,
|
|
||||||
partnerName: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_invoice_refound',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
currentInvoiceId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listInvoiceApproved(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.invoiceList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
handleView(row) {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.currentInvoiceId = row.id;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getInvoiceDetail(this.currentInvoiceId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.invoiceBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
listCompletedFlows({ businessKey: businessKey }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `开票单-${this.form.invoiceBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,183 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="invoice-detail">
|
|
||||||
<div style="text-align: center;font-weight:bold;font-size: 25px;">红冲开票申请单</div>
|
|
||||||
<el-descriptions title="开票单信息" :column="3" border>
|
|
||||||
<el-descriptions-item label="销售-开票单编号">{{ data.invoiceBillCode }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item :span="2" label="进货商">{{ data.partnerName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="含税总价(元)">
|
|
||||||
<span :style="data.totalPriceWithTax < 0 ? 'color: red' : ''">{{ formatCurrency(data.totalPriceWithTax) }}</span>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="未税总价(元)">
|
|
||||||
<span :style="data.totalPriceWithoutTax < 0 ? 'color: red' : ''">{{ formatCurrency(data.totalPriceWithoutTax) }}</span>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="税额(元)">
|
|
||||||
<span :style="data.taxAmount < 0 ? 'color: red' : ''">{{ formatCurrency(data.taxAmount) }}</span>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label="银行账号">{{ data.buyerBankAccount }}</el-descriptions-item>-->
|
|
||||||
<!-- <el-descriptions-item label="账户名称">{{ data.buyerName }}</el-descriptions-item>-->
|
|
||||||
<!-- <el-descriptions-item label="银行开户行">{{ data.buyerBank }}</el-descriptions-item>-->
|
|
||||||
<!-- <el-descriptions-item label="银行行号">{{ data.bankNumber }}</el-descriptions-item> -->
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;">
|
|
||||||
<div class="el-descriptions__title">发票信息</div>
|
|
||||||
<invoice-info-view :data="data" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-show="data.detailDTOList && data.detailDTOList.length>0">
|
|
||||||
<div class="el-descriptions__title">应收单列表</div>
|
|
||||||
<el-table :data="data.detailDTOList" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="receivableBillCode" label="销售-应收单编号" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="productType" label="产品类型" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.product_type" :value="scope.row.productType"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="totalPriceWithTax" label="含税总价" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span :style="scope.row.totalPriceWithTax < 0 ? 'color: red' : ''">{{ scope.row.totalPriceWithTax }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="receiptAmount" label="本次开票金额" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span :style="scope.row.receiptAmount < 0 ? 'color: red' : ''">{{ scope.row.receiptAmount }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-if="excelList && excelList.length > 0">
|
|
||||||
<div class="el-descriptions__title">附件信息</div>
|
|
||||||
<el-table :data="excelList" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column prop="fileName" label="附件名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createUserName" label="上传信息" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createTime" label="生成时间" align="center"></el-table-column>
|
|
||||||
<el-table-column label="操作" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-download" @click="handleDownload(scope.row)">下载</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="margin-top: 20px;" v-if="attachments && attachments.length > 0">
|
|
||||||
<div class="el-descriptions__title">附件信息</div>
|
|
||||||
<el-table :data="attachments" border style="width: 100%; margin-top: 10px;">
|
|
||||||
<el-table-column prop="fileName" label="附件名称" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createUserName" label="上传人" align="center"></el-table-column>
|
|
||||||
<el-table-column prop="createTime" label="上传时间" align="center"></el-table-column>
|
|
||||||
<el-table-column label="操作" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handlePreview(scope.row)">预览</el-button>
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-download" @click="handleDownload(scope.row)">下载</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="pdfPreviewVisible" width="80%" append-to-body top="5vh" title="PDF预览">
|
|
||||||
<iframe :src="currentPdfUrl" width="100%" height="600px" frameborder="0"></iframe>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog :visible.sync="imagePreviewVisible" width="60%" append-to-body top="5vh" title="图片预览">
|
|
||||||
<img :src="currentImageUrl" style="width: 100%;" />
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getInvoiceAttachments } from "@/api/finance/invoice";
|
|
||||||
import request from '@/utils/request';
|
|
||||||
import InvoiceInfoView from '@/views/finance/invoice/components/InvoiceInfoView';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceivableInvoiceDetail",
|
|
||||||
components: { InvoiceInfoView },
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dicts: ['product_type'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
attachments: [],
|
|
||||||
excelList: [],
|
|
||||||
pdfPreviewVisible: false,
|
|
||||||
currentPdfUrl: '',
|
|
||||||
imagePreviewVisible: false,
|
|
||||||
currentImageUrl: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
data: {
|
|
||||||
handler(val) {
|
|
||||||
if (val && val.updateTime) {
|
|
||||||
this.excelList = [{
|
|
||||||
fileName: '电子发票--购买方公司信息.xlsx',
|
|
||||||
createUserName: '系统生成',
|
|
||||||
createTime: val.updateTime,
|
|
||||||
isSystemGenerated: true
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate: true,
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
isPdf(filePath) {
|
|
||||||
return filePath && filePath.toLowerCase().endsWith('.pdf');
|
|
||||||
},
|
|
||||||
getImageUrl(resource) {
|
|
||||||
return process.env.VUE_APP_BASE_API + "/common/download/resource?resource=" + resource;
|
|
||||||
},
|
|
||||||
handlePreview(row) {
|
|
||||||
if (this.isPdf(row.filePath)) {
|
|
||||||
request({
|
|
||||||
url: '/common/download/resource',
|
|
||||||
method: 'get',
|
|
||||||
params: { resource: row.filePath },
|
|
||||||
responseType: 'blob'
|
|
||||||
}).then(res => {
|
|
||||||
const blob = new Blob([res.data], { type: 'application/pdf' });
|
|
||||||
this.currentPdfUrl = URL.createObjectURL(blob);
|
|
||||||
this.pdfPreviewVisible = true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.currentImageUrl = this.getImageUrl(row.filePath);
|
|
||||||
this.imagePreviewVisible = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleDownload(row) {
|
|
||||||
if (row.isSystemGenerated) {
|
|
||||||
request({
|
|
||||||
url: '/finance/invoice/export/' + this.data.invoiceBillCode,
|
|
||||||
method: 'get'
|
|
||||||
}).then(res => {
|
|
||||||
window.location.href = process.env.VUE_APP_BASE_API + "/common/download?fileName=" + encodeURIComponent(res.msg) + "&delete=true";
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = this.getImageUrl(row.filePath);
|
|
||||||
link.download = row.fileName || 'attachment';
|
|
||||||
link.style.display = 'none';
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.invoice-detail {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,304 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
|
||||||
<el-form-item label="开票编号" prop="invoiceBillCode">
|
|
||||||
<el-input v-model="queryParams.invoiceBillCode" placeholder="请输入开票编号" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="进货商" prop="partnerName">
|
|
||||||
<el-input v-model="queryParams.partnerName" placeholder="请输入进货商" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="提交日期">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
size="mini"
|
|
||||||
@click="toApproved()"
|
|
||||||
>审批历史</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="invoiceList">
|
|
||||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
|
||||||
<el-table-column label="开票编号" align="center" prop="invoiceBillCode" />
|
|
||||||
<el-table-column label="进货商" align="center" prop="partnerName" />
|
|
||||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span :style="scope.row.totalPriceWithTax < 0 ? 'color: red' : ''">{{ formatCurrency(scope.row.totalPriceWithTax) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="提交日期" align="center" prop="applyTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.applyTime, '{y}-{m}-{d}') }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(scope.row)">审批</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
|
||||||
|
|
||||||
<!-- 审批详情主对话框 -->
|
|
||||||
<el-dialog title="开票单审批" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
|
||||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
|
||||||
<div style="display: flex;flex-direction: row-reverse; margin-bottom: 10px;">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="exportPDF"
|
|
||||||
:loading="pdfExporting"
|
|
||||||
>导出PDF</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="approve-container" :class="{ 'exporting-pdf': pdfExporting }">
|
|
||||||
<ApproveLayout ref="approveLayout" title="开票单详情">
|
|
||||||
<receivable-invoice-detail :data="form"></receivable-invoice-detail>
|
|
||||||
<template #footer>
|
|
||||||
<span>{{ form.invoiceBillCode }}</span>
|
|
||||||
</template>
|
|
||||||
</ApproveLayout>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider content-position="left">流转意见</el-divider>
|
|
||||||
<div class="process-container">
|
|
||||||
<el-timeline>
|
|
||||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
|
||||||
<el-card>
|
|
||||||
<h4>{{ log.approveOpinion }}</h4>
|
|
||||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
|
||||||
<p><b>审批状态:</b> <el-tag :type="log.approveStatus == '3' ? 'success' : log.approveStatus == '2' ? 'danger' : 'info'">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
|
||||||
</el-card>
|
|
||||||
</el-timeline-item>
|
|
||||||
</el-timeline>
|
|
||||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="openOpinionDialog('approve')">同意</el-button>
|
|
||||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳回</el-button>
|
|
||||||
<el-button @click="detailDialogVisible = false">取 消</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 审批意见对话框 -->
|
|
||||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="30%" append-to-body>
|
|
||||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
|
||||||
<el-form-item label="审批意见" prop="approveOpinion">
|
|
||||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="opinionDialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="showConfirmDialog()">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listInvoiceApprove, getInvoiceDetail } from "@/api/finance/invoice";
|
|
||||||
import { approveTask, listCompletedFlows } from "@/api/flow";
|
|
||||||
import ReceivableInvoiceDetail from "./components/ReceivableInvoiceDetail";
|
|
||||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ReceivableInvoiceRefundApprove",
|
|
||||||
components: { ReceivableInvoiceDetail, ApproveLayout },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
invoiceList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
invoiceBillCode: null,
|
|
||||||
partnerName: null,
|
|
||||||
projectName: null,
|
|
||||||
processKey: 'finance_invoice_refound',
|
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
dateRange: [],
|
|
||||||
detailDialogVisible: false,
|
|
||||||
detailLoading: false,
|
|
||||||
form: {},
|
|
||||||
approveLogs: [],
|
|
||||||
opinionDialogVisible: false,
|
|
||||||
confirmDialogTitle: '',
|
|
||||||
currentApproveType: '',
|
|
||||||
opinionForm: {
|
|
||||||
approveOpinion: ''
|
|
||||||
},
|
|
||||||
opinionRules: {
|
|
||||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
|
||||||
},
|
|
||||||
processKey: 'finance_invoice_refound',
|
|
||||||
taskId: null,
|
|
||||||
currentInvoiceId: null,
|
|
||||||
pdfExporting: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listInvoiceApprove(this.addDateRange(this.queryParams, this.dateRange, 'ApplyTime')).then(response => {
|
|
||||||
this.invoiceList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
toApproved() {
|
|
||||||
this.$router.push('/approve/receivableInvoiceRefundLog')
|
|
||||||
},
|
|
||||||
handleApprove(row) {
|
|
||||||
this.resetDetailForm();
|
|
||||||
this.currentInvoiceId = row.id;
|
|
||||||
this.taskId = row.taskId;
|
|
||||||
this.detailLoading = true;
|
|
||||||
this.detailDialogVisible = true;
|
|
||||||
|
|
||||||
getInvoiceDetail(this.currentInvoiceId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.loadApproveHistory(this.form.invoiceBillCode);
|
|
||||||
this.detailLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.detailLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetDetailForm() {
|
|
||||||
this.form = {};
|
|
||||||
this.approveLogs = [];
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
},
|
|
||||||
loadApproveHistory(businessKey) {
|
|
||||||
if (businessKey) {
|
|
||||||
let keys = [];
|
|
||||||
if(this.processKey) keys.push(this.processKey);
|
|
||||||
|
|
||||||
listCompletedFlows({ businessKey: businessKey, processKeyList: keys }).then(response => {
|
|
||||||
this.approveLogs = response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openOpinionDialog(type) {
|
|
||||||
this.currentApproveType = type;
|
|
||||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批';
|
|
||||||
this.opinionDialogVisible = true;
|
|
||||||
this.opinionForm.approveOpinion = '';
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if(this.$refs.opinionForm) this.$refs.opinionForm.clearValidate();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showConfirmDialog() {
|
|
||||||
this.$refs.opinionForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
this.opinionDialogVisible = false;
|
|
||||||
this.submitApproval();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
submitApproval() {
|
|
||||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0;
|
|
||||||
const params = {
|
|
||||||
businessKey: this.form.invoiceBillCode,
|
|
||||||
processKey: this.processKey,
|
|
||||||
taskId: this.taskId,
|
|
||||||
variables: {
|
|
||||||
comment: this.opinionForm.approveOpinion,
|
|
||||||
approveBtn: approveBtn
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
approveTask(params).then(() => {
|
|
||||||
this.$modal.msgSuccess(this.confirmDialogTitle + "成功");
|
|
||||||
this.detailDialogVisible = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getStatusText(status) {
|
|
||||||
if (!status) {
|
|
||||||
return '提交审批'
|
|
||||||
}
|
|
||||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
|
||||||
return map[status] || '提交审批';
|
|
||||||
},
|
|
||||||
async exportPDF() {
|
|
||||||
this.pdfExporting = true;
|
|
||||||
try {
|
|
||||||
const element = this.$refs.approveLayout.$el;
|
|
||||||
const fileName = `开票单-${this.form.invoiceBillCode || ''}.pdf`;
|
|
||||||
await exportElementToPDF(element, fileName);
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('PDF导出失败:', error);
|
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
|
||||||
} finally {
|
|
||||||
this.pdfExporting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.process-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导出PDF时的特殊样式 */
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--primary,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-button--text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__inner,
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-textarea__inner {
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
resize: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.approve-container.exporting-pdf ::v-deep .el-input__suffix {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -135,7 +135,8 @@
|
||||||
import { approveOrder,getOrder } from "@/api/approve/order";
|
import { approveOrder,getOrder } from "@/api/approve/order";
|
||||||
import ConfigInfo from './ConfigInfo.vue';
|
import ConfigInfo from './ConfigInfo.vue';
|
||||||
import ApproveLayout from '@/views/approve/ApproveLayout.vue';
|
import ApproveLayout from '@/views/approve/ApproveLayout.vue';
|
||||||
import { exportElementToPDF } from "@/views/approve/finance/pdfUtils";
|
import html2canvas from 'html2canvas';
|
||||||
|
import jsPDF from 'jspdf';
|
||||||
|
|
||||||
import OrderInfoDisplay from '@/views/project/order/components/OrderInfoDisplay.vue';
|
import OrderInfoDisplay from '@/views/project/order/components/OrderInfoDisplay.vue';
|
||||||
|
|
||||||
|
|
@ -467,21 +468,65 @@ export default {
|
||||||
// 导出PDF
|
// 导出PDF
|
||||||
async exportPDF() {
|
async exportPDF() {
|
||||||
this.pdfExporting = true;
|
this.pdfExporting = true;
|
||||||
|
const disabledElements = [];
|
||||||
try {
|
try {
|
||||||
// 获取ApproveLayout组件的DOM元素
|
// 获取ApproveLayout组件的DOM元素
|
||||||
const element = this.$refs.approveLayout.$el;
|
const element = this.$refs.approveLayout.$el;
|
||||||
|
|
||||||
|
// 移除所有输入框的 disabled 属性,以便在PDF中正确显示
|
||||||
|
element.querySelectorAll('input:disabled, textarea:disabled').forEach(el => {
|
||||||
|
disabledElements.push(el);
|
||||||
|
el.disabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 使用html2canvas捕获内容
|
||||||
|
const canvas = await html2canvas(element, {
|
||||||
|
scale: 2, // 提高清晰度
|
||||||
|
useCORS: true, // 允许跨域图片
|
||||||
|
logging: false, // 关闭日志
|
||||||
|
backgroundColor: '#F8F5F0' // 设置背景色
|
||||||
|
});
|
||||||
|
|
||||||
|
// 计算PDF页面尺寸
|
||||||
|
const imgWidth = 210; // A4纸宽度(mm)
|
||||||
|
const pageHeight = 297; // A4纸高度(mm)
|
||||||
|
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
||||||
|
let heightLeft = imgHeight;
|
||||||
|
|
||||||
|
// 创建PDF
|
||||||
|
const pdf = new jsPDF('p', 'mm', 'a4');
|
||||||
|
let position = 0;
|
||||||
|
|
||||||
|
// 将canvas转换为图片
|
||||||
|
const imgData = canvas.toDataURL('image/jpeg');
|
||||||
|
|
||||||
|
// 添加第一页
|
||||||
|
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
|
||||||
|
heightLeft -= pageHeight;
|
||||||
|
|
||||||
|
// 如果内容超过一页,添加更多页
|
||||||
|
while (heightLeft > 0) {
|
||||||
|
position = heightLeft - imgHeight;
|
||||||
|
pdf.addPage();
|
||||||
|
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
|
||||||
|
heightLeft -= pageHeight;
|
||||||
|
}
|
||||||
|
|
||||||
// 生成文件名
|
// 生成文件名
|
||||||
const fileName = `${this.order.projectCode || '订单'}-${this.order.orderCode || ''}-Rev.${this.order.versionCode || '1'}.pdf`;
|
const fileName = `${this.order.projectCode || '订单'}-${this.order.orderCode || ''}-Rev.${this.order.versionCode || '1'}.pdf`;
|
||||||
|
|
||||||
// 调用通用方法导出PDF
|
// 保存PDF
|
||||||
await exportElementToPDF(element, fileName);
|
pdf.save(fileName);
|
||||||
|
|
||||||
this.$modal.msgSuccess('PDF导出成功');
|
this.$modal.msgSuccess('PDF导出成功');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('PDF导出失败:', error);
|
console.error('PDF导出失败:', error);
|
||||||
this.$modal.msgError('PDF导出失败,请稍后重试');
|
this.$modal.msgError('PDF导出失败,请稍后重试');
|
||||||
} finally {
|
} finally {
|
||||||
|
// 恢复之前移除的 disabled 属性
|
||||||
|
disabledElements.forEach(el => {
|
||||||
|
el.disabled = true;
|
||||||
|
});
|
||||||
this.pdfExporting = false;
|
this.pdfExporting = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
<td v-if="!hidePrice">{{ product.discount ? (product.discount * 100).toFixed(2) + '%' : '-' }}</td>
|
<td v-if="!hidePrice">{{ product.discount ? (product.discount * 100).toFixed(2) + '%' : '-' }}</td>
|
||||||
<td>{{ formatCurrency(product.price) }}</td>
|
<td>{{ formatCurrency(product.price) }}</td>
|
||||||
<td>{{ selectedDiscountLabel }}</td>
|
<td>{{ selectedDiscountLabel }}</td>
|
||||||
<td>{{ formatCurrency(getDisplayAllPrice(product, selectedDiscount)) }}</td>
|
<td>{{ formatCurrency(product.allPrice) }}</td>
|
||||||
<td>{{ formatCurrency(getDiscountedAllPrice(product, selectedDiscount)) }}</td>
|
<td>{{ formatCurrency(getDiscountedAllPrice(product, selectedDiscount)) }}</td>
|
||||||
<td>
|
<td>
|
||||||
<el-input
|
<el-input
|
||||||
|
|
@ -86,7 +86,7 @@
|
||||||
<td v-if="!hidePrice">{{ product.discount ? (product.discount * 100).toFixed(2) + '%' : '-' }}</td>
|
<td v-if="!hidePrice">{{ product.discount ? (product.discount * 100).toFixed(2) + '%' : '-' }}</td>
|
||||||
<td>{{ formatCurrency(product.price) }}</td>
|
<td>{{ formatCurrency(product.price) }}</td>
|
||||||
<td>{{ selectedDiscountLabel }}</td>
|
<td>{{ selectedDiscountLabel }}</td>
|
||||||
<td>{{ formatCurrency(getDisplayAllPrice(product, selectedDiscount)) }}</td>
|
<td>{{ formatCurrency(product.allPrice) }}</td>
|
||||||
<td>{{ formatCurrency(getDiscountedAllPrice(product, selectedDiscount)) }}</td>
|
<td>{{ formatCurrency(getDiscountedAllPrice(product, selectedDiscount)) }}</td>
|
||||||
<td>
|
<td>
|
||||||
<el-input
|
<el-input
|
||||||
|
|
@ -142,7 +142,7 @@
|
||||||
<td v-if="!hidePrice">{{ product.discount ? (product.discount * 100).toFixed(2) + '%' : '-' }}</td>
|
<td v-if="!hidePrice">{{ product.discount ? (product.discount * 100).toFixed(2) + '%' : '-' }}</td>
|
||||||
<td>{{ formatCurrency(product.price) }}</td>
|
<td>{{ formatCurrency(product.price) }}</td>
|
||||||
<td>{{ selectedDiscountLabel }}</td>
|
<td>{{ selectedDiscountLabel }}</td>
|
||||||
<td>{{ formatCurrency(getDisplayAllPrice(product, selectedDiscount)) }}</td>
|
<td>{{ formatCurrency(product.allPrice) }}</td>
|
||||||
<td>{{ formatCurrency(getDiscountedAllPrice(product, selectedDiscount)) }}</td>
|
<td>{{ formatCurrency(getDiscountedAllPrice(product, selectedDiscount)) }}</td>
|
||||||
<td>
|
<td>
|
||||||
<el-input
|
<el-input
|
||||||
|
|
@ -178,7 +178,7 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row type="flex" justify="end" align="middle" class="summary-row">
|
<el-row type="flex" justify="end" align="middle" class="summary-row">
|
||||||
<el-col :span="orderData.orderStatus==='1'?18:24" style="text-align: center;">
|
<el-col :span="18" style="text-align: center;">
|
||||||
<span style="margin-right: 5px;">商业折扣</span>
|
<span style="margin-right: 5px;">商业折扣</span>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="selectedDiscount"
|
v-model="selectedDiscount"
|
||||||
|
|
@ -195,7 +195,7 @@
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6" v-if="orderData.orderStatus==='1'">
|
<el-col :span="6">
|
||||||
<span class="summary-label"> 折后总价合计</span> <span
|
<span class="summary-label"> 折后总价合计</span> <span
|
||||||
class="summary-value-right"> {{ formatCurrency(finalTotal) }}</span>
|
class="summary-value-right"> {{ formatCurrency(finalTotal) }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -278,12 +278,7 @@ export default {
|
||||||
return this.calculateTotal(this.order.maintenanceProjectProductInfoList, this.selectedDiscount);
|
return this.calculateTotal(this.order.maintenanceProjectProductInfoList, this.selectedDiscount);
|
||||||
},
|
},
|
||||||
grandTotal() {
|
grandTotal() {
|
||||||
if (this.orderData.orderStatus === '1'){
|
|
||||||
|
|
||||||
return this.softwareTotal + this.hardwareTotal + this.maintenanceTotal;
|
return this.softwareTotal + this.hardwareTotal + this.maintenanceTotal;
|
||||||
}else{
|
|
||||||
return this.finalTotal;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
finalTotal() {
|
finalTotal() {
|
||||||
return this.softwareDiscountedTotal + this.hardwareDiscountedTotal + this.maintenanceDiscountedTotal;
|
return this.softwareDiscountedTotal + this.hardwareDiscountedTotal + this.maintenanceDiscountedTotal;
|
||||||
|
|
@ -302,20 +297,13 @@ export default {
|
||||||
// 税率变化时通知父组件
|
// 税率变化时通知父组件
|
||||||
this.$emit('tax-rate-change', product);
|
this.$emit('tax-rate-change', product);
|
||||||
},
|
},
|
||||||
getDisplayAllPrice(product, discount) {
|
|
||||||
const allPrice = product.allPrice || 0;
|
|
||||||
if (this.order.orderStatus === '2' || this.order.orderStatus === 2) {
|
|
||||||
return this.$calc.div(allPrice, discount || 1);
|
|
||||||
}
|
|
||||||
return allPrice;
|
|
||||||
},
|
|
||||||
getDiscountedAllPrice(product, discount) {
|
getDiscountedAllPrice(product, discount) {
|
||||||
const allPrice = product.allPrice || 0;
|
if (discount === 1) {
|
||||||
if (this.order.orderStatus === '2' || this.order.orderStatus === 2) {
|
return product.allPrice;
|
||||||
return allPrice;
|
|
||||||
}
|
}
|
||||||
const discountedPrice = this.$calc.mul(product.price || 0, discount == null ? 1 : discount, 2);
|
const roundedDiscountedUnitPrice = this.$calc.mul( product.price,discount);
|
||||||
return this.$calc.mul(discountedPrice, product.quantity || 0, 2);
|
|
||||||
|
return this.$calc.mul(roundedDiscountedUnitPrice , product.quantity);
|
||||||
},
|
},
|
||||||
calculateTotal(productList, discount) {
|
calculateTotal(productList, discount) {
|
||||||
if (!productList) return 0;
|
if (!productList) return 0;
|
||||||
|
|
|
||||||
|
|
@ -49,28 +49,15 @@
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="产品编码" prop="productCode">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.productCode"
|
|
||||||
placeholder="请输入产品编码"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="产品型号" prop="productModel">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.productModel"
|
|
||||||
placeholder="请输入产品型号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -88,12 +75,7 @@
|
||||||
<el-table-column label="项目名称" align="center" prop="projectName" />
|
<el-table-column label="项目名称" align="center" prop="projectName" />
|
||||||
<el-table-column label="项目编号" align="center" prop="projectCode" />
|
<el-table-column label="项目编号" align="center" prop="projectCode" />
|
||||||
<el-table-column label="客户名称" align="center" prop="customerName" />
|
<el-table-column label="客户名称" align="center" prop="customerName" />
|
||||||
|
<el-table-column label="订单金额" align="center" prop="actualPurchaseAmount" />
|
||||||
<el-table-column label="订单金额" align="center" prop="actualPurchaseAmount" >
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ formatCurrency(scope.row.actualPurchaseAmount || scope.row.shipmentAmount) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="汇智负责人" align="center" prop="dutyName" />
|
<el-table-column label="汇智负责人" align="center" prop="dutyName" />
|
||||||
<el-table-column label="审批节点" align="center" prop="approveNode">
|
<el-table-column label="审批节点" align="center" prop="approveNode">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
|
|
@ -124,7 +106,6 @@
|
||||||
<el-dialog
|
<el-dialog
|
||||||
title="订单审批"
|
title="订单审批"
|
||||||
:visible.sync="approveDialogVisible"
|
:visible.sync="approveDialogVisible"
|
||||||
:close-on-click-modal="false"
|
|
||||||
custom-class="approve-dialog"
|
custom-class="approve-dialog"
|
||||||
width="80%"
|
width="80%"
|
||||||
top="5vh"
|
top="5vh"
|
||||||
|
|
@ -149,7 +130,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { listOrder } from "@/api/approve/order";
|
import { listOrder } from "@/api/approve/order";
|
||||||
import ApproveDialog from './Approve.vue';
|
import ApproveDialog from './Approve.vue';
|
||||||
import {formatCurrency} from "../../../utils";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Order",
|
name: "Order",
|
||||||
|
|
@ -176,14 +156,9 @@ export default {
|
||||||
orderCode: null,
|
orderCode: null,
|
||||||
projectName: null,
|
projectName: null,
|
||||||
projectCode: null,
|
projectCode: null,
|
||||||
productCode: null,
|
|
||||||
productModel: null,
|
|
||||||
customerName: null,
|
customerName: null,
|
||||||
dutyName: null,
|
dutyName: null,
|
||||||
approveNode: null,
|
approveNode: null,
|
||||||
orderStatus: '1',
|
|
||||||
orderByColumn: 't2.id',
|
|
||||||
isAsc: 'desc',
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -191,7 +166,6 @@ export default {
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatCurrency,
|
|
||||||
toApproved(){
|
toApproved(){
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: '/approve/orderLog',
|
path: '/approve/orderLog',
|
||||||
|
|
|
||||||
|
|
@ -23,22 +23,7 @@
|
||||||
end-placeholder="结束日期"
|
end-placeholder="结束日期"
|
||||||
></el-date-picker>
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="产品编码" prop="productCode">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.productCode"
|
|
||||||
placeholder="请输入产品编码"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="产品型号" prop="productModel">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.productModel"
|
|
||||||
placeholder="请输入产品型号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
|
@ -157,15 +142,12 @@ export default {
|
||||||
buyerName: null,
|
buyerName: null,
|
||||||
vendorName: null,
|
vendorName: null,
|
||||||
ownerName: null,
|
ownerName: null,
|
||||||
productCode: null,
|
|
||||||
productModel: null,
|
|
||||||
approveStatus: '1',
|
approveStatus: '1',
|
||||||
params:{
|
params:{
|
||||||
applyTimeStart: null,
|
applyTimeStart: null,
|
||||||
applyTimeEnd: null,
|
applyTimeEnd: null,
|
||||||
},
|
}
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
},
|
||||||
// 时间范围选择器
|
// 时间范围选择器
|
||||||
dateRangeApplyTime: [],
|
dateRangeApplyTime: [],
|
||||||
|
|
|
||||||
|
|
@ -23,22 +23,7 @@
|
||||||
end-placeholder="结束日期"
|
end-placeholder="结束日期"
|
||||||
></el-date-picker>
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="产品编码" prop="productCode">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.productCode"
|
|
||||||
placeholder="请输入产品编码"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="产品型号" prop="productModel">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.productModel"
|
|
||||||
placeholder="请输入产品型号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
|
@ -149,16 +134,12 @@ export default {
|
||||||
purchaseNo: null,
|
purchaseNo: null,
|
||||||
buyerName: null,
|
buyerName: null,
|
||||||
vendorName: null,
|
vendorName: null,
|
||||||
productCode: null,
|
|
||||||
productModel: null,
|
|
||||||
ownerName: null,
|
ownerName: null,
|
||||||
approveStatus: '3', // 已审批状态通常为3
|
approveStatus: '3', // 已审批状态通常为3
|
||||||
params:{
|
params:{
|
||||||
applyTimeStart: null,
|
applyTimeStart: null,
|
||||||
applyTimeEnd: null,
|
applyTimeEnd: null,
|
||||||
},
|
}
|
||||||
orderByColumn: 'applyTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
},
|
||||||
// 时间范围选择器
|
// 时间范围选择器
|
||||||
dateRangeApplyTime: [],
|
dateRangeApplyTime: [],
|
||||||
|
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-drawer
|
|
||||||
title="报价单详情"
|
|
||||||
:visible.sync="visible"
|
|
||||||
direction="rtl"
|
|
||||||
size="80%"
|
|
||||||
:before-close="handleClose"
|
|
||||||
append-to-body
|
|
||||||
>
|
|
||||||
<div class="detail-container" v-loading="loading">
|
|
||||||
<!-- Basic Info -->
|
|
||||||
<el-divider content-position="left">基本信息</el-divider>
|
|
||||||
<el-descriptions :column="2" border size="medium">
|
|
||||||
<el-descriptions-item label="报价单号">{{ form.quotationCode }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="报价单名称">{{ form.quotationName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="币种">
|
|
||||||
<dict-tag :options="dict.type.currency_type" :value="form.amountType"/>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="代表处">{{ agentName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="客户名称">{{ form.customerName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="状态">{{ form.quotationStatus }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="创建时间">{{ parseTime(form.createTime) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="备注" :span="2">{{ form.remark }}</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<div v-if="form.quotationCode || catalogueTotalPrice > 0 || discountedTotalPrice > 0" style="margin-top: 20px;">
|
|
||||||
<el-row type="flex" justify="space-between" style="margin-bottom: 20px; font-size: 14px;">
|
|
||||||
<el-col :span="24" style="text-align: right;">
|
|
||||||
<span v-if="catalogueTotalPrice > 0" style="margin-right: 20px;">
|
|
||||||
<span style="font-weight: bold;">目录总价:</span>{{ formatAmount(catalogueTotalPrice) }}
|
|
||||||
</span>
|
|
||||||
<span v-if="discountedTotalPrice > 0">
|
|
||||||
<span style="font-weight: bold;">折后总价:</span>{{ formatAmount(discountedTotalPrice) }}
|
|
||||||
</span>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Config Info -->
|
|
||||||
<product-config :value="form" readonly />
|
|
||||||
</div>
|
|
||||||
</el-drawer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getQuotation } from "@/api/base/quotation";
|
|
||||||
import ProductConfig from "@/views/project/info/ProductConfig";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "QuotationDetail",
|
|
||||||
components: { ProductConfig },
|
|
||||||
dicts: ['currency_type'],
|
|
||||||
props: {
|
|
||||||
agentOptions: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
visible: false,
|
|
||||||
loading: false,
|
|
||||||
form: {
|
|
||||||
softwareProjectProductInfoList: [],
|
|
||||||
hardwareProjectProductInfoList: [],
|
|
||||||
maintenanceProjectProductInfoList: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
agentName() {
|
|
||||||
if (!this.form.agentCode || !this.agentOptions) return this.form.agentCode;
|
|
||||||
const agent = this.agentOptions.find(item => item.agentCode === this.form.agentCode);
|
|
||||||
return agent ? agent.agentName : this.form.agentCode;
|
|
||||||
},
|
|
||||||
catalogueTotalPrice() {
|
|
||||||
let total = 0;
|
|
||||||
const lists = [
|
|
||||||
this.form.softwareProjectProductInfoList,
|
|
||||||
this.form.hardwareProjectProductInfoList,
|
|
||||||
this.form.maintenanceProjectProductInfoList
|
|
||||||
];
|
|
||||||
lists.forEach(list => {
|
|
||||||
if (list && list.length > 0) {
|
|
||||||
list.forEach(item => {
|
|
||||||
total += Number(item.catalogueAllPrice) || 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return total;
|
|
||||||
},
|
|
||||||
discountedTotalPrice() {
|
|
||||||
let total = 0;
|
|
||||||
const lists = [
|
|
||||||
this.form.softwareProjectProductInfoList,
|
|
||||||
this.form.hardwareProjectProductInfoList,
|
|
||||||
this.form.maintenanceProjectProductInfoList
|
|
||||||
];
|
|
||||||
lists.forEach(list => {
|
|
||||||
if (list && list.length > 0) {
|
|
||||||
list.forEach(item => {
|
|
||||||
total += Number(item.allPrice) || 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
open(id) {
|
|
||||||
this.visible = true;
|
|
||||||
this.getDetail(id);
|
|
||||||
},
|
|
||||||
getDetail(id) {
|
|
||||||
this.loading = true;
|
|
||||||
getQuotation(id).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
// Ensure lists are arrays
|
|
||||||
this.form.softwareProjectProductInfoList = this.form.softwareProjectProductInfoList || [];
|
|
||||||
this.form.hardwareProjectProductInfoList = this.form.hardwareProjectProductInfoList || [];
|
|
||||||
this.form.maintenanceProjectProductInfoList = this.form.maintenanceProjectProductInfoList || [];
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleClose(done) {
|
|
||||||
this.visible = false;
|
|
||||||
if (done) done();
|
|
||||||
},
|
|
||||||
formatAmount(value) {
|
|
||||||
if (value === null || value === undefined) return '';
|
|
||||||
return Number(value).toLocaleString('en-US', {
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
maximumFractionDigits: 2
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<style scoped>
|
|
||||||
.detail-container {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,602 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
|
||||||
<el-form-item label="报价单号" prop="quotationCode">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.quotationCode"
|
|
||||||
placeholder="请输入报价单号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="报价单" prop="quotationName">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.quotationName"
|
|
||||||
placeholder="请输入报价单名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="状态" prop="quotationStatus">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.quotationStatus"
|
|
||||||
placeholder="请输入状态"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="创建时间">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
type="datetimerange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
icon="el-icon-plus"
|
|
||||||
size="mini"
|
|
||||||
@click="handleAdd"
|
|
||||||
v-hasPermi="['sip:quotation:add']"
|
|
||||||
>新增</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="success"
|
|
||||||
plain
|
|
||||||
icon="el-icon-edit"
|
|
||||||
size="mini"
|
|
||||||
:disabled="single"
|
|
||||||
@click="handleUpdate"
|
|
||||||
v-hasPermi="['sip:quotation:update']"
|
|
||||||
>修改</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
plain
|
|
||||||
icon="el-icon-delete"
|
|
||||||
size="mini"
|
|
||||||
:disabled="multiple"
|
|
||||||
@click="handleDelete"
|
|
||||||
v-hasPermi="['sip:quotation:delete']"
|
|
||||||
>删除</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="quotationList" @selection-change="handleSelectionChange">
|
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
|
||||||
<el-table-column label="报价单号" align="center" prop="quotationCode" />
|
|
||||||
<el-table-column label="报价单" align="center" prop="quotationName" />
|
|
||||||
<el-table-column label="项目编号" align="center" prop="projectCode" />
|
|
||||||
<!-- <el-table-column label="报价金额" align="center" prop="quotationAmount" />-->
|
|
||||||
<el-table-column label="报价金额(¥)" align="center" prop="discountAmount" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)" />
|
|
||||||
<el-table-column label="状态" align="center" prop="quotationStatus" >
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.quotation_status" :value="scope.row.quotationStatus"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="创建人" align="center" prop="createByName" />
|
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="备注" align="center" prop="remark" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-view"
|
|
||||||
@click="handleDetail(scope.row)"
|
|
||||||
>详情</el-button>
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-edit"
|
|
||||||
@click="handleUpdate(scope.row)"
|
|
||||||
v-hasPermi="['sip:quotation:update']"
|
|
||||||
>修改</el-button>
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-document-copy"
|
|
||||||
@click="handleCopy(scope.row)"
|
|
||||||
v-hasPermi="['sip:quotation:add']"
|
|
||||||
>复制创建</el-button>
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-delete"
|
|
||||||
@click="handleDelete(scope.row)"
|
|
||||||
v-hasPermi="['sip:quotation:delete']"
|
|
||||||
>删除</el-button>
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-download"
|
|
||||||
@click="handleExport(scope.row)"
|
|
||||||
v-hasPermi="['sip:quotation:export']"
|
|
||||||
>导出</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination
|
|
||||||
v-show="total>0"
|
|
||||||
:total="total"
|
|
||||||
:page.sync="queryParams.pageNum"
|
|
||||||
:limit.sync="queryParams.pageSize"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 添加或修改报价单对话框 -->
|
|
||||||
<el-dialog :title="title" :visible.sync="open" width="80%" append-to-body :close-on-click-modal="false" @close="cancel">
|
|
||||||
<el-steps :active="activeStep" simple finish-status="success" style="margin-bottom: 20px; cursor: pointer;">
|
|
||||||
<el-step icon="el-icon-caret-left" @click.native="handleStepClick(0)">
|
|
||||||
<template #title>
|
|
||||||
<i class="el-icon-caret-left"></i>
|
|
||||||
报价单列表
|
|
||||||
</template>
|
|
||||||
</el-step>
|
|
||||||
<el-step title="设置基本信息" @click.native="handleStepClick(1)"></el-step>
|
|
||||||
<el-step title="配置信息" @click.native="handleStepClick(2)"></el-step>
|
|
||||||
</el-steps>
|
|
||||||
|
|
||||||
<div v-if="form.quotationCode || catalogueTotalPrice > 0 || discountedTotalPrice > 0">
|
|
||||||
<el-divider></el-divider>
|
|
||||||
<el-row type="flex" justify="space-between" style="margin-bottom: 20px; font-size: 14px;">
|
|
||||||
<el-col :span="8">
|
|
||||||
<span v-if="form.quotationCode">
|
|
||||||
<span style="font-weight: bold;">报价单号:</span>{{ form.quotationCode }}
|
|
||||||
</span>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="16" style="text-align: right;">
|
|
||||||
<span v-if="catalogueTotalPrice > 0" style="margin-right: 20px;">
|
|
||||||
<span style="font-weight: bold;">目录总价:</span>{{ formatAmount(catalogueTotalPrice) }}
|
|
||||||
</span>
|
|
||||||
<span v-if="discountedTotalPrice > 0">
|
|
||||||
<span style="font-weight: bold;">折后总价:</span>{{ formatAmount(discountedTotalPrice) }}
|
|
||||||
</span>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-divider></el-divider>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px" style="max-height: 50vh;overflow-y: auto;padding: 10px">
|
|
||||||
<!-- Step 1 Content: Basic Info -->
|
|
||||||
<div v-show="activeStep === 1">
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="报价单名称" prop="quotationName">
|
|
||||||
<el-input v-model="form.quotationName" placeholder="请输入报价单名称" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="币种" prop="amountType">
|
|
||||||
<el-select v-model="form.amountType" placeholder="请选择币种" style="width: 100%">
|
|
||||||
<el-option
|
|
||||||
v-for="dict in dict.type.currency_type"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="代表处" prop="agentCode">
|
|
||||||
<el-select v-model="form.agentCode" placeholder="请选择代表处" style="width: 100%">
|
|
||||||
<el-option
|
|
||||||
v-for="item in agentOptions"
|
|
||||||
:key="item.agentCode"
|
|
||||||
:label="item.agentName"
|
|
||||||
:value="item.agentCode"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="客户名称" prop="customerName">
|
|
||||||
<el-input v-model="form.customerName" placeholder="请输入客户名称" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-form-item label="报价单备注" prop="remark">
|
|
||||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Step 2 Content: Config Info -->
|
|
||||||
<div v-show="activeStep === 2">
|
|
||||||
<product-config :value="form" @input="updateProductConfig" />
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<div v-if="activeStep === 1">
|
|
||||||
<el-button @click="cancel">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="nextStep">下一步</el-button>
|
|
||||||
</div>
|
|
||||||
<div v-if="activeStep === 2">
|
|
||||||
<el-button @click="prevStep">上一步</el-button>
|
|
||||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
<quotation-detail ref="detail" :agent-options="agentOptions" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listQuotation, getQuotation, delQuotation, addQuotation, updateQuotation,exportSingleQuotation } from "@/api/base/quotation";
|
|
||||||
import { listAgent } from "@/api/system/agent";
|
|
||||||
import ProductConfig from "@/views/project/info/ProductConfig";
|
|
||||||
import QuotationDetail from "./detail";
|
|
||||||
import {isEmpty} from "@/utils/validate";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Quotation",
|
|
||||||
components: {
|
|
||||||
ProductConfig,
|
|
||||||
QuotationDetail
|
|
||||||
},
|
|
||||||
dicts: ['currency_type','quotation_status'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 当前激活步骤
|
|
||||||
activeStep: 1,
|
|
||||||
// 遮罩层
|
|
||||||
loading: true,
|
|
||||||
// 选中数组
|
|
||||||
ids: [],
|
|
||||||
// 非单个禁用
|
|
||||||
single: true,
|
|
||||||
// 非多个禁用
|
|
||||||
multiple: true,
|
|
||||||
// 显示搜索条件
|
|
||||||
showSearch: true,
|
|
||||||
// 总条数
|
|
||||||
total: 0,
|
|
||||||
// 报价单表格数据
|
|
||||||
quotationList: [],
|
|
||||||
// 日期范围
|
|
||||||
dateRange: [],
|
|
||||||
// 代表处选项
|
|
||||||
agentOptions: [],
|
|
||||||
// 弹出层标题
|
|
||||||
title: "",
|
|
||||||
// 是否显示弹出层
|
|
||||||
open: false,
|
|
||||||
// 查询参数
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
quotationCode: null,
|
|
||||||
quotationName: null,
|
|
||||||
projectCode: null,
|
|
||||||
quotationStatus: null,
|
|
||||||
createTimeStart: null,
|
|
||||||
createTimeEnd: null,
|
|
||||||
isAsc : 'desc',
|
|
||||||
orderByColumn : 'createTime',
|
|
||||||
},
|
|
||||||
// 表单参数
|
|
||||||
form: {
|
|
||||||
softwareProjectProductInfoList: [],
|
|
||||||
hardwareProjectProductInfoList: [],
|
|
||||||
maintenanceProjectProductInfoList: []
|
|
||||||
},
|
|
||||||
// 表单校验
|
|
||||||
rules: {
|
|
||||||
quotationName: [
|
|
||||||
{ required: true, message: "报价单名称不能为空", trigger: "blur" }
|
|
||||||
],
|
|
||||||
amountType: [
|
|
||||||
{ required: true, message: "币种不能为空", trigger: "change" }
|
|
||||||
],
|
|
||||||
agentCode: [
|
|
||||||
{ required: true, message: "代表处不能为空", trigger: "change" }
|
|
||||||
],
|
|
||||||
customerName: [
|
|
||||||
{ required: true, message: "客户名称不能为空", trigger: "blur" }
|
|
||||||
],
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
catalogueTotalPrice() {
|
|
||||||
let total = 0;
|
|
||||||
const lists = [
|
|
||||||
this.form.softwareProjectProductInfoList,
|
|
||||||
this.form.hardwareProjectProductInfoList,
|
|
||||||
this.form.maintenanceProjectProductInfoList
|
|
||||||
];
|
|
||||||
lists.forEach(list => {
|
|
||||||
if (list && list.length > 0) {
|
|
||||||
list.forEach(item => {
|
|
||||||
total += Number(item.catalogueAllPrice) || 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return total;
|
|
||||||
},
|
|
||||||
discountedTotalPrice() {
|
|
||||||
let total = 0;
|
|
||||||
const lists = [
|
|
||||||
this.form.softwareProjectProductInfoList,
|
|
||||||
this.form.hardwareProjectProductInfoList,
|
|
||||||
this.form.maintenanceProjectProductInfoList
|
|
||||||
];
|
|
||||||
lists.forEach(list => {
|
|
||||||
if (list && list.length > 0) {
|
|
||||||
list.forEach(item => {
|
|
||||||
total += Number(item.allPrice) || 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
this.getAgentList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** 查询报价单列表 */
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
if (null != this.dateRange && '' != this.dateRange) {
|
|
||||||
this.queryParams.createTimeStart = this.dateRange[0];
|
|
||||||
this.queryParams.createTimeEnd = this.dateRange[1];
|
|
||||||
}
|
|
||||||
listQuotation(this.queryParams).then(response => {
|
|
||||||
this.quotationList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleDetail(row) {
|
|
||||||
this.$refs.detail.open(row.id);
|
|
||||||
},
|
|
||||||
handleExport(row){
|
|
||||||
this.$modal.confirm('是否确认导出已审批的采购数据项?').then(() => {
|
|
||||||
return exportSingleQuotation(row.id);
|
|
||||||
}).then(response => {
|
|
||||||
this.$download.download( response.msg)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
/** 查询代表处列表 */
|
|
||||||
getAgentList() {
|
|
||||||
listAgent().then(response => {
|
|
||||||
this.agentOptions = response.rows;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 取消按钮
|
|
||||||
cancel() {
|
|
||||||
this.open = false;
|
|
||||||
this.reset();
|
|
||||||
this.activeStep = 1;
|
|
||||||
},
|
|
||||||
// 表单重置
|
|
||||||
reset() {
|
|
||||||
this.form = {
|
|
||||||
id: null,
|
|
||||||
quotationCode: null,
|
|
||||||
quotationName: null,
|
|
||||||
projectCode: null,
|
|
||||||
quotationAmount: null,
|
|
||||||
discountAmount: null,
|
|
||||||
quotationStatus: null,
|
|
||||||
createBy: null,
|
|
||||||
createTime: null,
|
|
||||||
updateBy: null,
|
|
||||||
updateTime: null,
|
|
||||||
remark: null,
|
|
||||||
agentCode: null,
|
|
||||||
amountType: null,
|
|
||||||
customerName: null,
|
|
||||||
softwareProjectProductInfoList: [],
|
|
||||||
hardwareProjectProductInfoList: [],
|
|
||||||
maintenanceProjectProductInfoList: []
|
|
||||||
};
|
|
||||||
this.resetForm("form");
|
|
||||||
},
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
/** 重置按钮操作 */
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.queryParams.createTimeStart = null;
|
|
||||||
this.queryParams.createTimeEnd = null;
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
// 多选框选中数据
|
|
||||||
handleSelectionChange(selection) {
|
|
||||||
this.ids = selection.map(item => item.id)
|
|
||||||
this.single = selection.length!==1
|
|
||||||
this.multiple = !selection.length
|
|
||||||
},
|
|
||||||
/** 新增按钮操作 */
|
|
||||||
handleAdd() {
|
|
||||||
this.reset();
|
|
||||||
this.open = true;
|
|
||||||
this.activeStep = 1;
|
|
||||||
this.title = "添加报价单";
|
|
||||||
},
|
|
||||||
/** 复制创建 */
|
|
||||||
handleCopy(row) {
|
|
||||||
this.reset();
|
|
||||||
const id = row.id || this.ids
|
|
||||||
getQuotation(id).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
// Reset ID and Code for new creation
|
|
||||||
this.form.id = null;
|
|
||||||
this.form.quotationCode = null;
|
|
||||||
this.form.quotationStatus = null;
|
|
||||||
this.form.createTime = null;
|
|
||||||
this.form.updateTime = null;
|
|
||||||
this.form.createBy = null;
|
|
||||||
this.form.updateBy = null;
|
|
||||||
|
|
||||||
// Ensure product lists are initialized if null
|
|
||||||
this.form.softwareProjectProductInfoList = this.form.softwareProjectProductInfoList || [];
|
|
||||||
this.form.hardwareProjectProductInfoList = this.form.hardwareProjectProductInfoList || [];
|
|
||||||
this.form.maintenanceProjectProductInfoList = this.form.maintenanceProjectProductInfoList || [];
|
|
||||||
|
|
||||||
// Clear IDs in configuration lists to ensure they are created as new records
|
|
||||||
const clearIds = (list) => {
|
|
||||||
if (list && list.length > 0) {
|
|
||||||
list.forEach(item => {
|
|
||||||
item.id = null;
|
|
||||||
item.quotationId = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
clearIds(this.form.softwareProjectProductInfoList);
|
|
||||||
clearIds(this.form.hardwareProjectProductInfoList);
|
|
||||||
clearIds(this.form.maintenanceProjectProductInfoList);
|
|
||||||
|
|
||||||
this.open = true;
|
|
||||||
this.activeStep = 1;
|
|
||||||
this.title = "复制创建报价单";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 修改按钮操作 */
|
|
||||||
handleUpdate(row) {
|
|
||||||
this.reset();
|
|
||||||
const id = row.id || this.ids
|
|
||||||
getQuotation(id).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
// Ensure product lists are initialized if null
|
|
||||||
this.form.softwareProjectProductInfoList = this.form.softwareProjectProductInfoList || [];
|
|
||||||
this.form.hardwareProjectProductInfoList = this.form.hardwareProjectProductInfoList || [];
|
|
||||||
this.form.maintenanceProjectProductInfoList = this.form.maintenanceProjectProductInfoList || [];
|
|
||||||
this.open = true;
|
|
||||||
this.activeStep = 1;
|
|
||||||
this.title = "修改报价单";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 处理步骤点击 */
|
|
||||||
handleStepClick(stepIndex) {
|
|
||||||
if (stepIndex === 0) {
|
|
||||||
this.cancel();
|
|
||||||
} else if (stepIndex === 1) {
|
|
||||||
this.activeStep = 1;
|
|
||||||
} else if (stepIndex === 2) {
|
|
||||||
// Validate step 1 before going to step 2
|
|
||||||
this.$refs["form"].validateField(['quotationName', 'amountType', 'agentCode', 'customerName'], (errorMessage) => {
|
|
||||||
if (!errorMessage) {
|
|
||||||
this.activeStep = 2;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/** 下一步 */
|
|
||||||
nextStep() {
|
|
||||||
// 校验Step 1的字段
|
|
||||||
this.$refs["form"].validateField(['quotationName', 'amountType', 'agentCode', 'customerName'], (errorMessage) => {
|
|
||||||
if (!errorMessage) {
|
|
||||||
this.activeStep = 2;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 上一步 */
|
|
||||||
prevStep() {
|
|
||||||
this.activeStep = 1;
|
|
||||||
},
|
|
||||||
updateProductConfig(data) {
|
|
||||||
this.form.softwareProjectProductInfoList = data.softwareProjectProductInfoList;
|
|
||||||
this.form.hardwareProjectProductInfoList = data.hardwareProjectProductInfoList;
|
|
||||||
this.form.maintenanceProjectProductInfoList = data.maintenanceProjectProductInfoList;
|
|
||||||
},
|
|
||||||
formatAmount(value) {
|
|
||||||
if (value === null || value === undefined) return '';
|
|
||||||
return Number(value).toLocaleString('en-US', {
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
maximumFractionDigits: 2
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 提交按钮 */
|
|
||||||
submitForm() {
|
|
||||||
this.$refs["form"].validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
const checkProduct=(list)=>isEmpty(list) ||( !isEmpty(list) && list.every(item => item.productBomCode!==''))
|
|
||||||
if (!checkProduct(this.form.softwareProjectProductInfoList) || !checkProduct(this.form.hardwareProjectProductInfoList) || !checkProduct(this.form.maintenanceProjectProductInfoList)) {
|
|
||||||
this.$modal.msgError("请完善产品信息");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.form.quotationAmount = this.catalogueTotalPrice;
|
|
||||||
this.form.discountAmount = this.discountedTotalPrice;
|
|
||||||
if (this.form.id != null) {
|
|
||||||
updateQuotation(this.form).then(response => {
|
|
||||||
this.$modal.msgSuccess("修改成功");
|
|
||||||
this.open = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
addQuotation(this.form).then(response => {
|
|
||||||
this.$modal.msgSuccess("新增成功");
|
|
||||||
this.open = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 删除按钮操作 */
|
|
||||||
handleDelete(row) {
|
|
||||||
const ids = row.id || this.ids;
|
|
||||||
this.$modal.confirm('是否确认删除报价单?').then(function() {
|
|
||||||
return delQuotation(ids);
|
|
||||||
}).then(() => {
|
|
||||||
this.getList();
|
|
||||||
this.$modal.msgSuccess("删除成功");
|
|
||||||
}).catch(() => {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<style scoped>
|
|
||||||
/* 只有第一步显示自定义图标,覆盖完成状态的对勾 */
|
|
||||||
::v-deep .el-step:first-child .el-step__icon-inner.is-status {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
::v-deep .el-step:first-child .el-step__icon-inner:not(.is-status) {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 当前激活步骤标题颜色鲜明 */
|
|
||||||
::v-deep .el-step__title.is-process {
|
|
||||||
color: #1890ff;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 当前激活步骤图标颜色鲜明 */
|
|
||||||
::v-deep .el-step__head.is-process {
|
|
||||||
color: #1890ff;
|
|
||||||
border-color: #1890ff;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,126 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-dialog title="选择报价单" :visible.sync="visible" :close-on-click-modal="false" width="900px" append-to-body @close="handleClose">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" @submit.native.prevent>
|
|
||||||
<el-form-item label="报价单号" prop="quotationCode">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.quotationCode"
|
|
||||||
placeholder="请输入报价单号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="报价单名称" prop="quotationName">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.quotationName"
|
|
||||||
placeholder="请输入报价单名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="quotationList" @row-click="handleRowClick" highlight-current-row>
|
|
||||||
<el-table-column label="报价单号" align="center" prop="quotationCode" />
|
|
||||||
<el-table-column label="报价单名称" align="center" prop="quotationName" />
|
|
||||||
<el-table-column label="项目编号" align="center" prop="projectCode" />
|
|
||||||
<el-table-column label="报价金额" align="center" prop="discountAmount" />
|
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination
|
|
||||||
v-show="total>0"
|
|
||||||
:total="total"
|
|
||||||
:page.sync="queryParams.pageNum"
|
|
||||||
:limit.sync="queryParams.pageSize"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="handleClose">取 消</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listQuotation } from "@/api/base/quotation";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "SelectQuotation",
|
|
||||||
props: {
|
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
createBy: {
|
|
||||||
type: String,
|
|
||||||
default: "-1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 遮罩层
|
|
||||||
loading: true,
|
|
||||||
// 总条数
|
|
||||||
total: 0,
|
|
||||||
// 报价单表格数据
|
|
||||||
quotationList: [],
|
|
||||||
// 查询参数
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
// createBy: this.createBy,
|
|
||||||
quotationCode: null,
|
|
||||||
quotationName: null,
|
|
||||||
orderByColumn: 'createTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible(val) {
|
|
||||||
if (val) {
|
|
||||||
// this.queryParams.createBy = this.createBy||"-1";
|
|
||||||
this.getList();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** 查询报价单列表 */
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listQuotation(this.queryParams).then(response => {
|
|
||||||
this.quotationList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
/** 重置按钮操作 */
|
|
||||||
resetQuery() {
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
/** 行点击事件 */
|
|
||||||
handleRowClick(row) {
|
|
||||||
this.$emit("quotation-selected", row);
|
|
||||||
this.handleClose();
|
|
||||||
},
|
|
||||||
/** 关闭按钮 */
|
|
||||||
handleClose() {
|
|
||||||
this.$emit("update:visible", false);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -9,17 +9,17 @@
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="制造商名称" prop="vendorAddress">
|
<el-form-item label="制造商名称" prop="vendorName">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.vendorAddress"
|
v-model="queryParams.vendorName"
|
||||||
placeholder="请输入制造商名称"
|
placeholder="请输入制造商名称"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="制造商全称" prop="vendorName">
|
<el-form-item label="制造商全称" prop="vendorAddress">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.vendorName"
|
v-model="queryParams.vendorAddress"
|
||||||
placeholder="请输入制造商全称"
|
placeholder="请输入制造商全称"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
|
|
@ -98,8 +98,8 @@
|
||||||
<el-table v-loading="loading" :data="vendorList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="vendorList" @selection-change="handleSelectionChange">
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="制造商编码" align="center" prop="vendorCode" />
|
<el-table-column label="制造商编码" align="center" prop="vendorCode" />
|
||||||
<el-table-column label="制造商名称" align="center" prop="vendorAddress" />
|
<el-table-column label="制造商名称" align="center" prop="vendorName" />
|
||||||
<el-table-column label="制造商全称" align="center" prop="vendorName" />
|
<el-table-column label="制造商全称" align="center" prop="vendorAddress" />
|
||||||
<el-table-column label="默认仓库" align="center" prop="warehouseName" />
|
<el-table-column label="默认仓库" align="center" prop="warehouseName" />
|
||||||
<el-table-column label="联系人" align="center" prop="vendorUser" />
|
<el-table-column label="联系人" align="center" prop="vendorUser" />
|
||||||
<el-table-column label="联系邮箱" align="center" prop="vendorEmail" />
|
<el-table-column label="联系邮箱" align="center" prop="vendorEmail" />
|
||||||
|
|
@ -147,13 +147,13 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="制造商名称" prop="vendorAddress">
|
<el-form-item label="制造商名称" prop="vendorName">
|
||||||
<el-input v-model="form.vendorAddress" placeholder="请输入制造商名称" />
|
<el-input v-model="form.vendorName" placeholder="请输入制造商名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-form-item label="制造商全称" prop="vendorName">
|
<el-form-item label="制造商全称" prop="vendorAddress">
|
||||||
<el-input v-model="form.vendorName" placeholder="请输入制造商全称" />
|
<el-input v-model="form.vendorAddress" placeholder="请输入制造商全称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
|
|
@ -301,8 +301,6 @@ export default {
|
||||||
loading: true,
|
loading: true,
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 选中制造商编码
|
|
||||||
selectedVendorCodes: [],
|
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
single: true,
|
single: true,
|
||||||
// 非多个禁用
|
// 非多个禁用
|
||||||
|
|
@ -332,8 +330,6 @@ export default {
|
||||||
vendorAddress: null,
|
vendorAddress: null,
|
||||||
vendorUser: null,
|
vendorUser: null,
|
||||||
vendorStatus: null,
|
vendorStatus: null,
|
||||||
isAsc : 'desc',
|
|
||||||
orderByColumn : 'createTime',
|
|
||||||
},
|
},
|
||||||
// 表单参数
|
// 表单参数
|
||||||
form: {
|
form: {
|
||||||
|
|
@ -456,7 +452,6 @@ export default {
|
||||||
// 多选框选中数据
|
// 多选框选中数据
|
||||||
handleSelectionChange(selection) {
|
handleSelectionChange(selection) {
|
||||||
this.ids = selection.map(item => item.vendorId)
|
this.ids = selection.map(item => item.vendorId)
|
||||||
this.selectedVendorCodes = selection.map(item => item.vendorCode)
|
|
||||||
this.single = selection.length!==1
|
this.single = selection.length!==1
|
||||||
this.multiple = !selection.length
|
this.multiple = !selection.length
|
||||||
},
|
},
|
||||||
|
|
@ -529,12 +524,8 @@ export default {
|
||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
const queryParams = {
|
const queryParams = this.queryParams;
|
||||||
...this.queryParams,
|
this.$modal.confirm('是否确认导出所有制造商信息数据项?').then(() => {
|
||||||
vendorCodeList: this.selectedVendorCodes.length ? this.selectedVendorCodes : undefined
|
|
||||||
};
|
|
||||||
const exportTip = this.selectedVendorCodes.length ? '是否确认导出选中的制造商信息数据项?' : '是否确认导出所有制造商信息数据项?';
|
|
||||||
this.$modal.confirm(exportTip).then(() => {
|
|
||||||
this.exportLoading = true;
|
this.exportLoading = true;
|
||||||
return exportVendor(queryParams);
|
return exportVendor(queryParams);
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
|
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
|
|
||||||
<el-form-item label="SN码" prop="productSn">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.productSn"
|
|
||||||
placeholder="请输入SN码"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="inventoryInfoList">
|
|
||||||
<el-table-column label="SN码" align="center" prop="productSn" />
|
|
||||||
<el-table-column label="入库单号" align="center" prop="innerCode" />
|
|
||||||
<el-table-column label="出库单号" align="center" prop="outerCode" />
|
|
||||||
<el-table-column label="订单编号" align="center" prop="orderCode" />
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination
|
|
||||||
v-show="total>0"
|
|
||||||
:total="total"
|
|
||||||
:page.sync="queryParams.pageNum"
|
|
||||||
:limit.sync="queryParams.pageSize"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listInventoryInfoByProductSn } from '@/api/dataProcess/inventoryInfo'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'DataProcessInventoryInfo',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: false,
|
|
||||||
showSearch: true,
|
|
||||||
total: 0,
|
|
||||||
inventoryInfoList: [],
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
productSn: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.loading = true
|
|
||||||
listInventoryInfoByProductSn(this.queryParams).then(response => {
|
|
||||||
this.inventoryInfoList = response.rows
|
|
||||||
this.total = response.total
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1
|
|
||||||
this.getList()
|
|
||||||
},
|
|
||||||
resetQuery() {
|
|
||||||
this.resetForm('queryForm')
|
|
||||||
this.handleQuery()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,301 +0,0 @@
|
||||||
<template xmlns="http://www.w3.org/1999/html">
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
|
|
||||||
<el-form-item label="项目编号" prop="projectCode">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.projectCode"
|
|
||||||
placeholder="请输入项目编号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.projectName"
|
|
||||||
placeholder="请输入项目名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="代表处" prop="agentName">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.agentName"
|
|
||||||
placeholder="请输入代表处"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="汇智负责人" prop="hzSupportUserName">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.hzSupportUserName"
|
|
||||||
placeholder="请输入汇智负责人"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<br/>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
icon="el-icon-edit"
|
|
||||||
size="mini"
|
|
||||||
@click="handleTransfer"
|
|
||||||
v-hasPermi="['sip:project:add']"
|
|
||||||
>转移</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="projectList" @selection-change="handleSelectionChange" @sort-change="handleSortChange">
|
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
|
||||||
<el-table-column label="项目编号" align="center" prop="projectCode" width="100" />
|
|
||||||
<el-table-column label="项目名称" align="center" prop="projectName" width="300">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ scope.row.projectName }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="最终客户" align="center" prop="customerName" width="200" />
|
|
||||||
<el-table-column label="BG" align="center" prop="bgProperty" width="70">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.bg_type" :value="scope.row.bgProperty"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="行业" align="center" prop="industryType" width="70">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag v-if="scope.row.bgProperty === 'YYS'" :options="dict.type.bg_yys" :value="scope.row.industryType"/>
|
|
||||||
<dict-tag v-else :options="dict.type.bg_hysy" :value="scope.row.industryType"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="代表处" align="center" prop="agentName" width="70" />
|
|
||||||
<el-table-column label="项目把握度" align="center" prop="projectGraspDegree" width="70" />
|
|
||||||
<el-table-column label="预计金额(元)" align="center" prop="estimatedAmount" width="120" sortable="custom" :sort-orders="['descending', 'ascending']">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ formatAmountNumber(scope.row.estimatedAmount) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="项目阶段" align="center" prop="projectStage" width="160">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.project_stage" :value="scope.row.projectStage"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="建设类型" align="center" prop="constructionType" width="120" />
|
|
||||||
<el-table-column label="汇智负责人" align="center" prop="hzSupportUserName" width="100" />
|
|
||||||
<el-table-column label="POC" align="center" prop="poc" width="60">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ scope.row.poc === '1' ? '是' : '否' }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column label="预计下单时间" align="center" prop="estimatedOrderTime" width="140" sortable="custom" :sort-orders="['descending', 'ascending']">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.estimatedOrderTime, '{y}-{m}-{d}') }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="更新时间" align="center" prop="lastWorkUpdateTime" width="160" sortable="custom" :sort-orders="['descending', 'ascending']">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.lastWorkUpdateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="最后操作时间" align="center" prop="updateTime" width="160" sortable="custom" :sort-orders="['descending', 'ascending']">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination
|
|
||||||
v-show="total>0"
|
|
||||||
:total="total"
|
|
||||||
:page.sync="queryParams.pageNum"
|
|
||||||
:limit.sync="queryParams.pageSize"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
<el-dialog title="项目转移" :visible.sync="transferDialogVisible" width="500px" append-to-body>
|
|
||||||
<el-form ref="transferForm" :model="transferForm" :rules="transferRules" label-width="100px">
|
|
||||||
<el-form-item label="原汇智负责人" label-width="130px">
|
|
||||||
<el-input
|
|
||||||
v-model="transferForm.originalHzSupportUserName"
|
|
||||||
placeholder="原汇智负责人"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="新汇智负责人" prop="hzSupportUserName" label-width="130px">
|
|
||||||
<el-input
|
|
||||||
v-model="transferForm.hzSupportUserName"
|
|
||||||
placeholder="请选择新汇智负责人"
|
|
||||||
readonly
|
|
||||||
@click.native="openTransferUserSelect"
|
|
||||||
/>
|
|
||||||
<input type="hidden" v-model="transferForm.hzSupportUser" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="transferDialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="submitTransfer">确 定</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<select-user :visible.sync="selectUserVisible" @user-selected="handleUserSelected" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {listProject, transferProject} from "@/api/dataProcess/projectTransfer";
|
|
||||||
import SelectUser from "@/views/system/user/selectUser.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Project",
|
|
||||||
components: {
|
|
||||||
SelectUser
|
|
||||||
},
|
|
||||||
dicts: ['bg_type', 'bg_yys', 'bg_hysy', 'project_stage'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 遮罩层
|
|
||||||
loading: true,
|
|
||||||
// 选中数组
|
|
||||||
ids: [],
|
|
||||||
// 选中行数据
|
|
||||||
selectedRows: [],
|
|
||||||
// 显示搜索条件
|
|
||||||
showSearch: true,
|
|
||||||
// 总条数
|
|
||||||
total: 0,
|
|
||||||
// 项目管理表格数据
|
|
||||||
projectList: [],
|
|
||||||
// 查询参数
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
projectCode: null,
|
|
||||||
projectName: null,
|
|
||||||
agentName: null,
|
|
||||||
hzSupportUserName: null,
|
|
||||||
isAsc: 'desc',
|
|
||||||
orderByColumn: 'createTime',
|
|
||||||
},
|
|
||||||
selectUserVisible: false,
|
|
||||||
transferDialogVisible: false,
|
|
||||||
transferForm: {
|
|
||||||
originalHzSupportUser: null,
|
|
||||||
originalHzSupportUserName: null,
|
|
||||||
hzSupportUser: null,
|
|
||||||
hzSupportUserName: null,
|
|
||||||
projectIdList: []
|
|
||||||
},
|
|
||||||
transferRules: {
|
|
||||||
hzSupportUserName: [{ required: true, message: "请选择汇智负责人", trigger: "blur" }]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleSortChange(column) {
|
|
||||||
this.queryParams.orderByColumn = column.prop;
|
|
||||||
if (column.order === 'ascending') {
|
|
||||||
this.queryParams.isAsc = 'asc';
|
|
||||||
} else if (column.order === 'descending') {
|
|
||||||
this.queryParams.isAsc = 'desc';
|
|
||||||
} else {
|
|
||||||
this.queryParams.isAsc = null;
|
|
||||||
this.queryParams.orderByColumn = null;
|
|
||||||
}
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
/** 查询项目管理列表 */
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listProject(this.queryParams).then(response => {
|
|
||||||
this.projectList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
/** 重置按钮操作 */
|
|
||||||
resetQuery() {
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
// 多选框选中数据
|
|
||||||
handleSelectionChange(selection) {
|
|
||||||
this.ids = selection.map(item => item.id)
|
|
||||||
this.selectedRows = selection
|
|
||||||
},
|
|
||||||
handleTransfer() {
|
|
||||||
if (!this.selectedRows || this.selectedRows.length === 0) {
|
|
||||||
this.$modal.msgWarning("请至少选择一条数据");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const hasEmptyHzSupportUser = this.selectedRows.some(item => !item.hzSupportUser);
|
|
||||||
if (hasEmptyHzSupportUser) {
|
|
||||||
this.$modal.msgWarning("选中数据存在无汇智负责人的项目,无法转移");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const currentHzSupportUser = this.selectedRows[0].hzSupportUser;
|
|
||||||
const isSameHzSupportUser = this.selectedRows.every(item => item.hzSupportUser === currentHzSupportUser);
|
|
||||||
if (!isSameHzSupportUser) {
|
|
||||||
this.$modal.msgWarning("请选择同一个汇智负责人的项目进行转移");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.transferForm = {
|
|
||||||
originalHzSupportUser: currentHzSupportUser,
|
|
||||||
originalHzSupportUserName: this.selectedRows[0].hzSupportUserName,
|
|
||||||
hzSupportUser: null,
|
|
||||||
hzSupportUserName: null,
|
|
||||||
projectIdList: [...this.ids]
|
|
||||||
};
|
|
||||||
this.transferDialogVisible = true;
|
|
||||||
},
|
|
||||||
openTransferUserSelect() {
|
|
||||||
this.selectUserVisible = true;
|
|
||||||
},
|
|
||||||
handleUserSelected(user) {
|
|
||||||
this.transferForm.hzSupportUser = user.userId;
|
|
||||||
this.transferForm.hzSupportUserName = user.userName;
|
|
||||||
},
|
|
||||||
submitTransfer() {
|
|
||||||
this.$refs["transferForm"].validate(valid => {
|
|
||||||
if (!valid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const params = {
|
|
||||||
originalHzSupportUser: this.transferForm.originalHzSupportUser,
|
|
||||||
originalHzSupportUserName: this.transferForm.originalHzSupportUserName,
|
|
||||||
hzSupportUser: this.transferForm.hzSupportUser,
|
|
||||||
hzSupportUserName: this.transferForm.hzSupportUserName,
|
|
||||||
projectIdList: this.transferForm.projectIdList
|
|
||||||
};
|
|
||||||
transferProject(params).then(() => {
|
|
||||||
this.$modal.msgSuccess("提交成功");
|
|
||||||
this.transferDialogVisible = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 格式化金额 */
|
|
||||||
formatAmountNumber(value) {
|
|
||||||
if (value) {
|
|
||||||
return Number(value).toLocaleString('en-US');
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,310 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
|
|
||||||
<el-form-item label="项目编号" prop="projectCode">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.projectCode"
|
|
||||||
placeholder="请输入项目编号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="项目名称" prop="projectName">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.projectName"
|
|
||||||
placeholder="请输入项目名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="进货商" prop="partnerName">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.partnerName"
|
|
||||||
placeholder="请输入进货商"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<!-- <el-col :span="1.5">-->
|
|
||||||
<!-- <el-button-->
|
|
||||||
<!-- type="danger"-->
|
|
||||||
<!-- plain-->
|
|
||||||
<!-- icon="el-icon-delete"-->
|
|
||||||
<!-- size="mini"-->
|
|
||||||
<!-- :disabled="multiple"-->
|
|
||||||
<!-- @click="handleDelete"-->
|
|
||||||
<!-- v-hasPermi="['finance:charge:remove']"-->
|
|
||||||
<!-- >删除</el-button>-->
|
|
||||||
<!-- </el-col>-->
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="warning"
|
|
||||||
plain
|
|
||||||
icon="el-icon-download"
|
|
||||||
size="mini"
|
|
||||||
@click="handleExport"
|
|
||||||
v-hasPermi="['finance:charge:export']"
|
|
||||||
>导出</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="chargeList" @selection-change="handleSelectionChange">
|
|
||||||
<!-- <el-table-column type="selection" width="55" align="center" />-->
|
|
||||||
<el-table-column label="项目编码" align="center" prop="projectCode" width="180" v-if="columns.projectCode.visible" key="projectCode"/>
|
|
||||||
<el-table-column label="项目名称" align="center" prop="projectName" width="240" v-if="columns.projectName.visible" key="projectName"/>
|
|
||||||
<el-table-column label="合同编号" align="center" prop="orderCode" width="180" v-if="columns.orderCode.visible" key="orderCode"/>
|
|
||||||
<el-table-column label="下单通路" align="center" prop="orderChannel" width="100" v-if="columns.orderChannel.visible" key="orderChannel">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-tag>{{ scope.row.orderChannel==='1'? "总代":"直签" }}</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="供货商" align="center" prop="supplier" width="180" v-if="columns.supplier.visible" key="supplier"/>
|
|
||||||
<el-table-column label="进货商" align="center" prop="partnerName" width="180" v-if="columns.partnerName.visible" key="partnerName"/>
|
|
||||||
<el-table-column label="业务侧可计收时间" align="center" prop="bizChargeDate" width="180" v-if="columns.bizChargeDate.visible" key="bizChargeDate">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.bizChargeDate, '{y}-{m}-{d}') }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="财务计收时间" align="center" prop="financeChargeDate" width="180" v-if="columns.financeChargeDate.visible" key="financeChargeDate">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.financeChargeDate, '{y}-{m}-{d}') }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="收入" align="center" v-if="columns.incomeWithTaxTotal.visible || columns.incomeWithoutTaxTotal.visible || columns.incomeTax.visible">
|
|
||||||
<el-table-column label="含税总价(元)" align="center" prop="incomeWithTaxTotal" width="180" v-if="columns.incomeWithTaxTotal.visible" key="incomeWithTaxTotal" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="未含税总价(元)" align="center" prop="incomeWithoutTaxTotal" width="180" v-if="columns.incomeWithoutTaxTotal.visible" key="incomeWithoutTaxTotal" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="税额(元)" align="center" prop="incomeTax" width="180" v-if="columns.incomeTax.visible" key="incomeTax">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ formatCurrency($calc.sub(scope.row.incomeWithTaxTotal, scope.row.incomeWithoutTaxTotal)) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="成本" align="center" v-if="columns.costSoftwareWithoutTax.visible || columns.costHardwareWithoutTax.visible || columns.costSoftwareMaintWithoutTax.visible || columns.costHardwareMaintWithoutTax.visible || columns.costProvinceServiceWithoutTax.visible || columns.costOtherWithoutTax.visible || columns.allCostWithoutTax.visible">
|
|
||||||
<el-table-column label="软件折后未税小计" align="center" prop="costSoftwareWithoutTax" width="180" v-if="columns.costSoftwareWithoutTax.visible" key="costSoftwareWithoutTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="硬件折后未税小计" align="center" prop="costHardwareWithoutTax" width="180" v-if="columns.costHardwareWithoutTax.visible" key="costHardwareWithoutTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="软件维保折后未税小计" align="center" prop="costSoftwareMaintWithoutTax" width="180" v-if="columns.costSoftwareMaintWithoutTax.visible" key="costSoftwareMaintWithoutTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="硬件维保折后未税小计" align="center" prop="costHardwareMaintWithoutTax" width="180" v-if="columns.costHardwareMaintWithoutTax.visible" key="costHardwareMaintWithoutTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="省代服务折后未税小计" align="center" prop="costProvinceServiceWithoutTax" width="180" v-if="columns.costProvinceServiceWithoutTax.visible" key="costProvinceServiceWithoutTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="其它折后未税小计" align="center" prop="costOtherWithoutTax" width="180" v-if="columns.costOtherWithoutTax.visible" key="costOtherWithoutTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="成本未税合计" align="center" prop="allCostWithoutTax" width="180" v-if="columns.allCostWithoutTax.visible" key="allCostWithoutTax" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)">
|
|
||||||
|
|
||||||
</el-table-column>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="毛利" align="center" prop="grossProfit" width="180" v-if="columns.grossProfit.visible" key="grossProfit" :formatter="(row, column, cellValue)=>formatCurrency(cellValue)"/>
|
|
||||||
<el-table-column label="毛利率" align="center" prop="grossProfitRate" width="180" v-if="columns.grossProfitRate.visible" key="grossProfitRate"/>
|
|
||||||
<el-table-column label="备注" align="center" prop="remark" width="180" v-if="columns.remark.visible" key="remark"/>
|
|
||||||
<el-table-column label="操作" align="center" width="180" class-name="small-padding fixed-width">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-edit"
|
|
||||||
@click="handleRemark(scope.row)"
|
|
||||||
v-hasPermi="['finance:charge:edit']"
|
|
||||||
>编辑备注</el-button>
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-refresh-left"
|
|
||||||
@click="handleRevoke(scope.row)"
|
|
||||||
v-hasPermi="['finance:charge:remove']"
|
|
||||||
>撤销</el-button>
|
|
||||||
<!-- <el-button-->
|
|
||||||
<!-- size="mini"-->
|
|
||||||
<!-- type="text"-->
|
|
||||||
<!-- icon="el-icon-delete"-->
|
|
||||||
<!-- @click="handleDelete(scope.row)"-->
|
|
||||||
<!-- v-hasPermi="['finance:charge:remove']"-->
|
|
||||||
<!-- >删除</el-button>-->
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination
|
|
||||||
v-show="total>0"
|
|
||||||
:total="total"
|
|
||||||
:page.sync="queryParams.pageNum"
|
|
||||||
:limit.sync="queryParams.pageSize"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 编辑备注对话框 -->
|
|
||||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
|
||||||
<el-form ref="form" :model="form" label-width="80px">
|
|
||||||
<el-form-item label="备注" prop="remark">
|
|
||||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注内容" :rows="4" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
|
||||||
<el-button @click="cancel">取 消</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listCharge, getCharge, delCharge, updateCharge, revokeCharge } from "@/api/finance/charge";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Charge",
|
|
||||||
dicts: ['finance_charge_status'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 遮罩层
|
|
||||||
loading: true,
|
|
||||||
// 选中数组
|
|
||||||
ids: [],
|
|
||||||
// 非单个禁用
|
|
||||||
single: true,
|
|
||||||
// 非多个禁用
|
|
||||||
multiple: true,
|
|
||||||
// 显示搜索条件
|
|
||||||
showSearch: true,
|
|
||||||
// 总条数
|
|
||||||
total: 0,
|
|
||||||
// 财务计收表格数据
|
|
||||||
chargeList: [],
|
|
||||||
// 弹出层标题
|
|
||||||
title: "",
|
|
||||||
// 是否显示弹出层
|
|
||||||
open: false,
|
|
||||||
// 查询参数
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
projectCode: null,
|
|
||||||
projectName: null,
|
|
||||||
partnerName: null,
|
|
||||||
orderByColumn:'createTime',
|
|
||||||
isAsc: 'desc'
|
|
||||||
},
|
|
||||||
// 列信息
|
|
||||||
columns: {
|
|
||||||
projectCode: { label: '项目编码', visible: true },
|
|
||||||
projectName: { label: '项目名称', visible: true },
|
|
||||||
orderCode: { label: '合同编号', visible: true },
|
|
||||||
orderChannel: { label: '下单通路', visible: true },
|
|
||||||
supplier: { label: '供货商', visible: true },
|
|
||||||
partnerName: { label: '进货商', visible: true },
|
|
||||||
bizChargeDate: { label: '业务侧可计收时间', visible: true },
|
|
||||||
financeChargeDate: { label: '财务计收时间', visible: true },
|
|
||||||
incomeWithTaxTotal: { label: '含税总价(元)', visible: true },
|
|
||||||
incomeWithoutTaxTotal: { label: '未含税总价(元)', visible: true },
|
|
||||||
incomeTax: { label: '税额(元)', visible: true },
|
|
||||||
costSoftwareWithoutTax: { label: '软件折后未税小计', visible: true },
|
|
||||||
costHardwareWithoutTax: { label: '硬件折后未税小计', visible: true },
|
|
||||||
costSoftwareMaintWithoutTax: { label: '软件维保折后未税小计', visible: true },
|
|
||||||
costHardwareMaintWithoutTax: { label: '硬件维保折后未税小计', visible: true },
|
|
||||||
costProvinceServiceWithoutTax: { label: '省代服务折后未税小计', visible: true },
|
|
||||||
costOtherWithoutTax: { label: '其它折后未税小计', visible: true },
|
|
||||||
allCostWithoutTax: { label: '成本未税合计', visible: true },
|
|
||||||
grossProfit: { label: '毛利', visible: true },
|
|
||||||
grossProfitRate: { label: '毛利率', visible: true },
|
|
||||||
remark: { label: '备注', visible: true }
|
|
||||||
},
|
|
||||||
// 表单参数
|
|
||||||
form: {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** 查询财务计收列表 */
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listCharge(this.queryParams).then(response => {
|
|
||||||
this.chargeList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 取消按钮
|
|
||||||
cancel() {
|
|
||||||
this.open = false;
|
|
||||||
this.reset();
|
|
||||||
},
|
|
||||||
// 表单重置
|
|
||||||
reset() {
|
|
||||||
this.form = {
|
|
||||||
id: null,
|
|
||||||
remark: null,
|
|
||||||
};
|
|
||||||
this.resetForm("form");
|
|
||||||
},
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
/** 重置按钮操作 */
|
|
||||||
resetQuery() {
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
/** 多选框选中数据 */
|
|
||||||
handleSelectionChange(selection) {
|
|
||||||
this.ids = selection.map(item => item.id)
|
|
||||||
this.single = selection.length!==1
|
|
||||||
this.multiple = !selection.length
|
|
||||||
},
|
|
||||||
/** 编辑备注按钮操作 */
|
|
||||||
handleRemark(row) {
|
|
||||||
this.reset();
|
|
||||||
const id = row.id || this.ids
|
|
||||||
// 使用 getCharge 获取最新数据回显,或者直接用 row 赋值
|
|
||||||
getCharge(id).then(response => {
|
|
||||||
this.form = {
|
|
||||||
id: response.data.id,
|
|
||||||
remark: response.data.remark
|
|
||||||
};
|
|
||||||
this.open = true;
|
|
||||||
this.title = "编辑备注";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 撤销按钮操作 */
|
|
||||||
handleRevoke(row) {
|
|
||||||
this.$modal.confirm('是否确认撤销该条数据?').then(function() {
|
|
||||||
return revokeCharge({id: row.id});
|
|
||||||
}).then(() => {
|
|
||||||
this.getList();
|
|
||||||
this.$modal.msgSuccess("撤销成功");
|
|
||||||
}).catch(() => {});
|
|
||||||
},
|
|
||||||
/** 提交按钮 */
|
|
||||||
submitForm() {
|
|
||||||
// 仅提交备注修改
|
|
||||||
updateCharge({id:this.form.id,remark:this.form.remark}).then(response => {
|
|
||||||
this.$modal.msgSuccess("修改成功");
|
|
||||||
this.open = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 删除按钮操作 */
|
|
||||||
handleDelete(row) {
|
|
||||||
const ids = row.id || this.ids;
|
|
||||||
this.$modal.confirm('是否确认删除财务计收编号为"' + ids + '"的数据项?').then(function() {
|
|
||||||
return delCharge(ids);
|
|
||||||
}).then(() => {
|
|
||||||
this.getList();
|
|
||||||
this.$modal.msgSuccess("删除成功");
|
|
||||||
}).catch(() => {});
|
|
||||||
},
|
|
||||||
/** 导出按钮操作 */
|
|
||||||
handleExport() {
|
|
||||||
this.download('finance/charge/export', {
|
|
||||||
...this.queryParams
|
|
||||||
}, `charge_${new Date().getTime()}.xlsx`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue