新增商品团购
This commit is contained in:
@@ -40,7 +40,7 @@ export const newMenus = [
|
||||
{
|
||||
name: "套餐推广",
|
||||
icon: "tctg",
|
||||
pathName: "",
|
||||
pathName: "package_popularize",
|
||||
intro: "下单通过用户邀请好友减免金额的方式裂变宣传套餐加购",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="模块内容">
|
||||
<div class="textarea">
|
||||
<el-input type="textarea" :rows="4" :maxlength="50" placeholder="请输入内容"
|
||||
<el-input type="textarea" :rows="4" :maxlength="20" placeholder="请输入内容"
|
||||
v-model.trim="form.content"></el-input>
|
||||
<span class="num">{{ form.content.length }}/20</span>
|
||||
</div>
|
||||
@@ -68,14 +68,14 @@
|
||||
<el-form-item label="首页弹窗">
|
||||
<div class="center">
|
||||
<el-switch v-model="form.homeEnable" :active-value="1" :inactive-value="0"></el-switch>
|
||||
<div class="tips">开启后至少勾选1个显示时机</div>
|
||||
<!-- <div class="tips">开启后至少勾选1个显示时机</div> -->
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="显示时机" prop="homeType">
|
||||
<el-radio-group v-model="form.homeType">
|
||||
<el-radio value="only" label="仅显示1次" :disabled="!form.homeEnable"></el-radio>
|
||||
<el-radio value="day" label="每天显示1次" :disabled="!form.homeEnable"></el-radio>
|
||||
<el-radio value="every" label="每次达成触发条件都显示" :disabled="!form.homeEnable"></el-radio>
|
||||
<el-radio value="every" label="每次进入小程序" :disabled="!form.homeEnable"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="模块提示语">
|
||||
@@ -121,7 +121,7 @@ const rules = reactive({
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
if (form.value.orderType.length <= 0) {
|
||||
if (form.value.orderEnable && form.value.orderType.length <= 0) {
|
||||
callback(new Error('请选择可使用类型'))
|
||||
} else {
|
||||
callback()
|
||||
@@ -192,6 +192,10 @@ function submitHandle() {
|
||||
data.note = defaultNote.value
|
||||
}
|
||||
|
||||
if (data.content == '') {
|
||||
data.note = defaultContent.value
|
||||
}
|
||||
|
||||
await drainageConfigPost(data);
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
@@ -225,6 +229,9 @@ async function drainageConfigGetAjax() {
|
||||
if (form.value.note == '') {
|
||||
form.value.note = defaultNote.value
|
||||
}
|
||||
if (form.value.content == '') {
|
||||
form.value.content = defaultContent.value
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
<el-form-item label="可用门店">
|
||||
<el-radio-group v-model="form.useShopType" @change="useShopTypeChange">
|
||||
<el-radio label="仅本店" value="only"></el-radio>
|
||||
<el-radio label="全部门店" value="all"></el-radio>
|
||||
<el-radio label="指定门店可用" value="custom"></el-radio>
|
||||
<template v-if="shopInfo.isHeadShop && shopInfo.shopType != 'only'">
|
||||
<el-radio label="全部门店" value="all"></el-radio>
|
||||
<el-radio label="指定门店可用" value="custom"></el-radio>
|
||||
</template>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.useShopType == 'custom'" prop="useShops">
|
||||
@@ -18,7 +20,7 @@
|
||||
<div class="column">
|
||||
<el-input v-model="form.wareName" placeholder="请输入商品名称" :maxlength="30" style="width: 300px;"></el-input>
|
||||
<div>
|
||||
<el-button link type="primary">导入已有商品信息</el-button>
|
||||
<el-button link type="primary" @click="selecProductDialogRef.show()">导入已有商品信息</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
@@ -27,7 +29,8 @@
|
||||
v-model="form.wareDetail" style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图片" prop="wareImgs">
|
||||
<MultiImageUpload v-model="wareImgs" @uploadAllSuccess="wareImgsMultiOnSuccess" />
|
||||
<MultiImageUpload v-model="wareImgs" @uploadStart="loading = true"
|
||||
@uploadAllSuccess="wareImgsMultiOnSuccess" />
|
||||
</el-form-item>
|
||||
<el-form-item label="原价" prop="originalPrice">
|
||||
<el-input v-model="form.originalPrice" placeholder="请输入商品原价" :maxlength="8"
|
||||
@@ -39,7 +42,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="成团人数" prop="groupPeopleNum">
|
||||
<el-input v-model="form.groupPeopleNum" placeholder="当参与人数达到成团人数才能完成拼团" :maxlength="8"
|
||||
@input="e => form.groupPeopleNum = filterNumberInput(e, 1)" style="width: 300px;"></el-input>
|
||||
@input="e => form.groupPeopleNum = filterNumberInput(e, 2)" style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="成团期限" prop="groupTimeoutHour">
|
||||
<el-input v-model="form.groupTimeoutHour" placeholder="最小不低于1小时,最大不超过72小时" :maxlength="8"
|
||||
@@ -58,7 +61,8 @@
|
||||
<el-switch v-model="form.onlineStatus" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品详情">
|
||||
<MultiImageUpload v-model="wareCommentImgs" @upload-all-success="wareCommentImgsMultiOnSuccess" />
|
||||
<MultiImageUpload v-model="wareCommentImgs" @uploadStart="loading = true"
|
||||
@upload-all-success="wareCommentImgsMultiOnSuccess" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@@ -74,13 +78,27 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<selecProductDialog ref="selecProductDialogRef" @success="selectProduceHandle" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { filterNumberInput } from '@/utils'
|
||||
import { addGbWare, updateGbWareById } from '@/api/market/ware'
|
||||
import selecProductDialog from './selecProductDialog.vue'
|
||||
|
||||
const shopInfo = ref(null)
|
||||
|
||||
const selecProductDialogRef = ref(null)
|
||||
|
||||
// 选择商品导入
|
||||
function selectProduceHandle(obj) {
|
||||
form.value.wareName = obj.name
|
||||
form.value.wareImgs = obj.coverImg
|
||||
form.value.originalPrice = obj.price
|
||||
wareImgs.value = [obj.coverImg]
|
||||
}
|
||||
|
||||
const visible = ref(false)
|
||||
const limitBuyNumSwitch = ref(false) // 如果limitBuyNum = -10086 就是false,不限购,true为限购
|
||||
@@ -171,7 +189,7 @@ const rules = ref({
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
if (form.value.groupTimeoutHour < 1 || !form.value.groupTimeoutHour) {
|
||||
callback(new Error('请输入成团人数'))
|
||||
callback(new Error('请输入成团期限'))
|
||||
} else if (form.value.groupTimeoutHour > 72) {
|
||||
callback(new Error('最大不超过72小时'))
|
||||
} else {
|
||||
@@ -184,7 +202,7 @@ const rules = ref({
|
||||
limitBuyNum: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (form.value.limitBuyNumSwitch && !form.value.limitBuyNum) {
|
||||
if (limitBuyNumSwitch.value && !form.value.limitBuyNum) {
|
||||
callback(new Error('请输入每人最多购买次数'))
|
||||
} else {
|
||||
callback()
|
||||
@@ -205,11 +223,13 @@ function limitBuyNumSwitchChange(e) {
|
||||
|
||||
// 多图上传成功
|
||||
function wareImgsMultiOnSuccess(response) {
|
||||
loading.value = false
|
||||
form.value.wareImgs = wareImgs.value.join(',')
|
||||
}
|
||||
|
||||
// 商品详情图片上传成功
|
||||
function wareCommentImgsMultiOnSuccess(res) {
|
||||
loading.value = false
|
||||
form.value.wareCommentImgs = wareCommentImgs.value.join(',')
|
||||
}
|
||||
|
||||
@@ -220,6 +240,8 @@ function useShopTypeChange(e) {
|
||||
// 提交保存
|
||||
const emits = defineEmits(['success'])
|
||||
function submitHandle() {
|
||||
form.value.wareImgs = wareImgs.value.join(',')
|
||||
form.value.wareCommentImgs = wareCommentImgs.value.join(',')
|
||||
formRef.value.validate(async vaild => {
|
||||
try {
|
||||
if (vaild) {
|
||||
@@ -252,6 +274,11 @@ function submitHandle() {
|
||||
|
||||
function resetHandle() {
|
||||
form.value = { ...formObj }
|
||||
limitBuyNumSwitch.value = false
|
||||
wareImgs.value = []
|
||||
wareCommentImgs.value = []
|
||||
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
function show(obj) {
|
||||
@@ -276,6 +303,10 @@ function show(obj) {
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
shopInfo.value = JSON.parse(localStorage.getItem('userInfo'))
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<el-input v-model="queryForm.orderNo" placeholder="请输入订单号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input v-model="queryForm.groupNo" placeholder="请输入关联团单号"></el-input>
|
||||
<el-input v-model="queryForm.groupOrderNo" placeholder="请输入关联团单号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" :loading="tableData.loading" @click="searchHandle">搜索</el-button>
|
||||
@@ -67,21 +67,56 @@
|
||||
</div>
|
||||
<div class="row mt14">
|
||||
<el-table :data="tableData.list" stripe border v-loading="tableData.loading">
|
||||
<el-table-column label="订单号" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="商品" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="购买用户" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="支付金额(元)" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="支付时间" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="下单门店" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="状态" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="团单号" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="成团时间" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="核销码" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="核销时间" prop="orderNo"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<el-table-column label="订单号" prop="orderNo" width="180"></el-table-column>
|
||||
<el-table-column label="商品" prop="wareJson" width="200">
|
||||
<template v-slot="scope">
|
||||
<el-button link type="primary">核销</el-button>
|
||||
<el-button link type="danger">退款</el-button>
|
||||
<div class="center">
|
||||
<el-image :src="scope.row.wareJson.wareImgs.split(',')[0]"
|
||||
style="width: 40px;height: 40px;flex-shrink: 0;"></el-image>
|
||||
<el-text>{{ scope.row.wareJson.wareName }}</el-text>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="购买用户" prop="userName" width="200">
|
||||
<template v-slot="scope">
|
||||
<div class="center">
|
||||
{{ scope.row.userName }} / {{ scope.row.userPhone }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="支付金额(元)" prop="payAmount" width="130"></el-table-column>
|
||||
<el-table-column label="支付时间" prop="payTime" width="180"></el-table-column>
|
||||
<el-table-column label="下单门店" prop="shopName" width="130"></el-table-column>
|
||||
<el-table-column label="状态" prop="status" width="100">
|
||||
<template v-slot="scope">
|
||||
<el-tag disable-transitions :type="statusFilter(scope.row).type">
|
||||
{{ scope.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="团单号" prop="groupOrderNo" width="180"></el-table-column>
|
||||
<el-table-column label="成团时间" prop="groupEndTime" width="180"></el-table-column>
|
||||
<el-table-column label="核销码" prop="verifyCode" width="180"></el-table-column>
|
||||
<el-table-column label="核销时间" prop="verifyTime" width="180"></el-table-column>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template v-slot="scope">
|
||||
<template v-if="includesString(scope.row.status, '退款中')">
|
||||
<el-button link type="danger" @click="refundPopupHandle(scope.row)">审核</el-button>
|
||||
</template>
|
||||
<template v-if="includesString(scope.row.status, '待核销') || includesString(scope.row.status, '待成团')">
|
||||
<el-popconfirm title="确认要退款吗?" @confirm="refundHandle(scope.row)">
|
||||
<template #reference>
|
||||
<el-button link type="danger">退款</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
<template v-if="includesString(scope.row.status, '待核销')">
|
||||
<el-popconfirm title="确认要核销吗?" @confirm="checkoutHandle(scope.row)">
|
||||
<template #reference>
|
||||
<el-button link type="primary">核销</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -97,47 +132,67 @@
|
||||
<script setup>
|
||||
import dayjs from 'dayjs'
|
||||
import { ref, reactive } from 'vue'
|
||||
import { filterNumberInput, multiplyAndFormat } from '@/utils'
|
||||
import { filterNumberInput, multiplyAndFormat, includesString } from '@/utils'
|
||||
import { gbOrderPage, orderAgreeRefund, orderRejectRefund, orderCheckout, wareCount } from '@/api/market/ware'
|
||||
|
||||
const statusList = ref([
|
||||
{
|
||||
label: '待成团',
|
||||
value: 1,
|
||||
label: '待支付',
|
||||
value: '待支付',
|
||||
type: 'info'
|
||||
},
|
||||
{
|
||||
label: '待核销',
|
||||
value: 2,
|
||||
value: '待核销',
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
label: '待成团',
|
||||
value: '待成团',
|
||||
type: 'warning'
|
||||
},
|
||||
{
|
||||
label: '已核销',
|
||||
value: 3,
|
||||
value: '已核销',
|
||||
type: 'success'
|
||||
},
|
||||
{
|
||||
label: '退款中',
|
||||
value: 4,
|
||||
type: 'warning'
|
||||
value: '退款中',
|
||||
type: 'danger'
|
||||
},
|
||||
{
|
||||
label: '已退款',
|
||||
value: 5,
|
||||
value: '已退款',
|
||||
type: 'info'
|
||||
}
|
||||
])
|
||||
|
||||
// 筛选tag type
|
||||
function statusFilter(row) {
|
||||
let obj = statusList.value.find(item => includesString(row.status, item.value))
|
||||
if (obj) {
|
||||
return obj
|
||||
} else {
|
||||
return {
|
||||
label: row.status,
|
||||
value: row.status,
|
||||
type: 'info'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const confirmOrderTimes = ref([])
|
||||
const checkoutOrderTimes = ref([])
|
||||
const queryForm = reactive({
|
||||
status: '',
|
||||
orderStartTime: '',
|
||||
orderEndTime: '',
|
||||
checkoutStartTime: '',
|
||||
checkoutEndTime: '',
|
||||
verifyStartTime: '',
|
||||
verifyEndTime: '',
|
||||
phone: '',
|
||||
orderNo: '',
|
||||
groupNo: ''
|
||||
groupOrderNo: ''
|
||||
})
|
||||
|
||||
// 搜索
|
||||
@@ -154,11 +209,11 @@ function refreshHandle() {
|
||||
queryForm.status = ''
|
||||
queryForm.orderStartTime = ''
|
||||
queryForm.orderEndTime = ''
|
||||
queryForm.checkoutStartTime = ''
|
||||
queryForm.checkoutEndTime = ''
|
||||
queryForm.verifyStartTime = ''
|
||||
queryForm.verifyEndTime = ''
|
||||
queryForm.phone = ''
|
||||
queryForm.orderNo = ''
|
||||
queryForm.groupNo = ''
|
||||
queryForm.groupOrderNo = ''
|
||||
searchHandle()
|
||||
}
|
||||
|
||||
@@ -176,15 +231,20 @@ function confirmOrderTimesChange(value) {
|
||||
// 核销时间范围
|
||||
function checkoutOrderTimesChange(value) {
|
||||
if (value && value.length === 2) {
|
||||
queryForm.checkoutStartTime = dayjs(value[0]).format('YYYY-MM-DD 00:00:00');
|
||||
queryForm.checkoutEndTime = dayjs(value[1]).format('YYYY-MM-DD 23:59:59');
|
||||
queryForm.verifyStartTime = dayjs(value[0]).format('YYYY-MM-DD 00:00:00');
|
||||
queryForm.verifyEndTime = dayjs(value[1]).format('YYYY-MM-DD 23:59:59');
|
||||
} else {
|
||||
queryForm.checkoutStartTime = '';
|
||||
queryForm.checkoutEndTime = '';
|
||||
queryForm.verifyStartTime = '';
|
||||
queryForm.verifyEndTime = '';
|
||||
}
|
||||
}
|
||||
|
||||
const infoObj = reactive({})
|
||||
// 订单统计数据
|
||||
const infoObj = reactive({
|
||||
successAmount: 0,
|
||||
pendingAmount: 0,
|
||||
balanceAmount: 0
|
||||
})
|
||||
|
||||
const tableData = reactive({
|
||||
page: 1,
|
||||
@@ -206,9 +266,119 @@ function handleCurrentChange(e) {
|
||||
getTableData();
|
||||
}
|
||||
|
||||
// 直接退款操作
|
||||
async function refundHandle(row) {
|
||||
try {
|
||||
tableData.loading = true
|
||||
await orderAgreeRefund({
|
||||
recordId: row.id,
|
||||
orderNo: row.orderNo,
|
||||
reason: ''
|
||||
})
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
getTableData()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
tableData.loading = false
|
||||
}
|
||||
|
||||
// 审核退款操作
|
||||
function refundPopupHandle(row) {
|
||||
let promptValue = ''
|
||||
ElMessageBox.prompt('请通过审核或驳回?', '退款审核', {
|
||||
confirmButtonText: '通过',
|
||||
cancelButtonText: '驳回',
|
||||
inputPlaceholder: '驳回原因',
|
||||
inputValidator: (value) => {
|
||||
promptValue = value; // 核心:缓存最新输入值
|
||||
return true; // 不做校验,仅缓存
|
||||
},
|
||||
}).then(async ({ value }) => {
|
||||
try {
|
||||
console.log('通过', value);
|
||||
tableData.loading = true
|
||||
await orderAgreeRefund({
|
||||
recordId: row.id,
|
||||
orderNo: row.orderNo,
|
||||
reason: value
|
||||
})
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
getTableData()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}).catch(async () => {
|
||||
console.log('驳回', promptValue);
|
||||
tableData.loading = true
|
||||
await orderRejectRefund({
|
||||
recordId: row.id,
|
||||
orderNo: row.orderNo,
|
||||
reason: value
|
||||
})
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
getTableData()
|
||||
})
|
||||
}
|
||||
|
||||
// 核销操作
|
||||
async function checkoutHandle(row) {
|
||||
try {
|
||||
tableData.loading = true
|
||||
await orderCheckout(row.verifyCode)
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '已核销',
|
||||
type: 'success'
|
||||
})
|
||||
getTableData()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取订单列表
|
||||
async function getTableData() {
|
||||
try {
|
||||
tableData.loading = true
|
||||
const res = await gbOrderPage({
|
||||
...queryForm,
|
||||
page: tableData.page,
|
||||
size: tableData.size
|
||||
})
|
||||
res.records.forEach(item => {
|
||||
item.wareJson = JSON.parse(item.wareJson)
|
||||
})
|
||||
tableData.list = res.records
|
||||
tableData.total = res.totalRow
|
||||
|
||||
console.log(tableData.list);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
setTimeout(() => {
|
||||
tableData.loading = false
|
||||
}, 300);
|
||||
}
|
||||
|
||||
// 获取统计数据
|
||||
async function wareCountAjax() {
|
||||
try {
|
||||
const res = await wareCount({
|
||||
...queryForm,
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
@@ -216,6 +386,7 @@ async function getTableData() {
|
||||
|
||||
onMounted(() => {
|
||||
getTableData()
|
||||
wareCountAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -226,6 +397,11 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.info_wrap {
|
||||
display: flex;
|
||||
gap: 48px;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="row mt14">
|
||||
<div class="row">
|
||||
<el-table :data="tableData.list" stripe border v-loading="tableData.loading">
|
||||
<el-table-column label="商品图片">
|
||||
<template v-slot="scope">
|
||||
@@ -43,25 +43,30 @@
|
||||
<el-table-column label="拼团价(元)" prop="groupPrice"></el-table-column>
|
||||
<el-table-column label="成团期限(小时)" prop="groupTimeoutHour"></el-table-column>
|
||||
<el-table-column label="成团人数" prop="groupPeopleNum"></el-table-column>
|
||||
<el-table-column label="上架状态" prop="onlineStatus">
|
||||
<el-table-column label="上架状态" prop="onlineStatus" width="100">
|
||||
<template v-slot="scope">
|
||||
<el-switch v-model="scope.row.onlineStatus" :active-value="1" :inactive-value="0"
|
||||
@change="editOnlineStatusAjax($event, scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" prop="createTime"></el-table-column>
|
||||
<el-table-column label="创建时间" prop="createTime" width="200"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<template v-slot="scope">
|
||||
<template v-if="scope.row.onlineStatus">
|
||||
<el-button link type="primary" disabled>(下架后编辑/删除)</el-button>
|
||||
<template v-if="scope.row.shopId === shopInfo.id">
|
||||
<template v-if="scope.row.onlineStatus">
|
||||
<el-button link type="primary" disabled>(下架后编辑/删除)</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button link type="primary" @click="addGroupGoodsRef.show(scope.row)">编辑</el-button>
|
||||
<el-popconfirm title="确认要删除吗?" @confirm="delHandle(scope.row)">
|
||||
<template #reference>
|
||||
<el-button type="danger" link>删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button link type="primary" @click="addGroupGoodsRef.show(scope.row)">编辑</el-button>
|
||||
<el-popconfirm title="确认要删除吗?" @confirm="delHandle(scope.row)">
|
||||
<template #reference>
|
||||
<el-button type="danger" link>删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-button link type="primary" disabled>无权操作</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -82,6 +87,8 @@ import { ref, reactive } from 'vue'
|
||||
import addGroupGoods from './addGroupGoods.vue';
|
||||
import { getGbWarePage, editOnlineStatus, deleteGbWare } from '@/api/market/ware'
|
||||
|
||||
const shopInfo = ref(null)
|
||||
|
||||
const addGroupGoodsRef = ref(null)
|
||||
|
||||
const statusList = ref([
|
||||
@@ -192,6 +199,7 @@ async function delHandle(row) {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
shopInfo.value = JSON.parse(localStorage.getItem('userInfo'))
|
||||
getGbWarePageAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<el-dialog title="选择商品" width="800px" v-model="visible">
|
||||
<div class="scroll">
|
||||
<div class="list">
|
||||
<div class="item" v-for="item in list" :key="item.id" @click="selectItem(item)">
|
||||
<div class="img">
|
||||
<el-image :src="item.coverImg" style="width: 100%;height: 100%;border-radius: 4px;"></el-image>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="name">{{ item.name }}</div>
|
||||
<div class="price">{{ multiplyAndFormat(returnPrice(item.skuList) || 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getProductList } from '@/api/coupon/index'
|
||||
import { multiplyAndFormat } from '@/utils'
|
||||
|
||||
const visible = ref(false)
|
||||
|
||||
const list = ref([])
|
||||
|
||||
// 返回规格最高价
|
||||
function returnPrice(skuList) {
|
||||
return Math.max(...skuList.map(item => item.salePrice));
|
||||
}
|
||||
|
||||
// 选择商品
|
||||
const emits = defineEmits(['success'])
|
||||
function selectItem(item) {
|
||||
emits('success', {
|
||||
coverImg: item.coverImg,
|
||||
name: item.name,
|
||||
price: returnPrice(item.skuList)
|
||||
})
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
// 获取商品-列表
|
||||
async function getProductListAjax() {
|
||||
try {
|
||||
list.value = await getProductList()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
function show() {
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getProductListAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.scroll {
|
||||
height: 60vh;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-column-gap: 14px;
|
||||
grid-row-gap: 14px;
|
||||
|
||||
.item {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #ececec;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
transition: all .3s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
border-color: var(--el-color-primary);
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
}
|
||||
|
||||
.img {
|
||||
--size: 50px;
|
||||
height: var(--size);
|
||||
width: var(--size);
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 10px;
|
||||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
color: 333;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 16px;
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -15,9 +15,11 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { shopInfoGet } from '@/api/coupon/index'
|
||||
import groupPage from './components/groupPage.vue'
|
||||
import groupOrder from './components/groupOrder.vue'
|
||||
import { upShopConfig } from '@/api/market/ware'
|
||||
|
||||
const tabActiveIndex = ref(0)
|
||||
const tabList = ref([
|
||||
@@ -34,6 +36,26 @@ const tabList = ref([
|
||||
const form = ref({
|
||||
isEnable: 0
|
||||
})
|
||||
|
||||
watch(() => form.value.isEnable, () => {
|
||||
upShopConfigAjax()
|
||||
})
|
||||
|
||||
// 拼团商品-活动开关
|
||||
async function upShopConfigAjax() {
|
||||
try {
|
||||
await upShopConfig({
|
||||
onlineStatus: form.value.isEnable
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const { isGroupBuy } = await shopInfoGet()
|
||||
form.value.isEnable = isGroupBuy
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
<!-- 添加团购商品 -->
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog :title="form.id ? '编辑套餐' : '添加套餐'" width="1000px" v-model="visible" @submit.prevent
|
||||
@closed="resetHandle">
|
||||
<div class="form_warap">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-position="right" label-width="120">
|
||||
<el-form-item label="可用门店">
|
||||
<el-radio-group v-model="form.useShopType" @change="useShopTypeChange">
|
||||
<el-radio label="仅本店" value="only"></el-radio>
|
||||
<template v-if="shopInfo.isHeadShop && shopInfo.shopType != 'only'">
|
||||
<el-radio label="全部门店" value="all"></el-radio>
|
||||
<el-radio label="指定门店可用" value="custom"></el-radio>
|
||||
</template>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.useShopType == 'custom'" prop="useShops">
|
||||
<selectBranchs all v-model="form.useShops" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" prop="wareName">
|
||||
<div class="column">
|
||||
<el-input v-model="form.wareName" placeholder="请输入商品名称" :maxlength="30" style="width: 300px;"></el-input>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品描述">
|
||||
<el-input type="textarea" :rows="5" placeholder="请输入商品描述" :maxlength="50" show-password
|
||||
v-model="form.wareDetail" style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图片" prop="wareImgs">
|
||||
<MultiImageUpload v-model="wareImgs" @uploadStart="loading = true"
|
||||
@uploadAllSuccess="wareImgsMultiOnSuccess" />
|
||||
</el-form-item>
|
||||
<el-form-item label="原价" prop="originalPrice">
|
||||
<el-input v-model="form.originalPrice" placeholder="请输入商品原价" :maxlength="8"
|
||||
@input="e => form.originalPrice = filterNumberInput(e)" style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择商品">
|
||||
<div class="group_wrap">
|
||||
<div class="row padding" v-for="(item, index) in groupGoods" :key="index">
|
||||
<el-form inline>
|
||||
<el-form-item label="菜品组名">
|
||||
<el-input placeholder="请输入菜品组名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="`本组菜品${item.list.length}选`">
|
||||
<el-input placeholder="请数组选择数量" v-model="item.num"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button>删除</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="mt14">
|
||||
<el-table :data="item.list" border stripe>
|
||||
<el-table-column label="名称" prop="name">
|
||||
<template v-slot="scope">
|
||||
<el-input v-model="scope.row.name" placeholder="请输入名称"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="价格" prop="price">
|
||||
<template v-slot="scope">
|
||||
<el-input v-model="scope.row.price" placeholder="请输入价格"
|
||||
@input="e => scope.row.price = filterNumberInput(e)"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量" prop="num">
|
||||
<template v-slot="scope">
|
||||
<el-input-number :min="1" :step="1" v-model="scope.row.num"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="200">
|
||||
<template #header="scope">
|
||||
<el-button size="small" type="primary" @click="addGoodsHandle($event, item)">添加商品</el-button>
|
||||
<el-button size="small" type="primary" plain
|
||||
@click="showGoodsDialogHandle(index)">导入商品</el-button>
|
||||
</template>
|
||||
<template v-slot="scope">
|
||||
<el-button link type="primary">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<el-button type="primary" @click="addGroupHandle">添加套餐组</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="拼团价" prop="groupPrice">
|
||||
<el-input v-model="form.groupPrice" placeholder="请输入拼团价" :maxlength="8"
|
||||
@input="e => form.groupPrice = filterNumberInput(e)" style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="成团人数" prop="groupPeopleNum">
|
||||
<el-input v-model="form.groupPeopleNum" placeholder="当参与人数达到成团人数才能完成拼团" :maxlength="8"
|
||||
@input="e => form.groupPeopleNum = filterNumberInput(e, 2)" style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="成团期限" prop="groupTimeoutHour">
|
||||
<el-input v-model="form.groupTimeoutHour" placeholder="最小不低于1小时,最大不超过72小时" :maxlength="8"
|
||||
@input="e => form.groupTimeoutHour = filterNumberInput(e, 1)" style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="限购数量" prop="limitBuyNum">
|
||||
<div class="center">
|
||||
<el-switch v-model="limitBuyNumSwitch" @change="limitBuyNumSwitchChange"></el-switch>
|
||||
<div class="ipt" v-if="limitBuyNumSwitch">
|
||||
<el-input :maxlength="8" v-model="form.limitBuyNum" placeholder="每人最多购买次数"
|
||||
@input="e => form.limitBuyNum = filterNumberInput(e, 1)" style="width: 250px;"></el-input>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="上架状态">
|
||||
<el-switch v-model="form.onlineStatus" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品详情">
|
||||
<MultiImageUpload v-model="wareCommentImgs" @uploadStart="loading = true"
|
||||
@upload-all-success="wareCommentImgsMultiOnSuccess" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog_footer">
|
||||
<div class="btn">
|
||||
<el-button size="large" @click="visible = false" style="width: 100%;">取 消</el-button>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button size="large" type="primary" :loading="loading" @click="submitHandle" style="width: 100%;">确
|
||||
定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<selecProductDialog ref="selecProductDialogRef" @success="selectProduceHandle" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { filterNumberInput } from '@/utils'
|
||||
import { addGbWare, updateGbWareById } from '@/api/market/ware'
|
||||
import selecProductDialog from './selecProductDialog.vue'
|
||||
const shopInfo = ref(null)
|
||||
|
||||
const selecProductDialogRef = ref(null)
|
||||
|
||||
const groupGoodsItem = ref({
|
||||
name: '',
|
||||
count: '',
|
||||
list: []
|
||||
})
|
||||
|
||||
const groupGoodsItemListItem = ref({
|
||||
name: '',
|
||||
price: '',
|
||||
num: 1
|
||||
})
|
||||
|
||||
// 套餐商品组
|
||||
const groupGoods = ref([])
|
||||
|
||||
// 添加套餐租
|
||||
function addGroupHandle() {
|
||||
groupGoods.value.push({ ...groupGoodsItem.value })
|
||||
}
|
||||
|
||||
// 添加商品
|
||||
function addGoodsHandle(e, item) {
|
||||
item.list.push({ ...groupGoodsItemListItem.value })
|
||||
}
|
||||
|
||||
// 显示导入商品弹窗
|
||||
const portGoodsIndex = ref(0)
|
||||
function showGoodsDialogHandle(index) {
|
||||
portGoodsIndex.value = index
|
||||
selecProductDialogRef.value.show()
|
||||
}
|
||||
|
||||
// 选择的商品
|
||||
function selectProduceHandle(obj) {
|
||||
let data = { ...groupGoodsItemListItem.value }
|
||||
data.name = obj.name
|
||||
data.price = obj.price
|
||||
groupGoods.value[portGoodsIndex.value].list.push(data)
|
||||
}
|
||||
|
||||
const visible = ref(true)
|
||||
const limitBuyNumSwitch = ref(false) // 如果limitBuyNum = -10086 就是false,不限购,true为限购
|
||||
const loading = ref(false)
|
||||
const wareImgs = ref([])
|
||||
const wareCommentImgs = ref([])
|
||||
const formRef = ref(null)
|
||||
const formObj = {
|
||||
id: '',
|
||||
useShopType: 'only', // only-仅本店 all全部 /custom 指定
|
||||
useShops: '', // 可用门店(指定门店时存储门店ID,逗号分隔)
|
||||
wareName: '', // 商品名称
|
||||
wareDetail: '', // 商品描述
|
||||
wareImgs: '', // 商品图片(多个用逗号分隔)
|
||||
originalPrice: '', // 原价
|
||||
groupPrice: '', // 拼团价
|
||||
groupPeopleNum: '', // 成团人数 最小为1
|
||||
groupTimeoutHour: '', // 成团期限(小时)不低于1小时,最大72小时
|
||||
limitBuyNum: '', // 限购数量(每人最多购买次数) -10086
|
||||
onlineStatus: 1, // 上架状态(0下架 1上架)
|
||||
wareCommentImgs: '', // 商品详情图片(多个用逗号分隔)
|
||||
}
|
||||
const form = ref({ ...formObj })
|
||||
|
||||
const rules = ref({
|
||||
useShops: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择门店",
|
||||
trigger: "blur",
|
||||
}
|
||||
],
|
||||
wareName: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入商品名称",
|
||||
trigger: "blur",
|
||||
}
|
||||
],
|
||||
wareImgs: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择商品图片",
|
||||
trigger: "change",
|
||||
}
|
||||
],
|
||||
originalPrice: [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
if (form.value.originalPrice <= 0 || !form.value.originalPrice) {
|
||||
callback(new Error('请输入商品原价'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: "blur",
|
||||
}
|
||||
],
|
||||
groupPrice: [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
if (form.value.groupPrice <= 0 || !form.value.groupPrice) {
|
||||
callback(new Error('请输入拼团价'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: "blur",
|
||||
}
|
||||
],
|
||||
groupPeopleNum: [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
if (form.value.groupPeopleNum < 1 || !form.value.groupPeopleNum) {
|
||||
callback(new Error('请输入成团人数'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: "blur",
|
||||
}
|
||||
],
|
||||
groupTimeoutHour: [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
if (form.value.groupTimeoutHour < 1 || !form.value.groupTimeoutHour) {
|
||||
callback(new Error('请输入成团期限'))
|
||||
} else if (form.value.groupTimeoutHour > 72) {
|
||||
callback(new Error('最大不超过72小时'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: "blur",
|
||||
}
|
||||
],
|
||||
limitBuyNum: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (limitBuyNumSwitch.value && !form.value.limitBuyNum) {
|
||||
callback(new Error('请输入每人最多购买次数'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: "blur",
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
function limitBuyNumSwitchChange(e) {
|
||||
if (e) {
|
||||
form.value.limitBuyNum = ''
|
||||
} else {
|
||||
form.value.limitBuyNum = -10086
|
||||
}
|
||||
}
|
||||
|
||||
// 多图上传成功
|
||||
function wareImgsMultiOnSuccess(response) {
|
||||
loading.value = false
|
||||
form.value.wareImgs = wareImgs.value.join(',')
|
||||
}
|
||||
|
||||
// 商品详情图片上传成功
|
||||
function wareCommentImgsMultiOnSuccess(res) {
|
||||
loading.value = false
|
||||
form.value.wareCommentImgs = wareCommentImgs.value.join(',')
|
||||
}
|
||||
|
||||
function useShopTypeChange(e) {
|
||||
form.value.useShops = ''
|
||||
}
|
||||
|
||||
// 提交保存
|
||||
const emits = defineEmits(['success'])
|
||||
function submitHandle() {
|
||||
form.value.wareImgs = wareImgs.value.join(',')
|
||||
form.value.wareCommentImgs = wareCommentImgs.value.join(',')
|
||||
formRef.value.validate(async vaild => {
|
||||
try {
|
||||
if (vaild) {
|
||||
const data = { ...form.value }
|
||||
if (form.value.useShopType == 'custom') {
|
||||
data.useShops = form.value.useShops.join(',')
|
||||
}
|
||||
loading.value = true
|
||||
if (form.value.id) {
|
||||
await updateGbWareById(data)
|
||||
} else {
|
||||
await addGbWare(data)
|
||||
}
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '保存成功',
|
||||
type: 'success'
|
||||
})
|
||||
emits('success')
|
||||
visible.value = false
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 500);
|
||||
})
|
||||
}
|
||||
|
||||
function resetHandle() {
|
||||
form.value = { ...formObj }
|
||||
limitBuyNumSwitch.value = false
|
||||
wareImgs.value = []
|
||||
wareCommentImgs.value = []
|
||||
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
function show(obj) {
|
||||
visible.value = true
|
||||
if (obj && obj.id) {
|
||||
console.log(obj);
|
||||
form.value = { ...obj }
|
||||
if (form.value.wareImgs != '') {
|
||||
wareImgs.value = form.value.wareImgs.split(',')
|
||||
}
|
||||
if (form.value.wareCommentImgs != '') {
|
||||
wareCommentImgs.value = form.value.wareCommentImgs.split(',')
|
||||
}
|
||||
if (form.value.limitBuyNum != -10086) {
|
||||
limitBuyNumSwitch.value = true
|
||||
} else {
|
||||
limitBuyNumSwitch.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
shopInfo.value = JSON.parse(localStorage.getItem('userInfo'))
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form_warap {
|
||||
height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dialog_footer {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.group_wrap {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
|
||||
.row {
|
||||
.mt14 {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
&.padding {
|
||||
padding: 14px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,420 @@
|
||||
<!-- 拼团订单 -->
|
||||
<template>
|
||||
<div>
|
||||
<div class="row">
|
||||
<el-form :model="queryForm" inline>
|
||||
<el-form-item label="订单状态">
|
||||
<el-select v-model="queryForm.status" style="width: 150px;">
|
||||
<el-option v-for="item in statusList" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="下单时间">
|
||||
<el-date-picker style="width: 300px" v-model="confirmOrderTimes" type="daterange" range-separator="至"
|
||||
start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD"
|
||||
@change="confirmOrderTimesChange"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="核销时间">
|
||||
<el-date-picker style="width: 300px" v-model="checkoutOrderTimes" type="daterange" range-separator="至"
|
||||
start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD"
|
||||
@change="checkoutOrderTimesChange"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input :maxlength="11" v-model="queryForm.phone" placeholder="请输入手机号"
|
||||
@input="e => queryForm.phone = filterNumberInput(e, 1)"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input v-model="queryForm.orderNo" placeholder="请输入订单号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input v-model="queryForm.groupOrderNo" placeholder="请输入关联团单号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" :loading="tableData.loading" @click="searchHandle">搜索</el-button>
|
||||
<el-button icon="Refresh" :loading="tableData.loading" @click="refreshHandle">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="info_wrap">
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/fenxiao/3.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div>总订单数</div>
|
||||
<div>{{ multiplyAndFormat(infoObj.successAmount || 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/fenxiao/4.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div>已支付金额(元)</div>
|
||||
<div>{{ multiplyAndFormat(infoObj.pendingAmount || 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/fenxiao/5.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div>已退款金额(元)</div>
|
||||
<div>{{ multiplyAndFormat(infoObj.balanceAmount || 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt14">
|
||||
<el-table :data="tableData.list" stripe border v-loading="tableData.loading">
|
||||
<el-table-column label="订单号" prop="orderNo" width="180"></el-table-column>
|
||||
<el-table-column label="商品" prop="wareJson" width="200">
|
||||
<template v-slot="scope">
|
||||
<div class="center">
|
||||
<el-image :src="scope.row.wareJson.wareImgs.split(',')[0]"
|
||||
style="width: 40px;height: 40px;flex-shrink: 0;"></el-image>
|
||||
<el-text>{{ scope.row.wareJson.wareName }}</el-text>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="购买用户" prop="userName" width="200">
|
||||
<template v-slot="scope">
|
||||
<div class="center">
|
||||
{{ scope.row.userName }} / {{ scope.row.userPhone }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="支付金额(元)" prop="payAmount" width="130"></el-table-column>
|
||||
<el-table-column label="支付时间" prop="payTime" width="180"></el-table-column>
|
||||
<el-table-column label="下单门店" prop="shopName" width="130"></el-table-column>
|
||||
<el-table-column label="状态" prop="status" width="100">
|
||||
<template v-slot="scope">
|
||||
<el-tag disable-transitions :type="statusFilter(scope.row).type">
|
||||
{{ scope.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="团单号" prop="groupOrderNo" width="180"></el-table-column>
|
||||
<el-table-column label="成团时间" prop="groupEndTime" width="180"></el-table-column>
|
||||
<el-table-column label="核销码" prop="verifyCode" width="180"></el-table-column>
|
||||
<el-table-column label="核销时间" prop="verifyTime" width="180"></el-table-column>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template v-slot="scope">
|
||||
<template v-if="includesString(scope.row.status, '退款中')">
|
||||
<el-button link type="danger" @click="refundPopupHandle(scope.row)">审核</el-button>
|
||||
</template>
|
||||
<template v-if="includesString(scope.row.status, '待核销') || includesString(scope.row.status, '待成团')">
|
||||
<el-popconfirm title="确认要退款吗?" @confirm="refundHandle(scope.row)">
|
||||
<template #reference>
|
||||
<el-button link type="danger">退款</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
<template v-if="includesString(scope.row.status, '待核销')">
|
||||
<el-popconfirm title="确认要核销吗?" @confirm="checkoutHandle(scope.row)">
|
||||
<template #reference>
|
||||
<el-button link type="primary">核销</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="row mt14">
|
||||
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||
:page-sizes="[10, 20, 50, 100, 500]" background layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="tableData.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import dayjs from 'dayjs'
|
||||
import { ref, reactive } from 'vue'
|
||||
import { filterNumberInput, multiplyAndFormat, includesString } from '@/utils'
|
||||
import { gbOrderPage, orderAgreeRefund, orderRejectRefund, orderCheckout } from '@/api/market/ware'
|
||||
|
||||
const statusList = ref([
|
||||
{
|
||||
label: '待支付',
|
||||
value: '待支付',
|
||||
type: 'info'
|
||||
},
|
||||
{
|
||||
label: '待核销',
|
||||
value: '待核销',
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
label: '待成团',
|
||||
value: '待成团',
|
||||
type: 'warning'
|
||||
},
|
||||
{
|
||||
label: '已核销',
|
||||
value: '已核销',
|
||||
type: 'success'
|
||||
},
|
||||
{
|
||||
label: '退款中',
|
||||
value: '退款中',
|
||||
type: 'danger'
|
||||
},
|
||||
{
|
||||
label: '已退款',
|
||||
value: '已退款',
|
||||
type: 'info'
|
||||
}
|
||||
])
|
||||
|
||||
// 筛选tag type
|
||||
function statusFilter(row) {
|
||||
let obj = statusList.value.find(item => includesString(row.status, item.value))
|
||||
if (obj) {
|
||||
return obj
|
||||
} else {
|
||||
return {
|
||||
label: row.status,
|
||||
value: row.status,
|
||||
type: 'info'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const confirmOrderTimes = ref([])
|
||||
const checkoutOrderTimes = ref([])
|
||||
const queryForm = reactive({
|
||||
status: '',
|
||||
orderStartTime: '',
|
||||
orderEndTime: '',
|
||||
verifyStartTime: '',
|
||||
verifyEndTime: '',
|
||||
phone: '',
|
||||
orderNo: '',
|
||||
groupOrderNo: ''
|
||||
})
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableData.page = 1
|
||||
getTableData()
|
||||
}
|
||||
|
||||
// 重置搜索
|
||||
function refreshHandle() {
|
||||
confirmOrderTimes.value = []
|
||||
checkoutOrderTimes.value = []
|
||||
|
||||
queryForm.status = ''
|
||||
queryForm.orderStartTime = ''
|
||||
queryForm.orderEndTime = ''
|
||||
queryForm.verifyStartTime = ''
|
||||
queryForm.verifyEndTime = ''
|
||||
queryForm.phone = ''
|
||||
queryForm.orderNo = ''
|
||||
queryForm.groupOrderNo = ''
|
||||
searchHandle()
|
||||
}
|
||||
|
||||
// 下单时间范围
|
||||
function confirmOrderTimesChange(value) {
|
||||
if (value && value.length === 2) {
|
||||
queryForm.orderStartTime = dayjs(value[0]).format('YYYY-MM-DD 00:00:00');
|
||||
queryForm.orderEndTime = dayjs(value[1]).format('YYYY-MM-DD 23:59:59');
|
||||
} else {
|
||||
queryForm.orderStartTime = '';
|
||||
queryForm.orderEndTime = '';
|
||||
}
|
||||
}
|
||||
|
||||
// 核销时间范围
|
||||
function checkoutOrderTimesChange(value) {
|
||||
if (value && value.length === 2) {
|
||||
queryForm.verifyStartTime = dayjs(value[0]).format('YYYY-MM-DD 00:00:00');
|
||||
queryForm.verifyEndTime = dayjs(value[1]).format('YYYY-MM-DD 23:59:59');
|
||||
} else {
|
||||
queryForm.verifyStartTime = '';
|
||||
queryForm.verifyEndTime = '';
|
||||
}
|
||||
}
|
||||
|
||||
// 订单统计数据
|
||||
const infoObj = reactive({
|
||||
successAmount: 0,
|
||||
pendingAmount: 0,
|
||||
balanceAmount: 0
|
||||
})
|
||||
|
||||
const tableData = reactive({
|
||||
page: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
list: [],
|
||||
loading: false
|
||||
})
|
||||
|
||||
// 分页大小发生变化
|
||||
function handleSizeChange(e) {
|
||||
tableData.size = e;
|
||||
getTableData();
|
||||
}
|
||||
|
||||
// 分页发生变化
|
||||
function handleCurrentChange(e) {
|
||||
tableData.page = e;
|
||||
getTableData();
|
||||
}
|
||||
|
||||
// 直接退款操作
|
||||
async function refundHandle(row) {
|
||||
try {
|
||||
tableData.loading = true
|
||||
await orderAgreeRefund({
|
||||
recordId: row.id,
|
||||
orderNo: row.orderNo,
|
||||
reason: ''
|
||||
})
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
getTableData()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
tableData.loading = false
|
||||
}
|
||||
|
||||
// 审核退款操作
|
||||
function refundPopupHandle(row) {
|
||||
let promptValue = ''
|
||||
ElMessageBox.prompt('请通过审核或驳回?', '退款审核', {
|
||||
confirmButtonText: '通过',
|
||||
cancelButtonText: '驳回',
|
||||
inputPlaceholder: '驳回原因',
|
||||
inputValidator: (value) => {
|
||||
promptValue = value; // 核心:缓存最新输入值
|
||||
return true; // 不做校验,仅缓存
|
||||
},
|
||||
}).then(async ({ value }) => {
|
||||
try {
|
||||
console.log('通过', value);
|
||||
tableData.loading = true
|
||||
await orderAgreeRefund({
|
||||
recordId: row.id,
|
||||
orderNo: row.orderNo,
|
||||
reason: value
|
||||
})
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
getTableData()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}).catch(async () => {
|
||||
console.log('驳回', promptValue);
|
||||
tableData.loading = true
|
||||
await orderRejectRefund({
|
||||
recordId: row.id,
|
||||
orderNo: row.orderNo,
|
||||
reason: value
|
||||
})
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
getTableData()
|
||||
})
|
||||
}
|
||||
|
||||
// 核销操作
|
||||
async function checkoutHandle(row) {
|
||||
try {
|
||||
tableData.loading = true
|
||||
await orderCheckout(row.verifyCode)
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '已核销',
|
||||
type: 'success'
|
||||
})
|
||||
getTableData()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取订单列表
|
||||
async function getTableData() {
|
||||
try {
|
||||
tableData.loading = true
|
||||
const res = await gbOrderPage({
|
||||
...queryForm,
|
||||
page: tableData.page,
|
||||
size: tableData.size
|
||||
})
|
||||
res.records.forEach(item => {
|
||||
item.wareJson = JSON.parse(item.wareJson)
|
||||
})
|
||||
tableData.list = res.records
|
||||
tableData.total = res.totalRow
|
||||
|
||||
console.log(tableData.list);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
setTimeout(() => {
|
||||
tableData.loading = false
|
||||
}, 300);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getTableData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.row {
|
||||
&.mt14 {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.info_wrap {
|
||||
display: flex;
|
||||
gap: 48px;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid #D9D9D9;
|
||||
border-radius: 8px;
|
||||
padding: 0 10px;
|
||||
|
||||
.icon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,244 @@
|
||||
<!-- 拼团活动 -->
|
||||
<template>
|
||||
<div>
|
||||
<div class="row">
|
||||
<el-form :model="queryForm" inline @submit.prevent>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Plus" @click="addGroupGoodsRef.show()">添加</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="上架状态">
|
||||
<el-select v-model="queryForm.onlineStatus" style="width: 100px;">
|
||||
<el-option :label="item.label" :value="item.value" v-for="item in statusList" :key="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-date-picker style="width: 300px" v-model="times" type="daterange" range-separator="至"
|
||||
start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD"
|
||||
@change="selectTimeChange"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称">
|
||||
<el-input v-model="queryForm.wareName" placeholder="请输入商品名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" :loading="tableData.loading" @click="searchHandle">搜索</el-button>
|
||||
<el-button icon="Refresh" :loading="tableData.loading" @click="refreshHandle">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="row">
|
||||
<el-table :data="tableData.list" stripe border v-loading="tableData.loading">
|
||||
<el-table-column label="商品图片">
|
||||
<template v-slot="scope">
|
||||
<div class="wareImgs">
|
||||
<el-image :src="scope.row.wareImgs.split(',')[0]" style="width: 100%;height: 100%;" fit="cover"
|
||||
:preview-src-list="scope.row.wareImgs.split(',')" :initial-index="0" preview-teleported></el-image>
|
||||
<div class="num" v-if="scope.row.wareImgs.split(',').length > 1">
|
||||
+{{ scope.row.wareImgs.split(',').length }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" prop="wareName"></el-table-column>
|
||||
<el-table-column label="原价(元)" prop="originalPrice"></el-table-column>
|
||||
<el-table-column label="拼团价(元)" prop="groupPrice"></el-table-column>
|
||||
<el-table-column label="成团期限(小时)" prop="groupTimeoutHour"></el-table-column>
|
||||
<el-table-column label="成团人数" prop="groupPeopleNum"></el-table-column>
|
||||
<el-table-column label="上架状态" prop="onlineStatus" width="100">
|
||||
<template v-slot="scope">
|
||||
<el-switch v-model="scope.row.onlineStatus" :active-value="1" :inactive-value="0"
|
||||
@change="editOnlineStatusAjax($event, scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" prop="createTime" width="200"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<template v-slot="scope">
|
||||
<template v-if="scope.row.shopId === shopInfo.id">
|
||||
<template v-if="scope.row.onlineStatus">
|
||||
<el-button link type="primary" disabled>(下架后编辑/删除)</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button link type="primary" @click="addGroupGoodsRef.show(scope.row)">编辑</el-button>
|
||||
<el-popconfirm title="确认要删除吗?" @confirm="delHandle(scope.row)">
|
||||
<template #reference>
|
||||
<el-button type="danger" link>删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button link type="primary" disabled>无权操作</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="row mt14">
|
||||
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||
:page-sizes="[10, 20, 50, 100, 500]" background layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="tableData.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||
</div>
|
||||
<addGroupGoods ref="addGroupGoodsRef" @success="searchHandle" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import dayjs from 'dayjs';
|
||||
import { ref, reactive } from 'vue'
|
||||
import addGroupGoods from './addGroupGoods.vue';
|
||||
import { getGbWarePage, editOnlineStatus, deleteGbWare } from '@/api/market/ware'
|
||||
|
||||
const shopInfo = ref(null)
|
||||
|
||||
const addGroupGoodsRef = ref(null)
|
||||
|
||||
const statusList = ref([
|
||||
{
|
||||
label: '上架',
|
||||
value: 1,
|
||||
type: 'success'
|
||||
},
|
||||
{
|
||||
label: '下架',
|
||||
value: 0,
|
||||
type: 'info'
|
||||
},
|
||||
])
|
||||
|
||||
const times = ref([])
|
||||
|
||||
const selectTimeChange = (value) => {
|
||||
if (value && value.length === 2) {
|
||||
queryForm.startTime = dayjs(value[0]).format('YYYY-MM-DD 00:00:00');
|
||||
queryForm.endTime = dayjs(value[1]).format('YYYY-MM-DD 23:59:59');
|
||||
} else {
|
||||
queryForm.startTime = '';
|
||||
queryForm.endTime = '';
|
||||
}
|
||||
};
|
||||
|
||||
const queryForm = reactive({
|
||||
onlineStatus: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
wareName: ''
|
||||
})
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableData.page = 1
|
||||
getGbWarePageAjax()
|
||||
}
|
||||
|
||||
// 重置搜索
|
||||
function refreshHandle() {
|
||||
times.value = []
|
||||
queryForm.onlineStatus = ''
|
||||
queryForm.startTime = ''
|
||||
queryForm.endTime = ''
|
||||
queryForm.wareName = ''
|
||||
searchHandle()
|
||||
}
|
||||
|
||||
const tableData = reactive({
|
||||
page: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
list: [],
|
||||
loading: false
|
||||
})
|
||||
|
||||
// 分页大小发生变化
|
||||
function handleSizeChange(e) {
|
||||
tableData.size = e;
|
||||
getGbWarePageAjax();
|
||||
}
|
||||
|
||||
// 分页发生变化
|
||||
function handleCurrentChange(e) {
|
||||
tableData.page = e;
|
||||
getGbWarePageAjax();
|
||||
}
|
||||
|
||||
// 拼团商品-列表
|
||||
async function getGbWarePageAjax() {
|
||||
try {
|
||||
tableData.loading = true
|
||||
const res = await getGbWarePage({
|
||||
page: tableData.page,
|
||||
size: tableData.size,
|
||||
...queryForm
|
||||
})
|
||||
tableData.list = res.records
|
||||
tableData.total = res.totalRow
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
setTimeout(() => {
|
||||
tableData.loading = false
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// 修改状态
|
||||
async function editOnlineStatusAjax(e, row) {
|
||||
try {
|
||||
await editOnlineStatus(row)
|
||||
getGbWarePageAjax()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除
|
||||
async function delHandle(row) {
|
||||
try {
|
||||
await deleteGbWare(row.id)
|
||||
getGbWarePageAjax()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
shopInfo.value = JSON.parse(localStorage.getItem('userInfo'))
|
||||
getGbWarePageAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.row {
|
||||
&.mt14 {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.wareImgs {
|
||||
position: relative;
|
||||
--size: 80px;
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
border: 1px solid #ececec;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.num {
|
||||
padding: 0 4px;
|
||||
height: 16px;
|
||||
font-size: 10px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
border-radius: 0 0 0 4px;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
backdrop-filter: blur(10px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<el-dialog title="选择商品" width="800px" v-model="visible">
|
||||
<div class="scroll">
|
||||
<div class="list">
|
||||
<div class="item" v-for="item in list" :key="item.id" @click="selectItem(item)">
|
||||
<div class="img">
|
||||
<el-image :src="item.coverImg" style="width: 100%;height: 100%;border-radius: 4px;"></el-image>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="name">{{ item.name }}</div>
|
||||
<div class="price">{{ multiplyAndFormat(returnPrice(item.skuList) || 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getProductList } from '@/api/coupon/index'
|
||||
import { multiplyAndFormat } from '@/utils'
|
||||
|
||||
const visible = ref(false)
|
||||
|
||||
const list = ref([])
|
||||
|
||||
// 返回规格最高价
|
||||
function returnPrice(skuList) {
|
||||
return Math.max(...skuList.map(item => item.salePrice));
|
||||
}
|
||||
|
||||
// 选择商品
|
||||
const emits = defineEmits(['success'])
|
||||
function selectItem(item) {
|
||||
emits('success', {
|
||||
coverImg: item.coverImg,
|
||||
name: item.name,
|
||||
price: returnPrice(item.skuList)
|
||||
})
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
// 获取商品-列表
|
||||
async function getProductListAjax() {
|
||||
try {
|
||||
list.value = await getProductList()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
function show() {
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getProductListAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.scroll {
|
||||
height: 60vh;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-column-gap: 14px;
|
||||
grid-row-gap: 14px;
|
||||
|
||||
.item {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #ececec;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
transition: all .3s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
border-color: var(--el-color-primary);
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
}
|
||||
|
||||
.img {
|
||||
--size: 50px;
|
||||
height: var(--size);
|
||||
width: var(--size);
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 10px;
|
||||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
color: 333;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 16px;
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
82
src/views/marketing_center/package_popularize/index.vue
Normal file
82
src/views/marketing_center/package_popularize/index.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<!-- 套餐推广 -->
|
||||
<template>
|
||||
<div class="gyq_container">
|
||||
<div class="gyq_content">
|
||||
<HeaderCard name="套餐推广" intro="下单通过用户邀请好友减免金额的方式裂变宣传套餐加购" icon="tctg" showSwitch v-model:isOpen="form.isEnable">
|
||||
</HeaderCard>
|
||||
<div class="row mt14">
|
||||
<tabHeader v-model="tabActiveIndex" :list="tabList" />
|
||||
</div>
|
||||
<div class="row mt14">
|
||||
<groupPage name="groupPage" key="groupPage" v-if="tabActiveIndex == 0" />
|
||||
<groupOrder name="groupOrder" key="groupOrder" v-if="tabActiveIndex == 1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { shopInfoGet } from '@/api/coupon/index'
|
||||
import groupPage from './components/groupPage.vue'
|
||||
import groupOrder from './components/groupOrder.vue'
|
||||
import { upShopConfig } from '@/api/market/ware'
|
||||
|
||||
const tabActiveIndex = ref(0)
|
||||
const tabList = ref([
|
||||
{
|
||||
label: '套餐列表',
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
label: '订单列表',
|
||||
value: 1
|
||||
}
|
||||
])
|
||||
|
||||
const form = ref({
|
||||
isEnable: 0
|
||||
})
|
||||
|
||||
watch(() => form.value.isEnable, () => {
|
||||
upShopConfigAjax()
|
||||
})
|
||||
|
||||
// 拼团商品-活动开关
|
||||
async function upShopConfigAjax() {
|
||||
try {
|
||||
await upShopConfig({
|
||||
onlineStatus: form.value.isEnable
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const { isGroupBuy } = await shopInfoGet()
|
||||
form.value.isEnable = isGroupBuy
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gyq_container {
|
||||
padding: 14px;
|
||||
|
||||
.gyq_content {
|
||||
padding: 14px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
&.mt14 {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
margin-top: 14px;
|
||||
}
|
||||
</style>
|
||||
@@ -195,9 +195,10 @@
|
||||
<div class="form_item">
|
||||
<div class="upload_wrap" style="display: flex;flex-direction: column;gap: 28px;"
|
||||
v-if="selectItem.autoKey == 'index_bg' || selectItem.autoKey == 'shopinfo_bg'">
|
||||
<MultiImageUpload v-model="imgList" @upDataEvent="MultiOnSuccess" />
|
||||
<MultiImageUpload v-model="imgList" @uploadStart="uploading = true" @uploadAllSuccess="MultiOnSuccess" />
|
||||
<div>
|
||||
<el-button type="primary" size="large" @click="doSubmit">确认修改</el-button>
|
||||
<el-button type="primary" size="large" @click="doSubmit" :loading="uploading"
|
||||
loading-text="图片上传中...">确认修改</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
@@ -237,7 +238,8 @@ export default {
|
||||
selectItem: {},
|
||||
imageUrl: "",
|
||||
imgList: [],
|
||||
shopName: ''
|
||||
shopName: '',
|
||||
uploading: false
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
@@ -246,6 +248,7 @@ export default {
|
||||
methods: {
|
||||
// 刷新列表数据
|
||||
async doSubmit() {
|
||||
this.selectItem.value = JSON.stringify(this.imgList)
|
||||
await shopExtendApi.edit({
|
||||
...this.selectItem,
|
||||
autokey: this.selectItem.autoKey,
|
||||
@@ -263,14 +266,12 @@ export default {
|
||||
// 多图上传成功
|
||||
async MultiOnSuccess(response) {
|
||||
console.log(response);
|
||||
console.log(this.imgList);
|
||||
|
||||
if (!response && this.imgList.length > 0) {
|
||||
console.log(this.imgList);
|
||||
await nextTick()
|
||||
this.selectItem.value = JSON.stringify(this.imgList)
|
||||
console.log('onSuccess.selectItem.value', this.selectItem.value);
|
||||
}
|
||||
// console.log(this.imgList);
|
||||
// console.log(this.imgList);
|
||||
// await nextTick()
|
||||
this.uploading = false
|
||||
this.selectItem.value = JSON.stringify(this.imgList)
|
||||
console.log('onSuccess.selectItem.value', this.selectItem.value);
|
||||
},
|
||||
/**
|
||||
* 判断字符串是否为合法的 JSON 数组
|
||||
|
||||
Reference in New Issue
Block a user