Commit 556d8dfe authored by liwenhong's avatar liwenhong

Merge branch 'feature/activity' into release-activity

# Conflicts:
#	server/controllers/groupmeal.js
#	server/router.js
#	src/pages/Groupmeal/Distrib/index.vue
#	src/service/Groupmeal/groupmeal.js
parents f37bb5b5 8cbfb374
......@@ -11,6 +11,7 @@
"dependencies": {
"axios": "^0.21.1",
"core-js": "^3.6.5",
"dayjs": "^1.10.6",
"element-plus": "^1.0.2-beta.44",
"form-data": "^4.0.0",
"json-bigint": "^1.0.0",
......@@ -7299,9 +7300,15 @@
"dev": true
},
"node_modules/dayjs": {
<<<<<<< HEAD
"version": "1.10.6",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.6.tgz",
"integrity": "sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw=="
=======
"version": "1.10.5",
"resolved": "https://registry.nlark.com/dayjs/download/dayjs-1.10.5.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdayjs%2Fdownload%2Fdayjs-1.10.5.tgz",
"integrity": "sha1-VgDfRUj8JFOz8WPrsqu+llzPuYY="
>>>>>>> master
},
"node_modules/deasync": {
"version": "0.1.21",
......@@ -28546,9 +28553,9 @@
"dev": true
},
"dayjs": {
"version": "1.10.5",
"resolved": "https://registry.nlark.com/dayjs/download/dayjs-1.10.5.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdayjs%2Fdownload%2Fdayjs-1.10.5.tgz",
"integrity": "sha1-VgDfRUj8JFOz8WPrsqu+llzPuYY="
"version": "1.10.6",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.6.tgz",
"integrity": "sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw=="
},
"deasync": {
"version": "0.1.21",
......@@ -17,6 +17,7 @@
"dependencies": {
"axios": "^0.21.1",
"core-js": "^3.6.5",
"dayjs": "^1.10.6",
"element-plus": "^1.0.2-beta.44",
"form-data": "^4.0.0",
"json-bigint": "^1.0.0",
......
......@@ -19,6 +19,7 @@ module.exports = {
API_INTERNAL_URI: API_INTERNAL_URI[env],
PANDORA_URI: PANDORA_URI[env],
GOODS_URI: API_INTERNAL_URI[env],
ACTIVITY_URI: API_INTERNAL_URI[env],
WITHDRAWAL_URI: API_INTERNAL_URI[env],
GROUPMEAL_URI: API_INTERNAL_URI[env],
};
const ACTIVITY_URI = require("../config.js").ACTIVITY_URI;
const req = require("../utils/request").httpReq;
// 获取商家列表
exports.getBusinessList = async ctx => {
const url = `${ACTIVITY_URI}/goods/background/ota_list`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 添加商品
exports.addGoods = async ctx => {
const url = `${ACTIVITY_URI}/goods/background/add_goods`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
// 商品库列表
exports.pindanGoods = async ctx => {
const url = `${ACTIVITY_URI}/goods/background/pindan_goods`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 查看商品详情
exports.markGoodsInfo = async ctx => {
const url = `${ACTIVITY_URI}/goods/background/marketing_goods_info`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 编辑商品
exports.editGoods = async ctx => {
const url = `${ACTIVITY_URI}/goods/background/edit_goods`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
// 获取活动过列表
exports.getActivityList = async ctx => {
const url = `${ACTIVITY_URI}/marketing/background/marketing_list`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 修改商品
exports.editGoodsDetail = async ctx => {
const url = `${ACTIVITY_URI}/goods/background/edit_goods`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
// 添加营销活动
exports.addMarketing = async ctx => {
const url = `${ACTIVITY_URI}/marketing/background/add_marketing`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
// 编辑营销活动
exports.updateMarketing = async ctx => {
const url = `${ACTIVITY_URI}/marketing/background/update_marketing`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
// 营销活动详情
exports.marketingInfo = async ctx => {
const url = `${ACTIVITY_URI}/marketing/background/marketing_info`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
// 关闭/开启 活动
exports.updateActivity = async ctx => {
const url = `${ACTIVITY_URI}/marketing/background/update_marketing_online_status`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
// 查看活动订单
exports.checkActivityDetail = async ctx => {
const url = `${ACTIVITY_URI}/marketing/background/marketing_info`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
// 查看活动订单
exports.checkActivityDetailInfo = async ctx => {
const url = `${ACTIVITY_URI}/order/background/pindan_marketing_info_data_statistics`;
const opts = {
url,
method: "GET",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
// 获取自提点列表
exports.getPlaceList = async ctx => {
const url = `${ACTIVITY_URI}/marketing/background/take_place_list`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 添加自提点
exports.addPlace = async ctx => {
const url = `${ACTIVITY_URI}/marketing/background/add_take_place`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
//删除自提点
exports.deletePlace = async ctx => {
const url = `${ACTIVITY_URI}/marketing/background/delete_take_place`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
......@@ -42,6 +42,8 @@ exports.getSaveDeliverer = async ctx => {
ctx.body = await req(ctx, opts);
};
// 老订单管理
// 获取订单管理列表
exports.getOrderList = async ctx => {
const url = `${GROUPMEAL_URI}/order/oldbackground/order_list`;
......@@ -133,3 +135,97 @@ exports.orderRefundReject = async ctx => {
};
ctx.body = await req(ctx, opts);
};
// 新订单管理
// 获取订单管理列表
exports.newGetOrderList = async ctx => {
const url = `${GROUPMEAL_URI}/order/background/order_list`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 获取活动名称
exports.newGetMarketingList = async ctx => {
const url = `${GROUPMEAL_URI}/order/background/order_condition_marketing_list`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 获取商品名称
exports.newGetGoodsList = async ctx => {
const url = `${GROUPMEAL_URI}/order/background/order_condition_goods_list`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 获取自提点
exports.newGetSubShopList = async ctx => {
const url = `${GROUPMEAL_URI}/order/background/order_condition_take_place_list`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 导出订单
exports.newOrderExport = async ctx => {
const url = `${GROUPMEAL_URI}/order/background/order_export`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 打印订单
exports.newOrderPrint = async ctx => {
const url = `${GROUPMEAL_URI}/order/background/order_print`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 订单退款列表
exports.newOrderItemList = async ctx => {
const url = `${GROUPMEAL_URI}/order/background/order_item_list`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
// 订单退款列表
exports.newOrderRefund = async ctx => {
const url = `${GROUPMEAL_URI}/order/background/order_refund`;
const opts = {
url,
method: "POST",
json: true,
body: ctx.request.body
};
ctx.body = await req(ctx, opts);
};
// 订单驳回
exports.newOrderRefundReject = async ctx => {
const url = `${GROUPMEAL_URI}/order/background/order_refund_reject`;
const opts = {
url,
method: "GET"
};
ctx.body = await req(ctx, opts);
};
......@@ -6,6 +6,7 @@ const enterprise = require("./controllers/enterprise");
const role = require('./controllers/role')
const life = require('./controllers/life-no');
const goods = require('./controllers/goods');
const activity = require('./controllers/activity');
const withdrawal = require('./controllers/withdrawal');
const groupmeal = require('./controllers/groupmeal');
......@@ -63,13 +64,33 @@ router.post(`${API_VERSION}/merchant/lifeinner/life_info`, life.get_life_info)
router.get(`${API_VERSION}/merchant/lifeinner/life_list`, life.get_life_list)
//用户
router.post(`${API_VERSION}/merchant/authority/get_user_info`, user.getUser_detail)
// 后台运营管理
router.get(`${API_VERSION}/marketing/background/marketing_list`, activity.getActivityList)
router.get(`${API_VERSION}/order/background/pindan_marketing_info_data_statistics`, activity.checkActivityDetailInfo)
router.post(`${API_VERSION}/goods/background/edit_goods`, activity.editGoodsDetail)
router.post(`${API_VERSION}/marketing/background/update_marketing_online_status`, activity.updateActivity)
router.post(`${API_VERSION}/marketing/background/marketing_info`, activity.checkActivityDetail)
//
router.get(`${API_VERSION}/marketing/background/take_place_list`, activity.getPlaceList)
router.post(`${API_VERSION}/marketing/background/add_take_place`, activity.addPlace)
router.post(`${API_VERSION}/marketing/background/delete_take_place`, activity.deletePlace)
router.get(`${API_VERSION}/goods/background/ota_list`, activity.getBusinessList);
router.post(`${API_VERSION}/goods/background/add_goods`, activity.addGoods);
router.get(`${API_VERSION}/goods/background/pindan_goods`, activity.pindanGoods);
router.get(`${API_VERSION}/goods/background/marketing_goods_info`, activity.markGoodsInfo);
router.post(`${API_VERSION}/goods/background/edit_goods`, activity.editGoods);
router.post(`${API_VERSION}/marketing/background/add_marketing`, activity.addMarketing);
router.post(`${API_VERSION}/marketing/background/marketing_info`, activity.marketingInfo);
router.post(`${API_VERSION}/marketing/background/update_marketing`, activity.updateMarketing);
// 团餐运营--配送
router.post(`${API_VERSION}/order/deliverer/list_day_deliverer_conf`, groupmeal.getList)
router.post(`${API_VERSION}/order/deliverer/list_day_deliverer`, groupmeal.getDelivererList)
router.post(`${API_VERSION}/order/deliverer/add_deliverer`, groupmeal.getAddDeliverer)
router.post(`${API_VERSION}/order/deliverer/save_day_deliverer`, groupmeal.getSaveDeliverer)
// 订单管理
// 订单管理
router.get(`${API_VERSION}/order/oldbackground/order_list`, groupmeal.getOrderList);
router.get(`${API_VERSION}/order/oldbackground/marketing_list`, groupmeal.getMarketingList);
router.get(`${API_VERSION}/order/oldbackground/goods_list`, groupmeal.getGoodsList);
......
<template>
<div>
<div class="app-wrapper">
<router-view v-slot="{ Component }">
<keep-alive v-if="$route.meta.keepAlive">
<component :is="Component"> </component>
......@@ -28,8 +28,13 @@ export default {
} else {
redirectToLogin();
}
},
}
};
</script>
<style lang="less" src="./global.less"></style>
<style lang="less" scoped>
.app-wrapper {
height: 100%;
}
</style>
<template>
<el-dialog
title="提示"
v-model="dialogVisible"
width="30%"
:before-close="handleClose"
>
<span>这是一段信息</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false"
>确 定</el-button
>
</span>
</template>
</el-dialog>
</template>
<script>
export default {
components: {},
props: {},
data() {
return {
dialogVisible: true
};
},
watch: {},
computed: {},
methods: {},
created() {},
mounted() {}
};
</script>
<style lang="less" scoped></style>
......@@ -14,7 +14,6 @@ import { redirectToLogin } from "./utils/util";
// 处理路由权限
router.beforeResolve(async (to, from, next) => {
if (!to.meta.requireAuth) {
next();
return true;
......@@ -22,9 +21,9 @@ router.beforeResolve(async (to, from, next) => {
if (!store.state.permissions) {
const { status, user } = await fetchCurrentUser();
if (status === 'success') {
store.commit('updateUserInfo', user);
await store.dispatch('updateUserPermission', { email: user.email })
if (status === "success") {
store.commit("updateUserInfo", user);
await store.dispatch("updateUserPermission", { email: user.email });
} else {
redirectToLogin();
return false;
......@@ -32,11 +31,11 @@ router.beforeResolve(async (to, from, next) => {
}
if (!checkPathAuth(to.path)) {
router.push({name: 'Forbidden'})
router.push({ name: "Forbidden" });
} else {
next()
next();
}
})
});
createApp(App)
.use(router)
......
<template>
<div
class="wrapper"
v-loading="pageLoading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
>
<!-- 商品详情信息 -->
<div class="activityInfo-wrapper">
<el-card class="activityInfo">
<div class="infoItem">
<p class="infoItemText">{{ detailInfo.order_count }}</p>
<p>订单数量</p>
</div>
<div class="infoItem">
<p class="infoItemText">{{ detailInfo.sold_goods_count }}</p>
<p>已售商品数量</p>
</div>
<div class="infoItem">
<p class="infoItemText">{{ detailInfo.pay_amount_count }}</p>
<p>支付金额</p>
</div>
<div class="infoItem">
<p class="infoItemText">{{ detailInfo.discount_amount_count }}</p>
<p>优惠金额</p>
</div>
<div class="infoItem">
<p class="infoItemText">{{ detailInfo.refund_count }}</p>
<p>退款</p>
</div>
<div class="infoItem">
<p class="infoItemText">{{ detailInfo.real_income_count }}</p>
<p>实际收入</p>
</div>
</el-card>
</div>
<!-- 商品详情 -->
<div class="activityDetail">
<section class="content">
<!-- 商品列表 -->
<el-card class="activityGoods box-card">
<div class="my-header">
<h3>{{ marketingInfo.marketing_name }}</h3>
<p class="endTime">{{ showTimer }}</p>
</div>
<p class="title">拼单商品</p>
<div class="images-wrapper">
<div
class="image-block"
v-for="picItem in goodsList"
:key="picItem.audit_status"
>
<el-image
class="activityImage"
style="width: 100px; height: 100px"
:src="picItem.desc_pic_url_list[0]"
fit="cover"
></el-image>
<span class="goodsPrice">{{ `¥${picItem.price}` }}</span>
</div>
</div>
</el-card>
<!-- 商品描述 -->
<el-card class="activityIntroduce box-card">
<p class="introduceText">
{{ marketingInfo.pindan_desc }}
</p>
<el-image
v-for="(picItem, index) in marketingInfo.pindan_pic_url"
:key="index"
class="activityImage"
style="width: 100%; height: 400px"
:src="picItem"
fit="contain"
></el-image>
</el-card>
<el-card class="activities box-card">
<div
v-for="goodsItem in goodsList"
:key="goodsItem.goods_sku_id"
class="activityItem"
>
<el-image
class="activityImage"
style="width: 100px; height: 100px"
:src="goodsItem.desc_pic_url_list[0]"
fit="fit"
></el-image>
<div class="itemIntroduce">
<p>{{ goodsItem.goods_name }}</p>
<p class="price">
<span class="nowPrice">{{ `¥${goodsItem.price}` }}</span>
<span class="originPrice">{{
`¥${goodsItem.original_price} `
}}</span>
</p>
</div>
</div>
</el-card>
</section>
</div>
<div class="button-close">
<el-button
class="button-block"
size="medium"
type="primary"
@click="closePage"
> </el-button
>
</div>
</div>
</template>
<script>
import ActivityService from "@/service/Activity/index";
import { ElMessage } from "element-plus";
import dayJs from "dayjs";
export default {
props: {},
data() {
return {
pageLoading: false,
goodsList: [],
marketingInfo: {},
endTime: "",
showTimer: "",
detailInfo: {}
};
},
watch: {},
computed: {},
methods: {
async checkActivityDetail() {
try {
this.pageLoading = true;
let dataArr = await Promise.all([
ActivityService.checkActivityDetail({
marketing_id: this.$route.query.marketing_id,
marketing_type: this.$route.query.marketing_type
}),
ActivityService.checkActivityDetailInfo({
marketing_id: this.$route.query.marketing_id
})
]);
this.pageLoading = false;
this.goodsList = dataArr[0].result.goods_list;
this.marketingInfo = dataArr[0].result.marketing_info;
this.endTime = dataArr[0].result.marketing_info.end_time;
this.detailInfo = dataArr[1].result;
} catch {
this.pageLoading = false;
ElMessage.error("加载失败");
}
},
// 时间差转时分秒
getTimeout(timeCount) {
if (timeCount > 0) {
var days = parseInt(timeCount / (1000 * 60 * 60 * 24));
var hours = parseInt(
(timeCount % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
);
var minutes = parseInt((timeCount % (1000 * 60 * 60)) / (1000 * 60));
var seconds = parseInt((timeCount % (1000 * 60)) / 1000);
this.showTimer =
"距结束:" +
days +
" 天 " +
hours +
" 小时 " +
minutes +
" 分钟 " +
seconds +
" 秒 ";
} else {
this.showTimer = "已结束";
}
},
// 定时器
myTimer() {
let dateNow = dayJs();
this.timer = setInterval(() => {
dateNow = dayJs().subtract(1, "minute");
let myTime = dayJs(this.endTime).diff(dateNow); // 时间差
this.getTimeout(myTime);
if (this.myTime <= 0) {
clearInterval(this.timer);
}
}, 1000);
},
closePage() {
this.$router.go(-1);
}
},
async created() {
await this.checkActivityDetail();
this.myTimer();
},
beforeUnmount() {
clearInterval(this.timer);
}
};
</script>
<style lang="less" scoped>
.wrapper {
height: 100%;
display: flex;
overflow-y: scroll;
flex-direction: column;
justify-content: flex-start;
align-items: center;
padding: 45px 10px 0;
.activityInfo {
width: 500px;
/deep/ .el-card__body {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.infoItem {
width: 33%;
text-align: center;
margin-bottom: 20px;
.infoItemText {
font-weight: bolder;
}
}
}
.activityDetail {
width: 500px;
.content {
.my-header {
.endTime {
margin: 5px 0;
font-size: 15px;
color: red;
}
}
.box-card {
margin: 10px 0;
}
.activityGoods {
.images-wrapper {
display: flex;
flex-wrap: wrap;
.image-block {
margin: 0 5px 0 0px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.goodsPrice {
color: red;
font-size: 18px;
}
}
.image-block:nth-child(4n + 0) {
margin-right: 0;
}
}
.activityImage {
margin: 10px 10px 0 0;
}
}
.activityIntroduce {
padding: 5px 0;
.introduceText {
margin-bottom: 20px;
}
}
.activities {
.activityItem {
display: flex;
margin: 15px 0;
.itemIntroduce {
display: flex;
flex-direction: column;
justify-content: space-around;
margin-left: 10px;
> p {
width: 200px;
}
.price {
.nowPrice {
color: red;
padding-right: 10px;
}
.originPrice {
text-decoration: line-through;
}
}
}
}
}
}
}
.button-close {
margin: 10px 0 30px;
.button-block {
width: 200px;
}
}
}
</style>
.header {
width: 100%;
height: 100%;
padding: 0 30px;
}
\ No newline at end of file
<template>
<layout>
<div
class="manage-wrapper"
v-loading="tableLoading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
>
<el-form
ref="form"
:model="activity"
inline
label-width="80px"
class="form-wrapper"
>
<!-- 表单控件 -->
<div class="formitem-wrapper">
<el-form-item label="活动名称">
<el-input v-model="activity.activityName"></el-input>
</el-form-item>
<el-form-item label="活动状态">
<el-select v-model="activity.online_status">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item style="margin-left: 50px">
<el-button type="primary" @click="getActivityList">搜索</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="goReleaseProduc"
>发布拼单</el-button
>
</el-form-item>
</div>
<!-- 列表 -->
<div class="table-wrapper">
<el-table :data="tableActivityList" border style="width: 100%">
<el-table-column
align="center"
prop="activiteId"
label="活动ID"
width="width"
>
</el-table-column>
<el-table-column
align="center"
prop="activiteHead"
label="活动标题"
width="width"
>
<template #default="scope">
<div @click="handleHeadline(scope.row)" class="activityTitle">
<div>
{{ scope.row.activiteHead }}
</div>
<div class="activityPrice">
{{
scope.row.minPrice === scope.row.maxPrice
? ` ¥ ${scope.row.minPrice}`
: ` ¥ ${scope.row.minPrice}~¥${scope.row.maxPrice} `
}}
</div>
</div>
</template>
</el-table-column>
<el-table-column
align="center"
prop="activiteStatus"
label="活动状态"
width="width"
>
</el-table-column>
<el-table-column
align="center"
prop="orderNumber"
label="订单数量"
width="width"
>
</el-table-column>
<el-table-column
align="center"
prop="scope"
label="操作"
width="250"
>
<template #default="scope">
<div class="button-one">
<el-button
type="primary"
size="small"
@click="handleModify(scope.row)"
>修改</el-button
>
<el-popconfirm
title="确定要结束本次拼单吗?"
@confirm="updateActivity"
>
<template #reference>
<el-button
v-show="scope.row.status === 1"
type="primary"
size="small"
@click="handleEnd(scope.row)"
>结束</el-button
>
</template>
</el-popconfirm>
<el-popconfirm
title="确定要开启本次拼单吗?"
@confirm="updateActivity"
>
<template #reference>
<el-button
v-show="
scope.row.status === 2 || scope.row.status === 3
"
type="primary"
size="small"
@click="handleStart(scope.row)"
>开始</el-button
>
</template>
</el-popconfirm>
</div>
<el-button
class="checkButton"
type="primary"
size="small"
@click="handleLook(scope.row)"
>查看订单</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div class="pagination-wrapper">
<el-pagination
background
layout="prev, pager, next"
:total="pageCount"
:page-size="10"
@current-change="handleCurrentChange"
>
</el-pagination>
</div>
</el-form>
</div>
<YDDialog />
</layout>
</template>
<script>
import layout from "../../Groupmeal/layout/index.vue";
import { ElMessage } from "element-plus";
import ActivityService from "@/service/Activity/index";
import dayJs from "dayjs";
export default {
name: "Manage",
components: {
layout
},
data() {
return {
activity: {
activityName: "",
online_status: ""
},
pageCount: 0, // 总条数
currentPage: 1, //当前页码
pageSize: 10, // 每页条数
storeQuery: {}, // 存储开始 结束 参数
tableActivityList: [],
tableLoading: false,
options: [
{ value: "", label: "全部" },
{ value: "1", label: "未开始" },
{ value: "2", label: "进行中" },
{ value: "3", label: "已结束" }
]
};
},
methods: {
/* API */
// 获取商品列表
async getActivityList() {
let params = {
marketing_name: this.activity.activityName,
activity_status: this.activity.online_status, //1 未开始,2进行中,3已结束 空值 全部
marketing_type: 4, //1分销 2团购 3秒杀 4团餐 默认传4
// marketing_id: "",
page: this.currentPage,
page_size: this.pageSize
};
try {
this.tableLoading = true;
let data = await ActivityService.getActivityList(params);
this.filterTableActiveList(data.result);
this.pageCount = data.count;
this.tableLoading = false;
} catch {
this.tableLoading = false;
ElMessage.error("加载失败");
}
},
/* API */
// 结束 开始
async updateActivity() {
try {
this.tableLoading = true;
let data = await ActivityService.updateActivity(this.storeQuery);
if (data.code === 0) {
await this.getActivityList();
} else {
this.tableLoading = false;
ElMessage.error(data.reason);
}
} catch {
this.tableLoading = false;
}
},
/* API */
// 修改
/* API */
// 查看订单
// 数据转换成tableData格式
filterTableActiveList(tableData) {
this.tableActivityList = tableData.map(item => {
let activityStatusText = "";
let dateNow = dayJs();
if (dateNow.diff(dayJs(item.start_time)) < 0) {
// 开始时间大于当前时间 return 未开始
activityStatusText = "未开始";
} else if (
dateNow.diff(dayJs(item.start_time)) > 0 &&
dateNow.diff(dayJs(item.end_time)) < 0
) {
// 结束时间大于开始时间 return 进行中
activityStatusText = "进行中";
} else if (dateNow.diff(dayJs(item.end_time)) > 0) {
// 当前时间大于结束时间 return 已结束
activityStatusText = "已结束";
}
return {
activiteId: item.marketing_id,
activiteHead: item.marketing_name,
activiteStatus: activityStatusText,
status: item.online_status,
minPrice: item.min_price,
maxPrice: item.max_price,
marketing_type: 4
};
});
},
// 更改页数
handleCurrentChange(val) {
this.currentPage = val;
this.getActivityList();
},
// 点击活动标题
async handleHeadline(val) {
this.$router.push({
name: "ActivityDetail",
query: {
marketing_id: val.activiteId,
marketing_type: val.marketing_type
}
});
},
// 发布拼单
goReleaseProduc() {
this.$router.push("/op/activity/releaseProduc");
},
// 修改
handleModify(val) {
this.$router.push({
path: "/op/activity/releaseProduc",
query: {
marketing_id: val.activiteId,
marketing_type: val.marketing_type
}
});
},
// 结束
handleEnd(val) {
this.storeQuery = {
marketing_id: val.activiteId,
online_status: 2, // 1 启用 2 关闭
marketing_type: 4
// end_time: dayJs().format("YYYY-MM-DD HH:mm:ss")
};
},
// 开始
handleStart(val) {
this.storeQuery = {
marketing_id: val.activiteId,
online_status: 1, // 1 启用 2 关闭
marketing_type: 4
};
},
// 查看详情
handleLook(row) {
this.$router.push({
path: "/op/groupmeal/newOrderManagement",
query: {
marketing_id: row.activiteId,
marketing_type: row.marketing_type
}
});
}
},
created() {
this.getActivityList();
}
};
</script>
<style lang="less" src="./index.less" scope></style>
<style lang="less" scoped>
.manage-wrapper {
height: 100%;
}
.header {
height: 100%;
}
.form-wrapper {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
.el-card__body {
height: 100%;
}
.formitem-wrapper {
height: 100px;
display: flex;
align-items: flex-end;
}
.table-wrapper {
flex: 1;
overflow-y: scroll;
}
.pagination-wrapper {
width: 100%;
height: 100px;
bottom: 20px;
display: flex;
justify-content: center;
align-items: center;
}
}
.checkButton {
margin-top: 5px;
}
.activityTitle {
cursor: pointer;
}
.activityPrice {
color: red;
}
</style>
<template>
<div class="addProduc">
<!-- 按钮组 -->
<div class="btnGroup">
<el-button class="addCommodityBtn" @click="commodity('add', '')"
>添加商品</el-button
>
<el-button class="commodLibraryAdd" @click="commodLibraryAdd"
>从商品库添加</el-button
>
</div>
<!-- Tab -->
<el-table :data="comTableData" border style="width: 100%">
<el-table-column label="显示顺序" align="center" width="140">
<template #default="scope">
<i class="el-icon-top" @click="upMove(scope.$index, scope.row)"></i>
<i
class="el-icon-bottom"
@click="upDown(scope.$index, scope.row)"
></i>
</template>
</el-table-column>
<el-table-column
prop="goods_sku_id"
label="商品ID"
width="180"
></el-table-column>
<el-table-column
prop="goods_name"
label="商品标题"
width="180"
></el-table-column>
<el-table-column prop="price" label="售价"> </el-table-column>
<el-table-column prop="ota_name" label="商家"> </el-table-column>
<el-table-column prop="inventory_total" label="库存"> </el-table-column>
<el-table-column prop="total_amount_sold" label="已售数量">
</el-table-column>
<el-table-column prop="inventory_rest" label="剩余库存"></el-table-column>
<el-table-column label="操作" width="120">
<template #default="scope">
<el-button
type="text"
size="small"
@click="commodity('update', scope.row)"
>修改</el-button
>
<el-button type="text" size="small" @click="removeCom(scope.row)"
>移除</el-button
>
</template>
</el-table-column>
</el-table>
<!-- 添加商品 -->
<el-dialog
:title="addCommodityTitle"
v-model="addCommodityPopup"
width="40%"
>
<el-form
:inline="true"
:model="commodityForm"
ref="infoForm"
class="demo-form-inline infoForm"
label-width="100px"
>
<el-form-item label="图片:">
<el-upload
:class="{ hide: hideUpload }"
:data="{ type: 1 }"
:action="uploadUrl"
:on-preview="previewImage"
:on-success="handleDetailSuccess"
:on-change="handleDetailChange"
:before-remove="removeDetailFiles"
:file-list="picUrlList"
auto-upload
ref="picUpload"
:limit="limitCount"
list-type="picture-card"
multiple
>
<template #default>
<i class="el-icon-plus"></i>
</template>
</el-upload>
</el-form-item>
<el-form-item
label="商品标题:"
prop="goods_name"
:rules="[{ required: true, message: '请输入商品标题' }]"
>
<el-input
v-model="commodityForm.goods_name"
maxlength="30"
></el-input>
</el-form-item>
<el-form-item
label="售价:"
prop="price"
:rules="[{ required: true, message: '请输入售价' }]"
>
<el-input-number
class="price"
v-model="commodityForm.price"
:min="0"
:controls="false"
:precision="2"
placeholder=""
></el-input-number>
</el-form-item>
<el-form-item label="划线价:">
<el-input-number
class="price"
v-model="commodityForm.original_price"
:min="0"
:controls="false"
:precision="2"
placeholder=""
></el-input-number>
</el-form-item>
<br />
<el-form-item label="新增库存:">
<el-input
v-model="commodityForm.inventory_total"
placeholder=""
@input="inventoryIpt"
></el-input>
</el-form-item>
<div style="display: inline-block; height: 42px; margin-left: 33px">
已售:<span style="margin-right: 10px">{{
commodityForm.total_amount_sold
}}</span>
剩余库存:<span>{{ inventoryRest }}</span>
</div>
<br />
<el-form-item
label="商家"
prop="business1"
:rules="[{ required: true, message: '请选择商家' }]"
>
<el-select v-model="commodityForm.business1" placeholder="请选择">
<el-option
v-for="item in businessOpt"
:key="item.ota_id"
:label="item.ota_name"
:value="item.ota_id"
></el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="commodityCancel">取 消</el-button>
<el-button type="primary" @click="commoditySave('infoForm')"
>保存</el-button
>
</span>
</template>
</el-dialog>
<!-- 展示缩略图 -->
<el-dialog width="40%" v-model="isShowPopver">
<el-image :src="popoverImage" fit="fill" style="width: 100%"></el-image>
</el-dialog>
<!-- 从商品库添加 -->
<el-dialog
title="选择商品"
v-model="selCommodityPopup"
width="60%"
top="2%"
>
<div>
<span>商家:</span>
<el-select
v-model="business2"
placeholder="请选择"
@change="business2Sel"
>
<el-option
v-for="item in businessOpt"
:key="item.ota_id"
:label="item.ota_name"
:value="item.ota_id"
></el-option>
</el-select>
</div>
<span class="dioFor">已选:{{ multipleSelection.length }}件</span>
<el-table
:data="comLibTableData"
class="comLibTableData"
@selection-change="selectGoodsChange"
>
<el-table-column type="selection" width="55"> </el-table-column>
<el-table-column
prop="goods_sku_id"
label="商品ID"
width="150"
></el-table-column>
<el-table-column
prop="goods_name"
label="名称"
width="200"
></el-table-column>
<el-table-column prop="price" label="售价"></el-table-column>
<el-table-column prop="ota_name" label="商家"></el-table-column>
<el-table-column prop="inventory_total" label="库存"></el-table-column>
<el-table-column
prop="total_amount_sold"
label="已售数量"
></el-table-column>
<el-table-column
prop="inventory_rest"
label="剩余库存"
></el-table-column>
<el-table-column label="操作" width="100">
<template #default="scope">
<el-button
@click="commodity('update', scope.row)"
type="text"
size="small"
>修改</el-button
>
</template>
</el-table-column>
</el-table>
<template #footer>
<span class="dialog-footer">
<el-button @click="selCommodityPopup = false">取 消</el-button>
<el-button type="primary" @click="comLibrarySave">保存</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import { GOODS_URI } from "../../../../../server/config";
import store from "../../../../store/index";
import { ElMessage } from "element-plus";
import {
addGoods,
getBusinessList,
pindanGoods,
markGoodsInfo,
editGoods
} from "../../../../service/Activity/index";
export default {
props: {
editInfo: {
type: Object,
required: () => {}
},
addProduc: {
type: Array,
required: () => {}
},
stepTwoTitle: {
type: String,
default: ""
}
},
data() {
return {
// 商品列表
comTableData: [],
// 商品库列表
comLibTableData: [],
businessOpt: [], // 商家数据
// 添加商品
addCommodityPopup: false, // 添加商品弹窗状态
addCommodityTitle: "", // 标题
commodityForm: {
goods_name: "",
price: "",
original_price: "",
inventory_total: null,
total_amount_order: null,
business1: ""
},
picStr: "",
picUrlList: [],
picUploadList: [], // 上传详情图片列表
isShowPopver: false, // 是否展示图片框
uploadUrl: `${GOODS_URI}/ksy/ks3apiunencrypt/ks3api_upload`, // 金山云上传地址
hideUpload: false,
limitCount: 1,
// 商品库添加
selCommodityPopup: false, // 商品库添加弹窗状态
business2: "", // 商家
multipleSelection: [], // 勾选的数据
goodsSkuID: "",
inventoryTotal: 0, // 总库存
inventoryRest: 0 // 剩余库存
};
},
// computed: {
// // 计算剩余库存
// inventoryRest() {
// if (this.commodityForm.inventory_total == null) {
// return 0;
// } else {
// return Number(
// this.commodityForm.inventory_total -
// this.commodityForm.total_amount_order
// );
// }
// },
// },
methods: {
// 上移
upMove(index) {
if (index <= 0) {
this.$message.error("不能继续向上移动");
} else {
const upData = this.comTableData[index - 1];
this.comTableData.splice(index - 1, 1);
this.comTableData.splice(index, 0, upData);
}
},
// 下移
upDown(index) {
if (index === this.comTableData.length - 1) {
this.$message.error("不能继续向下移动");
} else {
const downData = this.comTableData[index + 1];
this.comTableData.splice(index + 1, 1);
this.comTableData.splice(index, 0, downData);
}
},
// 库存计算
inventoryIpt(val) {
var pattern = /^-?[1-9]\d*$|^0$/g;
if (!pattern.test(this.commodityForm.inventory_total)) {
this.commodityForm.inventory_total = "";
this.inventoryRest =
this.inventoryTotal - this.commodityForm.total_amount_order;
} else {
this.inventoryRest =
Number(val) +
this.inventoryTotal -
this.commodityForm.total_amount_order;
}
},
// 展示商品大图
previewImage(file) {
this.popoverImage = file.url;
this.isShowPopver = true;
},
handleDetailChange() {
this.hideUpload = this.picUploadList.length >= this.limitCount;
},
// 图片上传成功时
handleDetailSuccess(res) {
this.picStr = res.result.image_id;
this.picUploadList.push(res.result.image_id);
},
// 图片删除后
removeDetailFiles(file, fileList) {
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].uid == file.uid) {
this.picUploadList.splice(i, 1);
}
}
this.picStr = "";
this.hideUpload = this.picUploadList.length >= this.limitCount;
},
// 获取商家
async getBusinessListMet() {
let params = { ota_name: "", offset: "", limit: "" };
try {
const res = await getBusinessList(params);
this.businessOpt = [
{ ota_id: "", ota_name: "全部" },
...res.result.list
];
} catch (error) {
this.$message.error("发生未知错误,请稍后再试一下吧~~~");
console.error(error);
}
},
// 查看商品详情
async markGoodsInfoMet(goodSkuID) {
this.picUrlList = [];
let params = { goods_sku_id: goodSkuID, marketing_type: "4" };
const res = await markGoodsInfo(params);
this.inventoryRest = res.result.goods_info.inventory_rest;
this.inventoryTotal = res.result.goods_info.inventory_total;
this.commodityForm = res.result.goods_info;
this.commodityForm.business1 = res.result.goods_info.ota_id;
for (var i in res.result.goods_info.desc_pic_url_list) {
this.picUrlList.push({
url: res.result.goods_info.desc_pic_url_list[i]
});
}
this.picStr = this.getUrlParms(
res.result.goods_info.desc_pic_url_list[0],
"url"
);
},
getUrlParms(path, name) {
var reg = new RegExp("(^|\\?|&)" + name + "=([^&]*)(\\s|&|$)", "i");
if (reg.test(path)) return unescape(RegExp.$2.replace(/\+/g, " "));
return "";
},
// 编辑商品详情
async editGoodsMet(goodsSkuID) {
const res = await editGoods({
goods_name: this.commodityForm.goods_name,
desc_pic_url: this.picStr,
desc: "",
inventory_add: this.commodityForm.inventory_total,
original_price: this.commodityForm.original_price,
price: this.commodityForm.price,
marketing_name: this.editInfo.title,
marketing_type: "4",
ota_id: this.commodityForm.business1,
op_cur_user: store.state.userInfo.email,
goods_sku_id: goodsSkuID
});
if (res.code == 0) {
ElMessage.success({
message: "修改成功",
type: "success"
});
await this.pindanGoodsMet();
let result = null;
for (var j in this.comLibTableData) {
if (this.comLibTableData[j].goods_sku_id == goodsSkuID) {
result = this.comLibTableData[j];
}
}
for (var i in this.comTableData) {
if (this.comTableData[i].goods_sku_id == result.goods_sku_id) {
this.comTableData.splice(i, 1, result);
}
}
this.addCommodityPopup = false;
} else {
ElMessage.error(res.reason);
}
},
// 获取商品库列表
async pindanGoodsMet(otaID, goodsName) {
let params = { ota_id: otaID, goods_name: goodsName };
const res = await pindanGoods(params);
this.comLibTableData = res.result.list;
},
// 添加修改商品
async commodity(type, val) {
this.addCommodityPopup = true;
this.commodityForm = {};
if (type == "add") {
this.inventoryRest = 0;
this.commodityForm.total_amount_order = 0;
this.picUrlList = [];
this.addCommodityTitle = "商品添加";
this.$refs.infoForm.resetFields();
} else {
this.addCommodityTitle = "商品编辑";
this.goodsSkuID = val.goods_sku_id;
this.markGoodsInfoMet(this.goodsSkuID);
}
},
// 添加商品
async addGoodsMet() {
const res = await addGoods({
marketing_name: this.stepTwoTitle,
goods_name: this.commodityForm.goods_name,
desc_pic_url: this.picUploadList.join(","),
desc: "",
inventory: this.commodityForm.inventory_total,
original_price: this.commodityForm.original_price,
marketing_type: "4",
price: this.commodityForm.price,
ota_id: this.commodityForm.business1,
op_cur_user: store.state.userInfo.email
});
if (res.code == 0) {
ElMessage.success({
message: "添加商品成功",
type: "success"
});
this.comTableData.push(res.result.goods_info);
this.addCommodityPopup = false;
} else {
ElMessage.error(res.reason);
}
},
// 添加商品取消
commodityCancel() {
this.addCommodityPopup = false;
this.$refs.infoForm.clearValidate();
},
// 添加商品保存
commoditySave(infoForm) {
this.$refs[infoForm].validate(valid => {
if (valid) {
if (this.addCommodityTitle == "商品添加") {
this.addGoodsMet();
} else {
this.editGoodsMet(this.goodsSkuID);
}
} else {
return false;
}
});
},
// 从商品库添加
async commodLibraryAdd() {
this.selCommodityPopup = true;
this.pindanGoodsMet();
},
// 商家选择(选择商品)
business2Sel(val) {
this.pindanGoodsMet(val, "");
},
// 商品库中选择商品
selectGoodsChange(val) {
this.multipleSelection = val;
},
// 商品库选择商品保存
comLibrarySave() {
if (this.multipleSelection.length == 0) {
ElMessage.error("请选择商品");
return;
}
this.selCommodityPopup = false;
if (this.comTableData.length == 0) {
this.comTableData.push(...this.multipleSelection);
} else {
this.multipleSelection.forEach(item => {
let num = 0;
this.comTableData.some(val => {
num++;
if (val.goods_sku_id === item.goods_sku_id) {
val.goods_sku_id = item.goods_sku_id;
if (num == 1) {
ElMessage.error("商品添加重复,已过滤掉重复选项");
}
return true;
} else if (num === this.comTableData.length) {
this.comTableData.push(Object.assign({}, item));
}
});
});
}
},
// 移除
removeCom(val) {
for (var i in this.comTableData) {
if (this.comTableData[i].goods_sku_id == val.goods_sku_id) {
this.comTableData.splice(i, 1);
}
}
}
},
watch: {
addProduc: function(newVal) {
let marketingId = this.$route.query.marketing_id;
if (marketingId == undefined) {
return;
}
this.comTableData = newVal;
}
},
created() {
this.getBusinessListMet();
}
};
</script>
<style scoped>
.addProduc {
width: 90%;
margin: 0 auto;
}
.btnGroup {
margin-bottom: 15px;
}
.addCommodityBtn {
margin: 0 20px 0 0;
}
.infoForm /deep/.el-form-item:nth-child(1),
.infoForm /deep/.el-form-item:nth-child(2) {
width: 100%;
}
.dioFor {
display: block;
margin: 10px 0;
}
.comLibTableData /deep/ .el-table__body-wrapper {
height: 550px;
overflow: scroll;
}
.price /deep/ .el-input__inner {
text-align: left;
}
.hide /deep/ .el-upload--picture-card {
display: none;
}
</style>
<template>
<div class="infoEditing">
<el-form ref="infoEditForm" :model="infoEditForm" label-width="80px">
<el-form-item label="标题:">
<el-input v-model="infoEditForm.title" maxlength="30"></el-input>
</el-form-item>
<el-form-item label="介绍:">
<el-input
type="textarea"
v-model="infoEditForm.desc"
maxlength="1000"
rows="4"
></el-input>
</el-form-item>
<el-form-item label="图片:">
<el-upload
:class="{ hide: hideUpload }"
:data="{ type: 1 }"
:action="uploadUrl"
:on-preview="previewImage"
:on-success="handleDetailSuccess"
:on-change="handleDetailChange"
:before-remove="removeDetailFiles"
:file-list="infoEditForm.picUrlList"
auto-upload
ref="picUpload"
:limit="limitCount"
list-type="picture-card"
multiple
>
<template #default>
<i class="el-icon-plus"></i>
</template>
</el-upload>
</el-form-item>
</el-form>
<!-- 展示缩略图 -->
<el-dialog width="40%" v-model="isShowPopver">
<el-image :src="popoverImage" fit="fill" style="width: 100%"></el-image>
</el-dialog>
</div>
</template>
<script>
import { GOODS_URI } from "../../../../../server/config";
export default {
props: {
infoEditArr: {
type: Object,
default: () => {
return {
pindan_pic_url: []
};
},
require: true
}
},
data() {
return {
infoEditForm: {
title: "", // 标题
desc: "", // 介绍
picUploadList: [], // 上传详情图片列表
picUrlList: [] // 图片回显列表
},
picSubmitList: [], // 发布功能需要的图片列表
propData: {},
isShowPopver: false, // 是否展示图片框
uploadUrl: `${GOODS_URI}/ksy/ks3apiunencrypt/ks3api_upload`, // 金山云上传地址
hideUpload: false,
limitCount: 9
};
},
watch: {
infoEditArr: {
// 监听props属性 展示自提点列表
handler: function(newVal) {
if (this.$route.query.marketing_id) {
this.propData = newVal;
this.infoEditForm.title = this.propData.marketing_name;
this.infoEditForm.desc = this.propData.pindan_desc;
for (var i in this.propData.pindan_pic_url) {
this.infoEditForm.picUrlList.push({
url: this.propData.pindan_pic_url[i]
});
this.picSubmitList.push({
url: this.propData.pindan_pic_url[i]
});
}
this.hideUpload = this.picSubmitList.length >= this.limitCount; // 大于9 隐藏
}
},
deep: true,
immediate: true
}
},
methods: {
// 展示商品大图
previewImage(file) {
this.popoverImage = file.url;
this.isShowPopver = true;
},
handleDetailChange() {
this.hideUpload = this.picSubmitList.length >= this.limitCount;
},
// 图片上传成功时
handleDetailSuccess(res) {
this.infoEditForm.picUploadList.push(res.result.image_id); // 上传成功图片的id
this.picSubmitList.push({
// 发布功能需要的图片列表
url: res.result.url
});
this.hideUpload = this.picSubmitList.length >= this.limitCount;
},
// 图片删除后
removeDetailFiles(file, fileList) {
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].uid == file.uid) {
this.picSubmitList.splice(i, 1);
}
}
this.hideUpload = this.picSubmitList.length >= this.limitCount;
},
// 获取营销活动详情
marketingInfoMet() {
let marketingId = this.$route.query.marketing_id;
if (marketingId == undefined) {
return;
}
this.propData = JSON.parse(localStorage.getItem("propData"));
this.infoEditForm.title = this.propData.marketing_name;
this.infoEditForm.desc = this.propData.pindan_desc;
for (var i in this.propData.pindan_pic_url) {
this.infoEditForm.picUrlList.push({
url: this.propData.pindan_pic_url[i]
});
}
}
},
created() {
// this.marketingInfoMet();
}
};
</script>
<style scoped>
.infoEditing {
width: 64%;
margin: 0 auto;
}
.hide /deep/ .el-upload--picture-card {
display: none;
}
</style>
<template>
<div id="map" class="mapContainer">
<div class="mapWrapper">
<div class="search">
<el-form ref="form" label-width="80px">
<el-form-item label-position="left">
<el-button @click="handleSearch">搜索</el-button>
<el-input
class="dialog-input"
v-model="searchKey"
placeholder="请输入关键字"
autocomplete="on"
>
<template #suffix>
<i
@click="searchKey = ''"
class="el-input__icon el-icon-close"
></i>
</template>
</el-input>
</el-form-item>
</el-form>
<div id="js-result" v-show="searchKey" class="result"></div>
</div>
<div id="js-container" class="myMap">
正在加载数据 ...
</div>
</div>
<div class="mapInfo">
<h3 class="title">拖拽选址</h3>
<ul class="info">
<li><span>经度:</span>{{ dragData.lng }}</li>
<li><span>纬度:</span>{{ dragData.lat }}</li>
<li><span>地址:</span>{{ dragData.address }}</li>
</ul>
</div>
<div class="confirmButton">
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="confirm">确 定</el-button>
</div>
</div>
</template>
<script>
import remoteLoad from "@/utils/remoteLoad.js";
export default {
name: "app",
data() {
return {
dialogVisible: true,
MapCityName: "北京",
searchKey: "",
dragData: {
lng: null,
lat: null,
address: null,
nearestJunction: null,
nearestRoad: null,
nearestPOI: null
}
};
},
methods: {
// 取消
cancel() {
this.$emit("hideMapDialog", false);
},
// 确认
confirm() {
this.$emit("getMapInfo", this.dragData);
this.$emit("hideMapDialog", false);
},
// 搜索
handleSearch() {
if (this.searchKey) {
this.placeSearch.search(this.searchKey);
}
},
dragMap(data) {
this.dragData = {
lng: data.position.lng,
lat: data.position.lat,
address: data.address,
province: data.regeocode.addressComponent.province,
city: data.regeocode.addressComponent.city,
area: data.regeocode.addressComponent.district
};
},
// 初始化地图
initMap() {
// 加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分
let AMapUI = (this.AMapUI = window.AMapUI);
let AMap = (this.AMap = window.AMap);
AMapUI.loadUI(["misc/PositionPicker"], PositionPicker => {
let mapConfig = {
zoom: 16
// cityName: this.MapCityName
};
if (this.lat && this.lng) {
mapConfig.center = [this.lng, this.lat];
}
let map = new AMap.Map("js-container", mapConfig);
// 加载地图搜索插件
AMap.service("AMap.PlaceSearch", () => {
this.placeSearch = new AMap.PlaceSearch({
pageSize: 5,
pageIndex: 1,
citylimit: true,
// city: this.MapCityName,
map: map,
panel: "js-result"
});
});
// 启用工具条
AMap.plugin(["AMap.ToolBar"], function() {
map.addControl(
new AMap.ToolBar({
position: "RB"
})
);
});
// 地图地图定位
AMap.plugin("AMap.Geolocation", function() {
var geolocation = new AMap.Geolocation({
// 是否使用高精度定位,默认:true
enableHighAccuracy: true,
// 设置定位超时时间,默认:无穷大
timeout: 10000,
// 定位按钮的停靠位置的偏移量,默认:Pixel(10, 20)
buttonOffset: new AMap.Pixel(10, 20),
// 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
zoomToAccuracy: true,
// 定位按钮的排放位置, RB表示右下
buttonPosition: "RB"
});
map.addControl(geolocation);
geolocation.getCurrentPosition();
AMap.event.addListener(geolocation, "complete", onComplete);
AMap.event.addListener(geolocation, "error", onError);
function onComplete(data) {
console.log(data);
// data是具体的定位信息
}
function onError(data) {
console.log(data);
// 定位出错
}
});
// 创建地图拖拽
let positionPicker = new PositionPicker({
mode: "dragMap", // 设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'
map: map, // 依赖地图对象
iconStyle: {
//自定义外观
url: "//webapi.amap.com/ui/1.0/assets/position-picker2.png", //图片地址
size: [50, 50], //要显示的点大小,将缩放图片
ancher: [24, 40] //锚点的位置,即被size缩放之后,图片的什么位置作为选中的位置
}
});
// 拖拽完成发送自定义 drag 事件
positionPicker.on("success", positionResult => {
this.dragMap(positionResult);
});
// 启动拖放
positionPicker.start();
});
}
},
async created() {
// 已载入高德地图API,则直接初始化地图
if (window.AMap && window.AMapUI) {
this.initMap();
// 未载入高德地图API,则先载入API再初始化
} else {
await remoteLoad(
`http://webapi.amap.com/maps?v=1.3&key=bb057625545d8cf77df1379e7aaae0b5`
);
await remoteLoad("http://webapi.amap.com/ui/1.0/main.js");
this.initMap();
}
}
};
</script>
<style lang="less" scoped>
.mapDialog {
margin-top: 11vh !important;
display: flex !important;
flex-direction: column !important;
background: red !important;
/deep/ .el-dialog__body {
height: 90%;
}
}
.mapContainer {
height: 100%;
width: 100%;
display: flex;
flex-direction: row;
.mapWrapper {
position: relative;
width: 80%;
height: 100%;
.search {
position: absolute;
top: 10px;
left: 20px;
z-index: 100000;
.dialog-input {
width: 250px;
}
}
.myMap {
height: 100%;
height: 100%;
}
}
.mapInfo {
width: 20%;
padding-left: 20px;
display: flex;
flex-direction: column;
justify-content: start;
align-items: flex-start;
.info {
text-align: left;
}
}
.confirmButton {
position: absolute;
bottom: 100px;
right: 100px;
}
}
.m-map .search {
position: absolute;
top: 10px;
left: 10px;
width: 285px;
z-index: 1;
}
.m-map .search input {
width: 180px;
border: 1px solid #ccc;
line-height: 20px;
padding: 5px;
outline: none;
}
</style>
<template>
<div class="spellOrderSet">
<!-- 时间选择器 -->
<div class="datepickerWrapper">
<span class="demonstration">拼单起止时间: </span>
<el-date-picker
class="startTimePicker"
v-model="startDate"
type="datetime"
popper-class="date_picker"
:disabledDate="pickerOptions.disabledDateStart"
placeholder="拼单开始时间"
@change="changeStartTime"
>
</el-date-picker>
<el-date-picker
class="endTimePicker"
v-model="endDate"
:clearable="false"
type="datetime"
placeholder="拼单结束时间"
:disabledDate="option1"
@change="changeEndTime"
>
</el-date-picker>
</div>
<!-- 自提点列表 -->
<div
class="card-wrapper"
v-loading="pageLoading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
>
<el-card class="card-block">
<p>自提点设置</p>
<el-form ref="form" label-width="80px">
<el-form-item>
<el-input
class="set"
v-model="selfLiftingPoint"
placeholder="自提点名称/自提点联系人"
></el-input>
<el-button type="primary" @click="getPlaceList">搜索</el-button>
<el-button type="primary" @click="dialogFormVisible = true"
>添加自提点</el-button
>
</el-form-item>
<div class="tabla-wrapper">
<p class="checked">{{ `已选 ${checkedNum}` }}</p>
<!-- 自提点列表 -->
<el-table
class="tableList"
max-height="350"
ref="multipleTable"
:data="takePlacelist"
border
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column align="center" type="selection" width="80">
</el-table-column>
<el-table-column
prop="name"
label="自提点名称"
align="center"
width="width"
>
</el-table-column>
<el-table-column
prop="location"
align="center"
label="位置"
width="width"
>
</el-table-column>
<el-table-column
prop="address"
align="center"
label="详细地址"
width="width"
>
</el-table-column>
<el-table-column
prop="contactor"
align="center"
label="自提点联系人"
width="width"
>
</el-table-column>
<el-table-column
prop="name"
align="center"
label="操作"
width="width"
>
<template #default="scope">
<el-popconfirm
title="确定要删除此自提点吗?"
@confirm="deleteTakePlace"
>
<template #reference>
<el-button
type="primary"
size="small"
@click="handleDelete(scope.row)"
>删除</el-button
>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div class="pagination-wrapper">
<el-pagination
background
layout="prev, pager, next"
:total="pageCount"
:page-size="500"
@current-change="handleCurrentChange"
>
</el-pagination>
</div>
</el-form>
</el-card>
</div>
<!-- 添加自提点 -->
<el-dialog
:close-on-click-modal="false"
title="添加自提点"
v-model="dialogFormVisible"
:show-close="false"
>
<el-form
style="margin-left: 70px"
:model="form"
:rules="rules"
ref="ruleForm"
>
<el-form-item
label="自提点名称"
prop="name"
:label-width="formLabelWidth"
>
<el-input
class="dialog-input"
v-model="form.name"
maxlength="30"
show-word-limit
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item
label="位置"
prop="location"
:label-width="formLabelWidth"
>
<el-input
class="dialog-input"
v-model="form.location"
placeholder=""
:disabled="true"
></el-input>
<el-button type="primary" @click="mapDialogVisible = true"
>从高德获取坐标</el-button
>
</el-form-item>
<p class="location">{{ form.location }}</p>
<el-form-item
prop="address"
label="详细地址"
:label-width="formLabelWidth"
>
<el-input class="dialog-input" v-model="form.address"></el-input>
</el-form-item>
<el-form-item
label="自提点联系人"
prop="contactor"
:label-width="formLabelWidth"
>
<el-input
class="dialog-input"
v-model="form.contactor"
maxlength="30"
show-word-limit
></el-input>
</el-form-item>
<el-form-item
prop="phone"
type="tel"
label="联系电话"
:label-width="formLabelWidth"
>
<el-input class="dialog-input" v-model="form.phone"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="saveTakePlace"> </el-button>
<el-button @click="cancelSaveTakePlace"> </el-button>
</span>
</template>
</el-dialog>
<!-- 地图 dialog -->
<el-dialog custom-class="mapDialog" v-model="mapDialogVisible" width="100%">
<my-map
class="my-map"
@getMapInfo="getMapInfo"
@hideMapDialog="mapDialogVisible = false"
/>
</el-dialog>
</div>
</template>
<script>
import ActivityService from "@/service/Activity/index";
import { ElMessage } from "element-plus";
import myMap from "../components/myMap.vue";
import dayJs from "dayjs";
let checkphone = (rule, value, callback) => {
let myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
if (value === "") {
callback();
}
if (!myreg.test(value)) {
return callback(new Error("电话格式不对"));
} else {
callback();
}
};
export default {
data() {
return {
startDate: dayJs().format("YYYY-MM-DD HH:mm:ss"), //开始时间
endDate: dayJs()
.add(7, "day")
.format("YYYY-MM-DD HH:mm:ss"), // 结束时间
pickerOptions: {
disabledDateStart(time) {
let _now = Date.now();
let threeDays = _now + 3 * 24 * 60 * 60 * 1000;
return time.getTime() < _now - 8.64e7 || time.getTime() > threeDays; //大于当前的禁止,小于3天前的禁止
}
},
mapDialogVisible: false,
pageLoading: false,
rules: {
name: [
{ required: true, message: "请输入自提点名称", trigger: "blur" },
{ min: 0, max: 30, message: "长度在 0 到 30 个字符", trigger: "blur" }
],
location: [
{ required: true, message: "请输入位置", trigger: "change" }
],
address: [
{ required: true, message: "请输入详细地址", trigger: "blur" }
],
contactor: [
{ min: 0, max: 30, message: "长度在 0 到 30 个字符", trigger: "blur" }
],
phone: [{ validator: checkphone, trigger: "blur" }]
},
checkedNum: 0, // 勾选自提点数量
selfLiftingPoint: "", // 自提点搜索关键词
currentList: [],
offset: 0, // 偏移量
limit: 500, // 每页条数
page: 1, //当前页码
id: "", // 删除自提点id
pageCount: 0, // 总条数
takePlacelist: [], // 自提点列表
signal: false,
checkedTakePlacelist: [], // 已选择自提点列表 活动详情中添加的自提点列表
hasCheckedList: false, // 表示是否有选中的自提点列表 是编辑还是添加的区别
multipleSelection: [],
dialogFormVisible: false,
formLabelWidth: "120px",
form: {
name: "",
location: "",
address: "",
contactor: "",
phone: "",
province: "",
city: "",
area: ""
} // 添加自提点 详细信息
};
},
computed: {
option1() {
let _this = this;
return function(time) {
let _now = Date.now();
let ninety = 90 * 24 * 60 * 60 * 1000;
let ninetyDays = _now + ninety;
return (
time.getTime() < _this.startDate - 8.64e7 ||
time.getTime() < _now - 8.64e7 ||
time.getTime() > ninetyDays
); //大于当前的禁止,小于90天前的禁止
};
}
},
props: {
spellOrderSetArr: {
type: Array,
default: () => []
},
startTime: {
type: String,
default: ""
},
endTime: {
type: String,
default: ""
}
},
components: {
myMap
},
watch: {
spellOrderSetArr: {
// 监听props属性 展示自提点列表
handler: async function() {
this.checkedTakePlacelist = this.setTableListData(
// 选中的自提点列表
this.spellOrderSetArr
);
if (this.$route.query.marketing_id) {
await this.getPlaceList();
// 时间赋值
this.startDate = this.startTime;
this.endDate = this.endTime;
this.checkedTakePlacelist = this.setTableListData(
this.spellOrderSetArr
); // 选中的自提点列表
this.currentList = this.checkedTakePlacelist.map(item => {
return item.id;
});
let list = this.takePlacelist.filter(item => {
return this.currentList.includes(item.id);
});
this.toggleSelection(list);
this.signal = true;
}
},
deep: true
// immediate: true
}
},
methods: {
/* API */
// 获取自提点
async getPlaceList() {
this.offset = (this.page - 1) * this.limit;
let params = {
keywords: this.selfLiftingPoint, //搜索关键词
offset: this.offset, // 偏移量
limit: this.limit // 每页条数
};
try {
this.pageLoading = true;
let data = await ActivityService.getPlaceList(params);
this.pageLoading = false;
this.takePlacelist = this.setTableListData(data.result.list);
this.pageCount = data.result.total;
if (this.signal === true) {
this.currentList = this.checkedTakePlacelist.map(item => {
return item.id;
});
let list = this.takePlacelist.filter(item => {
return this.currentList.includes(item.id);
});
this.toggleSelection(list);
}
} catch {
this.pageLoading = false;
ElMessage.error("加载失败");
}
},
/* API */
// 删除自提点
async deletePlace() {
let params = {
take_place_id: this.id //搜索关键词
};
try {
this.pageLoading = true;
await ActivityService.deletePlace(params);
this.pageLoading = false;
} catch {
this.pageLoading = false;
ElMessage.error("删除失败");
}
},
// 添加自提点
async addPlace() {
let params = Object.assign(this.form, {
take_place_id: this.id //搜索关键词
});
try {
this.pageLoading = true;
await ActivityService.addPlace(params);
await this.getPlaceList();
this.pageLoading = false;
} catch {
this.pageLoading = false;
ElMessage.error("添加失败");
}
},
// tableList数据格式转换
setTableListData(data) {
let result = data.map(item => {
return {
name: item.take_place_name,
location: item.location, // p + c + a
address: item.address,
contactor: item.contact_name,
id: item.take_place_id
};
});
return result;
},
// 删除自提点操作
handleDelete(val) {
this.id = val.id;
},
// 保存自提点操作
saveTakePlace() {
this.$refs.ruleForm.validate(async valid => {
if (valid) {
await this.addPlace();
this.$refs.ruleForm.resetFields();
this.dialogFormVisible = false;
} else {
return false;
}
});
},
// 取消保存操作
cancelSaveTakePlace() {
this.$refs.ruleForm.resetFields();
this.dialogFormVisible = false;
},
// 确认删除自提点操作
async deleteTakePlace() {
await this.deletePlace();
await this.getPlaceList();
},
// 更改页数
handleCurrentChange(val) {
this.page = val;
this.getPlaceList();
},
// 复选框
handleSelectionChange(val) {
this.checkedNum = val.length;
this.multipleSelection = val;
let takePlaceIds = "";
val.forEach(item => {
if (takePlaceIds === "") {
takePlaceIds = item.id;
} else {
takePlaceIds = takePlaceIds + "," + item.id;
}
});
this.$emit("getTakeTakePlaceListFromChild", takePlaceIds);
},
// 勾选某些列表的操作
toggleSelection(rows) {
if (rows) {
rows.forEach(row => {
this.$refs.multipleTable.toggleRowSelection(row);
});
} else {
this.$refs.multipleTable.clearSelection();
}
},
//改变开始时间
changeStartTime() {
this.$emit("getStartTime", this.startDate);
},
// 改变结束时间
changeEndTime() {
this.$emit("getEndTime", this.endDate);
},
// 获取地图信息
getMapInfo(mapInfo) {
this.form.location = mapInfo.address;
this.form.province = mapInfo.province;
this.form.city = mapInfo.city;
this.form.area = mapInfo.area;
this.form.longitude = mapInfo.lng; // longitude latitude contactor
this.form.latitude = mapInfo.lat;
}
},
created() {
if (!this.$route.query.marketing_id) {
this.getPlaceList();
}
}
};
</script>
<style lang="less" scope>
.el-picker-panel {
.el-picker-panel__footer {
.el-button--text {
display: none;
}
}
}
</style>
<style lang="less">
.card-wrapper {
width: 100%;
//height: 500px;
.card-block {
width: 100%;
.tabla-wrapper {
> p {
margin-left: 10px;
text-align: left;
}
.tableList {
height: 500px;
}
}
}
.pagination-wrapper {
height: 60px;
display: flex;
justify-content: center;
align-items: center;
}
}
.spellOrderSet {
text-align: center;
margin: 50px 0;
.datepickerWrapper {
margin: 1px 0 30px;
}
.startTimePicker {
margin-right: 50px;
}
}
.set {
width: 50%;
margin-top: 40px;
}
.el-button {
margin-left: 30px;
}
.tabList {
margin-top: 10px;
}
.dialog-input {
width: 50%;
}
.location {
margin-bottom: 10px;
margin-left: 14%;
}
.dialog-footer {
display: flex;
justify-content: center;
align-items: center;
}
.mapDialog {
height: 80%;
margin-top: 10vh !important;
.el-dialog__body {
height: 85% !important;
}
.my-map {
height: 100%;
}
}
</style>
<template>
<div class="releaseProduc">
<h4 class="headTitle">发布活动</h4>
<el-steps
class="steps"
:active="active"
finish-status="success"
space="30%"
:align-center="true"
>
<el-step title="信息编辑"></el-step>
<el-step title="添加商品"></el-step>
<el-step title="拼单设置"></el-step>
</el-steps>
<div class="content">
<infoEditing
ref="infoEdit"
v-show="active === 1"
:infoEditArr="infoEditArr"
/>
<addProduc
ref="addProduc"
v-show="active === 2"
:addProduc="addProducArr"
:editInfo="infoEditArr"
:stepTwoTitle="stepTwoTitle"
/>
<spellOrderSet
ref="spellOrderSet"
v-show="active === 3"
:spellOrderSetArr="spellOrderSetArr"
:startTime="startTime"
:endTime="endTime"
@getTakeTakePlaceListFromChild="getTakeTakePlaceListFromChild"
/>
</div>
<div class="stepsBtn">
<el-button @click="prev" v-show="active >= 2" style="margin-right: 20px"
>上一步</el-button
>
<el-button @click="next" v-show="active < 3" style="margin-right: 20px"
>下一步</el-button
>
<el-button @click="cancel" v-show="active == 1">取消</el-button>
<el-button @click="confirmRelease" v-show="active == 3" type="primary"
>确认发布</el-button
>
</div>
</div>
</template>
<script>
import dayJs from "dayjs";
import { ElMessage } from "element-plus";
import infoEditing from "./components/infoEditing.vue";
import addProduc from "./components/addProduc.vue";
import spellOrderSet from "./components/spellOrderSet.vue";
import {
addMarketing,
marketingInfo,
updateMarketing
} from "../../../service/Activity/index";
export default {
components: {
infoEditing,
addProduc,
spellOrderSet
},
data() {
return {
active: 1, // 步骤条状态
infoEditArr: [], // 信息编辑数据
addProducArr: [], // 添加商品
goodsSkuIDArr: [], // 接收goods_sku_id
spellOrderSetArr: [],
startDate: "", // 开始时间
endDate: "", // 结束时间
takePlaceIDArr: [],
startTime: "",
endTime: "",
stepTwoTitle: "" // 传给addProduct的title
};
},
methods: {
// 上一步
prev() {
this.active--;
},
// 下一步
next() {
if (this.active === 1) {
if (this.$refs.infoEdit.infoEditForm.title == "") {
ElMessage.error("请填写商品标题");
return;
}
this.stepTwoTitle = this.$refs.infoEdit.infoEditForm.title;
this.active = 2;
} else if (this.active === 2) {
if (this.$refs.addProduc.comTableData.length == 0) {
ElMessage.error("请至少选择一个商品");
return;
}
this.addProducArr = this.$refs.addProduc.comTableData;
this.active = 3;
}
},
// 获取营销活动详情
async marketingInfoMet() {
let marketingId = this.$route.query.marketing_id;
if (marketingId == undefined) {
return;
}
let params = {
marketing_id: marketingId,
marketing_type: "4"
};
const res = await marketingInfo(params);
this.infoEditArr = res.result.marketing_info;
this.addProducArr = res.result.goods_list;
this.spellOrderSetArr = res.result.take_place;
this.startTime = res.result.marketing_info.start_time;
this.endTime = res.result.marketing_info.end_time;
localStorage.setItem("propData", JSON.stringify(this.infoEditArr));
},
// 取消
cancel() {
this.$router.go(-1);
},
// 确认发布
async confirmRelease() {
function getUrlParms(path, name) {
var reg = new RegExp("(^|\\?|&)" + name + "=([^&]*)(\\s|&|$)", "i");
if (reg.test(path)) return unescape(RegExp.$2.replace(/\+/g, " "));
return "";
}
let list = this.$refs.infoEdit.picSubmitList.map(item => {
let rs = getUrlParms(item.url, "url");
return rs;
});
let picList = list.join(",");
for (var i in this.addProducArr) {
this.goodsSkuIDArr.push(this.addProducArr[i].goods_sku_id);
}
this.startDate = this.$refs.spellOrderSet.startDate;
this.endDate = this.$refs.spellOrderSet.endDate;
let params = {
marketing_id:
this.$route.query.marketing_id == undefined
? ""
: this.$route.query.marketing_id,
goods_sku_id: this.goodsSkuIDArr.join(","),
marketing_name: this.$refs.infoEdit.infoEditForm.title,
marketing_type: "4",
op_cur_user: this.$store.state.userInfo.email,
start_time: dayJs(this.startDate).format("YYYY-MM-DD HH:mm:ss"),
end_time: dayJs(this.endDate).format("YYYY-MM-DD HH:mm:ss"),
pindan_pic: picList,
pindan_desc: this.$refs.infoEdit.infoEditForm.desc,
take_place_ids: this.takePlaceIDArr
};
if (this.$route.query.marketing_id == undefined) {
const res = await addMarketing(params);
if (res.code === 0) {
ElMessage.success({
message: "添加成功",
type: "success"
});
this.$router.push({ path: "/op/activity/manage" });
} else {
ElMessage.error(res.reason);
}
} else {
const res = await updateMarketing(params);
if (res.code === 0) {
ElMessage.success({
message: "修改成功",
type: "success"
});
this.$router.push({ path: "/op/activity/manage" });
} else {
ElMessage.error(res.reason);
}
}
},
getTakeTakePlaceListFromChild(val) {
this.takePlaceIDArr = val;
}
},
created() {
this.marketingInfoMet();
}
};
</script>
<style scope>
.releaseProduc {
padding: 30px;
box-sizing: border-box;
}
.headTitle {
width: 75%;
font-size: 18px;
margin: 0 auto 40px auto;
}
.steps {
display: flex;
justify-content: center;
margin-bottom: 50px;
}
.steps /deep/ .el-step__icon {
width: 50px;
height: 50px;
}
.steps /deep/ .el-step.is-horizontal .el-step__line {
top: 25px;
}
.stepsBtn {
margin: 20px auto;
}
.stepsBtn {
width: 64%;
text-align: center;
margin-top: 50px;
}
</style>
.detail {
height: 100%;
// height: 100%;
.state {
display: flex;
align-items: center;
......
......@@ -381,6 +381,14 @@
></el-input>
<span v-else>{{ goodsObj.original_price }}</span>
</el-form-item>
<el-form-item label="结算价">
<el-input
v-if="$route.params.operation === 'EDIT'"
v-model="goodsObj.clear_price"
@change="perPrice"
></el-input>
<span v-else>{{ goodsObj.clear_price }}</span>
</el-form-item>
<h4 style="margin:20px 0">库存信息</h4>
<el-form-item label="剩余库存量:">
<span>{{ goodsObj.inventory_rest }}</span>
......@@ -1167,23 +1175,14 @@ export default {
},
// 更改原价
perPrice () {
if (!this.goodsObj.original_price || this.goodsObj.original_price == 0) {
this.$nextTick(() => {
this.goodsObj.original_price = "";
})
perPrice (val) {
if (val.length === 0) val = 0;
const parseOriginalPrice = Number(val).toFixed(2);
val = Number(parseOriginalPrice);
if (typeof val === "number" &&isNaN(val)) {
val = 0;
return this.$message.error("原价价格必为数字");
}
const parseOriginalPrice = Number(this.goodsObj.original_price).toFixed(
2
);
this.goodsObj.original_price = Number(parseOriginalPrice);
// if (
// typeof this.goodsObj.original_price === "number" &&
// isNaN(this.goodsObj.original_price)
// ) {
// this.goodsObj.original_price = "";
// return this.$message.error("原价价格必为数字");
// }
},
// 审核通过
......@@ -1300,6 +1299,10 @@ export default {
}
console.log(query);
// 是否该商品关联的分销活动满足售价-分销总金额>=结算价
// if (query.price - d >= query.clear_price) {
// return this.$message.error("请至少选择一个门店");
// }
const res = await editGoods(query);
if (res.code !== 0) {
......
......@@ -2,10 +2,7 @@
<layout>
<el-card class="goods">
<!-- 筛选区 -->
<el-form
inline
class="search_condition"
>
<el-form inline class="search_condition">
<!-- 商品id -->
<el-form-item label="商品id">
<el-input v-model="searchProps.goods_spu_id"></el-input>
......@@ -66,21 +63,13 @@
</el-form-item>
<!-- 按钮操作 -->
<el-form-item style="justify-self: flex-end;">
<el-button
@click="searchList"
type="primary"
>搜索</el-button>
<el-button @click="searchList" type="primary">搜索</el-button>
<el-button @click="resetList">重置</el-button>
</el-form-item>
</el-form>
<!-- 列表区 -->
<el-table
class="goods_list"
:data="goodsList"
border
stripe
>
<el-table class="goods_list" :data="goodsList" border stripe>
<el-table-column
label="商品id"
prop="goods_spu_id"
......@@ -116,36 +105,33 @@
prop="publish_user_id"
align="center"
></el-table-column>
<el-table-column
label="状态"
align="center"
>
<el-table-column label="状态" align="center">
<template #default="scope">
<span
v-if="scope.row.audit_status == 0"
style="color:#FF982C;"
>待审核</span>
<span
v-if="scope.row.audit_status == 1"
style="color:#5CC247;"
>审核通过</span>
<span
v-if="scope.row.audit_status == 2"
style="color:#FD6B6F;"
>审核驳回</span>
<span v-if="scope.row.audit_status == 0" style="color:#FF982C;"
>待审核</span
>
<span v-if="scope.row.audit_status == 1" style="color:#5CC247;"
>审核通过</span
>
<span v-if="scope.row.audit_status == 2" style="color:#FD6B6F;"
>审核驳回</span
>
&nbsp;&nbsp;&nbsp;
<span
v-if="scope.row.online_status == 0 && scope.row.audit_status != 2"
style="color:#FF982C;"
>未上架</span>
>未上架</span
>
<span
v-if="scope.row.online_status == 1 && scope.row.audit_status != 2"
style="color:#5CC247;"
>已上架</span>
>已上架</span
>
<span
v-if="scope.row.online_status == 2 && scope.row.audit_status != 2"
style="color:#FD6B6F;"
>已下架</span>
>已下架</span
>
</template>
</el-table-column>
<el-table-column
......@@ -159,26 +145,23 @@
align="center"
></el-table-column>
<!-- 操作快捷键 -->
<el-table-column
label="操作"
align="center"
fixed="right"
width="200"
>
<el-table-column label="操作" align="center" fixed="right" width="200">
<template #default="scope">
<el-button
type="text"
@click="goDetail(`EDIT`, scope.row.goods_spu_id)"
>编辑</el-button>
>编辑</el-button
>
<el-button
v-if="scope.row.audit_status == 0"
type="text"
@click="goDetail(`AUDIT`, scope.row.goods_spu_id)"
>审核</el-button>
>审核</el-button
>
<el-popconfirm
v-if="scope.row.online_status == 2 "
v-if="scope.row.online_status == 2"
title="您确定要上架该商品吗?"
cancelButtonType="default"
@confirm="changeGoodsState('GROUNDING', scope.row.goods_spu_id)"
......@@ -189,7 +172,10 @@
</el-popconfirm>
<el-popconfirm
v-if=" scope.row.online_status != 2 && (scope.row.audit_status == 1 || scope.row.online_status == 1) "
v-if="
scope.row.online_status != 2 &&
(scope.row.audit_status == 1 || scope.row.online_status == 1)
"
title="您确定要下架该商品吗?"
cancelButtonType="default"
@confirm="
......@@ -202,9 +188,10 @@
</el-popconfirm>
<el-button
@click="goDetail(`DETAIL`,scope.row.goods_spu_id)"
@click="goDetail(`DETAIL`, scope.row.goods_spu_id)"
type="text"
>详情</el-button>
>详情</el-button
>
</template>
</el-table-column>
</el-table>
......@@ -240,14 +227,14 @@ export default {
Layout
},
created () {
created() {
// 获取级联选择
this.getOptionList();
// 获取商品列表
this.getCommodityList();
},
data () {
data() {
return {
// 级联选择器参数
cascaderProps: {
......@@ -300,7 +287,7 @@ export default {
methods: {
// 获取级联选择
async getOptionList () {
async getOptionList() {
try {
const res = await getGoodsList();
if (res.code !== 0) return this.$message.error(res.reason);
......@@ -310,20 +297,20 @@ export default {
}
},
// 获取数组返回值并转换为字符串
getVal (value, index = 0) {
getVal(value, index = 0) {
const valueArray = value.map(item => {
return item[index];
});
return valueArray.join();
},
getValue (value) {
getValue(value) {
const values = value.map(item => {
return item;
});
return values.join();
},
// 获取列表
async getCommodityList () {
async getCommodityList() {
try {
const res = await getList(this.searchProps);
if (res.code !== 0) return this.$message.error(res.reason);
......@@ -335,25 +322,25 @@ export default {
}
},
// 所属分类赋值
handleTypeChange (val) {
handleTypeChange(val) {
this.searchProps.category_1_id = this.getVal(val, 0);
this.searchProps.category_2_id = this.getVal(val, 1);
},
// 审核状态赋值
handleStatusChange (val) {
handleStatusChange(val) {
this.searchProps.audit_status = this.getValue(val);
},
// 上架状态赋值
handleOnlineStatusChange (val) {
handleOnlineStatusChange(val) {
this.searchProps.online_status = this.getValue(val);
},
// 按条件搜索
searchList () {
searchList() {
console.log(this.searchProps);
this.getCommodityList();
},
// 重置表单
resetList () {
resetList() {
this.searchProps = {
page: 1, // 页码
page_size: 20, // 页数大小
......@@ -372,7 +359,7 @@ export default {
this.getCommodityList();
},
// 上架/下架操作
async changeGoodsState (state, spuId) {
async changeGoodsState(state, spuId) {
// 上架操作
if (state === "GROUNDING") {
const res = await putOnline(spuId);
......@@ -389,14 +376,14 @@ export default {
},
// 页码变化
handleCurrentChange (e) {
handleCurrentChange(e) {
this.searchProps.page = e;
// 获取信息
this.getCommodityList();
},
// 去往详情页
goDetail (operation, spuId) {
goDetail(operation, spuId) {
console.log(spuId);
this.$router.push({ name: "GoodsDetail", params: { operation, spuId } });
}
......
......@@ -200,6 +200,12 @@
></el-input>
<div style="margin: 20px 0"></div>
</el-form-item>
<el-form-item prop="commission_mode" label="金额计算方式:">
<el-radio-group v-model="ruleForm.commission_mode">
<el-radio :label="2">按金额</el-radio>
<el-radio :label="1">按比例</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="上线佣金:" prop="first_commission_value">
<el-input
v-model="ruleForm.first_commission_value"
......@@ -207,7 +213,9 @@
@input="changeValue($event, 'first_commission_value')"
:disabled="shopStart !== 0"
>
<template #append>%</template>
<template #append>{{
ruleForm.commission_mode == 1 ? "%" : "¥"
}}</template>
</el-input>
</el-form-item>
<el-form-item label="分享者佣金: " prop="second_commission_value">
......@@ -217,7 +225,9 @@
@input="changeValue($event, 'second_commission_value')"
:disabled="shopStart !== 0"
>
<template #append>%</template>
<template #append>{{
ruleForm.commission_mode == 1 ? "%" : "¥"
}}</template>
</el-input>
</el-form-item>
<el-form-item label="活动生效时间:">
......@@ -334,13 +344,13 @@ import {
getFindGoodsList,
getAddMarketingList,
getMarketingInfo,
updateMarketingList,
updateMarketingList
} from "@/service/Goods/goods";
import { ElMessage } from "element-plus";
// 开启关闭防抖
function debounce(callback, delay) {
let timer = null;
return function (...args) {
return function(...args) {
if (timer) {
clearTimeout(timer);
}
......@@ -353,15 +363,16 @@ function debounce(callback, delay) {
export default {
name: "GoodsRetail",
components: {
Layout,
Layout
},
data() {
var commission = (rule, value, callback) => {
if (
this.ruleForm.first_commission_value +
this.ruleForm.commission_mode == 1 &&
(this.ruleForm.first_commission_value +
this.ruleForm.second_commission_value >
50 ||
value > 50
value > 50)
) {
callback(new Error("上线佣金与分享者佣金之和不可大于50%"));
} else {
......@@ -376,14 +387,14 @@ export default {
first_commission_value: "",
second_commission_value: "",
start_time: "",
end_time: "",
end_time: ""
},
goods_list: [],
options: [
{ value: 0, label: "全部" },
{ value: 1, label: "启用" },
{ value: 2, label: "关闭" },
{ value: 3, label: "到期" },
{ value: 3, label: "到期" }
],
// 搜索条件
retailActivitie: {
......@@ -393,42 +404,43 @@ export default {
online_status: [],
page: 1,
page_size: 20,
count: 0,
count: 0
},
ruleForm: {
marketing_name: "",
commission_mode: 1,
first_commission_value: "",
second_commission_value: "",
start_time: "",
end_time: "",
goods_spu_id: [],
goods_spu_id: []
},
timeSelect: [],
ruleIdForm: {
life_account_id: "",
goods_spu_id: "",
start_time: "",
end_time: "",
end_time: ""
},
rules: {
marketing_name: [
{ required: true, message: "请输入活动名称", trigger: "blur" },
{ min: 1, max: 50, message: "活动名称不能大于50", trigger: "blur" },
{ min: 1, max: 50, message: "活动名称不能大于50", trigger: "blur" }
],
second_commission_value: [
{
required: true,
message: "请填写分享者佣金",
trigger: "blur",
trigger: "blur"
},
{ type: "number", message: "必须为数值型" },
{ validator: commission },
{ validator: commission }
],
first_commission_value: [
{ type: "number", message: "必须为数值型" },
{ validator: commission },
],
{ validator: commission }
]
},
allList: [],
dialogFormVisible: false,
......@@ -437,7 +449,7 @@ export default {
endTime: "",
marketing_id: "",
marketing_info: {},
disabled: false,
disabled: false
};
},
methods: {
......@@ -481,11 +493,11 @@ export default {
}
},
// 开启关闭
handelEnable: debounce(async function (row, type) {
handelEnable: debounce(async function(row, type) {
try {
const res = await updateMarketingList({
marketing_id: row.marketing_id,
online_status: type,
online_status: type
});
if (res.code !== 0) {
ElMessage.error(res.reason);
......@@ -510,7 +522,7 @@ export default {
goods_sku_id: "",
online_status: [],
page: 1,
page_size: 20,
page_size: 20
}),
this.$refs[retailActivitie].resetFields();
this.getMarketingList({});
......@@ -568,7 +580,7 @@ export default {
goods_spu_id,
life_account_id,
start_time,
end_time,
end_time
};
try {
// 发请求
......@@ -581,18 +593,18 @@ export default {
}
},
selectGoodsChange(e) {
this.ruleForm.goods_spu_id = e.map((item) => item.goods_sku_id);
this.ruleForm.goods_spu_id = e.map(item => item.goods_sku_id);
},
async getAllList() {
let all = await getMarketingList({
page: 1,
page_size: this.retailActivitie.count,
page_size: this.retailActivitie.count
});
this.allList = all.result;
},
// 添加活动列表
async addList() {
this.$refs.ruleForm.validate(async (valid) => {
this.$refs.ruleForm.validate(async valid => {
if (valid) {
console.log(this.ruleForm.goods_spu_id);
if (this.ruleForm.goods_spu_id.length <= 0) {
......@@ -606,7 +618,8 @@ export default {
let {
marketing_name,
first_commission_value,
second_commission_value,
commission_mode,
second_commission_value
} = this.ruleForm;
let [start_time, end_time] = this.timeSelect || [];
if (
......@@ -620,11 +633,12 @@ export default {
}
let addParams = {
goods_sku_id,
commission_mode,
marketing_name,
first_commission_value: first_commission_value + "",
second_commission_value: second_commission_value + "",
start_time: this.formatTime(start_time),
end_time: this.formatTime(end_time),
end_time: this.formatTime(end_time)
};
try {
const res = await getAddMarketingList(addParams);
......@@ -651,7 +665,7 @@ export default {
second_commission_value: "",
start_time: "",
end_time: "",
goods_spu_id: [],
goods_spu_id: []
}),
(this.timeSelect = []),
(this.goods_list = []),
......@@ -659,7 +673,7 @@ export default {
life_account_id: "",
goods_spu_id: "",
start_time: "",
end_time: "",
end_time: ""
});
},
// 取消
......@@ -667,12 +681,12 @@ export default {
this.dialogFormVisible = false;
this.resetDate();
this.getMarketingList();
},
}
},
created() {
this.getMarketingList();
this.getAllList();
},
}
};
</script>
<style lang="less" scoped>
......
......@@ -7,14 +7,13 @@
<div class="main">
<slot></slot>
</div>
</div>
</template>
<script>
import PageHeader from '../components/PageHeader';
import PageHeader from "../components/PageHeader";
export default {
components: { PageHeader },
components: { PageHeader }
};
</script>
......
......@@ -376,7 +376,6 @@ export default {
const { selectActivity, multipleSelection } = this;
const uids = multipleSelection.map((item) => item.deliverer_id);
if (!selectActivity) return ElMessage("请选择活动姓名");
// if (!uids.length) return this.$message.info("请至少选择一名骑手");
try {
const { code, reason } = await getSaveDeliverer({
code: selectActivity,
......
const headerConfig = [
{
name: "活动管理",
path: "/op/activity/manage"
},
{
name: "订单管理",
path: "/op/groupmeal/orderManagement"
},
{
path: '/op/groupmeal/distrib',
name: '配送员管理'
name: "新订单管理",
path: "/op/groupmeal/newOrderManagement"
},
{
path: "/op/groupmeal/distrib",
name: "配送员管理"
}
];
export default headerConfig;
......@@ -7,14 +7,13 @@
<div class="main">
<slot></slot>
</div>
</div>
</template>
<script>
import PageHeader from '../components/PageHeader';
import PageHeader from "../components/PageHeader";
export default {
components: { PageHeader },
components: { PageHeader }
};
</script>
......
<template>
<Layout>
<div class="orderManage">
<!-- 查询栏 -->
<el-form
:inline="true"
:model="orderQueryObj"
ref="ruleForm"
class="demo-form-inline"
>
<el-form-item label="活动名称:" prop="marketing_id">
<el-select
v-model="orderQueryObj.marketing_id"
placeholder="请选择"
@change="activityNameSel"
@focus="activityNameFocus"
filterable
>
<el-option
v-for="item in activityNameArr"
:key="item.marketing_id"
:label="item.marketing_name"
:value="item.marketing_id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="订单状态:" prop="order_status">
<el-select v-model="orderQueryObj.order_status" placeholder="请选择">
<el-option
v-for="item in orderStatusArr"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="商品名称:" prop="goods_id">
<el-select
v-model="orderQueryObj.goods_id"
placeholder="请选择"
filterable
>
<el-option
v-for="item in tradeNameArr"
:key="item.goods_id"
:label="item.goods_name"
:value="item.goods_id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="收货人:" prop="cust_user">
<el-input
placeholder="请输入收货人姓名或手机号"
prefix-icon="el-icon-search"
v-model="orderQueryObj.cust_user"
></el-input>
</el-form-item>
<el-form-item label="订单编号:" prop="order_id">
<el-input
placeholder="请输入订单号"
prefix-icon="el-icon-search"
v-model="orderQueryObj.order_id"
></el-input>
</el-form-item>
<el-form-item label="自提点:" prop="sub_shop_id">
<el-select
v-model="orderQueryObj.sub_shop_id"
placeholder="请选择"
filterable
>
<el-option
v-for="item in selLiftPoinArr"
:key="item.take_place_id"
:label="item.take_place_name"
:value="item.take_place_id"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="resetOrder('ruleForm')">重置</el-button>
<el-button type="primary" @click="searchOrder">搜索</el-button>
</el-form-item>
</el-form>
<!-- Tabs标签页 -->
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-row class="tabHead">
<el-col :span="12">
<div>商品共计:{{ goodsNum }}</div>
</el-col>
<el-col :span="12" style="text-align: right">
<el-button @click="exportOrder">导出</el-button>
<el-button @click="printOrder">打印</el-button>
</el-col>
</el-row>
<el-tab-pane label="全部" name="all">
<el-table :data="orderTableData" border stripe style="width: 100%">
<el-table-column prop="marketing_name" label="活动名称">
<template #default="scope">
<div>
{{ scope.row.marketing_name }}({{ scope.row.marketing_id }})
</div>
</template>
</el-table-column>
<el-table-column
prop="order_id"
label="订单号"
width
></el-table-column>
<el-table-column
prop="order_status_text"
label="订单状态"
></el-table-column>
<el-table-column prop="order_item" label="商品信息">
<template #default="scope">
<div v-for="(item, index) in scope.row.order_item" :key="index">
{{ item.goods_name
}}<span style="color: red"> * {{ item.goods_num }} </span>
</div>
</template>
</el-table-column>
<el-table-column prop="user_name" label="收货人">
<template #default="scope">
<div>
<span
>{{ scope.row.user_name }}({{ scope.row.user_nick }})</span
>
<p>{{ scope.row.user_mobile }}</p>
</div>
</template>
</el-table-column>
<el-table-column
prop="sub_shop_name"
label="自提点"
></el-table-column>
<el-table-column prop="comment" label="备注"></el-table-column>
<el-table-column prop="pay_time" label="支付时间"></el-table-column>
<el-table-column prop="payment" label="支付金额">
<template #default="scope">
<div>
{{ scope.row.payment }}
<span v-show="scope.row.refund_amount"
>(已退¥{{ scope.row.refund_amount }})</span
>
</div>
</template>
</el-table-column>
<el-table-column
prop="discount_fee"
label="优惠金额"
></el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template #default="scope">
<el-button
type="text"
size="small"
@click="refund(scope.row)"
v-show="
(scope.row.order_status == '2' ||
scope.row.order_status == '6' ||
scope.row.order_status == '8') &&
scope.row.payment !== 0
"
>退款</el-button
>
<el-button-group v-show="scope.row.order_status == '3'">
<el-button type="text" size="small" @click="agree(scope.row)"
>同意</el-button
>
<el-button type="text" size="small" @click="refuse(scope.row)"
>拒绝</el-button
>
</el-button-group>
<!-- {{scope.row.payment}} -->
</template>
</el-table-column>
</el-table>
<page
@current-change="handleCurrentChange"
:current-page="orderQueryObj.page"
:page-size="orderQueryObj.page_size"
:total="totalNum"
/>
</el-tab-pane>
<el-tab-pane label="售后" name="afterSale">
<el-table :data="orderTableData" border stripe style="width: 100%">
<el-table-column prop="marketing_name" label="活动名称">
<template #default="scope">
<div>
{{ scope.row.marketing_name }}({{ scope.row.marketing_id }})
</div>
</template>
</el-table-column>
<el-table-column
prop="order_id"
label="订单号"
width
></el-table-column>
<el-table-column
prop="order_status_text"
label="订单状态"
></el-table-column>
<el-table-column prop="order_item" label="商品信息">
<template #default="scope">
<div v-for="(item, index) in scope.row.order_item" :key="index">
{{ item.goods_name
}}<span style="color: red"> * {{ item.goods_num }} </span>
</div>
</template>
</el-table-column>
<el-table-column prop="user_name" label="收货人">
<template #default="scope">
<div>
<span
>{{ scope.row.user_name }}({{ scope.row.user_nick }})</span
>
<p>{{ scope.row.user_mobile }}</p>
</div>
</template>
</el-table-column>
<el-table-column
prop="sub_shop_name"
label="自提点"
></el-table-column>
<el-table-column prop="comment" label="备注"></el-table-column>
<el-table-column prop="pay_time" label="支付时间"></el-table-column>
<el-table-column prop="payment" label="支付金额">
<template #default="scope">
<div>
{{ scope.row.payment }}
<span v-show="scope.row.refund_amount">{{
scope.row.refund_amount === 0
? ""
: `已退¥${scope.row.refund_amount} `
}}</span>
</div>
</template>
</el-table-column>
<el-table-column
prop="discount_fee"
label="优惠金额"
></el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template #default="scope">
<el-button
type="text"
size="small"
@click="refund(scope.row)"
v-show="
(scope.row.order_status == '2' ||
scope.row.order_status == '6' ||
scope.row.order_status == '8') &&
scope.row.payment !== 0
"
>退款</el-button
>
<el-button-group v-show="scope.row.order_status == '3'">
<el-button type="text" size="small" @click="agree(scope.row)"
>同意</el-button
>
<el-button type="text" size="small" @click="refuse(scope.row)"
>拒绝</el-button
>
</el-button-group>
</template>
</el-table-column>
</el-table>
<page
@current-change="handleCurrentChange"
:current-page="orderQueryObj.page"
:page-size="orderQueryObj.page_size"
:total="totalNum"
/>
</el-tab-pane>
</el-tabs>
<!-- 导出弹窗 -->
<el-dialog title="导出订单" width="45%" top="10%" v-model="exportShow">
<el-form-item class="exportForm" label>
<div style="margin-bottom: 15px">
请选择导出活动{{ exportType }}的表格类型
</div>
<a :href="exportURL1" style="margin-right: 10px"
><el-button type="primary" @click="exportShow = false"
>总表</el-button
></a
>
<a :href="exportURL2" style="margin-right: 10px"
><el-button type="primary" @click="exportShow = false"
>商品表</el-button
></a
>
<a :href="exportURL3"
><el-button type="primary" @click="exportShow = false"
>配送表</el-button
></a
>
</el-form-item>
</el-dialog>
<!-- 退款弹窗 -->
<el-dialog title="退款" width="30%" top="10%" v-model="refundShow">
<el-checkbox
:indeterminate="isIndeterminate"
v-model="checkAll"
@change="handleCheckAllChange"
style="margin-bottom: 15px"
>
全选
</el-checkbox>
<div
class="refundCon"
v-for="(item, index) in refundGoods"
:key="index"
>
<el-row>
<el-checkbox
class="check-wrap"
v-model="item.refundedGoodsSel"
:label="item.goods_name"
name="type"
></el-checkbox>
</el-row>
<el-row>
<el-col :span="6">实付:{{ item.payment }}</el-col>
<el-checkbox
class="check-wrap"
v-model="item.restoreInventory"
label="恢复库存"
name="type"
></el-checkbox>
</el-row>
</div>
<template #footer>
<span class="dialog-footer refundBtnGroup">
<el-button @click="refundShow = false"> </el-button>
<el-button type="primary" @click="handleConfirmRefund"
>退款</el-button
>
</span>
</template>
</el-dialog>
</div>
</Layout>
</template>
<script>
import Layout from "../layout/index.vue";
import {
newGetOrderList,
newGetMarketingList,
newGetGoodsList,
newGetSubShopList,
newOrderPrint,
newOrderItemList,
newOrderRefundReject,
newRefundOrder,
newGetOrderExportURL
} from "@/service/Groupmeal/groupmeal";
import page from "../components/Pagination/index.vue";
export default {
name: "orderManagement",
components: {
Layout,
page
},
data() {
return {
// 查询
orderQueryObj: {
page: 1,
page_size: 10,
marketing_id: "", // 活动名称
order_status: "0", // 订单状态
goods_id: "", // 商品名称
cust_user: "", // 收货人
order_id: "", // 订单编号
sub_shop_id: "" // 自提点
},
// 下拉框数据
// 活动名称
activityNameArr: [],
// 订单状态
orderStatusArr: [
{
value: "0",
label: "全部"
},
{
value: "1",
label: "未支付"
},
{
value: "2",
label: "已支付"
},
{
value: "3",
label: "待退款"
},
{
value: "4",
label: "已退款"
},
{
value: "5",
label: "退款中"
},
{
value: "6",
label: "已拒绝"
},
{
value: "7",
label: "售后"
}
],
// 商品名称
tradeNameArr: [],
// 自提点
selLiftPoinArr: [],
activeName: "all", // Tabs标签页
goodsNum: "", // 商品总计
// 导出
exportShow: false,
exportType: "",
// 表格数据
orderTableData: [],
totalNum: null, //总条数
// 退款
refundShow: false, // 退款状态
checkAll: false, // 全选
isIndeterminate: false,
refundGoods: [
{
refundedGoodsSel: false,
payment: "",
restoreInventory: false,
goods_name: ""
}
]
};
},
computed: {
exportURL1() {
return newGetOrderExportURL(this.orderQueryObj.marketing_id, "1");
},
exportURL2() {
return newGetOrderExportURL(this.orderQueryObj.marketing_id, "2");
},
exportURL3() {
return newGetOrderExportURL(this.orderQueryObj.marketing_id, "3");
}
},
methods: {
activityNameFocus() {
this.getMarketingListMet();
},
// 获取活动名称
async getMarketingListMet() {
try {
const res = await newGetMarketingList();
this.activityNameArr = res.result;
} catch (error) {
this.$message.error("发生未知错误,请稍后再试一下吧~~~");
console.error(error);
}
},
// 活动名称的change事件 获取商品名称+获取自提点
async activityNameSel(val) {
this.orderQueryObj.goods_id = "";
this.orderQueryObj.sub_shop_id = "";
const params = {
marketing_id: val
};
const res = await newGetGoodsList(params); // 商品名称
this.getSubShopListMet(val); //自提点
// const res = await getSubShopList(params);
this.tradeNameArr = res.result;
// this.selLiftPoinArr = res.result;
},
// 获取自提点
async getSubShopListMet(params) {
try {
let marketing_id = "";
if (params) {
marketing_id = params;
}
const res = await newGetSubShopList({ marketing_id: marketing_id });
this.selLiftPoinArr = res.result;
} catch (error) {
this.$message.error("发生未知错误,请稍后再试一下吧~~~");
console.error(error);
}
},
// 重置
resetOrder(formName) {
if (this.$route.query.marketing_type == "4") {
this.$router.push({
path: "/op/groupmeal/newOrderManagement"
});
this.$route.query.marketing_type = "";
}
this.$refs[formName].resetFields();
this.orderQueryObj.page = 1;
this.orderQueryObj.page_size = 10;
this.getOrderListMet(this.orderQueryObj);
this.getSubShopListMet();
},
// 搜索
searchOrder() {
if (this.$route.query.marketing_type == "4") {
this.$router.push({
path: "/op/groupmeal/newOrderManagement"
});
this.$route.query.marketing_type = "";
}
this.orderQueryObj.page = 1;
this.orderQueryObj.page_size = 10;
if (this.orderQueryObj.order_status === "0") {
this.activeName = "all";
this.orderStatusArr[1].disabled = false;
this.orderStatusArr[2].disabled = false;
}
// this.orderQueryObj.order_status = "0";
// this.orderStatusArr[1].disabled = false;
// this.orderStatusArr[2].disabled = false;
this.getOrderListMet(this.orderQueryObj);
},
// 标签页切换
handleClick(targetName) {
if (targetName.props.name == "all") {
this.orderQueryObj.order_status = "0";
this.orderStatusArr[1].disabled = false;
this.orderStatusArr[2].disabled = false;
} else {
this.orderQueryObj.order_status = "7";
this.orderStatusArr[1].disabled = true;
this.orderStatusArr[2].disabled = true;
}
this.getOrderListMet(this.orderQueryObj);
},
// 导出
exportOrder() {
if (this.orderQueryObj.marketing_id === "") {
this.$message.error("请选择活动名称");
return;
}
this.exportShow = true;
this.exportType = this.orderQueryObj.marketing_id;
},
async printOrderMet(forcePrint) {
const params = {
marketing_id: this.orderQueryObj.marketing_id,
force_print: forcePrint ? "1" : ""
};
const res = await newOrderPrint(params);
return res;
},
// 打印
async printOrder() {
if (this.orderQueryObj.marketing_id === "") {
this.$message.error("请选择活动名称");
return;
}
let res = await this.printOrderMet(false);
if (res.code === 0) {
this.$message({
type: "success",
message: "打印成功"
});
return;
}
if (res.code !== 5111040) {
if (res.reason) {
this.$message.error(res.reason);
} else {
this.$message.error("打印失败");
}
return;
}
if (res.reason) {
try {
await this.$confirm(res.reason, "打印", {
cancelButtonText: "取消",
confirmButtonText: "确定"
});
} catch (e) {
// 取消
return;
}
} else {
this.$message.error("打印失败");
}
res = await this.printOrderMet(true);
},
// 获取订单列表
async getOrderListMet() {
try {
let res = null;
if (this.$route.query.marketing_type == "4") {
res = await newGetOrderList({
page: 1,
page_size: 10,
marketing_id: this.$route.query.marketing_id,
order_status: "0",
goods_id: "",
cust_user: "",
order_id: "",
sub_shop_id: ""
});
} else {
res = await newGetOrderList(this.orderQueryObj);
}
this.goodsNum = res.goods_num; // 商品共计
this.totalNum = res.count; // 商品总数
this.orderTableData = res.result;
} catch (error) {
this.$message.error("发生未知错误,请稍后再试一下吧~~~");
console.error(error);
}
},
// 列表分页 页码变化
handleCurrentChange(e) {
this.orderQueryObj.page = e;
this.getOrderListMet();
},
// 拒绝
async refuse(val) {
try {
await this.$confirm("确定要拒绝退款么?", "拒绝", {
cancelButtonText: "取消",
confirmButtonText: "确定"
});
} catch (e) {
// 取消
return;
}
const params = {
order_id: val.order_id
};
const res = await newOrderRefundReject(params);
if (res.code === 0) {
this.$message({
type: "success",
message: "订单已驳回"
});
} else {
this.$message.error(res.reason);
}
this.getOrderListMet();
},
// 同意
agree(val) {
this.refund(val);
},
// 全选
handleCheckAllChange(val) {
for (var i in this.refundGoods) {
this.refundGoods[i].refundedGoodsSel = val;
}
},
// 退款
async refund(val) {
this.refundShow = true;
this.checkAll = false;
this.refundGoods = [];
const params = {
order_id: val.order_id
};
const res = await newOrderItemList(params);
this.refundGoods = res.result;
for (var i in res.result) {
this.refundGoods[i].payment = Number(res.result[i].payment);
}
},
// 退款确认
async handleConfirmRefund() {
const isCheckAllSelected = () => this.refundGoods.refundedGoodsSel;
const getAllItems = () => this.refundGoods;
const getSelectedItems = () => {
const isSelected = ({ refundedGoodsSel }) => refundedGoodsSel;
return this.refundGoods.filter(isSelected);
};
for (var i in this.refundGoods) {
if (
this.refundGoods[i].refundedGoodsSel == true &&
this.refundGoods[i].restoreInventory == true
) {
this.refundGoods[i].refund_type = "1";
} else {
this.refundGoods[i].refund_type = "2";
}
}
const convertToNumber = str => {
return !Number.isNaN(parseFloat(str)) ? parseFloat(str) : 0;
};
const processRefundItem = item => {
return {
order_item_id: item.order_item_id,
refund_num: item.refundableQuantity || 0,
refund_amount: convertToNumber(item.amountToRefund),
refund_type: item.refund_type
};
};
const orderId = this.refundGoods[0].order_id;
let itemsToRefund = null;
if (isCheckAllSelected()) {
itemsToRefund = getAllItems();
} else {
itemsToRefund = getSelectedItems();
}
itemsToRefund = itemsToRefund.map(processRefundItem);
const res = await newRefundOrder(orderId, itemsToRefund);
if (res.code === 0) {
this.$message.success("退款成功");
this.getOrderListMet();
this.refundShow = false;
return;
}
this.$message.error(res.reason);
}
},
created() {
this.getMarketingListMet(); // 活动名称
this.getSubShopListMet(); // 自提点
this.getOrderListMet(); // table列表
}
};
</script>
<style lang="less" src="../orderManagement/index.less" scoped></style>
<style lang="less" scoped>
.check-wrap {
/deep/ .el-checkbox__label {
white-space: normal;
word-break: break-all;
}
}
.refundCon /deep/ .el-row {
margin-bottom: 15px;
display: flex;
align-items: center;
}
</style>
......@@ -15,9 +15,3 @@
display: block;
text-align: center;
}
.refundCon /deep/ .el-row {
margin-bottom: 15px;
display: flex;
align-items: center;
}
\ No newline at end of file
......@@ -513,7 +513,7 @@ export default {
marketing_id: val,
};
const res = await getGoodsList(params); // 商品名称
this.getSubShopListMet(val) //自提点
this.getSubShopListMet(val); //自提点
// const res = await getSubShopList(params);
this.tradeNameArr = res.result;
// this.selLiftPoinArr = res.result;
......@@ -522,11 +522,11 @@ export default {
// 获取自提点
async getSubShopListMet(params) {
try {
let marketing_id = ''
if(params){
marketing_id = params
let marketing_id = "";
if (params) {
marketing_id = params;
}
const res = await getSubShopList({'marketing_id':marketing_id});
const res = await getSubShopList({ marketing_id: marketing_id });
this.selLiftPoinArr = res.result;
} catch (error) {
this.$message.error("发生未知错误,请稍后再试一下吧~~~");
......@@ -766,11 +766,15 @@ export default {
<style lang="less" src="./index.less" scope></style>
<style lang="less" scoped>
.check-wrap{
.check-wrap {
/deep/ .el-checkbox__label {
white-space: normal;
word-break: break-all;
}
}
.refundCon /deep/ .el-row{
margin-bottom: 15px;
display: flex;
align-items: center;
}
</style>
/**
* 活动管理
*/
const activityRouters = [
{
path: "/op/activity",
redirect: "/op/activity/manage"
},
{
path: "/op/activity/manage",
name: "ManageList",
component: () =>
import(/* webpackChunkName: "activity" */ "@/pages/Activity/Manage")
},
// 发布拼单
{
path: "/op/activity/releaseProduc",
name: "releaseProduc",
component: () =>
import(
/* webpackChunkName: "activity" */ "@/pages/Activity/releaseProduc"
)
},
// 标题详情
{
path: "/op/activity/activityDetail",
name: "ActivityDetail",
component: () =>
import(
/* webpackChunkName: "activity" */ "@/pages/Activity/ActivityDetail"
)
},
{
path: "/op/activity/releaseProduc/spellOrderSet",
name: "spellOrderSet",
component: () =>
import(
/* webpackChunkName: "activity" */ "@/pages/Activity/releaseProduc/components/spellOrderSet"
)
}
];
export default activityRouters;
......@@ -8,6 +8,12 @@
// redirect: "/op/groupmeal/orderManagement",
component: () => import(/* webpackChunkName: "goods" */ "@/pages/Groupmeal/orderManagement")
},
{
path: "/op/groupmeal/newOrderManagement",
name: "newOrderManagement",
// redirect: "/op/groupmeal/orderManagement",
component: () => import(/* webpackChunkName: "goods" */ "@/pages/Groupmeal/newOrderManagement")
},
{
path: "/op/groupmeal/distrib",
name: "Distrib",
......
......@@ -10,6 +10,8 @@ import User from "../pages/User/userList";
import ManageRole from "../pages/Role/manage-role.vue";
import RoleDetail from "../pages/Role/role-detail.vue";
import goodsRouter from "./Goods/index";
import activityRouters from "./Activity/index";
import withdrawalRoutes from "./Withdrawal/index";
import groupmealRouters from "./Groupmeal/index";
const routes = [
......@@ -96,12 +98,13 @@ const routes = [
},
// 商品管理路由
...goodsRouter,
// 活动管理路由
...activityRouters,
// 钱包审核
...withdrawalRoutes,
// 团餐运营
...groupmealRouters
];
console.log(routes);
const router = createRouter({
history: createWebHistory(),
......
import axios from "@/utils/request";
// 获取商家列表
export async function getBusinessList(params) {
const res = await axios.get("/api/v1/goods/background/ota_list", {
params
});
return res;
}
// 添加商品
export async function addGoods(params) {
const res = await axios.post("/api/v1/goods/background/add_goods", params);
return res;
}
// 商品库列表
export async function pindanGoods(params) {
const res = await axios.get("/api/v1/goods/background/pindan_goods", {
params
});
return res;
}
// 查看商品详情
export async function markGoodsInfo(params) {
const res = await axios.get("/api/v1/goods/background/marketing_goods_info", {
params
});
return res;
}
// 编辑商品详情
export async function editGoods(params) {
const res = await axios.post("/api/v1/goods/background/edit_goods", params);
return res;
}
// 添加营销活动
export async function addMarketing(params) {
const res = await axios.post(
"/api/v1/marketing/background/add_marketing",
params
);
return res;
}
// 编辑营销活动
export async function updateMarketing(params) {
const res = await axios.post(
"/api/v1/marketing/background/update_marketing",
params
);
return res;
}
// 营销活动详情
export async function marketingInfo(params) {
const res = await axios.post(
"/api/v1/marketing/background/marketing_info",
params
);
return res;
}
class ActivityService {
// 获取活动列表
static async getActivityList(params) {
const res = await axios.get("/api/v1/marketing/background/marketing_list", {
params
});
return res;
}
// 修改商品
static async editGoodsDetail(query) {
const res = await axios.post("/api/v1/goods/background/edit_goods", {
...query
});
return res;
}
// 关闭/开启 活动
static async updateActivity(query) {
const res = await axios.post(
"/api/v1/marketing/background/update_marketing_online_status",
{
...query
}
);
return res;
}
// 查看活动订单
static async checkActivityDetail(query) {
const res = await axios.post(
"/api/v1/marketing/background/marketing_info",
{
...query
}
);
return res;
}
// 查看活动订单-- 具体信息(新添加)
static async checkActivityDetailInfo(params) {
const res = await axios.get(
"/api/v1/order/background/pindan_marketing_info_data_statistics",
{
params
}
);
return res;
}
// 获取自提点列表
static async getPlaceList(params) {
const res = await axios.get(
"/api/v1/marketing/background/take_place_list",
{
params
}
);
return res;
}
// 添加自提点
static async addPlace(query) {
const res = await axios.post(
"/api/v1/marketing/background/add_take_place",
{
...query
}
);
return res;
}
//删除自提点
static async deletePlace(query) {
const res = await axios.post(
"/api/v1/marketing/background/delete_take_place",
{
...query
}
);
return res;
}
}
export default ActivityService;
......@@ -27,6 +27,8 @@ export async function getSaveDeliverer(params) {
return res;
}
// 老订单管理
// 获取订单列表
export async function getOrderList(params) {
const res = await axios.get("/api/v1/order/oldbackground/order_list", {
......@@ -57,6 +59,14 @@ export async function getSubShopList(params) {
return res;
}
// 导出订单
export async function orderExport(params) {
const res = await axios.get("/api/v1/order/oldbackground/order_export", {
params
});
return res;
}
// 打印订单
export async function orderPrint(params) {
const res = await axios.get("/api/v1/order/oldbackground/order_print", {
......@@ -104,3 +114,79 @@ export function getOrderExportURL(eventId, type) {
}
return `${ENV}order/oldbackground/order_export?marketing_id=${eventId}&type=${type}`;
}
// 新订单管理
// 获取订单列表
export async function newGetOrderList(params) {
const res = await axios.get("/api/v1/order/background/order_list", {
params
});
return res;
}
// 获取活动名称
export async function newGetMarketingList() {
const res = await axios.get("/api/v1/order/background/order_condition_marketing_list");
return res;
}
// 获取商品名称
export async function newGetGoodsList(params) {
const res = await axios.get("/api/v1/order/background/order_condition_goods_list", {
params
});
return res;
}
// 获取自提点
export async function newGetSubShopList(params) {
const res = await axios.get("/api/v1/order/background/order_condition_take_place_list",{
params
});
return res;
}
// 打印订单
export async function newOrderPrint(params) {
const res = await axios.get("/api/v1/order/background/order_print", {
params
});
return res;
}
// 订单退款列表
export async function newOrderItemList(params) {
const res = await axios.get("/api/v1/order/background/order_item_list", {
params
});
return res;
}
// 订单退款
export async function newRefundOrder(orderId, itemsToRefund) {
const res = await axios.post("/api/v1/order/background/order_refund", {
order_id: orderId,
refund_list: itemsToRefund
});
return res;
}
// 订单驳回
export async function newOrderRefundReject(params) {
const res = await axios.get("/api/v1/order/background/order_refund_reject", {
params
});
return res;
}
// 导出订单
export function newGetOrderExportURL(eventId, type) {
var ENV;
if(process.env.NODE_ENV == "development"){
ENV = "http://bp-dev.ini.yidian-inc.com/"
}else{
ENV = "http://bp-test.ini.yidian-inc.com/"
}
return `${ENV}order/background/order_export?marketing_id=${eventId}&type=${type}`;
}
......@@ -25,8 +25,6 @@ export default createStore({
actions: {
async updateUserPermission({ commit }, payload) {
const { permissions = [] } = await getPermissions(payload.email);
console.log("VUEX action updateUserPermission::", permissions);
commit("updateUserPermission", permissions);
},
async fetchPermission({ commit }, { email, appId }) {
......
export default function remoteLoad(url, hasCallback) {
return createScript(url);
/**
* 创建script
* @param url
* @returns {Promise}
*/
function createScript(url) {
let scriptElement = document.createElement("script");
document.body.appendChild(scriptElement);
let promise = new Promise((resolve, reject) => {
scriptElement.addEventListener(
"load",
e => {
removeScript(scriptElement);
if (!hasCallback) {
resolve(e);
}
},
false
);
scriptElement.addEventListener(
"error",
e => {
removeScript(scriptElement);
reject(e);
},
false
);
if (hasCallback) {
window.____callback____ = function() {
resolve();
window.____callback____ = null;
};
}
});
if (hasCallback) {
url += "&callback=____callback____";
}
scriptElement.src = url;
return promise;
}
/**
* 移除script标签
* @param scriptElement script dom
*/
function removeScript(scriptElement) {
document.body.removeChild(scriptElement);
}
}
import axios from "axios";
import store from "@/store"
import { v1 as uuidv1 } from 'uuid';
import store from "@/store";
import { v1 as uuidv1 } from "uuid";
// import jsonBig from 'json-bigint'
// import { ElMessage } from "element-plus";
......@@ -32,17 +32,16 @@ export const defaultConfig = {
*/
const getDefaultParams = () => {
return {
'op_cur_user': store.state.userInfo && store.state.userInfo.email,
'reqid': uuidv1().replace(/-/g, '')
}
op_cur_user: store.state.userInfo && store.state.userInfo.email,
reqid: uuidv1().replace(/-/g, "")
};
};
const getDefaultHeaders = (config) => {
const getDefaultHeaders = config => {
const { method } = config;
if (method.toLowerCase() === 'post') {
if (method.toLowerCase() === "post") {
return {
"Content-Type": "application/json"
}
};
}
};
......@@ -56,7 +55,7 @@ const instance = axios.create(defaultConfig);
* axios instance interceptors
*/
instance.interceptors.request.use(
function (config) {
function(config) {
// network error
if (navigator.onLine !== undefined && navigator.onLine === false) {
return Promise.reject({ message: "网络未链接", code: -1 });
......@@ -65,7 +64,7 @@ instance.interceptors.request.use(
/**
* merge headers
*/
config.headers = { ...getDefaultHeaders(config), ...config.headers }
config.headers = { ...getDefaultHeaders(config), ...config.headers };
/**
* merge params
......@@ -74,7 +73,7 @@ instance.interceptors.request.use(
return config;
},
function (error) {
function(error) {
// handle error
return Promise.reject(error);
}
......@@ -84,7 +83,7 @@ instance.interceptors.request.use(
* axios response instance
*/
instance.interceptors.response.use(
function (response) {
function(response) {
const { data = {} } = response;
// const code = data.code ?? -1;
// if (code !== 0) {
......@@ -106,8 +105,7 @@ instance.interceptors.response.use(
// return data;
// }
return data;
},
}
// function (error) {
// if (!(error.code && error.code === -1)) error.message = "接口请求错误";
// showErrorMessage(error.message);
......
const path = require('path');
const path = require("path");
const isDev = process.env.NODE_ENV === 'development';
const isDev = process.env.NODE_ENV === "development";
module.exports = {
outputDir: isDev
? './dist'
: path.resolve('./public/dist/'),
publicPath: isDev ? '/' : '/dist',
outputDir: isDev ? "./dist" : path.resolve("./public/dist/"),
publicPath: isDev ? "/" : "/dist",
configureWebpack: {
devServer: {
proxy: 'http://localhost:8055',
proxy: "http://127.0.0.1:8055", //http://localhost:8055
hot: true,
disableHostCheck: true,
},
disableHostCheck: true
}
},
chainWebpack: config => {
// 默认不开启 prefetch
config.plugins.delete('prefetch');
// 默认不开启 c
config.plugins.delete("prefetch");
// 默认不开启 preload
config.plugins.delete('preload');
config.plugins.delete("preload");
// 修改页面 title
config.plugin('html').tap(args => {
args[0].title = '运营管理系统';
config.plugin("html").tap(args => {
args[0].title = "运营管理系统";
return args;
});
},
}
};
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