This commit is contained in:
liushiwei
2023-10-25 12:20:10 +08:00
parent e52e62c1d5
commit 0522cadeee
11 changed files with 761 additions and 71 deletions

View File

@@ -110,7 +110,11 @@
</el-select>
</el-form-item>
<el-form-item label="商品分类" style="width: 100%;" prop="targetCatId" :rules="[{ required: true, message: '请选择商品分类', trigger: 'blur' }]">
<el-cascader style="width: 380px" v-model="form.targetCatId" :props="props"></el-cascader>
<ai-lazy-cascader
style="width: 380px"
v-model="form.targetCatId"
filterable
:props="props"></ai-lazy-cascader>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
@@ -126,10 +130,11 @@ import {sendChromeAPIMessage} from '@/api/chromeApi'
import {timestampToTime} from '@/utils/date'
import {transform} from '@/utils/product'
import { Message } from 'element-ui'
import AiLazyCascader from "@/components/AiLazyCascader.vue"
export default {
name: 'CopyProduct',
components: {AiLazyCascader},
data () {
return {
search: {
@@ -144,12 +149,12 @@ import { Message } from 'element-ui'
value: 'catId',
label: 'catName',
lazy: true,
lazyLoad (node, resolve) {
lazyLoad (value, resolve) {
sendChromeAPIMessage({
url: 'bg-anniston-mms/category/children/list',
needMallId: true,
data: {
parentCatId: node.value || ''
parentCatId: value || ''
}
}).then(res => {
if (res.errorCode === 1000000) {
@@ -161,6 +166,32 @@ import { Message } from 'element-ui'
}))
}
})
},
lazySearch(queryString, resolve) {
sendChromeAPIMessage({
url: 'bg-anniston-mms/category/search',
needMallId: true,
data: {
searchText: queryString || ''
}
}).then(res => {
if (res.errorCode === 1000000) {
resolve(res.result.categoryPaths.map(v => {
let value = []
let label = []
for (let i = 1; i <= 10; i++ ) {
if (v['cat'+i+'NodeVO']) {
value.push(v['cat'+i+'NodeVO'].catId)
label.push(v['cat'+i+'NodeVO'].catName)
}
}
return {
catId: value,
catName: label
}
}))
}
})
}
},
colConfigs: [

View File

@@ -45,7 +45,7 @@
@getList="getList">
<el-table-column slot="url" label="商品地址" align="left">
<template slot-scope="scope">
<div><a :href="scope.row.url" target="_blank">{{ scope.row.url }}</a></div>
<div><a class="el-link el-link--primary" :href="scope.row.url" target="_blank">{{ scope.row.url }}</a></div>
</template>
</el-table-column>
</ai-table>

View File

@@ -7,14 +7,24 @@
isShowBottomBorder isShowBack @onBackClick="cancel(false)">
</ai-title>
<template slot="content">
<div style="margin-right: 0px; margin-bottom: 10px;">
<el-select v-model="search.orderBy" :clearable="true" @change="search.current =1, getList()" placeholder="请选择排序方式" size="small">
<el-option
v-for="item in orderBys"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr; gap: 16px;">
<el-card v-for="item in tableData" :key="item.id" :body-style="{ padding: '0px', margin: '5px' }">
<img :src="item.imgUrl" class="image">
<div style="padding: 14px;">
<div class="bottom clearfix">
<div style="margin-bottom: 5px;">
<div style="display: inline; margin-left: 5px;">${{ item.priceAndSale[0].price }}<sub style="margin-left: 2px;" v-html="getPricePercent(item.priceAndSale)"></sub></div>
<div style="display: inline; margin-right: 5px; float: right;">{{ item.priceAndSale[0].sale_total }}<sub style="margin-left: 2px;" v-html="getSalePercent(item.priceAndSale)"></sub></div>
<div style="display: inline; margin-left: 5px;">${{ item.price }}<sub style="margin-left: 2px;" v-html="getPricePercent(item.priceChange)"></sub></div>
<div style="display: inline; margin-right: 5px; float: right;">{{ item.saleTotal }}<sub style="margin-left: 2px;" v-html="getSalePercent(item.saleChange)"></sub></div>
</div>
<ai-product-drop-down :params="item" :isShowDetail="true" @onGoDetail="goDetail(item.goodsId, item.monitorId)" style="float: right;"></ai-product-drop-down>
</div>
@@ -61,8 +71,22 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
search: {
current: 1,
type: '1',
size: 120
size: 120,
orderBy: ''
},
orderBys: [{
value: '0',
label: '按销量涨辐排序'
},{
value: '1',
label: '按价格涨辐排序'
},{
value: '2',
label: '按销量排序'
},{
value: '3',
label: '按价格排序'
}],
tableData: [],
total: 0,
isShowDetailDlg: false,
@@ -77,7 +101,7 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
methods: {
getList () {
this.$http.post('/api/monitorDetail/myPage',null,{
this.$http.post('/api/monitorDetail/myPageNew',null,{
params: {
monitorId: this.monitorId,
...this.search
@@ -94,32 +118,20 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
})
},
getPricePercent(data) {
if (data.length == 2) {
let a = (data[0].price - data[1].price) / data[1].price
if (a < 0) {
return '<div style="display: inline; color: green">' + (a*100).toFixed(2) + '%</div>'
} else if (a == 0) {
return ''
} else if (a > 0) {
return '<div style="display: inline; color: red">↑' + (a*100).toFixed(2) + '%</div>'
}
} else {
return ''
if (data < 0) {
return '<div style="display: inline; color: green">↓' + data + '%</div>'
} else if (data > 0) {
return '<div style="display: inline; color: red">' + data + '%</div>'
}
return ''
},
getSalePercent(data) {
if (data.length == 2) {
let a = (data[0].sale_total - data[1].sale_total) / data[1].sale_total
if (a < 0) {
return '<div style="display: inline; color: green">' + (a*100).toFixed(2) + '%</div>'
} else if (a == 0) {
return ''
} else if (a > 0) {
return '<div style="display: inline; color: red">↑' + (a*100).toFixed(2) + '%</div>'
}
} else {
return ''
if (data < 0) {
return '<div style="display: inline; color: green">↓' + data + '%</div>'
} else if (data > 0) {
return '<div style="display: inline; color: red">' + data + '%</div>'
}
return ''
},
handleClose() {
this.isShowDetailDlg = false

View File

@@ -26,16 +26,22 @@
:current.sync="search.current" :size.sync="search.size"
@selection-change="onChooseChange"
@getList="getList">
<el-table-column slot="options" label="操作" width="200px" show-overflow-tooltip align="center" fixed="right">
<el-table-column slot="options" label="操作" width="240px" show-overflow-tooltip align="center" fixed="right">
<template slot-scope="{ row }">
<div class="table-options">
<el-button type="text" @click="deleteMonitor(row.id)">删除</el-button>
<el-button type="text" @click="toUpdateMonitor(row)">修改</el-button>
<el-button type="text" @click="renew(row.id)">续费</el-button>
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
<el-button type="text" @click="toBegin(row)">采集数据</el-button>
</div>
</template>
</el-table-column>
<el-table-column slot="content" label="关键字" show-overflow-tooltip align="center">
<template slot-scope="{ row }">
<div><a class="el-link el-link--primary" :href="'https://www.temu.com/search_result.html?search_key='+row.content+'&search_method=user&filter_items='+row.orderType" target="_blank">{{ row.content }}</a></div>
</template>
</el-table-column>
</ai-table>
</div>
</template>
@@ -66,12 +72,45 @@
:rules="[{ required: true, message: '请选择排序方式', trigger: 'blur' }]">
<ai-select :selectList="$dict.getDict('monitor_order_type')" v-model="form.orderType"></ai-select>
</el-form-item>
<el-form-item
prop="remark"
label="备注"
:rules="[{ required: true, message: '请输入备注', trigger: 'blur' }]">
<el-input placeholder="请输入备注" v-model="form.remark"></el-input>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<el-button @click="isDlgShow = false"> </el-button>
<el-button type="primary" @click="saveStore">确定</el-button>
</div>
</ai-dialog>
<ai-dialog
title="修改店铺"
:visible.sync="isUpdateDlgShow"
:close-on-click-modal="false"
width="790px"
customFooter
@close="isDlgShow = false">
<el-form class="ai-form" :model="updateForm" label-width="120px" ref="updateForm">
<el-form-item
prop="mallId"
label="店铺ID"
:rules="[{ required: true, message: '请输入店铺ID', trigger: 'blur' }]">
<el-input placeholder="请输入店铺ID" disabled v-model="updateForm.mallId"></el-input>
</el-form-item>
<el-form-item
prop="remark"
label="备注"
:rules="[{ required: true, message: '请输入备注', trigger: 'blur' }]">
<el-input placeholder="请输入备注" v-model="updateForm.remark"></el-input>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<el-button @click="isUpdateDlgShow = false"> </el-button>
<el-button type="primary" @click="updateStore">确定</el-button>
</div>
</ai-dialog>
</div>
</template>
@@ -91,8 +130,9 @@ import { Message } from 'element-ui'
},
colConfigs: [
{ type: "selection", width: '70px', align: 'left' },
{ prop: 'content', label: '关键字', align: 'left' },
{ slot: 'content', label: '关键字', align: 'left' },
{ prop: 'orderType', label: '排序方式', align: 'left', format: v => this.$dict.getLabel('monitor_order_type', v) },
{ prop: 'remark', label: '备注', align: 'left'},
{ prop: 'lastUpdateTime', label: '最后一次更新时间', align: 'left' },
{ prop: 'status', label: '状态', align: 'left', format: v => this.$dict.getLabel('monitor_status', v), },
{ prop: 'expireTime', label: '失效时间', align: 'left' },
@@ -103,7 +143,16 @@ import { Message } from 'element-ui'
form: {
content: '',
orderType: '0:1'
orderType: '0:1',
remark: ''
},
updateObj: {},
isUpdateDlgShow: false,
updateForm: {
id: '',
mallId: '',
remark: ''
},
isDlgShow: false,
@@ -142,7 +191,7 @@ import { Message } from 'element-ui'
if (valid) {
this.$http.post('/api/monitor/check',null, {params: {type: 0}}).then(res => {
if (res.code == 0) {
this.$http.post(`/api/monitor/add`, {content: this.form.content, orderType: this.form.orderType, type: this.search.type}).then(res => {
this.$http.post(`/api/monitor/add`, {content: this.form.content, remark: this.form.remark, orderType: this.form.orderType, type: this.search.type}).then(res => {
if (res.code == 0) {
this.$message.success('添加成功!')
this.$store.dispatch('getUserInfo')
@@ -155,6 +204,25 @@ import { Message } from 'element-ui'
}
})
},
toUpdateMonitor (obj) {
this.updateObj = obj
this.updateForm.mallId = obj.content
this.updateForm.remark = obj.remark
this.isUpdateDlgShow = true
},
updateStore () {
this.$refs.updateForm.validate((valid) => {
if (valid) {
this.$http.post(`/api/monitor/update`, {id: this.updateObj.id, remark: this.updateForm.remark}).then(res => {
if (res.code == 0) {
this.$message.success('修改成功!')
this.getList()
this.isUpdateDlgShow = false
}
})
}
})
},
renew(id) {
this.$confirm('确定要续费?', '温馨提示', {
type: 'warning'

View File

@@ -7,14 +7,24 @@
isShowBottomBorder isShowBack @onBackClick="cancel(false)">
</ai-title>
<template slot="content">
<div style="margin-right: 0px; margin-bottom: 10px;">
<el-select v-model="search.orderBy" :clearable="true" @change="search.current =1, getList()" placeholder="请选择排序方式" size="small">
<el-option
v-for="item in orderBys"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr; gap: 16px;">
<el-card v-for="item in tableData" :key="item.id" :body-style="{ padding: '0px', margin: '5px' }">
<img :src="item.imgUrl" class="image">
<div style="padding: 14px;">
<div class="bottom clearfix">
<div style="margin-bottom: 5px;">
<div style="display: inline; margin-left: 5px;">${{ item.priceAndSale[0].price }}<sub style="margin-left: 2px;" v-html="getPricePercent(item.priceAndSale)"></sub></div>
<div style="display: inline; margin-right: 5px; float: right;">{{ item.priceAndSale[0].sale_total }}<sub style="margin-left: 2px;" v-html="getSalePercent(item.priceAndSale)"></sub></div>
<div style="display: inline; margin-left: 5px;">${{ item.price }}<sub style="margin-left: 2px;" v-html="getPricePercent(item.priceChange)"></sub></div>
<div style="display: inline; margin-right: 5px; float: right;">{{ item.saleTotal }}<sub style="margin-left: 2px;" v-html="getSalePercent(item.saleChange)"></sub></div>
</div>
<ai-product-drop-down :params="item" :isShowDetail="true" @onGoDetail="goDetail(item.goodsId, item.monitorId)" style="float: right;"></ai-product-drop-down>
</div>
@@ -59,8 +69,22 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
search: {
current: 1,
type: '1',
size: 120
size: 120,
orderBy: ''
},
orderBys: [{
value: '0',
label: '按销量涨辐排序'
},{
value: '1',
label: '按价格涨辐排序'
},{
value: '2',
label: '按销量排序'
},{
value: '3',
label: '按价格排序'
}],
tableData: [],
total: 0,
isShowDetailDlg: false,
@@ -75,7 +99,7 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
methods: {
getList () {
this.$http.post('/api/monitorDetail/myPage',null,{
this.$http.post('/api/monitorDetail/myPageNew',null,{
params: {
monitorId: this.monitorId,
...this.search
@@ -92,32 +116,20 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
})
},
getPricePercent(data) {
if (data.length == 2) {
let a = (data[0].price - data[1].price) / data[1].price
if (a < 0) {
return '<div style="display: inline; color: green">' + (a*100).toFixed(2) + '%</div>'
} else if (a == 0) {
return ''
} else if (a > 0) {
return '<div style="display: inline; color: red">↑' + (a*100).toFixed(2) + '%</div>'
}
} else {
return ''
if (data < 0) {
return '<div style="display: inline; color: green">↓' + data + '%</div>'
} else if (data > 0) {
return '<div style="display: inline; color: red">' + data + '%</div>'
}
return ''
},
getSalePercent(data) {
if (data.length == 2) {
let a = (data[0].sale_total - data[1].sale_total) / data[1].sale_total
if (a < 0) {
return '<div style="display: inline; color: green">' + (a*100).toFixed(2) + '%</div>'
} else if (a == 0) {
return ''
} else if (a > 0) {
return '<div style="display: inline; color: red">↑' + (a*100).toFixed(2) + '%</div>'
}
} else {
return ''
if (data < 0) {
return '<div style="display: inline; color: green">↓' + data + '%</div>'
} else if (data > 0) {
return '<div style="display: inline; color: red">' + data + '%</div>'
}
return ''
},
handleClose() {
this.isShowDetailDlg = false

View File

@@ -26,16 +26,22 @@
@selection-change="onChooseChange"
:current.sync="search.current" :size.sync="search.size"
@getList="getList">
<el-table-column slot="options" label="操作" width="200px" show-overflow-tooltip align="center" fixed="right">
<el-table-column slot="options" label="操作" width="240px" show-overflow-tooltip align="center" fixed="right">
<template slot-scope="{ row }">
<div class="table-options">
<el-button type="text" @click="deleteMonitor(row.id)">删除</el-button>
<el-button type="text" @click="toUpdateMonitor(row)">修改</el-button>
<el-button type="text" @click="renew(row.id)">续费</el-button>
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
<el-button type="text" @click="toBegin(row)">采集数据</el-button>
</div>
</template>
</el-table-column>
<el-table-column slot="content" label="店铺ID" show-overflow-tooltip align="center">
<template slot-scope="{ row }">
<div><a class="el-link el-link--primary" :href="'https://www.temu.com/mall.html?mall_id=' + row.content" target="_blank">{{ row.content }}</a></div>
</template>
</el-table-column>
</ai-table>
</div>
</template>
@@ -60,12 +66,45 @@
:rules="[{ required: true, message: '请输入店铺ID', trigger: 'blur' }]">
<el-input placeholder="请输入店铺ID" v-model="form.mallId"></el-input>
</el-form-item>
<el-form-item
prop="remark"
label="备注"
:rules="[{ required: true, message: '请输入备注', trigger: 'blur' }]">
<el-input placeholder="请输入备注" v-model="form.remark"></el-input>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<el-button @click="isDlgShow = false"> </el-button>
<el-button type="primary" @click="saveStore">确定</el-button>
</div>
</ai-dialog>
<ai-dialog
title="修改店铺"
:visible.sync="isUpdateDlgShow"
:close-on-click-modal="false"
width="790px"
customFooter
@close="isDlgShow = false">
<el-form class="ai-form" :model="updateForm" label-width="120px" ref="updateForm">
<el-form-item
prop="mallId"
label="店铺ID"
:rules="[{ required: true, message: '请输入店铺ID', trigger: 'blur' }]">
<el-input placeholder="请输入店铺ID" disabled v-model="updateForm.mallId"></el-input>
</el-form-item>
<el-form-item
prop="remark"
label="备注"
:rules="[{ required: true, message: '请输入备注', trigger: 'blur' }]">
<el-input placeholder="请输入备注" v-model="updateForm.remark"></el-input>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<el-button @click="isUpdateDlgShow = false"> </el-button>
<el-button type="primary" @click="updateStore">确定</el-button>
</div>
</ai-dialog>
</div>
</template>
@@ -84,7 +123,8 @@ import {sendTemuAPIMessage} from '@/api/chromeApi'
},
colConfigs: [
{ type: "selection", width: '70px', align: 'left' },
{ prop: 'content', label: '店铺ID', align: 'left' },
{ slot: 'content', label: '店铺ID', align: 'left' },
{ prop: 'remark', label: '备注', align: 'left'},
{ prop: 'lastUpdateTime', label: '最后一次更新时间', align: 'left' },
{ prop: 'status', label: '状态', align: 'left', format: v => this.$dict.getLabel('monitor_status', v), },
{ prop: 'expireTime', label: '失效时间', align: 'left' },
@@ -94,7 +134,16 @@ import {sendTemuAPIMessage} from '@/api/chromeApi'
total: 0,
form: {
mallId: ''
mallId: '',
remark: ''
},
updateObj: {},
isUpdateDlgShow: false,
updateForm: {
id: '',
mallId: '',
remark: ''
},
isDlgShow: false,
@@ -133,7 +182,7 @@ import {sendTemuAPIMessage} from '@/api/chromeApi'
if (valid) {
this.$http.post('/api/monitor/check',null, {params: {type: 1}}).then(res => {
if (res.code == 0) {
this.$http.post(`/api/monitor/add`, {content: this.form.mallId, type: this.search.type}).then(res => {
this.$http.post(`/api/monitor/add`, {content: this.form.mallId, remark: this.form.remark, type: this.search.type}).then(res => {
if (res.code == 0) {
this.$message.success('添加成功!')
this.$store.dispatch('getUserInfo')
@@ -146,6 +195,25 @@ import {sendTemuAPIMessage} from '@/api/chromeApi'
}
})
},
toUpdateMonitor (obj) {
this.updateObj = obj
this.updateForm.mallId = obj.content
this.updateForm.remark = obj.remark
this.isUpdateDlgShow = true
},
updateStore () {
this.$refs.updateForm.validate((valid) => {
if (valid) {
this.$http.post(`/api/monitor/update`, {id: this.updateObj.id, remark: this.updateForm.remark}).then(res => {
if (res.code == 0) {
this.$message.success('修改成功!')
this.getList()
this.isUpdateDlgShow = false
}
})
}
})
},
batchRemove() {
if (this.selectRows.length <= 0) {
this.$message.error('请选择要删除的监测对象');