376 lines
12 KiB
Vue
376 lines
12 KiB
Vue
<template>
|
||
<view class="calculator-page">
|
||
<!-- 自定义导航栏 -->
|
||
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||
<view class="custom-navbar__content" :style="{ height: navBarHeight + 'px' }">
|
||
<image class="custom-navbar__back" src="/static/ic_back.png" mode="aspectFit" @click="goBack" />
|
||
<text class="custom-navbar__title">金工石计算器</text>
|
||
<view class="custom-navbar__placeholder" />
|
||
</view>
|
||
</view>
|
||
<view :style="{ height: (statusBarHeight + navBarHeight) + 'px' }" />
|
||
|
||
<!-- 第1行:净金重 = 金重 - 主石重×0.2 - 副石重×0.2 -->
|
||
<view class="calc-row calc-row--first">
|
||
<view class="calc-col">
|
||
<view class="field-row">
|
||
<text class="field-label">金重</text>
|
||
<input class="field-input" type="digit" v-model="row1.goldWeight" />
|
||
<text class="field-unit">g</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">主石量</text>
|
||
<input class="field-input" type="digit" v-model="row1.mainStoneWeight" />
|
||
<text class="field-unit">ct</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">副石重</text>
|
||
<input class="field-input" type="digit" v-model="row1.sideStoneWeight" />
|
||
<text class="field-unit">ct</text>
|
||
</view>
|
||
</view>
|
||
<view class="calc-col calc-col--result">
|
||
<view class="result-item">
|
||
<text class="result-label">净金重</text>
|
||
<text class="result-value">{{ res1 }}</text>
|
||
<text class="result-unit">克</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 第2行:含耗重 = 净金重 × 损耗 -->
|
||
<view class="calc-row">
|
||
<view class="calc-col">
|
||
<view class="field-row">
|
||
<text class="field-label">净金重</text>
|
||
<input class="field-input" type="digit" v-model="row2.netGoldWeight" />
|
||
<text class="field-unit">g</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">损耗</text>
|
||
<input class="field-input" type="digit" v-model="row2.lossRate" />
|
||
<text class="field-unit">%</text>
|
||
</view>
|
||
</view>
|
||
<view class="calc-col calc-col--result">
|
||
<view class="result-item">
|
||
<text class="result-label">含耗重</text>
|
||
<text class="result-value">{{ res2 }}</text>
|
||
<text class="result-unit">克</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 第3行:金值 = 含耗重 × 倒模金价 -->
|
||
<view class="calc-row">
|
||
<view class="calc-col">
|
||
<view class="field-row">
|
||
<text class="field-label">含耗重</text>
|
||
<input class="field-input" type="digit" v-model="row3.weightWithLoss" />
|
||
<text class="field-unit">g</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">倒模金价</text>
|
||
<input class="field-input" type="digit" v-model="row3.moldGoldPrice" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
</view>
|
||
<view class="calc-col calc-col--result">
|
||
<view class="result-item">
|
||
<text class="result-label">金值</text>
|
||
<text class="result-value">{{ res3 }}</text>
|
||
<text class="result-unit">元</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 第4行:主石总价 = 主石重 × 主石单价 -->
|
||
<view class="calc-row">
|
||
<view class="calc-col">
|
||
<view class="field-row">
|
||
<text class="field-label">主石重</text>
|
||
<input class="field-input" type="digit" v-model="row4.mainStoneWeight" />
|
||
<text class="field-unit">ct</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">主石单价</text>
|
||
<input class="field-input" type="digit" v-model="row4.mainStoneUnitPrice" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
</view>
|
||
<view class="calc-col calc-col--result">
|
||
<view class="result-item">
|
||
<text class="result-label">主石总价</text>
|
||
<text class="result-value">{{ res4 }}</text>
|
||
<text class="result-unit">元</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 第5行:副石总价 = 副石重 × 副石单价 -->
|
||
<view class="calc-row">
|
||
<view class="calc-col">
|
||
<view class="field-row">
|
||
<text class="field-label">副石重</text>
|
||
<input class="field-input" type="digit" v-model="row5.sideStoneWeight" />
|
||
<text class="field-unit">ct</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">副石单价</text>
|
||
<input class="field-input" type="digit" v-model="row5.sideStoneUnitPrice" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
</view>
|
||
<view class="calc-col calc-col--result">
|
||
<view class="result-item">
|
||
<text class="result-label">副石总价</text>
|
||
<text class="result-value">{{ res5 }}</text>
|
||
<text class="result-unit">元</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 第6行:微镶总价 = 副石粒数 × 微镶费 -->
|
||
<view class="calc-row">
|
||
<view class="calc-col">
|
||
<view class="field-row">
|
||
<text class="field-label">副石粒数</text>
|
||
<input class="field-input" type="digit" v-model="row6.sideStoneCount" />
|
||
<text class="field-unit">p</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">微镶费</text>
|
||
<input class="field-input" type="digit" v-model="row6.microSettingFee" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
</view>
|
||
<view class="calc-col calc-col--result">
|
||
<view class="result-item">
|
||
<text class="result-label">微镶总价</text>
|
||
<text class="result-value">{{ res6 }}</text>
|
||
<text class="result-unit">元</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 第7行:总价汇总 -->
|
||
<view class="calc-row calc-row--last">
|
||
<view class="calc-col">
|
||
<view class="field-row">
|
||
<text class="field-label">金值</text>
|
||
<input class="field-input" type="digit" v-model="row7.goldValue" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">主石总价</text>
|
||
<input class="field-input" type="digit" v-model="row7.mainStoneTotal" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">副石总价</text>
|
||
<input class="field-input" type="digit" v-model="row7.sideStoneTotal" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">主石镶费</text>
|
||
<input class="field-input" type="digit" v-model="row7.mainStoneSettingFee" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">微镶总价</text>
|
||
<input class="field-input" type="digit" v-model="row7.microSettingTotal" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">3D起版费</text>
|
||
<input class="field-input" type="digit" v-model="row7.threeDFee" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">基本工费</text>
|
||
<input class="field-input" type="digit" v-model="row7.basicLaborCost" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="field-label">其他费用</text>
|
||
<input class="field-input" type="digit" v-model="row7.otherCost" />
|
||
<text class="field-unit">元</text>
|
||
</view>
|
||
</view>
|
||
<view class="calc-col calc-col--result">
|
||
<view class="result-item result-item--total">
|
||
<text class="result-label">总价</text>
|
||
<text class="result-value result-value--total">{{ res7 }}</text>
|
||
<text class="result-unit">元</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, reactive, computed } from 'vue'
|
||
|
||
const statusBarHeight = ref(20)
|
||
const navBarHeight = ref(44)
|
||
try {
|
||
const sysInfo = uni.getSystemInfoSync()
|
||
statusBarHeight.value = sysInfo.statusBarHeight || 20
|
||
// #ifdef MP-WEIXIN
|
||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||
navBarHeight.value = (menuBtn.top - (sysInfo.statusBarHeight || 20)) * 2 + menuBtn.height
|
||
// #endif
|
||
} catch { /* fallback */ }
|
||
|
||
function goBack() {
|
||
uni.navigateBack({ delta: 1 })
|
||
}
|
||
|
||
function n(v: string | number): number {
|
||
const num = Number(v)
|
||
return isNaN(num) ? 0 : num
|
||
}
|
||
|
||
function fmt(v: number): string {
|
||
return v.toFixed(2)
|
||
}
|
||
|
||
// 每行独立的输入数据
|
||
const row1 = reactive({ goldWeight: '0', mainStoneWeight: '0', sideStoneWeight: '0' })
|
||
const row2 = reactive({ netGoldWeight: '0', lossRate: '0' })
|
||
const row3 = reactive({ weightWithLoss: '0', moldGoldPrice: '0' })
|
||
const row4 = reactive({ mainStoneWeight: '0', mainStoneUnitPrice: '0' })
|
||
const row5 = reactive({ sideStoneWeight: '0', sideStoneUnitPrice: '0' })
|
||
const row6 = reactive({ sideStoneCount: '0', microSettingFee: '3.5' })
|
||
const row7 = reactive({
|
||
goldValue: '0', mainStoneTotal: '0', sideStoneTotal: '0',
|
||
mainStoneSettingFee: '0', microSettingTotal: '0',
|
||
threeDFee: '0', basicLaborCost: '0', otherCost: '0',
|
||
})
|
||
|
||
// 公式1: 净金重 = 金重 - 主石重×0.2 - 副石重×0.2
|
||
const res1 = computed(() => fmt(n(row1.goldWeight) - n(row1.mainStoneWeight) * 0.2 - n(row1.sideStoneWeight) * 0.2))
|
||
|
||
// 公式2: 含耗重 = 净金重 × 损耗
|
||
const res2 = computed(() => fmt(n(row2.netGoldWeight) * n(row2.lossRate)))
|
||
|
||
// 公式3: 金值 = 含耗重 × 倒模金价
|
||
const res3 = computed(() => fmt(n(row3.weightWithLoss) * n(row3.moldGoldPrice)))
|
||
|
||
// 公式4: 主石总价 = 主石重 × 主石单价
|
||
const res4 = computed(() => fmt(n(row4.mainStoneWeight) * n(row4.mainStoneUnitPrice)))
|
||
|
||
// 公式5: 副石总价 = 副石重 × 副石单价
|
||
const res5 = computed(() => fmt(n(row5.sideStoneWeight) * n(row5.sideStoneUnitPrice)))
|
||
|
||
// 公式6: 微镶总价 = 副石粒数 × 微镶费
|
||
const res6 = computed(() => fmt(n(row6.sideStoneCount) * n(row6.microSettingFee)))
|
||
|
||
// 公式7: 总价 = 金值 + 主石总价 + 副石总价 + 主石镶费 + 微镶总价 + 3D起版费 + 基本工费 + 其他费用
|
||
const res7 = computed(() => fmt(
|
||
n(row7.goldValue) + n(row7.mainStoneTotal) + n(row7.sideStoneTotal)
|
||
+ n(row7.mainStoneSettingFee) + n(row7.microSettingTotal)
|
||
+ n(row7.threeDFee) + n(row7.basicLaborCost) + n(row7.otherCost)
|
||
))
|
||
</script>
|
||
|
||
<style scoped>
|
||
.calculator-page {
|
||
min-height: 100vh;
|
||
background: #f5f5f5;
|
||
}
|
||
.custom-navbar {
|
||
background: linear-gradient(to right, #FFCFDE, #FFA6C4);
|
||
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
||
}
|
||
.custom-navbar__content {
|
||
display: flex; align-items: center; padding: 0 24rpx;
|
||
}
|
||
.custom-navbar__back { width: 44rpx; height: 44rpx; }
|
||
.custom-navbar__title {
|
||
flex: 1; text-align: center; font-size: 34rpx; font-weight: bold; color: #333;
|
||
}
|
||
.custom-navbar__placeholder { width: 44rpx; }
|
||
|
||
.calc-row {
|
||
display: flex;
|
||
background: #fff;
|
||
margin: 0 24rpx;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
}
|
||
.calc-row--first {
|
||
margin-top: 16rpx;
|
||
border-radius: 16rpx 16rpx 0 0;
|
||
}
|
||
.calc-row--last {
|
||
border-radius: 0 0 16rpx 16rpx;
|
||
border-bottom: none;
|
||
margin-bottom: 32rpx;
|
||
}
|
||
.calc-col {
|
||
flex: 1;
|
||
padding: 20rpx 24rpx;
|
||
}
|
||
.calc-col--result {
|
||
flex: 0 0 260rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-left: 1rpx solid #f0f0f0;
|
||
}
|
||
.field-row {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 12rpx 0;
|
||
}
|
||
.field-label {
|
||
font-size: 26rpx;
|
||
color: #333;
|
||
width: 140rpx;
|
||
flex-shrink: 0;
|
||
font-weight: 500;
|
||
}
|
||
.field-input {
|
||
flex: 1;
|
||
height: 56rpx;
|
||
background: #fff5f8;
|
||
border: none;
|
||
border-radius: 8rpx;
|
||
padding: 0 16rpx;
|
||
font-size: 28rpx;
|
||
color: #e91e63;
|
||
text-align: center;
|
||
font-weight: 600;
|
||
}
|
||
.field-unit {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
margin-left: 8rpx;
|
||
width: 40rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
.result-item {
|
||
text-align: center;
|
||
}
|
||
.result-label {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
.result-value {
|
||
font-size: 36rpx;
|
||
color: #e91e63;
|
||
font-weight: 700;
|
||
display: block;
|
||
}
|
||
.result-value--total {
|
||
font-size: 44rpx;
|
||
}
|
||
.result-unit {
|
||
font-size: 22rpx;
|
||
color: #999;
|
||
margin-left: 4rpx;
|
||
}
|
||
</style>
|