等距复制
This commit is contained in:
parent
709df94ff3
commit
b26c03ba25
@ -3,7 +3,7 @@
|
||||
<Dialog
|
||||
v-model="dialogFormVisible"
|
||||
title="批量复制"
|
||||
width="500"
|
||||
width="600"
|
||||
class="batch-copying-dialog-form"
|
||||
@close="dialogClose"
|
||||
>
|
||||
@ -30,18 +30,53 @@
|
||||
precision="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- 常用方向快捷按钮 -->
|
||||
<el-form-item label="常用方向">
|
||||
<div class="quick-angles">
|
||||
<el-button
|
||||
size="small"
|
||||
@click="setQuickAngle(0)"
|
||||
:type="batchCopyingForm.radian === 0 ? 'primary' : 'default'"
|
||||
>向右 (0)</el-button
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
@click="setQuickAngle(Math.PI / 2)"
|
||||
:type="batchCopyingForm.radian === Math.PI / 2 ? 'primary' : 'default'"
|
||||
>向上 (π/2)</el-button
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
@click="setQuickAngle(Math.PI)"
|
||||
:type="batchCopyingForm.radian === Math.PI ? 'primary' : 'default'"
|
||||
>向左 (π)</el-button
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
@click="setQuickAngle(-Math.PI / 2)"
|
||||
:type="batchCopyingForm.radian === -Math.PI / 2 ? 'primary' : 'default'"
|
||||
>向下 (-π/2)</el-button
|
||||
>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<div class="tips">
|
||||
<div class="mb-1">
|
||||
<el-text>向上:弧度 1.57079</el-text>
|
||||
<div class="tips-title">
|
||||
<el-icon><InfoFilled /></el-icon>
|
||||
<span>角度说明</span>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<el-text>向左:弧度 3.141592</el-text>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<el-text>向下:弧度 -1.57079</el-text>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<el-text>向右:弧度 0</el-text>
|
||||
<div class="tips-content">
|
||||
<div class="tip-item">
|
||||
<el-text>向上:弧度 1.57079 (90°)</el-text>
|
||||
</div>
|
||||
<div class="tip-item">
|
||||
<el-text>向左:弧度 3.141592 (180°)</el-text>
|
||||
</div>
|
||||
<div class="tip-item">
|
||||
<el-text>向下:弧度 -1.57079 (-90°)</el-text>
|
||||
</div>
|
||||
<div class="tip-item">
|
||||
<el-text>向右:弧度 0 (0°)</el-text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
@ -130,6 +165,11 @@ const submitLineLibraryForm = async () => {
|
||||
|
||||
const safeNumber = (value) => Number(value || 0)
|
||||
|
||||
// 常用方向快捷设置
|
||||
const setQuickAngle = (angle) => {
|
||||
batchCopyingForm.value.radian = angle
|
||||
}
|
||||
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
</script>
|
||||
|
||||
@ -142,8 +182,56 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
.quick-angles {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.el-button {
|
||||
min-width: 80px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
user-select: text;
|
||||
padding-left: 110px;
|
||||
margin-top: 16px;
|
||||
|
||||
.tips-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-bottom: 8px;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
|
||||
.el-icon {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.tips-content {
|
||||
background: #f0f9ff;
|
||||
border: 1px solid #b3d8ff;
|
||||
border-radius: 4px;
|
||||
padding: 8px 12px;
|
||||
|
||||
.tip-item {
|
||||
margin-bottom: 6px;
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.el-text {
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<Dialog
|
||||
v-model="dialogFormVisible"
|
||||
title="等距复制"
|
||||
width="540"
|
||||
width="600"
|
||||
class="isometric-replication-dialog"
|
||||
@close="dialogClose"
|
||||
>
|
||||
@ -13,40 +13,99 @@
|
||||
v-model="form.distance"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入"
|
||||
placeholder="请输入间隔距离"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="复制数量" prop="number" required>
|
||||
<el-input-number
|
||||
v-model="form.number"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入"
|
||||
:min="1"
|
||||
:max="50"
|
||||
:precision="0"
|
||||
placeholder="请输入复制数量"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="复制角度" prop="angle" required>
|
||||
<el-form-item label="复制弧度" prop="angle" required>
|
||||
<el-input-number
|
||||
v-model="form.angle"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入"
|
||||
:min="-Math.PI"
|
||||
:max="Math.PI"
|
||||
:precision="4"
|
||||
placeholder="请输入弧度"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 常用角度快捷按钮 -->
|
||||
<el-form-item label="常用方向">
|
||||
<div class="quick-angles">
|
||||
<el-button
|
||||
size="small"
|
||||
@click="setQuickAngle(0)"
|
||||
:type="form.angle === 0 ? 'primary' : 'default'"
|
||||
>
|
||||
向右 (0)
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
@click="setQuickAngle(Math.PI / 2)"
|
||||
:type="form.angle === Math.PI / 2 ? 'primary' : 'default'"
|
||||
>
|
||||
向上 (π/2)
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
@click="setQuickAngle(Math.PI)"
|
||||
:type="form.angle === Math.PI ? 'primary' : 'default'"
|
||||
>
|
||||
向左 (π)
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
@click="setQuickAngle(-Math.PI / 2)"
|
||||
:type="form.angle === -Math.PI / 2 ? 'primary' : 'default'"
|
||||
>
|
||||
向下 (-π/2)
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<div class="tips">
|
||||
<div class="tips-title">
|
||||
<el-icon><InfoFilled /></el-icon>
|
||||
<span>角度说明</span>
|
||||
</div>
|
||||
<div class="tips-content">
|
||||
<div class="tip-item">
|
||||
<el-text>向上:弧度 1.57079 (90°)</el-text>
|
||||
</div>
|
||||
<div class="tip-item">
|
||||
<el-text>向左:弧度 3.141592 (180°)</el-text>
|
||||
</div>
|
||||
<div class="tip-item">
|
||||
<el-text>向下:弧度 -1.57079 (-90°)</el-text>
|
||||
</div>
|
||||
<div class="tip-item">
|
||||
<el-text>向右:弧度 0 (0°)</el-text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm(ruleFormRef)"> 确定 </el-button>
|
||||
<el-button type="primary" @click="submitForm(ruleFormRef)" :loading="submitting">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { reactive, ref, nextTick } from 'vue'
|
||||
import * as MapApi from '@/api/map/map'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
|
||||
@ -54,27 +113,51 @@ const message = useMessage() // 消息弹窗
|
||||
|
||||
const ruleFormRef = ref()
|
||||
const dialogFormVisible = ref(false) //列表的
|
||||
const submitting = ref(false) // 提交状态
|
||||
|
||||
const props = defineProps({
|
||||
imgBgObj: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
})
|
||||
|
||||
const rules = reactive({
|
||||
distance: [{ required: true, message: '请输入间隔距离', trigger: 'blur' }],
|
||||
number: [{ required: true, message: '请输入复制数量', trigger: 'blur' }],
|
||||
angle: [{ required: true, message: '请输入复制角度', trigger: 'blur' }]
|
||||
distance: [
|
||||
{ required: true, message: '请输入间隔距离', trigger: 'blur' },
|
||||
{ type: 'number', min: 0.01, message: '间隔距离必须大于0', trigger: 'blur' }
|
||||
],
|
||||
number: [
|
||||
{ required: true, message: '请输入复制数量', trigger: 'blur' },
|
||||
{ type: 'number', min: 1, max: 50, message: '复制数量必须在1-50之间', trigger: 'blur' }
|
||||
],
|
||||
angle: [
|
||||
{ required: true, message: '请输入复制弧度', trigger: 'blur' },
|
||||
{ type: 'number', min: -Math.PI, max: Math.PI, message: '弧度必须在-π到π之间', trigger: 'blur' }
|
||||
]
|
||||
})
|
||||
|
||||
//新增
|
||||
const form = ref({
|
||||
positionMapId: '',
|
||||
skuInfo: '', //物料信息
|
||||
areaName: '', //物料区域名称
|
||||
areaNumber: 0,
|
||||
mapItemIds: []
|
||||
distance: 1,
|
||||
number: 1,
|
||||
angle: 0
|
||||
})
|
||||
|
||||
const open = (list) => {
|
||||
const initialPoint = ref()
|
||||
const open = (item) => {
|
||||
console.log(item)
|
||||
initialPoint.value = item
|
||||
// 重置表单
|
||||
form.value = {
|
||||
distance: 1,
|
||||
number: 1,
|
||||
angle: 0
|
||||
}
|
||||
dialogFormVisible.value = true
|
||||
}
|
||||
|
||||
const emit = defineEmits(['addEventListener', 'itemAreaSettingSubmitSuccess'])
|
||||
const emit = defineEmits(['addEventListener', 'equalDistanceReplicationSucceeded'])
|
||||
const dialogClose = () => {
|
||||
emit('addEventListener')
|
||||
}
|
||||
@ -83,10 +166,142 @@ const submitForm = async (formEl) => {
|
||||
if (!formEl) return
|
||||
await formEl.validate(async (valid, fields) => {
|
||||
if (valid) {
|
||||
submitting.value = true
|
||||
try {
|
||||
// 边界检查
|
||||
if (!validateBoundaries()) {
|
||||
return
|
||||
}
|
||||
|
||||
// 弧度转角度(正东为0度,正北为90度,正西为180度,正南为-90度)
|
||||
const angleInDegrees = (form.value.angle * 180) / Math.PI
|
||||
|
||||
// 距离米转换为像素
|
||||
const distanceInPixels = form.value.distance / Number(props.imgBgObj.resolution)
|
||||
|
||||
// 计算复制点
|
||||
const replicationPoints = calculateReplicationPoints(
|
||||
initialPoint.value,
|
||||
angleInDegrees,
|
||||
distanceInPixels,
|
||||
form.value.number
|
||||
)
|
||||
|
||||
// 触发父组件更新
|
||||
emit('equalDistanceReplicationSucceeded', replicationPoints)
|
||||
|
||||
// 关闭弹窗
|
||||
dialogFormVisible.value = false
|
||||
|
||||
message.success(`成功复制 ${form.value.number} 个点`)
|
||||
} catch (error) {
|
||||
console.error('等距离复制失败:', error)
|
||||
message.error('等距离复制失败:' + (error.message || '未知错误'))
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 边界检查
|
||||
const validateBoundaries = () => {
|
||||
const distanceInPixels = form.value.distance / Number(props.imgBgObj.resolution)
|
||||
const maxDistance = distanceInPixels * form.value.number
|
||||
|
||||
// 检查是否会超出地图边界
|
||||
const angleInDegrees = (form.value.angle * 180) / Math.PI
|
||||
const maxX =
|
||||
initialPoint.value.locationX + maxDistance * Math.cos((angleInDegrees * Math.PI) / 180)
|
||||
const maxY =
|
||||
initialPoint.value.locationY - maxDistance * Math.sin((angleInDegrees * Math.PI) / 180)
|
||||
|
||||
if (maxX < 0 || maxX > props.imgBgObj.width || maxY < 0 || maxY > props.imgBgObj.height) {
|
||||
message.warning('复制点可能超出地图边界,请检查参数')
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 计算等距离复制点
|
||||
const calculateReplicationPoints = (initialPoint, angleInDegrees, distanceInPixels, count) => {
|
||||
const points = []
|
||||
|
||||
for (let i = 1; i <= count; i++) {
|
||||
// 计算当前点的偏移距离
|
||||
const currentDistance = distanceInPixels * i
|
||||
|
||||
// 根据角度计算新的坐标
|
||||
// 正东方向为0度,正北方向为90度,正西方向为180度,正南方向为-90度
|
||||
const newX =
|
||||
initialPoint.locationX + currentDistance * Math.cos((angleInDegrees * Math.PI) / 180)
|
||||
const newY =
|
||||
initialPoint.locationY - currentDistance * Math.sin((angleInDegrees * Math.PI) / 180)
|
||||
|
||||
// 生成新的点对象
|
||||
const newPoint = generateReplicationPoint(initialPoint, newX, newY, i)
|
||||
points.push(newPoint)
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
// 生成复制点对象
|
||||
const generateReplicationPoint = (initialPoint, newX, newY, index) => {
|
||||
// 计算实际坐标
|
||||
const actualLocationX =
|
||||
Number(props.imgBgObj.origin[0]) + Number(newX) * Number(props.imgBgObj.resolution)
|
||||
const actualLocationY =
|
||||
Number(props.imgBgObj.origin[1]) +
|
||||
(Number(props.imgBgObj.height) - Number(newY)) * Number(props.imgBgObj.resolution)
|
||||
|
||||
const { sortNum, createTime, ...restNode } = initialPoint
|
||||
let dataObj = {}
|
||||
let dataList = []
|
||||
let dataJson = ''
|
||||
if (restNode.type === 1 || restNode.type === 6) {
|
||||
dataObj = {}
|
||||
dataList = []
|
||||
dataJson = ''
|
||||
} else if (restNode.type === 2) {
|
||||
dataList = restNode.dataList.map(
|
||||
({ locationDeep, locationStorey, locationWide, positionMapId, locationTypeId }) => ({
|
||||
locationDeep,
|
||||
locationStorey,
|
||||
locationWide,
|
||||
positionMapId,
|
||||
locationTypeId
|
||||
})
|
||||
)
|
||||
dataJson = JSON.stringify(dataList)
|
||||
} else if (restNode.type === 4) {
|
||||
dataObj = {
|
||||
locationDeep: restNode.dataObj.locationDeep,
|
||||
locationWide: restNode.dataObj.locationWide,
|
||||
positionMapId: restNode.dataObj.positionMapId
|
||||
}
|
||||
dataJson = JSON.stringify(dataObj)
|
||||
}
|
||||
|
||||
return {
|
||||
...restNode,
|
||||
id: undefined,
|
||||
locationX: Number(newX.toFixed(4)),
|
||||
locationY: Number(newY.toFixed(4)),
|
||||
actualLocationX: Number(actualLocationX.toFixed(4)),
|
||||
actualLocationY: Number(actualLocationY.toFixed(4)),
|
||||
dataObj,
|
||||
dataList,
|
||||
dataJson
|
||||
}
|
||||
}
|
||||
|
||||
// 设置快捷角度
|
||||
const setQuickAngle = (angle) => {
|
||||
form.value.angle = angle
|
||||
}
|
||||
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
</script>
|
||||
|
||||
@ -98,5 +313,92 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
padding: 0px 20px 20px 0;
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
.quick-angles {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.el-button {
|
||||
min-width: 80px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
user-select: text;
|
||||
padding-left: 110px;
|
||||
margin-top: 16px;
|
||||
|
||||
.tips-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-bottom: 8px;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
|
||||
.el-icon {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.tips-content {
|
||||
background: #f0f9ff;
|
||||
border: 1px solid #b3d8ff;
|
||||
border-radius: 4px;
|
||||
padding: 8px 12px;
|
||||
|
||||
.tip-item {
|
||||
margin-bottom: 6px;
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.el-text {
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表单验证样式优化
|
||||
.el-form-item {
|
||||
margin-bottom: 20px;
|
||||
|
||||
&.is-error {
|
||||
.el-input-number {
|
||||
.el-input__wrapper {
|
||||
box-shadow: 0 0 0 1px #f56c6c inset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 按钮样式优化
|
||||
.dialog-footer {
|
||||
.el-button {
|
||||
min-width: 80px;
|
||||
|
||||
&.el-button--primary {
|
||||
background: #409eff;
|
||||
border-color: #409eff;
|
||||
|
||||
&:hover {
|
||||
background: #66b1ff;
|
||||
border-color: #66b1ff;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: #3a8ee6;
|
||||
border-color: #3a8ee6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -959,17 +959,21 @@
|
||||
<GenerateStraightLinesDialog
|
||||
ref="GenerateStraightLinesDialogRef"
|
||||
@generate-straight-lines-submit="GenerateStraightLinesSubmit"
|
||||
@add-event-listener="addEventListener"
|
||||
/>
|
||||
<!-- 批量复制节点和路线 -->
|
||||
<BatchCopyingDialogForm
|
||||
ref="BatchCopyingDialogFormRef"
|
||||
:imgBgObj="imgBgObj"
|
||||
@submit-batch-copying-form-success="submitBatchCopyingFormSuccess"
|
||||
@add-event-listener="addEventListener"
|
||||
/>
|
||||
<!-- 等距复制 -->
|
||||
<IsometricReplicationDialog
|
||||
ref="IsometricReplicationDialogRef"
|
||||
:imgBgObj="imgBgObj"
|
||||
@add-event-listener="addEventListener"
|
||||
@equal-distance-replication-succeeded="equalDistanceReplicationSucceeded"
|
||||
/>
|
||||
|
||||
<!-- 节点右击菜单 -->
|
||||
@ -981,7 +985,17 @@
|
||||
>
|
||||
<div class="context-menu-item" @click="deleteSingleNode">删除</div>
|
||||
<div class="context-menu-item" @click="contextMenuEditNode">编辑节点</div>
|
||||
<div class="context-menu-item" @click="isometricReplication">等距复制</div>
|
||||
<div
|
||||
class="context-menu-item"
|
||||
@click="isometricReplication"
|
||||
v-if="
|
||||
state.contextMenu.currentItem.type === 1 ||
|
||||
state.contextMenu.currentItem.type === 2 ||
|
||||
state.contextMenu.currentItem.type === 4 ||
|
||||
state.contextMenu.currentItem.type === 6
|
||||
"
|
||||
>等距复制</div
|
||||
>
|
||||
<div
|
||||
class="context-menu-item"
|
||||
@click="generateDetectionPoint"
|
||||
@ -2207,9 +2221,14 @@ const contextMenuEditNode = () => {
|
||||
|
||||
//等距复制
|
||||
const isometricReplication = () => {
|
||||
// IsometricReplicationDialogRef.value.open()
|
||||
// hideContextMenu()
|
||||
message.warning('规则暂未制定')
|
||||
removeEventListener() //移除监听
|
||||
IsometricReplicationDialogRef.value.open(state.contextMenu.currentItem)
|
||||
hideContextMenu()
|
||||
}
|
||||
//复制成功
|
||||
const equalDistanceReplicationSucceeded = (list) => {
|
||||
state.allMapPointInfo.push(...list)
|
||||
addEditHistory()
|
||||
}
|
||||
|
||||
//生成检测点
|
||||
@ -2952,6 +2971,7 @@ const clickDrawSelectionArea = () => {
|
||||
message.warning('您选择的路径点存在未保存的')
|
||||
return
|
||||
}
|
||||
removeEventListener() //移除监听
|
||||
GenerateStraightLinesDialogRef.value.open(routeList)
|
||||
}
|
||||
//批量删除
|
||||
@ -2983,6 +3003,7 @@ const clickDrawSelectionArea = () => {
|
||||
top: Math.min(...state.drawSelectionPointList.map((point) => Number(point.locationY))),
|
||||
bottom: Math.max(...state.drawSelectionPointList.map((point) => Number(point.locationY)))
|
||||
}
|
||||
removeEventListener() //移除监听
|
||||
BatchCopyingDialogFormRef.value.open(boundaryValue)
|
||||
} else {
|
||||
message.warning('至少选择一个点')
|
||||
@ -3056,11 +3077,12 @@ const submitBatchCopyingFormSuccess = async (form) => {
|
||||
dataJson = ''
|
||||
} else if (restNode.type === 2) {
|
||||
dataList = restNode.dataList.map(
|
||||
({ locationDeep, locationStorey, locationWide, positionMapId }) => ({
|
||||
({ locationDeep, locationStorey, locationWide, positionMapId, locationTypeId }) => ({
|
||||
locationDeep,
|
||||
locationStorey,
|
||||
locationWide,
|
||||
positionMapId
|
||||
positionMapId,
|
||||
locationTypeId
|
||||
})
|
||||
)
|
||||
dataJson = JSON.stringify(dataList)
|
||||
|
Loading…
Reference in New Issue
Block a user