cellsysArt/components/equData/eqDataForm.vue
ag 8a7ab9c495 1、设备数据图片上传优化
2、材料信息图片上传优化
2025-03-27 11:10:58 +08:00

506 lines
19 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>
<el-container style="background-color: #fff">
<el-main>
<el-form
class="dataForm"
ref="dataForm"
:rules="rules"
:model="form"
label-position="top">
<el-form-item
label="数据名称"
prop="name">
<el-input
v-model="form.name"
:readonly="isReadonly"
placeholder="请输入数据名称" />
</el-form-item>
<el-form-item
label="创建时间"
prop="dateTime">
<el-date-picker
:readonly="isReadonly"
style="width: 100%"
v-model="form.dateTime"
type="datetime"
value-format="x"
:disabled-date="disabledDate"
:default-value="defaultValue"
placeholder="选择上报时间"></el-date-picker>
</el-form-item>
<el-form-item label="标签">
<el-tag
v-for="tag in form.tags"
:key="tag"
:closable="!isReadonly"
:disable-transitions="false">
{{ tag.name }}
</el-tag>
<el-button
v-if="!isReadonly"
class="button-new-tag"
size="small"
@click="handleAddTag">
+ 添加标签
</el-button>
</el-form-item>
<el-form-item
label="图片附件"
prop="data">
<imagesUpload
ref="ImageUpload"
:is-show="isReadonly"
:data="uploadDate"
@handleImageRemove="handleImageRemove"
@uploadSuccess="uploadSuccess"
@uploadChange="uploadChange"
:maxSize="9"
:imageList="uploadOption.imgList"
type="file"></imagesUpload>
</el-form-item>
<el-form-item label="材料选择">
<materialCard
v-model="materialDialogVisible"
:material-id="form.materialId"
:currentMaterial="currentMaterial"
@confirm="selectMaterial"></materialCard>
<el-button
v-if="!isReadonly"
class="button-new-tag"
size="small"
@click="handleAddMaterial">
+ 选择材料
</el-button>
</el-form-item>
<el-form-item
prop="destinationGeometry"
label="填报地址">
<el-input
readonly
@click="openMap"
v-model="geoDialog.currrentAddress"
:suffix-icon="ArrowRight"></el-input>
</el-form-item>
<el-form-item
label="描述"
prop="remarks">
<el-input
:readonly="isReadonly"
:rows="4"
type="textarea"
v-model="form.remarks"></el-input>
</el-form-item>
<el-form-item
v-if="!isReadonly"
label="导入数据"
prop="data">
<el-upload
class="upload-demo"
accept=".txt,.csv"
:auto-upload="false"
:show-file-list="false"
:before-upload="handleBeforeUpload"
:on-change="handleFileChange">
<el-button
type="primary"
plain>
选择txt或csv文件
</el-button>
</el-upload>
<el-button
link
type="primary"
@click="downloadTXT">
下载txt模版
</el-button>
<el-button
link
type="primary"
@click="downloadCSV">
下载csv模版
</el-button>
<p style="width: 100%; color: #999; font-size: 12px">
支持上传txtcsv格式的文件
</p>
</el-form-item>
</el-form>
<div
v-if="form.data && form.data.length > 0"
ref="lineChart"
style="width: 100%; height: 40vh"></div>
</el-main>
<el-footer class="footer-btn">
<el-button @click="close">取消</el-button>
<el-button
type="primary"
:btnloading="btnloading"
@click="save">
完成
</el-button>
</el-footer>
<!--标签选择器-->
<tagSelect
:dialogOption="tagSelect"
:activeTags="form.tags"
:cellsysOrg="cellsysOrg"
:isAdmin="isAdmin"
@handleTagSelect="handleTagSelect"></tagSelect>
<GeocoderComponent
v-model="geoDialog.visible"
:isReadonly="isReadonly"
:isGetCurrentPosition="false"
:currentPosition="geoDialog.currentPosition"
:address="geoDialog.currrentAddress"
@confirm="handleDialogConfirm"
@close="handleDialogCancel"></GeocoderComponent>
</el-container>
</template>
<script>
import ImagesUpload from '../imagesUpload.vue';
import MaterialCard from '../materialCard.vue';
import * as echarts from 'echarts';
import tagSelect from '../tag/tagSelect.vue';
import GeocoderComponent from '../amapSearch.vue';
import ArtSystem from '../../artSystem';
import { ArrowRight } from '@element-plus/icons-vue';
import EquipmentData from '../../equipmentData';
export default {
name: 'EqDataForm',
emits: ['close', 'update'],
components: { GeocoderComponent, tagSelect, MaterialCard, ImagesUpload },
props: {
defaultName: String,
currentEquipment: Object, //cellsysArt的Equipment对象
currentEquData: Object,
mode: 'create', //create和details目前还没有编辑模式
cellsysOrg: Object,
isAdmin: Boolean,
},
computed: {
ArrowRight() {
return ArrowRight;
},
uploadDate() {
return {
module: 'equipment',
};
},
},
data() {
return {
form: new EquipmentData(),
rules: {
dateTime: [{ required: true, message: '请选择时间', trigger: 'blur' }],
},
isReadonly: false,
defaultValue: new Date(),
uploadOption: {
filePath: null,
imgList: [],
},
materialDialogVisible: false,
coordinates: null, //坐标
tagSelect: {
visible: false,
},
equipment: null, //cellsysArt的equipment对象
geoDialog: {
visible: false,
currentPosition: null, //设备当前所在实验室geometry
currrentAddress: '', //上报数据所在地点,默认数据填充实验室名称
},
btnloading: false,
currentMaterial: null,
};
},
created() {
if (this.currentEquipment && this.currentEquipment.id) {
//项目内弹窗通常由props传递设备信息
this.equipment = this.currentEquipment;
this.queryLaboratoryInfo();
if (this.mode === 'details') {
this.form = this.currentEquData;
let { images } = this.form;
//图片填充
this.uploadOption.imgList = images;
//图表数据填充
if (this.form.data && this.form.data.length > 0) {
this.$nextTick(() => {
this.initChart(this.form.data);
});
}
//材料数据填充
this.currentEquData.queryqueryMateria().then((res) => {
if (res && res.length > 0) {
this.currentMaterial = res[0];
console.log(this.currentMaterial);
}
});
} else {
this.form = new EquipmentData();
this.form.dateTime = new Date().getTime();
}
} else {
let routerParams = this.$route.query;
let { id, equipmentId } = routerParams;
if (equipmentId) {
//移动端webview通常用url参数传递id
this.queryEquipment(equipmentId);
}
if (id) {
//从移动端webview的查看详情界面进入逻辑
this.getEquipmentDataDetail(id);
}
}
if (this.defaultName) {
this.form.name = this.defaultName;
}
},
methods: {
//查询设备信息
queryEquipment(equipmentId) {
let filter = [
{
name: 'id',
operator: '=',
value: equipmentId,
},
];
ArtSystem.queryEquipment({
filter,
}).then((equipments) => {
if (equipments && equipments.length > 0) {
this.equipment = equipments[0];
this.queryLaboratoryInfo();
}
});
},
//获取设备数据详细内容
getEquipmentDataDetail(id) {},
//获取设备所在实验室信息
queryLaboratoryInfo() {
//查询当前设备所在实验室,用于填充默认定位数据
this.equipment.queryLaboratory().then((laboratorys) => {
if (laboratorys && laboratorys.length > 0) {
let { name, geometry } = laboratorys[0];
this.geoDialog.currentPosition = geometry;
this.geoDialog.currrentAddress = name;
}
});
},
handleDialogConfirm(coordinates) {
this.form.geometry = { type: 'Point', coordinates: coordinates };
this.coordinates = coordinates;
},
handleDialogCancel() {},
openMap() {
this.geoDialog.visible = true;
},
disabledDate(time) {
return time.getTime() > Date.now();
},
handleAddTag() {
this.tagSelect.visible = true;
},
handleImageRemove(artImages) {
//进行了删除图片的操作
this.form.images = artImages.map((artImage) => {
return artImage['url'];
});
},
//图片上传完成
uploadSuccess(data) {
this.form['images'] = data.map((item) => {
return item['url'];
});
this.handleSubmit();
},
handleTagSelect(tagList) {
this.form.tags = tagList;
},
uploadChange(fileList) {
//图片部分是否发生变化
this.isUploadChange = true;
},
selectMaterial(materialId) {
this.form.materialId = materialId;
},
handleAddMaterial() {
this.materialDialogVisible = true;
},
handleBeforeUpload(file) {
const isTxtOrXlsx = file.type === 'text/plain' || file.type === 'text/csv';
if (!isTxtOrXlsx) {
this.$message.error('只能上传 txt 或 csv 文件!');
return false;
}
return true;
},
handleFileChange(file) {
// 检查文件类型
const fileType = file.name.split('.').pop().toLowerCase();
const reader = new FileReader();
reader.onload = (e) => {
// 读取成功后,设置文件内容
// console.log(e, e.target, e.target.result);
const dataString = e.target.result;
// 使用正则表达式分割字符串,得到每一行的数据
const rows = dataString.split(/\n/);
// 初始化一个空数组来存储二维数组
const twoDimensionalArray = [];
// 遍历每一行数据
rows.forEach((row) => {
// 如果行不是空的,则继续处理
if (row) {
let values;
if (fileType === 'txt') {
// 使用't'分割每一行中的两个数值
values = row.split('\t');
} else {
values = row.split(',');
}
// 将分割后的数值转换为浮点数,并添加到二维数组中
twoDimensionalArray.push(values.map(Number));
}
});
this.form.data = twoDimensionalArray;
this.$nextTick(() => {
this.initChart(twoDimensionalArray);
});
// 输出二维数组
// console.log(twoDimensionalArray);
};
reader.onerror = () => {
this.$message.error('文件读取失败');
};
reader.readAsText(file.raw); // 读取文件内容
},
downloadTXT() {
const content =
'185.551\t16.00\r\n185.939\t16.00\r\n186.327\t16.00\r\n193.318\t16.21\r\n201.097\t15.34\r\n1024.282\t16.31\r'; // 定义模板内容
const blob = new Blob([content], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
// 创建一个a元素用于下载
const link = document.createElement('a');
link.href = url;
link.download = 'txt模板.txt'; // 指定下载文件名
document.body.appendChild(link);
link.click();
// 清理和释放URL对象
document.body.removeChild(link);
URL.revokeObjectURL(url);
},
downloadCSV() {
const content =
'185.551,16.00\r\n185.939,16.00\r\n186.327,16.00\r\n192.318,16.21\r\n201.097,15.34\r\n1024.282,16.31\r'; // CSV内容字段以逗号分隔记录以回车换行分隔
const blob = new Blob([content], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'csv_template.csv'; // 指定下载文件名,使用.csv扩展名
document.body.appendChild(link);
link.click();
// 清理和释放URL对象
document.body.removeChild(link);
URL.revokeObjectURL(url);
},
initChart(data) {
const chart = echarts.init(this.$refs.lineChart);
const option = {
tooltip: {
trigger: 'axis',
formatter: function (params) {
// params 是一个包含当前数据点信息的数组
// 对于 line 图表,通常 params[0] 就是我们需要的信息
return `X:${params[0].value[0]}, Y: ${params[0].value[1]}`;
},
},
xAxis: {
type: 'value',
},
yAxis: {
type: 'value',
},
series: [
{
data: data,
type: 'line',
showSymbol: false,
},
],
};
if (this.equipment.chartConfiguration) {
let chartConfiguration = this.equipment.chartConfiguration;
option.xAxis.name =
chartConfiguration.xAxis.key + '(' + chartConfiguration.xAxis.unit + ')';
option.xAxis.nameLocation = 'end';
option.yAxis.name =
chartConfiguration.yAxis.key + '(' + chartConfiguration.yAxis.unit + ')';
option.yAxis.nameLocation = 'end';
}
chart.setOption(option);
},
close() {
this.materialDialogVisible = false;
this.$emit('close');
},
save() {
this.form.geometry = this.geoDialog.currentPosition;
this.btnloading = true;
//有图片先上传图,没有则直接提交
if (this.isUploadChange) {
this.$refs.ImageUpload.submitUpload();
} else {
this.handleSubmit();
}
},
handleSubmit() {
let newEqData;
this.equipment
.createEquipmentData(this.form)
.then((res) => {
// console.log(res);
newEqData = res;
if (this.form.tags) {
return this.updateTagRel(res.id);
}
})
.then(() => {
this.$message.success('数据填报成功');
this.$emit('update', newEqData);
//todo 操作成功后给移动端的反馈
})
.catch((error) => {
console.error(error);
this.$message.error(error.message);
})
.finally(() => {
this.btnloading = false;
});
},
updateTagRel(id) {
return this.cellsysOrg.updateTagRel({
tags: this.form.tags,
modelCode: 'artworkEquipmentData',
modelObjectId: id,
});
},
},
};
</script>
<style scoped>
.footer-btn {
display: flex;
align-items: center;
justify-content: flex-end;
}
</style>