Commit 07d14cda authored by 何远江's avatar 何远江

修改设置标题逻辑,添加附加信息设置

parent 0aa99b16
......@@ -80,5 +80,7 @@ export const authorityConfig = {
export const areaMarksColor = {
'data': '#65d0ea',
'head': '#34718d',
'default': '#ffffff'
'default': '#ffffff',
'attch': '#e6ccb2',
'attch_head': '#b08968'
}
\ No newline at end of file
import type { Recordable } from '@/types/global'
export function chatatABC(n: number) {
var orda = 'a'.charCodeAt(0)
......@@ -21,17 +23,74 @@ export function getRangetxt(row0: number, row1: number, column0: number, column1
// let column0 = range["column"][0], column1 = range["column"][1];
if (row0 == null && row1 == null) {
return chatatABC(column0) + ":" + chatatABC(column1);
return chatatABC(column0) + ':' + chatatABC(column1)
} else if (column0 == null && column1 == null) {
return row0 + 1 + ':' + (row1 + 1)
} else {
if (column0 == column1 && row0 == row1) {
return chatatABC(column0) + (row0 + 1)
} else {
return chatatABC(column0) + (row0 + 1) + ':' + chatatABC(column1) + (row1 + 1)
}
else if (column0 == null && column1 == null) {
return (row0 + 1) + ":" + (row1 + 1);
}
else {
if (column0 == column1 && row0 == row1) {
return chatatABC(column0) + (row0 + 1);
}
export function getRangeState(range: any) {
let rowLen = range.length
let columnLen = range[0].length
let isOneRow = !(rowLen > 1)
let isOneColumn = !(columnLen > 1)
return {
rowLen,
columnLen,
isOneRow,
isOneColumn
}
else {
return chatatABC(column0) + (row0 + 1) + ":" + chatatABC(column1) + (row1 + 1);
}
export function handleRangeTitle(range: any, dataArea: Recordable) {
const { isOneColumn, isOneRow, rowLen, columnLen } = getRangeState(range)
const { beginColum, beginRow, endRow, endColum, sheetNum } = dataArea
const titles: Recordable[] = []
let isVertical = false
if (rowLen - 1 === endRow - beginRow && columnLen - 1 !== endColum - beginColum) {
isVertical = true
}
/**
* 横向:以列为单位取值,多值取最后有值单元格
*
* 纵向:以行为单位,多值取最后有值单元格
*/
for (let c = 0; c < (isVertical ? rowLen : columnLen); c++) {
const title = {
title: '',
sheet: sheetNum,
row: 0,
colum: 0
}
for (let r = 0; r < (isVertical ? columnLen : rowLen); r++) {
const cell = isVertical ? range[c][r] : range[r][c]
let v = ''
// 如果获取值报错,那么断定单元格值为空,继续执行
try {
v = cell.v || cell?.ct?.s.map((itm) => itm.v).join('')
} catch {}
if (v != '') {
title.title = v.replaceAll(' ', '')
title.colum = +beginColum + (isVertical ? r : c)
title.row = +beginRow + (isVertical ? c : r)
}
// 如果有单元格合并,跳过单元格
if (cell?.mc) {
r += isVertical ? cell.mc.rs - 1 : cell.mc.cs - 1
c += isVertical ? cell.mc.cs - 1 : cell.mc.rs - 1
}
}
titles.push(title)
}
return titles
}
......@@ -49,8 +49,16 @@
</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-group>
</el-col>
</el-row>
</el-form>
......@@ -154,6 +162,40 @@
</template>
</vxe-column>
</vxe-table>
<template v-if="currentAreaMark.desGroups.length">
<p class="font-bold">附加信息</p>
<vxe-table
:data="currentAreaMark.desGroups"
@cell-click="cellClick"
border
size="mini"
max-height="200"
>
<vxe-column title="附加区域" field="area" width="120">
<template #default="{ row }">
{{ getRangetxt(row.beginRow, row.endRow, row.beginColum, row.endColum) }}
</template>
</vxe-column>
<vxe-column title="附加title" field="area">
<template #default="{ row }">
{{ row.titles[0].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>
</template>
<el-button type="primary" size="small" @click="saveAreaMark">保存</el-button>
<el-button
v-if="isEditCurrentArea"
......@@ -334,7 +376,7 @@ import {
removeExcelAreaConnect
} from '@/api/excel'
import type { Recordable } from '@/types/global'
import { getRangetxt } from '@/utils/excel'
import { getRangetxt, handleRangeTitle } from '@/utils/excel'
import type { VxeTableInstance } from 'vxe-table'
import { apiDictFindById, apiDictList } from '@/api/common'
......@@ -472,24 +514,43 @@ const currentAreaMark = reactive<Recordable>({
oneself: 'N',
checkSelf: 'N',
checkNumber: 1,
excelAreaTitle: []
excelAreaTitle: [],
desGroups: [],
titleArea: ''
})
const isEditCurrentArea = computed(() => !!currentAreaMark.excelAreaId)
const currentTitlesArea = ref<Recordable>([])
const currentAttchInfo = reactive({
sheetNum: '',
beginRow: '',
beginColum: '',
endRow: '',
titles: []
})
// 删除附加信息
const delAttchInfo = (row, index) => {
currentAreaMark.desGroups.splice(index, 1)
// 选中要删除的区域,设置颜色
luckysheet.setRangeShow({
row: [row.beginRow, row.endRow],
column: [row.beginColum, row.endColum]
})
// const currentHeadAreaData = ref([])
// watch(
// () => currentAreaMark.excelAreaTitle,
// (val) => {
// currentHeadAreaData.value = val || []
// },
// {
// deep: true
// }
// )
// const currentHeadAreaData = computed(() => currentAreaMark?.excelAreaTitle || [])
const setAreaMark = async (type: 'data' | 'head' = 'data') => {
luckysheet.setRangeFormat('bg', areaMarksColor['data'])
}
const resetAttchInfo = () => {
Object.assign(currentAttchInfo, {
sheetNum: '',
beginRow: '',
beginColum: '',
endRow: '',
titles: []
})
}
const setAreaMark = async (type: 'data' | 'head' | 'attch' | 'attch_head' = 'data') => {
if (type === 'data') {
/**
* 判断是否有未保存的区域
......@@ -541,7 +602,7 @@ const setAreaMark = async (type: 'data' | 'head' = 'data') => {
'checkSelf',
'checkNumber'
])
} else {
} else if (type === 'head') {
if (currentAreaMark.excelAreaId) {
return ElMessage.error('请先保存或取消正在修改的数据区域!')
}
......@@ -558,70 +619,61 @@ const setAreaMark = async (type: 'data' | 'head' = 'data') => {
* 判断选择的 head区域 是否在数据区域 内部
* 判断是否有重复的单元格添加,如有重复无需添加此单元格
*/
const result: Recordable[] = []
const rangeData = luckysheet.getRangeValue()
console.log('rangeData', rangeData)
const titles = handleRangeTitle(rangeData, unref(formState))
console.log('titles', titles)
// return
const { beginColum, beginRow, endColum, endRow } = formState as Recordable
const { beginColum: bc, beginRow: br, endColum: ec, endRow: er } = currentAreaMark
// 是否是纵向
let isVertical = rangeData.length > 1
// if (!isRangeSide(unref(currentAreaMark), unref(formState))) {
// return ElMessage.error('请选择区域边缘作为标题!')
// }
if (isVertical) {
for (let r = 0; r < rangeData.length; r++) {
const item = rangeData[r][0]
const title = item.v || item.ct.s.map((itm) => itm.v).join('')
result.push({
title: title.replaceAll(' ', ''),
sheet: formState.sheetNum,
row: +beginRow + r,
colum: beginColum
})
// 如果有合并的,跳过合并单元格个数
if (item.mc) {
r += item.mc.rs - 1
}
}
} else {
// // 如果只有一列,只能是头部或者尾部
for (let c = 0; c < rangeData[0].length; c++) {
const item = rangeData[0][c]
const title = item.v || item.ct.s.map((itm) => itm.v).join('')
result.push({
title: title.replaceAll(' ', ''),
sheet: formState.sheetNum,
row: beginRow,
colum: +beginColum + c
currentTitlesArea.value.push({
excelAreaId: '',
excelAreaNicname: currentAreaMark.excelAreaNicname,
sr: formState.beginRow,
sc: formState.beginColum,
er: formState.endRow,
ec: formState.endColum
})
// 如果有合并的,跳过合并单元格个数
if (item.mc) {
c += item.mc.cs - 1
}
}
}
// 清除之前的title颜色
// resetCurrentHeadArea(() => {
// luckysheet.setRangeShow({
// row: [beginRow, endRow],
// column: [beginColum, endColum]
// })
// // currentAreaMark.excelAreaTitle = result
// })
// 合并组装的表头区域数据
if (currentAreaMark.excelAreaTitle?.length > 0) {
const arr = [...result, ...unref(currentAreaMark.excelAreaTitle)]
const arr = [...titles, ...unref(currentAreaMark.excelAreaTitle)]
// 合并,去重
currentAreaMark.excelAreaTitle = uniqArrayObject(arr)
} else {
currentAreaMark.excelAreaTitle = result
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,
titles: []
}
Object.assign(currentAttchInfo, area)
} else if (type === 'attch_head') {
// 验证是否在附加区域
// 验证是否设置附加区域
if (currentAttchInfo.beginRow == '') {
return ElMessage.error('请先设置附加信息区域!')
}
const res = {}
const rangeData = luckysheet.getRangeValue()
const titles = handleRangeTitle(rangeData, unref(currentAttchInfo))
Object.assign(res, currentAttchInfo, { titles })
// 设置完title 直接添加
currentAreaMark.desGroups.push(res)
// 重置附加信息区域
resetAttchInfo()
}
function uniqArrayObject(arr = []) {
......@@ -649,28 +701,6 @@ const setAreaMark = async (type: 'data' | 'head' = 'data') => {
}, 100)
}
const isRangeSide = (range, insideRage) => {
const { beginColum, beginRow, endColum, endRow } = range
const { beginColum: bc, beginRow: br, endColum: ec, endRow: er } = insideRage
const sides = []
// 上
sides.push({ br: beginRow, er: beginRow, bc: beginColum, ec: endColum })
// 右
sides.push({ br: beginRow, er: endRow, bc: endColum, ec: endColum })
//下
sides.push({ br: endRow, er: endRow, bc: beginColum, ec: endColum })
// 左
sides.push({ br: beginRow, er: endRow, bc: beginColum, ec: beginColum })
const side = { br, bc, er, ec }
console.log('isRangeside', side, sides)
return !!sides.filter((item) => {
return item.bc == bc && item.br == br && item.ec == ec && item.er == er
}).length
}
const resetCurrentAreaState = (isedit: boolean = false) => {
// 重置 其他属性
const tmp: Recordable = {
......@@ -682,11 +712,14 @@ const resetCurrentAreaState = (isedit: boolean = false) => {
excelAreaType: '',
excelAreaNicname: '',
excelAreaTitle: [],
desGroups: [],
titleArea: '',
oneself: 'N',
checkSelf: 'N',
checkNumber: ''
}
isedit && (tmp.excelAreaId = '')
currentTitlesArea.value = []
Object.assign(currentAreaMark, tmp)
}
const resetCurrentArea = (fn?: Function) => {
......@@ -706,27 +739,10 @@ const resetCurrentArea = (fn?: Function) => {
}
)
}
const resetCurrentHeadArea = (cb: any) => {
// 清除标题区域颜色 -> 设置成数据区域颜色
luckysheet.setRangeShow(
{
row: [currentAreaMark.beginRow, currentAreaMark.endRow],
column: [currentAreaMark.beginColum, currentAreaMark.endColum]
},
{
show: false,
success: () => {
luckysheet.setRangeFormat('bg', areaMarksColor['data'])
// 删除 excelAreaTitle 属性
delete currentAreaMark.excelAreaTitle
cb && cb()
}
}
)
}
const saveAreaMark = async () => {
currentAreaMark.fileId = getFileInfo.value.orderFileId
currentAreaMark.titleArea = JSON.stringify(unref(currentTitlesArea))
// 如果有id 调用修改,否则调用新增
const isEdit = !!currentAreaMark.excelAreaId
const { data } = isEdit
......@@ -743,6 +759,7 @@ const saveAreaMark = async () => {
}
ElMessage.success('操作成功!')
resetCurrentAreaState(true)
resetAttchInfo()
}
const cachAreaMark = reactive<Recordable>({})
......@@ -802,15 +819,13 @@ const toModify = (row) => {
Object.assign(cachAreaMark, cloneDeep(row))
Object.assign(currentAreaMark, row)
currentTitlesArea.value = JSON.parse(currentAreaMark.titleArea)
}
const queryArea = async () => {
const { data } = await getExcelAreaByFileId(getFileInfo.value.orderFileId)
data.result.forEach((item: any) => locaExcelAreaMarks[item.sheetNum || 0].push(item))
}
const toModifyConnect = (row: any) => {
Object.assign(currentConnectInfo, row)
connectVisible.value = true
}
const confirmConnect = () => {
/**
* 1. 验证是否选择了要关联的title
......@@ -998,12 +1013,25 @@ const loadExcel = () => {
},
sheetActivate: (index: any) => {
const sheet = luckysheet.getSheet({ index })
setSheetAreaMark(sheet)
},
workbookCreateAfter: () => {
const sheet = luckysheet.getSheet()
setSheetAreaMark(sheet)
}
}
})
}
)
}
const setSheetAreaMark = (sheet: any) => {
if (!!isSetSheetMark.value[sheet.order]) {
return
}
// 修改当前sheet 已经标记
isSetSheetMark.value[sheet.order] = true
console.log(isSetSheetMark, locaExcelAreaMarks)
// 判断本地是否记有第一个sheet页的标
if (locaExcelAreaMarks[sheet.order].length) {
locaExcelAreaMarks[sheet.order].forEach((item: any) => {
// 设置数据区标记
......@@ -1020,66 +1048,57 @@ const loadExcel = () => {
)
}, 50)
if (item.excelAreaTitle.length) {
item.excelAreaTitle.forEach((cell: any) => {
// 设置数据区head标记
const areas = JSON.parse(item.titleArea)
areas.forEach((area: any) => {
setTimeout(() => {
luckysheet.menuButton.customUpdateFormat(
null,
'bg',
areaMarksColor['head'],
cell.row,
cell.row,
cell.colum,
cell.colum,
area.sr,
area.er,
area.sc,
area.ec,
false
)
}, 50)
})
}
})
}
},
workbookCreateAfter: () => {
// 修改当前sheet 已经标记
isSetSheetMark.value[0] = true
// 判断本地是否有第一个sheet页的标记
if (locaExcelAreaMarks[0].length) {
locaExcelAreaMarks[0].forEach((item: any) => {
// 设置数据区标记
if (item.desGroups.length) {
item.desGroups.forEach((area) => {
setTimeout(() => {
luckysheet.menuButton.customUpdateFormat(
null,
'bg',
areaMarksColor['data'],
item.beginRow,
item.endRow,
item.beginColum,
item.endColum,
areaMarksColor['attch'],
area.beginRow,
area.endRow,
area.beginColum,
area.endColum,
false
)
if (item.excelAreaTitle.length) {
item.excelAreaTitle.forEach((cell: any) => {
// 设置数据区head标记
// luckysheet.setCellValue()
}, 50)
if (area.titles.length) {
area.titles.forEach((a) => {
setTimeout(() => {
luckysheet.menuButton.customUpdateFormat(
null,
'bg',
areaMarksColor['head'],
cell.row,
cell.row,
cell.colum,
cell.colum,
areaMarksColor['attch_head'],
a.row,
a.row,
a.colum,
a.colum,
false
)
}, 50)
})
}
})
}
}
}
})
}
)
}
const queryDict = async (code: string) => {
......
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