new-ruoyi-geek/ruoyi-geek-app/pages_caltools/components/NGCom.vue

344 lines
6.3 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="app-container">
<uni-forms label-position="top" :modelValue="formData" class="component-form">
<view class="form-row">
<!-- 常用组分选择框 -->
<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">
<view class="fields-grid">
<uni-forms-item v-for="field in componentFields" :key="field.prop" :label="field.label"
:name="field.prop" class="field-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>
.app-container {
padding: 20rpx;
}
.component-form {
margin-bottom: 30rpx;
}
.form-row {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
align-items: flex-end;
}
.form-item {
flex: 1;
min-width: 300rpx;
}
.fields-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300rpx, 1fr));
gap: 20rpx;
}
.field-item {
margin-bottom: 0;
}
.total-input {
font-weight: bold;
color: #007AFF;
}
/* 调整uni-ui组件样式 */
:deep(.uni-forms-item__label) {
font-size: 28rpx;
color: #666;
margin-bottom: 10rpx;
}
:deep(.uni-input-input) {
font-size: 28rpx;
}
:deep(.uni-easyinput__content) {
border-radius: 8rpx;
}
:deep(.total-input .uni-input-input) {
font-weight: bold;
color: #007AFF;
}
@media (max-width: 750px) {
.fields-grid {
grid-template-columns: repeat(2, 1fr);
gap: 15rpx;
}
.form-item {
min-width: 250rpx;
}
}
</style>