feat(currency): 引入精确货币舍入工具函数并优化价格计算逻辑
- 在 ruoyi.js 中新增 preciseCurrencyRound 函数用于处理货币精度 - 替换 ConfigInfo.vue 和 ProductConfig.vue 中的 Math.round 为精确舍入方法 - 移除 ProductConfig.vue 组件内原有的 preciseCurrencyRound 方法定义 - 优化库存管理页面排序字段,从 deliveryTime 改为 createTime - 新增项目与订单详情抽屉组件,替换原有占位提示逻辑 - 设置默认排序方式为按 approveTime 降序排列已审批订单列表master
parent
87c5fade50
commit
d745fe6de8
|
|
@ -226,3 +226,9 @@ export function getNormalPath(p) {
|
||||||
export function blobValidate(data) {
|
export function blobValidate(data) {
|
||||||
return data.type !== 'application/json'
|
return data.type !== 'application/json'
|
||||||
}
|
}
|
||||||
|
export function preciseCurrencyRound(amount,decimalPlace) {
|
||||||
|
if (decimalPlace){
|
||||||
|
return Number(Math.round(amount + `e${decimalPlace}`) + `e-${decimalPlace}`);
|
||||||
|
}
|
||||||
|
return Number(Math.round(amount + 'e2') + 'e-2');
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,8 @@ export default {
|
||||||
customerName: null,
|
customerName: null,
|
||||||
dutyName: null,
|
dutyName: null,
|
||||||
approveNode: null,
|
approveNode: null,
|
||||||
|
orderByColumn:'approveTime',
|
||||||
|
isAsc: 'desc'
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import {preciseCurrencyRound} from "@/utils/ruoyi";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ConfigInfo",
|
name: "ConfigInfo",
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -300,8 +302,7 @@ export default {
|
||||||
if (discount === 1) {
|
if (discount === 1) {
|
||||||
return product.allPrice;
|
return product.allPrice;
|
||||||
}
|
}
|
||||||
const discountedUnitPrice = product.price * discount;
|
const roundedDiscountedUnitPrice = preciseCurrencyRound( product.price * discount);
|
||||||
const roundedDiscountedUnitPrice = Math.round(discountedUnitPrice * 100) / 100;
|
|
||||||
return roundedDiscountedUnitPrice * product.quantity;
|
return roundedDiscountedUnitPrice * product.quantity;
|
||||||
},
|
},
|
||||||
calculateTotal(productList, discount) {
|
calculateTotal(productList, discount) {
|
||||||
|
|
|
||||||
|
|
@ -275,20 +275,33 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
||||||
|
<!-- 项目详情抽屉 -->
|
||||||
|
<project-detail-drawer :visible.sync="projectDrawerVisible" :project-id="currentProjectId" />
|
||||||
|
|
||||||
|
<!-- 订单详情抽屉 -->
|
||||||
|
<order-detail-drawer :visible.sync="orderDrawerVisible" :order-id="currentOrderId" title="订单详情" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listStock, getStock, addStock, updateStock, delStock, exportStock } from "@/api/inventory/stock";
|
import { listStock, getStock, addStock, updateStock, delStock, exportStock } from "@/api/inventory/stock";
|
||||||
import Pagination from '@/components/Pagination'; // Assuming standard path
|
import Pagination from '@/components/Pagination';
|
||||||
|
import OrderDetailDrawer from "@/views/project/order/OrderDetailDrawer.vue";
|
||||||
|
import ProjectDetailDrawer from "@/views/project/info/ProjectDetailDrawer.vue"; // Assuming standard path
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Stock",
|
name: "Stock",
|
||||||
components: {
|
components: {
|
||||||
|
ProjectDetailDrawer, OrderDetailDrawer,
|
||||||
Pagination,
|
Pagination,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
currentOrderId: null,
|
||||||
|
projectDrawerVisible: false,
|
||||||
|
orderDrawerVisible: false,
|
||||||
|
currentProjectId: null,
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 选中数组
|
// 选中数组
|
||||||
|
|
@ -318,7 +331,7 @@ export default {
|
||||||
orderCode: null,
|
orderCode: null,
|
||||||
stockStatus: null,
|
stockStatus: null,
|
||||||
deliveryTimeRange: [], // For el-date-picker daterange
|
deliveryTimeRange: [], // For el-date-picker daterange
|
||||||
orderByColumn: 't2.deliveryTime',
|
orderByColumn: 't1.createTime',
|
||||||
isAsc: 'desc',
|
isAsc: 'desc',
|
||||||
},
|
},
|
||||||
// 表单参数
|
// 表单参数
|
||||||
|
|
@ -551,19 +564,13 @@ export default {
|
||||||
},
|
},
|
||||||
/** 查看项目详情 */
|
/** 查看项目详情 */
|
||||||
viewProjectDetail(projectId) {
|
viewProjectDetail(projectId) {
|
||||||
// Placeholder: In a real app, this would open a dialog/drawer or navigate to a project detail page.
|
this.currentProjectId = projectId;
|
||||||
// Example using El-drawer if a component exists:
|
this.projectDrawerVisible = true;
|
||||||
// this.$refs.projectDetailDrawer.open(projectId);
|
|
||||||
// Or routing:
|
|
||||||
// this.$router.push('/project/detail/' + projectId);
|
|
||||||
this.$modal.alert('查看项目详情 ID: ' + projectId);
|
|
||||||
console.log('Viewing Project Detail ID:', projectId);
|
|
||||||
},
|
},
|
||||||
/** 查看订单详情 */
|
/** 查看订单详情 */
|
||||||
viewDetail(orderId) {
|
viewDetail(orderId) {
|
||||||
// Placeholder: In a real app, this would open a dialog/drawer or navigate to an order detail page.
|
this.currentOrderId = orderId;
|
||||||
this.$modal.alert('查看订单详情 ID: ' + orderId);
|
this.orderDrawerVisible = true;
|
||||||
console.log('Viewing Order Detail ID:', orderId);
|
|
||||||
},
|
},
|
||||||
/** 查看审批日志 */
|
/** 查看审批日志 */
|
||||||
viewApproveLog(orderId) {
|
viewApproveLog(orderId) {
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SelectProduct from '@/views/system/product/selectProduct.vue';
|
import SelectProduct from '@/views/system/product/selectProduct.vue';
|
||||||
|
import {preciseCurrencyRound} from "@/utils/ruoyi";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ProductConfig',
|
name: 'ProductConfig',
|
||||||
|
|
@ -321,8 +322,8 @@ export default {
|
||||||
quantity: item.quantity || 0,
|
quantity: item.quantity || 0,
|
||||||
taxRate: item.taxRate || 13,
|
taxRate: item.taxRate || 13,
|
||||||
cataloguePriceFormat: this.formatAmount(item.cataloguePrice),
|
cataloguePriceFormat: this.formatAmount(item.cataloguePrice),
|
||||||
guidanceDiscountFormat: item.guidanceDiscount ? this.preciseCurrencyRound(item.guidanceDiscount * 100, 2) : '',
|
guidanceDiscountFormat: item.guidanceDiscount ? preciseCurrencyRound(item.guidanceDiscount * 100, 2) : '',
|
||||||
discountFormat: item.discount ? this.preciseCurrencyRound(item.discount * 100, 2) : '',
|
discountFormat: item.discount ? preciseCurrencyRound(item.discount * 100, 2) : '',
|
||||||
priceFormat: this.formatAmount(item.price),
|
priceFormat: this.formatAmount(item.price),
|
||||||
allPriceFormat: this.formatAmount(item.allPrice),
|
allPriceFormat: this.formatAmount(item.allPrice),
|
||||||
catalogueAllPriceFormat: this.formatAmount(item.catalogueAllPrice)
|
catalogueAllPriceFormat: this.formatAmount(item.catalogueAllPrice)
|
||||||
|
|
@ -412,9 +413,9 @@ export default {
|
||||||
row.cataloguePrice = product.cataloguePrice;
|
row.cataloguePrice = product.cataloguePrice;
|
||||||
row.cataloguePriceFormat = this.formatAmount(product.cataloguePrice);
|
row.cataloguePriceFormat = this.formatAmount(product.cataloguePrice);
|
||||||
row.guidanceDiscount = product.guidanceDiscount;
|
row.guidanceDiscount = product.guidanceDiscount;
|
||||||
row.guidanceDiscountFormat = product.guidanceDiscount ? this.preciseCurrencyRound(product.guidanceDiscount * 100, 2) : '';
|
row.guidanceDiscountFormat = product.guidanceDiscount ? preciseCurrencyRound(product.guidanceDiscount * 100, 2) : '';
|
||||||
row.discount = product.guidanceDiscount || 0;
|
row.discount = product.guidanceDiscount || 0;
|
||||||
row.discountFormat = product.guidanceDiscount ? this.preciseCurrencyRound(product.guidanceDiscount * 100, 2) : '';
|
row.discountFormat = product.guidanceDiscount ? preciseCurrencyRound(product.guidanceDiscount * 100, 2) : '';
|
||||||
|
|
||||||
this.calculateRow(row);
|
this.calculateRow(row);
|
||||||
this.emitChange();
|
this.emitChange();
|
||||||
|
|
@ -438,14 +439,14 @@ export default {
|
||||||
if (isNaN(price)) {
|
if (isNaN(price)) {
|
||||||
price = 0;
|
price = 0;
|
||||||
}
|
}
|
||||||
row.price = this.preciseCurrencyRound(price, 2);
|
row.price = preciseCurrencyRound(price, 2);
|
||||||
row.priceFormat = this.formatAmount(row.price);
|
row.priceFormat = this.formatAmount(row.price);
|
||||||
|
|
||||||
// 如果目录单价存在且不为0,则重新计算折扣
|
// 如果目录单价存在且不为0,则重新计算折扣
|
||||||
if (row.cataloguePrice && row.cataloguePrice > 0) {
|
if (row.cataloguePrice && row.cataloguePrice > 0) {
|
||||||
const discount = row.price / row.cataloguePrice;
|
const discount = row.price / row.cataloguePrice;
|
||||||
row.discount = this.preciseCurrencyRound(discount, 4); // 精度为4位
|
row.discount = preciseCurrencyRound(discount, 4); // 精度为4位
|
||||||
row.discountFormat = this.preciseCurrencyRound(discount * 100, 2); // 显示为百分比,保留2位小数
|
row.discountFormat = preciseCurrencyRound(discount * 100, 2); // 显示为百分比,保留2位小数
|
||||||
} else {
|
} else {
|
||||||
// 如果目录单价为0,则折扣也为0
|
// 如果目录单价为0,则折扣也为0
|
||||||
row.discount = 0;
|
row.discount = 0;
|
||||||
|
|
@ -453,9 +454,9 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重新计算总价和目录总价
|
// 重新计算总价和目录总价
|
||||||
row.allPrice = this.preciseCurrencyRound(row.price * row.quantity, 2);
|
row.allPrice = preciseCurrencyRound(row.price * row.quantity, 2);
|
||||||
row.allPriceFormat = this.formatAmount(row.allPrice);
|
row.allPriceFormat = this.formatAmount(row.allPrice);
|
||||||
row.catalogueAllPrice = this.preciseCurrencyRound(row.cataloguePrice * row.quantity, 2);
|
row.catalogueAllPrice = preciseCurrencyRound(row.cataloguePrice * row.quantity, 2);
|
||||||
row.catalogueAllPriceFormat = this.formatAmount(row.catalogueAllPrice);
|
row.catalogueAllPriceFormat = this.formatAmount(row.catalogueAllPrice);
|
||||||
|
|
||||||
this.emitChange();
|
this.emitChange();
|
||||||
|
|
@ -466,16 +467,16 @@ export default {
|
||||||
}
|
}
|
||||||
// 计算单价 = 目录单价 * 折扣
|
// 计算单价 = 目录单价 * 折扣
|
||||||
const discount = row.discountFormat ? row.discountFormat / 100 : 0;
|
const discount = row.discountFormat ? row.discountFormat / 100 : 0;
|
||||||
row.discount = this.preciseCurrencyRound(discount, 4);
|
row.discount = preciseCurrencyRound(discount, 4);
|
||||||
row.price = this.preciseCurrencyRound(row.cataloguePrice * discount, 2);
|
row.price =preciseCurrencyRound(row.cataloguePrice * discount, 2);
|
||||||
row.priceFormat = this.formatAmount(row.price);
|
row.priceFormat = this.formatAmount(row.price);
|
||||||
|
|
||||||
// 计算总价 = 单价 * 数量
|
// 计算总价 = 单价 * 数量
|
||||||
row.allPrice = this.preciseCurrencyRound(row.price * row.quantity, 2);
|
row.allPrice = preciseCurrencyRound(row.price * row.quantity, 2);
|
||||||
row.allPriceFormat = this.formatAmount(row.allPrice);
|
row.allPriceFormat = this.formatAmount(row.allPrice);
|
||||||
|
|
||||||
// 计算目录总价 = 目录单价 * 数量
|
// 计算目录总价 = 目录单价 * 数量
|
||||||
row.catalogueAllPrice = this.preciseCurrencyRound(row.cataloguePrice * row.quantity, 2);
|
row.catalogueAllPrice = preciseCurrencyRound(row.cataloguePrice * row.quantity, 2);
|
||||||
row.catalogueAllPriceFormat = this.formatAmount(row.catalogueAllPrice);
|
row.catalogueAllPriceFormat = this.formatAmount(row.catalogueAllPrice);
|
||||||
|
|
||||||
this.emitChange();
|
this.emitChange();
|
||||||
|
|
@ -487,9 +488,6 @@ export default {
|
||||||
maximumFractionDigits: 2
|
maximumFractionDigits: 2
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
preciseCurrencyRound(value, decimals = 2) {
|
|
||||||
return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
|
|
||||||
},
|
|
||||||
emitChange() {
|
emitChange() {
|
||||||
const data = {
|
const data = {
|
||||||
softwareProjectProductInfoList: this.softwareList.map(item => ({
|
softwareProjectProductInfoList: this.softwareList.map(item => ({
|
||||||
|
|
@ -537,7 +535,7 @@ export default {
|
||||||
if (isNaN(cataloguePrice)) {
|
if (isNaN(cataloguePrice)) {
|
||||||
cataloguePrice = 0;
|
cataloguePrice = 0;
|
||||||
}
|
}
|
||||||
row.cataloguePrice = this.preciseCurrencyRound(cataloguePrice, 2);
|
row.cataloguePrice = preciseCurrencyRound(cataloguePrice, 2);
|
||||||
row.cataloguePriceFormat = this.formatAmount(row.cataloguePrice);
|
row.cataloguePriceFormat = this.formatAmount(row.cataloguePrice);
|
||||||
|
|
||||||
// Recalculate based on new catalogue price
|
// Recalculate based on new catalogue price
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue