Merge branch 'new_gyq' of https://newgitea.sxczgkj.cn/czg_team/cashier_app into ymf
This commit is contained in:
commit
c6a1751e72
|
|
@ -1,44 +1,39 @@
|
||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
<up-checkbox-group
|
<up-checkbox-group v-model="useType" placement="row" shape="square" size="28rpx">
|
||||||
v-model="useType"
|
<up-checkbox v-for="item in dinetyps" :key="item.value" :name="item.value" :label="item.label" :customStyle="customStyle"></up-checkbox>
|
||||||
placement="row"
|
</up-checkbox-group>
|
||||||
shape="square"
|
</view>
|
||||||
size="28rpx"
|
|
||||||
>
|
|
||||||
<up-checkbox
|
|
||||||
:customStyle="{ marginRight: '16rpx' }"
|
|
||||||
v-for="item in dinetyps"
|
|
||||||
:key="item.value"
|
|
||||||
:name="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
></up-checkbox>
|
|
||||||
</up-checkbox-group>
|
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
const customStyle = ref({
|
||||||
|
marginRight: '15px'
|
||||||
|
});
|
||||||
|
|
||||||
// 可使用类型:dine堂食/pickup自取/deliv配送/express快递
|
// 可使用类型:dine堂食/pickup自取/deliv配送/express快递
|
||||||
const dinetyps = [
|
const dinetyps = [
|
||||||
{
|
{
|
||||||
value: "dine-in",
|
value: 'dine-in',
|
||||||
label: "堂食",
|
label: '堂食'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "take-out",
|
value: 'take-out',
|
||||||
label: "自取",
|
label: '自取'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "post",
|
value: 'post',
|
||||||
label: "配送",
|
label: '配送'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "take-away",
|
value: 'take-away',
|
||||||
label: "快递",
|
label: '快递'
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const useType = defineModel({
|
const useType = defineModel({
|
||||||
default: () => [],
|
default: () => [],
|
||||||
type: Array,
|
type: Array
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -43,6 +43,7 @@ const emits = defineEmits(['confirm', 'cancel']);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
z-index: 99;
|
||||||
padding: 10px 14px calc(20px + env(safe-area-inset-bottom) / 2) 10px;
|
padding: 10px 14px calc(20px + env(safe-area-inset-bottom) / 2) 10px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
.btn {
|
.btn {
|
||||||
|
|
|
||||||
|
|
@ -1,111 +1,97 @@
|
||||||
<template>
|
<template>
|
||||||
<view >
|
<view>
|
||||||
<up-radio-group v-model="useTimeType" placement="row">
|
<up-radio-group v-model="useTimeType" placement="row">
|
||||||
<up-radio
|
<up-radio v-for="item in useTimeTypeList" :key="item.value" :value="item.value" :name="item.value" :label="item.label" :customStyle="customStyle"></up-radio>
|
||||||
v-for="item in useTimeTypeList"
|
</up-radio-group>
|
||||||
:key="item.value"
|
<view class="u-flex u-m-t-30 box" v-if="useTimeType == 'custom'">
|
||||||
:value="item.value"
|
<view class="u-flex u-flex-1">
|
||||||
:name="item.value"
|
<view class="item" @click="pirckerShow(startValue, 'startValue')">
|
||||||
:label="item.label"
|
<text class="u-m-r-12" v-if="!startValue">开始时间</text>
|
||||||
></up-radio>
|
<text class="u-m-r-12" v-else>{{ startValue }}</text>
|
||||||
</up-radio-group>
|
</view>
|
||||||
|
<view class="u-m-l-8 u-m-r-8" style="padding: 0 30rpx">—</view>
|
||||||
<view class="u-flex u-m-t-30 box" v-if="useTimeType=='custom'">
|
<view class="item" @click="pirckerShow(endValue, 'endValue')">
|
||||||
<view class="u-flex u-flex-1">
|
<text class="u-m-r-12" v-if="!endValue">结束时间</text>
|
||||||
<view class="item " @click="pirckerShow(startValue, 'startValue')">
|
<text class="u-m-r-12" v-else>{{ endValue }}</text>
|
||||||
<text class="u-m-r-12" v-if="!startValue">开始时间</text>
|
</view>
|
||||||
<text class="u-m-r-12" v-else>{{ startValue }}</text>
|
</view>
|
||||||
</view>
|
<up-icon name="clock"></up-icon>
|
||||||
<view class="u-m-l-8 u-m-r-8" style="padding: 0 30rpx;">—</view>
|
</view>
|
||||||
<view class="item " @click="pirckerShow(endValue, 'endValue')">
|
<up-datetime-picker :show="show" v-model="value1" closeOnClickOverlay @close="close" @cancel="close" @confirm="confirm" mode="time"></up-datetime-picker>
|
||||||
<text class="u-m-r-12" v-if="!endValue">结束时间</text>
|
</view>
|
||||||
<text class="u-m-r-12" v-else>{{ endValue }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<up-icon name="clock"></up-icon>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<up-datetime-picker
|
|
||||||
:show="show"
|
|
||||||
v-model="value1"
|
|
||||||
closeOnClickOverlay
|
|
||||||
@close="close"
|
|
||||||
@cancel="close"
|
|
||||||
@confirm="confirm"
|
|
||||||
mode="time"
|
|
||||||
></up-datetime-picker>
|
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from 'vue';
|
||||||
const useTimeType = defineModel("useTimeType", {
|
|
||||||
type: String,
|
const customStyle = ref({
|
||||||
default: "all",
|
marginRight: '15px'
|
||||||
|
});
|
||||||
|
|
||||||
|
const useTimeType = defineModel('useTimeType', {
|
||||||
|
type: String,
|
||||||
|
default: 'all'
|
||||||
});
|
});
|
||||||
const useTimeTypeList = [
|
const useTimeTypeList = [
|
||||||
{
|
{
|
||||||
value: "all",
|
value: 'all',
|
||||||
label: "全时段可用",
|
label: '全时段可用'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "custom",
|
value: 'custom',
|
||||||
label: "指定时间段可用",
|
label: '指定时间段可用'
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
import dayjs from "dayjs";
|
import dayjs from 'dayjs';
|
||||||
const startValue = defineModel("startValue", {
|
const startValue = defineModel('startValue', {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: ''
|
||||||
});
|
});
|
||||||
const endValue = defineModel("endValue", {
|
const endValue = defineModel('endValue', {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
show.value = false;
|
show.value = false;
|
||||||
}
|
}
|
||||||
const value1 = ref('');
|
const value1 = ref('');
|
||||||
const show = ref(false);
|
const show = ref(false);
|
||||||
const nowKey = ref("");
|
const nowKey = ref('');
|
||||||
|
|
||||||
function pirckerShow(date, key) {
|
function pirckerShow(date, key) {
|
||||||
nowKey.value = key;
|
nowKey.value = key;
|
||||||
show.value = true;
|
show.value = true;
|
||||||
value1.value = date||''
|
value1.value = date || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirm(e) {
|
function confirm(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
|
||||||
if (nowKey.value == "startValue") {
|
if (nowKey.value == 'startValue') {
|
||||||
startValue.value=e.value
|
startValue.value = e.value;
|
||||||
} else if (nowKey.value == "endValue") {
|
} else if (nowKey.value == 'endValue') {
|
||||||
endValue.value = e.value;
|
endValue.value = e.value;
|
||||||
}
|
}
|
||||||
value1.value = e.value;
|
value1.value = e.value;
|
||||||
show.value = false;
|
show.value = false;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.item {
|
.item {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #666;
|
color: #666;
|
||||||
line-height: 48rpx;
|
line-height: 48rpx;
|
||||||
padding: 0 12rpx;
|
padding: 0 12rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
}
|
}
|
||||||
.box{
|
.box {
|
||||||
border: 2rpx solid #dddfe6;
|
border: 2rpx solid #dddfe6;
|
||||||
padding: 16rpx 30rpx;
|
padding: 16rpx 30rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 564rpx;
|
width: 564rpx;
|
||||||
border-radius: 4rpx;
|
border-radius: 4rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,316 @@
|
||||||
|
<template>
|
||||||
|
<view class="my-select-goods">
|
||||||
|
<view class="radio-wrap">
|
||||||
|
<u-radio-group v-model="foodType">
|
||||||
|
<u-radio v-for="item in radioList" :key="item.value" :label="item.label" :name="item.value" :customStyle="customStyle"></u-radio>
|
||||||
|
</u-radio-group>
|
||||||
|
</view>
|
||||||
|
<view class="selec-goods-card" @click="popupShow = true" v-if="foodType == 2">
|
||||||
|
<view class="title">
|
||||||
|
<text class="t">选择商品</text>
|
||||||
|
</view>
|
||||||
|
<view class="placeholder">
|
||||||
|
<view class="left">
|
||||||
|
<text class="placeholder-t" v-if="selectGoodsCount.length <= 0">请选择商品</text>
|
||||||
|
<text class="t" v-else>{{ selectGoodsCount.map((item) => item.name).join('、') }}</text>
|
||||||
|
</view>
|
||||||
|
<u-icon name="arrow-right" size="14px" color="#999"></u-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<u-popup :show="popupShow" :round="20" closeable @close="popupClosed">
|
||||||
|
<view class="popup-container">
|
||||||
|
<view class="title">
|
||||||
|
<text class="t">请选择</text>
|
||||||
|
</view>
|
||||||
|
<view class="goods-scroll-wrap">
|
||||||
|
<view class="left">
|
||||||
|
<scroll-view scroll-y class="scroll-view">
|
||||||
|
<view
|
||||||
|
class="category-item"
|
||||||
|
v-for="(item, index) in categorys"
|
||||||
|
:key="item.id"
|
||||||
|
:class="{ active: categorysIndex == index }"
|
||||||
|
@click="changeCategorys(item, index)"
|
||||||
|
>
|
||||||
|
<text class="t">{{ item.name }}</text>
|
||||||
|
<text class="t" v-if="item.selectedNum > 0">({{ item.selectedNum }})</text>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
<view class="right">
|
||||||
|
<scroll-view scroll-y class="scroll-view">
|
||||||
|
<view class="goods-item" v-for="(item, index) in categorys[categorysIndex].goods" :key="item.id" @click="selectGoods(item, index)">
|
||||||
|
<view class="name">
|
||||||
|
<text class="t">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="selec-btn">
|
||||||
|
<u-icon name="checkmark-circle-fill" color="#318afe" size="18" v-if="item.selected"></u-icon>
|
||||||
|
<view class="circle" v-else></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="footer">
|
||||||
|
<view class="btn">
|
||||||
|
<u-button type="primary" size="large" @click="confirmHandle">
|
||||||
|
确定
|
||||||
|
<template v-if="countNum > 0">({{ countNum }})</template>
|
||||||
|
</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { getCategoryList, getProductList } from '@/http/api/product.js';
|
||||||
|
|
||||||
|
const popupShow = ref(false);
|
||||||
|
|
||||||
|
const modelValue = defineModel({
|
||||||
|
type: [String, Array],
|
||||||
|
default: []
|
||||||
|
});
|
||||||
|
|
||||||
|
const customStyle = ref({
|
||||||
|
marginRight: '20px'
|
||||||
|
});
|
||||||
|
|
||||||
|
const radioList = ref([
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: '全部商品参与'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
label: '部分商品参与'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const foodType = defineModel('foodType', {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
const categorys = ref([]);
|
||||||
|
const categorysIndex = ref(0);
|
||||||
|
|
||||||
|
// 切换分类
|
||||||
|
function changeCategorys(item, index) {
|
||||||
|
categorysIndex.value = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取商品分类
|
||||||
|
async function getCategoryListAjax() {
|
||||||
|
try {
|
||||||
|
categorys.value = await getCategoryList();
|
||||||
|
categorys.value.forEach((item) => {
|
||||||
|
item.goods = [];
|
||||||
|
item.selectedNum = 0;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const goods = ref([]);
|
||||||
|
|
||||||
|
function selectGoods(item, index) {
|
||||||
|
item.selected = !item.selected;
|
||||||
|
updateSelectGoods();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在这个方法里更新已选择的数量和商品
|
||||||
|
const countNum = ref(0);
|
||||||
|
function updateSelectGoods() {
|
||||||
|
countNum.value = 0;
|
||||||
|
categorys.value.forEach((item) => {
|
||||||
|
let num = 0;
|
||||||
|
item.goods.forEach((val) => {
|
||||||
|
if (val.selected) {
|
||||||
|
num++;
|
||||||
|
countNum.value++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
item.selectedNum = num;
|
||||||
|
});
|
||||||
|
confirmSelectGoods;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确定
|
||||||
|
const foods = defineModel('foods', {
|
||||||
|
type: [Array, String],
|
||||||
|
default: []
|
||||||
|
});
|
||||||
|
function confirmHandle() {
|
||||||
|
confirmSelectGoods();
|
||||||
|
popupShow.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击确定更新已选择的商品
|
||||||
|
const selectGoodsCount = ref([]);
|
||||||
|
function confirmSelectGoods() {
|
||||||
|
selectGoodsCount.value = [];
|
||||||
|
categorys.value.forEach((item) => {
|
||||||
|
item.goods.forEach((val) => {
|
||||||
|
if (val.selected) {
|
||||||
|
selectGoodsCount.value.push(val);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
foods.value = selectGoodsCount.value.map((item) => item.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取商品列表
|
||||||
|
async function getProductListAjax() {
|
||||||
|
try {
|
||||||
|
const res = await getProductList();
|
||||||
|
res.forEach((item, index) => {
|
||||||
|
console.log('modelValue.value===', modelValue.value);
|
||||||
|
console.log('index===', item.id.includes(modelValue.value));
|
||||||
|
if (modelValue.value.includes(item.id)) {
|
||||||
|
item.selected = true;
|
||||||
|
} else {
|
||||||
|
item.selected = false;
|
||||||
|
}
|
||||||
|
categorys.value.forEach((val, i) => {
|
||||||
|
if (val.id == item.categoryId) {
|
||||||
|
val.goods.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
updateSelectGoods();
|
||||||
|
confirmSelectGoods();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// popup关闭
|
||||||
|
function popupClosed() {
|
||||||
|
popupShow.value = false;
|
||||||
|
// countNum.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await getCategoryListAjax();
|
||||||
|
await getProductListAjax();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.my-select-goods {
|
||||||
|
.selec-goods-card {
|
||||||
|
margin-top: 20upx;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
border-radius: 10upx;
|
||||||
|
padding: 20upx;
|
||||||
|
.ttile {
|
||||||
|
.t {
|
||||||
|
font-size: 28upx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.placeholder {
|
||||||
|
display: flex;
|
||||||
|
padding-top: 12upx;
|
||||||
|
.left {
|
||||||
|
flex: 1;
|
||||||
|
.placeholder-t {
|
||||||
|
font-size: 28upx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.popup-container {
|
||||||
|
$color: #318afe;
|
||||||
|
.title {
|
||||||
|
padding: 28upx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
.t {
|
||||||
|
font-size: 32upx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.goods-scroll-wrap {
|
||||||
|
width: 100%;
|
||||||
|
height: 50vh;
|
||||||
|
display: flex;
|
||||||
|
.left {
|
||||||
|
width: 240upx;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.scroll-view {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.category-item {
|
||||||
|
width: 100%;
|
||||||
|
height: 84upx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 38upx;
|
||||||
|
&.active {
|
||||||
|
background-color: #fff;
|
||||||
|
position: relative;
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
width: 8upx;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: $color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.t {
|
||||||
|
font-size: 32upx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.goods-item {
|
||||||
|
height: 84upx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 28upx;
|
||||||
|
.name {
|
||||||
|
.t {
|
||||||
|
font-size: 32upx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.selec-btn {
|
||||||
|
$size: 32upx;
|
||||||
|
width: $size;
|
||||||
|
height: $size;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.circle {
|
||||||
|
width: $size;
|
||||||
|
height: $size;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
padding: 28upx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -18,10 +18,21 @@ export function limitTimeDiscountPage(data) {
|
||||||
* 删除限时折扣
|
* 删除限时折扣
|
||||||
* @param {Object} data
|
* @param {Object} data
|
||||||
*/
|
*/
|
||||||
export function limitTimeDiscountDel(params) {
|
export function limitTimeDiscountDel(id) {
|
||||||
return request({
|
return request({
|
||||||
url: `${urlType}/admin/limitTimeDiscount`,
|
url: `${urlType}/admin/limitTimeDiscount?id=${id}`,
|
||||||
method: "DELETE",
|
method: "DELETE"
|
||||||
params
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限时折扣-新增/编辑
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
export function limitTimeDiscount(data) {
|
||||||
|
return request({
|
||||||
|
url: `${urlType}/admin/limitTimeDiscount`,
|
||||||
|
method: data.id ? 'put' : 'post',
|
||||||
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -5,14 +5,19 @@
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bignumber.js": "^9.3.1",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"gm-crypto": "^0.1.8",
|
"gm-crypto": "^0.1.8",
|
||||||
"immutable": "^4.3.7",
|
"immutable": "^4.3.7",
|
||||||
"js-base64": "^3.7.2",
|
"js-base64": "^3.7.2",
|
||||||
|
"jsbn": "^1.1.0",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"uview-plus": "^3.3.32"
|
"pinia-plugin-unistorage": "^0.1.2",
|
||||||
|
"to-arraybuffer": "^1.0.1",
|
||||||
|
"uview-plus": "^3.3.32",
|
||||||
|
"ysk-utils": "^1.0.78"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"copy-webpack-plugin": "^12.0.2",
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
|
|
@ -450,6 +455,14 @@
|
||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bignumber.js": {
|
||||||
|
"version": "9.3.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.3.1.tgz",
|
||||||
|
"integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
"resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||||
|
|
@ -1071,6 +1084,12 @@
|
||||||
"node": ">=8.9.0"
|
"node": ">=8.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/loadsh": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/loadsh/-/loadsh-0.0.4.tgz",
|
||||||
|
"integrity": "sha512-U+wLL8InpfRalWrr+0SuhWgGt10M4OyAk6G8xCYo2rwpiHtxZkWiFpjei0vO463ghW8LPCdhqQxXlMy2qicAEw==",
|
||||||
|
"deprecated": "This is a typosquat on the popular Lodash package. This is not maintained nor is the original Lodash package."
|
||||||
|
},
|
||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
|
||||||
|
|
@ -1181,6 +1200,11 @@
|
||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pinia-plugin-unistorage": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/pinia-plugin-unistorage/-/pinia-plugin-unistorage-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-WXit2cGnm5rG6CDTcLSLehNWhyJS/Yq7WEeeXAapZbCnqoPJxlszqg7rT8S+OP47az0h5nlajGo+LuyMxUQ2uw=="
|
||||||
|
},
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
|
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
|
||||||
|
|
@ -1726,6 +1750,16 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ysk-utils": {
|
||||||
|
"version": "1.0.78",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ysk-utils/-/ysk-utils-1.0.78.tgz",
|
||||||
|
"integrity": "sha512-Bgr5B3WWiy0nbgL91QVKoVPYm4wt13Rlav757zEjMVRHbmTjwFEhi3wJlYus0JGd52mbknSxXHMazAPHXwA7uQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"bignumber.js": "^9.3.1",
|
||||||
|
"loadsh": "^0.0.4",
|
||||||
|
"lodash": "^4.17.21"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
<template>
|
|
||||||
<view class="fixed-wrap" :style="{ '--num': showCancel ? '63px' : '0px' }">
|
|
||||||
<view class="fixed-btn" id="targetRef">
|
|
||||||
<div class="btn">
|
|
||||||
<u-button type="primary" :shape="shape" size="large" @click="emits('confirm')">{{ confirmText }}</u-button>
|
|
||||||
</div>
|
|
||||||
<div class="btn" v-if="showCancel">
|
|
||||||
<u-button :shape="shape" size="large" @click="emits('cancel')">取消</u-button>
|
|
||||||
</div>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted, nextTick, getCurrentInstance } from 'vue';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
confirmText: {
|
|
||||||
type: String,
|
|
||||||
default: '添加'
|
|
||||||
},
|
|
||||||
showCancel: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
shape: {
|
|
||||||
type: String,
|
|
||||||
default: 'squre' // squre circle
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const emits = defineEmits(['confirm', 'cancel']);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.fixed-wrap {
|
|
||||||
--height: calc(83px + var(--num) + env(safe-area-inset-bottom) / 2);
|
|
||||||
width: 100%;
|
|
||||||
height: var(--height);
|
|
||||||
.fixed-btn {
|
|
||||||
width: 100%;
|
|
||||||
height: var(--height);
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
padding: 10px 14px calc(20px + env(safe-area-inset-bottom) / 2) 10px;
|
|
||||||
background-color: #fff;
|
|
||||||
.btn {
|
|
||||||
&:first-child {
|
|
||||||
margin-bottom: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
<template>
|
|
||||||
<view class="item-doc" :style="{ height: headHeight + 'px' }">
|
|
||||||
<view class="item" :style="{ height: headHeight + 'px' }">
|
|
||||||
<view class="left">
|
|
||||||
<image :src="`/static/applocation/${options.icon}.png`" mode="aspectFit" class="icon"></image>
|
|
||||||
<view class="info">
|
|
||||||
<view class="title">
|
|
||||||
<text class="t">{{ options.name }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="intro">
|
|
||||||
<text class="t">{{ options.intro }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="right" v-if="showSwitch">
|
|
||||||
<u-switch :active-value="1" :inactive-value="0" v-model="isOpen"></u-switch>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted, nextTick } from 'vue';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
options: {
|
|
||||||
type: Object,
|
|
||||||
default: {
|
|
||||||
name: '标题',
|
|
||||||
intro: '说明',
|
|
||||||
icon: 'xszk'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showSwitch: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const headHeight = ref(70);
|
|
||||||
|
|
||||||
const isOpen = defineModel('isOpen', {
|
|
||||||
type: [Boolean, String, Number],
|
|
||||||
default: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
const emits = defineEmits(['load']);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
emits('load', { height: headHeight.value });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.item-doc {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.item {
|
|
||||||
width: 100%;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 99;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 20upx 28upx;
|
|
||||||
.left {
|
|
||||||
display: flex;
|
|
||||||
.icon {
|
|
||||||
$size: 80upx;
|
|
||||||
width: $size;
|
|
||||||
height: $size;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
.info {
|
|
||||||
display: flex;
|
|
||||||
padding-left: 20upx;
|
|
||||||
flex-direction: column;
|
|
||||||
.title {
|
|
||||||
.t {
|
|
||||||
font-size: 28upx;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.intro {
|
|
||||||
.t {
|
|
||||||
font-size: 28upx;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<u-form label-position="top" labelWidth="100" :model="form" :rules="rules" ref="formRef">
|
<u-form label-position="top" labelWidth="200" :model="form" :rules="rules" ref="formRef">
|
||||||
<view class="card">
|
<view class="card">
|
||||||
<u-form-item label="活动名称" prop="title">
|
<u-form-item label="活动名称" prop="title">
|
||||||
<u-input placeholder="请输入活动名称" v-model="form.title" border="bottom" :customStyle="inputStyle"></u-input>
|
<u-input placeholder="请输入活动名称" v-model="form.title" border="bottom" :customStyle="inputStyle"></u-input>
|
||||||
|
|
@ -10,7 +10,52 @@
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="card">
|
<view class="card">
|
||||||
<u-form-item label="活动日期" prop="validStartTime"></u-form-item>
|
<u-form-item label="活动日期" prop="validStartTime">
|
||||||
|
<my-time-area v-model:startDate="form.validStartTime" v-model:endDate="form.validEndTime"></my-time-area>
|
||||||
|
</u-form-item>
|
||||||
|
<u-form-item label="可用日期" prop="useDays">
|
||||||
|
<my-week-sel v-model="form.useDays"></my-week-sel>
|
||||||
|
</u-form-item>
|
||||||
|
<u-form-item label="指定时间段可用" prop="useTimeType">
|
||||||
|
<my-hour-area v-model:useTimeType="form.useTimeType" v-model:startValue="form.useStartTime" v-model:endValue="form.useEndTime"></my-hour-area>
|
||||||
|
</u-form-item>
|
||||||
|
</view>
|
||||||
|
<view class="card">
|
||||||
|
<u-form-item label="可使用类型" prop="useType">
|
||||||
|
<my-dine-types v-model="form.useType"></my-dine-types>
|
||||||
|
</u-form-item>
|
||||||
|
</view>
|
||||||
|
<view class="card">
|
||||||
|
<u-form-item label="折扣" prop="discountRate">
|
||||||
|
<view class="center">
|
||||||
|
<u-input placeholder="请输入折扣" type="number" v-model="form.discountRate" @change="discountRateInput">
|
||||||
|
<template v-slot:suffix>%</template>
|
||||||
|
</u-input>
|
||||||
|
<text class="red-tips">范围:1-99%</text>
|
||||||
|
</view>
|
||||||
|
<view class="tips">
|
||||||
|
<text class="t">例如:填写90,那么折扣后价格=原价*90%</text>
|
||||||
|
</view>
|
||||||
|
</u-form-item>
|
||||||
|
<u-form-item label="优先级">
|
||||||
|
<view class="center">
|
||||||
|
<u-input placeholder="默认值:0" v-model="form.sort"></u-input>
|
||||||
|
</view>
|
||||||
|
<view class="tips">
|
||||||
|
<text class="red-tips">数值越大,排序越靠前。重复时段下,按照排序值最高的折扣使用</text>
|
||||||
|
</view>
|
||||||
|
</u-form-item>
|
||||||
|
<u-form-item label="限时折扣优先级">
|
||||||
|
<u-radio-group v-model="form.discountPriority" placement="column">
|
||||||
|
<u-radio label="优先使用限时折扣价" name="limit-time"></u-radio>
|
||||||
|
<u-radio label="优先使用会员价/会员折扣" name="vip-price"></u-radio>
|
||||||
|
</u-radio-group>
|
||||||
|
</u-form-item>
|
||||||
|
</view>
|
||||||
|
<view class="card">
|
||||||
|
<u-form-item label="参与商品" prop="foodType">
|
||||||
|
<my-select-goods v-model:foodType="form.foodType" v-model="form.foods"></my-select-goods>
|
||||||
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
<my-footer-btn confirmText="保存" @confirm="submitHandle"></my-footer-btn>
|
<my-footer-btn confirmText="保存" @confirm="submitHandle"></my-footer-btn>
|
||||||
|
|
@ -18,8 +63,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||||
|
dayjs.extend(customParseFormat); // 注册插件
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import FooterBtn from '../components/FooterBtn.vue';
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { filterNumberInput } from '@/utils/index.js';
|
||||||
|
import { limitTimeDiscount } from '@/http/api/market/index.js';
|
||||||
|
|
||||||
const inputStyle = ref({
|
const inputStyle = ref({
|
||||||
paddingLeft: 0
|
paddingLeft: 0
|
||||||
|
|
@ -32,20 +82,19 @@ const form = ref({
|
||||||
shopId: '',
|
shopId: '',
|
||||||
title: '', // 活动名称
|
title: '', // 活动名称
|
||||||
useShopType: 'only', // only-仅本店 all全部 /custom 指定
|
useShopType: 'only', // only-仅本店 all全部 /custom 指定
|
||||||
useShops: '', // 可用门店
|
useShops: [], // 可用门店
|
||||||
validStartTime: '', // 有效期开始时间
|
validStartTime: '', // 有效期开始时间
|
||||||
validEndTime: '', // 有效期结束时间
|
validEndTime: '', // 有效期结束时间
|
||||||
useDays: '', // 周一,周二,周三,周四,周五,周六,周日
|
useDays: ['周一', '周二', '周三'], // 周一,周二,周三,周四,周五,周六,周日
|
||||||
useTimeType: '', // all-全时段,custom-指定时段
|
useTimeType: 'all', // all-全时段,custom-指定时段
|
||||||
useStartTime: '', // 可用开始时间
|
useStartTime: '', // 可用开始时间
|
||||||
useEndTime: '', // 可用结束时间
|
useEndTime: '', // 可用结束时间
|
||||||
useType: '', // 堂食 dine-in 外带 take-out 外卖 take-away 配送 post
|
useType: ['dine-in', 'take-out'], // 堂食 dine-in 外带 take-out 外卖 take-away 配送 post
|
||||||
discountRate: '', // 折扣% 范围1-99
|
discountRate: '', // 折扣% 范围1-99
|
||||||
sort: '', // 数字越小级别越高
|
sort: '', // 数字越小级别越高
|
||||||
discountPriority: '', // 折扣优先级 限时折扣优先limit-time/会员价优先vip-price
|
discountPriority: 'limit-time', // 折扣优先级 限时折扣优先limit-time/会员价优先vip-price
|
||||||
foodType: '', // 1全部 2部分
|
foodType: 1, // 1全部 2部分
|
||||||
foods: '', // 参与商品
|
foods: [] // 参与商品
|
||||||
status: '' // 1未开始,2进行中,3已结束 -1当前时间不可用
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const rules = ref({
|
const rules = ref({
|
||||||
|
|
@ -54,17 +103,206 @@ const rules = ref({
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入活动名称',
|
message: '请输入活动名称',
|
||||||
trigger: ['blur']
|
trigger: ['blur']
|
||||||
}
|
},
|
||||||
|
useShops: [
|
||||||
|
{
|
||||||
|
trigger: ['change'],
|
||||||
|
message: '请选择可用门店',
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (form.value.useShopType == 'custom' && form.value.useShops.length == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
validStartTime: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
trigger: ['change'],
|
||||||
|
message: '请选择活动日期',
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (form.value.validStartTime.length == 0 || form.value.validEndTime.length == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
useDays: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择可用日期',
|
||||||
|
trigger: ['change'],
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (form.value.useDays.length == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
useTimeType: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
trigger: ['change'],
|
||||||
|
message: '请选择活动日期',
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (form.value.useTimeType == 'custom' && (form.value.useStartTime.length == 0 || form.value.useEndTime.length == 0)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
useType: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择可使用类型',
|
||||||
|
trigger: ['change'],
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (form.value.useType.length == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
discountRate: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
type: 'string',
|
||||||
|
message: '请输入折扣',
|
||||||
|
trigger: ['blur'],
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (form.value.discountRate == '') {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
foodType: [
|
||||||
|
{
|
||||||
|
trigger: ['change'],
|
||||||
|
message: '请选择商品',
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (form.value.foodType == 2 && form.value.foods.length == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 输入折扣率
|
||||||
|
function discountRateInput(e) {
|
||||||
|
setTimeout(() => {
|
||||||
|
form.value.discountRate = filterNumberInput(e, 1);
|
||||||
|
if (form.value.discountRate > 99) {
|
||||||
|
form.value.discountRate = 99;
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间格式互转:HH:mm → HH:mm:ss;HH:mm:ss → HH:mm
|
||||||
|
* @param {string} timeStr - 输入的时间字符串
|
||||||
|
* @returns {string} 转换后的时间字符串
|
||||||
|
*/
|
||||||
|
const convertTimeFormat = (timeStr) => {
|
||||||
|
if (!timeStr) return '00:00';
|
||||||
|
|
||||||
|
// 正则判断格式
|
||||||
|
const isHms = /^\d{1,2}:\d{2}:\d{2}$/.test(timeStr); // HH:mm:ss
|
||||||
|
const isHm = /^\d{1,2}:\d{2}$/.test(timeStr); // HH:mm
|
||||||
|
|
||||||
|
if (isHm) {
|
||||||
|
// HH:mm → 解析后格式化为 HH:mm:ss
|
||||||
|
return dayjs(timeStr, 'HH:mm').format('HH:mm:ss');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHms) {
|
||||||
|
// HH:mm:ss → 解析后格式化为 HH:mm
|
||||||
|
return dayjs(timeStr, 'HH:mm:ss').format('HH:mm');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非法格式兜底
|
||||||
|
return '00:00';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交保存
|
||||||
function submitHandle() {
|
function submitHandle() {
|
||||||
|
// console.log('前置form', form.value);
|
||||||
formRef.value
|
formRef.value
|
||||||
.validate()
|
.validate()
|
||||||
.then((res) => {
|
.then(async (res) => {
|
||||||
console.log('通过了', res);
|
try {
|
||||||
|
const data = { ...form.value };
|
||||||
|
|
||||||
|
console.log('通过了', data);
|
||||||
|
data.shopId = uni.getStorageSync('shopInfo').id;
|
||||||
|
data.useShops = form.value.useShops.join(',');
|
||||||
|
data.useDays = form.value.useDays.join(',');
|
||||||
|
data.useType = form.value.useType.join(',');
|
||||||
|
data.foods = form.value.foods.join(',');
|
||||||
|
data.useStartTime = convertTimeFormat(form.value.useStartTime);
|
||||||
|
data.useEndTime = convertTimeFormat(form.value.useEndTime);
|
||||||
|
|
||||||
|
uni.showLoading({
|
||||||
|
title: '提交中...',
|
||||||
|
mask: true
|
||||||
|
});
|
||||||
|
await limitTimeDiscount(data);
|
||||||
|
uni.showToast({
|
||||||
|
title: '添加成功',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack();
|
||||||
|
}, 1000);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.hideLoading();
|
||||||
|
}, 500);
|
||||||
})
|
})
|
||||||
.catch((err) => {});
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 从本地获取限时折扣信息
|
||||||
|
function getLocalLimitDiscount() {
|
||||||
|
const data = uni.getStorageSync('limitDiscountObj');
|
||||||
|
if (data.id) {
|
||||||
|
// uni.setStorageSync('limitDiscountObj', '');
|
||||||
|
data.useShops = data.useShops.split(',');
|
||||||
|
data.useDays = data.useDays.split(',');
|
||||||
|
data.useType = data.useType.split(',');
|
||||||
|
data.foods = data.foods.split(',');
|
||||||
|
|
||||||
|
if (data.useStartTime) {
|
||||||
|
data.useStartTime = convertTimeFormat(data.useStartTime);
|
||||||
|
data.useEndTime = convertTimeFormat(data.useEndTime);
|
||||||
|
}
|
||||||
|
console.log('从本地获取限时折扣信息', data);
|
||||||
|
form.value = { ...data };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getLocalLimitDiscount();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
@ -81,5 +319,22 @@ page {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 20upx;
|
border-radius: 20upx;
|
||||||
padding: 0 28upx 14upx;
|
padding: 0 28upx 14upx;
|
||||||
|
margin-bottom: 28upx;
|
||||||
|
}
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 28upx;
|
||||||
|
}
|
||||||
|
.red-tips {
|
||||||
|
font-size: 28upx;
|
||||||
|
color: #eb4f4f;
|
||||||
|
}
|
||||||
|
.tips {
|
||||||
|
padding-top: 8upx;
|
||||||
|
.t {
|
||||||
|
font-size: 28upx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,10 @@
|
||||||
<u-tag :type="statusFilter(item.status, 'type')" plain :text="statusFilter(item.status, 'label')"></u-tag>
|
<u-tag :type="statusFilter(item.status, 'type')" plain :text="statusFilter(item.status, 'label')"></u-tag>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="row">
|
||||||
|
<text class="b">活动名称:</text>
|
||||||
|
<text class="t">{{ item.title }}</text>
|
||||||
|
</view>
|
||||||
<view class="row">
|
<view class="row">
|
||||||
<text class="b">活动时间:</text>
|
<text class="b">活动时间:</text>
|
||||||
<text class="t">{{ item.updateTime }}</text>
|
<text class="t">{{ item.updateTime }}</text>
|
||||||
|
|
@ -26,7 +30,7 @@
|
||||||
<u-button @click="delHandle(item)">删除</u-button>
|
<u-button @click="delHandle(item)">删除</u-button>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
<u-button type="primary">编辑</u-button>
|
<u-button type="primary" @click="editorHandle(item)">编辑</u-button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -38,12 +42,16 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
|
import { onLoad, onShow, onReachBottom } from '@dcloudio/uni-app';
|
||||||
import HeaderCard from '../components/HeaderCard.vue';
|
import { limitTimeDiscountPage, limitTimeDiscountDel } from '@/http/api/market/index.js';
|
||||||
import FooterBtn from '../components/FooterBtn.vue';
|
|
||||||
import { limitTimeDiscountPage } from '@/http/api/market/index.js';
|
|
||||||
import go from '@/commons/utils/go.js';
|
import go from '@/commons/utils/go.js';
|
||||||
|
|
||||||
|
// 去编辑
|
||||||
|
function editorHandle(item) {
|
||||||
|
uni.setStorageSync('limitDiscountObj', item);
|
||||||
|
go.to('PAGES_LIMIT_DISCOUNT_ADD');
|
||||||
|
}
|
||||||
|
|
||||||
// 删除限时折扣
|
// 删除限时折扣
|
||||||
function delHandle(item) {
|
function delHandle(item) {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
|
|
@ -56,7 +64,7 @@ function delHandle(item) {
|
||||||
title: '删除中...',
|
title: '删除中...',
|
||||||
mask: true
|
mask: true
|
||||||
});
|
});
|
||||||
await limitTimeDiscountDel({ id: item.id });
|
await limitTimeDiscountDel(item.id);
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '删除成功',
|
title: '删除成功',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
|
|
@ -128,7 +136,7 @@ async function limitTimeDiscountPageAjax() {
|
||||||
} else {
|
} else {
|
||||||
tableData.list.push(...res.records);
|
tableData.list.push(...res.records);
|
||||||
}
|
}
|
||||||
if (res.totalPage == res.totalRow) {
|
if (res.pageNumber == res.totalPage) {
|
||||||
tableData.status = 'nomore';
|
tableData.status = 'nomore';
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -136,9 +144,12 @@ async function limitTimeDiscountPageAjax() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoad(() => {
|
onShow(() => {
|
||||||
|
tableData.page = 1;
|
||||||
limitTimeDiscountPageAjax();
|
limitTimeDiscountPageAjax();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onLoad(() => {});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
@ -156,12 +167,16 @@ page {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
padding: 20upx;
|
padding: 20upx;
|
||||||
border-radius: 20upx;
|
border-radius: 20upx;
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-top: 28upx;
|
||||||
|
}
|
||||||
.head {
|
.head {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
.left {
|
.left {
|
||||||
.t {
|
.t {
|
||||||
color: #999;
|
color: #999;
|
||||||
|
font-size: 28upx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* 过滤输入,只允许数字和最多两位小数
|
||||||
|
* @param {string} value - 输入框当前值
|
||||||
|
* @param {boolean} isIntegerOnly - 是否只允许正整数(无小数点),开启时最小值为1,或为传入的值
|
||||||
|
* @returns {string} 过滤后的合法值
|
||||||
|
*/
|
||||||
|
export function filterNumberInput(value, isIntegerOnly = false) {
|
||||||
|
// 第一步就过滤所有非数字和非小数点的字符(包括字母)
|
||||||
|
let filtered = value.replace(/[^\d.]/g, "");
|
||||||
|
|
||||||
|
// 整数模式处理
|
||||||
|
if (isIntegerOnly !== false) {
|
||||||
|
// 移除所有小数点
|
||||||
|
filtered = filtered.replace(/\./g, "");
|
||||||
|
|
||||||
|
// 处理前导零
|
||||||
|
filtered = filtered.replace(/^0+(\d)/, "$1") || filtered;
|
||||||
|
|
||||||
|
// 空值处理(允许临时删除)
|
||||||
|
if (filtered === "") {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最小值限制
|
||||||
|
if (filtered === isIntegerOnly || parseInt(filtered, 10) < isIntegerOnly) {
|
||||||
|
return isIntegerOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 小数模式处理
|
||||||
|
const parts = filtered.split(".");
|
||||||
|
if (parts.length > 1) {
|
||||||
|
filtered = parts[0] + "." + (parts[1].substring(0, 2) || "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理前导零
|
||||||
|
if (filtered.startsWith("0") && filtered.length > 1 && !filtered.startsWith("0.")) {
|
||||||
|
filtered = filtered.replace(/^0+(\d)/, "$1");
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue