Commit 328a4f11 authored by 何远江's avatar 何远江

添加多字段映射,接口对接

parent 5ea0d8dc
......@@ -88,3 +88,75 @@ export const useExcelStore = defineStore('excelStore', {
}
}
})
export const useExcelChangeStore = defineStore('excelChangeStore', {
state: () => ({
allMapConfigs: {}, // 缓存当前这条数据的所有映射关系
scriptList: [], // 脚本
orderFieldList: [], // 订单字段
variableField: [], // 后端获取的变量字段
usedFieldList: [] // 当前编辑column使用过的映射字段
}),
getters: {
getAllMapConfigs(): any {
return this.allMapConfigs
},
getScriptList(): any {
return this.scriptList
},
getEffectConfigs(): any[] {
const currenttitle = this.usedFieldList[0]?.title || ''
const res: any = [...this.usedFieldList]
for (const key in this.allMapConfigs) {
if (key != currenttitle) {
if (this.allMapConfigs[key].orderFiledConfs.length) {
res.push(...this.allMapConfigs[key].orderFiledConfs)
}
}
}
return res.map((item) => item.mapField)
},
getAllFields(): any {
return [
{
label: '普通字段',
options: this.orderFieldList.map((item) => {
this.getEffectConfigs.includes(item.filedName)
? (item.disabled = true)
: (item.disabled = false)
return item
})
},
{
label: '变量字段',
options: this.variableField.map((item) => {
this.getEffectConfigs.includes(item.filedName)
? (item.disabled = true)
: (item.disabled = false)
return item
})
}
]
}
},
actions: {
setAllMapConfigs(config: any) {
this.allMapConfigs = config
},
setSingleFieldMap(config: any) {
this.allMapConfigs[config.title] = config
},
setScriptList(list: any) {
this.scriptList = list
},
setOrderFieldList(list: any) {
this.orderFieldList = list
},
setVariableField(list: any) {
this.variableField = list
},
setUsedFieldList(list: any) {
this.usedFieldList = list
}
}
})
......@@ -201,17 +201,23 @@ export function filterRunData(data: any, config: boolean = false) {
// 映射字段配置生成
const configs: Recordable = {}
const temConf = {
// title: '',
// content: '',
// mapField: '',
// scriptName: '',
// groupTitle: '',
// templateFileId: '',
// excelOrderFiledConfId: '',
// params: {},
// orderFiled: {},
excelOrderFiledConfId:'',
title: '',
content: '',
mapField: '',
scriptName: '',
groupTitle: '',
templateFileId: '',
excelOrderFiledConfId: '',
params: {},
orderFiled: {}
orderFiledConfs: [],
templateFileId: ''
}
console.log(data, 'data-----')
data.forEach((row: any) => {
const rw: Recordable = {}
row.order.forEach((itm: any) => {
......@@ -239,6 +245,8 @@ export function filterRunData(data: any, config: boolean = false) {
res.push(rw)
})
console.log('----res', res)
return {
res,
titles: [...titles],
......
......@@ -113,7 +113,10 @@
<vxe-column :title="item" :field="item" width="200">
<template #header>
<div class="header-cell" @click="(e) => showPopover(e, item)">
<span>{{ allMapConfigs[item]?.orderFiled.fliedTitle || '' }}</span>
<template v-for="cf in getAllMapConfigs[item].orderFiledConfs">
<span>{{ cf.orderFiled.fliedTitle }}</span>
</template>
<!-- <span>{{ allMapConfigs[item]?.orderFiled.fliedTitle || '' }}</span> -->
<el-icon v-if="currentRow.status == 'un_convert'"><Setting /></el-icon>
</div>
</template>
......@@ -133,73 +136,13 @@
width="360"
transition=""
>
<el-form size="small" label-width="7em" inline :model="currentConfigColumn">
<el-row>
<el-col :span="24">
<el-form-item label="对应字段" prop="mapField">
<el-select
v-model="currentConfigColumn.mapField"
style="width: 220px"
filterable
placeholder="请选择"
:teleported="false"
clearable
>
<el-option-group v-for="group in allFields" :key="group.label" :label="group.label">
<el-option
v-for="item in group.options"
:key="item.filedName"
:label="item.fliedTitle"
:value="item.filedName"
:disabled="!!item.disabled"
<ConfigForm
:title="currentConfigTitle"
:current-conf="currentColConf"
:current-row="currentRow"
@cancel="popoverVisible = false"
@confirm="confirmConfig"
/>
</el-option-group>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="currentConfigColumn.mapField">
<el-form-item label="脚本">
<el-select
style="width: 220px"
v-model="currentConfigColumn.scriptName"
:teleported="false"
clearable
>
<el-option
v-for="item in scriptList"
:key="item.srciptName"
:value="item.srciptName"
:label="item.srciptName"
></el-option>
</el-select>
</el-form-item>
</el-col>
<template v-for="params in currentScriptParamsList" :key="params.fliedTitle">
<el-col :span="24">
<el-form-item :label="params.fliedTitle">
<el-input v-model="scriptPs[params.filedName]" style="width: 220px" />
</el-form-item>
</el-col>
</template>
<el-col :span="24" v-if="currentConfigColumn.scriptName && !!currentConfigColumn.content">
<el-form-item label="脚本语句">
<el-input
style="width: 220px"
rows="3"
disabled
type="textarea"
v-model.trim="currentConfigColumn.content"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button type="primary" @click="confirmConfig">确认</el-button>
<el-button type="primary" @click="popoverVisible = false">取消</el-button>
</el-form-item>
</el-form>
</el-popover>
<template #footer>
......@@ -212,7 +155,7 @@
</template>
<script lang="ts" setup>
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { onMounted, reactive, ref, watch } from 'vue'
import { Setting } from '@element-plus/icons-vue'
import { cloneDeep } from 'lodash-es'
import {
......@@ -224,14 +167,18 @@ import {
getConfByExcelOrderId,
saveConfExcelFileOrderPage
} from '@/api/order'
import { ElMessage, ElMessageBox, ClickOutside as vClickOutside } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { VxeTableInstance } from 'vxe-table'
import type { Recordable } from '@/types/global'
import { filterRunData } from '@/utils/excel'
import { apiGetOrderField, apiGetScript, getVariableField } from '@/api/excel'
import { apiDictList } from '@/api/common'
import ConfigForm from './components/ConfigForm.vue'
import { useExcelChangeStore } from '@/stores/excel'
import { storeToRefs } from 'pinia'
const loading = ref(false)
const excelChangeStore = useExcelChangeStore()
const { getAllMapConfigs } = storeToRefs(excelChangeStore)
/**查询参数 */
const queryParams = reactive({
status: '',
......@@ -242,32 +189,14 @@ const queryParams = reactive({
order: 'desc'
})
/**所有列映射配置 */
const allMapConfigs = ref<Recordable>({})
const effectConfigs = computed(() => {
return Object.values(allMapConfigs.value).filter((item) => item.title != '')
})
/**当前表单映射字段配置 */
const currentConfigColumn = reactive({
title: '',
content: '',
mapField: '',
scriptName: '',
groupTitle: '',
templateFileId: '',
const currentColConf = reactive({
excelOrderFiledConfId: '',
params: {},
orderFiled: {}
title: '',
orderFiledConfs: [],
templateFileId: ''
})
const currentConfigTitle = ref('')
const scriptPs = ref<Recordable>({})
/**所有脚本 */
const scriptList = ref<Recordable[]>([])
/**所有映射字段 */
const orderFieldList = ref<Recordable[]>([])
const variableField = ref([])
const xTable = ref<VxeTableInstance>()
const tableData = ref([])
/**当前选择行 */
......@@ -291,16 +220,30 @@ const queryDict = async (code: string) => {
const popoverRef = ref()
const buttonRef = ref()
const popoverVisible = ref(false)
const showPopover = (e: any, title: string, groupTitle: string = '') => {
const showPopover = (e: any, title: string) => {
if (currentRow.status != 'un_convert') {
return
}
buttonRef.value = e.target
const t = groupTitle ? `${groupTitle}-${title}` : title
// 设置标题
currentConfigTitle.value = t
currentConfigTitle.value = title
Object.assign(currentConfigColumn, { ...allMapConfigs.value[t], title, groupTitle })
const hasConf = !!getAllMapConfigs.value[title].orderFiledConfs.length
const conf = hasConf
? getAllMapConfigs.value[title]
: {
excelOrderFiledConfId: '',
title,
orderFiledConfs: [
{
mapField: '',
orderFiled: {},
scripts: []
}
],
templateFileId: currentRow.templateFileId
}
Object.assign(currentColConf, conf)
// 打开popover
popoverVisible.value = true
}
......@@ -311,122 +254,17 @@ watch([detailVisible, popoverVisible], (val) => {
if (val.includes(false)) {
// 解决关闭弹窗之后,popover未关闭情况
popoverVisible.value = false
// 重置表单
resetConfigForm()
}
})
/**监听currentConfigColumn.mapField字段,重置/设置 orderFiled */
watch(
() => currentConfigColumn.mapField,
(val) => {
// 如果有值设置 currentConfigColumn.orderFiled字段
if (val) {
let item = orderFieldList.value.find((v) => v.filedName == val)
if (!item) {
item = variableField.value.find((v) => v.filedName == val)
}
Reflect.set(currentConfigColumn, 'orderFiled', item)
} else {
Reflect.set(currentConfigColumn, 'orderFiled', {})
Reflect.set(currentConfigColumn, 'scriptName', '')
Reflect.set(currentConfigColumn, 'content', '')
}
}
)
const allFields = computed(() => {
return [
{
label: '普通字段',
options: orderFieldList.value.map((item) => {
return {
...item,
disabled: effectConfigs.value.some((v) => v.mapField == item.filedName)
}
/** 确认字段映射及脚本的配置 */
const confirmConfig = (configList: any) => {
excelChangeStore.setSingleFieldMap({
...currentColConf,
orderFiledConfs: cloneDeep(configList.filter((v) => !!v.mapField))
})
},
{
label: '变量字段',
options: variableField.value.map((item) => {
return {
...item,
disabled: effectConfigs.value.some((v) => v.mapField == item.filedName)
}
})
}
]
})
/**重置popover配置表单 */
const resetConfigForm = () => {
Object.assign(currentConfigColumn, {
title: '',
content: '',
mapField: '',
scriptName: '',
groupTitle: '',
templateFileId: '',
excelOrderFiledConfId: ''
})
}
/** 脚本参数List */
const currentScriptParamsList = computed(() => {
const item: any = scriptList.value.find((v) => v.srciptName == currentConfigColumn.scriptName)
Reflect.set(currentConfigColumn, 'content', item?.scriptContent || '')
// 生成脚本参数表单
gScriptPs(item?.paramsName)
return item?.paramsName != null ? item.paramsName : []
})
/**通过选中的脚本生成脚本配置表单 */
const gScriptPs = (scriptNames: null | Recordable[] | undefined) => {
// 如果没有配置参数,清空脚本表单
if (scriptNames == null && scriptNames == undefined) {
scriptPs.value = {}
} else {
// 查询是否有已经设置过的值
const { title, groupTitle } = currentConfigColumn
const t = groupTitle ? `${groupTitle}__${title}` : title
const params = allMapConfigs.value[t].params
scriptNames.forEach((item) => {
Reflect.set(scriptPs.value, item.filedName, params[item.filedName] || '')
})
}
}
/** 保存字段映射及脚本的配置 */
const confirmConfig = () => {
// 合并脚本参数
Reflect.set(currentConfigColumn, 'params', scriptPs.value)
Reflect.set(currentConfigColumn, 'templateFileId', currentRow.templateFileId)
// 处理标题
const { title, groupTitle } = currentConfigColumn
// 保存本地配置
title && Reflect.set(allMapConfigs.value, title, cloneDeep(currentConfigColumn))
// 关闭popover
popoverVisible.value = false
console.log('allMapConfigs.value', allMapConfigs.value)
}
const getScriptList = async () => {
const { data } = await apiGetScript()
scriptList.value = data.result
}
const getOrderFields = async () => {
const { data } = await apiGetOrderField()
orderFieldList.value = data.result
}
const getOrderVariableField = async () => {
const { data } = await getVariableField(currentRow.excelOrderId)
if (data.code != 200) {
ElMessage.warning(data.message)
}
variableField.value = data.result || []
}
/**确认解析/转换的订单的状态 */
......@@ -465,13 +303,9 @@ const confirmOrderStatus = async (row: any) => {
const saveOrderField = async () => {
const params = {
templateFileId: currentRow.templateFileId,
confs: Object.values(allMapConfigs.value).filter((v) => {
if (v.title !== '') {
v.templateFileId = currentRow.templateFileId
return true
}
return false
})
confs: Object.values(getAllMapConfigs.value).filter(
(v) => v.title !== '' && !!v.orderFiledConfs.length
)
}
saveConfExcelFileOrderPage(params).then(({ data }) => {
......@@ -501,30 +335,13 @@ const confirmChange = async (row) => {
}
const toDetail = async (row: any) => {
allMapConfigs.value = {}
Object.assign(currentRow, row)
const { res, titles, configs } = filterRunData(row.orders, true)
await getOrderVariableField()
const { data } = await getConfByExcelOrderId(row.excelOrderId)
if (data.result.length) {
const tmp = {
title: '',
content: '',
mapField: '',
scriptName: '',
groupTitle: '',
templateFileId: '',
excelOrderFiledConfId: '',
params: {},
orderFiled: {}
}
data.result.forEach((item: any) => {
item.params == null && (item.params = {})
item.orderFiled == null && (item.orderFiled = {})
configs[item.title] = Object.assign({}, tmp, item)
data.result?.forEach((item: any) => {
configs[item.title] = item
})
}
// 排除通过循环不显示的column
const excludeTitles = ['sortNum', '数据区', 'expendData']
detailTable.value = res
......@@ -535,13 +352,7 @@ const toDetail = async (row: any) => {
Reflect.deleteProperty(configs, key)
})
Object.assign(allMapConfigs.value, configs)
console.log('allMapConfigs.value', allMapConfigs.value)
}
const filterObjKeys = (data: any) => {
return Object.keys(data).filter((v) => v !== '_X_ROW_KEY')
excelChangeStore.setAllMapConfigs(configs)
}
/**批量删除行 */
......@@ -570,8 +381,6 @@ const onQuery = async () => {
onMounted(() => {
onQuery()
getOrderFields()
getScriptList()
queryDict('excel_order_status')
})
</script>
......
<template>
<!-- 字段映射设置 -->
<el-col>
<el-form-item label="对应字段" prop="mapField">
<el-select
v-model="item.mapField"
style="width: 220px"
filterable
placeholder="请选择"
@change="mapFieldChange"
clearable
>
<el-option-group v-for="group in getAllFields" :key="group.label" :label="group.label">
<el-option
v-for="item in group.options"
:key="item.filedName"
:label="item.fliedTitle"
:value="item.filedName"
:disabled="!!item.disabled"
/>
</el-option-group>
</el-select>
<el-button v-if="props.index != 0" circle type="danger" @click="emits('remove', props.index)"
><el-icon><CircleClose /></el-icon
></el-button>
</el-form-item>
</el-col>
<!-- 脚本设置 -->
<el-col :span="24" v-if="item.mapField">
<template v-for="(sitem, idx) in item.scripts">
<el-form-item :label="'脚本' + (idx ? idx + 1 : '')">
<el-row>
<el-col>
<el-select
style="width: 220px"
v-model="sitem.scriptName"
@change="(e) => scriptChange(sitem, e)"
clearable
>
<el-option
v-for="item in getScriptList"
:key="item.srciptName"
:value="item.srciptName"
:label="item.srciptName"
></el-option>
</el-select>
<span>
<el-button v-if="idx == 0" @click="addScript" type="primary" circle
><el-icon><Plus /></el-icon
></el-button>
<el-button v-if="idx != 0" @click="removeScript(idx)" type="danger" circle
><el-icon><Minus /></el-icon
></el-button>
</span>
</el-col>
<el-col v-if="sitem.scriptName" class="mt-1">
<el-input
type="textarea"
style="width: 220px"
disabled
rows="3"
v-model="sitem.content"
></el-input>
</el-col>
</el-row>
</el-form-item>
</template>
</el-col>
</template>
<script lang="ts" setup>
import { useExcelChangeStore } from '@/stores/excel'
import { Plus, Minus, CircleClose } from '@element-plus/icons-vue'
import { storeToRefs } from 'pinia'
import { watch } from 'vue'
const props = defineProps<{ item?: any; index: number }>()
const emits = defineEmits(['remove'])
const excelChangeStore = useExcelChangeStore()
const { getAllFields, getScriptList } = storeToRefs(excelChangeStore)
const scriptChange = (sitem, e) => {
if (e) {
sitem.content = getScriptList.value.find((item) => item.srciptName == e)?.scriptContent
} else {
sitem.content = ''
}
}
const mapFieldChange = (e) => {
if (e) {
getAllFields.value.some((items) => {
return items.options.some((item) => {
if (item.filedName == e) {
props.item.orderFiled = item
return true
}
return false
})
})
} else {
props.item.orderFiled = null
}
}
const removeScript = (index: number) => {
props.item.scripts.splice(index, 1)
}
const addScript = () => {
props.item.scripts.push({
content: '',
scriptName: ''
})
}
watch(
() => props.item.mapField,
(val) => {
// 如果有值,添加脚本
if (val && props.item.scripts.length == 0) {
props.item.scripts.push({
content: '',
scriptName: ''
})
}
}
)
</script>
<style lang="scss" scoped></style>
<template>
<div>
123
</div>
<el-scrollbar max-height="350px">
<el-form size="small" label-width="60px">
<template v-for="(item, index) in configList" :key="item.time">
<ConfigFormItem :item="item" :index="index" @remove="removeMapField" />
<el-divider v-if="index + 1 != configList.length">{{ index + 2 }}映射字段 </el-divider>
</template>
</el-form>
</el-scrollbar>
<el-row type="flex" justify="center">
<el-button size="small" type="primary" @click="emits('confirm', configList)">确认</el-button>
<el-button size="small" type="primary" @click="addFormItem">添加字段</el-button>
<el-button size="small" @click="emits('cancel')">取消</el-button>
</el-row>
</template>
<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import type { Recordable } from '@/types/global'
import ConfigFormItem from './ConfigFormItem.vue'
import { cloneDeep } from 'loadsh'
import { ElMessage } from 'element-plus'
import { apiGetOrderField, apiGetScript, getVariableField } from '@/api/excel'
import { useExcelChangeStore } from '@/stores/excel'
/**
* 数据结构
* {templateFileId: '', confs: [{title: '',orderFiledConfs: [{mapField: '',orderFiled: {}, scripts: {}}], templateFileId: ''}]}
*/
const props = defineProps<{ title: string; currentRow: Recordable; currentConf: Recordable }>()
const emits = defineEmits(['cancel', 'confirm'])
const excelChangeStore = useExcelChangeStore()
const configList = ref<Recordable[]>([])
const getOrderVariableField = async () => {
const { data } = await getVariableField(props.currentRow.excelOrderId)
if (data.code != 200) {
ElMessage.warning(data.message)
}
excelChangeStore.setVariableField(data.result || [])
}
// 添加映射字段表单对象
const addFormItem = () => {
configList.value.push({
time: Date.now(),
mapField: '',
orderFiled: {},
scripts: []
})
}
const removeMapField = (index: number) => {
configList.value.splice(index, 1)
}
const getScriptList = async () => {
const { data } = await apiGetScript()
excelChangeStore.setScriptList(data.result)
}
const getOrderFields = async () => {
const { data } = await apiGetOrderField()
excelChangeStore.setOrderFieldList(data.result)
}
// 监听选中行变化
watch(
() => props.currentRow.excelOrderId,
(val) => {
getOrderVariableField()
},
{ immediate: true }
)
watch(
() => props.currentConf.title,
(val) => {
console.log('watch--props.currentConf.title', val, props.currentConf)
configList.value = cloneDeep(props.currentConf).orderFiledConfs.map((item, i) => {
item.time = Date.now() + i
return item
})
},
{
immediate: true
}
)
watch(
configList,
(val) => {
console.log('configList----', val)
excelChangeStore.setUsedFieldList(val)
},
{ deep: true }
)
onMounted(() => {
getScriptList()
getOrderFields()
})
</script>
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