344 lines
6.3 KiB
Vue
344 lines
6.3 KiB
Vue
<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> |