ruoyi-geek-App/pages_caltools/components/NGCom.vue
2025-11-25 14:26:23 +08:00

405 lines
7.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="form-container">
<uni-forms label-position="top" :modelValue="formData" class="component-form">
<view class="fields-grid">
<!-- 常用组分选择框 -->
<uni-forms-item label="常用组分" class="form-item">
<uni-data-select v-model="selectedComponent" @change="handleComponentChange" placeholder="请选择常用组分"
:clear="true" :localdata="componentOptions" />
</uni-forms-item>
<!-- 合计输入框 -->
<uni-forms-item label="合计" class="form-item">
<uni-easyinput :value="totalPercentage" disabled class="total-input" />
</uni-forms-item>
</view>
</uni-forms>
<uni-forms :modelValue="formData" label-position="top" class="component-form" :label-width="160">
<view class="fields-grid">
<uni-forms-item v-for="field in componentFields" :key="field.prop" :label="field.label"
:name="field.prop" class="form-item">
<uni-easyinput v-model="formData[field.prop]" type="digit" @input="handleValueChange"
@focus="selectAllText" />
</uni-forms-item>
</view>
</uni-forms>
</view>
</template>
<script setup>
import {
ref,
watch,
onMounted,
computed,
nextTick
} from 'vue';
import {
onLoad
} from '@dcloudio/uni-app';
import {
useDict
} from '@/utils/dict'
// 使用字典Hook获取ngtools_cyzf字典数据
const {
ngtools_cyzf
} = useDict('ngtools_cyzf')
const dictLoading = ref(false)
// 计算属性:将字典数据转换为下拉框需要的格式
const componentOptions = computed(() => {
return (ngtools_cyzf.value || []).map(item => ({
value: item.value,
text: item.label
}))
})
// 字段配置元数据
const COMPONENT_FIELDS = [{
prop: 'ngC1',
label: '甲烷C1'
},
{
prop: 'ngN2',
label: '氮气N2'
},
{
prop: 'ngCo2',
label: '二氧化碳CO2'
},
{
prop: 'ngC2',
label: '乙烷C2'
},
{
prop: 'ngC3',
label: '丙烷C3'
},
{
prop: 'ngH2o',
label: '水H2O'
},
{
prop: 'ngH2s',
label: '硫化氢H2S'
},
{
prop: 'ngH2',
label: '氢气H2'
},
{
prop: 'ngCo',
label: '一氧化碳CO'
},
{
prop: 'ngO2',
label: '氧气O2'
},
{
prop: 'ngIc4',
label: '异丁烷iC4'
},
{
prop: 'ngNc4',
label: '正丁烷nC4'
},
{
prop: 'ngIc5',
label: '异戊烷iC5'
},
{
prop: 'ngNc5',
label: '正戊烷nC5'
},
{
prop: 'ngC6',
label: '己烷C6'
},
{
prop: 'ngC7',
label: '庚烷C7'
},
{
prop: 'ngC8',
label: '辛烷C8'
},
{
prop: 'ngC9',
label: '壬烷C9'
},
{
prop: 'ngC10',
label: '癸烷C10'
},
{
prop: 'ngHe',
label: '氦气He'
},
{
prop: 'ngAr',
label: '氩气Ar'
}
];
// 定义 props
const props = defineProps({
modelValue: {
type: String,
default: ''
},
elFormWidth: {
type: Number,
default: 180
}
});
// 定义 emits
const emits = defineEmits(['update:modelValue']);
// 定义响应式数据
const selectWidth = ref(0);
const selectedComponent = ref(null);
const formData = ref(initFormData());
const componentFields = ref(COMPONENT_FIELDS);
// 页面加载
onMounted(() => {
selectWidth.value = props.elFormWidth;
// 获取字典数据
});
// 计算属性
const totalPercentage = computed(() => {
return Object.values(formData.value)
.reduce((sum, val) => sum + (parseFloat(val) || 0), 0)
.toFixed(4);
});
// 初始化表单数据
function initFormData() {
return COMPONENT_FIELDS.reduce((acc, field) => {
acc[field.prop] = 0;
return acc;
}, {});
}
// 全选输入框文本
function selectAllText(event) {
// 在uniapp中可以通过设置selection-range实现全选
const query = uni.createSelectorQuery().in(this);
query.select(`[data-field="${event.target.dataset.field}"]`).node((res) => {
const node = res.node;
if (node && node.setSelectionRange) {
node.setSelectionRange(0, node.value.length);
}
}).exec();
}
// 解析传入的字符串值
function parseValueString(valueStr) {
const values = (valueStr || '').split('_');
componentFields.value.forEach((field, index) => {
const value = parseFloat(values[index]) || 0;
formData.value[field.prop] = value;
});
}
// 生成要输出的字符串值
function generateValueString() {
return Object.values(formData.value)
.map((v) => v.toFixed(4))
.join('_');
}
// 处理组件选择变化
function handleComponentChange(value) {
if (!value) return;
try {
console.log(value)
const componentData = JSON.parse(value);
Object.keys(formData.value).forEach((key) => {
formData.value[key] = parseFloat(componentData[key]) || 0;
});
emitUpdate();
} catch (error) {
uni.showToast({
title: '获取标准组分失败',
icon: 'none'
});
console.error(error);
}
}
// 处理值变化
function handleValueChange() {
nextTick(() => {
emitUpdate();
});
}
// 触发更新事件
function emitUpdate() {
if (Math.abs(parseFloat(totalPercentage.value) - 100) > 0.0001) {
uni.showToast({
title: '组分合计不等于100%,请检查输入',
icon: 'none'
});
}
emits('update:modelValue', generateValueString());
}
// 监听 elFormWidth 的变化
watch(
() => props.elFormWidth,
(newVal) => {
selectWidth.value = newVal;
}, {
deep: true
}
);
// 监听 value 的变化
watch(
() => props.modelValue,
(newVal) => {
parseValueString(newVal);
}, {
immediate: true
}
);
</script>
<style scoped>
.form-container {
padding: 10rpx;
box-sizing: border-box;
width: 100%;
}
.component-form {
background-color: #ffffff;
border-radius: 12rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}
/* 网格布局容器 */
.fields-grid {
display: grid;
gap: 24rpx;
/* 表单项之间的间距 */
width: 100%;
}
/* 表单项基础样式 */
.form-item {
width: 100%;
margin: 0;
}
/* 响应式布局 - 屏幕宽度小于768px时显示2列 */
@media screen and (max-width: 768px) {
.fields-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* 响应式布局 - 屏幕宽度大于等于768px时显示3列 */
@media screen and (min-width: 768px) {
.fields-grid {
grid-template-columns: repeat(3, 1fr);
}
}
/* 优化表单元素样式 */
:deep(.uni-forms-item) {
margin-bottom: 0 !important;
}
:deep(.uni-forms-item__label) {
font-size: 22rpx;
color: #868686;
margin-bottom: 5rpx;
line-height: 1.4;
}
:deep(.uni-data-select__input),
:deep(.uni-easyinput__content) {
width: 100%;
min-height: 70rpx;
box-sizing: border-box;
}
:deep(.uni-input-input),
:deep(.uni-easyinput__content input) {
font-size: 28rpx;
padding: 0 20rpx;
height: 70rpx;
line-height: 70rpx;
}
/* 禁用输入框的特殊样式 */
.total-input :deep(.uni-easyinput__content) {
background-color: #f5f7fa;
border-color: #e4e7ed;
}
.total-input :deep(.uni-input-input) {
background-color: #f5f7fa;
color: #606266;
-webkit-text-fill-color: #606266;
opacity: 1;
}
/* 确保小屏幕下表单不溢出 */
@media screen and (max-width: 480px) {
.form-container {
padding: 10rpx;
}
.component-form {
padding: 16rpx;
margin-bottom: 16rpx;
}
.fields-grid {
gap: 16rpx;
}
:deep(.uni-forms-item__label) {
font-size: 22rpx;
}
:deep(.uni-input-input) {
font-size: 28rpx;
}
}
/* 针对选择器的特殊样式调整 */
:deep(.uni-data-select) {
width: 100%;
}
:deep(.uni-data-select__selector) {
min-height: 70rpx;
border-radius: 8rpx;
}
:deep(.uni-data-select__input-text) {
font-size: 28rpx;
line-height: 70rpx;
padding: 0 20rpx;
}
/* 数字输入框的特殊样式 */
:deep(input[type="digit"]) {
text-align: right;
}
</style>