ruoyi-geek-App/pages_caltools/components/NGCom.vue

405 lines
7.6 KiB
Vue
Raw Normal View History

2025-11-24 14:57:53 +00:00
<template>
2025-11-25 06:26:23 +00:00
<view class="form-container">
2025-11-24 14:57:53 +00:00
<uni-forms label-position="top" :modelValue="formData" class="component-form">
2025-11-25 06:26:23 +00:00
<view class="fields-grid">
2025-11-24 14:57:53 +00:00
<!-- 常用组分选择框 -->
<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>
2025-11-25 06:26:23 +00:00
<uni-forms :modelValue="formData" label-position="top" class="component-form" :label-width="160">
2025-11-24 14:57:53 +00:00
<view class="fields-grid">
<uni-forms-item v-for="field in componentFields" :key="field.prop" :label="field.label"
2025-11-25 06:26:23 +00:00
:name="field.prop" class="form-item">
2025-11-24 14:57:53 +00:00
<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
}))
})
2025-11-25 06:26:23 +00:00
2025-11-24 14:57:53 +00:00
// 字段配置元数据
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) {
2025-11-25 06:26:23 +00:00
node.setSelectionRange(0, node.value.length);
2025-11-24 14:57:53 +00:00
}
}).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({
2025-11-25 06:26:23 +00:00
title: '获取标准组分失败',
2025-11-24 14:57:53 +00:00
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>
2025-11-25 06:26:23 +00:00
.form-container {
padding: 10rpx;
box-sizing: border-box;
width: 100%;
2025-11-24 14:57:53 +00:00
}
.component-form {
2025-11-25 06:26:23 +00:00
background-color: #ffffff;
border-radius: 12rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
2025-11-24 14:57:53 +00:00
}
2025-11-25 06:26:23 +00:00
/* 网格布局容器 */
.fields-grid {
display: grid;
gap: 24rpx;
/* 表单项之间的间距 */
width: 100%;
2025-11-24 14:57:53 +00:00
}
2025-11-25 06:26:23 +00:00
/* 表单项基础样式 */
2025-11-24 14:57:53 +00:00
.form-item {
2025-11-25 06:26:23 +00:00
width: 100%;
margin: 0;
2025-11-24 14:57:53 +00:00
}
2025-11-25 06:26:23 +00:00
/* 响应式布局 - 屏幕宽度小于768px时显示2列 */
@media screen and (max-width: 768px) {
.fields-grid {
grid-template-columns: repeat(2, 1fr);
}
2025-11-24 14:57:53 +00:00
}
2025-11-25 06:26:23 +00:00
/* 响应式布局 - 屏幕宽度大于等于768px时显示3列 */
@media screen and (min-width: 768px) {
.fields-grid {
grid-template-columns: repeat(3, 1fr);
}
2025-11-24 14:57:53 +00:00
}
2025-11-25 06:26:23 +00:00
/* 优化表单元素样式 */
:deep(.uni-forms-item) {
margin-bottom: 0 !important;
2025-11-24 14:57:53 +00:00
}
:deep(.uni-forms-item__label) {
2025-11-25 06:26:23 +00:00
font-size: 22rpx;
color: #868686;
margin-bottom: 5rpx;
line-height: 1.4;
2025-11-24 14:57:53 +00:00
}
2025-11-25 06:26:23 +00:00
: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) {
2025-11-24 14:57:53 +00:00
font-size: 28rpx;
2025-11-25 06:26:23 +00:00
padding: 0 20rpx;
height: 70rpx;
line-height: 70rpx;
2025-11-24 14:57:53 +00:00
}
2025-11-25 06:26:23 +00:00
/* 禁用输入框的特殊样式 */
.total-input :deep(.uni-easyinput__content) {
background-color: #f5f7fa;
border-color: #e4e7ed;
2025-11-24 14:57:53 +00:00
}
2025-11-25 06:26:23 +00:00
.total-input :deep(.uni-input-input) {
background-color: #f5f7fa;
color: #606266;
-webkit-text-fill-color: #606266;
opacity: 1;
2025-11-24 14:57:53 +00:00
}
2025-11-25 06:26:23 +00:00
/* 确保小屏幕下表单不溢出 */
@media screen and (max-width: 480px) {
.form-container {
padding: 10rpx;
}
.component-form {
padding: 16rpx;
margin-bottom: 16rpx;
}
2025-11-24 14:57:53 +00:00
.fields-grid {
2025-11-25 06:26:23 +00:00
gap: 16rpx;
}
:deep(.uni-forms-item__label) {
font-size: 22rpx;
2025-11-24 14:57:53 +00:00
}
2025-11-25 06:26:23 +00:00
:deep(.uni-input-input) {
font-size: 28rpx;
2025-11-24 14:57:53 +00:00
}
}
2025-11-25 06:26:23 +00:00
/* 针对选择器的特殊样式调整 */
: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;
}
2025-11-24 14:57:53 +00:00
</style>