feat(currency): 引入精确货币舍入工具函数并优化价格计算逻辑

- 在 ruoyi.js 中新增 preciseCurrencyRound 函数用于处理货币精度
- 替换 ConfigInfo.vue 和 ProductConfig.vue 中的 Math.round 为精确舍入方法
- 移除 ProductConfig.vue 组件内原有的 preciseCurrencyRound 方法定义
- 优化库存管理页面排序字段,从 deliveryTime 改为 createTime
- 新增项目与订单详情抽屉组件,替换原有占位提示逻辑
- 设置默认排序方式为按 approveTime 降序排列已审批订单列表
dev_1.0.0
chenhao 2025-11-25 15:16:54 +08:00
parent 87c5fade50
commit d745fe6de8
5 changed files with 45 additions and 31 deletions

View File

@ -226,3 +226,9 @@ export function getNormalPath(p) {
export function blobValidate(data) {
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');
}

View File

@ -148,6 +148,8 @@ export default {
customerName: null,
dutyName: null,
approveNode: null,
orderByColumn:'approveTime',
isAsc: 'desc'
},
};
},

View File

@ -206,6 +206,8 @@
</template>
<script>
import {preciseCurrencyRound} from "@/utils/ruoyi";
export default {
name: "ConfigInfo",
props: {
@ -300,8 +302,7 @@ export default {
if (discount === 1) {
return product.allPrice;
}
const discountedUnitPrice = product.price * discount;
const roundedDiscountedUnitPrice = Math.round(discountedUnitPrice * 100) / 100;
const roundedDiscountedUnitPrice = preciseCurrencyRound( product.price * discount);
return roundedDiscountedUnitPrice * product.quantity;
},
calculateTotal(productList, discount) {

View File

@ -275,20 +275,33 @@
</el-row>
</el-form>
</el-drawer>
<!-- 项目详情抽屉 -->
<project-detail-drawer :visible.sync="projectDrawerVisible" :project-id="currentProjectId" />
<!-- 订单详情抽屉 -->
<order-detail-drawer :visible.sync="orderDrawerVisible" :order-id="currentOrderId" title="订单详情" />
</div>
</template>
<script>
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 {
name: "Stock",
components: {
ProjectDetailDrawer, OrderDetailDrawer,
Pagination,
},
data() {
return {
currentOrderId: null,
projectDrawerVisible: false,
orderDrawerVisible: false,
currentProjectId: null,
//
loading: true,
//
@ -318,7 +331,7 @@ export default {
orderCode: null,
stockStatus: null,
deliveryTimeRange: [], // For el-date-picker daterange
orderByColumn: 't2.deliveryTime',
orderByColumn: 't1.createTime',
isAsc: 'desc',
},
//
@ -551,19 +564,13 @@ export default {
},
/** 查看项目详情 */
viewProjectDetail(projectId) {
// Placeholder: In a real app, this would open a dialog/drawer or navigate to a project detail page.
// Example using El-drawer if a component exists:
// 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);
this.currentProjectId = projectId;
this.projectDrawerVisible = true;
},
/** 查看订单详情 */
viewDetail(orderId) {
// Placeholder: In a real app, this would open a dialog/drawer or navigate to an order detail page.
this.$modal.alert('查看订单详情 ID: ' + orderId);
console.log('Viewing Order Detail ID:', orderId);
this.currentOrderId = orderId;
this.orderDrawerVisible = true;
},
/** 查看审批日志 */
viewApproveLog(orderId) {

View File

@ -254,6 +254,7 @@
<script>
import SelectProduct from '@/views/system/product/selectProduct.vue';
import {preciseCurrencyRound} from "@/utils/ruoyi";
export default {
name: 'ProductConfig',
@ -321,8 +322,8 @@ export default {
quantity: item.quantity || 0,
taxRate: item.taxRate || 13,
cataloguePriceFormat: this.formatAmount(item.cataloguePrice),
guidanceDiscountFormat: item.guidanceDiscount ? this.preciseCurrencyRound(item.guidanceDiscount * 100, 2) : '',
discountFormat: item.discount ? this.preciseCurrencyRound(item.discount * 100, 2) : '',
guidanceDiscountFormat: item.guidanceDiscount ? preciseCurrencyRound(item.guidanceDiscount * 100, 2) : '',
discountFormat: item.discount ? preciseCurrencyRound(item.discount * 100, 2) : '',
priceFormat: this.formatAmount(item.price),
allPriceFormat: this.formatAmount(item.allPrice),
catalogueAllPriceFormat: this.formatAmount(item.catalogueAllPrice)
@ -412,9 +413,9 @@ export default {
row.cataloguePrice = product.cataloguePrice;
row.cataloguePriceFormat = this.formatAmount(product.cataloguePrice);
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.discountFormat = product.guidanceDiscount ? this.preciseCurrencyRound(product.guidanceDiscount * 100, 2) : '';
row.discountFormat = product.guidanceDiscount ? preciseCurrencyRound(product.guidanceDiscount * 100, 2) : '';
this.calculateRow(row);
this.emitChange();
@ -438,14 +439,14 @@ export default {
if (isNaN(price)) {
price = 0;
}
row.price = this.preciseCurrencyRound(price, 2);
row.price = preciseCurrencyRound(price, 2);
row.priceFormat = this.formatAmount(row.price);
// 0
if (row.cataloguePrice && row.cataloguePrice > 0) {
const discount = row.price / row.cataloguePrice;
row.discount = this.preciseCurrencyRound(discount, 4); // 4
row.discountFormat = this.preciseCurrencyRound(discount * 100, 2); // 2
row.discount = preciseCurrencyRound(discount, 4); // 4
row.discountFormat = preciseCurrencyRound(discount * 100, 2); // 2
} else {
// 00
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.catalogueAllPrice = this.preciseCurrencyRound(row.cataloguePrice * row.quantity, 2);
row.catalogueAllPrice = preciseCurrencyRound(row.cataloguePrice * row.quantity, 2);
row.catalogueAllPriceFormat = this.formatAmount(row.catalogueAllPrice);
this.emitChange();
@ -466,16 +467,16 @@ export default {
}
// = *
const discount = row.discountFormat ? row.discountFormat / 100 : 0;
row.discount = this.preciseCurrencyRound(discount, 4);
row.price = this.preciseCurrencyRound(row.cataloguePrice * discount, 2);
row.discount = preciseCurrencyRound(discount, 4);
row.price =preciseCurrencyRound(row.cataloguePrice * discount, 2);
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.catalogueAllPrice = this.preciseCurrencyRound(row.cataloguePrice * row.quantity, 2);
row.catalogueAllPrice = preciseCurrencyRound(row.cataloguePrice * row.quantity, 2);
row.catalogueAllPriceFormat = this.formatAmount(row.catalogueAllPrice);
this.emitChange();
@ -487,9 +488,6 @@ export default {
maximumFractionDigits: 2
});
},
preciseCurrencyRound(value, decimals = 2) {
return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
},
emitChange() {
const data = {
softwareProjectProductInfoList: this.softwareList.map(item => ({
@ -537,7 +535,7 @@ export default {
if (isNaN(cataloguePrice)) {
cataloguePrice = 0;
}
row.cataloguePrice = this.preciseCurrencyRound(cataloguePrice, 2);
row.cataloguePrice = preciseCurrencyRound(cataloguePrice, 2);
row.cataloguePriceFormat = this.formatAmount(row.cataloguePrice);
// Recalculate based on new catalogue price