|
@@ -72,11 +72,20 @@
|
|
style="width: 200px"
|
|
style="width: 200px"
|
|
disabled
|
|
disabled
|
|
/>
|
|
/>
|
|
|
|
+<!-- <el-input
|
|
|
|
+ v-else
|
|
|
|
+ v-model="item.fillContent"
|
|
|
|
+ clearable
|
|
|
|
+ style="width: 200px"
|
|
|
|
+ />-->
|
|
<el-input
|
|
<el-input
|
|
v-else
|
|
v-else
|
|
v-model="item.fillContent"
|
|
v-model="item.fillContent"
|
|
clearable
|
|
clearable
|
|
style="width: 200px"
|
|
style="width: 200px"
|
|
|
|
+ :placeholder="item.type === 'double' ? t('operationFillForm.enterNumber') : t('operationFillForm.enterContent')"
|
|
|
|
+ @input="handleInput(item)"
|
|
|
|
+ :maxlength="item.type === 'double' ? calculateMaxLength(item) : undefined"
|
|
/>
|
|
/>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</div>
|
|
</div>
|
|
@@ -103,6 +112,8 @@ import { ElMessage } from 'element-plus'
|
|
import moment from 'moment';
|
|
import moment from 'moment';
|
|
import { format } from 'date-fns';
|
|
import { format } from 'date-fns';
|
|
import {cx} from "@fullcalendar/core/internal-common";
|
|
import {cx} from "@fullcalendar/core/internal-common";
|
|
|
|
+
|
|
|
|
+
|
|
/** 运行记录填报 列表 */
|
|
/** 运行记录填报 列表 */
|
|
defineOptions({ name: 'FillOrderInfo' })
|
|
defineOptions({ name: 'FillOrderInfo' })
|
|
|
|
|
|
@@ -141,7 +152,10 @@ const queryParams = reactive({
|
|
creDate: [],
|
|
creDate: [],
|
|
createTime: [],
|
|
createTime: [],
|
|
deviceCategoryId:1,
|
|
deviceCategoryId:1,
|
|
- deviceId:undefined
|
|
|
|
|
|
+ deviceId:undefined,
|
|
|
|
+ threshold:undefined,
|
|
|
|
+ defaultValue:undefined,
|
|
|
|
+ isSum:undefined,
|
|
})
|
|
})
|
|
const queryFormRef = ref() // 搜索的表单
|
|
const queryFormRef = ref() // 搜索的表单
|
|
const exportLoading = ref(false) // 导出的加载中
|
|
const exportLoading = ref(false) // 导出的加载中
|
|
@@ -151,7 +165,69 @@ const formatDescription = async(row, column, cellValue) =>{
|
|
return cellValue.split(',').map(part => `<div>${part}</div>`).join('');
|
|
return cellValue.split(',').map(part => `<div>${part}</div>`).join('');
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 计算数字输入的最大长度(根据阈值动态计算)
|
|
|
|
+const calculateMaxLength = (item: any) => {
|
|
|
|
+ if (item.type !== 'double' || !item.threshold) return undefined;
|
|
|
|
+
|
|
|
|
+ const max = parseFloat(item.threshold);
|
|
|
|
+ if (isNaN(max)) return undefined;
|
|
|
|
|
|
|
|
+ // 整数部分长度 + 可能的小数点 + 两位小数
|
|
|
|
+ return max.toString().length + (max.toString().includes('.') ? 0 : 3);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+// 处理输入事件,实时限制输入格式和最大值
|
|
|
|
+const handleInput = (item: any) => {
|
|
|
|
+ if (item.type === 'double') {
|
|
|
|
+ // 保存原始值用于后续比较
|
|
|
|
+ const originalValue = item.fillContent;
|
|
|
|
+
|
|
|
|
+ // 1. 格式验证:只允许数字和小数点
|
|
|
|
+ item.fillContent = item.fillContent.replace(/[^\d.]/g, '');
|
|
|
|
+ // 确保只有一个小数点
|
|
|
|
+ item.fillContent = item.fillContent.replace(/\.{2,}/g, '.');
|
|
|
|
+ // 确保小数点不在开头
|
|
|
|
+ item.fillContent = item.fillContent.replace(/^\./g, '');
|
|
|
|
+ // 限制小数位数为两位
|
|
|
|
+ item.fillContent = item.fillContent.replace(/(\d+)\.(\d{2}).*/, '$1.$2');
|
|
|
|
+
|
|
|
|
+ // 2. 最大值验证
|
|
|
|
+ if (item.threshold) {
|
|
|
|
+ const value = parseFloat(item.fillContent);
|
|
|
|
+ const max = parseFloat(item.threshold);
|
|
|
|
+
|
|
|
|
+ if (!isNaN(value) && !isNaN(max) && value > max) {
|
|
|
|
+ // 输入值超过阈值时,恢复到修改前的值
|
|
|
|
+ item.fillContent = originalValue.replace(/[^\d.]/g, '')
|
|
|
|
+ .replace(/\.{2,}/g, '.')
|
|
|
|
+ .replace(/^\./g, '')
|
|
|
|
+ .replace(/(\d+)\.(\d{2}).*/, '$1.$2');
|
|
|
|
+
|
|
|
|
+ // 如果修正后的值仍然超过阈值,则设置为最大值
|
|
|
|
+ if (parseFloat(item.fillContent) > max) {
|
|
|
|
+ item.fillContent = max.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 显示提示信息(使用节流避免频繁提示)
|
|
|
|
+ throttle(() => {
|
|
|
|
+ ElMessage.warning(t('operationFillForm.exceedMax', { max }));
|
|
|
|
+ }, 1000)();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+// 简单的节流函数,避免提示信息过于频繁
|
|
|
|
+const throttle = (fn: Function, delay: number) => {
|
|
|
|
+ let lastTime = 0;
|
|
|
|
+ return function(...args: any[]) {
|
|
|
|
+ const now = Date.now();
|
|
|
|
+ if (now - lastTime >= delay) {
|
|
|
|
+ fn.apply(this, args);
|
|
|
|
+ lastTime = now;
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+};
|
|
|
|
|
|
const showComponent = () => {
|
|
const showComponent = () => {
|
|
if(JSON.parse(fillStatus)=== 1){
|
|
if(JSON.parse(fillStatus)=== 1){
|
|
@@ -226,6 +302,7 @@ const getAttrList = async () => {
|
|
try {
|
|
try {
|
|
queryParams.createTime = formatTimestamp(JSON.parse(deptId.split(",")[2].substring(0,10)));
|
|
queryParams.createTime = formatTimestamp(JSON.parse(deptId.split(",")[2].substring(0,10)));
|
|
const data = await IotOpeationFillApi.getAttrs(queryParams)
|
|
const data = await IotOpeationFillApi.getAttrs(queryParams)
|
|
|
|
+
|
|
attrList.value = data[0].nonSumList;
|
|
attrList.value = data[0].nonSumList;
|
|
attrList1.value = data[0].sumList;
|
|
attrList1.value = data[0].sumList;
|
|
attrList.value.forEach(function (item,index){
|
|
attrList.value.forEach(function (item,index){
|
|
@@ -237,12 +314,15 @@ const getAttrList = async () => {
|
|
item.deptId = queryParams.deptId;
|
|
item.deptId = queryParams.deptId;
|
|
item.deviceId = queryParams.deviceId;
|
|
item.deviceId = queryParams.deviceId;
|
|
item.deviceCategoryId = queryParams.deviceCategoryId;
|
|
item.deviceCategoryId = queryParams.deviceCategoryId;
|
|
|
|
+ item.modelId = item.id;
|
|
})
|
|
})
|
|
|
|
+ console.log(JSON.stringify(attrList.value))
|
|
attrList1.value.forEach(function (item,index){
|
|
attrList1.value.forEach(function (item,index){
|
|
item.deviceCode = queryParams.deviceCode;
|
|
item.deviceCode = queryParams.deviceCode;
|
|
item.deptId = queryParams.deptId;
|
|
item.deptId = queryParams.deptId;
|
|
item.deviceId = queryParams.deviceId;
|
|
item.deviceId = queryParams.deviceId;
|
|
item.deviceCategoryId = queryParams.deviceCategoryId;
|
|
item.deviceCategoryId = queryParams.deviceCategoryId;
|
|
|
|
+ item.modelId = item.id;
|
|
})
|
|
})
|
|
} finally {
|
|
} finally {
|
|
loading.value = false
|
|
loading.value = false
|