新增跳转企业微信客服功能

This commit is contained in:
gyq
2025-12-29 13:54:53 +08:00
parent 8d917d49ed
commit cbe27a43de
3 changed files with 557 additions and 585 deletions

View File

@@ -1,5 +1,6 @@
// const debug = process.env.NODE_ENV == 'development' ? true : false;
const debug = false; // false线上 true本地
// const debug = false; // false线上 true本地
const debug = true; // false线上 true本地
let baseUrl = ''
let baseUrlwws = ''

View File

@@ -27,7 +27,6 @@
<image :src="imgs.code" class="code"></image>
</view>
</view>
<!-- <button type="primary" @click="openContact">打开客服</button> -->
<view class="new-menus-box">
<view class="new-menus layout2" v-if="allConfig.takeout">
<view class="diner" @click="scanCodehandle(0)">
@@ -125,27 +124,6 @@ import { getMemberConfig, getRechargeConfig } from '@/common/api/index/index.js'
import { ref, reactive, defineProps, defineEmits, onMounted } from 'vue';
import { isJsonArrayString } from '@/utils/util.js';
function openContact() {
wx.openCustomerServiceChat({
corpId: 'wwc76ab19fa6df267f',
extInfo: {
url: 'https://work.weixin.qq.com/kfid/kfc40ac2dc5e20c2e8e'
},
// 成功回调
success: (res) => {
console.log('跳转企业微信客服成功', res);
},
// 失败回调
fail: (err) => {
console.error('跳转企业微信客服失败', err);
uni.showToast({
title: '跳转客服失败,请稍后重试',
icon: 'none'
});
}
});
}
const attractPopupRef = ref(null);
const imgs = {

View File

@@ -1,12 +1,16 @@
<template>
<view class="container">
<image class="topBack" :src="
<image
class="topBack"
:src="
userInfo.shopExtendList
? userInfo.shopExtendList[1].value
? userInfo.shopExtendList[1].value
: 'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/myTopBack.png'
: 'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/myTopBack.png'
" mode="aspectFill"></image>
"
mode="aspectFill"
></image>
<view class="myContent">
<view class="my_info flex-between">
<view class="my_info_left">
@@ -15,8 +19,7 @@
<image class="my_info_left_head" :src="userInfo.headImg" mode="aspectFill"></image>
</button>
<!-- <view class="name">{{ userInfo.nickName }}</view> -->
<input type="nickname" class="name" v-model="userInfo.nickName" placeholder="输入昵称"
@blur="onNicknameInput" />
<input type="nickname" class="name" v-model="userInfo.nickName" placeholder="输入昵称" @blur="onNicknameInput" />
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<image class="my_info_left_head" :src="userInfo.headImg" mode="aspectFill"></image>
@@ -27,8 +30,7 @@
<image class="my_info_right_qr" src="/static/icon/code.png" mode="aspectFill"></image>
<view class="msg-view" @click="viewUserMsgList">
<view class="msg-icon-wrapper">
<image v-if="unreadMsgCount > 0" class="my-msg-icon" src="/static/mine/msg_select.png"
mode="aspectFill"></image>
<image v-if="unreadMsgCount > 0" class="my-msg-icon" src="/static/mine/msg_select.png" mode="aspectFill"></image>
<image v-else class="my-msg-icon" src="/static/mine/msg.png" mode="aspectFill"></image>
<!-- 角标 -->
@@ -39,7 +41,6 @@
</view>
</view>
<!-- <image class="my_info_right_qr" @click="clickEvent" v-if="userInfo.isVip == 1 && ShopId"
:src="'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/my_qRcode.png'" mode="aspectFill">
</image>
@@ -55,9 +56,7 @@
<view class="amount">
<view class="u-flex u-flex-between u-m-t-20">
<view class="u-flex">
<image style="width: 50rpx; height: 37rpx"
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/storedValue.png"
mode="aspectFill"></image>
<image style="width: 50rpx; height: 37rpx" src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/storedValue.png" mode="aspectFill"></image>
<text class="color-333 font-14 u-m-l-20">储值</text>
</view>
<view class="u-flex color-666" @click="toChargeList">
@@ -67,23 +66,17 @@
</view>
<view class="card-list">
<view class="card-list-item" v-for="(item, index) in rechargeList" :key="index"
@click="toCharge(item)">
<view class="card-list-item" v-for="(item, index) in rechargeList" :key="index" @click="toCharge(item)">
<up-image radius="20rpx" width="182rpx" height="182rpx" :src="item.logo"></up-image>
<view class="info text-center">
<view class="color-333 u-m-t-14">
<text class="font-10">¥</text>
<text class="font-16 font-700">{{
item.amount || "0.00"
}}</text>
<text class="font-16 font-700">{{ item.amount || '0.00' }}</text>
</view>
<view class="font-12 color-666 u-line-1">{{
item.shopName
}}</view>
<view class="font-12 color-666 u-line-1">{{ item.shopName }}</view>
</view>
</view>
<view class="u-flex u-flex-column u-flex-center" style="width: 12px" v-if="rechargeList.length"
@click="toChargeList">
<view class="u-flex u-flex-column u-flex-center" style="width: 12px" v-if="rechargeList.length" @click="toChargeList">
<view class="text-center color-333 font-12">查看全部</view>
</view>
</view>
@@ -91,8 +84,7 @@
<view class="vip u-m-t-40">
<view class="u-flex u-flex-between u-m-t-20">
<view class="u-flex">
<image style="width: 50rpx; height: 40rpx" src="/static/icon/vip.png" mode="aspectFill">
</image>
<image style="width: 50rpx; height: 40rpx" src="/static/icon/vip.png" mode="aspectFill"></image>
<text class="color-333 font-14 u-m-l-20">会员</text>
</view>
<view class="u-flex color-666" @click="tomemberList">
@@ -102,13 +94,10 @@
</view>
<view class="card-list">
<view class="card-list-item" v-for="(item, index) in memberList" :key="index"
@click="tomember(item)">
<view class="card-list-item" v-for="(item, index) in memberList" :key="index" @click="tomember(item)">
<up-image radius="20rpx" width="182rpx" height="182rpx" :src="item.logo"></up-image>
<view class="info text-center">
<view class="font-12 color-666 u-m-t-14 u-line-1">{{
item.shopName
}}</view>
<view class="font-12 color-666 u-m-t-14 u-line-1">{{ item.shopName }}</view>
</view>
</view>
<view class="u-flex u-flex-column u-flex-center" style="width: 12px" v-if="memberList.length">
@@ -119,9 +108,7 @@
<view class="amount">
<view class="u-flex u-flex-between u-m-t-20">
<view class="u-flex">
<image style="width: 50rpx; height: 44rpx"
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/points.png" mode="aspectFill">
</image>
<image style="width: 50rpx; height: 44rpx" src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/points.png" mode="aspectFill"></image>
<text class="color-333 font-14 u-m-l-20">积分</text>
</view>
<view class="u-flex color-666" @click="toCoin()">
@@ -131,22 +118,16 @@
</view>
<view class="card-list">
<view class="card-list-item" v-for="(item, index) in coinList" :key="index"
@click="toCoin(item)">
<view class="card-list-item" v-for="(item, index) in coinList" :key="index" @click="toCoin(item)">
<up-image radius="20rpx" width="182rpx" height="182rpx" :src="item.logo"></up-image>
<view class="info text-center">
<view class="color-333 u-m-t-14">
<text class="font-16 font-700">{{
item.pointBalance || "0"
}}</text>
<text class="font-16 font-700">{{ item.pointBalance || '0' }}</text>
</view>
<view class="font-12 color-666 u-line-1">{{
item.shopName
}}</view>
<view class="font-12 color-666 u-line-1">{{ item.shopName }}</view>
</view>
</view>
<view class="u-flex u-flex-column u-flex-center" style="width: 12px" v-if="coinList.length"
@click="toCoin()">
<view class="u-flex u-flex-column u-flex-center" style="width: 12px" v-if="coinList.length" @click="toCoin()">
<view class="text-center color-333 font-12">查看全部</view>
</view>
</view>
@@ -154,16 +135,13 @@
</view>
<view class="my_item my_fun u-m-t-30">
<view class="my_fun_list">
<view class="my_list_item" v-for="(item, index) in myFunList" :key="index"
@click="clickTo(item, index)">
<view class="my_list_item" v-for="(item, index) in myFunList" :key="index" @click="clickTo(item, index)">
<view class="my_list_item_left">
<image class="my_list_item_icon" :src="item.icon" mode="aspectFill"></image>
<view class="my_list_item_name">{{ item.name }}</view>
</view>
<view class="my_list_item_right u-flex">
<text v-if="item.type == 'score'" class="font-12">{{
userInfo.pointBalance || 0
}}</text>
<text v-if="item.type == 'score'" class="font-12">{{ userInfo.pointBalance || 0 }}</text>
<!-- <text v-else-if="item.type=='my_coupon'" class="font-12 ">{{userInfo.couponNum || 0}}</text> -->
<text class="font-12 color-999" v-else>查看</text>
<u-icon class="u-m-t-2" name="arrow-right" color="#999999" size="12"></u-icon>
@@ -190,47 +168,58 @@
</template>
<script setup>
import weQrcode from "@/components/wechat-ac-qrcode.vue";
import devetools from "@/components/devetools.vue";
import weQrcode from '@/components/wechat-ac-qrcode.vue';
import devetools from '@/components/devetools.vue';
import {
ref,
computed,
onMounted,
reactive,
watch
} from "vue";
import {
onLoad,
onReady,
onShow
} from "@dcloudio/uni-app";
import {
productStore
} from "@/stores/user.js";
import * as vipApi from "@/common/api/account/vip.js";
import * as rechargeApi from "@/common/api/market/recharge.js";
import {
pointsShopList
} from '@/common/api/market/points.js'
import {
getUnReadCountReq
} from "../../common/api/account/message";
import {
updateUserInfoReq
} from "../../common/api/api";
import {
uploadFile
} from '@/common/api/upload.js';
import { ref, computed, onMounted, reactive, watch } from 'vue';
import { onLoad, onReady, onShow } from '@dcloudio/uni-app';
import { productStore, Storelogin } from '@/stores/user.js';
import * as vipApi from '@/common/api/account/vip.js';
import * as rechargeApi from '@/common/api/market/recharge.js';
import { pointsShopList } from '@/common/api/market/points.js';
import { getUnReadCountReq } from '../../common/api/account/message';
import { updateUserInfoReq } from '../../common/api/api';
import { uploadFile } from '@/common/api/upload.js';
function qrcodeResult(res) {
qrcode.value = res;
// 打开企业微信客服
const userStore = Storelogin();
function openContact() {
const shopInfo = uni.cache.get('ordershopUserInfo');
if (shopInfo.weworkId && shopInfo.weworkUrl) {
wx.openCustomerServiceChat({
// corpId: 'wwc76ab19fa6df267f',
corpId: shopInfo.weworkId,
extInfo: {
// url: 'https://work.weixin.qq.com/kfid/kfc40ac2dc5e20c2e8e'
url: shopInfo.weworkUrl
},
// 成功回调
success: (res) => {
console.log('跳转企业微信客服成功', res);
},
// 失败回调
fail: (err) => {
console.error('跳转企业微信客服失败', err);
uni.showToast({
title: '跳转客服失败,请稍后重试',
icon: 'none'
});
}
});
} else {
uni.showToast({
title: '未开放',
icon: 'none'
});
}
}
const store = productStore();
const myFunList = ref([
function qrcodeResult(res) {
qrcode.value = res;
}
const store = productStore();
const myFunList = ref([
// {
// name: "积分",
// type: "score",
@@ -238,14 +227,14 @@
// url: '/user/score/list'
// },
{
name: "优惠券",
type: "my_coupon",
icon: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/my_coupon.png",
name: '优惠券',
type: 'my_coupon',
icon: 'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/my_coupon.png'
},
{
name: "分销",
type: "fenxiao",
icon: "/static/icon/fenxiao.svg",
name: '分销',
type: 'fenxiao',
icon: '/static/icon/fenxiao.svg'
},
// {
// name: "商家推送",
@@ -269,34 +258,35 @@
// icon: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/my_member.png"
// },
// { name: "关于", type: "", icon: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/inRegard.png"},
]);
{ name: '联系商家', type: 'contact', icon: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/2b0480c32c1844dbae2c09f6a729c6e8.png' }
]);
const userInfo = reactive({});
const userInfo = reactive({});
const ShopId = ref(uni.cache.get("shopId"));
console.log("ShopId", uni.cache.get("shopId"));
const ShopId = ref(uni.cache.get('shopId'));
console.log('ShopId', uni.cache.get('shopId'));
function tomemberList() {
function tomemberList() {
uni.navigateTo({
url: "/pages/user/member/list",
url: '/pages/user/member/list'
});
}
}
function tomember(item) {
function tomember(item) {
uni.navigateTo({
url: "/user/vip/vip?shopId=" + item.shopId,
url: '/user/vip/vip?shopId=' + item.shopId
});
}
}
const clickEvent = () => {
const clickEvent = () => {
if (ShopId.value) {
if (!userInfo.isVip) {
uni.navigateTo({
url: "/user/vip/buy-vip?shopId=" + ShopId.value,
url: '/user/vip/buy-vip?shopId=' + ShopId.value
});
} else {
uni.navigateTo({
url: "/user/vip/vip?shopId=" + ShopId.value,
url: '/user/vip/vip?shopId=' + ShopId.value
});
}
@@ -312,115 +302,118 @@
// })
// }
} else {
uni.pro.navigateTo("member/list", {
type: "user_payCode",
uni.pro.navigateTo('member/list', {
type: 'user_payCode'
});
}
};
};
// 我的资产
const Myassets = () => {
if (uni.cache.get("shopId")) {
uni.pro.navigateTo("user/member/memberdetails", {
shopId: uni.cache.get("shopId"),
type: "index",
// 我的资产
const Myassets = () => {
if (uni.cache.get('shopId')) {
uni.pro.navigateTo('user/member/memberdetails', {
shopId: uni.cache.get('shopId'),
type: 'index'
});
} else {
uni.pro.navigateTo("user/member/list", {
shopId: uni.cache.get("shopId"),
type: "index",
uni.pro.navigateTo('user/member/list', {
shopId: uni.cache.get('shopId'),
type: 'index'
});
}
};
};
function toCharge(item) {
function toCharge(item) {
uni.navigateTo({
url: "/pages/user/member/czzx?shopId=" + item.shopId,
url: '/pages/user/member/czzx?shopId=' + item.shopId
});
}
}
function toChargeList() {
function toChargeList() {
uni.navigateTo({
url: "/pages/user/member/amount-list",
url: '/pages/user/member/amount-list'
});
}
}
const clickTo = (item, index) => {
const clickTo = (item, index) => {
if (item.url) {
uni.navigateTo({
url: item.url,
url: item.url
});
return;
}
let shopId = null;
switch (item.type) {
case "msg":
case 'msg':
uni.navigateTo({
url: "/pageChat/index"
url: '/pageChat/index'
});
break;
case "my_order":
uni.pro.switchTab("order/index");
case 'my_order':
uni.pro.switchTab('order/index');
break;
case "my_member":
uni.pro.navigateTo("user/member/list");
case 'my_member':
uni.pro.navigateTo('user/member/list');
break;
case "recharge":
if (uni.cache.get("shopId") && uni.cache.get("token")) {
uni.pro.navigateTo("member/index", {
shopId: uni.cache.get("shopId"),
type: "index",
case 'recharge':
if (uni.cache.get('shopId') && uni.cache.get('token')) {
uni.pro.navigateTo('member/index', {
shopId: uni.cache.get('shopId'),
type: 'index'
});
} else {
uni.pro.navigateTo("member/list", {
type: "user_recharge",
uni.pro.navigateTo('member/list', {
type: 'user_recharge'
});
}
break;
case "points": //积分
if (uni.cache.get("shopId") && uni.cache.get("token")) {
uni.pro.navigateTo("/pagesPoints/index/index", {
shopId: uni.cache.get("shopId"),
type: "user",
case 'points': //积分
if (uni.cache.get('shopId') && uni.cache.get('token')) {
uni.pro.navigateTo('/pagesPoints/index/index', {
shopId: uni.cache.get('shopId'),
type: 'user'
});
} else {
uni.pro.navigateTo("member/list", {
type: "user_points",
uni.pro.navigateTo('member/list', {
type: 'user_points'
});
}
break;
case "my_coupon": //优惠券
uni.pro.navigateTo("user/coupon", {
shopId: uni.cache.get("shopId") || "",
case 'my_coupon': //优惠券
uni.pro.navigateTo('user/coupon', {
shopId: uni.cache.get('shopId') || ''
});
break;
case "fenxiao": //优惠券
case 'fenxiao': //优惠券
uni.navigateTo({
url: "/distribution/index",
url: '/distribution/index'
});
break;
case "myself": //内部页面
uni.pro.navigateTo("user/myself");
case 'myself': //内部页面
uni.pro.navigateTo('user/myself');
break;
case "scan_applet":
case 'scan_applet':
uni.navigateToMiniProgram(JSON.parse(item.value));
break;
case "absolute": //外链url
case 'absolute': //外链url
uni.navigateTo({
url: `/pages/webview/webview?url=${item.menuUrl}`,
url: `/pages/webview/webview?url=${item.menuUrl}`
});
break;
case 'contact': // 联系商家
openContact();
break;
}
};
};
const memberList = ref([]);
const rechargeList = ref([]);
const memberTotal = ref(0);
const rechargeTotal = ref(0);
const memberList = ref([]);
const rechargeList = ref([]);
const memberTotal = ref(0);
const rechargeTotal = ref(0);
const coinTotal = ref(0);
const coinList = ref([]);
async function getData() {
const coinTotal = ref(0);
const coinList = ref([]);
async function getData() {
const res = await vipApi.list();
memberTotal.value = res.length;
memberList.value = res.slice(0, 3);
@@ -431,102 +424,102 @@
const res3 = await pointsShopList();
coinTotal.value = res3.length;
coinList.value = res3;
}
}
function toCoin(item) {
if(item){
function toCoin(item) {
if (item) {
uni.navigateTo({
url: "/pages/user/member/billDetails?type=2&shopId="+item.shopId+"&id="+(item.id||''),
url: '/pages/user/member/billDetails?type=2&shopId=' + item.shopId + '&id=' + (item.id || '')
});
return
return;
}
uni.navigateTo({
url: "/user/score/list",
url: '/user/score/list'
});
}
}
const unreadMsgCount = ref(0);
const unreadMsgCount = ref(0);
const getUnReadMsgCount = async () => {
let res = await getUnReadCountReq()
const getUnReadMsgCount = async () => {
let res = await getUnReadCountReq();
let badge = Number(res)
let badge = Number(res);
if (badge > 0) {
uni.setTabBarBadge({
index: 2,
text: badge.toString()
})
});
} else {
uni.removeTabBarBadge({
index: 2
})
});
}
unreadMsgCount.value = badge
}
unreadMsgCount.value = badge;
};
const viewUserMsgList = () => {
const viewUserMsgList = () => {
uni.navigateTo({
url: "/pages/user/message/index"
})
}
url: '/pages/user/message/index'
});
};
onShow(() => {
loadUserInfo()
console.log("userInfo", userInfo);
onShow(() => {
loadUserInfo();
console.log('userInfo', userInfo);
getData();
getUnReadMsgCount()
});
getUnReadMsgCount();
});
const loadUserInfo = async () => {
const loadUserInfo = async () => {
await store.actionsAPIuser();
if (uni.cache.get("shopId")) {
Object.assign(userInfo, uni.cache.get("orderVIP"));
if (uni.cache.get('shopId')) {
Object.assign(userInfo, uni.cache.get('orderVIP'));
} else {
Object.assign(userInfo, {
...uni.cache.get("userInfo"),
...uni.cache.get("userInfo").assetsSummary,
...uni.cache.get('userInfo'),
...uni.cache.get('userInfo').assetsSummary
});
}
}
};
const qrcode = ref("");
const showQrcode = computed(() => {
const followIndex = uni.cache.get("followIndex");
if (followIndex == "mine" && qrcode.value) {
const qrcode = ref('');
const showQrcode = computed(() => {
const followIndex = uni.cache.get('followIndex');
if (followIndex == 'mine' && qrcode.value) {
return true;
}
});
const onChooseAvatar = async (e) => {
const fileRes = await uploadFile(e.detail.avatarUrl);
updateUserInfo({
headImg: fileRes
});
};
const onChooseAvatar = async (e) => {
const fileRes = await uploadFile(e.detail.avatarUrl)
const onNicknameInput = (e) => {
updateUserInfo({
"headImg": fileRes
})
}
nickName: e.detail.value
});
};
const onNicknameInput = (e) => {
updateUserInfo({
"nickName": e.detail.value
})
}
const updateUserInfo = async (param) => {
await updateUserInfoReq(param);
const updateUserInfo = async (param) => {
await updateUserInfoReq(param)
loadUserInfo()
}
loadUserInfo();
};
</script>
<style scoped lang="scss">
.topBack {
.topBack {
width: 100%;
height: 400rpx;
position: absolute;
}
}
.myContent {
.myContent {
position: relative;
z-index: 1;
padding: 298rpx 0 60rpx 0;
@@ -668,9 +661,9 @@
}
}
}
}
}
.card-list {
.card-list {
display: grid;
grid-template-columns: repeat(4, 1fr);
column-gap: 40rpx;
@@ -687,21 +680,21 @@
overflow: hidden;
}
}
}
}
.qrcode {
.qrcode {
padding: 24rpx;
margin: 60rpx 32rpx 60rpx 32rpx;
border-radius: 18rpx;
border: 2rpx solid #d9d9d9;
}
}
.qrcode-box {
.qrcode-box {
position: fixed;
transform: translateX(200vw, 200vh);
}
}
.right-icons {
.right-icons {
display: flex;
.my_info_right_qr {
@@ -742,5 +735,5 @@
text-align: center;
}
}
}
}
</style>