Commit 47293dba authored by 何远江's avatar 何远江

修改展示解析结果样式,调整设置区域修改为按步骤进行

parent 442ce459
...@@ -59,16 +59,9 @@ export function getRangeState(range: any) { ...@@ -59,16 +59,9 @@ export function getRangeState(range: any) {
} }
} }
export function handleRangeTitle(range: any, dataArea: Recordable) { export function handleRangeTitle(range: any) {
const { const { beginColum, beginRow, endRow, endColum, sheetNum, rowLen, columnLen } =
beginColum, getRangeState(range)
beginRow,
endRow,
endColum,
sheetNum,
rowLen,
columnLen
} = getRangeState(range)
const titles: Recordable[] = [] const titles: Recordable[] = []
let isVertical = false let isVertical = false
...@@ -81,45 +74,42 @@ export function handleRangeTitle(range: any, dataArea: Recordable) { ...@@ -81,45 +74,42 @@ export function handleRangeTitle(range: any, dataArea: Recordable) {
) { ) {
isVertical = true isVertical = true
} }
/** /**
* 取最后一个单元格的坐标,值为最后一个单元格,如果当前单元格没有值,继承前一个单元格值 * 由底向上循环
* 横向 -> row 不变 纵向 -> column 不变
* *
* 横向:以列为单位取值,多值取最后有值单元格
*
* 纵向:以行为单位,多值取最后有值单元格
*/ */
for (let c = 0; c < (isVertical ? rowLen : columnLen); c++) { for (let c = 0; c < (isVertical ? rowLen : columnLen); c++) {
const title = { const title = {
title: '', title: '',
sheet: sheetNum, sheet: sheetNum,
row: 0, row: !isVertical ? +beginRow + rowLen - 1 : endRow - rowLen - 1,
colum: 0 colum: isVertical ? +beginColum + columnLen - 1 : endColum - columnLen - 1
} }
for (let r = 0; r < (isVertical ? columnLen : rowLen); r++) { for (let r = (isVertical ? columnLen : rowLen) - 1; r >= 0; r--) {
const cell = isVertical ? range[c][r] : range[r][c] const cell = isVertical ? range[c][r] : range[r][c]
let v = ''
isVertical ? (title.row = +beginRow + c) : (title.colum = +beginColum + c)
// 如果获取值报错,那么断定单元格值为空,直接取上一个单元格的值 // 如果获取值报错,那么断定单元格值为空,直接取上一个单元格的值
try { try {
v = cell.v || cell?.ct?.s.map((itm) => itm.v).join('') title.title = cell.v || cell?.ct?.s.map((itm) => itm.v).join('')
} catch { // 如果有值那么直接进入下一列或者下一行
v = title.title if (title.title) {
// 如果有合并单元格,直接跳过合并的单元格
if (cell?.mc?.rs > 1 || cell?.mc?.cs > 1) {
c += (isVertical ? cell.mc.rs : cell.mc.cs) - 1
} }
// 如果有单元格合并,跳过单元格 break
if (cell?.mc) { }
r += isVertical ? cell.mc.cs - 1 : cell.mc.rs - 1 } catch {
c += isVertical ? cell.mc.rs - 1 : cell.mc.cs - 1 continue
} }
title.title = v.replaceAll(/(\s+)/g, '')
title.colum = +beginColum + (isVertical ? r : c)
title.row = +beginRow + (isVertical ? c : r)
} }
titles.push(title) titles.push(title)
} }
return titles return titles
} }
/** /**
* 获取当前选取的坐标 * 获取当前选取的坐标
* @returns * @returns
......
<template>
<el-form size="small" inline>
<el-row :gutter="12">
<el-col>
<el-form-item label="数据区域">
<el-tag>{{
getRangetxt(
currentForm.beginRow,
currentForm.endRow,
currentForm.beginColum,
currentForm.endColum
)
}}</el-tag>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="区域别称" prop="excelAreaNicname">
<el-input v-model="currentForm.excelAreaNicname"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="区域类型" prop="excelAreaType">
<el-select v-model="currentForm.excelAreaType">
<template v-for="item in areaTypeSelectOption" :key="item.value">
<el-option :label="item.label" :value="item.value"></el-option>
</template>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="循环体间隔" prop="checkNumber">
<el-input type="number" v-model="currentForm.checkNumber"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="标题作为数据" prop="oneself">
<el-checkbox v-model="currentForm.oneself" true-label="Y" false-label="N"></el-checkbox>
</el-form-item>
</el-col>
</el-row>
<vxe-table
:row-config="{ isCurrent: true }"
border
:data="currentForm.excelAreaTitle"
size="mini"
height="200"
:edit-config="{ trigger: 'click', mode: 'cell' }"
>
<vxe-column title="标题" field="title" :edit-render="{}">
<template #edit="{ row }">
<el-input v-model="row.title" size="small"></el-input>
</template>
</vxe-column>
<vxe-column title="单元格" field="cell" width="90">
<template #default="{ row }">
{{ getRangetxt(row.row, row.row, row.colum, row.colum) }}
</template>
</vxe-column>
<vxe-column title="操作" field="action" width="50">
<template #default="{ row, $rowIndex }">
<el-link style="font-size: 12px" type="danger" @click="delAreaTitle($rowIndex)"
>删除</el-link
>
</template>
</vxe-column>
</vxe-table>
</el-form>
<p>
附加信息:<el-tag>{{
getRangetxt(attchInfo.beginRow, attchInfo.endRow, attchInfo.beginColum, attchInfo.endColum)
}}</el-tag>
</p>
<vxe-table
style="margin-top: 8px"
:row-config="{ isCurrent: true }"
border
:data="attchInfo.groupTitles"
size="mini"
max-height="200"
:edit-config="{ trigger: 'click', mode: 'cell' }"
>
<vxe-column title="别称" field="title" :edit-render="{}">
<template #edit="{ row }">
<el-input size="small" v-model="row.title"></el-input>
</template>
</vxe-column>
<vxe-column title="单元格" field="area" width="100">
<template #default="{ row }">
{{ getRangetxt(row.row, row.row, row.colum, row.colum) }}
</template>
</vxe-column>
<vxe-column title="操作" field="action" width="50">
<template #default="{ row, $rowIndex }">
<el-link style="font-size: 12px" type="danger" @click="delGroupTitle($rowIndex)"
>删除</el-link
>
</template>
</vxe-column>
</vxe-table>
<vxe-table
style="margin-top: 8px"
:row-config="{ isCurrent: true }"
border
:data="attchInfo.areaTitles"
size="mini"
max-height="200"
:edit-config="{ trigger: 'click', mode: 'cell' }"
>
<vxe-column title="标题" field="title" :edit-render="{}">
<template #edit="{ row }">
<el-input v-model="row.title" size="small"></el-input>
</template>
</vxe-column>
<vxe-column title="单元格" field="cell" width="100">
<template #default="{ row }">
{{ getRangetxt(row.row, row.row, row.colum, row.colum) }}
</template>
</vxe-column>
<vxe-column title="操作" field="action" width="50">
<template #default="{ row, $rowIndex }">
<el-link style="font-size: 12px" type="danger" @click="delGroupAreaTitle($rowIndex)"
>删除</el-link
>
</template>
</vxe-column>
</vxe-table>
</template>
<script setup lang="ts">
import { ref, reactive, watch, onMounted } from 'vue'
import { cloneDeep } from 'lodash-es'
import { getRangetxt } from '@/utils/excel'
import type { Recordable } from '@/types/global'
import { apiDictList } from '@/api/common'
import { ElMessage } from 'element-plus'
const props = defineProps({
currentAreaMark: {
type: Object,
defualt: () => ({})
}
})
const areaTypeSelectOption = ref<Recordable[]>([])
const currentForm = reactive<Recordable>({
beginRow: '',
endRow: '',
beginColum: '',
endColum: '',
sheetNum: 0,
excelAreaTitle: []
})
const attchInfo = reactive<Recordable>({
beginRow: '',
endRow: '',
beginColum: '',
endColum: '',
sheetNum: 0,
areaTitles: [],
groupTitles: []
})
watch(
() => props.currentAreaMark,
(val) => {
Object.assign(currentForm, val)
if (val?.desGroups.length) {
Object.assign(attchInfo, cloneDeep(val.desGroups[0]))
}
},
{ deep: true, immediate: true }
)
const delAreaTitle = (index: number) => {
currentForm.excelAreaTitle.splice(index, 1)
}
const delGroupAreaTitle = (index: number) => {
attchInfo.areaTitles.splice(index, 1)
}
const delGroupTitle = (index: number) => {
if (attchInfo.groupTitles.length == 1) {
return ElMessage.error('附加信息必须有别称!')
}
attchInfo.groupTitles.splice(index, 1)
}
const queryDict = async (code: string) => {
const { data } = await apiDictList({
dictCodes: code
})
areaTypeSelectOption.value = data.result[code]
}
onMounted(() => {
queryDict('excel_area_type')
})
const getAreaData = () => {
return {
...currentForm,
desGroups: [{ ...attchInfo }]
}
}
defineExpose({
getAreaData
})
</script>
...@@ -6,227 +6,6 @@ ...@@ -6,227 +6,6 @@
<div class="w-[420px] h-full bg-white"> <div class="w-[420px] h-full bg-white">
<p class="pl-2 text-lg font-bold leading-[40px] bg-slate-200">标注配置</p> <p class="pl-2 text-lg font-bold leading-[40px] bg-slate-200">标注配置</p>
<SetArea @success="onSaveSuccess" /> <SetArea @success="onSaveSuccess" />
<!-- <el-form
ref="settingForm"
size="small"
:rules="rules"
:model="formState"
label-width="6em"
class="comment-form pl-2 pr-2 pt-2 pb-2 border-b-2"
>
<el-row :gutter="10">
<el-col :span="24">
<el-form-item label="区域别称" prop="excelAreaNicname">
<el-input v-model="formState.excelAreaNicname" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="区域类型" prop="excelAreaType">
<el-select v-model="formState.excelAreaType" clearable>
<template v-for="item in areaTypeSelectOption" :key="item.value">
<el-option :label="item.label" :value="item.value"></el-option>
</template>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="循环体间隔" prop="checkNumber">
<el-input type="number" v-model="formState.checkNumber" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="标题区作为数据" prop="oneself" label-width="100px">
<el-checkbox true-label="Y" false-label="N" v-model="formState.oneself"
></el-checkbox
>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="标题参与循环" prop="checkSelf" label-width="100px">
<el-checkbox true-label="Y" false-label="N" v-model="formState.checkSelf"
></el-checkbox
>
</el-form-item>
</el-col>
<el-col :span="24">
<el-button-group class="mr-2">
<el-button type="primary" @click="setAreaMark('data')">设置数据区</el-button>
<el-button type="primary" @click="setAreaMark('head')">设置标题区</el-button>
</el-button-group>
<el-button-group>
<el-button type="primary" @click="setAreaMark('attch')">设置附加信息</el-button>
<el-button type="primary" @click="setAreaMark('attch_head')"
>设置附加别称</el-button
>
<el-button type="primary" @click="setAreaMark('attch_title')"
>设置附加标题</el-button
>
</el-button-group>
</el-col>
</el-row>
</el-form>
<div class="border-b-2 p-2 leading-7 text-sm">
<el-descriptions
class="current-area-mark"
border
title="当前标记数据区域"
size="small"
:column="2"
>
<el-descriptions-item label-class-name="descriptions-label" :span="2" label="区域别称">
<template v-if="isEditCurrentArea">
<el-input v-model="currentAreaMark.excelAreaNicname" size="small"></el-input>
</template>
<template v-else>
{{ currentAreaMark.excelAreaNicname || '--' }}
</template>
</el-descriptions-item>
<el-descriptions-item label-class-name="descriptions-label" label="标记区域">
{{
getRangetxt(
currentAreaMark.beginRow,
currentAreaMark.endRow,
currentAreaMark.beginColum,
currentAreaMark.endColum
)
}}
</el-descriptions-item>
<el-descriptions-item label-class-name="descriptions-label" label="区域类型">
<template v-if="isEditCurrentArea">
<el-select
style="width: 80px"
size="small"
v-model="currentAreaMark.excelAreaType"
clearable
>
<template v-for="item in areaTypeSelectOption" :key="item.value">
<el-option :label="item.label" :value="item.value"></el-option>
</template>
</el-select>
</template>
<template v-else>
{{ getAreaTypeText(currentAreaMark.excelAreaType) }}
</template>
</el-descriptions-item>
<el-descriptions-item label-class-name="descriptions-label" label="循环体间隔">
<template v-if="isEditCurrentArea">
<el-input
style="width: 80px"
size="small"
type="number"
v-model="currentAreaMark.checkNumber"
></el-input>
</template>
<template v-else>
{{ currentAreaMark.checkNumber || '--' }}
</template>
</el-descriptions-item>
<el-descriptions-item label-class-name="descriptions-label" label="标题作为数据">
<el-checkbox
true-label="Y"
false-label="N"
size="small"
v-model="currentAreaMark.oneself"
:disabled="!isEditCurrentArea"
></el-checkbox
>
</el-descriptions-item>
<el-descriptions-item label-class-name="descriptions-label" label="标题参与循环">
<el-checkbox
true-label="Y"
false-label="N"
size="small"
v-model="currentAreaMark.checkSelf"
:disabled="!isEditCurrentArea"
></el-checkbox
>
</el-descriptions-item>
</el-descriptions>
<vxe-table
class="mb-2 mt-2"
:row-config="{ isCurrent: true }"
border
:data="currentAreaMark.excelAreaTitle"
size="mini"
height="200"
:edit-config="{ trigger: 'click', mode: 'cell' }"
>
<vxe-column title="title" field="title" :edit-render="{}">
<template #edit="{ row }">
<el-input :disabled="isEditCurrentArea" v-model="row.title" size="small"></el-input>
</template>
</vxe-column>
<vxe-column title="单元格" field="cell" width="90">
<template #default="{ row }">
{{ getRangetxt(row.row, row.row, row.colum, row.colum) }}
</template>
</vxe-column>
</vxe-table>
<p class="font-bold">附加信息</p>
<vxe-table
:data="currentAttchInfo.groupTitles"
@cell-click="cellClick"
border
size="mini"
max-height="200"
>
<vxe-column title="附加区域" field="area" width="120">
<template #default="{ row }">
{{ getRangetxt(row.row, row.row, row.colum, row.colum) }}
</template>
</vxe-column>
<vxe-column title="附加title" field="attch_title">
<template #default="{ row }">
{{ row.title }}
</template>
</vxe-column>
<vxe-column title="操作" field="action" width="80">
<template #default="{ row, $rowIndex }">
<el-link
style="font-size: 12px"
type="danger"
@click.stop="delAttchInfo(row, $rowIndex)"
>删除</el-link
>
</template>
</vxe-column>
</vxe-table>
<vxe-table
class="mb-2 mt-2"
:row-config="{ isCurrent: true }"
border
:data="currentAttchInfo.areaTitles"
size="mini"
height="200"
:edit-config="{ trigger: 'click', mode: 'cell' }"
>
<vxe-column title="title" field="title" :edit-render="{}">
<template #edit="{ row }">
<el-input :disabled="isEditCurrentArea" v-model="row.title" size="small"></el-input>
</template>
</vxe-column>
<vxe-column title="单元格" field="cell" width="90">
<template #default="{ row }">
{{ getRangetxt(row.row, row.row, row.colum, row.colum) }}
</template>
</vxe-column>
</vxe-table>
<el-button type="primary" size="small" @click="saveAreaMark">保存</el-button>
<el-button
v-if="isEditCurrentArea"
type="default"
size="small"
@click="resetCurrentAreaState(true)"
>取消修改</el-button
>
</div> -->
<div class="pt-2 pl-2 pr-2 pb-2 text-sm border-t-2 border-b-2"> <div class="pt-2 pl-2 pr-2 pb-2 text-sm border-t-2 border-b-2">
<p class="font-bold">标记区域</p> <p class="font-bold">标记区域</p>
...@@ -255,10 +34,14 @@ ...@@ -255,10 +34,14 @@
@click.stop="chooseConnect(row)" @click.stop="chooseConnect(row)"
>关联</el-link >关联</el-link
> >
<el-link class="mr-1" style="font-size: 12px" type="primary" @click="toModify(row)" <el-link
class="mr-1"
style="font-size: 12px"
type="primary"
@click.stop="toModify(row)"
>修改</el-link >修改</el-link
> >
<el-link style="font-size: 12px" type="danger" @click="delAreaMark(row)" <el-link style="font-size: 12px" type="danger" @click.stop="delAreaMark(row)"
>删除</el-link >删除</el-link
> >
</template> </template>
...@@ -273,9 +56,6 @@ ...@@ -273,9 +56,6 @@
<vxe-column title="别关联名称" field="excelAreaBeId_dictText"></vxe-column> <vxe-column title="别关联名称" field="excelAreaBeId_dictText"></vxe-column>
<vxe-column title="操作" field="action" width="80"> <vxe-column title="操作" field="action" width="80">
<template #default="{ row, $rowIndex }"> <template #default="{ row, $rowIndex }">
<!-- <el-link style="font-size: 12px" type="primary" @click="toModifyConnect(row)"
>修改</el-link
> -->
<el-link style="font-size: 12px" type="danger" @click="delConnect(row, $rowIndex)" <el-link style="font-size: 12px" type="danger" @click="delConnect(row, $rowIndex)"
>删除</el-link >删除</el-link
> >
...@@ -288,6 +68,13 @@ ...@@ -288,6 +68,13 @@
</div> </div>
</el-scrollbar> </el-scrollbar>
<vxe-modal width="600" height="600" v-model="editVisible" title="编辑区域" show-footer>
<EditArea ref="editAreaRef" :current-area-mark="currentAreaMark" />
<template #footer>
<el-button type="primary" @click="confirmEdit">提交</el-button>
</template>
</vxe-modal>
<vxe-modal <vxe-modal
width="600" width="600"
@hide="chooseConnectOnHide" @hide="chooseConnectOnHide"
...@@ -351,8 +138,31 @@ ...@@ -351,8 +138,31 @@
border border
height="500" height="500"
> >
<vxe-column title="行号" field="sortNum" width="120"></vxe-column> <vxe-column title="行号" type="expand" width="120">
<vxe-column title="数据区" field="数据区" width="120"></vxe-column> <template #default="{ row }">{{ row.sortNum }}</template>
<template #content="{ row, rowIndex }">
<div style="padding: 10px">
<template v-for="attchName of filterObjKeys(row.expendData)">
<el-descriptions
direction="vertical"
border
:column="filterObjKeys(row.expendData[attchName]).length"
size="small"
:title="attchName"
>
<el-descriptions-item
v-for="pro in filterObjKeys(row.expendData[attchName])"
:label="pro"
>{{ row.expendData[attchName][pro] }}</el-descriptions-item
>
</el-descriptions>
</template>
</div>
</template>
</vxe-column>
<vxe-column title="数据区" width="120">
<template #default="{ row }">{{ row['数据区'] }}</template>
</vxe-column>
<template v-for="item in runResultTitle" :key="item"> <template v-for="item in runResultTitle" :key="item">
<vxe-column :title="item" :field="item" width="200"></vxe-column> <vxe-column :title="item" :field="item" width="200"></vxe-column>
</template> </template>
...@@ -377,15 +187,8 @@ import { flatten, cloneDeep } from 'lodash-es' ...@@ -377,15 +187,8 @@ import { flatten, cloneDeep } from 'lodash-es'
import { useCommentExcel } from '@/stores/commentExcel' import { useCommentExcel } from '@/stores/commentExcel'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { isFunction } from '@/utils/is' import { isFunction } from '@/utils/is'
import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
import { import {
ElLoading,
ElMessage,
ElMessageBox,
type FormInstance,
type FormItemRule
} from 'element-plus'
import {
addExcelArea,
addExcelAreaConnect, addExcelAreaConnect,
editExcelArea, editExcelArea,
excelMarkRun, excelMarkRun,
...@@ -395,27 +198,12 @@ import { ...@@ -395,27 +198,12 @@ import {
removeExcelAreaConnect removeExcelAreaConnect
} from '@/api/excel' } from '@/api/excel'
import type { Recordable } from '@/types/global' import type { Recordable } from '@/types/global'
import { getRangetxt, handleRangeTitle } from '@/utils/excel' import { getRangetxt } from '@/utils/excel'
import type { VxeTableInstance } from 'vxe-table' import type { VxeTableInstance } from 'vxe-table'
import { apiDictFindById, apiDictList } from '@/api/common' import EditArea from '../EditArea/EditArea.vue'
const tableData = ref([])
const settingForm = ref<FormInstance>()
const rules = reactive({
excelAreaNicname: [{ required: true, message: '请输入区域别称!', trigger: 'change' }],
excelAreaType: [{ required: true, message: '请选择区域类型!', trigger: 'change' }],
checkNumber: [
{
validator: (rule, value, cb) => {
if (value <= 0) {
cb(new Error('请输入正整数!'))
return false
}
return true
},
trigger: 'change'
}
]
})
const connectVisible = ref(false) const connectVisible = ref(false)
const xTableConnect = ref<VxeTableInstance>() const xTableConnect = ref<VxeTableInstance>()
const beConnectTable = ref<VxeTableInstance>() const beConnectTable = ref<VxeTableInstance>()
...@@ -424,7 +212,7 @@ const commentExcelStore = useCommentExcel() ...@@ -424,7 +212,7 @@ const commentExcelStore = useCommentExcel()
const { getFileInfo } = storeToRefs(commentExcelStore) const { getFileInfo } = storeToRefs(commentExcelStore)
const connectList = ref<any[]>([]) const connectList = ref<any[]>([])
const chooseVisible = ref(false) const chooseVisible = ref(false)
const areaTypeSelectOption = ref<any[]>([]) const editVisible = ref(false)
const currentConnectInfo = reactive<Recordable>({ const currentConnectInfo = reactive<Recordable>({
excelAreaConnectId: '', excelAreaConnectId: '',
excelAreaId: '', excelAreaId: '',
...@@ -452,31 +240,7 @@ const beConnectData = computed(() => { ...@@ -452,31 +240,7 @@ const beConnectData = computed(() => {
.filter((v: any) => v.excelAreaId != currentConnectInfo.excelAreaId) .filter((v: any) => v.excelAreaId != currentConnectInfo.excelAreaId)
} }
}) })
const formState = reactive({
// excelAreaId: '',
fileId: '',
sheetNum: 0,
beginRow: '',
beginColum: '',
endRow: '',
endColum: '',
excelAreaType: '',
excelAreaNicname: '',
checkNumber: 1,
oneself: 'N',
checkSelf: 'N'
})
watch(
() => formState.excelAreaType,
(val) => {
console.log('watch----val', val)
formState.excelAreaNicname = val
? areaTypeSelectOption.value.find((v) => v.value == val).label +
(areaList.value.filter((v) => v.excelAreaType == val).length + 1)
: ''
}
)
const isSetSheetMark = ref<any>([]) const isSetSheetMark = ref<any>([])
const initIsSetSheetMark = (length: number) => { const initIsSetSheetMark = (length: number) => {
isSetSheetMark.value = Array.from({ length }).fill(false) isSetSheetMark.value = Array.from({ length }).fill(false)
...@@ -490,15 +254,14 @@ const initIsSetSheetMark = (length: number) => { ...@@ -490,15 +254,14 @@ const initIsSetSheetMark = (length: number) => {
*/ */
const locaExcelAreaMarks: Recordable = reactive({}) const locaExcelAreaMarks: Recordable = reactive({})
const areaList = computed(() => flatten(Object.values(locaExcelAreaMarks))) const areaList = computed(() => flatten(Object.values(locaExcelAreaMarks)))
const onSaveSuccess = (data: any) => {
locaExcelAreaMarks[data.result['sheetNum']].push(data.result)
}
const initExcelAreaMarksKey = (len: number) => { const initExcelAreaMarksKey = (len: number) => {
Array.from({ length: len }).forEach((item, index) => { Array.from({ length: len }).forEach((item, index) => {
Reflect.set(locaExcelAreaMarks, index, []) Reflect.set(locaExcelAreaMarks, index, [])
}) })
} }
const onSaveSuccess = (data: any) => {
locaExcelAreaMarks[data.result['sheetNum']].push(data.result)
}
const exportRunData = () => { const exportRunData = () => {
runDataTable.value?.exportData({ type: 'csv' }) runDataTable.value?.exportData({ type: 'csv' })
...@@ -516,11 +279,13 @@ const setSheetAuthority = (exportJson: any) => { ...@@ -516,11 +279,13 @@ const setSheetAuthority = (exportJson: any) => {
} }
const cellClick = ({ row }) => { const cellClick = ({ row }) => {
const sheetNum = row?.sheetNum || row.sheet let sheetNum: number, beginRow: number, beginColum: number, endColum: number, endRow: number
const beginRow = row?.beginRow || row.row const flag = row.sheetNum !== undefined
const beginColum = row?.beginColum || row.colum sheetNum = flag ? row.sheetNum : row.sheet
const endColum = row?.endColum || row.colum beginRow = flag ? row.beginRow : row.row
const endRow = row?.endRow || row.row beginColum = flag ? row.beginColum : row.colum
endColum = flag ? row.endColum : row.colum
endRow = flag ? row.endRow : row.row
// 判断是否是当前sheet页标记 // 判断是否是当前sheet页标记
const sheet = luckysheet.getSheet() const sheet = luckysheet.getSheet()
if (sheet.order != sheetNum) { if (sheet.order != sheetNum) {
...@@ -530,305 +295,12 @@ const cellClick = ({ row }) => { ...@@ -530,305 +295,12 @@ const cellClick = ({ row }) => {
targetRow: beginRow - 3 < 0 ? 0 : beginRow - 3, targetRow: beginRow - 3 < 0 ? 0 : beginRow - 3,
targetColumn: beginColum - 3 < 0 ? 0 : beginColum - 3 targetColumn: beginColum - 3 < 0 ? 0 : beginColum - 3
}) })
setTimeout(() => {
luckysheet.setRangeShow({ luckysheet.setRangeShow({
row: [beginRow, endRow], row: [beginRow, endRow],
column: [beginColum, endColum] column: [beginColum, endColum]
}) })
}, 100)
} }
const currentAreaMark = reactive<Recordable>({
oneself: 'N',
checkSelf: 'N',
checkNumber: 1,
excelAreaTitle: [],
desGroups: [],
titleArea: ''
})
const isEditCurrentArea = computed(() => !!currentAreaMark.excelAreaId)
const currentTitlesArea = ref<Recordable>([])
const currentAttchInfo = reactive({
sheetNum: '',
beginRow: '',
beginColum: '',
endRow: '',
endColum: '',
groupTitles: [],
areaTitles: []
})
// 删除附加信息
const delAttchInfo = (row, index) => {
currentAreaMark.desGroups.splice(index, 1)
// 选中要删除的区域,设置颜色
luckysheet.setRangeShow({
row: [row.beginRow, row.endRow],
column: [row.beginColum, row.endColum]
})
luckysheet.setRangeFormat('bg', areaMarksColor['data'])
}
const resetAttchInfo = () => {
Object.assign(currentAttchInfo, {
sheetNum: '',
beginRow: '',
beginColum: '',
endRow: '',
endColum: '',
groupTitles: [],
areaTitles: []
})
}
const saveAttchInfo = () => {
const res = Object.assign({}, currentAttchInfo)
const haveAttch = res.beginRow != ''
if (haveAttch) {
// 判断是否有 groupTitles
if (!res.groupTitles.length) {
ElMessage.error('请设置附加信息的别称!')
return false
}
Object.assign(currentAreaMark, { desGroups: currentAreaMark.desGroups.concat(res) })
}
return true
}
const setAreaMark = async (
type: 'data' | 'head' | 'attch' | 'attch_head' | 'attch_title' = 'data'
) => {
if (type === 'data') {
/**
* 判断是否有未保存的区域
* 如果有未保存的标记 -> 提示用户,是否覆盖
*/
// 验证表单
await settingForm.value?.validate()
if (currentAreaMark.beginRow !== '' && currentAreaMark.beginRow !== undefined) {
try {
await ElMessageBox.confirm('检测到未保存的标记,是否保存?', '提示消息', {
confirmButtonText: '保存',
cancelButtonText: '取消'
})
return saveAreaMark()
} catch {
if (currentAreaMark.excelAreaId) {
currentAreaMark.excelAreaId = ''
resetCurrentAreaState()
} else {
currentAreaMark.excelAreaId = ''
resetCurrentArea(() => {
// 设置当前选区
luckysheet.setRangeShow({
row: [formState.beginRow, formState.endRow],
column: [formState.beginColum, formState.endColum]
})
})
}
}
// resetCurrentArea(() => {
// // 设置当前选区
// luckysheet.setRangeShow({
// row: [formState.beginRow, formState.endRow],
// column: [formState.beginColum, formState.endColum]
// })
// })
}
// console.log(formState)
// debugger
Object.assign(currentAreaMark, unref(formState))
// 设置完成之后重置表单
settingForm.value?.resetFields([
'excelAreaType',
'excelAreaNicname',
'oneself',
'checkSelf',
'checkNumber'
])
} else if (type === 'head') {
if (currentAreaMark.excelAreaId) {
return ElMessage.error('请先保存或取消正在修改的数据区域!')
}
if (!currentAreaMark.excelAreaNicname) {
return ElMessage.error('请先设置数据区!')
}
// 判断是否在同一sheet
if (formState.sheetNum !== currentAreaMark.sheetNum) {
return ElMessage.error('请在同一sheet页中选择数据!')
}
/**
* 组装数据
* 判断选择的 head区域 是否在数据区域 内部
* 判断是否有重复的单元格添加,如有重复无需添加此单元格
*/
const rangeData = luckysheet.getRangeValue()
console.log('rangeData', rangeData)
const titles = handleRangeTitle(rangeData, unref(formState))
console.log('titles', titles)
currentTitlesArea.value.push({
excelAreaId: '',
excelAreaNicname: currentAreaMark.excelAreaNicname,
sr: formState.beginRow,
sc: formState.beginColum,
er: formState.endRow,
ec: formState.endColum
})
// 合并组装的表头区域数据
if (currentAreaMark.excelAreaTitle?.length > 0) {
const arr = [...titles, ...unref(currentAreaMark.excelAreaTitle)]
// 合并,去重
currentAreaMark.excelAreaTitle = uniqArrayObject(arr)
} else {
currentAreaMark.excelAreaTitle = titles
}
} else if (type === 'attch') {
// 是否设置数据区
if (!currentAreaMark.excelAreaNicname) {
return ElMessage.error('请先设置数据区!')
}
const area = {
sheetNum: formState.sheetNum,
beginRow: formState.beginRow,
beginColum: formState.beginColum,
endRow: formState.endRow,
endColum: formState.endColum,
groupTitles: [],
areaTitles: []
}
Object.assign(currentAttchInfo, area)
} else if (type === 'attch_head') {
// 验证是否在附加区域
// 验证是否设置附加区域
if (currentAttchInfo.beginRow == '') {
return ElMessage.error('请先设置附加信息区域!')
}
const rangeData = luckysheet.getRangeValue()
const groupTitles = handleRangeTitle(rangeData, unref(currentAttchInfo))
Object.assign(currentAttchInfo, { groupTitles })
} else if (type === 'attch_title') {
// 验证是否在附加区域
// 验证是否设置附加区域
if (currentAttchInfo.beginRow == '') {
return ElMessage.error('请先设置附加信息区域!')
}
const rangeData = luckysheet.getRangeValue()
const areaTitles = handleRangeTitle(rangeData, unref(currentAttchInfo))
console.log('areaTitles', areaTitles)
Object.assign(currentAttchInfo, { areaTitles })
}
function uniqArrayObject(arr = []) {
return arr.reduce((cur, pre, index) => {
if (index == 0) {
cur.push(pre)
} else {
const isDiff = cur.every((item) => {
return (
item.column != pre.column ||
item.row != pre.row ||
item.sheet != pre.sheet ||
item.title != pre.title
)
})
isDiff && cur.push(pre)
}
return cur
}, [])
}
setTimeout(() => {
// 设置区域颜色
luckysheet.setRangeFormat('bg', areaMarksColor[type])
}, 100)
}
const resetCurrentAreaState = (isedit: boolean = false) => {
// 重置 其他属性
const tmp: Recordable = {
sheetNum: 0,
beginRow: '',
beginColum: '',
endRow: '',
endColum: '',
excelAreaType: '',
excelAreaNicname: '',
excelAreaTitle: [],
desGroups: [],
titleArea: '',
oneself: 'N',
checkSelf: 'N',
checkNumber: ''
}
isedit && (tmp.excelAreaId = '')
currentTitlesArea.value = []
resetAttchInfo()
Object.assign(currentAreaMark, tmp)
}
const resetCurrentArea = (fn?: Function) => {
// 清除区域颜色
luckysheet.setRangeShow(
{
row: [currentAreaMark.beginRow, currentAreaMark.endRow],
column: [currentAreaMark.beginColum, currentAreaMark.endColum]
},
{
show: false,
success: () => {
luckysheet.setRangeFormat('bg', areaMarksColor['default'])
resetCurrentAreaState()
fn && fn()
}
}
)
}
const hasRepeatValue = (data: any[], field: string) => {
const datas = data.map((item) => item[field])
const res = Array.from(new Set(datas))
return res.length == datas.length
}
const saveAreaMark = async () => {
if (!hasRepeatValue(currentAreaMark.excelAreaTitle, 'title')) {
return ElMessage.error('有重复标题!请修改后保存!')
}
// 保存附加信息
if (!saveAttchInfo()) {
return
}
currentAreaMark.fileId = getFileInfo.value.orderFileId
currentAreaMark.titleArea = JSON.stringify(unref(currentTitlesArea))
// 如果有id 调用修改,否则调用新增
const isEdit = !!currentAreaMark.excelAreaId
const { data } = isEdit
? await editExcelArea(currentAreaMark)
: await addExcelArea(currentAreaMark)
// 接口保存成功之后,保存/更新 locaExcelAreaMarks
if (isEdit) {
const idx = locaExcelAreaMarks[cachAreaMark.sheetNum].findIndex(
(v) => v.excelAreaId == cachAreaMark.excelAreaId
)
locaExcelAreaMarks[cachAreaMark.sheetNum].splice(idx, 1, cloneDeep(currentAreaMark))
} else {
locaExcelAreaMarks[currentAreaMark.sheetNum].push(data.result)
}
ElMessage.success('操作成功!')
resetCurrentAreaState(true)
}
const cachAreaMark = reactive<Recordable>({})
const cachDelOtherSheetArea = reactive<Recordable>({})
const delAreaMark = async (row: any) => { const delAreaMark = async (row: any) => {
// 判断当前区域是否关联了其他区域 // 判断当前区域是否关联了其他区域
if ( if (
...@@ -839,32 +311,23 @@ const delAreaMark = async (row: any) => { ...@@ -839,32 +311,23 @@ const delAreaMark = async (row: any) => {
return ElMessage.warning('当前区域绑定与其他区域绑定了关联信息,请先删除关联信息之后再做修改!') return ElMessage.warning('当前区域绑定与其他区域绑定了关联信息,请先删除关联信息之后再做修改!')
} }
if (currentAreaMark.excelAreaId == row.excelAreaId) {
resetCurrentAreaState(true)
}
// 调用接口删除 // 调用接口删除
await removeExcelArea(row.excelAreaId) await removeExcelArea(row.excelAreaId)
const sheet = luckysheet.getSheet() const sheet = luckysheet.getSheet()
/** /**
* 如果在本sheet那么直接删除,并且改变区域颜色 * 如果在本sheet那么直接删除,并且清除区域颜色
* 如果不在当前sheet,保存删除的数据,在切换sheet的hook中删除颜色 * 不在当前sheet页,切换sheet显示页
*/ */
if (row.sheetNum == sheet.order) { if (row.sheetNum == sheet.order) {
} else {
luckysheet.setSheetActive(row.sheetNum)
}
const range: Recordable = { const range: Recordable = {
row: [row.beginRow, row.endRow], row: [row.beginRow, row.endRow],
column: [row.beginColum, row.endColum] column: [row.beginColum, row.endColum]
} }
luckysheet.setRangeShow(range) luckysheet.setRangeShow(range)
setTimeout(() => {
luckysheet.setRangeFormat('bg', areaMarksColor['default']) luckysheet.setRangeFormat('bg', areaMarksColor['default'])
}, 100)
} else {
// 保存本地
if (!Reflect.has(cachDelOtherSheetArea, row.sheetNum)) {
cachDelOtherSheetArea[row.sheetNum] = []
}
cachDelOtherSheetArea[row.sheetNum].push(row)
}
// 删除本地标记 locaExcelAreaMark[row.sheetNum] 对应的区域 // 删除本地标记 locaExcelAreaMark[row.sheetNum] 对应的区域
const index = locaExcelAreaMarks[row.sheetNum].findIndex( const index = locaExcelAreaMarks[row.sheetNum].findIndex(
...@@ -872,6 +335,9 @@ const delAreaMark = async (row: any) => { ...@@ -872,6 +335,9 @@ const delAreaMark = async (row: any) => {
) )
locaExcelAreaMarks[row.sheetNum].splice(index, 1) locaExcelAreaMarks[row.sheetNum].splice(index, 1)
} }
const editAreaRef = ref()
const currentAreaMark = reactive({})
const toModify = (row) => { const toModify = (row) => {
// 判断当前区域是否关联了其他区域 // 判断当前区域是否关联了其他区域
if ( if (
...@@ -882,12 +348,26 @@ const toModify = (row) => { ...@@ -882,12 +348,26 @@ const toModify = (row) => {
return ElMessage.warning('当前区域绑定与其他区域绑定了关联信息,请先删除关联信息之后再做修改!') return ElMessage.warning('当前区域绑定与其他区域绑定了关联信息,请先删除关联信息之后再做修改!')
} }
Object.assign(cachAreaMark, cloneDeep(row)) Object.assign(currentAreaMark, cloneDeep(row))
Object.assign(currentAreaMark, row) editVisible.value = true
// Object.assign(currentAttchInfo) }
const confirmEdit = async () => {
const areaData = editAreaRef.value.getAreaData()
const { data } = await editExcelArea(areaData)
if (data.code == 200) {
ElMessage.success('修改成功!')
editVisible.value = false
currentTitlesArea.value = JSON.parse(currentAreaMark.titleArea) const idx = locaExcelAreaMarks[areaData['sheetNum']].findIndex((item: any) => {
item.excelAreaId == areaData.excelAreaId
})
locaExcelAreaMarks[areaData['sheetNum']].splice(idx, 1, areaData)
// Object.assign()
} else {
return ElMessage.error(data.message)
}
} }
const queryArea = async () => { const queryArea = async () => {
const { data } = await getExcelAreaByFileId(getFileInfo.value.orderFileId) const { data } = await getExcelAreaByFileId(getFileInfo.value.orderFileId)
data.result.forEach((item: any) => locaExcelAreaMarks[item.sheetNum || 0].push(item)) data.result.forEach((item: any) => locaExcelAreaMarks[item.sheetNum || 0].push(item))
...@@ -957,7 +437,6 @@ const chooseConnect = (row: any) => { ...@@ -957,7 +437,6 @@ const chooseConnect = (row: any) => {
Object.assign(cachCurrentConnectInfo, unref(row)) Object.assign(cachCurrentConnectInfo, unref(row))
chooseVisible.value = true chooseVisible.value = true
} }
const connectConfigData = ref([]) const connectConfigData = ref([])
const beConnectSelectOptions = computed( const beConnectSelectOptions = computed(
() => () =>
...@@ -1062,21 +541,6 @@ const loadExcel = () => { ...@@ -1062,21 +541,6 @@ const loadExcel = () => {
title: exportJson.info.name, title: exportJson.info.name,
userInfo: exportJson.info.name.creator, userInfo: exportJson.info.name.creator,
hook: { hook: {
sheetMouseup: (c: any, p: any, sheet: any, status: any) => {
console.log('c,p,sheet,status-----', c, p, sheet, status)
// 选择的区域
if (sheet.luckysheet_select_save.length === 1) {
const [selected] = sheet.luckysheet_select_save
const [beginRow, endRow] = selected.row
const [beginColum, endColum] = selected.column
formState.sheetNum = +sheet.order
formState.beginColum = beginColum
formState.beginRow = beginRow
formState.endColum = endColum
formState.endRow = endRow
}
},
sheetActivate: (index: any) => { sheetActivate: (index: any) => {
const sheet = luckysheet.getSheet({ index }) const sheet = luckysheet.getSheet({ index })
nextTick(() => setSheetAreaMark(sheet)) nextTick(() => setSheetAreaMark(sheet))
...@@ -1090,7 +554,6 @@ const loadExcel = () => { ...@@ -1090,7 +554,6 @@ const loadExcel = () => {
} }
) )
} }
const setSheetAreaMark = (sheet: any) => { const setSheetAreaMark = (sheet: any) => {
if (!!isSetSheetMark.value[sheet.order]) { if (!!isSetSheetMark.value[sheet.order]) {
return return
...@@ -1176,17 +639,6 @@ const setSheetAreaMark = (sheet: any) => { ...@@ -1176,17 +639,6 @@ const setSheetAreaMark = (sheet: any) => {
} }
} }
const queryDict = async (code: string) => {
const { data } = await apiDictList({
dictCodes: code
})
areaTypeSelectOption.value = data.result[code]
}
const getAreaTypeText = (value: string) => {
const item = areaTypeSelectOption.value.find((v) => v.value == value)
return item?.label || '--'
}
const runResultData = ref([]) const runResultData = ref([])
const runResultTitle = ref([]) const runResultTitle = ref([])
const runResultVisible = ref(false) const runResultVisible = ref(false)
...@@ -1211,20 +663,23 @@ const toRun = async () => { ...@@ -1211,20 +663,23 @@ const toRun = async () => {
data.result.forEach((item) => { data.result.forEach((item) => {
item.expendData = {} item.expendData = {}
for (const key in item) { for (const key in item) {
if (typeof item[key] == 'object') { if (typeof item[key] == 'object' && key != 'expendData') {
item.expendData[key] = item[key] item.expendData[key] = item[key]
delete item[key] delete item[key]
} }
} }
}) })
console.log('data.result', data.result)
runResultData.value = data.result runResultData.value = data.result
runResultTitle.value = Object.keys(data.result[0]).filter((field) => { runResultTitle.value = filterRunDataTitle(data.result).filter((field) => {
return field != 'sortNum' && field != '数据区' && field != 'expendData' return field != 'sortNum' && field != '数据区' && field != 'expendData'
}) })
// const idx = runResultTitle.value.findIndex((v) => v == 'sortNum') // const idx = runResultTitle.value.findIndex((v) => v == 'sortNum')
// runResultTitle.value.splice(idx, 1) // runResultTitle.value.splice(idx, 1)
runResultVisible.value = true runResultVisible.value = true
console.log('runResultData.value', runResultData.value)
} catch { } catch {
nextTick(() => { nextTick(() => {
// Loading should be closed asynchronously // Loading should be closed asynchronously
...@@ -1232,10 +687,21 @@ const toRun = async () => { ...@@ -1232,10 +687,21 @@ const toRun = async () => {
}) })
} }
} }
const filterRunDataTitle = (data: any) => {
const titles = []
for (const row of data) {
titles.push(...Object.keys(row))
}
return Array.from(new Set(titles))
}
const filterObjKeys = (data: any) => {
return Object.keys(data)
}
onMounted(() => { onMounted(() => {
loadExcel() loadExcel()
queryConnectList() queryConnectList()
queryDict('excel_area_type')
}) })
onUnmounted(() => { onUnmounted(() => {
isFunction((window as any)?.luckysheet?.destroy) && luckysheet.destroy() isFunction((window as any)?.luckysheet?.destroy) && luckysheet.destroy()
......
...@@ -57,7 +57,11 @@ const nextStep = (index = 1, data: any) => { ...@@ -57,7 +57,11 @@ const nextStep = (index = 1, data: any) => {
break break
case 2: case 2:
if (index != -1) { if (index != -1) {
if (data.desGroups.beginRow != '') {
currentAreaMark.desGroups = [data.desGroups] currentAreaMark.desGroups = [data.desGroups]
} else {
currentAreaMark.desGroups = []
}
try { try {
// 保存 // 保存
saveArea() saveArea()
......
...@@ -46,11 +46,11 @@ ...@@ -46,11 +46,11 @@
<el-checkbox true-label="Y" false-label="N" v-model="formState.oneself"></el-checkbox> <el-checkbox true-label="Y" false-label="N" v-model="formState.oneself"></el-checkbox>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <!-- <el-col :span="12">
<el-form-item label="标题参与循环" prop="checkSelf" label-width="7em"> <el-form-item label="标题参与循环" prop="checkSelf" label-width="7em">
<el-checkbox true-label="Y" false-label="N" v-model="formState.checkSelf">是</el-checkbox> <el-checkbox true-label="Y" false-label="N" v-model="formState.checkSelf">是</el-checkbox>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col> <el-col>
<el-form-item label-width="0"> <el-form-item label-width="0">
<el-button type="primary" @click="setAreaMark('data')">标记数据区</el-button> <el-button type="primary" @click="setAreaMark('data')">标记数据区</el-button>
...@@ -72,7 +72,7 @@ import { onMounted, reactive, ref, watch } from 'vue' ...@@ -72,7 +72,7 @@ import { onMounted, reactive, ref, watch } from 'vue'
const luckysheet = (window as any).luckysheet const luckysheet = (window as any).luckysheet
const emits = defineEmits(['next']) const emits = defineEmits(['next'])
const areaTypeSelectOption = ref<Recordable>([]) const areaTypeSelectOption = ref<Recordable>([])
const formState = reactive({ const formState = reactive<Recordable>({
excelAreaNicname: '', excelAreaNicname: '',
excelAreaType: '', excelAreaType: '',
checkNumber: 1, checkNumber: 1,
...@@ -89,7 +89,7 @@ watch( ...@@ -89,7 +89,7 @@ watch(
() => formState.excelAreaType, () => formState.excelAreaType,
(val) => { (val) => {
if (val) { if (val) {
formState.excelAreaNicname = areaTypeSelectOption.value.find((v) => v.value == val).label formState.excelAreaNicname = areaTypeSelectOption.value.find((v: any) => v.value == val).label
} }
} }
) )
...@@ -100,7 +100,7 @@ const rules = reactive({ ...@@ -100,7 +100,7 @@ const rules = reactive({
excelAreaType: [{ required: true, message: '请选择区域类型!', trigger: 'change' }], excelAreaType: [{ required: true, message: '请选择区域类型!', trigger: 'change' }],
checkNumber: [ checkNumber: [
{ {
validator: (rule, value, cb) => { validator: (rule: any, value: any, cb: Function) => {
if (value <= 0) { if (value <= 0) {
cb(new Error('请输入正整数!')) cb(new Error('请输入正整数!'))
return false return false
...@@ -113,13 +113,7 @@ const rules = reactive({ ...@@ -113,13 +113,7 @@ const rules = reactive({
}) })
const resetFormState = () => { const resetFormState = () => {
// 重置字段 // 重置字段
form.value?.resetFields([ form.value?.resetFields(['excelAreaNicname', 'excelAreaType', 'checkNumber', 'oneself'])
'excelAreaNicname',
'excelAreaType',
'checkNumber',
'checkSelf',
'oneself'
])
// 清空位置信息 // 清空位置信息
Object.assign(formState, { Object.assign(formState, {
sheetNum: 0, sheetNum: 0,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment