Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 已存在的决策表导出后无法导入问题修复 #59 #60

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions frontend/src/components/DecisionTable/ImportExport/ExportBtn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,25 @@
// 暂时过滤【条件组合】类型!!!
if (cur.inputs.type !== 'common') return acc;
const arr = [];
cur.inputs.conditions.forEach((item) => {
arr.push({ v: getCellText(item), t: 's', s: cellStyles });
cur.inputs.conditions.forEach((item, index) => {
const inputInfo = inputs[index];
const v = getCellText(item);
if (inputInfo.type === 'select') {
// 下拉框类型导出为text
const option = inputInfo.options.items.find(o => o.id === v);
arr.push({ v: option.name, t: 's', s: cellStyles });
} else {
arr.push({ v, t: 's', s: cellStyles });
}
});
outputs.forEach((item) => {
arr.push({ v: cur.outputs[item.id], t: 's', s: cellStyles });
if (item.type === 'select') {
// 下拉框类型导出为text
const option = item.options.items.find(o => o.id === cur.outputs[item.id]);
arr.push({ v: option.name, t: 's', s: cellStyles });
} else {
arr.push({ v: cur.outputs[item.id], t: 's', s: cellStyles });
}
});
acc.push(arr);
return acc;
Expand Down Expand Up @@ -112,8 +126,9 @@
fill: { fgColor: { rgb: '9FE3FF' } },
},
});
const c = headerIndex === 0 ? childIndex : (headers[headerIndex - 1].children.length + childIndex);
comments.push({
cell: XLSX.utils.encode_cell({ c: headerIndex * header.children.length + childIndex, r: 1 }),
cell: XLSX.utils.encode_cell({ c, r: 1 }),
comment: child.description,
});
});
Expand Down
12 changes: 4 additions & 8 deletions frontend/src/components/DecisionTable/ImportExport/ImportBtn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<script>
import * as XLSX from 'xlsx';
import tools from '@/utils/tools.js';
import { validateFiled, parseValue, validateValue, getValueRight } from './dataTransfer.js';
import { validateFiled, parseValue, getValueRight } from './dataTransfer.js';
export default {
props: {
data: {
Expand Down Expand Up @@ -71,7 +71,6 @@
const inputs = [];
const outputs = [];
const records = [];
console.log(jsonData, sheetValue);
const result = jsonData.some((row, rIndex) => {
// 类型
if (rIndex === 0) return false;
Expand Down Expand Up @@ -154,19 +153,16 @@
const outputs = {};

const result = header.every((col, colIndex) => {
// 解析value和操作方式
const { value, type } = parseValue(row[colIndex]);

// 校验value
const message = validateValue(value, col);
// 解析并校验value和操作方式
const { value, type, message } = parseValue(row[colIndex], col);
if (message) {
this.showMessage(message);
return false;
}

// 生成record
if (col.from === 'outputs') {
outputs[col.id] = value.trim();
outputs[col.id] = value;
}
if (col.from === 'inputs') {
inputs.conditions.push({
Expand Down
99 changes: 61 additions & 38 deletions frontend/src/components/DecisionTable/ImportExport/dataTransfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const getCellText = (data = {}) => {
const { type, value } = right.obj;
// 非范围条件
if (compare in operateMap) {
return `${operateMap[compare]} ${value}`;
return compare === 'equals' ? value : `${operateMap[compare]} ${value}`;
}
// 范围条件
const isIntRange = type === 'int[Range]';
Expand Down Expand Up @@ -82,10 +82,22 @@ export const validateFiled = (data = []) => {
let isOptionsValid = Object.prototype.toString.call(options) === '[object Object]';
isOptionsValid = isOptionsValid && (Array.isArray(options.items) && options.type === 'custom');
isOptionsValid = isOptionsValid && options.items.every(item => (item.id && item.name));
if (!isOptionsValid) {
message = `【${field.name}】列注释配置中options结构不对`;
return false;
if (isOptionsValid) {
const names = new Set();
const ids = new Set();
const isUnique = options.items.every((item) => {
if (names.has(item.name) || ids.has(item.id)) {
return false;
}
names.add(item.name);
ids.add(item.id);
return true;
});
message = isUnique ? '' : `【${field.name}】列注释配置中option的id和name不唯一`;
return isUnique;
}
message = `【${field.name}】列注释配置中options结构不对`;
return false;
}

return true;
Expand All @@ -94,53 +106,64 @@ export const validateFiled = (data = []) => {
return message;
};

export const parseValue = (data = '') => {
export const parseValue = (data = '', config) => {
// 解析出表格实际值,类型
let value = String(data).trim();
let type = 'equals';
let message = '';

Object.keys(operateMap).forEach((key) => {
const text = operateMap[key];
if (text) {
const regex = new RegExp(`^${text}`);
if (regex.test(value)) {
[, value] = value.split(text);
type = key;
}
return;
}
// 数字
value = intRegex.test(value) ? Number(value) : value;
// 范围条件
if (value && /^(!)?\[.*\]$/.test(value)) {
const [v1, v2] = value.match(/^(!)?\[.*\]$/);
value = v1.slice(v2 ? 2 : 1, -1).split(',')
.map(item => intRegex.test(item) ? Number(item) : item.trim());
type = `${v2 ? 'not-' : ''}in-range`;
// 检查是否有操作符匹配
for (const [key, text] of Object.entries(operateMap)) {
if (text && new RegExp(`^${text}`).test(value)) {
[, value] = value.split(text);
value = value.trim();
type = key;
break;
}
});
}

return { value, type };
};
// 定义一个函数来验证整数
const validateInt = (val) => {
if (!intRegex.test(val)) {
message = `【${config.name}】列存在非数字类型`;
return '';
}
return Number(val);
};

export const validateValue = (value, config) => {
let message = '';
// 处理范围条件(只有数字和下拉框类型有范围条件)
if (!operateMap[type] && value && /^(!)?\[.*\]$/.test(value)) {
const [v1, v2] = value.match(/^(!)?\[.*\]$/);
value = v1.slice(v2 ? 2 : 1, -1).split(',')
.map((item) => {
if (config.type === 'int') {
return validateInt(item);
}
const option = config.options.items.find(option => option.name === item.trim());
if (!option) {
message = `【${config.name}】列存在所填选项不存在`;
return '';
}
return option.id;
});
type = `${v2 ? 'not-' : ''}in-range`;
return { value, type, message };
}

// 判断数据类型是否合规
// 处理等于和其他条件
if (config.type === 'int') {
const isMatch = Array.isArray(value) ? value.every(item => intRegex.test(item)) : intRegex.test(value);
if (!isMatch) {
message = `【${config.name}】列存在非数字类型`;
}
} else if (config.type === 'select' && value) {
const ids = Array.isArray(value) ? value : [value];
const isMatch = ids.every(id => config.options.items.some(item => item.id === id));
if (!isMatch) {
value = validateInt(value);
} else if (config.type === 'select') {
const option = config.options.items.find(option => option.name === value);
if (!option) {
message = `【${config.name}】列存在所填选项不存在`;
value = '';
} else {
value = option.id;
}
}

return message;
return { value, type, message };
};

export const getValueRight = (value, type, config) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@
message: this.$t('必填项不能为空'),
trigger: 'blur',
},
{
validator: this.checkOption,
message: this.$t('id或name不唯一'),
trigger: 'blur',
},
],
},
};
Expand All @@ -190,6 +195,20 @@
}, []);
return !keys.includes(val);
},
// 校验option是否存在相同id和name
checkOption(val) {
if (!val) return false;
const names = new Set();
const ids = new Set();
return val.items.every((item) => {
if (names.has(item.name) || ids.has(item.id)) {
return false;
}
names.add(item.name);
ids.add(item.id);
return true;
});
},
updateOptions(options) {
this.formData.options = options;
// 单独校验
Expand Down
1 change: 1 addition & 0 deletions frontend/src/config/i18n/cn.js
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,7 @@ const cn = {
当前调试任务: '当前调试任务',
待复用调试任务: '待复用调试任务',
复用成功: '复用成功',
id或name不唯一: 'id或name不唯一',
};

export default cn;
1 change: 1 addition & 0 deletions frontend/src/config/i18n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,7 @@ const en = {
当前调试任务: 'Current Debug Task',
待复用调试任务: 'Pending Reuse Debug Task',
复用成功: 'Reuse success',
id或name不唯一: 'ID or name is not unique',
};

export default en;
Loading