增加聊天功能

This commit is contained in:
2025-12-04 17:14:47 +08:00
parent ca829d7f00
commit 6f1185be3a
25 changed files with 2504 additions and 2 deletions

View File

@@ -0,0 +1,152 @@
<template>
<text class="" v-if="item.msg_type == 1">{{ item.content }}</text>
<image
v-if="item.msg_type == 2"
:src="item.image_url"
class="img"
mode="widthFix"
@click="previewImage(item.image_url)"
></image>
<video
@error="videoErrorCallback"
v-if="item.msg_type == 5"
:src="item.image_url"
class="img"
mode="widthFix"
@click="previewVideo(item.video_url)"
></video>
<view class="" v-if="item.msg_type == 4">
<view>{{ item.coupon.title }}</view>
<view class="u-m-t-16 bg-f7 coupon u-flex" style="min-width: 500rpx;">
<template v-if="item.coupon.type == 1">
<view class="left">
<view class="price">
<text class="u-font-32">¥</text>
<text style="font-size: 72rpx">{{
item.coupon.discountAmount
}}</text>
</view>
<view class="u-font-24 color-999 no-wrap"
>{{ item.coupon.fullAmount }}可用</view
>
</view>
</template>
<template v-if="item.coupon.type == 2">
<view class="left">
<view class="price">
<text class="u-font-32"
>商品兑换券</text
>
</view>
<view class="u-font-24 color-999 no-wrap"
>{{ item.coupon.fullAmount }}可用</view
>
</view>
</template>
<template v-if="item.coupon.type == 3">
<view class="left">
<view class="price">
<text class="u-font-32"
>{{ item.coupon.discountRate / 100 }}</text
>
</view>
<view class="u-font-24 color-999 no-wrap"
>{{ item.coupon.fullAmount }}可用</view
>
</view>
</template>
<template v-if="item.coupon.type == 4">
<view class="left">
<view class="price">
<text class="u-font-32"
>第二件半价券</text
>
</view>
</view>
</template>
<template v-if="item.coupon.type == 6">
<view class="left">
<view class="price">
<text class="u-font-32"
>买一送一券</text
>
</view>
</view>
</template>
<view class="right u-p-l-28">
<view class="u-font-32">{{ item.coupon.couponName }}</view>
<view class="u-font-24 color-999 u-m-t-8"
>有效期{{ returnTime(item.coupon) }}</view
>
</view>
</view>
<view class="u-flex u-row-center u-m-t-32">
<!-- <view class="lingqu hasGet" v-if="item.coupon_claim">已领取</view> -->
<view class="lingqu" @click="getCoupon()" >领取</view>
</view>
</view>
</template>
<script setup>
const props = defineProps({
item: {
type: Object,
default: () => {},
},
});
const emits = defineEmits(["getCoupon"]);
function getCoupon() {
emits("getCoupon", props.item);
}
function previewImage(url) {
uni.previewImage({
urls: [url],
});
}
function returnTime(coupon){
let startTime = coupon.useStartTime;
let endTime = coupon.useEndTime;
if(startTime && endTime){
return startTime.split(' ')[0] + '-' + endTime.split(' ')[0]
}
}
</script>
<style lang="scss" scoped>
.img {
width: 50vw;
}
.coupon {
padding: 16rpx 10rpx;
border-radius: 16rpx;
.price {
color: #ff1c1c;
font-weight: 700;
}
.left {
width: 112rpx;
margin-right: 26rpx;
}
.right {
border-left: 1rpx solid #ededed;
}
}
.lingqu {
background-color: #e8ad7b;
line-height: 48rpx;
font-size: 28rpx;
padding: 6rpx 70rpx;
color: #fff;
border-radius: 140rpx;
&.hasGet {
background-color: #eee;
color: #999;
}
}
</style>

View File

@@ -0,0 +1,108 @@
<template>
<view>
<view @click="open">
<slot v-if="$slots.default"> </slot>
<view v-else class="choose-goods u-flex u-row-between">
<text class="color-999" v-if="!startTime && !endTime"
>请选择日期范围</text
>
<text class="color-333 u-font-24 u-m-r-32 " v-else
>{{ startTime }} - {{ endTime }}</text
>
<view class="u-flex" v-if="startTime&&endTime" @click.stop="clear">
<up-icon name="close" size="14"></up-icon>
</view>
<up-icon size="14" name="arrow-right" v-else ></up-icon>
</view>
</view>
<my-date-pickerview
@confirm="datePickerConfirm"
mode="all"
ref="datePicker"
></my-date-pickerview>
</view>
</template>
<script setup>
import { ref } from "vue";
const datePicker = ref(null);
const startTime = defineModel("startTime", {
default: () => "",
type: String,
});
const endTime = defineModel("endTime", {
default: () => "",
type: String,
});
function clear(){
startTime.value = "";
endTime.value = "";
}
function open() {
datePicker.value.toggle();
}
function datePickerConfirm(e) {
startTime.value = e.start;
endTime.value = e.end;
console.log(e);
}
</script>
<style lang="scss">
.popup-content {
background: #fff;
width: 640rpx;
border-radius: 18rpx;
}
.top {
padding: 40rpx 48rpx;
border-bottom: 1px solid #d9d9d9;
}
.bottom {
padding: 48rpx 52rpx;
display: flex;
justify-content: space-between;
border-top: 1px solid #d9d9d9;
gap: 50rpx;
.btn {
flex: 1;
text-align: center;
padding: 18rpx 60rpx;
border-radius: 100rpx;
font-size: 32rpx;
border: 2rpx solid transparent;
&.success {
background-color: $my-main-color;
color: #fff;
}
&.cancel {
border-color: #d9d9d9;
box-shadow: 0 4rpx 0 0 #00000005;
}
}
}
.item {
padding: 10rpx 30rpx;
border: 1px solid #d9d9d9;
margin: 10rpx;
border-radius: 8rpx;
transition: all 0.3s ease-in-out;
box-shadow: 0 0 10px transparent;
&.selected {
border-color: $my-main-color;
box-shadow: 0 0 10px $my-main-color;
}
}
.choose-goods {
display: flex;
padding: 24rpx;
align-items: center;
border-radius: 8rpx;
border: 2rpx solid #d9d9d9;
background: #fff;
font-size: 28rpx;
font-weight: 400;
min-height: 90rpx;
}
</style>

View File

@@ -0,0 +1,85 @@
<template>
<view>
<up-popup :show="show" mode="center">
<view class="popup-content">
<view class="top u-flex u-row-between">
<text class="font-bold u-font-32 color-333">{{ title }}</text>
<up-icon size="18" name="close" @click="close"></up-icon>
</view>
<up-line></up-line>
<scroll-view style="max-height: 50vh" :scroll-y="true">
<slot></slot>
</scroll-view>
<up-line></up-line>
<view class="bottom">
<view class="btn cancel" @click="close">{{ cancelText }}</view>
<view class="btn success" @click="confirm">{{ confirmText }}</view>
</view>
</view>
</up-popup>
</view>
</template>
<script setup>
import { ref } from "vue";
const props = defineProps({
title: {
type: String,
default: "标题",
},
confirmText: {
type: String,
default: "保存",
},
cancelText: {
type: String,
default: "取消",
},
});
const show = defineModel({
type: Boolean,
default: false,
});
const emits = defineEmits(["close", "confirm"]);
function close() {
show.value = false;
emits("close");
}
function confirm() {
emits("confirm");
}
</script>
<style lang="scss">
.popup-content {
background: #fff;
width: 640rpx;
border-radius: 18rpx;
}
.top {
padding: 40rpx 48rpx;
}
.bottom {
padding: 48rpx 52rpx;
display: flex;
justify-content: space-between;
gap: 50rpx;
.btn {
flex: 1;
text-align: center;
padding: 18rpx 60rpx;
border-radius: 100rpx;
font-size: 32rpx;
border: 2rpx solid transparent;
white-space: nowrap;
&.success {
background-color: $my-main-color;
color: #fff;
}
&.cancel {
border-color: #d9d9d9;
box-shadow: 0 4rpx 0 0 #00000005;
}
}
}
</style>

View File

@@ -0,0 +1,49 @@
<template>
<view>
<up-action-sheet
:round="14"
:actions="list"
:title="title"
:show="show"
closeOnClickAction
cancelText="取消"
@close="close"
@select="sheetSelect"
></up-action-sheet>
</view>
</template>
<script setup >
import { ref, reactive, onMounted } from "vue";
import { getShopList } from "@/http/api/shop.js";
const props = defineProps({
title: {
type: String,
default: "请选择",
},
});
const list = ref([]);
const show=defineModel({
name: "show",
default: false,
})
function close() {
show.value = false;
}
const emit=defineEmits(["choose"]);
function sheetSelect(e) {
console.log(e);
emit("choose", e);
}
onMounted(() => {
getShopList().then((res) => {
list.value = res.map((v) => ({
...v,
value: v.shopId,
name: v.shopName,
}));
});
});
</script>