提交 19b17451 authored 作者: lidongxu's avatar lidongxu

feat(bi/finance): 口味规格和直播间支持全选

watch 观察表单参数有值显示对应列,暂时注释了,默认全都显示所有列
上级 4069f78a
...@@ -42,9 +42,12 @@ export const getFinanceListAPI = (data) => { ...@@ -42,9 +42,12 @@ export const getFinanceListAPI = (data) => {
url: '/bi/finance/cost/list', url: '/bi/finance/cost/list',
method: 'POST', method: 'POST',
data: { data: {
zbjQdType: data.brand, zbjQdType: data.zbjQdType,
flavor: data.taste, flavor: data.flavorErp,
specName: data.spec, specName: data.specNameErp,
zbjQdTypeAll: data.zbjQdTypeAll,
flavorErpAll: data.flavorErpAll,
specNameErpAll: data.specNameErpAll,
series: data.seriesPrdMap.map(o => o[0]), series: data.seriesPrdMap.map(o => o[0]),
goodsName: data.seriesPrdMap.map(o => o[1]), goodsName: data.seriesPrdMap.map(o => o[1]),
startDate: parseTime(data.date[0], `{y}-{m}-{d}`), startDate: parseTime(data.date[0], `{y}-{m}-{d}`),
...@@ -58,9 +61,12 @@ export const getFinanceDetailAPI = (data) => { ...@@ -58,9 +61,12 @@ export const getFinanceDetailAPI = (data) => {
url: '/bi/finance/cost/detail/list', url: '/bi/finance/cost/detail/list',
method: 'POST', method: 'POST',
data: { data: {
zbjQdType: data.brand, zbjQdType: data.zbjQdType,
flavor: data.taste, flavor: data.flavorErp,
specName: data.spec, specName: data.specNameErp,
zbjQdTypeAll: data.zbjQdTypeAll,
flavorErpAll: data.flavorErpAll,
specNameErpAll: data.specNameErpAll,
series: data.seriesPrdMap.map(o => o[0]), series: data.seriesPrdMap.map(o => o[0]),
goodsName: data.seriesPrdMap.map(o => o[1]), goodsName: data.seriesPrdMap.map(o => o[1]),
startDate: parseTime(data.date[0], `{y}-{m}-{d}`), startDate: parseTime(data.date[0], `{y}-{m}-{d}`),
......
...@@ -2,17 +2,18 @@ ...@@ -2,17 +2,18 @@
<el-select v-bind="$attrs" <el-select v-bind="$attrs"
v-model="selectedOptions" v-model="selectedOptions"
@change="handleChange"> @change="handleChange">
<el-option v-for="str in options"
:label="str"
:value="str">
</el-option>
<li class="el-select-dropdown__item all_item" <li class="el-select-dropdown__item all_item"
:class="{ 'is-selected': isAll }" :class="{ 'is-selected': isAll }"
v-if="props.options.length > 0"
@click.stop="selectAll" @click.stop="selectAll"
@mouseenter.stop="over" @mouseenter.stop="over"
@mouseleave.stop="out"> @mouseleave.stop="out">
<span>全选</span> <span>全选</span>
</li> </li>
<el-option v-for="obj in options"
:label="obj.label"
:value="obj.value">
</el-option>
</el-select> </el-select>
</template> </template>
...@@ -20,7 +21,7 @@ ...@@ -20,7 +21,7 @@
const selectedOptions = ref([]) // 当前选中的值集合 const selectedOptions = ref([]) // 当前选中的值集合
const isAll = ref(false) // 全选状态 const isAll = ref(false) // 全选状态
const emits = defineEmits(['update:modelValue']); const emits = defineEmits(['update:modelValue', 'change']);
const props = defineProps({ const props = defineProps({
options: { options: {
...@@ -35,43 +36,45 @@ const props = defineProps({ ...@@ -35,43 +36,45 @@ const props = defineProps({
watch(() => props.modelValue, val => { watch(() => props.modelValue, val => {
selectedOptions.value = val; selectedOptions.value = val;
isAll.value = val.length === props.options.length if (props.options.length > 0) {
isAll.value = val.length === props.options.length
}
}, { }, {
deep: true, deep: true,
immediate: true immediate: true
}) })
// 设置样式
const noHover = () => {
const list = document.querySelectorAll('.el-select-dropdown .el-select-dropdown__item')
list.forEach(el => el.classList.add('no-hovering'))
}
// 全选点击 // 全选点击
const selectAll = () => { const selectAll = () => {
isAll.value = !isAll.value isAll.value = !isAll.value
if (isAll.value) { if (isAll.value) {
selectedOptions.value = [...props.options]; selectedOptions.value = props.options.map(item => item.value);
emits('update:modelValue', selectedOptions.value); emits('update:modelValue', selectedOptions.value);
emits('change')
} else { } else {
selectedOptions.value = []; selectedOptions.value = [];
emits('update:modelValue', selectedOptions.value); emits('update:modelValue', selectedOptions.value);
emits('change')
} }
nextTick(() => { nextTick(() => {
noHover() const list = document.querySelectorAll('.el-select-dropdown .el-select-dropdown__item')
list.forEach(el => el.classList.add('no-hovering'))
}) })
} }
const handleChange = (val) => { const handleChange = (val) => {
isAll.value = val.length === props.options.length isAll.value = val.length === props.options.length
emits('update:modelValue', val) emits('update:modelValue', val)
emits('change')
} }
const over = () => { const over = () => {
noHover() const list = document.querySelectorAll('.el-select-dropdown .el-select-dropdown__item')
list.forEach(el => el.classList.add('no-hovering'))
} }
const out = () => { const out = () => {
noHover() const list = document.querySelectorAll('.el-select-dropdown .el-select-dropdown__item')
list.forEach(el => el.classList.remove('no-hovering'))
} }
</script> </script>
......
...@@ -3,9 +3,10 @@ ...@@ -3,9 +3,10 @@
* @param {*} type 0:从今天开始往前,-1 则是 T - 1 开始日期往前 * @param {*} type 0:从今天开始往前,-1 则是 T - 1 开始日期往前
* @returns {} * @returns {}
*/ */
export const useDatePickerOptions = (type = -1,) => { export const useDatePickerOptions = (type = -1) => {
const last30Date = [new Date().setDate((new Date().getDate() - (30 - 1))), new Date().setDate((new Date().getDate() + type))] const last30Date = [new Date().setDate((new Date().getDate() - (30 - 1))), new Date().setDate((new Date().getDate() + type))]
const last7Date = [new Date().setDate((new Date().getDate() - (7 - 1))), new Date().setDate((new Date().getDate() + type))] const last7Date = [new Date().setDate((new Date().getDate() - (7 - 1))), new Date().setDate((new Date().getDate() + type))]
const lastDate = [new Date().setDate((new Date().getDate() + type)), new Date().setDate((new Date().getDate() + type))]
const recentPickerOptions = ref([// 日期选项配置 const recentPickerOptions = ref([// 日期选项配置
{ {
text: '最近一周', text: '最近一周',
...@@ -47,9 +48,10 @@ export const useDatePickerOptions = (type = -1,) => { ...@@ -47,9 +48,10 @@ export const useDatePickerOptions = (type = -1,) => {
} }
]) ])
return { return {
lastDate, // 昨天
last30Date, // 前 30 天 last30Date, // 前 30 天
last7Date, // 前 7 天 last7Date, // 前 7 天
recentPickerOptions, // 最近一周/一月 recentPickerOptions, // 最近一周/一月
lastPickerOptions lastPickerOptions // 上一周/上一月
} }
} }
\ No newline at end of file
...@@ -4,50 +4,50 @@ ...@@ -4,50 +4,50 @@
<!-- 搜索表单 --> <!-- 搜索表单 -->
<el-form :model="queryParams" <el-form :model="queryParams"
label-position="right" label-position="right"
label-width="68px" label-width="88px"
inline inline
v-show="showSearch"> v-show="showSearch">
<el-form-item label="直播间"> <el-form-item label="直播间分类">
<el-select v-model="queryParams.brand" <xl-select v-model="queryParams.zbjQdType"
:options="brandList"
selectAllValue="ALL"
multiple multiple
clearable clearable
filterable filterable
collapse-tags collapse-tags
collapse-tags-tooltip collapse-tags-tooltip
@change="getList"> @change="getList">
<el-option v-for="item in brandList" </xl-select>
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="口味"> <el-form-item label="口味">
<el-select v-model="queryParams.taste" <xl-select v-model="queryParams.flavorErp"
multiple multiple
:options="tasteList"
clearable clearable
filterable filterable
collapse-tags collapse-tags
collapse-tags-tooltip collapse-tags-tooltip
@change="getList"> @change="getList">
<el-option v-for="item in tasteList" <!-- <el-option v-for="item in tasteList"
:label="item.label" :label="item.label"
:value="item.value"> :value="item.value">
</el-option> </el-option> -->
</el-select> </xl-select>
</el-form-item> </el-form-item>
<el-form-item label="规格"> <el-form-item label="规格">
<el-select v-model="queryParams.spec" <xl-select v-model="queryParams.specNameErp"
:options="specList"
multiple multiple
clearable clearable
filterable filterable
collapse-tags collapse-tags
collapse-tags-tooltip collapse-tags-tooltip
@change="getList"> @change="getList">
<el-option v-for="item in specList" <!-- <el-option v-for="item in specList"
:label="item.label" :label="item.label"
:value="item.value"> :value="item.value">
</el-option> </el-option> -->
</el-select> </xl-select>
</el-form-item> </el-form-item>
<el-form-item label="系列商品" <el-form-item label="系列商品"
class="series"> class="series">
...@@ -100,13 +100,12 @@ ...@@ -100,13 +100,12 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 操作工具 --> <!-- 操作工具 -->
<el-row <el-row class="mb8">
class="mb8">
<el-button icon="Refresh" <el-button icon="Refresh"
@click="reset" @click="reset"
v-show="showSearch"> v-show="showSearch">
重置 重置
</el-button> </el-button>
<right-toolbar v-model:showSearch="showSearch" <right-toolbar v-model:showSearch="showSearch"
@queryTable="getList" @queryTable="getList"
:columns="columns"> :columns="columns">
...@@ -115,7 +114,10 @@ ...@@ -115,7 +114,10 @@
<!-- 数据 --> <!-- 数据 -->
<el-table :data="tableList" <el-table :data="tableList"
border border
@row-click="rowClick"> row-key="zbjQdType"
lazy
:load="load"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
<template v-for="item in columns"> <template v-for="item in columns">
<el-table-column v-if="item.visible" <el-table-column v-if="item.visible"
:key="item.prop" :key="item.prop"
...@@ -125,6 +127,13 @@ ...@@ -125,6 +127,13 @@
:formatter="formatter"> :formatter="formatter">
</el-table-column> </el-table-column>
</template> </template>
<el-table-column label="操作" width="120">
<template v-slot="scope">
<el-button type="primary"
link
@click="rowClick(scope.row)">订单详情</el-button>
</template>
</el-table-column>
</el-table> </el-table>
<!-- 订单详情 --> <!-- 订单详情 -->
<el-dialog v-model="detailVisible" <el-dialog v-model="detailVisible"
...@@ -169,16 +178,16 @@ import { getBrandListAPI, getTasteListAPI, getSpecListAPI, getSeriesListAPI, get ...@@ -169,16 +178,16 @@ import { getBrandListAPI, getTasteListAPI, getSpecListAPI, getSeriesListAPI, get
import { useDatePickerOptions } from '@/hooks' import { useDatePickerOptions } from '@/hooks'
import { formatNumberWithUnit, parseTime } from '@/utils' import { formatNumberWithUnit, parseTime } from '@/utils'
const { lastPickerOptions: pickerOptions } = useDatePickerOptions() const { lastPickerOptions: pickerOptions, lastDate } = useDatePickerOptions()
const showSearch = ref(true) // 搜索 const showSearch = ref(true) // 搜索
const detailVisible = ref(false) // 详情 const detailVisible = ref(false) // 详情
const data = reactive({ const data = reactive({
queryParams: { queryParams: {
brand: [], // 直播间 zbjQdType: [], // 直播间
taste: [], // 口味 flavorErp: [], // 口味
spec: [], // 规格 specNameErp: [], // 规格
date: [], // 日期 date: lastDate, // 日期
seriesPrdMap: [] // 系列商品 seriesPrdMap: [] // 系列商品
}, },
detailQueryParams: { // 详情查询 detailQueryParams: { // 详情查询
...@@ -191,13 +200,11 @@ const { queryParams, detailQueryParams } = toRefs(data) ...@@ -191,13 +200,11 @@ const { queryParams, detailQueryParams } = toRefs(data)
const reset = () => { const reset = () => {
queryParams.value = { queryParams.value = {
brand: [], // 直播间 zbjQdType: [], // 直播间
taste: [], // 口味 flavorErp: [], // 口味
spec: [], // 规格 specNameErp: [], // 规格
date: [], // 日期 date: lastDate, // 日期
seriesPrdMap: [], // 系列商品 seriesPrdMap: [] // 系列商品
pageNum: 1,
pageSize: 10
} }
getList() getList()
} }
...@@ -212,6 +219,8 @@ const getBrandList = async () => { ...@@ -212,6 +219,8 @@ const getBrandList = async () => {
label: obj.zbjQdType label: obj.zbjQdType
}; };
}); });
// 默认查询所有直播间列表
queryParams.value.zbjQdType = brandList.value.map(obj => obj.value);
}; };
getBrandList(); getBrandList();
...@@ -248,6 +257,7 @@ const getSeriesList = async () => { ...@@ -248,6 +257,7 @@ const getSeriesList = async () => {
seriesList.value = response.data.map(obj => { seriesList.value = response.data.map(obj => {
return { return {
value: obj.seriesId, value: obj.seriesId,
// value: obj.seriesName,
label: obj.seriesName label: obj.seriesName
}; };
}); });
...@@ -262,7 +272,8 @@ const props = reactive({ // 级联选择器配置 ...@@ -262,7 +272,8 @@ const props = reactive({ // 级联选择器配置
const { data: { total } } = await getProductListAPI({ seriesId }); const { data: { total } } = await getProductListAPI({ seriesId });
const { data: { rows } } = await getProductListAPI({ seriesId, pageNum: 1, pageSize: total }); const { data: { rows } } = await getProductListAPI({ seriesId, pageNum: 1, pageSize: total });
const nodes = rows.map(item => ({ const nodes = rows.map(item => ({
value: item.prdCode, // value: item.prdCode,
value: item.prdName,
label: item.prdName, label: item.prdName,
leaf: true // 指定叶子节点 leaf: true // 指定叶子节点
})); }));
...@@ -277,71 +288,105 @@ const props = reactive({ // 级联选择器配置 ...@@ -277,71 +288,105 @@ const props = reactive({ // 级联选择器配置
// 表格数据 // 表格数据
const columns = ref([ const columns = ref([
{ {
label: '直播间', label: '直播间分类',
prop: 'zbjQdType', prop: 'zbjQdType',
visible: true, visible: true,
width: 140 width: 140,
check: true // 根据查询条件有无,判断当前列实/隐
}, },
{ {
label: '口味', label: '口味',
prop: 'flavorErp', prop: 'flavorErp',
visible: true, visible: true,
width: 120 width: 120,
check: true
}, },
{ {
label: '规格', label: '规格',
prop: 'specNameErp', prop: 'specNameErp',
visible: true, visible: true,
width: 140 width: 140,
check: true
}, },
{ {
label: '系列', label: '系列',
prop: '', prop: 'series',
visible: true, visible: true,
width: 140 width: 140,
check: true
}, },
{ {
label: '商品', label: '商品',
prop: 'goodsName', prop: 'goodsName',
visible: true, visible: true,
width: 140 width: 140,
check: true
},
{
label: '分销商 id',
prop: 'fenxiaoId',
visible: true,
width: 100,
check: true
},
{
label: '分销商名称',
prop: 'fenxiaoName',
visible: true,
width: 200,
check: true
}, },
{ {
label: '分摊后总价', label: '分摊后总价',
prop: 'shareAmountSum', prop: 'shareAmountSum',
visible: true, visible: true,
width: 120 width: 120,
check: false
}, },
{ {
label: '实际成本', label: '实际成本',
prop: 'actualCostSum', prop: 'actualCostSum',
visible: true, visible: true,
width: 120 width: 120,
check: false
}, },
{ {
label: '实际成本毛利', label: '实际成本毛利',
prop: 'actualCostGrossProfitSum', prop: 'actualCostGrossProfitSum',
visible: true, visible: true,
width: 120 width: 120,
check: false
}, },
{ {
label: '标准成本', label: '标准成本',
prop: 'standardCostSum', prop: 'standardCostSum',
visible: true, visible: true,
width: 120 width: 120,
check: false
}, },
{ {
label: '标准成本毛利', label: '标准成本毛利',
prop: 'standardCostGrossProfitSum', prop: 'standardCostGrossProfitSum',
visible: true, visible: true,
width: 120 width: 120,
check: false
} }
]) ])
const tableList = ref([ const tableList = ref([
]) ])
const getList = async () => { const getList = async () => {
// 直播间分类全选时,单独增加字段给后台
queryParams.value.zbjQdTypeAll = (queryParams.value.zbjQdType.length === brandList.value.length)
// 口味
queryParams.value.flavorErpAll = (queryParams.value.flavorErp.length === tasteList.value.length)
// 规格
queryParams.value.specNameErpAll = (queryParams.value.specNameErp.length === specList.value.length)
const res = await getFinanceListAPI(queryParams.value) const res = await getFinanceListAPI(queryParams.value)
tableList.value = res.data.list tableList.value = res.data.list.map(o => {
o.hasChildren = true
return o
})
} }
getList() getList()
...@@ -353,6 +398,55 @@ const formatter = (row, column, value) => { ...@@ -353,6 +398,55 @@ const formatter = (row, column, value) => {
} }
} }
// 观察查询表单选择字段,则显示
// watch(queryParams, (val) => {
// // 日期无需决定列显示与否
// const showQuery = { ...val }
// delete showQuery.date
// // 如果每个筛选条件都无值,则显示直播间分类这一列
// if (Object.values(showQuery).every(item => item.length === 0)) {
// columns.value.forEach(item => {
// if (item.check) {
// item.visible = item.prop === 'zbjQdType'
// }
// })
// return
// }
// // 哪个筛选条件有值,则显示哪一列
// Object.entries(showQuery).forEach(([key, value]) => {
// // 处理查询参数名和列 prop 字段名不同的情况
// // 系列和商品搜索字段叫 seriesPrdMap,但是列字段叫 series 和 goodsName
// if (key === 'seriesPrdMap') {
// const columnSeries = columns.value.find(item => item.prop === 'series')
// const columnGoods = columns.value.find(item => item.prop === 'goodsName')
// if (columnSeries && columnGoods) {
// columnSeries.visible = value.length > 0
// columnGoods.visible = value.length > 0
// }
// } else {
// // 查询参数名和 prop 能对上的
// const columnObj = columns.value.find(item => item.prop === key)
// if (columnObj && columnObj.check) {
// // 显示该列
// columnObj.visible = value.length > 0
// }
// }
// })
// }, {
// deep: true,
// immediate: true
// })
// 展开行
const load = (options) => {
// 请求某个展开行下属的数据
console.log(options)
// const { page, limit } = options
// queryParams.value.pageNum = page
// queryParams.value.pageSize = limit
// getList()
}
// 详情数据 // 详情数据
const detailList = ref([]) const detailList = ref([])
const detailColumns = ref([ const detailColumns = ref([
...@@ -508,24 +602,14 @@ const giftType = { ...@@ -508,24 +602,14 @@ const giftType = {
const rowClick = (row) => { const rowClick = (row) => {
detailQueryParams.value = { detailQueryParams.value = {
brand: row.zbjQdType && [row.zbjQdType], // 直播间 zbjQdType: row.zbjQdType && [row.zbjQdType], // 直播间
taste: row.flavorErp && [row.flavorErp], // 口味 flavorErp: row.flavorErp && [row.flavorErp], // 口味
spec: row.specNameErp && [row.specNameErp], // 规格 specNameErp: row.specNameErp && [row.specNameErp], // 规格
seriesPrdMap: [], // TODO:行里没有系列字段等会看下 seriesPrdMap: row.seriesId && [{ value: row.seriesId, label: row.seriesName }], // TODO:行里没有系列字段等会看下
date: queryParams.value.date, // 日期 date: queryParams.value.date, // 日期
pageNum: 1, pageNum: 1,
pageSize: 10 pageSize: 10
} }
// 口味
row.flavorErp && (detailQueryParams.value.taste = [row.flavorErp])
// 规格
row.specNameErp && (detailQueryParams.value.spec = [row.specNameErp])
// 系列+商品
row.seriesId && (detailQueryParams.value.seriesPrdMap = [{ value: row.seriesId, label: row.seriesName }])
// 日期
detailQueryParams.value.date = queryParams.value.date
detailQueryParams.value.pageNum = 1
detailQueryParams.value.pageSize = 10
detailVisible.value = true detailVisible.value = true
getDetailList() getDetailList()
} }
...@@ -543,7 +627,7 @@ const detailFormatter = (row, column, value) => { ...@@ -543,7 +627,7 @@ const detailFormatter = (row, column, value) => {
return goodsType[value] return goodsType[value]
} else if (['giftType'].includes(column.property)) { } else if (['giftType'].includes(column.property)) {
return giftType[value] return giftType[value]
} }
return value return value
} }
const changeShowOver = () => { const changeShowOver = () => {
...@@ -554,7 +638,7 @@ const changeShowOver = () => { ...@@ -554,7 +638,7 @@ const changeShowOver = () => {
<style scoped <style scoped
lang="scss"> lang="scss">
::v-deep(.el-form-item) { ::v-deep(.el-form-item) {
width: 250px; width: 300px;
&.date_picker { &.date_picker {
width: 350px; width: 350px;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论