Compare commits
6 Commits
1a4f64865a
...
94348aebc4
| Author | SHA1 | Date |
|---|---|---|
|
|
94348aebc4 | |
|
|
1d842d3bf2 | |
|
|
da0a5c8014 | |
|
|
1bdc88cd7c | |
|
|
86de8e2b0a | |
|
|
7afab80e0c |
|
|
@ -0,0 +1,27 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询采购应付单列表
|
||||||
|
export function listPayable(query) {
|
||||||
|
return request({
|
||||||
|
url: '/finance/payable/list',
|
||||||
|
method: 'post',
|
||||||
|
data: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询付款计划列表
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -21,8 +21,11 @@ export function getUser(userId) {
|
||||||
// 新增用户
|
// 新增用户
|
||||||
export function addUser(data) {
|
export function addUser(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user',
|
url: '/system/user/add',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
},
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -45,14 +48,14 @@ export function delUser(userId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户密码重置
|
// 用户密码重置
|
||||||
export function resetUserPwd(userId, password) {
|
export function resetUserPwd(data) {
|
||||||
const data = {
|
|
||||||
userId,
|
|
||||||
password
|
|
||||||
}
|
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/resetPwd',
|
url: '/system/user/resetPwd',
|
||||||
method: 'put',
|
method: 'post',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
},
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +119,7 @@ export function uploadAvatar(data) {
|
||||||
// 查询授权角色
|
// 查询授权角色
|
||||||
export function getAuthRole(userId) {
|
export function getAuthRole(userId) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/user/authRole/' + userId,
|
url: '/system/user/vue/authRole/' + userId,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1764836070482" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4880" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M480 480m-160 0a2.5 2.5 0 1 0 320 0 2.5 2.5 0 1 0-320 0Z" p-id="4881"></path></svg>
|
||||||
|
After Width: | Height: | Size: 416 B |
|
|
@ -0,0 +1,106 @@
|
||||||
|
<template>
|
||||||
|
<div style="width: 100%">
|
||||||
|
<el-input-number style="width: 100%"
|
||||||
|
v-bind="$attrs"
|
||||||
|
:value="displayValue"
|
||||||
|
@input="onInput"
|
||||||
|
@change="onChange"
|
||||||
|
@blur="onBlur"
|
||||||
|
@focus="onFocus"
|
||||||
|
>
|
||||||
|
<slot/>
|
||||||
|
</el-input-number>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {isNumberStr} from "@/utils";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TaxRateInput",
|
||||||
|
|
||||||
|
props: {
|
||||||
|
// 父组件实际值(未放大的值),例如 0.01
|
||||||
|
value: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
|
||||||
|
// 显示值 : 实际值 = ratio : 1
|
||||||
|
ratio: {
|
||||||
|
type: Number,
|
||||||
|
default: 100
|
||||||
|
},
|
||||||
|
|
||||||
|
// 显示值的小数位精度,比如 2 表示显示保留两位小数
|
||||||
|
precision: {
|
||||||
|
type: Number,
|
||||||
|
default: 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
innerDisplayValue: "" // 用户看到的值(已按比例放大)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
value: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal) {
|
||||||
|
this.innerDisplayValue = this.formatDisplay(newVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
displayValue() {
|
||||||
|
return this.innerDisplayValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
// 将实际值转换为显示值
|
||||||
|
formatDisplay(val) {
|
||||||
|
if (val === null || val === "" || isNaN(val) ) return "";
|
||||||
|
// 按精度格式化
|
||||||
|
return this.$calc.mul(val, this.ratio);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 将显示值转换为实际值
|
||||||
|
parseActual(val) {
|
||||||
|
if (val === null || val === "" || isNaN(val)) return "";
|
||||||
|
|
||||||
|
let num = this.$calc.div(val, this.ratio, 4);
|
||||||
|
|
||||||
|
// 输出给父组件时默认保留更高精度
|
||||||
|
return num;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// 用户输入
|
||||||
|
onInput(val) {
|
||||||
|
this.innerDisplayValue = val;
|
||||||
|
|
||||||
|
const actual = this.parseActual(val);
|
||||||
|
this.$emit("input", actual);
|
||||||
|
},
|
||||||
|
|
||||||
|
// change 事件透传
|
||||||
|
onChange(val) {
|
||||||
|
const actual = this.parseActual(val);
|
||||||
|
console.log()
|
||||||
|
this.$emit("change", actual);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 原生事件保留
|
||||||
|
onBlur(e) {
|
||||||
|
this.$emit("blur", e);
|
||||||
|
},
|
||||||
|
onFocus(e) {
|
||||||
|
this.$emit("focus", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -97,3 +97,9 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep .el-submenu__title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -226,3 +226,4 @@ export function getNormalPath(p) {
|
||||||
export function blobValidate(data) {
|
export function blobValidate(data) {
|
||||||
return data.type !== 'application/json'
|
return data.type !== 'application/json'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog title="修改采购应付单" :visible.sync="internalVisible" width="70%" @close="handleClose">
|
||||||
|
<div class="dialog-body">
|
||||||
|
<!-- Part 1: Details -->
|
||||||
|
<div>
|
||||||
|
<el-divider content-position="left">采购-应付单</el-divider>
|
||||||
|
<div class="details-container">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>应付单编号:</strong> {{ data.payableBillCode }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="16">
|
||||||
|
<div class="detail-item"><strong>生成时间:</strong> {{ data.createTime }}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>制造商名称:</strong> {{ data.vendorName }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>项目编号:</strong> {{ data.projectCode }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>项目名称:</strong> {{ data.projectName }}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>合同编号:</strong> {{ data.orderCode }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>出入库单号:</strong> {{ data.inventoryCode }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item" style="display: flex"><strong>产品类型:</strong>
|
||||||
|
<dict-tag :options="dict.type.product_type" :value="data.productType"/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>含税总价:</strong> {{ data.totalPriceWithTax }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>未税总价:</strong> {{ data.totalPriceWithoutTax }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>税额:</strong> {{ data.taxAmount }}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>未付款金额:</strong> {{ data.unpaidAmount }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>已付款金额:</strong> {{ data.paidAmount }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>付款中金额:</strong> {{ data.payingAmount }}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>未收票金额:</strong> {{ data.unInvoicedAmount }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>已收票金额:</strong> {{ data.invoicedAmount }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="detail-item"><strong>收票中金额:</strong> {{ data.invoicingAmount }}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Part 2: Tabs -->
|
||||||
|
<div style="margin-top: 20px;">
|
||||||
|
<el-tabs v-model="activeTab">
|
||||||
|
<el-tab-pane label="明细" name="details">
|
||||||
|
<!-- Content for 明细 tab will be added later -->
|
||||||
|
明细内容
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="付款计划" name="paymentPlan">
|
||||||
|
<PaymentPlan :isInitEdit=true :payableData="data"/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="handleClose">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import PaymentPlan from './PaymentPlan.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "EditForm",
|
||||||
|
dicts: ['product_type'],
|
||||||
|
components: {
|
||||||
|
PaymentPlan
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
}, data() {
|
||||||
|
return {
|
||||||
|
internalVisible: this.visible, // Local copy of the visible prop
|
||||||
|
activeTab: 'details',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible(newVal) {
|
||||||
|
this.internalVisible = newVal; // Sync prop to local data
|
||||||
|
},
|
||||||
|
internalVisible(newVal) {
|
||||||
|
this.$emit('update:visible', newVal); // Emit changes to parent
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClose() {
|
||||||
|
this.internalVisible = false; // Close dialog locally
|
||||||
|
},
|
||||||
|
handleSubmit() {
|
||||||
|
this.handleClose();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>.details-container {
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item {
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-body {
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,330 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog title="合并发起付款单" :visible.sync="dialogVisible" width="80%" @close="handleClose" append-to-body>
|
||||||
|
<div class="dialog-body">
|
||||||
|
<el-form ref="form" :model="form" :inline="true" label-width="120px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="付款单类型" prop="paymentBillType">
|
||||||
|
<el-select v-model="form.paymentBillType" placeholder="请选择付款单类型" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in paymentBillTypeOptions"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="制造商名称">
|
||||||
|
<el-input v-model="form.vendorName" readonly/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="预计付款时间" prop="estimatedPaymentTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.estimatedPaymentTime"
|
||||||
|
type="date"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
placeholder="选择日期"
|
||||||
|
></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-divider content-position="left">采购应付单表</el-divider>
|
||||||
|
<el-table :data="payableOrdersWithPlans" border max-height="300px" style="margin-bottom: 20px;">
|
||||||
|
<el-table-column label="应付单编号" align="center" prop="payableBillCode" width="150"/>
|
||||||
|
<el-table-column label="预计付款时间" align="center" prop="estimatedPaymentTime" width="180"/>
|
||||||
|
<el-table-column label="付款计划" align="center" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.paymentPlans ? scope.row.paymentPlans.length : 0 }} 条计划</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="项目名称" align="center" prop="projectName" width="150"/>
|
||||||
|
<el-table-column label="合同编号" align="center" prop="orderCode" width="150"/>
|
||||||
|
<el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150"/>
|
||||||
|
<el-table-column label="付款状态" align="center" prop="paymentStatus" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.payment_status" :value="scope.row.paymentStatus"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" width="120"/>
|
||||||
|
<el-table-column label="未付款金额" align="center" prop="unpaidAmount" width="120"/>
|
||||||
|
<el-table-column label="本次付款金额" align="center" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ calculateOrderCurrentPaymentAmount(scope.row.id).toFixed(2) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="本次付款比例" align="center" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ calculateOrderCurrentPaymentRate(scope.row.id).toFixed(2) }}%
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="已付款金额" align="center" prop="paidAmount" width="120"/>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100" fixed="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
@click="handleOpenPaymentPlanSelector(scope.row, scope.$index)"
|
||||||
|
>选择
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="total-info">
|
||||||
|
<span>合并应付总金额 (含税): <el-tag type="info">{{ totalPayableAmountWithTax.toFixed(2) }}</el-tag></span>
|
||||||
|
<span style="margin-left: 20px;">计划付款总金额: <el-tag type="success">{{
|
||||||
|
totalPlannedAmount.toFixed(2)
|
||||||
|
}}</el-tag></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="handleCancel">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleConfirm">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
<el-dialog :title="planTitle" :visible.sync="isPaymentPlanSelectorOpen" width="70%"
|
||||||
|
@close="isPaymentPlanSelectorOpen=false" append-to-body>
|
||||||
|
<payment-plan-selector
|
||||||
|
:payable-data="choosePayable"
|
||||||
|
@confirm="handlePaymentPlanConfirm"
|
||||||
|
/>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="isPaymentPlanSelectorOpen=false">取 消</el-button>
|
||||||
|
<!-- <el-button type="primary" @click="handleConfirm" >确 定</el-button>-->
|
||||||
|
<el-button type="primary" @click="handleConfirm">保 存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 付款计划选择器弹窗 -->
|
||||||
|
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import PaymentPlan from './PaymentPlan.vue';
|
||||||
|
import {getPaymentPlan} from "@/api/finance/payable";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MergePaymentDialog",
|
||||||
|
components: {PaymentPlanSelector: PaymentPlan},
|
||||||
|
dicts: ['payment_status'], // Add dicts for dict-tag
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
payableOrders: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
internalVisible: this.visible,
|
||||||
|
planTitle: '',
|
||||||
|
choosePayable: {},
|
||||||
|
form: {
|
||||||
|
paymentBillType: '1', // Default to a type, or make it dynamic
|
||||||
|
vendorName: '',
|
||||||
|
estimatedPaymentTime: null,
|
||||||
|
},
|
||||||
|
paymentBillTypeOptions: [
|
||||||
|
{label: '普通付款单', value: '1'},
|
||||||
|
{label: '紧急付款单', value: '2'},
|
||||||
|
],
|
||||||
|
payableOrdersWithPlans: [], // Each order will now have its own paymentPlans array
|
||||||
|
isPaymentPlanSelectorOpen: false,
|
||||||
|
currentPayableOrderIndexForPlan: -1, // Index of the order in payableOrdersWithPlans
|
||||||
|
loadingPaymentPlans: false, // Loading state for fetching payment plans
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
dialogVisible: {
|
||||||
|
get() {
|
||||||
|
return this.internalVisible;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.internalVisible = val;
|
||||||
|
this.$emit('update:visible', val);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
totalPayableAmountWithTax() {
|
||||||
|
return this.payableOrdersWithPlans.reduce((sum, order) => sum + (order.totalPriceWithTax || 0), 0);
|
||||||
|
},
|
||||||
|
totalPlannedAmount() {
|
||||||
|
return this.payableOrdersWithPlans.reduce((orderSum, order) => {
|
||||||
|
const orderPlansTotal = (order.paymentPlans || []).reduce((planSum, plan) => planSum + (plan.planAmount || 0), 0);
|
||||||
|
return orderSum + orderPlansTotal;
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible(newVal) {
|
||||||
|
this.internalVisible = newVal;
|
||||||
|
if (newVal) {
|
||||||
|
this.initDialogData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
payableOrders: {
|
||||||
|
handler(newVal) {
|
||||||
|
if (this.dialogVisible) {
|
||||||
|
this.initDialogData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initDialogData() {
|
||||||
|
// Initialize form fields
|
||||||
|
if (this.payableOrders.length > 0) {
|
||||||
|
const firstVendorName = this.payableOrders[0].vendorName;
|
||||||
|
const allSameVendor = this.payableOrders.every(order => order.vendorName === firstVendorName);
|
||||||
|
this.form.vendorName = allSameVendor ? firstVendorName : '多个制造商';
|
||||||
|
this.form.estimatedPaymentTime = this.payableOrders[0].estimatedPaymentTime || null; // Use first order's estimated time as default
|
||||||
|
} else {
|
||||||
|
this.form.vendorName = '';
|
||||||
|
this.form.estimatedPaymentTime = null;
|
||||||
|
}
|
||||||
|
this.form.paymentBillType = '1'; // Default
|
||||||
|
|
||||||
|
// Initialize payableOrdersWithPlans
|
||||||
|
this.payableOrdersWithPlans = this.payableOrders.map(order => ({
|
||||||
|
...order,
|
||||||
|
paymentPlans: order.paymentPlans || [], // Retain existing plans if any, otherwise empty
|
||||||
|
totalPriceWithTax: order.totalPriceWithTax || 0, // Ensure numeric for calculations
|
||||||
|
unpaidAmount: order.unpaidAmount || 0,
|
||||||
|
paidAmount: order.paidAmount || 0, // Ensure numeric for calculations
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
handleClose() {
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.resetForm();
|
||||||
|
},
|
||||||
|
handleConfirm() {
|
||||||
|
// Validate main form fields
|
||||||
|
if (!this.form.paymentBillType) {
|
||||||
|
this.$modal.msgError('请选择付款单类型');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.form.estimatedPaymentTime) {
|
||||||
|
this.$modal.msgError('请选择预计付款时间');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate each payable order's payment plans
|
||||||
|
for (const order of this.payableOrdersWithPlans) {
|
||||||
|
if (!order.paymentPlans || order.paymentPlans.length === 0) {
|
||||||
|
this.$modal.msgError(`应付单 ${order.payableBillCode} 至少需要一条付款计划`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalPlannedAmountForOrder = order.paymentPlans.reduce((sum, plan) => sum + (plan.planAmount || 0), 0);
|
||||||
|
if (Math.abs(totalPlannedAmountForOrder - order.unpaidAmount) > 0.01) { // Compare against unpaidAmount
|
||||||
|
this.$modal.msgError(`应付单 ${order.payableBillCode} 的计划付款总金额 (${totalPlannedAmountForOrder.toFixed(2)}) 与其未付款金额 (${order.unpaidAmount.toFixed(2)}) 不符,请检查。`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const plan of order.paymentPlans) {
|
||||||
|
if (!plan.planPaymentDate) {
|
||||||
|
this.$modal.msgError(`应付单 ${order.payableBillCode} 的付款计划中预计付款时间不能为空。`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (plan.planAmount === null || plan.planAmount === undefined || plan.planAmount <= 0) {
|
||||||
|
this.$modal.msgError(`应付单 ${order.payableBillCode} 的付款计划中预计付款金额必须大于0。`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (plan.planRate === null || plan.planRate === undefined) {
|
||||||
|
this.$modal.msgError(`应付单 ${order.payableBillCode} 的付款计划中应付比例不能为空。`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the final data to be emitted to the parent
|
||||||
|
const mergedPaymentData = {
|
||||||
|
paymentBillType: this.form.paymentBillType,
|
||||||
|
estimatedPaymentTime: this.form.estimatedPaymentTime,
|
||||||
|
// Collect all payable orders with their updated payment plans
|
||||||
|
payableOrders: this.payableOrdersWithPlans.map(order => ({
|
||||||
|
id: order.id,
|
||||||
|
payableBillCode: order.payableBillCode,
|
||||||
|
paymentPlans: order.paymentPlans.map(plan => ({
|
||||||
|
planPaymentDate: plan.planPaymentDate,
|
||||||
|
planAmount: plan.planAmount,
|
||||||
|
planRate: plan.planRate,
|
||||||
|
remark: plan.remark,
|
||||||
|
})),
|
||||||
|
})),
|
||||||
|
totalMergePaymentAmount: this.totalPlannedAmount, // Total amount for the merged bill
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$emit('confirm', mergedPaymentData);
|
||||||
|
this.dialogVisible = false;
|
||||||
|
},
|
||||||
|
handleCancel() {
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.resetForm();
|
||||||
|
},
|
||||||
|
resetForm() {
|
||||||
|
this.form = {
|
||||||
|
paymentBillType: '1',
|
||||||
|
vendorName: '',
|
||||||
|
estimatedPaymentTime: null,
|
||||||
|
};
|
||||||
|
this.payableOrdersWithPlans = [];
|
||||||
|
|
||||||
|
this.currentPayableOrderIndexForPlan = -1;
|
||||||
|
this.loadingPaymentPlans = false;
|
||||||
|
},
|
||||||
|
handleOpenPaymentPlanSelector(row, index) {
|
||||||
|
this.planTitle = `选择付款计划 - ${row.payableBillCode}`;
|
||||||
|
this.choosePayable = row;
|
||||||
|
this.currentPayableOrderIndexForPlan = index;
|
||||||
|
this.isPaymentPlanSelectorOpen = true;
|
||||||
|
console.log(this.choosePayable.id)
|
||||||
|
},
|
||||||
|
handlePaymentPlanConfirm(updatedPlans) {
|
||||||
|
// Update the payment plans for the specific order
|
||||||
|
if (this.currentPayableOrderIndexForPlan !== -1) {
|
||||||
|
this.$set(this.payableOrdersWithPlans[this.currentPayableOrderIndexForPlan], 'paymentPlans', updatedPlans);
|
||||||
|
}
|
||||||
|
this.isPaymentPlanSelectorOpen = false;
|
||||||
|
this.currentPayableOrderIndexForPlan = -1;
|
||||||
|
},
|
||||||
|
calculateOrderCurrentPaymentAmount(orderId) {
|
||||||
|
const order = this.payableOrdersWithPlans.find(o => o.id === orderId);
|
||||||
|
if (order && order.paymentPlans) {
|
||||||
|
return order.paymentPlans.reduce((sum, plan) => sum + (plan.planAmount || 0), 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
calculateOrderCurrentPaymentRate(orderId) {
|
||||||
|
const order = this.payableOrdersWithPlans.find(o => o.id === orderId);
|
||||||
|
if (order && order.paymentPlans && order.unpaidAmount > 0) {
|
||||||
|
const currentAmount = this.calculateOrderCurrentPaymentAmount(orderId);
|
||||||
|
return (currentAmount / order.unpaidAmount * 100);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dialog-body {
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: 10px; /* To prevent scrollbar from overlapping content */
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-info {
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: right;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,286 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<div class="dialog-body">
|
||||||
|
<el-divider content-position="left">付款计划</el-divider>
|
||||||
|
<el-button v-if="isEditing" type="primary" size="mini" @click="handleSavePaymentPlan"
|
||||||
|
style="margin-bottom: 10px;">
|
||||||
|
保存付款计划
|
||||||
|
</el-button>
|
||||||
|
<el-button v-else type="primary" size="mini" @click="isEditing=true"
|
||||||
|
style="margin-bottom: 10px;">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-table :data="paymentPlans" border @selection-change="selectPlan">
|
||||||
|
<el-table-column type="selection" width="50" align="center"/>
|
||||||
|
<el-table-column label="序号" type="index" width="50" align="center"></el-table-column>
|
||||||
|
<el-table-column label="预计付款时间" align="center" width="200">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-date-picker v-model="scope.row.planPaymentDate" type="date" style="width: 180px"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
placeholder="选择日期"
|
||||||
|
:disabled="!isEditing || scope.row.status === 'paid'"></el-date-picker>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="预计付款金额" align="center" width="230">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-input-number
|
||||||
|
v-model="scope.row.planAmount"
|
||||||
|
:precision="2"
|
||||||
|
:step="100"
|
||||||
|
:min="0.01"
|
||||||
|
:max="totalPriceWithTax"
|
||||||
|
@change="handleAmountChange(scope.row)"
|
||||||
|
:disabled="!isEditing || scope.row.status === 'paid'"
|
||||||
|
></el-input-number>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="应付比例(%)" align="center" width="230">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-input-number
|
||||||
|
v-model="scope.row.planRate"
|
||||||
|
:precision="2"
|
||||||
|
:step="1"
|
||||||
|
:min="0.01"
|
||||||
|
:max="100"
|
||||||
|
@change="handleRateChange(scope.row)"
|
||||||
|
:disabled="!isEditing || scope.row.status === 'paid'"
|
||||||
|
></el-input-number>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-input v-model="scope.row.remark" placeholder="请输入备注"
|
||||||
|
:disabled="!isEditing || scope.row.status === 'paid'"></el-input>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" width="150" fixed="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button v-if="isEditing"
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-plus"
|
||||||
|
@click="handleAddPaymentPlanRow"
|
||||||
|
>增加下行
|
||||||
|
</el-button>
|
||||||
|
<el-button v-if="isEditing"
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleDeletePaymentPlanRow(scope.$index)"
|
||||||
|
:disabled="paymentPlans.length === 1 || scope.row.status === 'paid'"
|
||||||
|
>删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="total-info">
|
||||||
|
<span>应付单未付款金额: <el-tag type="info">{{ totalUnpaidAmount.toFixed(2) }}</el-tag></span>
|
||||||
|
<span style="margin-left: 20px;">计划付款总金额: <el-tag type="success">{{
|
||||||
|
totalPlannedAmount.toFixed(2)
|
||||||
|
}}</el-tag></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {getPaymentPlan, updatePaymentPlan} from "@/api/finance/payable";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "PaymentPlanSelector",
|
||||||
|
props: {
|
||||||
|
payableData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isInitEdit: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedPlan:[],
|
||||||
|
isEditing: false,
|
||||||
|
loading: false,
|
||||||
|
paymentPlans: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
title() {
|
||||||
|
return `选择付款计划 - ${this.payableData.payableBillCode}`;
|
||||||
|
},
|
||||||
|
totalPlannedAmount() {
|
||||||
|
return this.paymentPlans.reduce((sum, plan) => sum + (plan.planAmount || 0), 0);
|
||||||
|
},
|
||||||
|
totalUnpaidAmount() {
|
||||||
|
return this.payableData.unpaidAmount || 0;
|
||||||
|
},
|
||||||
|
totalPriceWithTax() {
|
||||||
|
return this.payableData.totalPriceWithTax || 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'payableData.id': {
|
||||||
|
handler(newVal, oldVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.fetchPaymentPlans(newVal)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
isInitEdit: {
|
||||||
|
handler(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.isEditing = newVal
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectPlan( selection){
|
||||||
|
this.selectedPlan=selection
|
||||||
|
},
|
||||||
|
fetchPaymentPlans(payableId) {
|
||||||
|
if (this.payableData && payableId) {
|
||||||
|
getPaymentPlan(payableId).then(response => {
|
||||||
|
this.paymentPlans = response.data.map(item => ({
|
||||||
|
...item,
|
||||||
|
// Add a default status if not present, similar to EditForm.vue
|
||||||
|
status: item.status || 'pending'
|
||||||
|
}));
|
||||||
|
if (this.paymentPlans.length === 0) {
|
||||||
|
this.initDefaultPaymentPlan();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.initDefaultPaymentPlan();
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initDefaultPaymentPlan() {
|
||||||
|
// Default to a single plan covering the unpaid amount if no initial plans
|
||||||
|
this.paymentPlans = [{
|
||||||
|
planPaymentDate: null,
|
||||||
|
planAmount: this.totalUnpaidAmount,
|
||||||
|
planRate: 100,
|
||||||
|
remark: '',
|
||||||
|
status: 'pending' // Default status
|
||||||
|
}];
|
||||||
|
},
|
||||||
|
handleSavePaymentPlan() {
|
||||||
|
if (!this.validatePaymentPlans()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.validatePaymentPlanTotals()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this.paymentPlans.length; i++) {
|
||||||
|
const plan = this.paymentPlans[i];
|
||||||
|
if (!plan.planPaymentDate) {
|
||||||
|
this.$modal.msgError(`第 ${i + 1} 行付款计划的预计付款时间不能为空。`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (plan.planAmount === null || plan.planAmount === undefined || plan.planAmount === '' || plan.planAmount < 0) {
|
||||||
|
this.$modal.msgError(`第 ${i + 1} 行付款计划的预计付款金额不能为空。`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (plan.planRate === null || plan.planRate === undefined || plan.planRate === '') {
|
||||||
|
this.$modal.msgError(`第 ${i + 1} 行付款计划的应付比例不能为空。`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePaymentPlan(this.payableData.id, this.paymentPlans).then(() => {
|
||||||
|
this.$modal.msgSuccess("保存成功");
|
||||||
|
this.fetchPaymentPlans(this.payableData.id); // Re-fetch using the correct method and ID
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
handleAddPaymentPlanRow() {
|
||||||
|
this.paymentPlans.push({
|
||||||
|
planPaymentDate: null,
|
||||||
|
planAmount: 0,
|
||||||
|
planRate: 0,
|
||||||
|
remark: '',
|
||||||
|
status: 'pending' // Default status
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleDeletePaymentPlanRow(index) {
|
||||||
|
if (this.paymentPlans.length === 1) {
|
||||||
|
this.$modal.msgError("至少需要保留一条付款计划。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Only allow deletion if not 'paid' or status is not set (newly added)
|
||||||
|
if (this.paymentPlans[index].status === 'paid') {
|
||||||
|
this.$modal.msgError("已付款的计划不能删除。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.paymentPlans.splice(index, 1);
|
||||||
|
},
|
||||||
|
handleAmountChange(row) {
|
||||||
|
if (this.totalPriceWithTax === 0) {
|
||||||
|
row.planRate = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
row.planRate = this.$calc.mul((this.$calc.div(row.planAmount, this.totalPriceWithTax,4)), 100);
|
||||||
|
},
|
||||||
|
handleRateChange(row) {
|
||||||
|
row.planAmount = this.$calc.div(this.$calc.mul(this.totalPriceWithTax , row.planRate),100);
|
||||||
|
},
|
||||||
|
validatePaymentPlanTotals() {
|
||||||
|
const totalAmount = this.paymentPlans.reduce((sum, plan) => sum + (plan.planAmount || 0), 0);
|
||||||
|
const totalRate = this.paymentPlans.reduce((sum, plan) => sum + (plan.planRate || 0), 0);
|
||||||
|
|
||||||
|
if (totalAmount !== this.totalPriceWithTax) {
|
||||||
|
this.$modal.msgError(`预计付款金额之和应该等于应付总金额[${this.totalPriceWithTax}]`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
validatePaymentPlans() {
|
||||||
|
if (this.paymentPlans.length === 0) {
|
||||||
|
this.$modal.msgError("请至少添加一条付款计划。");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalPlannedAmount = this.paymentPlans.reduce((sum, plan) => sum + (plan.planAmount || 0), 0);
|
||||||
|
|
||||||
|
for (let i = 0; i < this.paymentPlans.length; i++) {
|
||||||
|
const plan = this.paymentPlans[i];
|
||||||
|
if (!plan.planPaymentDate) {
|
||||||
|
this.$modal.msgError(`第 ${i + 1} 行付款计划的预计付款时间不能为空。`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (plan.planAmount === null || plan.planAmount === undefined || plan.planAmount <= 0) {
|
||||||
|
this.$modal.msgError(`第 ${i + 1} 行付款计划的预计付款金额必须大于0。`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (plan.planRate === null || plan.planRate === undefined || plan.planRate === '') {
|
||||||
|
this.$modal.msgError(`第 ${i + 1} 行付款计划的应付比例不能为空。`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dialog-body {
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: 10px; /* To prevent scrollbar from overlapping content */
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-info {
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: right;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,339 @@
|
||||||
|
<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="payableBillCode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.payableBillCode"
|
||||||
|
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="orderCode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.orderCode"
|
||||||
|
placeholder="请输入合同编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出入库单号" prop="inventoryCode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.inventoryCode"
|
||||||
|
placeholder="请输入出入库单号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品类型" prop="productType">
|
||||||
|
<el-select v-model="queryParams.productType" placeholder="请选择产品类型" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dict.type.product_type"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="付款状态" prop="paymentStatus">
|
||||||
|
<el-select v-model="queryParams.paymentStatus" placeholder="请选择付款状态" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dict.type.payment_status"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</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 label="预计付款时间">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="estimatedPaymentDateRange"
|
||||||
|
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 icon="el-icon-plus" @click="handleMergeAndInitiatePayment" v-hasPermi="['finance:payable:mergePayment']">
|
||||||
|
合并并发起付款单
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5" >
|
||||||
|
<el-button type="primary" plain icon="el-icon-plus" v-hasPermi="['inventory:inner:add']">
|
||||||
|
合并并发起收票单
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="payableList" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="50" />
|
||||||
|
<el-table-column label="项目编号" align="center" prop="projectCode" width="120" />
|
||||||
|
<el-table-column label="项目名称" align="center" prop="projectName" width="150" />
|
||||||
|
<el-table-column label="应付单编号" align="center" prop="payableBillCode" width="150" />
|
||||||
|
<el-table-column label="生成时间" align="center" prop="createTime" width="180"/>
|
||||||
|
<el-table-column label="预计付款时间" align="center" prop="estimatedPaymentTime" width="180"/>
|
||||||
|
<el-table-column label="预计付款金额" align="center" prop="totalPriceWithTax" width="120" />
|
||||||
|
<el-table-column label="该制造商是否有预付单" align="center" prop="hasAdvancePayment" width="150" />
|
||||||
|
<el-table-column label="预付金额" align="center" prop="advancePaymentAmount" width="120" />
|
||||||
|
<el-table-column label="制造商名称" align="center" prop="vendorName" width="150" />
|
||||||
|
<el-table-column label="合同编号" align="center" prop="orderCode" width="150" />
|
||||||
|
<el-table-column label="出入库单号" align="center" prop="inventoryCode" width="150" />
|
||||||
|
<el-table-column label="产品类型" align="center" prop="productType" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.product_type" :value="scope.row.productType"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="含税总价" align="center" prop="totalPriceWithTax" width="120" />
|
||||||
|
<el-table-column label="未税总价" align="center" prop="totalPriceWithoutTax" width="120" />
|
||||||
|
<el-table-column label="税额" align="center" prop="taxAmount" width="120" />
|
||||||
|
<el-table-column label="付款状态" align="center" prop="paymentStatus" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.payment_status" :value="scope.row.paymentStatus"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="生成付款单" align="center" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
@click="handleGeneratePayment(scope.row)"
|
||||||
|
>生成付款单</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="收票状态" align="center" prop="invoiceStatus" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.invoice_status" :value="scope.row.invoiceStatus"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="生成收票单" align="center" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
@click="handleGenerateInvoice(scope.row)"
|
||||||
|
>生成收票单</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="未付款金额" align="center" prop="unpaidAmount" width="120" />
|
||||||
|
<el-table-column label="付款中金额" align="center" prop="payingAmount" width="120" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160" fixed="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
@click="handleUpdate(scope.row)"
|
||||||
|
v-hasPermi="['finance:payable:edit']"
|
||||||
|
>修改</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['finance:payable: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"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 修改弹窗 -->
|
||||||
|
<edit-form :visible.sync="open" :data="selectedRow" />
|
||||||
|
|
||||||
|
<!-- 合并付款单弹窗 -->
|
||||||
|
<merge-payment-dialog :visible.sync="isMergePaymentDialogOpen" :payable-orders="selectedPayableRows" @confirm="confirmMergePayment" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listPayable } from "@/api/finance/payable";
|
||||||
|
import EditForm from './components/EditForm.vue';
|
||||||
|
import MergePaymentDialog from './components/MergePaymentDialog.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Payable",
|
||||||
|
components: { EditForm, MergePaymentDialog },
|
||||||
|
dicts: ['product_type', 'payment_status', 'invoice_status'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 。。。 (other data properties)
|
||||||
|
// 是否显示修改弹窗
|
||||||
|
open: false,
|
||||||
|
// 选中行数据
|
||||||
|
selectedRow: {},
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 采购应付单表格数据
|
||||||
|
payableList: [],
|
||||||
|
// 日期范围
|
||||||
|
dateRange: [],
|
||||||
|
// 预计付款日期范围
|
||||||
|
estimatedPaymentDateRange: [],
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
projectCode: null,
|
||||||
|
projectName: null,
|
||||||
|
payableBillCode: null,
|
||||||
|
vendorName: null,
|
||||||
|
orderCode: null,
|
||||||
|
inventoryCode: null,
|
||||||
|
productType: null,
|
||||||
|
paymentStatus: null,
|
||||||
|
createTimeStart: null,
|
||||||
|
createTimeEnd: null,
|
||||||
|
estimatedPaymentTimeStart: null,
|
||||||
|
estimatedPaymentTimeEnd: null
|
||||||
|
},
|
||||||
|
// 选中行数据
|
||||||
|
selectedPayableRows: [],
|
||||||
|
// 是否显示合并付款弹窗
|
||||||
|
isMergePaymentDialogOpen: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询采购应付单列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true;
|
||||||
|
if (null != this.dateRange && '' != this.dateRange) {
|
||||||
|
this.queryParams.createTimeStart = this.dateRange[0];
|
||||||
|
this.queryParams.createTimeEnd = this.dateRange[1];
|
||||||
|
}
|
||||||
|
if (null != this.estimatedPaymentDateRange && '' != this.estimatedPaymentDateRange) {
|
||||||
|
this.queryParams.estimatedPaymentTimeStart = this.estimatedPaymentDateRange[0];
|
||||||
|
this.queryParams.estimatedPaymentTimeEnd = this.estimatedPaymentDateRange[1];
|
||||||
|
}
|
||||||
|
listPayable(this.queryParams).then(response => {
|
||||||
|
this.payableList = response.rows;
|
||||||
|
this.total = response.total;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.dateRange = [];
|
||||||
|
this.estimatedPaymentDateRange = [];
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.queryParams.createTimeStart=null;
|
||||||
|
this.queryParams.createTimeEnd=null;
|
||||||
|
this.queryParams.estimatedPaymentTimeStart=null;
|
||||||
|
this.queryParams.estimatedPaymentTimeEnd=null;
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
handleUpdate(row) {
|
||||||
|
this.selectedRow = row;
|
||||||
|
this.open = true;
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
handleDelete(row) {
|
||||||
|
this.$modal.confirm('是否确认删除采购应付单编号为"' + row.payableBillCode + '"的数据项?').then(function() {
|
||||||
|
return Promise.resolve();
|
||||||
|
}).then(() => {
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
/** 生成付款单按钮操作 */
|
||||||
|
handleGeneratePayment(row) {
|
||||||
|
console.log("handleGeneratePayment", row);
|
||||||
|
},
|
||||||
|
/** 生成收票单按钮操作 */
|
||||||
|
handleGenerateInvoice(row) {
|
||||||
|
console.log("handleGenerateInvoice", row);
|
||||||
|
},
|
||||||
|
/** 多选框选中数据 */
|
||||||
|
handleSelectionChange(selection) {
|
||||||
|
this.selectedPayableRows = selection;
|
||||||
|
},
|
||||||
|
/** 合并并发起付款单按钮操作 */
|
||||||
|
handleMergeAndInitiatePayment() {
|
||||||
|
if (this.selectedPayableRows.length === 0) {
|
||||||
|
this.$modal.msgWarning("请选择至少一条应付单进行合并操作");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let vendorLength = new Set(this.selectedPayableRows.map(item=>item.vendorCode)).size;
|
||||||
|
if (vendorLength > 1) {
|
||||||
|
this.$modal.msgWarning("请选择同一家供应商的应付单进行合并操作");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isMergePaymentDialogOpen = true;
|
||||||
|
},
|
||||||
|
/** 确认合并付款单操作 */
|
||||||
|
confirmMergePayment(paymentData) {
|
||||||
|
console.log("Merged payment data received:", paymentData);
|
||||||
|
// TODO: Call backend API to initiate merged payment
|
||||||
|
// this.$modal.msgSuccess("合并付款单发起成功");
|
||||||
|
this.isMergePaymentDialogOpen = false;
|
||||||
|
this.getList(); // Refresh the list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -82,14 +82,14 @@
|
||||||
<delivery-detail :delivery-id="deliveryId" :visible.sync="viewOpen" />
|
<delivery-detail :delivery-id="deliveryId" :visible.sync="viewOpen" />
|
||||||
|
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button v-if="showReturn" type="danger" @click="handleCancel">退 回</el-button>
|
<el-button v-if="showReturn" type="danger" @click="handleStatusChange(this.form, '4')">退 回</el-button>
|
||||||
<el-button @click="handleCancel">关 闭</el-button>
|
<el-button @click="handleCancel">关 闭</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getOuter, queryInfo } from '@/api/inventory/outer';
|
import {changeOuterStatus, getOuter, queryInfo} from '@/api/inventory/outer';
|
||||||
import { removeDelivery, updateDeliveryStatus } from '@/api/inventory/delivery';
|
import { removeDelivery, updateDeliveryStatus } from '@/api/inventory/delivery';
|
||||||
import GenerateDeliveryForm from './GenerateDeliveryForm.vue';
|
import GenerateDeliveryForm from './GenerateDeliveryForm.vue';
|
||||||
import DeliveryDetail from '@/views/inventory/delivery/Detail.vue';
|
import DeliveryDetail from '@/views/inventory/delivery/Detail.vue';
|
||||||
|
|
@ -181,6 +181,19 @@ export default {
|
||||||
handleViewDelivery(deliveryId) {
|
handleViewDelivery(deliveryId) {
|
||||||
this.deliveryId = deliveryId;
|
this.deliveryId = deliveryId;
|
||||||
this.viewOpen = true;
|
this.viewOpen = true;
|
||||||
|
},
|
||||||
|
handleStatusChange(row, status) {
|
||||||
|
const actionText = status === '3' ? '确认接收' : '退回';
|
||||||
|
this.$confirm(`确认要"${actionText}"该出库单吗?`, '系统提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}).then(() => {
|
||||||
|
return changeOuterStatus(row.id, status, row.orderCode);
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success(`${actionText}成功`);
|
||||||
|
this.getList();
|
||||||
|
}).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
<!-- 操作按钮栏 -->
|
<!-- 操作按钮栏 -->
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['inventory:outer:export']">导出</el-button>
|
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['inventory:outer:export']">导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,9 @@ export default {
|
||||||
dutyName: null,
|
dutyName: null,
|
||||||
partnerName: null,
|
partnerName: null,
|
||||||
timeType: 'deliveryTime',
|
timeType: 'deliveryTime',
|
||||||
params: {}
|
params: {},
|
||||||
|
orderByColumn:'createTime',
|
||||||
|
isAsc: 'desc'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,10 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="采购员" prop="purchaserId">
|
<el-form-item label="采购员" prop="purchaserId">
|
||||||
<el-input v-model="form.purchaserName" placeholder="请选择采购员" @click.native="purchaserSelectOpen=true" :readonly="true" >
|
<el-input v-model="form.purchaserName" placeholder="请选择采购员"
|
||||||
<el-button slot="append" icon="el-icon-search" @click="purchaserSelectOpen=true"></el-button>
|
@click.native="$refs.purchase.queryParams.roleId=117;purchaserSelectOpen=true;" :readonly="true">
|
||||||
|
<el-button slot="append" icon="el-icon-search"
|
||||||
|
@click="$refs.purchase.queryParams.roleId=117;purchaserSelectOpen=true"></el-button>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -94,7 +96,8 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="汇智负责人" prop="ownerId">
|
<el-form-item label="汇智负责人" prop="ownerId">
|
||||||
<el-input v-model="form.ownerName" placeholder="请选择汇智负责人" :readonly="true" >
|
<el-input v-model="form.ownerName" placeholder="请选择汇智负责人" @click.native="ownerSelectOpen=true"
|
||||||
|
:readonly="true">
|
||||||
<el-button slot="append" icon="el-icon-search" @click="ownerSelectOpen=true"></el-button>
|
<el-button slot="append" icon="el-icon-search" @click="ownerSelectOpen=true"></el-button>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -148,6 +151,11 @@
|
||||||
<el-input v-model.number="scope.row.price" type="number" :precision="2" :step="0.1" :min="0" @change="calculateRowTotal(scope.row)"></el-input>
|
<el-input v-model.number="scope.row.price" type="number" :precision="2" :step="0.1" :min="0" @change="calculateRowTotal(scope.row)"></el-input>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="税率(%)" prop="taxRate" width="200">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<tax-rate-input v-model="scope.row.taxRate" :step="0.1" :min="0" :max="100" @change="calculateRowTotal(scope.row)"></tax-rate-input>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="含税小计" prop="amountTotal"></el-table-column>
|
<el-table-column label="含税小计" prop="amountTotal"></el-table-column>
|
||||||
<el-table-column label="交货日期">
|
<el-table-column label="交货日期">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
|
|
@ -176,7 +184,8 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
<select-user :visible.sync="purchaserSelectOpen" @user-selected="handlePurchaserSelect"></select-user>
|
<select-user ref="purchase" :visible.sync="purchaserSelectOpen"
|
||||||
|
@user-selected="handlePurchaserSelect"></select-user>
|
||||||
<select-user :visible.sync="ownerSelectOpen" @user-selected="handleOwnerSelect"></select-user>
|
<select-user :visible.sync="ownerSelectOpen" @user-selected="handleOwnerSelect"></select-user>
|
||||||
<select-product :visible.sync="productSelectOpen" @product-selected="handleProductSelected" :vendor-code="currentVendorCode" :product-type="currentProductType"></select-product>
|
<select-product :visible.sync="productSelectOpen" @product-selected="handleProductSelected" :vendor-code="currentVendorCode" :product-type="currentProductType"></select-product>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -188,11 +197,12 @@ import { listAllVendor } from "@/api/base/vendor";
|
||||||
import SelectUser from "@/views/system/user/selectUser";
|
import SelectUser from "@/views/system/user/selectUser";
|
||||||
import SelectProduct from "@/views/system/product/selectProduct";
|
import SelectProduct from "@/views/system/product/selectProduct";
|
||||||
import { getDicts } from "@/api/system/dict/data";
|
import { getDicts } from "@/api/system/dict/data";
|
||||||
|
import TaxRateInput from "@/components/TaxRateInput/TaxInput.vue";
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PurchaseOrderDetail",
|
name: "PurchaseOrderDetail",
|
||||||
components: { SelectUser, SelectProduct },
|
components: {TaxRateInput, SelectUser, SelectProduct },
|
||||||
props: {
|
props: {
|
||||||
orderData: {
|
orderData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
@ -223,7 +233,7 @@ export default {
|
||||||
id: null,
|
id: null,
|
||||||
purchaseNo: null,
|
purchaseNo: null,
|
||||||
buyerName: '紫光汇智信息技术有限公司',
|
buyerName: '紫光汇智信息技术有限公司',
|
||||||
buyerAddress: '重庆市南岸区广福大道12号行政中心B区3号楼14-17',
|
buyerAddress: '重庆市两江新区云杉南路6号涉外商务区B6栋7楼',
|
||||||
vendorId: null,
|
vendorId: null,
|
||||||
currency: 'RMB',
|
currency: 'RMB',
|
||||||
purchaserId: null,
|
purchaserId: null,
|
||||||
|
|
@ -276,9 +286,10 @@ export default {
|
||||||
},
|
},
|
||||||
totalAmountWithoutTax() {
|
totalAmountWithoutTax() {
|
||||||
const total = this.form.omsPurchaseOrderItemList?.reduce((acc, cur) => {
|
const total = this.form.omsPurchaseOrderItemList?.reduce((acc, cur) => {
|
||||||
const amount = cur.quantity * cur.price || 0;
|
const amount = this.$calc.mul(cur.quantity, cur.price) || 0;
|
||||||
const taxRate = cur.taxRate || 0;
|
const taxRate = cur.taxRate || 0;
|
||||||
return acc + (amount / (1 + taxRate));
|
console.log(taxRate)
|
||||||
|
return acc + this.$calc.div(amount , (1 + taxRate));
|
||||||
}, 0);
|
}, 0);
|
||||||
return (this.$calc.toFixed(total)) || 0;
|
return (this.$calc.toFixed(total)) || 0;
|
||||||
},
|
},
|
||||||
|
|
@ -401,9 +412,9 @@ export default {
|
||||||
},
|
},
|
||||||
/** 获取厂商列表 */
|
/** 获取厂商列表 */
|
||||||
getVendorList() {
|
getVendorList() {
|
||||||
return listAllVendor().then(res => {
|
return listAllVendor().then(res => {
|
||||||
this.vendorOptions = res.data;
|
this.vendorOptions = res.data;
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/** 制造商选择变化 */
|
/** 制造商选择变化 */
|
||||||
handleVendorChange(vendorId) {
|
handleVendorChange(vendorId) {
|
||||||
|
|
@ -414,26 +425,26 @@ export default {
|
||||||
this.form.payMethod=this.selectedVendor.payMethod;
|
this.form.payMethod=this.selectedVendor.payMethod;
|
||||||
} else {
|
} else {
|
||||||
this.selectedVendor = {};
|
this.selectedVendor = {};
|
||||||
this.form.warehouseId = null;
|
this.form.warehouseId = null;
|
||||||
this.currentVendorCode = null;
|
this.currentVendorCode = null;
|
||||||
this.form.payMethod = null;
|
this.form.payMethod = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/** 处理采购员选择 */
|
/** 处理采购员选择 */
|
||||||
handlePurchaserSelect(user) {
|
handlePurchaserSelect(user) {
|
||||||
|
|
||||||
console.log(user)
|
console.log(user)
|
||||||
this.$set(this.form, 'purchaserId', user.userId);
|
this.$set(this.form, 'purchaserId', user.userId);
|
||||||
this.$set(this.form, 'purchaserName', user.userName);
|
this.$set(this.form, 'purchaserName', user.userName);
|
||||||
this.$set(this.form, 'purchaserMobile', user.phonenumber);
|
this.$set(this.form, 'purchaserMobile', user.phonenumber);
|
||||||
this.$set(this.form, 'purchaserEmail', user.email);
|
this.$set(this.form, 'purchaserEmail', user.email);
|
||||||
this.purchaserSelectOpen = false;
|
this.purchaserSelectOpen = false;
|
||||||
},
|
},
|
||||||
/** 处理汇智负责人选择 */
|
/** 处理汇智负责人选择 */
|
||||||
handleOwnerSelect(user) {
|
handleOwnerSelect(user) {
|
||||||
this.$set(this.form, 'ownerId', user.userId);
|
this.$set(this.form, 'ownerId', user.userId);
|
||||||
this.$set(this.form, 'ownerName', user.userName);
|
this.$set(this.form, 'ownerName', user.userName);
|
||||||
this.ownerSelectOpen = false;
|
this.ownerSelectOpen = false;
|
||||||
},
|
},
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
submitForm() {
|
submitForm() {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<el-table v-loading="loading" @row-click="handleSelect" :data="purchaseorderList" >
|
<el-table v-loading="loading" @row-click="handleSelect" :data="purchaseorderList" >
|
||||||
<el-table-column label="采购单号" align="center" prop="purchaseNo" width="180"/>
|
<el-table-column label="采购单号" align="center" prop="purchaseNo" width="180"/>
|
||||||
<el-table-column label="采购方名称" align="center" prop="buyerName" width="220"/>
|
<el-table-column label="采购方名称" align="center" prop="buyerName" width="220"/>
|
||||||
<el-table-column label="制造商名称" align="center" prop="vendorName" width="120"/>
|
<el-table-column label="制造商名称" align="center" prop="vendorName" width="120"/>
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
<el-table-column label="联系电话" align="center" prop="vendorPhone" width="120"/>
|
<el-table-column label="联系电话" align="center" prop="vendorPhone" width="120"/>
|
||||||
<el-table-column label="发起日期" align="center" prop="createTime" width="180">
|
<el-table-column label="发起日期" align="center" prop="createTime" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="汇智负责人" align="center" prop="ownerName" width="120"/>
|
<el-table-column label="汇智负责人" align="center" prop="ownerName" width="120"/>
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
<el-table-column label="产品编码" align="center" prop="productCode" width="100"/>
|
<el-table-column label="产品编码" align="center" prop="productCode" width="100"/>
|
||||||
<el-table-column label="产品型号" align="center" prop="productModel" width="100"/>
|
<el-table-column label="产品型号" align="center" prop="productModel" width="100"/>
|
||||||
<el-table-column label="数量" align="center" prop="quantity" width="100"/>
|
<el-table-column label="数量" align="center" prop="quantity" width="100"/>
|
||||||
<el-table-column label="单件" align="center" prop="price" width="100"/>
|
<el-table-column label="单价" align="center" prop="price" width="100"/>
|
||||||
<el-table-column label="小计" align="center" prop="price" width="100">
|
<el-table-column label="小计" align="center" prop="price" width="100">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{ scope.row.quantity * scope.row.price}}
|
{{ scope.row.quantity * scope.row.price}}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,8 @@
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="purchaseorderList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="purchaseorderList" @selection-change="handleSelectionChange"
|
||||||
|
@sort-change="handleSortChange">
|
||||||
<!-- <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="purchaseNo" width="180"/>
|
<el-table-column label="采购编号" align="center" prop="purchaseNo" width="180"/>
|
||||||
<el-table-column label="采购方名称" align="center" prop="buyerName" width="120"/>
|
<el-table-column label="采购方名称" align="center" prop="buyerName" width="120"/>
|
||||||
|
|
@ -92,9 +93,9 @@
|
||||||
<el-table-column label="联系人" align="center" prop="vendorUser" width="100"/>
|
<el-table-column label="联系人" align="center" prop="vendorUser" width="100"/>
|
||||||
<el-table-column label="联系电话" align="center" prop="vendorPhone" width="120"/>
|
<el-table-column label="联系电话" align="center" prop="vendorPhone" width="120"/>
|
||||||
<el-table-column label="含税总计金额" align="center" prop="totalAmount" width="120"/>
|
<el-table-column label="含税总计金额" align="center" prop="totalAmount" width="120"/>
|
||||||
<el-table-column label="发起日期" align="center" prop="createTime" width="180">
|
<el-table-column label="发起日期" align="center" prop="createTime" width="180" sortable>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="汇智负责人" align="center" prop="ownerName" width="120"/>
|
<el-table-column label="汇智负责人" align="center" prop="ownerName" width="120"/>
|
||||||
|
|
@ -331,6 +332,8 @@ export default {
|
||||||
approveStatus: null,
|
approveStatus: null,
|
||||||
confirmStatus: null,
|
confirmStatus: null,
|
||||||
status: null,
|
status: null,
|
||||||
|
orderByColumn:'createTime',
|
||||||
|
isAsc: 'desc'
|
||||||
},
|
},
|
||||||
// 表单参数
|
// 表单参数
|
||||||
form: {},
|
form: {},
|
||||||
|
|
@ -382,6 +385,11 @@ export default {
|
||||||
this.open = false;
|
this.open = false;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
handleSortChange(column, prop, order) {
|
||||||
|
this.queryParams.orderByColumn = column.prop
|
||||||
|
this.queryParams.isAsc = column.order
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
// 表单重置
|
// 表单重置
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,9 @@
|
||||||
<!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>-->
|
<!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>-->
|
||||||
<!-- </el-row>-->
|
<!-- </el-row>-->
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="purchaseorderList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="purchaseorderList" @selection-change="handleSelectionChange"
|
||||||
|
@sort-change="handleSortChange"
|
||||||
|
>
|
||||||
<!-- <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="purchaseNo" width="180"/>
|
<el-table-column label="采购编号" align="center" prop="purchaseNo" width="180"/>
|
||||||
<el-table-column label="采购方名称" align="center" prop="buyerName" />
|
<el-table-column label="采购方名称" align="center" prop="buyerName" />
|
||||||
|
|
@ -73,9 +75,9 @@
|
||||||
<el-table-column label="联系人" align="center" prop="vendorUser" width="100"/>
|
<el-table-column label="联系人" align="center" prop="vendorUser" width="100"/>
|
||||||
<el-table-column label="联系电话" align="center" prop="vendorPhone" width="120"/>
|
<el-table-column label="联系电话" align="center" prop="vendorPhone" width="120"/>
|
||||||
<el-table-column label="含税总计金额" align="center" prop="totalAmount" width="120"/>
|
<el-table-column label="含税总计金额" align="center" prop="totalAmount" width="120"/>
|
||||||
<el-table-column label="发起日期" align="center" prop="createTime" width="180">
|
<el-table-column label="发起日期" align="center" prop="createTime" sortable width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="汇智负责人" align="center" prop="ownerName" width="120"/>
|
<el-table-column label="汇智负责人" align="center" prop="ownerName" width="120"/>
|
||||||
|
|
@ -282,6 +284,8 @@ export default {
|
||||||
approveStatus: null,
|
approveStatus: null,
|
||||||
confirmStatus: '0',
|
confirmStatus: '0',
|
||||||
status: null,
|
status: null,
|
||||||
|
orderByColumn:'createTime',
|
||||||
|
isAsc: 'desc'
|
||||||
},
|
},
|
||||||
// 表单参数
|
// 表单参数
|
||||||
form: {},
|
form: {},
|
||||||
|
|
@ -329,6 +333,11 @@ export default {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleSortChange(column, prop, order) {
|
||||||
|
this.queryParams.orderByColumn = column.prop
|
||||||
|
this.queryParams.isAsc = column.order
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
cancel() {
|
cancel() {
|
||||||
this.open = false;
|
this.open = false;
|
||||||
|
|
|
||||||
|
|
@ -534,15 +534,15 @@ export default {
|
||||||
/** 分配数据权限操作 */
|
/** 分配数据权限操作 */
|
||||||
handleDataScope(row) {
|
handleDataScope(row) {
|
||||||
this.reset()
|
this.reset()
|
||||||
const deptTreeSelect = this.getDeptTree(row.roleId)
|
// const deptTreeSelect = this.getDeptTree(row.roleId)
|
||||||
getRole(row.roleId).then(response => {
|
getRole(row.roleId).then(response => {
|
||||||
this.form = response.data
|
this.form = response.data
|
||||||
this.openDataScope = true
|
this.openDataScope = true
|
||||||
this.$nextTick(() => {
|
// this.$nextTick(() => {
|
||||||
deptTreeSelect.then(res => {
|
// deptTreeSelect.then(res => {
|
||||||
this.$refs.dept.setCheckedKeys(res.checkedKeys)
|
// this.$refs.dept.setCheckedKeys(res.checkedKeys)
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
})
|
})
|
||||||
this.title = "分配数据权限"
|
this.title = "分配数据权限"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,8 @@ export default {
|
||||||
if (userId) {
|
if (userId) {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
getAuthRole(userId).then((response) => {
|
getAuthRole(userId).then((response) => {
|
||||||
this.form = response.user
|
this.form = response.data.user
|
||||||
this.roles = response.roles
|
this.roles = response.data.roles
|
||||||
this.total = this.roles.length
|
this.total = this.roles.length
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.roles.forEach((row) => {
|
this.roles.forEach((row) => {
|
||||||
|
|
|
||||||
|
|
@ -123,8 +123,8 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item v-if="form.userId == undefined" label="用户名称" prop="loginName">
|
<el-form-item v-if="form.userId == undefined" label="登录名" prop="loginName">
|
||||||
<el-input v-model="form.loginName" placeholder="请输入用户名称" maxlength="30" />
|
<el-input v-model="form.loginName" placeholder="登录名" maxlength="30" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
|
|
@ -476,10 +476,15 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}).then(({ value }) => {
|
}).then(({ value }) => {
|
||||||
resetUserPwd(row.userId, value).then(response => {
|
let data={
|
||||||
this.$modal.msgSuccess("修改成功,新密码是:" + value)
|
userId: row.userId,
|
||||||
})
|
loginName: row.loginName,
|
||||||
}).catch(() => {})
|
password: value
|
||||||
|
}
|
||||||
|
resetUserPwd(data).then(response => {
|
||||||
|
this.$modal.msgSuccess("修改成功,新密码是:" + value)
|
||||||
|
})
|
||||||
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
/** 分配角色操作 */
|
/** 分配角色操作 */
|
||||||
handleAuthRole: function(row) {
|
handleAuthRole: function(row) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.ruoyi.web.controller.system;
|
package com.ruoyi.web.controller.system;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
|
@ -467,4 +468,16 @@ public class SysRoleController extends BaseController
|
||||||
roleService.checkRoleDataScope(roleId);
|
roleService.checkRoleDataScope(roleId);
|
||||||
return toAjax(roleService.insertAuthUsers(roleId, userIds));
|
return toAjax(roleService.insertAuthUsers(roleId, userIds));
|
||||||
}
|
}
|
||||||
|
@GetMapping("/vue/deptTree/{roleId}")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
|
||||||
|
{
|
||||||
|
AjaxResult ajax = AjaxResult.success();
|
||||||
|
SysRole sysRole = new SysRole();
|
||||||
|
sysRole.setRoleId(roleId);
|
||||||
|
List<Ztree> ztrees = deptService.roleDeptTreeData(sysRole);
|
||||||
|
ajax.put("checkedKeys", ztrees.stream().filter(Ztree::isChecked).map(Ztree::getId).collect(Collectors.toList()));
|
||||||
|
ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
|
||||||
|
return ajax;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,9 @@ package com.ruoyi.web.controller.system;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Dict;
|
import cn.hutool.core.lang.Dict;
|
||||||
|
|
@ -269,6 +271,19 @@ public class SysUserController extends BaseController
|
||||||
mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
||||||
return prefix + "/authRole";
|
return prefix + "/authRole";
|
||||||
}
|
}
|
||||||
|
@RequiresPermissions("system:user:edit")
|
||||||
|
@GetMapping("/vue/authRole/{userId}")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult authRole(@PathVariable("userId") Long userId)
|
||||||
|
{
|
||||||
|
Map<String,Object> mmap=new HashMap<>();
|
||||||
|
SysUser user = userService.selectUserById(userId);
|
||||||
|
// 获取用户所属的角色列表
|
||||||
|
List<SysRole> roles = roleService.selectRolesByUserId(userId);
|
||||||
|
mmap.put("user", user);
|
||||||
|
mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
||||||
|
return AjaxResult.success(mmap);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户授权角色
|
* 用户授权角色
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
flowable:
|
||||||
|
database-schema-update: false
|
||||||
|
ruoyi:
|
||||||
|
excelTemplate: /home/application/excelTemplate
|
||||||
|
profile: /home/application/uploadPath
|
||||||
|
# 数据源配置
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
|
druid:
|
||||||
|
# 主库数据源
|
||||||
|
master:
|
||||||
|
url: jdbc:mysql://121.199.168.157:3306/unis_pms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowMultiQueries=true
|
||||||
|
username: root
|
||||||
|
password: unis@db
|
||||||
|
# 从库数据源
|
||||||
|
slave:
|
||||||
|
# 从数据源开关/默认关闭
|
||||||
|
enabled: false
|
||||||
|
url:
|
||||||
|
username:
|
||||||
|
password:
|
||||||
|
# 初始连接数
|
||||||
|
initialSize: 5
|
||||||
|
# 最小连接池数量
|
||||||
|
minIdle: 10
|
||||||
|
# 最大连接池数量
|
||||||
|
maxActive: 20
|
||||||
|
# 配置获取连接等待超时的时间
|
||||||
|
maxWait: 60000
|
||||||
|
# 配置连接超时时间
|
||||||
|
connectTimeout: 30000
|
||||||
|
# 配置网络超时时间
|
||||||
|
socketTimeout: 60000
|
||||||
|
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||||
|
timeBetweenEvictionRunsMillis: 60000
|
||||||
|
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||||
|
minEvictableIdleTimeMillis: 300000
|
||||||
|
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||||
|
maxEvictableIdleTimeMillis: 900000
|
||||||
|
# 配置检测连接是否有效
|
||||||
|
validationQuery: SELECT 1 FROM DUAL
|
||||||
|
testWhileIdle: true
|
||||||
|
testOnBorrow: false
|
||||||
|
testOnReturn: false
|
||||||
|
webStatFilter:
|
||||||
|
enabled: true
|
||||||
|
statViewServlet:
|
||||||
|
enabled: true
|
||||||
|
# 设置白名单,不填则允许所有访问
|
||||||
|
allow:
|
||||||
|
url-pattern: /druid/*
|
||||||
|
# 控制台管理用户名和密码
|
||||||
|
login-username: ruoyi
|
||||||
|
login-password: 123456
|
||||||
|
filter:
|
||||||
|
stat:
|
||||||
|
enabled: true
|
||||||
|
# 慢SQL记录
|
||||||
|
log-slow-sql: true
|
||||||
|
slow-sql-millis: 1000
|
||||||
|
merge-sql: true
|
||||||
|
wall:
|
||||||
|
config:
|
||||||
|
multi-statement-allow: true
|
||||||
|
unis:
|
||||||
|
order:
|
||||||
|
# 执行单截止时间
|
||||||
|
endHour: 96
|
||||||
|
mail:
|
||||||
|
enabled: false
|
||||||
|
|
@ -4,7 +4,9 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.validation.constraints.*;
|
import javax.validation.constraints.*;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
@ -22,6 +24,7 @@ import com.ruoyi.common.xss.Xss;
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@ToString
|
@ToString
|
||||||
|
@Data
|
||||||
public class SysUser extends BaseEntity
|
public class SysUser extends BaseEntity
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
@ -40,13 +43,16 @@ public class SysUser extends BaseEntity
|
||||||
|
|
||||||
/** 角色ID */
|
/** 角色ID */
|
||||||
private Long roleId;
|
private Long roleId;
|
||||||
|
private String roleKey;
|
||||||
|
|
||||||
/** 登录名称 */
|
/** 登录名称 */
|
||||||
@Excel(name = "登录名称")
|
@Excel(name = "登录名称")
|
||||||
|
@Getter(value = AccessLevel.NONE)
|
||||||
private String loginName;
|
private String loginName;
|
||||||
|
|
||||||
/** 用户名称 */
|
/** 用户名称 */
|
||||||
@Excel(name = "用户名称")
|
@Excel(name = "用户名称")
|
||||||
|
@Getter(value = AccessLevel.NONE)
|
||||||
private String userName;
|
private String userName;
|
||||||
|
|
||||||
/** 用户类型 */
|
/** 用户类型 */
|
||||||
|
|
@ -54,10 +60,12 @@ public class SysUser extends BaseEntity
|
||||||
|
|
||||||
/** 用户邮箱 */
|
/** 用户邮箱 */
|
||||||
@Excel(name = "用户邮箱")
|
@Excel(name = "用户邮箱")
|
||||||
|
@Getter(value = AccessLevel.NONE)
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
/** 手机号码 */
|
/** 手机号码 */
|
||||||
@Excel(name = "手机号码", cellType = ColumnType.TEXT)
|
@Excel(name = "手机号码", cellType = ColumnType.TEXT)
|
||||||
|
@Getter(value = AccessLevel.NONE)
|
||||||
private String phonenumber;
|
private String phonenumber;
|
||||||
|
|
||||||
/** 用户性别 */
|
/** 用户性别 */
|
||||||
|
|
@ -68,9 +76,11 @@ public class SysUser extends BaseEntity
|
||||||
private String avatar;
|
private String avatar;
|
||||||
|
|
||||||
/** 密码 */
|
/** 密码 */
|
||||||
|
@Getter(value = AccessLevel.NONE)
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
/** 盐加密 */
|
/** 盐加密 */
|
||||||
|
@Getter(value = AccessLevel.NONE)
|
||||||
private String salt;
|
private String salt;
|
||||||
|
|
||||||
/** 帐号状态(0正常 1停用) */
|
/** 帐号状态(0正常 1停用) */
|
||||||
|
|
@ -116,15 +126,7 @@ public class SysUser extends BaseEntity
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getUserId()
|
|
||||||
{
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserId(Long userId)
|
|
||||||
{
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAdmin()
|
public boolean isAdmin()
|
||||||
{
|
{
|
||||||
|
|
@ -136,35 +138,6 @@ public class SysUser extends BaseEntity
|
||||||
return userId != null && 1L == userId;
|
return userId != null && 1L == userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getDeptId()
|
|
||||||
{
|
|
||||||
return deptId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeptId(Long deptId)
|
|
||||||
{
|
|
||||||
this.deptId = deptId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getParentId()
|
|
||||||
{
|
|
||||||
return parentId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParentId(Long parentId)
|
|
||||||
{
|
|
||||||
this.parentId = parentId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getRoleId()
|
|
||||||
{
|
|
||||||
return roleId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRoleId(Long roleId)
|
|
||||||
{
|
|
||||||
this.roleId = roleId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Xss(message = "登录账号不能包含脚本字符")
|
@Xss(message = "登录账号不能包含脚本字符")
|
||||||
@NotBlank(message = "登录账号不能为空")
|
@NotBlank(message = "登录账号不能为空")
|
||||||
|
|
@ -174,11 +147,6 @@ public class SysUser extends BaseEntity
|
||||||
return loginName;
|
return loginName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoginName(String loginName)
|
|
||||||
{
|
|
||||||
this.loginName = loginName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Xss(message = "用户昵称不能包含脚本字符")
|
@Xss(message = "用户昵称不能包含脚本字符")
|
||||||
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
|
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
|
||||||
public String getUserName()
|
public String getUserName()
|
||||||
|
|
@ -186,20 +154,6 @@ public class SysUser extends BaseEntity
|
||||||
return userName;
|
return userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserName(String userName)
|
|
||||||
{
|
|
||||||
this.userName = userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserType()
|
|
||||||
{
|
|
||||||
return userType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserType(String userType)
|
|
||||||
{
|
|
||||||
this.userType = userType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Email(message = "邮箱格式不正确")
|
@Email(message = "邮箱格式不正确")
|
||||||
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
||||||
|
|
@ -208,52 +162,18 @@ public class SysUser extends BaseEntity
|
||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmail(String email)
|
|
||||||
{
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
|
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
|
||||||
public String getPhonenumber()
|
public String getPhonenumber()
|
||||||
{
|
{
|
||||||
return phonenumber;
|
return phonenumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPhonenumber(String phonenumber)
|
|
||||||
{
|
|
||||||
this.phonenumber = phonenumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSex()
|
|
||||||
{
|
|
||||||
return sex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSex(String sex)
|
|
||||||
{
|
|
||||||
this.sex = sex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAvatar()
|
|
||||||
{
|
|
||||||
return avatar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAvatar(String avatar)
|
|
||||||
{
|
|
||||||
this.avatar = avatar;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public String getPassword()
|
public String getPassword()
|
||||||
{
|
{
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPassword(String password)
|
|
||||||
{
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public String getSalt()
|
public String getSalt()
|
||||||
|
|
@ -261,110 +181,5 @@ public class SysUser extends BaseEntity
|
||||||
return salt;
|
return salt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSalt(String salt)
|
|
||||||
{
|
|
||||||
this.salt = salt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus()
|
|
||||||
{
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(String status)
|
|
||||||
{
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDelFlag()
|
|
||||||
{
|
|
||||||
return delFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDelFlag(String delFlag)
|
|
||||||
{
|
|
||||||
this.delFlag = delFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLoginIp()
|
|
||||||
{
|
|
||||||
return loginIp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoginIp(String loginIp)
|
|
||||||
{
|
|
||||||
this.loginIp = loginIp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getLoginDate()
|
|
||||||
{
|
|
||||||
return loginDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoginDate(Date loginDate)
|
|
||||||
{
|
|
||||||
this.loginDate = loginDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getPwdUpdateDate()
|
|
||||||
{
|
|
||||||
return pwdUpdateDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPwdUpdateDate(Date pwdUpdateDate)
|
|
||||||
{
|
|
||||||
this.pwdUpdateDate = pwdUpdateDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SysDept getDept()
|
|
||||||
{
|
|
||||||
if (dept == null)
|
|
||||||
{
|
|
||||||
dept = new SysDept();
|
|
||||||
}
|
|
||||||
return dept;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDept(SysDept dept)
|
|
||||||
{
|
|
||||||
this.dept = dept;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<SysRole> getRoles()
|
|
||||||
{
|
|
||||||
return roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRoles(List<SysRole> roles)
|
|
||||||
{
|
|
||||||
this.roles = roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long[] getRoleIds()
|
|
||||||
{
|
|
||||||
return roleIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRoleIds(Long[] roleIds)
|
|
||||||
{
|
|
||||||
this.roleIds = roleIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long[] getPostIds()
|
|
||||||
{
|
|
||||||
return postIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPostIds(Long[] postIds)
|
|
||||||
{
|
|
||||||
this.postIds = postIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Long> getUserIdList() {
|
|
||||||
return userIdList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserIdList(List<Long> userIdList) {
|
|
||||||
this.userIdList = userIdList;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.ruoyi.sip.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
|
||||||
|
import com.ruoyi.sip.oms.domain.OmsPayablePaymentPlan;
|
||||||
|
|
||||||
|
import com.ruoyi.sip.oms.service.IOmsPayablePaymentPlanService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/finance/payable/plan")
|
||||||
|
public class OmsPayablePlanController extends BaseController {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IOmsPayablePaymentPlanService paymentPlanService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/{payableBillId}")
|
||||||
|
public AjaxResult getPaymentPlan(@PathVariable("payableBillId") Long payableBillId) {
|
||||||
|
return AjaxResult.success(paymentPlanService.selectOmsPayablePaymentPlanListByPayableBillId(payableBillId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/{payableBillId}")
|
||||||
|
public AjaxResult updatePaymentPlan(@PathVariable("payableBillId") Long payableBillId, @RequestBody List<OmsPayablePaymentPlan> paymentPlanList) {
|
||||||
|
paymentPlanService.updatePaymentPlans(payableBillId, paymentPlanList);
|
||||||
|
return AjaxResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.ruoyi.sip.oms.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
@Data
|
||||||
|
public class OmsPayablePaymentPlan extends BaseEntity {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 主键 */
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 应付单ID */
|
||||||
|
private Long payableBillId;
|
||||||
|
|
||||||
|
/** 计划付款时间 */
|
||||||
|
private Date planPaymentDate;
|
||||||
|
|
||||||
|
/** 计划付款金额 */
|
||||||
|
private BigDecimal planAmount;
|
||||||
|
|
||||||
|
/** 计划付款比例 */
|
||||||
|
private BigDecimal planRate;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.ruoyi.sip.oms.mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.ruoyi.sip.oms.domain.OmsPayablePaymentPlan;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
public interface OmsPayablePaymentPlanMapper {
|
||||||
|
/**
|
||||||
|
* 根据应付单ID查询付款计划列表
|
||||||
|
*
|
||||||
|
* @param payableBillId 应付单ID
|
||||||
|
* @return 付款计划集合
|
||||||
|
*/
|
||||||
|
public List<OmsPayablePaymentPlan> selectOmsPayablePaymentPlanListByPayableBillId(Long payableBillId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插入单个付款计划
|
||||||
|
*
|
||||||
|
* @param omsPayablePaymentPlan 付款计划对象
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertOmsPayablePaymentPlan(OmsPayablePaymentPlan omsPayablePaymentPlan);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新单个付款计划
|
||||||
|
*
|
||||||
|
* @param omsPayablePaymentPlan 付款计划对象
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateOmsPayablePaymentPlan(OmsPayablePaymentPlan omsPayablePaymentPlan);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量新增付款计划
|
||||||
|
*
|
||||||
|
* @param omsPayablePaymentPlanList 付款计划列表
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int batchOmsPayablePaymentPlan(List<OmsPayablePaymentPlan> omsPayablePaymentPlanList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据应付单ID删除付款计划
|
||||||
|
*
|
||||||
|
* @param payableBillId 应付单ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteOmsPayablePaymentPlanByPayableBillId(Long payableBillId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID删除付款计划
|
||||||
|
*
|
||||||
|
* @param id 付款计划ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteOmsPayablePaymentPlanById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据应付单ID查询所有付款计划的ID
|
||||||
|
*
|
||||||
|
* @param payableBillId 应付单ID
|
||||||
|
* @return 付款计划ID列表
|
||||||
|
*/
|
||||||
|
public List<Long> selectOmsPayablePaymentPlanIdsByPayableBillId(Long payableBillId);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.ruoyi.sip.oms.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.ruoyi.sip.oms.domain.OmsPayablePaymentPlan;
|
||||||
|
|
||||||
|
public interface IOmsPayablePaymentPlanService {
|
||||||
|
/**
|
||||||
|
* 根据应付单ID查询付款计划列表
|
||||||
|
*
|
||||||
|
* @param payableBillId 应付单ID
|
||||||
|
* @return 付款计划集合
|
||||||
|
*/
|
||||||
|
public List<OmsPayablePaymentPlan> selectOmsPayablePaymentPlanListByPayableBillId(Long payableBillId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新付款计划
|
||||||
|
*
|
||||||
|
* @param payableBillId 应付单ID
|
||||||
|
* @param paymentPlanList 付款计划列表
|
||||||
|
*/
|
||||||
|
public void updatePaymentPlans(Long payableBillId, List<OmsPayablePaymentPlan> paymentPlanList);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.ruoyi.sip.oms.service.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.ShiroUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import com.ruoyi.sip.oms.mapper.OmsPayablePaymentPlanMapper;
|
||||||
|
import com.ruoyi.sip.oms.domain.OmsPayablePaymentPlan;
|
||||||
|
import com.ruoyi.sip.oms.service.IOmsPayablePaymentPlanService;
|
||||||
|
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class OmsPayablePaymentPlanServiceImpl implements IOmsPayablePaymentPlanService {
|
||||||
|
@Autowired
|
||||||
|
private OmsPayablePaymentPlanMapper omsPayablePaymentPlanMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<OmsPayablePaymentPlan> selectOmsPayablePaymentPlanListByPayableBillId(Long payableBillId) {
|
||||||
|
return omsPayablePaymentPlanMapper.selectOmsPayablePaymentPlanListByPayableBillId(payableBillId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void updatePaymentPlans(Long payableBillId, List<OmsPayablePaymentPlan> paymentPlanList) {
|
||||||
|
// 获取数据库中现有付款计划的ID
|
||||||
|
List<Long> existingPlanIds = omsPayablePaymentPlanMapper.selectOmsPayablePaymentPlanIdsByPayableBillId(payableBillId);
|
||||||
|
Set<Long> existingPlanIdSet = existingPlanIds.stream().collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// 用于存放前端传入的有效(非新增或已删除)的计划ID
|
||||||
|
Set<Long> incomingPlanIdSet = paymentPlanList.stream()
|
||||||
|
.filter(plan -> plan.getId() != null)
|
||||||
|
.map(OmsPayablePaymentPlan::getId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
for (OmsPayablePaymentPlan plan : paymentPlanList) {
|
||||||
|
plan.setPayableBillId(payableBillId);
|
||||||
|
if (plan.getId() == null) {
|
||||||
|
// 新增付款计划
|
||||||
|
plan.setCreateBy(ShiroUtils.getLoginName());
|
||||||
|
omsPayablePaymentPlanMapper.insertOmsPayablePaymentPlan(plan);
|
||||||
|
} else if (existingPlanIdSet.contains(plan.getId())) {
|
||||||
|
// 更新现有付款计划
|
||||||
|
omsPayablePaymentPlanMapper.updateOmsPayablePaymentPlan(plan);
|
||||||
|
}
|
||||||
|
// 如果plan.getId()不为null但不在existingPlanIdSet中,说明是前端新添加但带有id的脏数据,或者是非法数据,这里不处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除数据库中存在但前端未提交的付款计划
|
||||||
|
existingPlanIdSet.removeAll(incomingPlanIdSet);
|
||||||
|
for (Long idToDelete : existingPlanIdSet) {
|
||||||
|
omsPayablePaymentPlanMapper.deleteOmsPayablePaymentPlanById(idToDelete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -193,7 +193,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</foreach>
|
</foreach>
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
|
order by t2.create_time desc
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
<select id="listByItemId" resultType="com.ruoyi.sip.domain.OmsPurchaseOrderItem">
|
<select id="listByItemId" resultType="com.ruoyi.sip.domain.OmsPurchaseOrderItem">
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</if>
|
</if>
|
||||||
<if test="userId != null and userId != 0">
|
<if test="userId != null and userId != 0">
|
||||||
AND u.user_id = #{userId}
|
AND u.user_id = #{userId}
|
||||||
|
</if>
|
||||||
|
<if test="roleId != null and roleId != ''">
|
||||||
|
AND u.user_id in (select user_id from sys_user_role where role_id=#{roleId})
|
||||||
</if>
|
</if>
|
||||||
<if test="userName != null and userName != ''">
|
<if test="userName != null and userName != ''">
|
||||||
AND u.user_name like concat('%', #{userName}, '%')
|
AND u.user_name like concat('%', #{userName}, '%')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue