数据过滤

main
fanfan 6 months ago
parent e4db389bd2
commit c193a9da15
  1. 12
      src/config/router.config.js
  2. 278
      src/views/goods/filter/Index.vue
  3. 12844
      yarn.lock

@ -339,7 +339,17 @@ export const asyncRouterMap = [
meta: { title: '接口配置', keepAlive: false, permission: ['/apps/collector/setting'] }
}
]
}
},
{
path: '/goods/filter/index',
component: () => import(/* webpackChunkName: "goods" */ '@/views/goods/filter/Index'),
meta: {
title: '数据过滤',
pageTitle: '数据过滤',
keepAlive: false,
permission: ['/goods/filter/index']
}
},
]
},

@ -0,0 +1,278 @@
<template>
<a-card :bordered="false">
<div class="card-title">{{ $route.meta.title }}</div>
<a-spin :spinning="isLoading">
<a-form :form="form" @submit="handleSubmit">
<a-form-item label="数据渠道" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select
allowClear
mode="multiple"
@change="getChannel"
placeholder="请选择渠道"
v-decorator="[`open_channel`, { rules: [{ required: true, message: '请至少选择1个渠道' }] }]"
>
<a-select-option :value="item.id" v-for="item in checkList" :key="item.id">
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item
v-for="(k, index) in form.getFieldValue('fliter_condition')"
:key="k.id"
:label="index === 0 ? '过滤数据' : ''"
:labelCol="labelCol"
v-bind="index === 0 ? { wrapperCol } : formItemLayoutWithOutLabel"
required
>
<div class="fan">
<a-tree-select
style="width: 100%; margin-right: 8px; margin-top: 3px"
placeholder="请选择商品分类"
:dropdownStyle="{ maxHeight: '500px', overflow: 'auto' }"
:treeData="formData.categoryList"
treeCheckable
allowClear
v-decorator="[`category${index}`, { rules: [{ required: true, message: '请至少选择1个商品分类' }] }]"
></a-tree-select>
<a-form-item>
<a-input
placeholder="利润值"
prefix=">"
suffix="元"
v-decorator="[`profit${index}`, { rules: [{ required: true, message: '请输入利润值' }] }]"
style="width: 94%; margin-right: 8px"
/>
</a-form-item>
<a-form-item>
<a-input
placeholder="利润率"
prefix=">"
suffix="%"
v-decorator="[`profit_rate${index}`, { rules: [{ required: true, message: '请输入利润率' }] }]"
style="width: 94%; margin-right: 8px"
/>
</a-form-item>
<a-form-item>
<a-icon
style="margin-top: 30rpx"
v-if="form.getFieldValue('fliter_condition').length > 0"
class="dynamic-delete-button"
type="minus-circle-o"
:disabled="form.getFieldValue('fliter_condition').length === 1"
@click="() => handleRemoveCondition(index)"
/>
</a-form-item>
</div>
</a-form-item>
<a-form-item v-bind="formItemLayoutWithOutLabel">
<a-button type="dashed" style="width: calc(50% + 8px)" @click="handleAddCondition">
<a-icon type="plus" /> 新增过滤数据
</a-button>
</a-form-item>
<a-form-item :wrapperCol="{ span: wrapperCol.span, offset: labelCol.span }">
<a-button type="primary" html-type="submit">提交</a-button>
</a-form-item>
</a-form>
</a-spin>
</a-card>
</template>
<script>
import pick from 'lodash.pick'
import * as Api from '@/api/store'
import * as GoodsApi from '@/api/goods'
import GoodsModel from '@/common/model/goods/Index'
import { isEmpty } from '@/utils/util'
export default {
data() {
return {
//
labelCol: { span: 3 },
//
wrapperCol: { span: 10 },
// loading
isLoading: false,
//
form: this.$form.createForm(this),
//
formData: GoodsModel.formData,
record: {},
checkList: [],
formItemLayoutWithOutLabel: {
wrapperCol: { span: 10, offset: 3 },
},
}
},
//
created() {
this.isLoading = true
// form
GoodsModel.getFromData().then(() => {
this.isLoading = false
})
this.form.getFieldDecorator('fliter_condition', { initialValue: [], preserve: true })
this.getDataList() //
//
this.getDetail()
},
methods: {
//
handleRemoveCondition(index) {
const { form } = this
const keys = form.getFieldValue('fliter_condition')
if (keys.length === 0) {
return
}
const fliter_condition = keys.filter((x, i) => i !== index)
form.setFieldsValue({
fliter_condition,
})
},
handleAddCondition() {
const { form } = this
const keys = form.getFieldValue('fliter_condition')
const nextKeys = keys.concat([{ category: '', profit: '', profit_rate: '', id: this.generateRandomString(8) }])
form.setFieldsValue({
fliter_condition: nextKeys,
})
},
generateRandomString(length) {
let result = ''
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
const charactersLength = characters.length
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength))
}
return result
},
//
getDataList() {
return GoodsApi.getDataList().then((result) => {
const obj = result.data
Object.keys(obj).forEach((item) => {
this.checkList.push({ id: item, name: obj[item] })
})
})
},
//
setFieldsValue() {
const { record, form, $nextTick } = this
const profitAry = []
const profitRateAry = []
const categoryAry = []
if (record.fliter_condition) {
record.fliter_condition = JSON.parse(record.fliter_condition)
record.fliter_condition = record.fliter_condition.map((x) => {
x.id = this.generateRandomString(8)
return x
})
record.fliter_condition.forEach((x, i) => {
record[`profit${i}`] = x.profit
record[`profit_rate${i}`] = x.profit_rate
record[`category${i}`] = x.category
categoryAry.push(`category${i}`)
profitAry.push(`profit${i}`)
profitRateAry.push(`profit_rate${i}`)
this.form.getFieldDecorator(`category${i}`, { initialValue: '', preserve: true })
this.form.getFieldDecorator(`profit${i}`, { initialValue: '', preserve: true })
this.form.getFieldDecorator(`profit_rate${i}`, { initialValue: '', preserve: true })
})
}
if (record.open_channel) {
const list = record.open_channel
const channelAry = []
this.checkList.map((item) => {
if (list.indexOf(item.id) != -1) {
channelAry.push(item.name)
}
})
this.form.open_channel = channelAry
}
//
!isEmpty(form.getFieldsValue()) &&
$nextTick(() => {
form.setFieldsValue(
pick(record, ['open_channel', 'fliter_condition', ...profitAry, ...profitRateAry, ...categoryAry])
)
this.$forceUpdate()
})
},
formatCategoryIds(categoryIds) {
return categoryIds.map((id) => {
return { value: id }
})
},
//
getDetail() {
this.isLoading = true
Api.info()
.then((result) => {
//
result.data.storeInfo.open_channel = result.data.storeInfo.open_channel.split(',')
this.record = result.data.storeInfo
//
this.setFieldsValue()
})
.finally(() => (this.isLoading = false))
},
getChannel(val) {
this.form.open_channel = val
},
//
handleSubmit(e) {
e.preventDefault()
//
const {
form: { validateFields },
onFormSubmit,
} = this
validateFields((errors, values) => {
!errors && onFormSubmit(values)
})
},
// api
onFormSubmit(values) {
const params = {}
params.fliter_condition = values.fliter_condition.map((x, i) => {
return {
category: values[`category${i}`],
profit: values[`profit${i}`],
profit_rate: values[`profit_rate${i}`],
}
})
params.open_channel = values.open_channel ? values.open_channel.join(',') : ''
this.isLoading = true
Api.update({ form: params })
.then((result) => {
//
this.$message.success(result.message, 1.5)
this.getDetail()
})
.catch(() => {
this.isLoading = false
})
.finally(() => (this.isLoading = false))
},
},
}
</script>
<style lang="less" scoped>
/deep/.ant-form-item-control {
padding-left: 10px;
.ant-form-item-control {
padding-left: 0;
}
}
/deep/.ant-input-prefix {
font-weight: bold;
}
.fan {
display: flex;
align-items: top;
}
.fan /deep/ .ant-form-item {
margin-bottom: 0;
}
</style>

12844
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save