ruoyi-ui/src/components/NGTools/NGCom.vue

270 lines
6.0 KiB
Vue

<template>
<div class="app-container">
<el-form label-position="top" size="small" :inline="true" class="component-form">
<!-- <el-row> -->
<!-- 常用组分选择框 -->
<!-- <el-col :span="10"> -->
<el-form-item label="常用组分" :style="{ width: selectWidth + 'px' }">
<el-select v-model="selectedComponent" @change="handleComponentChange" placeholder="请选择常用组分" clearable filterable>
<el-option v-for="dict in dict.type.ngtools_cyzf" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<!-- </el-col> -->
<!-- 合计输入框 -->
<!-- <el-col :span="6"> -->
<el-form-item label="合计" :style="{ width: selectWidth + 'px' }">
<el-input :value="totalPercentage" readonly class="total-input" />
</el-form-item>
<!-- </el-col> -->
<!-- </el-row> -->
</el-form>
<el-form :model="formData" label-position="top" size="small" :inline="true" class="component-form">
<el-form-item v-for="field in componentFields" :key="field.prop" :label="field.label" :prop="field.prop" :style="{ width: selectWidth + 'px' }">
<el-input v-model="formData[field.prop]" controls-position="right" @change="handleValueChange" @focus="selectAllText" />
</el-form-item>
</el-form>
</div>
</template>
<script>
import { listComponents, getComponents, delComponents, addComponents, updateComponents } from '@/api/ngtools/components';
// 字段配置元数据
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'
}
];
export default {
name: 'NgComponentsForm',
props: {
value: {
type: String,
default: ''
},
elFormWidth: {
type: Number,
default: 180
}
},
dicts: ['ngtools_cyzf'],
data() {
return {
selectWidth: 0,
selectedComponent: null,
formData: this.initFormData(),
componentFields: COMPONENT_FIELDS
};
},
computed: {
totalPercentage() {
return Object.values(this.formData)
.reduce((sum, val) => sum + (parseFloat(val) || 0), 0)
.toFixed(4);
}
},
watch: {
elFormWidth: {
deep: true,
handler(newVal) {
this.selectWidth = newVal;
}
},
value: {
immediate: true,
handler(newVal) {
this.parseValueString(newVal);
}
}
},
mounted() {
this.selectWidth = this.elFormWidth;
},
methods: {
initFormData() {
return COMPONENT_FIELDS.reduce((acc, field) => {
acc[field.prop] = 0;
return acc;
}, {});
},
selectAllText(event) {
// 通过 event.target 获取原生 DOM 元素
const inputElement = event.target;
// 调用 select() 方法全选文本
inputElement.select();
},
parseValueString(valueStr) {
const values = (valueStr || '').split('_');
this.componentFields.forEach((field, index) => {
const value = parseFloat(values[index]) || 0;
this.$set(this.formData, field.prop, value);
});
},
generateValueString() {
return Object.values(this.formData)
.map((v) => v.toFixed(4))
.join('_');
},
async handleComponentChange(value) {
if (!value) return;
console.log(value);
try {
const temp = value.replace(/\\'"/g, '"').replace(/'/g, '"'); // 替换剩余单引号;
const componentData = Object.assign({}, this.formData, JSON.parse(temp));
Object.keys(this.formData).forEach((key) => {
this.formData[key] = parseFloat(componentData[key]) || 0;
});
this.emitUpdate();
} catch (error) {
this.$message.error('获取标准组分失败');
console.error(error);
}
},
handleValueChange() {
this.$nextTick(() => {
this.emitUpdate();
});
},
emitUpdate() {
if (Math.abs(this.totalPercentage - 100) > 0.0001) {
this.$message.warning('组分合计不等于100%,请检查输入');
}
this.$emit('input', this.generateValueString());
},
async fetchComponentData(params) {
try {
const { data } = await getComponents(params);
this.parseValueString(data.componentStr);
} catch (error) {
console.error('获取组分数据失败:', error);
}
}
}
};
</script>
<style scoped>
.component-form {
display: grid;
/* 优化后的自适应规则 */
grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
gap: 10px;
/* 移动端优化补充 */
@media (max-width: 768px) {
/* 手机端强制单列布局 */
grid-template-columns: 1fr;
/* 防止内容溢出 */
overflow-x: hidden;
/* 移动端缩小间距 */
gap: 5px;
/* 表单项最小高度保障 */
grid-auto-rows: minmax(40px, auto);
}
/* 子元素弹性处理 */
> * {
min-width: 0; /* 允许内容收缩 */
overflow: hidden;
text-overflow: ellipsis;
}
}
.total-input >>> .el-input__inner {
font-weight: bold;
color: #409eff;
}
</style>