更新优化
This commit is contained in:
@@ -407,6 +407,49 @@ export function smsMoneyGetFee() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 微信公众号 商家每日可创建次数
|
||||||
|
export function acDayCount() {
|
||||||
|
return request({
|
||||||
|
url: `${System_BaseUrl + "/admin/sysParams/code/ac_day_count"}`,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 公众号推送:列表
|
||||||
|
export function acPushEventGet(params) {
|
||||||
|
return request({
|
||||||
|
url: `${Market_BaseUrl + "/admin/acPushEvent"}`,
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 公众号推送:删除任务
|
||||||
|
export function acPushEventDel(id) {
|
||||||
|
return request({
|
||||||
|
url: `${Market_BaseUrl}/admin/acPushEvent/${id}`,
|
||||||
|
method: 'DELETE'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 公众号推送:新增/更新
|
||||||
|
export function acPushEventPost(data, method = 'post') {
|
||||||
|
return request({
|
||||||
|
url: `${Market_BaseUrl}/admin/acPushEvent`,
|
||||||
|
method: method,
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 公众号任务获取用户
|
||||||
|
export function getAcPushEventUser(data) {
|
||||||
|
return request({
|
||||||
|
url: `${Account_BaseUrl + "/admin/shopUser/getAcPushEventUser"}`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
<el-radio-button :value="1">员工</el-radio-button>
|
<el-radio-button :value="1">员工</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="快捷输入账号" label-width="100px" v-if="env == 'development'">
|
||||||
|
<el-button :type="item.type" v-for="item in accountList" @click="accountHandle(item)">
|
||||||
|
{{ item.username }}
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<el-input v-model="state.loginForm.username" type="text" auto-complete="off" placeholder="商户号"></el-input>
|
<el-input v-model="state.loginForm.username" type="text" auto-complete="off" placeholder="商户号"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -28,7 +33,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item style="width: 100%">
|
<el-form-item style="width: 100%">
|
||||||
<el-button :loading="state.loading" size="default" type="primary" style="width: 100%"
|
<el-button :loading="state.loading" size="default" type="primary" style="width: 100%"
|
||||||
@click.prevent="handleLogin">
|
@click.prevent="handleLogin">
|
||||||
@@ -38,10 +42,10 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
<div id="el-login-footer">
|
<!-- <div id="el-login-footer">
|
||||||
<span>⋅</span>
|
<span>⋅</span>
|
||||||
<a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank"></a>
|
<a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank"></a>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -57,6 +61,23 @@ import { $douyin_checkIn } from "@/api/coup/index";
|
|||||||
import { getToken, getDouyinToken, setDouyinToken } from "@/utils/auth";
|
import { getToken, getDouyinToken, setDouyinToken } from "@/utils/auth";
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
const env = process.env.NODE_ENV
|
||||||
|
|
||||||
|
const accountList = reactive([
|
||||||
|
{ username: "admin", type: 'primary' },
|
||||||
|
{ username: "19191703856", type: 'warning' },
|
||||||
|
// { username: "19191703856", type: 'danger' },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 快捷模拟登录
|
||||||
|
function accountHandle(item) {
|
||||||
|
state.loginForm.username = item.username;
|
||||||
|
const d = new Date();
|
||||||
|
state.loginForm.password = `czg${d.getHours().toString().padStart(2, '0')}${d.getMinutes().toString().padStart(2, '0')}`;
|
||||||
|
|
||||||
|
handleLogin()
|
||||||
|
}
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
Background: Background,
|
Background: Background,
|
||||||
codeUrl: "",
|
codeUrl: "",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="返现类型">
|
<el-form-item label="返现类型">
|
||||||
<el-radio-group v-model="form.cashbackType" @change="callbackList = []">
|
<el-radio-group v-model="form.cashbackType">
|
||||||
<el-radio label="按比例返现" value="percentage"></el-radio>
|
<el-radio label="按比例返现" value="percentage"></el-radio>
|
||||||
<el-radio label="固定金额" value="fix"></el-radio>
|
<el-radio label="固定金额" value="fix"></el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
@@ -124,19 +124,29 @@ const rules = ref({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let flag = true;
|
let flag = true;
|
||||||
|
let errStr = ''
|
||||||
form.value.cashbackStepList.map(item => {
|
form.value.cashbackStepList.map(item => {
|
||||||
if (!item.amount || !item.cashbackAmount || item.cashbackAmount > item.amount) {
|
if (form.value.cashbackType == 'percentage') {
|
||||||
flag = false
|
if (item.cashbackAmount > 100) {
|
||||||
|
flag = false
|
||||||
|
errStr = '输入有误,请检查返现比例是不是大于100'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (form.value.cashbackType == 'fix') {
|
||||||
|
if (!item.amount || !item.cashbackAmount || item.cashbackAmount > item.amount) {
|
||||||
|
flag = false
|
||||||
|
errStr = '输入有误,请检查返现金额是不是大于返现门槛'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!flag) {
|
if (!flag) {
|
||||||
callback(new Error('输入有误,请检查返现金额是不是大于返现门槛'))
|
callback(new Error(errStr))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
trigger: 'change'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-form :model="queryForm" inline>
|
<el-form :model="queryForm" inline>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<selectBranchs :multiple="false" v-model="queryForm.shopId" />
|
<selectBranchs all :multiple="false" v-model="queryForm.shopId" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-date-picker style="width: 300px" v-model="times" type="daterange" range-separator="至"
|
<el-date-picker style="width: 300px" v-model="times" type="daterange" range-separator="至"
|
||||||
@@ -58,8 +58,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row" style="margin-top: 14px;">
|
<div class="row" style="margin-top: 14px;">
|
||||||
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||||
:page-sizes="[100, 200, 300, 400]" background layout="total, sizes, prev, pager, next, jumper"
|
:page-sizes="[10, 30, 50, 100]" background layout="total, sizes, prev, pager, next, jumper"
|
||||||
:page-count="tableData.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
:total="tableData.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -141,7 +141,9 @@ async function consumeCashbackRecordAjax(params) {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
tableData.loading = false
|
setTimeout(() => {
|
||||||
|
tableData.loading = false
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ import { ref, onMounted } from 'vue'
|
|||||||
import { getBranchPage, getBranchList } from "@/api/coupon/index.js";
|
import { getBranchPage, getBranchList } from "@/api/coupon/index.js";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
// 是否显示所有店铺(包括主店)
|
||||||
|
all: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 单选多选
|
||||||
multiple: {
|
multiple: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
@@ -26,15 +32,15 @@ const branchList = ref([]);
|
|||||||
async function getBranchPageAjax() {
|
async function getBranchPageAjax() {
|
||||||
try {
|
try {
|
||||||
let res = null
|
let res = null
|
||||||
if (props.multiple) {
|
if (props.all) {
|
||||||
res = await getBranchPage();
|
|
||||||
branchList.value = res.records;
|
|
||||||
} else {
|
|
||||||
res = await getBranchList()
|
res = await getBranchList()
|
||||||
res.map(item => {
|
res.map(item => {
|
||||||
item.id = item.shopId
|
item.id = item.shopId
|
||||||
})
|
})
|
||||||
branchList.value = res;
|
branchList.value = res;
|
||||||
|
} else {
|
||||||
|
res = await getBranchPage();
|
||||||
|
branchList.value = res.records;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
<el-checkbox value="周四" label="周四" />
|
<el-checkbox value="周四" label="周四" />
|
||||||
<el-checkbox value="周五" label="周五" />
|
<el-checkbox value="周五" label="周五" />
|
||||||
<el-checkbox value="周六" label="周六" />
|
<el-checkbox value="周六" label="周六" />
|
||||||
<el-checkbox value="周七" label="周日" />
|
<el-checkbox value="周日" label="周日" />
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="指定时间段">
|
<el-form-item label="指定时间段">
|
||||||
@@ -163,7 +163,7 @@ const form = ref({
|
|||||||
shopId: '',
|
shopId: '',
|
||||||
validStartTime: '',
|
validStartTime: '',
|
||||||
validEndTime: '',
|
validEndTime: '',
|
||||||
useDays: ['周一', '周二', '周三', '周四', '周五', '周六', '周七'],
|
useDays: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
|
||||||
useTimeType: 'all',
|
useTimeType: 'all',
|
||||||
useStartTime: '',
|
useStartTime: '',
|
||||||
useEndTime: '',
|
useEndTime: '',
|
||||||
@@ -355,6 +355,8 @@ function show(obj = null) {
|
|||||||
|
|
||||||
console.log(useTimeScope.value);
|
console.log(useTimeScope.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validityScope.value = [form.value.validStartTime, form.value.validEndTime]
|
||||||
} else {
|
} else {
|
||||||
reset();
|
reset();
|
||||||
titleOptions.title = `添加满减活动`;
|
titleOptions.title = `添加满减活动`;
|
||||||
|
|||||||
@@ -23,10 +23,7 @@
|
|||||||
<el-table-column label="ID" prop="id" width="80"></el-table-column>
|
<el-table-column label="ID" prop="id" width="80"></el-table-column>
|
||||||
<el-table-column label="活动日期" prop="orderNo">
|
<el-table-column label="活动日期" prop="orderNo">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div v-if="scope.row.useTimeType == 'all'">全时段</div>
|
{{ scope.row.validStartTime }} - {{ scope.row.validEndTime }}
|
||||||
<div v-else>
|
|
||||||
{{ scope.row.validStartTime }} - {{ scope.row.validEndTime }}
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="生效周期" prop="useDays"></el-table-column>
|
<el-table-column label="生效周期" prop="useDays"></el-table-column>
|
||||||
@@ -91,8 +88,8 @@ const form = ref({
|
|||||||
})
|
})
|
||||||
|
|
||||||
watch(() => form.value.isEnableDiscount, (newVal, oldVal) => {
|
watch(() => form.value.isEnableDiscount, (newVal, oldVal) => {
|
||||||
console.log('值改变了', form.value);
|
if (form.value.id && !tableData.loading) {
|
||||||
if (form.value.id) {
|
console.log('值改变了', form.value);
|
||||||
shopInfoPutAjax()
|
shopInfoPutAjax()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -113,7 +110,7 @@ const queryForm = ref({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const tableData = reactive({
|
const tableData = reactive({
|
||||||
loading: false,
|
loading: true,
|
||||||
page: 1,
|
page: 1,
|
||||||
size: 10,
|
size: 10,
|
||||||
list: [],
|
list: [],
|
||||||
@@ -186,7 +183,9 @@ async function getTableData() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
tableData.loading = false
|
setTimeout(() => {
|
||||||
|
tableData.loading = false
|
||||||
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取店铺信息
|
// 获取店铺信息
|
||||||
|
|||||||
@@ -31,15 +31,15 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="选择门店" prop="shopIdList" v-if="form.useShopType == 'part'">
|
<el-form-item label="选择门店" prop="shopIdList" v-if="form.useShopType == 'part'">
|
||||||
<selectBranchs v-model="form.shopIdList" />
|
<selectBranchs all v-model="form.shopIdList" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 可使用类型 -->
|
<!-- 可使用类型 -->
|
||||||
<el-form-item label="可使用类型" prop="useType">
|
<el-form-item label="可使用类型" prop="useType">
|
||||||
<el-checkbox-group v-model="form.useType">
|
<el-checkbox-group v-model="form.useType">
|
||||||
<el-checkbox label="店内" value="dine-in"></el-checkbox>
|
<el-checkbox label="堂食" value="dine-in"></el-checkbox>
|
||||||
<el-checkbox label="自取" value="take-out"></el-checkbox>
|
<el-checkbox label="外带" value="take-out"></el-checkbox>
|
||||||
<el-checkbox label="快递" value="post"></el-checkbox>
|
<el-checkbox label="外卖" value="take-away"></el-checkbox>
|
||||||
<el-checkbox label="外卖" value="takeaway"></el-checkbox>
|
<el-checkbox label="配送" value="post"></el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="可与优惠券同享">
|
<el-form-item label="可与优惠券同享">
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ const menus = ref([
|
|||||||
{
|
{
|
||||||
name: "微信公众号",
|
name: "微信公众号",
|
||||||
icon: "wxgzh",
|
icon: "wxgzh",
|
||||||
pathName: "",
|
pathName: "official_accounts",
|
||||||
intro:
|
intro:
|
||||||
"授权微信公众号后,让你能够在后台查看和维护公众号的粉丝;同时你的店铺也有出现关注公众号的入口。",
|
"授权微信公众号后,让你能够在后台查看和维护公众号的粉丝;同时你的店铺也有出现关注公众号的入口。",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="dialogVisible" :title="form.id ? '编辑推送任务' : '添加推送任务'" width="1200px" top="4vh">
|
<el-dialog v-model="dialogVisible" :title="form.id ? '编辑推送任务' : '添加推送任务'" width="1200px" top="4vh"
|
||||||
|
@closed="formRef.resetFields()">
|
||||||
<div class="scroll" ref="scrollRef">
|
<div class="scroll" ref="scrollRef">
|
||||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="160px">
|
<el-form ref="formRef" :model="form" :rules="formRules" label-width="160px">
|
||||||
<div class="title">短信内容</div>
|
<div class="title">短信内容</div>
|
||||||
@@ -11,12 +12,16 @@
|
|||||||
<el-option :label="item.title" :value="item.id" v-for="item in tempList" :key="item.id"></el-option>
|
<el-option :label="item.title" :value="item.id" v-for="item in tempList" :key="item.id"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-for="(item, index) in selectTempList" :key="index" :label="item.key"
|
<el-form-item v-for="(item, index) in form.selectTempList" :key="index" :label="item.key"
|
||||||
style="margin-top: 14px;" prop="selectTempList">
|
style="margin-top: 14px;" :prop="`selectTempList.${index}.value`" :rules="[{
|
||||||
|
required: !item.disabled,
|
||||||
|
message: `${item.key}不能为空`,
|
||||||
|
trigger: 'blur'
|
||||||
|
}]" v-show="!item.disabled">
|
||||||
<el-input v-if="item.type === 'input'" v-model="item.value" :placeholder="`请输入${item.key}`"
|
<el-input v-if="item.type === 'input'" v-model="item.value" :placeholder="`请输入${item.key}`"
|
||||||
style="width:300px"></el-input>
|
style="width:300px"></el-input>
|
||||||
<el-time-picker v-else-if="item.type === 'time'" v-model="item.value" placeholder="请选择时间" format="HH:mm"
|
<el-date-picker v-else-if="item.type === 'time'" v-model="item.value" type="datetime"
|
||||||
value-format="HH:mm" :picker-options="{ selectableRange: '00:00:00-23:59:59' }"
|
placeholder="请选择时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
style="width: 300px;" />
|
style="width: 300px;" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="赠送优惠券" style="margin-top: 14px;" prop="coupon">
|
<el-form-item label="赠送优惠券" style="margin-top: 14px;" prop="coupon">
|
||||||
@@ -53,51 +58,57 @@
|
|||||||
<div class="shop_user_wrap">
|
<div class="shop_user_wrap">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<el-form-item label="发送对象">
|
<el-form-item label="发送对象">
|
||||||
<el-radio-group v-model="form.userType" @change="getPushEventUserAjax">
|
<el-radio-group v-model="form.userType">
|
||||||
<el-radio label="全部绑定手机号用户" :value="1"></el-radio>
|
<el-radio label="全部绑定手机号用户" :value="1"></el-radio>
|
||||||
<el-radio label="自定义用户" :value="2"></el-radio>
|
<el-radio label="自定义用户" :value="2"></el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div v-if="form.userType == 2">
|
<div v-if="form.userType == 2">
|
||||||
<el-form-item label="性别">
|
<el-form-item label="性别">
|
||||||
<el-checkbox v-model="form.smsPushEventUser.sexMan" label="男" :true-value="1" :false-value="0"
|
<el-checkbox v-model="form.smsPushEventUser.sexMan" label="男" :true-value="1"
|
||||||
@change="getPushEventUserAjax"></el-checkbox>
|
:false-value="0"></el-checkbox>
|
||||||
<el-checkbox v-model="form.smsPushEventUser.sexWoman" label="女" :true-value="1" :false-value="0"
|
<el-checkbox v-model="form.smsPushEventUser.sexWoman" label="女" :true-value="1"
|
||||||
@change="getPushEventUserAjax"></el-checkbox>
|
:false-value="0"></el-checkbox>
|
||||||
<el-checkbox v-model="form.smsPushEventUser.sexUnknown" label="未知" :true-value="1" :false-value="0"
|
<el-checkbox v-model="form.smsPushEventUser.sexUnknown" label="未知" :true-value="1"
|
||||||
@change="getPushEventUserAjax"></el-checkbox>
|
:false-value="0"></el-checkbox>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="下单">
|
<el-form-item label="下单">
|
||||||
<el-checkbox v-model="form.smsPushEventUser.noOrder" label="从未下单" :true-value="1" :false-value="0"
|
<el-checkbox v-model="form.smsPushEventUser.noOrder" label="从未下单" :true-value="1"
|
||||||
@change="getPushEventUserAjax"></el-checkbox>
|
:false-value="0"></el-checkbox>
|
||||||
<el-checkbox v-model="form.smsPushEventUser.oneOrder" label="下过1单" :true-value="1" :false-value="0"
|
<el-checkbox v-model="form.smsPushEventUser.oneOrder" label="下过1单" :true-value="1"
|
||||||
@change="getPushEventUserAjax"></el-checkbox>
|
:false-value="0"></el-checkbox>
|
||||||
<el-checkbox v-model="form.smsPushEventUser.fiveOrder" label="下过5单及以上" :true-value="1"
|
<el-checkbox v-model="form.smsPushEventUser.fiveOrder" label="下过5单及以上" :true-value="1"
|
||||||
:false-value="0" @change="getPushEventUserAjax"></el-checkbox>
|
:false-value="0"></el-checkbox>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="下单时间">
|
<el-form-item label="下单时间">
|
||||||
<el-checkbox v-model="form.smsPushEventUser.orderTimeToday" label="今天" :true-value="1"
|
<el-checkbox v-model="form.smsPushEventUser.orderTimeToday" label="今天" :true-value="1"
|
||||||
:false-value="0" @change="getPushEventUserAjax"></el-checkbox>
|
:false-value="0"></el-checkbox>
|
||||||
<el-checkbox v-model="form.smsPushEventUser.orderTimeYesterday" label="昨天" :true-value="1"
|
<el-checkbox v-model="form.smsPushEventUser.orderTimeYesterday" label="昨天" :true-value="1"
|
||||||
:false-value="0" @change="getPushEventUserAjax"></el-checkbox>
|
:false-value="0"></el-checkbox>
|
||||||
<el-checkbox v-model="form.smsPushEventUser.orderTimeTwoWeeks" label="2周内" :true-value="1"
|
<el-checkbox v-model="form.smsPushEventUser.orderTimeTwoWeeks" label="2周内" :true-value="1"
|
||||||
:false-value="0" @change="getPushEventUserAjax"></el-checkbox>
|
:false-value="0"></el-checkbox>
|
||||||
<el-checkbox v-model="form.smsPushEventUser.orderTimeMoreThanTwoWeeks" label="2周前" :true-value="1"
|
<el-checkbox v-model="form.smsPushEventUser.orderTimeMoreThanTwoWeeks" label="2周前" :true-value="1"
|
||||||
:false-value="0" @change="getPushEventUserAjax"></el-checkbox>
|
:false-value="0"></el-checkbox>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="会员">
|
<el-form-item label="会员">
|
||||||
<el-radio-group v-model="form.smsPushEventUser.isVip" @change="getPushEventUserAjax">
|
<el-radio-group v-model="form.smsPushEventUser.isVip">
|
||||||
|
<el-radio label="全部" value=""></el-radio>
|
||||||
<el-radio label="会员" :value="1"></el-radio>
|
<el-radio label="会员" :value="1"></el-radio>
|
||||||
<el-radio label="非会员" :value="0"></el-radio>
|
<el-radio label="非会员" :value="0"></el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="充值">
|
<el-form-item label="充值">
|
||||||
<el-radio-group v-model="form.smsPushEventUser.isRecharge" @change="getPushEventUserAjax">
|
<el-radio-group v-model="form.smsPushEventUser.isRecharge">
|
||||||
|
<el-radio label="全部" value=""></el-radio>
|
||||||
<el-radio label="从未充值过" :value="0"></el-radio>
|
<el-radio label="从未充值过" :value="0"></el-radio>
|
||||||
<el-radio label="充值过" :value="1"></el-radio>
|
<el-radio label="充值过" :value="1"></el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
<el-form-item label-width="120" style="margin-top: 50px;">
|
||||||
|
<el-button type="primary" icon="Search" :loading="userTableData.loading"
|
||||||
|
@click="getPushEventUserAjax">搜索</el-button>
|
||||||
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="item2">
|
<div class="item2">
|
||||||
<div class="user_wrap" v-loading="userTableData.loading">
|
<div class="user_wrap" v-loading="userTableData.loading">
|
||||||
@@ -138,8 +149,9 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="选择时间" v-if="form.sendType == 2" prop="sendTime">
|
<el-form-item label="选择时间" v-if="form.sendType == 2" prop="sendTime">
|
||||||
<el-date-picker v-model="form.sendTime" type="datetime" placeholder="请选择发送时间" format="YYYY-MM-DD HH:mm:sss"
|
<el-date-picker v-model="form.sendTime" type="datetime" placeholder="请选择发送时间" format="YYYY-MM-DD HH:mm:ss"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss" style="width: 220px;" />
|
value-format="YYYY-MM-DD HH:mm:ss" :min-date="minTime" :teleported="false" style="width: 220px;"
|
||||||
|
@open="refreshMinTime" @change="handleChange" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="预计发送人数">
|
<el-form-item label="预计发送人数">
|
||||||
{{ form.estimateNum }}人
|
{{ form.estimateNum }}人
|
||||||
@@ -170,6 +182,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import { ElMessage } from 'element-plus'; // 用于提示
|
||||||
import { multiplyAndFormat } from '@/utils'
|
import { multiplyAndFormat } from '@/utils'
|
||||||
import { ref, reactive, onMounted, computed, nextTick } from 'vue'
|
import { ref, reactive, onMounted, computed, nextTick } from 'vue'
|
||||||
import { getPushEventUser, smsTemplateGet, couponPage, pushEventPost, smsMoneyGet, smsMoneyGetFee } from '@/api/coupon'
|
import { getPushEventUser, smsTemplateGet, couponPage, pushEventPost, smsMoneyGet, smsMoneyGetFee } from '@/api/coupon'
|
||||||
@@ -179,7 +193,6 @@ const smsPushEventUserObj = ref({
|
|||||||
sexMan: 1,
|
sexMan: 1,
|
||||||
sexWoman: 1,
|
sexWoman: 1,
|
||||||
sexUnknown: 1,
|
sexUnknown: 1,
|
||||||
isRecharge: 0,
|
|
||||||
noOrder: 1,
|
noOrder: 1,
|
||||||
oneOrder: 0,
|
oneOrder: 0,
|
||||||
fiveOrder: 0,
|
fiveOrder: 0,
|
||||||
@@ -187,8 +200,8 @@ const smsPushEventUserObj = ref({
|
|||||||
orderTimeYesterday: 0,
|
orderTimeYesterday: 0,
|
||||||
orderTimeTwoWeeks: 0,
|
orderTimeTwoWeeks: 0,
|
||||||
orderTimeMoreThanTwoWeeks: 0,
|
orderTimeMoreThanTwoWeeks: 0,
|
||||||
isVip: 1,
|
isVip: '',
|
||||||
isRecharge: 1,
|
isRecharge: '',
|
||||||
vipLevel: 0,
|
vipLevel: 0,
|
||||||
vipLevelId: 0
|
vipLevelId: 0
|
||||||
})
|
})
|
||||||
@@ -213,24 +226,22 @@ const resetForm = ref({})
|
|||||||
const formRules = ref({
|
const formRules = ref({
|
||||||
pushEventId: [{ required: true, message: '请选择模板', trigger: 'change' }],
|
pushEventId: [{ required: true, message: '请选择模板', trigger: 'change' }],
|
||||||
// 校验 selectTempList
|
// 校验 selectTempList
|
||||||
selectTempList: [
|
items: [
|
||||||
{
|
{
|
||||||
validator: (rule, value, callback) => {
|
type: 'array', // 声明为数组类型
|
||||||
// value 实际不会自动传递,需要手动取 selectTempList.value
|
required: true,
|
||||||
const fields = selectTempList.value;
|
message: ' ',
|
||||||
if (!fields || fields.length === 0) {
|
// 配置数组中每个元素的规则
|
||||||
callback();
|
defaultField: {
|
||||||
} else {
|
type: 'object',
|
||||||
for (let i = 0; i < fields.length; i++) {
|
properties: {
|
||||||
if (fields[i].value === '' || fields[i].value == null) {
|
value: {
|
||||||
callback(new Error(`请填写${fields[i].key}`));
|
required: true,
|
||||||
return;
|
message: '值不能为空',
|
||||||
}
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
callback();
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
trigger: 'change'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
coupon: [
|
coupon: [
|
||||||
@@ -268,6 +279,25 @@ const formRules = ref({
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 最小可选时间(响应式)
|
||||||
|
const minTime = ref(new Date());
|
||||||
|
|
||||||
|
// 刷新最小时间为当前时间
|
||||||
|
const refreshMinTime = () => {
|
||||||
|
minTime.value = new Date(); // 每次打开面板,强制更新为当前时间
|
||||||
|
};
|
||||||
|
|
||||||
|
// 变更时二次校验(防止极端情况)
|
||||||
|
const handleChange = (value) => {
|
||||||
|
if (!value) return;
|
||||||
|
const selectedTime = new Date(value).getTime();
|
||||||
|
const currentTime = new Date().getTime();
|
||||||
|
if (selectedTime < currentTime) {
|
||||||
|
form.value.sendTime = '';
|
||||||
|
ElMessage.warning('选择的时间不能早于当前时间');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 开始提交
|
// 开始提交
|
||||||
const formRef = ref(null)
|
const formRef = ref(null)
|
||||||
const emits = defineEmits(["success"]);
|
const emits = defineEmits(["success"]);
|
||||||
@@ -275,17 +305,18 @@ const loading = ref(false);
|
|||||||
const tempPrewiewContentRef = ref(null);
|
const tempPrewiewContentRef = ref(null);
|
||||||
|
|
||||||
function getJsonFromFields(fields, mapping) {
|
function getJsonFromFields(fields, mapping) {
|
||||||
|
// console.log(fields);
|
||||||
const result = {};
|
const result = {};
|
||||||
// 先处理可编辑字段
|
// 先处理可编辑字段
|
||||||
fields.forEach(f => {
|
fields.forEach(f => {
|
||||||
result[f.key] = f.value;
|
result[f.key] = f.value;
|
||||||
});
|
});
|
||||||
// 再处理 disabled 且有 default 的字段
|
// 再处理 disabled 且有 default 的字段
|
||||||
mapping.forEach(m => {
|
// mapping.forEach(m => {
|
||||||
if (m.disabled && m.default != null) {
|
// if (m.disabled && m.default != null) {
|
||||||
result[m.key] = m.default;
|
// result[m.key] = m.default;
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,7 +330,10 @@ function submitHandle() {
|
|||||||
data.content = tempPrewiewContentRef.value ? tempPrewiewContentRef.value.innerText : '';
|
data.content = tempPrewiewContentRef.value ? tempPrewiewContentRef.value.innerText : '';
|
||||||
|
|
||||||
// 转换 json
|
// 转换 json
|
||||||
data.json = JSON.stringify(getJsonFromFields(selectTempList.value, mapping));
|
data.json = JSON.stringify(getJsonFromFields(form.value.selectTempList, mapping));
|
||||||
|
|
||||||
|
// console.log(data.json);
|
||||||
|
// return
|
||||||
|
|
||||||
await pushEventPost(data, data.id ? 'put' : 'post');
|
await pushEventPost(data, data.id ? 'put' : 'post');
|
||||||
emits("success");
|
emits("success");
|
||||||
@@ -355,7 +389,9 @@ async function getPushEventUserAjax() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
userTableData.loading = false
|
setTimeout(() => {
|
||||||
|
userTableData.loading = false
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页大小发生变化
|
// 分页大小发生变化
|
||||||
@@ -418,9 +454,9 @@ async function show(obj, temp = null) {
|
|||||||
// 选择模板
|
// 选择模板
|
||||||
selectTemp.value = tempList.value.find(item => item.id === obj.pushEventId)
|
selectTemp.value = tempList.value.find(item => item.id === obj.pushEventId)
|
||||||
// 提取可编辑字段
|
// 提取可编辑字段
|
||||||
selectTempList.value = parseTemplate(selectTemp.value?.content)
|
form.value.selectTempList = parseTemplate(selectTemp.value?.content)
|
||||||
} else {
|
} else {
|
||||||
selectTempList.value = []
|
form.value.selectTempList = []
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析优惠券
|
// 解析优惠券
|
||||||
@@ -443,7 +479,7 @@ async function show(obj, temp = null) {
|
|||||||
if (form.value.json) {
|
if (form.value.json) {
|
||||||
try {
|
try {
|
||||||
const jsonObj = JSON.parse(form.value.json)
|
const jsonObj = JSON.parse(form.value.json)
|
||||||
selectTempList.value = selectTempList.value.map(field => {
|
form.value.selectTempList = form.value.selectTempList.map(field => {
|
||||||
if (jsonObj.hasOwnProperty(field.key)) {
|
if (jsonObj.hasOwnProperty(field.key)) {
|
||||||
return { ...field, value: jsonObj[field.key] }
|
return { ...field, value: jsonObj[field.key] }
|
||||||
}
|
}
|
||||||
@@ -454,11 +490,11 @@ async function show(obj, temp = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectTempList.value = []
|
form.value.selectTempList = []
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
form.value = { ...resetForm.value }
|
form.value = { ...resetForm.value }
|
||||||
selectTempList.value = []
|
form.value.selectTempList = []
|
||||||
selectCoupons.value = []
|
selectCoupons.value = []
|
||||||
// 选中模板id
|
// 选中模板id
|
||||||
if (temp && temp.id) {
|
if (temp && temp.id) {
|
||||||
@@ -468,11 +504,13 @@ async function show(obj, temp = null) {
|
|||||||
} else {
|
} else {
|
||||||
form.value.pushEventId = ''
|
form.value.pushEventId = ''
|
||||||
selectTemp.value = null
|
selectTemp.value = null
|
||||||
selectTempList.value = []
|
form.value.selectTempList = []
|
||||||
}
|
}
|
||||||
|
|
||||||
form.value.estimateNum = userTableData.total
|
form.value.estimateNum = userTableData.total
|
||||||
}
|
}
|
||||||
|
form.value.selectTempList = []
|
||||||
|
getPushEventUserAjax()
|
||||||
}
|
}
|
||||||
// 从本地获取商户信息
|
// 从本地获取商户信息
|
||||||
const shopInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
|
const shopInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
|
||||||
@@ -480,9 +518,8 @@ const shopInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
|
|||||||
// 获取模板列表
|
// 获取模板列表
|
||||||
const tempList = ref([])
|
const tempList = ref([])
|
||||||
const selectTemp = ref(null);
|
const selectTemp = ref(null);
|
||||||
const selectTempList = ref([])
|
|
||||||
|
|
||||||
// 映射表(你给的样例)
|
// 映射表
|
||||||
const mapping = [
|
const mapping = [
|
||||||
{ key: '用户昵称', inputType: 'input', disabled: true, default: '某某某' },
|
{ key: '用户昵称', inputType: 'input', disabled: true, default: '某某某' },
|
||||||
{ key: '店铺名称', inputType: 'input', disabled: true, default: shopInfo.value ? shopInfo.value.shopName : '' },
|
{ key: '店铺名称', inputType: 'input', disabled: true, default: shopInfo.value ? shopInfo.value.shopName : '' },
|
||||||
@@ -491,42 +528,47 @@ const mapping = [
|
|||||||
{ key: '数量', inputType: 'input' },
|
{ key: '数量', inputType: 'input' },
|
||||||
{ key: '金额', inputType: 'input' },
|
{ key: '金额', inputType: 'input' },
|
||||||
{ key: '时间', inputType: 'time' }
|
{ key: '时间', inputType: 'time' }
|
||||||
]
|
];
|
||||||
|
|
||||||
// parseTemplate: 提取占位符并映射到目标数组
|
// parseTemplate: 提取占位符并映射到目标数组
|
||||||
function parseTemplate(templateStr, mappingList = mapping) {
|
function parseTemplate(templateStr, mappingList = mapping) {
|
||||||
if (!templateStr) return []
|
if (!templateStr) return [];
|
||||||
|
|
||||||
const regex = /\$\{\s*([^}]+?)\s*\}/g
|
const regex = /\$\{\s*([^}]+?)\s*\}/g;
|
||||||
const seen = new Set()
|
const seen = new Set();
|
||||||
const result = []
|
const result = [];
|
||||||
let match
|
let match;
|
||||||
|
|
||||||
while ((match = regex.exec(templateStr)) !== null) {
|
while ((match = regex.exec(templateStr)) !== null) {
|
||||||
const key = match[1].trim()
|
const key = match[1].trim();
|
||||||
if (!key || seen.has(key)) continue
|
if (!key || seen.has(key)) continue;
|
||||||
seen.add(key)
|
seen.add(key);
|
||||||
|
|
||||||
const map = mappingList.find(item => item.key === key)
|
// 查找映射项
|
||||||
// 如果映射项被标记为 disabled,则不加入可编辑列表(但会用于预览默认值)
|
const mapItem = mappingList.find(item => item.key === key);
|
||||||
const type = map ? (map.inputType || map.type || 'input') : 'input'
|
// 确定输入类型(默认input)
|
||||||
if (map && map.disabled) {
|
const type = mapItem?.inputType || mapItem?.type || 'input';
|
||||||
continue
|
// 确定是否禁用(默认false)
|
||||||
}
|
const disabled = Boolean(mapItem?.disabled);
|
||||||
|
// 确定默认值(映射项有默认值则使用,否则为空)
|
||||||
|
const value = disabled ? (mapItem?.default || '') : '';
|
||||||
|
|
||||||
result.push({ key, value: '', type })
|
result.push({ key, value, type, disabled });
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择模板
|
// 选择模板
|
||||||
function selectTempChange(e) {
|
function selectTempChange(e) {
|
||||||
selectTemp.value = tempList.value.find(item => item.id == e)
|
selectTemp.value = tempList.value.find(item => item.id == e)
|
||||||
form.value.content = selectTemp.value.content;
|
form.value.content = selectTemp.value.content;
|
||||||
selectTempList.value = parseTemplate(selectTemp.value.content)
|
|
||||||
|
|
||||||
console.log('选择模板===', selectTempList.value);
|
nextTick(() => {
|
||||||
|
form.value.selectTempList = parseTemplate(selectTemp.value.content)
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('选择模板===', form.value.selectTempList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取短信模板列表
|
// 获取短信模板列表
|
||||||
@@ -611,7 +653,7 @@ const previewHtml = computed(() => {
|
|||||||
if (!selectTemp.value) return ''
|
if (!selectTemp.value) return ''
|
||||||
// 合并 title + content
|
// 合并 title + content
|
||||||
const tpl = `${selectTemp.value.title || ''}${selectTemp.value.content || ''}`
|
const tpl = `${selectTemp.value.title || ''}${selectTemp.value.content || ''}`
|
||||||
return renderPreviewHtml(tpl, selectTempList.value)
|
return renderPreviewHtml(tpl, form.value.selectTempList)
|
||||||
})
|
})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
@@ -620,7 +662,6 @@ defineExpose({
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
resetForm.value = { ...form.value }
|
resetForm.value = { ...form.value }
|
||||||
getPushEventUserAjax()
|
|
||||||
getTempListAjax()
|
getTempListAjax()
|
||||||
couponPageAjax()
|
couponPageAjax()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<el-form-item label="模板名称" prop="title">
|
<el-form-item label="模板名称" prop="title">
|
||||||
<el-input placeholder="请输入内容" v-model="form.title" :maxlength="30" style="width: 300px;"></el-input>
|
<el-input placeholder="请输入内容" v-model="form.title" :maxlength="30" style="width: 300px;"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="模版内容" prop="title">
|
<el-form-item label="模版内容" prop="content">
|
||||||
<div style="width: 300px;">
|
<div style="width: 300px;">
|
||||||
<editorDiv ref="editorDivRef" v-model="form.content" />
|
<editorDiv ref="editorDivRef" v-model="form.content" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,23 +2,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<el-button type="primary" @click="addTaskRef?.show()">添加任务</el-button>
|
<el-form inline>
|
||||||
|
<el-form-item>
|
||||||
|
<el-select v-model="querForm.status" style="width: 300px;">
|
||||||
|
<el-option value="" label="全部"></el-option>
|
||||||
|
<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>
|
||||||
|
<el-button type="primary" @click="getTableData">搜索</el-button>
|
||||||
|
<el-button type="warning" icon="Refresh" :loading="tableData.loading" @click="reseQueryHandle">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<el-button type="primary" icon="Plus" @click="addTaskRef?.show()">添加任务</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<el-table :data="tableData.list" stripe border v-loading="tableData.loading">
|
<el-table :data="tableData.list" stripe border v-loading="tableData.loading">
|
||||||
<el-table-column label="ID" prop="id"></el-table-column>
|
<el-table-column label="ID" prop="id" width="80"></el-table-column>
|
||||||
<el-table-column label="短信内容" prop="content" width="300"></el-table-column>
|
<el-table-column label="短信内容" prop="content" min-width="300"></el-table-column>
|
||||||
<el-table-column label="优惠券信息" prop="coupon"></el-table-column>
|
<el-table-column label="优惠券信息" prop="coupon" width="160">
|
||||||
<el-table-column label="发送对象" prop="userType"></el-table-column>
|
<template #default="scope">
|
||||||
|
<div class="column">
|
||||||
|
<div v-for="item in JSON.parse(scope.row.coupon)" :key="item.id">
|
||||||
|
<el-tag effect="dark" round disable-transitions :type="getRandomStatus()">
|
||||||
|
{{ item.title }} x{{ item.num }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="发送对象" prop="userType" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ userTypeFilters(scope.row.userType).label }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="发送人数「预计」" prop="estimateNum" width="150"></el-table-column>
|
<el-table-column label="发送人数「预计」" prop="estimateNum" width="150"></el-table-column>
|
||||||
<el-table-column label="发送时间" prop="sendTime"></el-table-column>
|
<el-table-column label="发送时间" prop="sendTime" width="200"></el-table-column>
|
||||||
<el-table-column label="状态" prop="status"></el-table-column>
|
<el-table-column label="状态" prop="status" width="100">
|
||||||
<el-table-column label="创建时间" prop="createTime"></el-table-column>
|
<template #default="scope">
|
||||||
|
<el-tag disable-transitions :type="statusListFilter(scope.row.status).type">
|
||||||
|
{{ statusListFilter(scope.row.status).label }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" prop="createTime" width="200"></el-table-column>
|
||||||
<el-table-column label="操作" fixed="right" width="120">
|
<el-table-column label="操作" fixed="right" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button link type="primary" v-if="scope.row.status != 2"
|
<el-button link type="primary" v-if="scope.row.status != 2 && scope.row.status != 1"
|
||||||
@click="addTaskRef.show(scope.row)">编辑</el-button>
|
@click="addTaskRef.show(scope.row)">编辑</el-button>
|
||||||
<el-popconfirm title="确认要删除吗?" @confirm="deleteHandle(scope.row)">
|
<el-popconfirm title="确认要删除吗?" @confirm="deleteHandle(scope.row)"
|
||||||
|
v-if="scope.row.status != 2 && scope.row.status != 1">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-button type="danger" link>删除</el-button>
|
<el-button type="danger" link>删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -40,6 +75,15 @@
|
|||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
import addTask from './components/addTask.vue';
|
import addTask from './components/addTask.vue';
|
||||||
import { pushEventGet, pushEventDel } from '@/api/coupon'
|
import { pushEventGet, pushEventDel } from '@/api/coupon'
|
||||||
|
import { template } from 'lodash';
|
||||||
|
|
||||||
|
function getRandomStatus() {
|
||||||
|
const statusList = ['primary', 'success', 'warning', 'danger'];
|
||||||
|
// 生成0到数组长度之间的随机整数索引
|
||||||
|
const randomIndex = Math.floor(Math.random() * statusList.length);
|
||||||
|
// 返回随机索引对应的元素
|
||||||
|
return statusList[randomIndex];
|
||||||
|
}
|
||||||
|
|
||||||
const addTaskRef = ref(null)
|
const addTaskRef = ref(null)
|
||||||
|
|
||||||
@@ -50,6 +94,64 @@ const tableData = reactive({
|
|||||||
list: []
|
list: []
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 发送对象
|
||||||
|
function userTypeFilters(status) {
|
||||||
|
const m = [
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: '全部用户',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
label: '范围用户',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 3,
|
||||||
|
label: '指定用户',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
return m.find(item => item.value == status)
|
||||||
|
}
|
||||||
|
|
||||||
|
const querForm = ref({
|
||||||
|
status: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
function reseQueryHandle() {
|
||||||
|
querForm.value.status = ''
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 状态列表
|
||||||
|
const statusList = ref([
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
label: '待发送',
|
||||||
|
type: 'info'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: '发送中...',
|
||||||
|
type: 'warning'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
label: '发送成功',
|
||||||
|
type: 'success'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: -1,
|
||||||
|
label: '失败 ',
|
||||||
|
type: 'danger'
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// 筛选状态
|
||||||
|
function statusListFilter(status) {
|
||||||
|
return statusList.value.find(item => item.value == status)
|
||||||
|
}
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
async function deleteHandle(row) {
|
async function deleteHandle(row) {
|
||||||
try {
|
try {
|
||||||
@@ -84,14 +186,17 @@ const getTableData = async () => {
|
|||||||
tableData.loading = true;
|
tableData.loading = true;
|
||||||
const res = await pushEventGet({
|
const res = await pushEventGet({
|
||||||
page: tableData.page,
|
page: tableData.page,
|
||||||
size: tableData.size
|
size: tableData.size,
|
||||||
|
status: querForm.value.status
|
||||||
});
|
});
|
||||||
tableData.list = res.records;
|
tableData.list = res.records;
|
||||||
tableData.total = res.totalRow;
|
tableData.total = res.totalRow;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
tableData.loading = false;
|
setTimeout(() => {
|
||||||
|
tableData.loading = false;
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加模板,并且默认选中模板
|
// 添加模板,并且默认选中模板
|
||||||
@@ -112,4 +217,10 @@ onMounted(() => {
|
|||||||
.row {
|
.row {
|
||||||
padding-top: 14px;
|
padding-top: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
<!-- 用量记录 -->
|
<!-- 用量记录 -->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<div class="row">
|
||||||
|
<el-button type="primary" icon="Refresh" :loading="tableData.loading" @click="getTableData">刷新</el-button>
|
||||||
|
</div>
|
||||||
<div class="data_show">
|
<div class="data_show">
|
||||||
<div class="data_list">
|
<div class="data_list">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
@@ -65,7 +68,7 @@ function handleCurrentChange(e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取店铺短信余额明细
|
// 获取店铺短信余额明细
|
||||||
async function getTableData(params) {
|
async function getTableData() {
|
||||||
try {
|
try {
|
||||||
tableData.loading = true
|
tableData.loading = true
|
||||||
const res = await smsMoneyDetail({
|
const res = await smsMoneyDetail({
|
||||||
@@ -78,7 +81,9 @@ async function getTableData(params) {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
tableData.loading = false
|
setTimeout(() => {
|
||||||
|
tableData.loading = false
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -88,7 +93,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.data_show {
|
.data_show {
|
||||||
padding: 0 0 14px;
|
padding: 14px 0;
|
||||||
|
|
||||||
.data_list {
|
.data_list {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<el-button type="primary" icon="Refresh" :loading="loading" @click="smsTemplateGetAjax">刷新</el-button>
|
||||||
<el-button type="primary" @click="addTemplateRef.show()">申请新模板</el-button>
|
<el-button type="primary" @click="addTemplateRef.show()">申请新模板</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row" v-loading="loading">
|
||||||
<div class="title">可用模板</div>
|
<div class="title">可用模板</div>
|
||||||
<div class="card_wrap" :class="[`card_wrap${useData.length}`]">
|
<div class="card_wrap" :class="[`card_wrap${useData.length}`]">
|
||||||
<div class="card" v-for="item in useData" :key="item.id">
|
<div class="card" v-for="item in useData" :key="item.id">
|
||||||
@@ -85,14 +86,19 @@ const useData = ref([]) // 可用模板
|
|||||||
const applyData = ref([]) // 申请模板
|
const applyData = ref([]) // 申请模板
|
||||||
|
|
||||||
// 获取模板列表
|
// 获取模板列表
|
||||||
|
const loading = ref(false)
|
||||||
async function smsTemplateGetAjax() {
|
async function smsTemplateGetAjax() {
|
||||||
try {
|
try {
|
||||||
|
loading.value = true
|
||||||
const res = await smsTemplateGet()
|
const res = await smsTemplateGet()
|
||||||
useData.value = res.filter(item => item.status === 2)
|
useData.value = res.filter(item => item.status === 2)
|
||||||
applyData.value = res.filter(item => item.status !== 2)
|
applyData.value = res.filter(item => item.status !== 2)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('error', error);
|
console.log('error', error);
|
||||||
}
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳转去使用模板
|
// 跳转去使用模板
|
||||||
|
|||||||
@@ -0,0 +1,630 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" :title="form.id ? '编辑推送任务' : '添加推送任务'" width="1200px" top="4vh"
|
||||||
|
@closed="formRef.resetFields()">
|
||||||
|
<div class="scroll" ref="scrollRef">
|
||||||
|
<el-form ref="formRef" :model="form" :rules="formRules" label-width="160px">
|
||||||
|
<div class="title">选择目标用户</div>
|
||||||
|
<el-form-item label-width="0">
|
||||||
|
<div class="shop_user_wrap">
|
||||||
|
<div class="item">
|
||||||
|
<el-form-item label="发送对象">
|
||||||
|
<el-radio-group v-model="form.userType">
|
||||||
|
<el-radio label="全部绑定手机号用户" :value="1"></el-radio>
|
||||||
|
<el-radio label="自定义用户" :value="2"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<div v-if="form.userType == 2">
|
||||||
|
<el-form-item label="性别">
|
||||||
|
<el-checkbox v-model="form.pushEventUser.sexMan" label="男" :true-value="1"
|
||||||
|
:false-value="0"></el-checkbox>
|
||||||
|
<el-checkbox v-model="form.pushEventUser.sexWoman" label="女" :true-value="1"
|
||||||
|
:false-value="0"></el-checkbox>
|
||||||
|
<el-checkbox v-model="form.pushEventUser.sexUnknown" label="未知" :true-value="1"
|
||||||
|
:false-value="0"></el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="下单">
|
||||||
|
<el-checkbox v-model="form.pushEventUser.noOrder" label="从未下单" :true-value="1"
|
||||||
|
:false-value="0"></el-checkbox>
|
||||||
|
<el-checkbox v-model="form.pushEventUser.oneOrder" label="下过1单" :true-value="1"
|
||||||
|
:false-value="0"></el-checkbox>
|
||||||
|
<el-checkbox v-model="form.pushEventUser.fiveOrder" label="下过5单及以上" :true-value="1"
|
||||||
|
:false-value="0"></el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="下单时间">
|
||||||
|
<el-checkbox v-model="form.pushEventUser.orderTimeToday" label="今天" :true-value="1"
|
||||||
|
:false-value="0"></el-checkbox>
|
||||||
|
<el-checkbox v-model="form.pushEventUser.orderTimeYesterday" label="昨天" :true-value="1"
|
||||||
|
:false-value="0"></el-checkbox>
|
||||||
|
<el-checkbox v-model="form.pushEventUser.orderTimeTwoWeeks" label="2周内" :true-value="1"
|
||||||
|
:false-value="0"></el-checkbox>
|
||||||
|
<el-checkbox v-model="form.pushEventUser.orderTimeMoreThanTwoWeeks" label="2周前" :true-value="1"
|
||||||
|
:false-value="0"></el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="会员">
|
||||||
|
<el-radio-group v-model="form.pushEventUser.isVip">
|
||||||
|
<el-radio label="全部" value=""></el-radio>
|
||||||
|
<el-radio label="会员" :value="1"></el-radio>
|
||||||
|
<el-radio label="非会员" :value="0"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="充值">
|
||||||
|
<el-radio-group v-model="form.pushEventUser.isRecharge">
|
||||||
|
<el-radio label="全部" value=""></el-radio>
|
||||||
|
<el-radio label="从未充值过" :value="0"></el-radio>
|
||||||
|
<el-radio label="充值过" :value="1"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<el-form-item label-width="160" style="margin-top: 50px;">
|
||||||
|
<el-button type="primary" icon="Search" :loading="userTableData.loading"
|
||||||
|
@click="getPushEventUserAjax">搜索</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div class="item2">
|
||||||
|
<div class="user_wrap" v-loading="userTableData.loading">
|
||||||
|
<div class="user_header">
|
||||||
|
<span>预计发送</span>
|
||||||
|
<span>{{ form.estimateNum }}人</span>
|
||||||
|
</div>
|
||||||
|
<div class="list">
|
||||||
|
<div class="item" v-for="item in userTableData.list" :key="item.id">
|
||||||
|
<div class="avatar">
|
||||||
|
<el-avatar :size="50" :src="item.headImg" />
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<div class="name">{{ item.nickName }}</div>
|
||||||
|
<div class="info_wrap">
|
||||||
|
<span>余额:{{ item.amount }}</span>
|
||||||
|
<span>积分:{{ item.accountPoints }}</span>
|
||||||
|
<span>手机号:{{ item.phone }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex;justify-content: center;padding-bottom: 14px;">
|
||||||
|
<el-pagination v-model:current-page="userTableData.page" v-model:page-size="userTableData.pageSize"
|
||||||
|
:page-sizes="[100, 200, 300, 400]" background layout="prev, pager, next"
|
||||||
|
:total="userTableData.total" @size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="title">发送内容</div>
|
||||||
|
<el-form-item label="商家名称">
|
||||||
|
<el-input placeholder="请输入文字" v-model="form.shopName" disabled :maxlength="20" show-word-limit
|
||||||
|
style="width: 300px;"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商家地址" prop="address">
|
||||||
|
<el-input placeholder="请输入文字" type="textarea" :rows="4" v-model="form.address" :maxlength="10" show-word-limit
|
||||||
|
style="width: 300px;"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="活动描述" prop="activityDetail">
|
||||||
|
<el-input type="textarea" v-model="form.activityDetail" :rows="4" placeholder="请输入活动描述" :maxlength="20"
|
||||||
|
show-word-limit style="width: 300px;"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="活动时间" prop="activityTime">
|
||||||
|
<el-date-picker v-model="form.activityTime" type="datetime" placeholder="请选择时间" format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss" style="width: 300px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="赠送优惠券">
|
||||||
|
<div class="column">
|
||||||
|
<div class="center" v-for="(item, index) in selectCoupons" :key="item.id">
|
||||||
|
<el-select v-model="item.id" @change="selectCouponChnge($event, index)">
|
||||||
|
<el-option :label="val.title" :value="val.id" v-for="val in couponList" :key="val.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-input v-model="item.num" input-style="text-align:center;">
|
||||||
|
<template #append>数量</template>
|
||||||
|
</el-input>
|
||||||
|
<div class="del" @click="selectCoupons.splice(index, 1)">
|
||||||
|
<el-icon size="18" color="#FF2F2F">
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="center">
|
||||||
|
<el-button link type="primary" icon="CirclePlus" @click="addCoupon">新增券</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="title">发送设置</div>
|
||||||
|
<el-form-item label="发送时间">
|
||||||
|
<el-radio-group v-model="form.sendType">
|
||||||
|
<el-radio label="立即发送" :value="1"></el-radio>
|
||||||
|
<el-radio label="定时发送" :value="2"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="选择时间" v-if="form.sendType == 2" prop="sendTime">
|
||||||
|
<el-date-picker v-model="form.sendTime" type="datetime" placeholder="请选择发送时间" format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss" :min-date="minTime" :teleported="false" style="width: 220px;"
|
||||||
|
@open="refreshMinTime" @change="handleChange" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="预计发送人数">
|
||||||
|
{{ form.estimateNum }}人
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="短信单价">
|
||||||
|
{{ notePirce }}元/条
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="预计费用">
|
||||||
|
¥{{ predictPrice }}
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="账户余额">
|
||||||
|
¥{{ multiplyAndFormat(shopBalance.money || 0) }}
|
||||||
|
<span v-if="predictPrice > shopBalance.money"
|
||||||
|
style="color:#FF2F2F;margin-left: 14px;">余额不足,请联系管理员充值后再发送</span>
|
||||||
|
</el-form-item> -->
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" :disabled="form.estimateNum <= 0" :loading="loading" @click="submitHandle">确
|
||||||
|
定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import _ from 'lodash'
|
||||||
|
import { multiplyAndFormat } from '@/utils'
|
||||||
|
import { ref, reactive, onMounted, computed, nextTick } from 'vue'
|
||||||
|
import { getAcPushEventUser, couponPage, acPushEventPost, smsMoneyGet, smsMoneyGetFee } from '@/api/coupon'
|
||||||
|
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const smsPushEventUserObj = ref({
|
||||||
|
sexMan: 1,
|
||||||
|
sexWoman: 1,
|
||||||
|
sexUnknown: 1,
|
||||||
|
noOrder: 1,
|
||||||
|
oneOrder: 0,
|
||||||
|
fiveOrder: 0,
|
||||||
|
orderTimeToday: 0,
|
||||||
|
orderTimeYesterday: 0,
|
||||||
|
orderTimeTwoWeeks: 0,
|
||||||
|
orderTimeMoreThanTwoWeeks: 0,
|
||||||
|
isVip: '',
|
||||||
|
isRecharge: '',
|
||||||
|
vipLevel: 0,
|
||||||
|
vipLevelId: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const form = ref({
|
||||||
|
id: '',
|
||||||
|
shopId: localStorage.getItem('shopId') || '',
|
||||||
|
userType: 1,
|
||||||
|
pushEventId: '',
|
||||||
|
estimateNum: 0, // 预计人数
|
||||||
|
coupon: '',
|
||||||
|
shopName: '',
|
||||||
|
activityDetail: '',
|
||||||
|
activityTime: '',
|
||||||
|
address: '',
|
||||||
|
sendType: 1,
|
||||||
|
sendTime: '',
|
||||||
|
pushEventUser: { ...smsPushEventUserObj.value }
|
||||||
|
})
|
||||||
|
|
||||||
|
const resetForm = ref({})
|
||||||
|
|
||||||
|
const formRules = ref({
|
||||||
|
address: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (value === '') {
|
||||||
|
callback(new Error('请输入商家地址'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value && value.length > 10) {
|
||||||
|
callback(new Error('最多10个字'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
activityDetail: [
|
||||||
|
{ required: true, message: '请输入活动描述', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
activityTime: [
|
||||||
|
{ required: true, message: '请选择活动时间', trigger: 'change' },
|
||||||
|
],
|
||||||
|
coupon: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
// value 是 selectCoupons.value 的 JSON 字符串
|
||||||
|
let coupons = selectCoupons.value;
|
||||||
|
if (coupons.length === 0) {
|
||||||
|
// 没有添加优惠券,不校验
|
||||||
|
callback();
|
||||||
|
} else {
|
||||||
|
// 校验每个优惠券
|
||||||
|
for (let i = 0; i < coupons.length; i++) {
|
||||||
|
if (!coupons[i].id) {
|
||||||
|
callback(new Error('请选择优惠券'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!coupons[i].num || !Number.isInteger(Number(coupons[i].num)) || Number(coupons[i].num) <= 0) {
|
||||||
|
callback(new Error('请输入大于零的优惠券数量'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
sendTime: [
|
||||||
|
{
|
||||||
|
required: (form) => form.sendType == 2,
|
||||||
|
message: '请选择发送时间',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// 最小可选时间(响应式)
|
||||||
|
const minTime = ref(new Date());
|
||||||
|
|
||||||
|
// 刷新最小时间为当前时间
|
||||||
|
const refreshMinTime = () => {
|
||||||
|
minTime.value = new Date(); // 每次打开面板,强制更新为当前时间
|
||||||
|
};
|
||||||
|
|
||||||
|
// 变更时二次校验(防止极端情况)
|
||||||
|
const handleChange = (value) => {
|
||||||
|
if (!value) return;
|
||||||
|
const selectedTime = new Date(value).getTime();
|
||||||
|
const currentTime = new Date().getTime();
|
||||||
|
if (selectedTime < currentTime) {
|
||||||
|
form.value.sendTime = '';
|
||||||
|
ElMessage.warning('选择的时间不能早于当前时间');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 开始提交
|
||||||
|
const formRef = ref(null)
|
||||||
|
const emits = defineEmits(["success"]);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
function submitHandle() {
|
||||||
|
formRef.value.validate(async (valid) => {
|
||||||
|
try {
|
||||||
|
if (valid) {
|
||||||
|
loading.value = true;
|
||||||
|
let data = { ...form.value }
|
||||||
|
data.coupon = JSON.stringify(selectCoupons.value);
|
||||||
|
// console.log(data.json);
|
||||||
|
// return
|
||||||
|
await acPushEventPost(data, data.id ? 'put' : 'post');
|
||||||
|
emits("success");
|
||||||
|
dialogVisible.value = false;
|
||||||
|
|
||||||
|
ElNotification({
|
||||||
|
title: '注意',
|
||||||
|
message: '保存成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
|
||||||
|
form.value = { ...resetForm.value }
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户列表
|
||||||
|
const notePirce = ref(0); // 短信单价
|
||||||
|
|
||||||
|
// 预计费用
|
||||||
|
const predictPrice = computed(() => {
|
||||||
|
return multiplyAndFormat(form.value.estimateNum, notePirce.value);
|
||||||
|
})
|
||||||
|
|
||||||
|
const userTableData = reactive({
|
||||||
|
loading: false,
|
||||||
|
list: [],
|
||||||
|
total: 0,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 5
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取推送用户
|
||||||
|
async function getPushEventUserAjax() {
|
||||||
|
try {
|
||||||
|
userTableData.loading = true
|
||||||
|
const res = await getAcPushEventUser({
|
||||||
|
...form.value.pushEventUser,
|
||||||
|
isAll: form.value.userType,
|
||||||
|
shopId: form.value.shopId,
|
||||||
|
page: userTableData.page,
|
||||||
|
size: userTableData.pageSize
|
||||||
|
})
|
||||||
|
userTableData.list = res.records
|
||||||
|
userTableData.total = res.totalRow
|
||||||
|
form.value.estimateNum = res.totalRow
|
||||||
|
|
||||||
|
console.log(form.value);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
userTableData.loading = false
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页大小发生变化
|
||||||
|
function handleSizeChange(e) {
|
||||||
|
userTableData.pageSize = e;
|
||||||
|
getPushEventUserAjax();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页发生变化
|
||||||
|
function handleCurrentChange(e) {
|
||||||
|
userTableData.page = e;
|
||||||
|
getPushEventUserAjax();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取商户短信余额
|
||||||
|
const shopBalance = ref('')
|
||||||
|
async function smsMoneyGetAjax() {
|
||||||
|
try {
|
||||||
|
const res = await smsMoneyGet()
|
||||||
|
shopBalance.value = res
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取短信单价
|
||||||
|
async function smsMoneyGetFeeAjax() {
|
||||||
|
try {
|
||||||
|
const res = await smsMoneyGetFee()
|
||||||
|
console.log('获取短信单价', res);
|
||||||
|
notePirce.value = +res.paramValue
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示弹窗
|
||||||
|
const scrollRef = ref(null);
|
||||||
|
async function show(obj, temp = null) {
|
||||||
|
dialogVisible.value = true
|
||||||
|
nextTick(() => {
|
||||||
|
if (scrollRef.value) {
|
||||||
|
setTimeout(() => {
|
||||||
|
scrollRef.value.scrollTop = 0;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// smsMoneyGetAjax()
|
||||||
|
// smsMoneyGetFeeAjax()
|
||||||
|
|
||||||
|
if (obj && obj.id) {
|
||||||
|
form.value = { ...obj }
|
||||||
|
form.value.userType = +obj.userType
|
||||||
|
if (obj.userType == 1) {
|
||||||
|
form.value.pushEventUser = { ...smsPushEventUserObj.value }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析优惠券
|
||||||
|
if (form.value.coupon) {
|
||||||
|
try {
|
||||||
|
const coupons = JSON.parse(form.value.coupon)
|
||||||
|
if (Array.isArray(coupons)) {
|
||||||
|
selectCoupons.value = coupons
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectCoupons.value = []
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
form.value = { ...resetForm.value }
|
||||||
|
form.value.shopName = shopInfo.value.shopName || ''
|
||||||
|
form.value.address = shopInfo.value.address || ''
|
||||||
|
selectCoupons.value = []
|
||||||
|
form.value.estimateNum = userTableData.total
|
||||||
|
}
|
||||||
|
getPushEventUserAjax()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从本地获取商户信息
|
||||||
|
const shopInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
|
||||||
|
|
||||||
|
// 选择优惠券开始
|
||||||
|
const couponList = ref([])
|
||||||
|
const selectCoupons = ref([]);
|
||||||
|
const couponObj = ref({ id: '', num: 1, title: '' });
|
||||||
|
|
||||||
|
// 选择优惠券添加标题
|
||||||
|
function selectCouponChnge(e, index) {
|
||||||
|
const coupon = couponList.value.find(item => item.id === e)
|
||||||
|
if (coupon) {
|
||||||
|
selectCoupons.value[index].title = coupon.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增优惠券
|
||||||
|
function addCoupon() {
|
||||||
|
selectCoupons.value.push(_.cloneDeep(couponObj.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取优惠券列表
|
||||||
|
async function couponPageAjax() {
|
||||||
|
try {
|
||||||
|
const res = await couponPage({
|
||||||
|
shopId: form.value.shopId,
|
||||||
|
page: 1,
|
||||||
|
size: 500
|
||||||
|
})
|
||||||
|
couponList.value = res.records
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 选择优惠券结束
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
resetForm.value = { ...form.value }
|
||||||
|
couponPageAjax()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.title {
|
||||||
|
color: #000;
|
||||||
|
padding: 14px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll {
|
||||||
|
height: 76vh;
|
||||||
|
padding-bottom: 60px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 14px;
|
||||||
|
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.del {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop_user_wrap {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 14px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.temp_preview {
|
||||||
|
border: 1px solid #D9D9D9;
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #F8F8F8;
|
||||||
|
padding: 14px;
|
||||||
|
|
||||||
|
.temp_preview_title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp_preview_content {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item2 {
|
||||||
|
width: 400px;
|
||||||
|
margin-right: 50px;
|
||||||
|
|
||||||
|
.user_wrap {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.user_header {
|
||||||
|
padding: 20px 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: #F8F8F8;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
--count: 5;
|
||||||
|
--itemHeight: 70px;
|
||||||
|
height: calc(var(--count) * var(--itemHeight) + 30px);
|
||||||
|
|
||||||
|
.item {
|
||||||
|
height: var(--itemHeight);
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 14px;
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 10px;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info_wrap {
|
||||||
|
margin-top: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
span {
|
||||||
|
&:nth-child(1) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(3) {
|
||||||
|
flex: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
247
src/views/marketing_center/official_accounts/index.vue
Normal file
247
src/views/marketing_center/official_accounts/index.vue
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
<!-- 公众号推送列表 -->
|
||||||
|
<template>
|
||||||
|
<div class="gyq_container">
|
||||||
|
<div class="gyq_content">
|
||||||
|
<div class="row">
|
||||||
|
<el-form inline>
|
||||||
|
<el-form-item>
|
||||||
|
<el-select v-model="querForm.status" style="width: 300px;">
|
||||||
|
<el-option value="" label="全部"></el-option>
|
||||||
|
<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>
|
||||||
|
<el-button type="primary" @click="getTableData">搜索</el-button>
|
||||||
|
<el-button type="warning" icon="Refresh" :loading="tableData.loading"
|
||||||
|
@click="reseQueryHandle">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" icon="Plus" @click="addTaskRef?.show()">添加任务</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<el-table :data="tableData.list" stripe border v-loading="tableData.loading">
|
||||||
|
<el-table-column label="ID" prop="id" width="80"></el-table-column>
|
||||||
|
<el-table-column label="推送任务" min-width="300">
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="column">
|
||||||
|
<div>商家名称:{{ scope.row.shopName }}</div>
|
||||||
|
<div>活动描述:{{ scope.row.activityDetail }}</div>
|
||||||
|
<div>开始时间:{{ scope.row.activityTime }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="优惠券信息" prop="coupon" width="160">
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="column" v-if="scope.row.coupon">
|
||||||
|
<div v-for="item in JSON.parse(scope.row.coupon)" :key="item.id">
|
||||||
|
<el-tag effect="dark" round disable-transitions :type="getRandomStatus()">
|
||||||
|
{{ item.title }} x{{ item.num }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="发送对象" prop="userType" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ userTypeFilters(scope.row.userType).label }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="发送人数「预计」" prop="estimateNum" width="150"></el-table-column>
|
||||||
|
<el-table-column label="发送时间" prop="sendTime" width="200"></el-table-column>
|
||||||
|
<el-table-column label="状态" prop="status" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag disable-transitions :type="statusListFilter(scope.row.status).type">
|
||||||
|
{{ statusListFilter(scope.row.status).label }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" prop="createTime" width="200"></el-table-column>
|
||||||
|
<el-table-column label="操作" fixed="right" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" v-if="scope.row.status != 2 && scope.row.status != 1"
|
||||||
|
@click="addTaskRef.show(scope.row)">编辑</el-button>
|
||||||
|
<el-popconfirm title="确认要删除吗?" @confirm="deleteHandle(scope.row)"
|
||||||
|
v-if="scope.row.status != 2 && scope.row.status != 1">
|
||||||
|
<template #reference>
|
||||||
|
<el-button type="danger" link>删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||||
|
:page-sizes="[100, 200, 300, 400]" background layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="tableData.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||||
|
</div>
|
||||||
|
<addTask ref="addTaskRef" @success="getTableData" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import addTask from './components/addTask.vue';
|
||||||
|
import { acPushEventGet, acPushEventDel } from '@/api/coupon'
|
||||||
|
|
||||||
|
function getRandomStatus() {
|
||||||
|
const statusList = ['primary', 'success', 'warning', 'danger'];
|
||||||
|
// 生成0到数组长度之间的随机整数索引
|
||||||
|
const randomIndex = Math.floor(Math.random() * statusList.length);
|
||||||
|
// 返回随机索引对应的元素
|
||||||
|
return statusList[randomIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
const addTaskRef = ref(null)
|
||||||
|
|
||||||
|
const tableData = reactive({
|
||||||
|
loading: false,
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
list: []
|
||||||
|
})
|
||||||
|
|
||||||
|
// 发送对象
|
||||||
|
function userTypeFilters(status) {
|
||||||
|
const m = [
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: '全部用户',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
label: '范围用户',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 3,
|
||||||
|
label: '指定用户',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
return m.find(item => item.value == status)
|
||||||
|
}
|
||||||
|
|
||||||
|
const querForm = ref({
|
||||||
|
status: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
function reseQueryHandle() {
|
||||||
|
querForm.value.status = ''
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 状态列表
|
||||||
|
const statusList = ref([
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
label: '待发送',
|
||||||
|
type: 'info'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: '发送中...',
|
||||||
|
type: 'warning'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
label: '发送成功',
|
||||||
|
type: 'success'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: -1,
|
||||||
|
label: '失败 ',
|
||||||
|
type: 'danger'
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// 筛选状态
|
||||||
|
function statusListFilter(status) {
|
||||||
|
return statusList.value.find(item => item.value == status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
async function deleteHandle(row) {
|
||||||
|
try {
|
||||||
|
tableData.loading = true;
|
||||||
|
await acPushEventDel(row.id);
|
||||||
|
ElNotification({
|
||||||
|
title: '注意',
|
||||||
|
message: '已删除',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
getTableData();
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页大小发生变化
|
||||||
|
function handleSizeChange(e) {
|
||||||
|
tableData.pageSize = e;
|
||||||
|
getTableData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页发生变化
|
||||||
|
function handleCurrentChange(e) {
|
||||||
|
tableData.page = e;
|
||||||
|
getTableData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取列表
|
||||||
|
const getTableData = async () => {
|
||||||
|
try {
|
||||||
|
tableData.loading = true;
|
||||||
|
const res = await acPushEventGet({
|
||||||
|
page: tableData.page,
|
||||||
|
size: tableData.size,
|
||||||
|
status: querForm.value.status
|
||||||
|
});
|
||||||
|
tableData.list = res.records;
|
||||||
|
tableData.total = res.totalRow;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
tableData.loading = false;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加模板,并且默认选中模板
|
||||||
|
function useTemplate(item) {
|
||||||
|
addTaskRef.value?.show(null, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
useTemplate
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTableData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.gyq_container {
|
||||||
|
padding: 14px;
|
||||||
|
|
||||||
|
.gyq_content {
|
||||||
|
padding: 14px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
padding-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -51,10 +51,7 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="选择门店" v-if="form.useType == 'part'">
|
<el-form-item label="选择门店" v-if="form.useType == 'part'">
|
||||||
<el-select v-model="form.shopIdList" multiple clearable placeholder="请选择门店" style="width: 300px">
|
<selectBranchs all v-model="form.shopIdList" />
|
||||||
<el-option :label="item.shopName" :value="item.id" v-for="item in branchList"
|
|
||||||
:key="item.id"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="自定义金额">
|
<el-form-item label="自定义金额">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
@@ -105,6 +102,7 @@
|
|||||||
import HeaderCard from "../components/headerCard.vue";
|
import HeaderCard from "../components/headerCard.vue";
|
||||||
import AddDialog from "./components/addDialog.vue";
|
import AddDialog from "./components/addDialog.vue";
|
||||||
import ChargeList from "@/views/user/charge/index.vue";
|
import ChargeList from "@/views/user/charge/index.vue";
|
||||||
|
import selectBranchs from "../components/selectBranchs.vue";
|
||||||
import { couponPage, getBranchPage, shopRecharge, shopRechargeGet } from "@/api/coupon/index.js";
|
import { couponPage, getBranchPage, shopRecharge, shopRechargeGet } from "@/api/coupon/index.js";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { ElNotification } from "element-plus";
|
import { ElNotification } from "element-plus";
|
||||||
|
|||||||
Reference in New Issue
Block a user