update at 2026-02-13 23:17:10
This commit is contained in:
@@ -232,6 +232,41 @@ function buildColumnSelectedMap(indices) {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为三组列选择 UI 构造可直接渲染的数据,避免模板层做复杂表达式计算。
|
||||||
|
*/
|
||||||
|
function buildColumnRenderRows(headers, sourceDataColumn, sourceDescMap, targetDescMap) {
|
||||||
|
const normalizedHeaders = Array.isArray(headers) ? headers : [];
|
||||||
|
const sourceRows = [];
|
||||||
|
const sourceDescRows = [];
|
||||||
|
const targetDescRows = [];
|
||||||
|
|
||||||
|
normalizedHeaders.forEach((header, index) => {
|
||||||
|
const label = String(header || '');
|
||||||
|
sourceRows.push({
|
||||||
|
index,
|
||||||
|
label,
|
||||||
|
selected: sourceDataColumn === index
|
||||||
|
});
|
||||||
|
sourceDescRows.push({
|
||||||
|
index,
|
||||||
|
label,
|
||||||
|
checked: !!(sourceDescMap && sourceDescMap[index])
|
||||||
|
});
|
||||||
|
targetDescRows.push({
|
||||||
|
index,
|
||||||
|
label,
|
||||||
|
checked: !!(targetDescMap && targetDescMap[index])
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
sourceDataRows: sourceRows,
|
||||||
|
sourceDescRows,
|
||||||
|
targetDescRows
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一错误文案:
|
* 统一错误文案:
|
||||||
* - xlsx 解析能力缺失时,固定提示用户去“构建 npm”
|
* - xlsx 解析能力缺失时,固定提示用户去“构建 npm”
|
||||||
@@ -543,6 +578,9 @@ Page({
|
|||||||
targetDescriptionColumns: [],
|
targetDescriptionColumns: [],
|
||||||
sourceDescSelectedMap: {},
|
sourceDescSelectedMap: {},
|
||||||
targetDescSelectedMap: {},
|
targetDescSelectedMap: {},
|
||||||
|
sourceDataRows: [],
|
||||||
|
sourceDescRows: [],
|
||||||
|
targetDescRows: [],
|
||||||
sectionVisibleSourceData: true,
|
sectionVisibleSourceData: true,
|
||||||
sectionVisibleSourceDesc: true,
|
sectionVisibleSourceDesc: true,
|
||||||
sectionVisibleTargetDesc: true,
|
sectionVisibleTargetDesc: true,
|
||||||
@@ -965,7 +1003,13 @@ Page({
|
|||||||
sourceDescriptionColumns,
|
sourceDescriptionColumns,
|
||||||
targetDescriptionColumns,
|
targetDescriptionColumns,
|
||||||
sourceDescSelectedMap: buildColumnSelectedMap(sourceDescriptionColumns),
|
sourceDescSelectedMap: buildColumnSelectedMap(sourceDescriptionColumns),
|
||||||
targetDescSelectedMap: buildColumnSelectedMap(targetDescriptionColumns)
|
targetDescSelectedMap: buildColumnSelectedMap(targetDescriptionColumns),
|
||||||
|
...buildColumnRenderRows(
|
||||||
|
headers.length > 0 ? headers : [],
|
||||||
|
sourceDataColumn,
|
||||||
|
buildColumnSelectedMap(sourceDescriptionColumns),
|
||||||
|
buildColumnSelectedMap(targetDescriptionColumns)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.rebuildSankey();
|
this.rebuildSankey();
|
||||||
@@ -975,9 +1019,16 @@ Page({
|
|||||||
|
|
||||||
onSelectSourceData(e) {
|
onSelectSourceData(e) {
|
||||||
const index = Number(e.currentTarget.dataset.index);
|
const index = Number(e.currentTarget.dataset.index);
|
||||||
|
const safeSourceDataColumn = Number.isNaN(index) ? null : index;
|
||||||
this.setData(
|
this.setData(
|
||||||
{
|
{
|
||||||
sourceDataColumn: Number.isNaN(index) ? null : index
|
sourceDataColumn: safeSourceDataColumn,
|
||||||
|
...buildColumnRenderRows(
|
||||||
|
this.data.columnHeaders || [],
|
||||||
|
safeSourceDataColumn,
|
||||||
|
this.data.sourceDescSelectedMap || {},
|
||||||
|
this.data.targetDescSelectedMap || {}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.rebuildSankey();
|
this.rebuildSankey();
|
||||||
@@ -995,10 +1046,17 @@ Page({
|
|||||||
const next = exists
|
const next = exists
|
||||||
? current.filter((item) => item !== index)
|
? current.filter((item) => item !== index)
|
||||||
: normalizeColumnIndexArray(current.concat(index));
|
: normalizeColumnIndexArray(current.concat(index));
|
||||||
|
const nextSourceDescSelectedMap = buildColumnSelectedMap(next);
|
||||||
this.setData(
|
this.setData(
|
||||||
{
|
{
|
||||||
sourceDescriptionColumns: next,
|
sourceDescriptionColumns: next,
|
||||||
sourceDescSelectedMap: buildColumnSelectedMap(next)
|
sourceDescSelectedMap: nextSourceDescSelectedMap,
|
||||||
|
...buildColumnRenderRows(
|
||||||
|
this.data.columnHeaders || [],
|
||||||
|
this.data.sourceDataColumn,
|
||||||
|
nextSourceDescSelectedMap,
|
||||||
|
this.data.targetDescSelectedMap || {}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.rebuildSankey();
|
this.rebuildSankey();
|
||||||
@@ -1016,10 +1074,17 @@ Page({
|
|||||||
const next = exists
|
const next = exists
|
||||||
? current.filter((item) => item !== index)
|
? current.filter((item) => item !== index)
|
||||||
: normalizeColumnIndexArray(current.concat(index));
|
: normalizeColumnIndexArray(current.concat(index));
|
||||||
|
const nextTargetDescSelectedMap = buildColumnSelectedMap(next);
|
||||||
this.setData(
|
this.setData(
|
||||||
{
|
{
|
||||||
targetDescriptionColumns: next,
|
targetDescriptionColumns: next,
|
||||||
targetDescSelectedMap: buildColumnSelectedMap(next)
|
targetDescSelectedMap: nextTargetDescSelectedMap,
|
||||||
|
...buildColumnRenderRows(
|
||||||
|
this.data.columnHeaders || [],
|
||||||
|
this.data.sourceDataColumn,
|
||||||
|
this.data.sourceDescSelectedMap || {},
|
||||||
|
nextTargetDescSelectedMap
|
||||||
|
)
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.rebuildSankey();
|
this.rebuildSankey();
|
||||||
|
|||||||
@@ -106,12 +106,12 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="column-list" wx:if="{{sectionVisibleSourceData}}">
|
<view class="column-list" wx:if="{{sectionVisibleSourceData}}">
|
||||||
<view class="column-list-line" />
|
<view class="column-list-line" />
|
||||||
<view class="row" wx:for="{{columnHeaders}}" wx:key="index" data-index="{{index}}" bindtap="onSelectSourceData">
|
<view class="row" wx:for="{{sourceDataRows}}" wx:key="index" data-index="{{item.index}}" bindtap="onSelectSourceData">
|
||||||
<view class="row-link" />
|
<view class="row-link" />
|
||||||
<image src="../../assets/icons/data.svg" mode="aspectFit" />
|
<image src="../../assets/icons/data.svg" mode="aspectFit" />
|
||||||
<text class="label">{{item}}</text>
|
<text class="label">{{item.label}}</text>
|
||||||
<image
|
<image
|
||||||
src="{{sourceDataColumn === index ? '../../assets/icons/radiobutton.svg' : '../../assets/icons/radiobutton-no.svg'}}"
|
src="{{item.selected ? '../../assets/icons/radiobutton.svg' : '../../assets/icons/radiobutton-no.svg'}}"
|
||||||
mode="aspectFit"
|
mode="aspectFit"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
@@ -128,12 +128,12 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="column-list" wx:if="{{sectionVisibleSourceDesc}}">
|
<view class="column-list" wx:if="{{sectionVisibleSourceDesc}}">
|
||||||
<view class="column-list-line" />
|
<view class="column-list-line" />
|
||||||
<view class="row" wx:for="{{columnHeaders}}" wx:key="index" data-index="{{index}}" bindtap="onToggleSourceDesc">
|
<view class="row" wx:for="{{sourceDescRows}}" wx:key="index" data-index="{{item.index}}" bindtap="onToggleSourceDesc">
|
||||||
<view class="row-link" />
|
<view class="row-link" />
|
||||||
<image src="../../assets/icons/description.svg" mode="aspectFit" />
|
<image src="../../assets/icons/description.svg" mode="aspectFit" />
|
||||||
<text class="label">{{item}}</text>
|
<text class="label">{{item.label}}</text>
|
||||||
<image
|
<image
|
||||||
src="{{sourceDescSelectedMap[index] ? '../../assets/icons/checkbox.svg' : '../../assets/icons/checkbox-no.svg'}}"
|
src="{{item.checked ? '../../assets/icons/checkbox.svg' : '../../assets/icons/checkbox-no.svg'}}"
|
||||||
mode="aspectFit"
|
mode="aspectFit"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
@@ -150,12 +150,12 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="column-list" wx:if="{{sectionVisibleTargetDesc}}">
|
<view class="column-list" wx:if="{{sectionVisibleTargetDesc}}">
|
||||||
<view class="column-list-line" />
|
<view class="column-list-line" />
|
||||||
<view class="row" wx:for="{{columnHeaders}}" wx:key="index" data-index="{{index}}" bindtap="onToggleTargetDesc">
|
<view class="row" wx:for="{{targetDescRows}}" wx:key="index" data-index="{{item.index}}" bindtap="onToggleTargetDesc">
|
||||||
<view class="row-link" />
|
<view class="row-link" />
|
||||||
<image src="../../assets/icons/description.svg" mode="aspectFit" />
|
<image src="../../assets/icons/description.svg" mode="aspectFit" />
|
||||||
<text class="label">{{item}}</text>
|
<text class="label">{{item.label}}</text>
|
||||||
<image
|
<image
|
||||||
src="{{targetDescSelectedMap[index] ? '../../assets/icons/checkbox.svg' : '../../assets/icons/checkbox-no.svg'}}"
|
src="{{item.checked ? '../../assets/icons/checkbox.svg' : '../../assets/icons/checkbox-no.svg'}}"
|
||||||
mode="aspectFit"
|
mode="aspectFit"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
Reference in New Issue
Block a user