榴莲果配置 扫码加好友

This commit is contained in:
lr 2025-02-18 11:38:36 +08:00
parent e6d75c5a01
commit d77e175b52
20 changed files with 1123 additions and 601 deletions

View File

@ -72,5 +72,15 @@ export const durian = {
load: true,
})
},
/**
* 榴莲果配置
* @param {Object} param
*/
durianFruitConfig() {
return util.request({
url: `/coreplay/durianFruitTransactionType/10`,
method: 'GET',
})
},
}
export default durian

View File

@ -449,6 +449,31 @@ const shop = {
query: param,
})
},
/**
* 根据店铺id查商品列表
* @param {Object} param
*/
getShopProductList(param) {
return util.request({
url: `/shopify/appProductionApi/getProductionList`,
method: 'GET',
query: param,
})
},
/**
* 查询用户在当前商铺的订单列表
* @param {Object} param
*/
getShopOrderList(param) {
return util.request({
url: `/shopify/appOrder/getOrderList`,
method: 'GET',
query: param,
})
},
}
export default shop

View File

@ -8,6 +8,7 @@ const config = {
// #ifndef H5
// host: 'http://91f.xyz:8080',
host: 'https://b433d23.r24.cpolar.top/',
// host: 'http://hvw2rn.natappfree.cc',
// #endif
// 支付方式配置
payType: {

View File

@ -110,6 +110,28 @@ function handleList(list) {
if (item.groupId != null) {
item.unreadCount = getGroupNoReadNum(item.groupId)
}
if (item.callbackJson.callback_json.length) {
let msgType = item.callbackJson.callback_json[0].MsgType;
if (msgType == TencentCloudChat.TYPES.MSG_TEXT) {
item.chatText = item.callbackJson.callback_json[0].MsgContent.Text
} else if (msgType == TencentCloudChat.TYPES.MSG_IMAGE) {
item.chatText = '[图片]'
} else if (msgType == TencentCloudChat.TYPES.MSG_AUDIO) {
item.chatText = '[语音]'
} else if (msgType == TencentCloudChat.TYPES.MSG_VIDEO) {
item.chatText = '[视频]'
} else if (msgType == TencentCloudChat.TYPES.MSG_CUSTOM) {
if (item.callbackJson.callback_json[0].businessType == 'redPacket') {
item.chatText = `[红包] ${item.callbackJson.blessing}`
} else if (item.callbackJson.callback_json[0].businessType == '1') {
// if (item.callbackJson.callback_json[0].call_type == '1') {
// item.chatText = '[]'
// } else if (item.callbackJson.callback_json[0].call_type == '2') {
// item.chatText = '[]'
// }
}
}
}
})
return list
@ -297,8 +319,7 @@ function setRead(item) {
<view class="datetime c999 f22">
{{ util.formatTime('MM-dd HH:mm', item.createTime) }}</view>
</view>
<view class="desc thd mt10 c666 f24">{{
item.callbackJson.callback_json[0].MsgContent.Text }}</view>
<view class="desc thd mt10 c666 f24">{{ item.chatText }}</view>
</view>
</view>
</uni-swipe-action-item>

View File

@ -4,15 +4,15 @@
<uni-section>
<template v-slot:decoration>
<!-- 商品图 -->
<image class="shop-image" :src="orderInfo.productName" mode="aspectFill"></image>
<image class="shop-image" :src="orderInfo.productImage" mode="aspectFill"></image>
</template>
<template v-slot:content>
<!-- 订单 | 聊天-->
<template v-if="showType == 1 || showType == 4">
<view class="commodity-name commodity-name-1">
<text class="commodity-name-title t2hd">耳钉耳钉耳钉耳钉耳钉耳钉耳钉耳钉耳钉耳钉耳钉</text>
<text class="commodity-name-ks thd">X602 款式</text>
<text v-if="showType == 4">待发货</text>
<text class="commodity-name-title t2hd">{{ orderInfo.productName }}</text>
<text class="commodity-name-ks thd">{{ orderInfo.status_text }}</text>
<text v-if="showType == 4">{{ orderInfo.status }}</text>
</view>
</template>
<!-- 历史浏览 | 收藏 -->
@ -54,10 +54,10 @@
<view class="price-num">
<view class="df aic price">
<text class="f20 jg"></text>
<text class="f28">999.00</text>
<text class="f28">{{ orderInfo.productPrice }}</text>
</view>
<!-- 数量 -->
<text class="c999 f24">x1</text>
<text class="c999 f24">x{{ orderInfo.totalNum }}</text>
</view>
<!-- 发送到聊天 -->
<view @click.stop="emit('consult', orderInfo)" class="go-buy" v-if="showType == 4">
@ -106,6 +106,10 @@ const props = defineProps({
})
</script>
<style scoped lang="scss">
.commodity-information {
padding: 0 20rpx;
}
$h : 164rpx;
.shop-image {

View File

@ -90,31 +90,24 @@ function handleBuy() {
//
function toCustomer() {
api.shop.getCustomerService({ merchantId: props.detail.merId }).then(rs => {
console.log(rs);
//
if (rs.code == 200) {
let param = {};
param.type = 'C2C'
param.name = `${props.detail.merName}`
param.msgId = `${rs.data.serviceId}`
param.isCustomer = true
util.toChat(param)
uni.navigateTo({
url: util.setUrl('/pages/news/chat/chat', param)
})
} else {
util.alert(rs.msg)
}
})
let param = {};
param.type = 'C2C'
param.name = `${props.detail.merName}`
param.msgId = `${props.detail.merId}`
param.isCustomer = true
util.toChat(param)
uni.navigateTo({
url: util.setUrl('/pages/news/chat/chat', param)
})
}
</script>
@ -138,10 +131,10 @@ function toCustomer() {
</view>
</view>
<view class="option ver" @click="toCustomer">
<!-- <view class="option ver" @click="toCustomer">
<image class="wh30" src="/static/customer-service.png" mode="aspectFit" />
<text class="text mt10">客服</text>
</view>
</view> -->
</view>
<!-- 下单 -->

View File

@ -0,0 +1,133 @@
// @ts-nocheck
export {};
; declare module 'vue' {
export interface GlobalComponents { }
export interface GlobalDirectives { }
}
; declare global {
const __VLS_intrinsicElements: __VLS_IntrinsicElements;
const __VLS_directiveBindingRestFields: { instance: null, oldValue: null, modifiers: any, dir: any };
const __VLS_unref: typeof import('vue').unref;
const __VLS_placeholder: any;
const __VLS_nativeElements = {
...{} as SVGElementTagNameMap,
...{} as HTMLElementTagNameMap,
};
type __VLS_IntrinsicElements = globalThis.JSX.IntrinsicElements;
type __VLS_Element = globalThis.JSX.Element;
type __VLS_GlobalComponents = import('vue').GlobalComponents & Pick<typeof import('vue'), 'Transition' | 'TransitionGroup' | 'KeepAlive' | 'Suspense' | 'Teleport'>;
type __VLS_GlobalDirectives = import('vue').GlobalDirectives;
type __VLS_IsAny<T> = 0 extends 1 & T ? true : false;
type __VLS_PickNotAny<A, B> = __VLS_IsAny<A> extends true ? B : A;
type __VLS_unknownDirective = (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void;
type __VLS_WithComponent<N0 extends string, LocalComponents, Self, N1 extends string, N2 extends string, N3 extends string> =
N1 extends keyof LocalComponents ? N1 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N1] } :
N2 extends keyof LocalComponents ? N2 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N2] } :
N3 extends keyof LocalComponents ? N3 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N3] } :
Self extends object ? { [K in N0]: Self } :
N1 extends keyof __VLS_GlobalComponents ? N1 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : { [K in N0]: __VLS_GlobalComponents[N1] } :
N2 extends keyof __VLS_GlobalComponents ? N2 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : { [K in N0]: __VLS_GlobalComponents[N2] } :
N3 extends keyof __VLS_GlobalComponents ? N3 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : { [K in N0]: __VLS_GlobalComponents[N3] } :
{ [K in N0]: unknown };
type __VLS_FunctionalComponentProps<T, K> =
'__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends { __ctx?: { props?: infer P } } ? NonNullable<P> : never
: T extends (props: infer P, ...args: any) => any ? P :
{};
type __VLS_IsFunction<T, K> = K extends keyof T
? __VLS_IsAny<T[K]> extends false
? unknown extends T[K]
? false
: true
: false
: false;
type __VLS_NormalizeComponentEvent<Props, Events, onEvent extends keyof Props, Event extends keyof Events, CamelizedEvent extends keyof Events> = (
__VLS_IsFunction<Props, onEvent> extends true
? Props
: __VLS_IsFunction<Events, Event> extends true
? { [K in onEvent]?: Events[Event] }
: __VLS_IsFunction<Events, CamelizedEvent> extends true
? { [K in onEvent]?: Events[CamelizedEvent] }
: Props
) & Record<string, unknown>;
// fix https://github.com/vuejs/language-tools/issues/926
type __VLS_UnionToIntersection<U> = (U extends unknown ? (arg: U) => unknown : never) extends ((arg: infer P) => unknown) ? P : never;
type __VLS_OverloadUnionInner<T, U = unknown> = U & T extends (...args: infer A) => infer R
? U extends T
? never
: __VLS_OverloadUnionInner<T, Pick<T, keyof T> & U & ((...args: A) => R)> | ((...args: A) => R)
: never;
type __VLS_OverloadUnion<T> = Exclude<
__VLS_OverloadUnionInner<(() => never) & T>,
T extends () => never ? never : () => never
>;
type __VLS_ConstructorOverloads<T> = __VLS_OverloadUnion<T> extends infer F
? F extends (event: infer E, ...args: infer A) => any
? { [K in E & string]: (...args: A) => void; }
: never
: never;
type __VLS_NormalizeEmits<T> = __VLS_PrettifyGlobal<
__VLS_UnionToIntersection<
__VLS_ConstructorOverloads<T> & {
[K in keyof T]: T[K] extends any[] ? { (...args: T[K]): void } : never
}
>
>;
type __VLS_PrettifyGlobal<T> = { [K in keyof T]: T[K]; } & {};
type __VLS_PickFunctionalComponentCtx<T, K> = NonNullable<__VLS_PickNotAny<
'__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends { __ctx?: infer Ctx } ? Ctx : never : any
, T extends (props: any, ctx: infer Ctx) => any ? Ctx : any
>>;
type __VLS_OmitStringIndex<T> = {
[K in keyof T as string extends K ? never : K]: T[K];
};
type __VLS_UseTemplateRef<T> = Readonly<import('vue').ShallowRef<T | null>>;
function __VLS_getVForSourceType(source: number): [number, number][];
function __VLS_getVForSourceType(source: string): [string, number][];
function __VLS_getVForSourceType<T extends any[]>(source: T): [
item: T[number],
index: number,
][];
function __VLS_getVForSourceType<T extends { [Symbol.iterator](): Iterator<any> }>(source: T): [
item: T extends { [Symbol.iterator](): Iterator<infer T1> } ? T1 : never,
index: number,
][];
// #3845
function __VLS_getVForSourceType<T extends number | { [Symbol.iterator](): Iterator<any> }>(source: T): [
item: number | (Exclude<T, number> extends { [Symbol.iterator](): Iterator<infer T1> } ? T1 : never),
index: number,
][];
function __VLS_getVForSourceType<T>(source: T): [
item: T[keyof T],
key: keyof T,
index: number,
][];
// @ts-ignore
function __VLS_getSlotParams<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>;
// @ts-ignore
function __VLS_getSlotParam<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>[0];
function __VLS_asFunctionalDirective<T>(dir: T): T extends import('vue').ObjectDirective
? NonNullable<T['created' | 'beforeMount' | 'mounted' | 'beforeUpdate' | 'updated' | 'beforeUnmount' | 'unmounted']>
: T extends (...args: any) => any
? T
: __VLS_unknownDirective;
function __VLS_withScope<T, K>(ctx: T, scope: K): ctx is T & K;
function __VLS_makeOptional<T>(t: T): { [K in keyof T]?: T[K] };
function __VLS_asFunctionalComponent<T, K = T extends new (...args: any) => any ? InstanceType<T> : unknown>(t: T, instance?: K):
T extends new (...args: any) => any
? (props: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>, ctx?: any) => __VLS_Element & { __ctx?: {
attrs?: any,
slots?: K extends { $scopedSlots: infer Slots } ? Slots : any,
emit?: K extends { $emit: infer Emit } ? Emit : any
} & { props?: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>; expose?(exposed: K): void; } }
: T extends () => any ? (props: {}, ctx?: any) => ReturnType<T>
: T extends (...args: any) => any ? T
: (_: {} & Record<string, unknown>, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: {} & Record<string, unknown> } };
function __VLS_asFunctionalElement<T>(tag: T, endTag?: T): (_: T & Record<string, unknown>) => void;
function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): 2 extends Parameters<T>['length'] ? [any] : [];
function __VLS_normalizeSlot<S>(s: S): S extends () => infer R ? (props: {}) => R : S;
function __VLS_tryAsConstant<const T>(t: T): T;
}

View File

@ -1,205 +1,229 @@
<script setup>
/**
* 榴莲首页
*/
import {
useStore,
} from 'vuex'
import {
onMounted,
ref,
reactive,
computed,
getCurrentInstance,
watch,
defineExpose,
} from 'vue';
/**
* 榴莲首页
*/
import {
useStore,
} from 'vuex'
import {
onMounted,
ref,
reactive,
computed,
getCurrentInstance,
watch,
defineExpose,
} from 'vue';
import {
onLoad,
onReady,
onHide,
} from '@dcloudio/uni-app'
//
import noLogin from '@/components/login/noLogin.vue'
//
import util from '@/common/js/util.js'
//
import task from '@/components/index/task'
//
import api from '@/api/index.js'
//
import payPwd from '@/components/mine/payPwd.vue'
const {
proxy
} = getCurrentInstance()
//
const store = useStore()
//
const form = reactive({
// ID
targetUserId: '',
//
account: '',
//
fruitAmount: '',
//
first: '',
//
name: '',
//
secondPassword: '',
})
//
const viewData = ref({
seconds: 0
})
//
const userinfo = computed(() => {
return store.state.userinfo
})
//
const progress = computed(() => {
let result = viewData.value.seconds
result = Math.min(Number(result), 100)
return result
})
//
const purse = computed(() => {
return store.state.purse || {}
})
import {
onLoad,
onReady,
onHide,
} from '@dcloudio/uni-app'
//
import noLogin from '@/components/login/noLogin.vue'
//
import util from '@/common/js/util.js'
//
import task from '@/components/index/task'
//
import api from '@/api/index.js'
//
import payPwd from '@/components/mine/payPwd.vue'
const {
proxy
} = getCurrentInstance()
//
const store = useStore()
//
const form = reactive({
// ID
targetUserId: '',
//
account: '',
//
fruitAmount: '',
//
first: '',
//
name: '',
//
secondPassword: '',
})
//
const viewData = ref({
seconds: 0
})
//
const userinfo = computed(() => {
return store.state.userinfo
})
//
const progress = computed(() => {
let result = viewData.value.seconds
result = Math.min(Number(result), 100)
return result
})
//
const purse = computed(() => {
return store.state.purse || {}
})
onReady(() => {
// proxy.$refs.dealRef.open()
// proxy.$refs.payPwdRef.open()
})
//
const configData = reactive({
minConsumption: '',
platformPercentage: ''
})
onLoad(() => {
//
util.getPurse()
onReady(() => {
// proxy.$refs.dealRef.open()
// proxy.$refs.payPwdRef.open()
})
onLoad(() => {
//
util.getPurse()
getConfig()
})
//
function handleSubmit() {
//
if (!form.account) {
util.alert('请输入账号')
return
}
if (!form.fruitAmount) {
util.alert('请输入榴莲果转账数量')
return
}
// id
api.mine.getUserDataByAccount({
query: {
account: form.account,
},
}).then(rs => {
if (rs.code === 200) {
const result = rs.data
// id
form.targetUserId = result.userName
form.name = result.userRealName.slice(1, result.userRealName.length)
//
proxy.$refs.payee.open()
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
})
}
//
function handlePayeeConfirm() {
//
if (!form.first) {
util.alert('请输入对方姓名首字母')
return
}
api.durian.nameComparison({
query: {
//
account: form.account,
//
name: `${form.first}${form.name}`,
}
}).then(rs => {
if (rs.code == 200) {
if (rs.data) proxy.$refs.payPwdRef.open()
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
})
}
/**
* 交易
* @param {Object} ev 二级密码
*/
function handlePwdConfirm(ev) {
//
if (!form.first) {
util.alert('请输入对方姓名首字母')
return
}
if (!form.first) {
util.alert('请输入对方姓名首字母')
return
}
if (!form.account) {
util.alert('请输入账号')
return
}
if (!form.fruitAmount) {
util.alert('请输入榴莲果转账数量')
return
}
//
function handleSubmit() {
//
if (!form.account) {
util.alert('请输入账号')
api.durian.consume({
data: {
//
userId: userinfo.value.id,
// id
targetUserId: form.targetUserId,
//
transactionType: 10,
//
fruitAmount: form.fruitAmount,
//
name: `${form.first}${form.name}`,
//
account: form.account,
//
secondPassword: ev
}
}).then(rs => {
if (rs.code === 200) {
//
util.getPurse()
return
}
if (!form.fruitAmount) {
util.alert('请输入榴莲果转账数量')
return
}
// id
api.mine.getUserDataByAccount({
query: {
account: form.account,
},
}).then(rs => {
if (rs.code === 200) {
const result = rs.data
// id
form.targetUserId = result.userName
form.name = result.userRealName.slice(1, result.userRealName.length)
//
proxy.$refs.payee.open()
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
util.alert({
content: rs.msg,
showCancel: false,
})
}
})
}
//
function handlePayeeConfirm() {
//
if (!form.first) {
util.alert('请输入对方姓名首字母')
return
//
function navigateToPage(path) {
uni.navigateTo({
url: path
})
}
//
function getConfig() {
api.durian.durianFruitConfig().then(rs => {
if (rs.code == 200) {
configData.minConsumption = rs.data.minConsumption
configData.platformPercentage = +rs.data.platformPercentage * 100
return;
}
api.durian.nameComparison({
query: {
//
account: form.account,
//
name: `${form.first}${form.name}`,
}
}).then(rs => {
if (rs.code == 200) {
if (rs.data) proxy.$refs.payPwdRef.open()
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
util.alert({
content: rs.msg,
showCancel: false,
})
}
/**
* 交易
* @param {Object} ev 二级密码
*/
function handlePwdConfirm(ev) {
//
if (!form.first) {
util.alert('请输入对方姓名首字母')
return
}
if (!form.first) {
util.alert('请输入对方姓名首字母')
return
}
if (!form.account) {
util.alert('请输入账号')
return
}
if (!form.fruitAmount) {
util.alert('请输入榴莲果转账数量')
return
}
//
api.durian.consume({
data: {
//
userId: userinfo.value.id,
// id
targetUserId: form.targetUserId,
//
transactionType: 10,
//
fruitAmount: form.fruitAmount,
//
name: `${form.first}${form.name}`,
//
account: form.account,
//
secondPassword: ev
}
}).then(rs => {
if (rs.code === 200) {
//
util.getPurse()
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
})
}
//
function navigateToPage(path) {
uni.navigateTo({
url: path
})
}
})
}
</script>
<template>
@ -221,7 +245,7 @@
<image class="wh110" src="/static/sapling.png" mode="aspectFit" />
</view>
<view class="f1 fmid">
<view class=" f38 b wsn">* {{purse.seed}}</view>
<view class=" f38 b wsn">* {{ purse.seed }}</view>
</view>
</view>
</view>
@ -254,8 +278,8 @@
<navigator url="/pages/index/durianLog" hover-class="none">
<image class="fruit wh150" src="/static/fruit.png" mode="aspectFit" />
<view class="mt30 f20">
<view class=" f1 b">可用: {{purse.fruit}}</view>
<view class="cFF4242 f1 mt10">待释放: 105.53</view>
<view class=" f1 b">可用: {{ purse.fruit }}</view>
<view class="cFF4242 f1 mt10">待释放: {{ purse.fruitFrozen }}</view>
</view>
</navigator>
</view>
@ -296,8 +320,8 @@
</view>
<view class="hint mtb30 tac f22">
<view>销毁15%</view>
<view>(最低x起转)</view>
<view>销毁{{ configData.platformPercentage }}%</view>
<view>(最低{{ configData.minConsumption }}起转)</view>
</view>
<view class="button btn lg bar black" @click="handleSubmit">转移</view>
@ -314,7 +338,7 @@
<view class="inputBox rows mauto mtb20 plr30">
<input class="first" v-model.trim="form.first" type="text" placeholder="" />
<view class="">*</view>
<view class="f1 tar">{{form.name}}</view>
<view class="f1 tar">{{ form.name }}</view>
</view>
<view class="rows mt50">
@ -330,64 +354,64 @@
</template>
<style lang="scss">
//
.board {
background-image: linear-gradient(103deg, #27EFE2 0%, #A45EFF 43%, #FF004F 100%);
}
//
.board {
background-image: linear-gradient(103deg, #27EFE2 0%, #A45EFF 43%, #FF004F 100%);
}
//
.bgColor {
background-color: #FFFBF3;
border-radius: 20rpx;
}
//
.bgColor {
background-color: #FFFBF3;
border-radius: 20rpx;
}
.explain {
.button {
width: 250rpx;
margin-left: 0;
.explain {
.button {
width: 250rpx;
margin-left: 0;
}
}
//
.sapling {
.button {
width: 300rpx;
}
}
//
.durianSection {
//
.notice {
.key {
width: 140rpx;
height: 70rpx;
color: #fff;
background: linear-gradient(99deg, #27efe2 0%, #a45eff 43%, #ff004f 100%), linear-gradient(108deg, #d7f550 -2%, #afef4d 98%);
border-radius: 100rpx;
}
}
}
//
.sapling {
.button {
width: 300rpx;
}
//
.dealAlt {
.hint {
color: #3d3d3d;
opacity: .7;
}
}
//
.payee {
.inputBox {
width: 120rpx;
box-shadow: 0 0 20rpx rgba(0, 0, 0, .2);
}
//
.durianSection {
//
.notice {
.key {
width: 140rpx;
height: 70rpx;
color: #fff;
background: linear-gradient(99deg, #27efe2 0%, #a45eff 43%, #ff004f 100%), linear-gradient(108deg, #d7f550 -2%, #afef4d 98%);
border-radius: 100rpx;
}
}
}
//
.dealAlt {
.hint {
color: #3d3d3d;
opacity: .7;
}
}
//
.payee {
.inputBox {
width: 120rpx;
box-shadow: 0 0 20rpx rgba(0, 0, 0, .2);
}
.first {
width: 50rpx;
}
.first {
width: 50rpx;
}
}
</style>

View File

@ -1,161 +1,168 @@
<script setup>
/**
* 添加朋友
*/
/**
* 添加朋友
*/
//
import util from '@/common/js/util';
// api
import api from '@/api/index.js'
import {
useStore,
} from 'vuex'
import {
ref,
reactive,
computed,
getCurrentInstance
} from 'vue'
import {
onLoad,
onReady,
onReachBottom,
onPullDownRefresh
} from '@dcloudio/uni-app'
//
const {
proxy
} = getCurrentInstance()
// vuex
const store = useStore()
//
const userinfo = computed(() => {
let result = store.state.userinfo
return result
})
//
const userList = reactive({
data: [],
pageNum: 1,
pageSize: 10,
total: 0,
})
const keyword = ref('')
//
const form = reactive({
Remark: '',
AddWording: '',
})
//
const friend = ref({})
//
import util from '@/common/js/util';
// api
import api from '@/api/index.js'
import {
useStore,
} from 'vuex'
import {
ref,
reactive,
computed,
getCurrentInstance
} from 'vue'
import {
onLoad,
onReady,
onReachBottom,
onPullDownRefresh
} from '@dcloudio/uni-app'
//
const {
proxy
} = getCurrentInstance()
// vuex
const store = useStore()
//
const userinfo = computed(() => {
let result = store.state.userinfo
return result
})
//
const userList = reactive({
data: [],
pageNum: 1,
pageSize: 10,
total: 0,
})
const keyword = ref('')
//
const form = reactive({
Remark: '',
AddWording: '',
})
//
const friend = ref({})
onReady(() => {
// proxy.$refs.friendRef.open()
})
onReachBottom(() => {
//
getMoreFriendList()
})
onPullDownRefresh(() => {
onLoad((option) => {
if (option.account) {
keyword.value = option.account
refreshFriendList()
})
}
})
//
function getSearchFriendList() {
if (!keyword.value) {
util.alert('请输入你想搜索的内容')
onReady(() => {
// proxy.$refs.friendRef.open()
})
onReachBottom(() => {
//
getMoreFriendList()
})
onPullDownRefresh(() => {
refreshFriendList()
})
//
function getSearchFriendList() {
if (!keyword.value) {
util.alert('请输入你想搜索的内容')
return
}
api.news.searchUsers({
query: {
searchValue: keyword.value,
pageNum: userList.pageNum,
pageSize: userList.pageSize,
}
}).then(rs => {
if (rs.code == 200) {
const result = rs.data
if (userList.pageNum) userList.data.length = 0
//
userList.data.push(...result.rows.map(item => {
item.format_userPortrait = util.format_url(item.userPortrait, 'img')
return item
}))
//
userList.total = rs.total
return
}
api.news.searchUsers({
query: {
searchValue: keyword.value,
pageNum: userList.pageNum,
pageSize: userList.pageSize,
}
}).then(rs => {
if (rs.code == 200) {
const result = rs.data
if (userList.pageNum) userList.data.length = 0
//
userList.data.push(...result.rows.map(item => {
item.format_userPortrait = util.format_url(item.userPortrait, 'img')
return item
}))
//
userList.total = rs.total
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
}).finally(() => {
uni.stopPullDownRefresh()
util.alert({
content: rs.msg,
showCancel: false,
})
}
}).finally(() => {
uni.stopPullDownRefresh()
})
}
//
function refreshFriendList() {
userList.pageNum = 1
userList.total = 0
getSearchFriendList()
}
//
function refreshFriendList() {
userList.pageNum = 1
userList.total = 0
getSearchFriendList()
}
//
function getMoreFriendList() {
if (userList.data.length >= userList.total) return
userList.pageNum++
getSearchFriendList()
}
//
function getMoreFriendList() {
if (userList.data.length >= userList.total) return
userList.pageNum++
getSearchFriendList()
}
//
function handleUser(item) {
uni.navigateTo({
url: util.setUrl('/pages/index/videoHome', {
userId: item.userId,
})
//
function handleUser(item) {
uni.navigateTo({
url: util.setUrl('/pages/index/videoHome', {
userId: item.userId,
})
}
})
}
/**
* 添加好友
* @param {Object} item 用户信息
*/
function handleAdd(item) {
friend.value.userId = item.userId
friend.value.userName = item.userName
friend.value.AddWording = `你好,我是${userinfo.value.userNickname}`
proxy.$refs.friendRef.open()
}
/**
* 添加好友
* @param {Object} item 用户信息
*/
function handleAdd(item) {
friend.value.userId = item.userId
friend.value.userName = item.userName
friend.value.AddWording = `你好,我是${userinfo.value.userNickname}`
proxy.$refs.friendRef.open()
}
//
function pushNickname() {
friend.value.Remark = friend.value.userName
}
//
function pushNickname() {
friend.value.Remark = friend.value.userName
}
//
function addFriendConfirm() {
api.news.addFriend({
data: [{
toAccount: friend.value.userId,
addWording: friend.value.AddWording,
remark: friend.value.Remark,
}],
}).then(rs => {
if (rs.code == 200) {
util.alert('已发送好友申请,请等待对方同意')
proxy.$refs.friendRef.close()
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
//
function addFriendConfirm() {
api.news.addFriend({
data: [{
toAccount: friend.value.userId,
addWording: friend.value.AddWording,
remark: friend.value.Remark,
}],
}).then(rs => {
if (rs.code == 200) {
util.alert('已发送好友申请,请等待对方同意')
proxy.$refs.friendRef.close()
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
}
})
}
</script>
<template>
<view class="app">
@ -169,14 +176,14 @@
</view>
<view class="listArea plr30 bfff">
<view class="item rows ptb30 c333 f32" v-for="(item,index) in userList.data" :key="index"
<view class="item rows ptb30 c333 f32" v-for="(item, index) in userList.data" :key="index"
@click="handleUser(item)">
<view class="avatar fs0">
<image class="wh100 cir" :src="item.imageUrl" mode="aspectFill" />
</view>
<view class="content f1 mlr20">
<view class="name">{{item.userName}}</view>
<view class="name">{{ item.userName }}</view>
<!-- <view class="time c999 f22">{{item.createTime}}</view> -->
</view>
@ -227,14 +234,14 @@
</template>
<style lang="scss" scoped>
.search {
background-color: #eaeaea;
}
.search {
background-color: #eaeaea;
}
//
.listArea {
.item+.item {
border-top: 1rpx solid #ddd;
}
//
.listArea {
.item+.item {
border-top: 1rpx solid #ddd;
}
}
</style>

View File

@ -12,6 +12,8 @@ import {
screenHeight
} from '@/components/public/Mixins'
import JyCommodityInformation from '@/components/public/jy-commodity-information'
// api
import api from '@/api/index.js'
//
import util from '@/common/js/util.js'
import { inject } from 'vue'
@ -75,6 +77,9 @@ const popupData = reactive({
title: '选择订单'
})
//
const list = reactive([])
//
const plusClickObj = {
voice: () => {
@ -109,14 +114,49 @@ const plusClickObj = {
//
chooseOrder: () => {
nextTick().then(() => {
popupRef.value.open()
});
let param = {
pageSize: 10,
pageNum: 1,
merId: props.msg.id,
}
api.shop.getShopOrderList(param).then(rs => {
if (rs.code == 200) {
list.length = 0
list.push(...rs.rows.map(item => {
//
item.status = Number(item.status)
//
item.status_text = {
'0': '待支付',
'1': '待发货',
'4': '待收货',
'5': '已收货',
'6': '已完成',
'9': '已取消',
}[item.status]
return item
}))
nextTick().then(() => {
popupRef.value.open()
});
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
})
},
//
chooseShop: () => {
checkLink('pages/news/goodsList/index')
uni.navigateTo({
url: `/pages/news/goodsList/index?merId=${props.msg.id}`
});
},
//
@ -228,11 +268,11 @@ const consult = (content) => {
</uni-easyinput>
</view>
<scroll-view scroll-y scroll-with-animation>
<view v-for="(item, index) in 2">
<view v-for="(item, index) in list" :key="index">
<view class="time">
下单时间2024-07-28 22:45:25
下单时间{{ item.createTime }}
</view>
<JyCommodityInformation :showType="4" @consult="consult"></JyCommodityInformation>
<JyCommodityInformation :showType="4" :orderInfo="item" @consult="consult"></JyCommodityInformation>
</view>
</scroll-view>
</view>

View File

@ -1,22 +1,122 @@
<script setup>
/**
* 客服聊天界面商品列表
*/
import {
reactive,
defineExpose,
} from 'vue'
//
import util from '@/common/js/util.js'
// api
import api from '@/api/index.js'
//
import JyCommodityInformation from '@/components/public/jy-commodity-information'
import { onLoad } from "@dcloudio/uni-app"
//
const listPrototype = reactive({
pageSize: 10,
pageNum: 1,
total: 0,
merId: '',
data: [],
})
onLoad(option => {
getList(option)
})
/**
* 点击列表项
* @param {Object} item 列表项
*/
function handleItem(item) {
//
uni.navigateTo({
url: util.setUrl('/pages/shop/commodity/index', {
productId: item.id
})
})
}
//
function refreshList() {
listPrototype.pageNum = 1
listPrototype.total = 0
getList()
}
//
function getMoreList() {
console.log('getMoreList', listPrototype)
if (listPrototype.total <= listPrototype.data.length) return
listPrototype.pageNum++
getList()
}
//
function getList(option) {
let param = {
pageSize: listPrototype.pageSize,
pageNum: listPrototype.pageNum,
merId: option.merId
}
api.shop.getShopProductList(param).then(rs => {
if (rs.code == 200) {
if (listPrototype.pageNum == 1) listPrototype.data.length = []
listPrototype.data.push(...rs.rows)
listPrototype.total = rs.total
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
}).finally(rs => {
uni.stopPullDownRefresh()
})
}
//
function sendProduct(item) {
console.log('发送商品', item);
}
defineExpose({
getList,
listPrototype,
refreshList,
getMoreList,
})
</script>
<template>
<view class="appbw">
<scroll-view scroll-y scroll-with-animation>
<view v-for="(item, index) in 10">
<JyCommodityInformation :showType="5"></JyCommodityInformation>
<view class="list">
<view class="product line df ptb20 plr20" v-for="(item, index) in listPrototype.data" :key="index"
@click="handleItem(item)">
<view class="poster wh160">
<image class="wh160 br10" :src="item.sliderImage.split(',')[0]" mode="aspectFill" />
</view>
</scroll-view>
<view class="info df fdc jcsb f1 ml20">
<view class="name t2hd c333 f28">{{ item.name }}</view>
<view class="other rows">
<view class="col c333">
<text class="f20"></text>
<text class="f30">{{ item.price }}</text>
<text class="count ml20 fs0 c999 f24">销量{{ item.sales }}</text>
</view>
<view @click.stop="sendProduct(item)" class="btn ti warmHollow plr20">去咨询</view>
</view>
</view>
</view>
</view>
</template>
<style lang="scss" scoped></style>
<style scoped lang="scss"></style>

View File

@ -1,63 +1,62 @@
<script setup>
//
import uQRCode from '@/common/js/uqrcode.js'
//
import uQRCode from '@/common/js/uqrcode.js'
import {
ref,
reactive,
computed,
} from 'vue'
import {
useStore,
} from 'vuex'
import {
onLoad,
} from '@dcloudio/uni-app'
// vuex
const store = useStore()
//
const userinfo = computed(() => {
let result = store.state.userinfo
return result
import {
ref,
reactive,
computed,
} from 'vue'
import {
useStore,
} from 'vuex'
import {
onLoad,
} from '@dcloudio/uni-app'
//
import util from '@/common/js/util';
// vuex
const store = useStore()
//
const userinfo = computed(() => {
let result = store.state.userinfo
return result
})
//
const qrcodeSize = ref(300)
//
const qrUrl = ref('')
onLoad(() => {
init()
})
//
function init() {
uni.showLoading({
title: '二维码生成中',
mask: true
})
//
const qrcodeSize = ref(300)
//
const qrUrl = ref('')
let url = `${util.config.host}/#/pages/news/addFriend?account=${userinfo.value.account}`
console.log(url);
onLoad(() => {
init()
})
//
function init() {
uni.showLoading({
title: '二维码生成中',
mask: true
})
//
const content = {
key: 'user',
userId: userinfo.value.userId,
userNickname: userinfo.value.userNickname,
uQRCode.make({
canvasId: 'qrcode',
text: url,
size: qrcodeSize.value,
margin: 10,
success: res => {
qrUrl.value = res
// console.log('qrcodeSrc ', qrUrl.value);
},
complete: () => {
uni.hideLoading()
}
uQRCode.make({
canvasId: 'qrcode',
text: JSON.stringify(content),
size: qrcodeSize.value,
margin: 10,
success: res => {
qrUrl.value = res
console.log('qrcodeSrc ', qrUrl.value);
},
complete: () => {
uni.hideLoading()
}
})
}
})
}
</script>
<template>
@ -65,13 +64,13 @@
<!-- -->
<view class="container ver mtb30 mlr30 tac">
<!-- 二维码插件 width height设置宽高 -->
<canvas canvas-id="qrcode" :style="{width: `${qrcodeSize}px`, height: `${qrcodeSize}px`}" />
<canvas canvas-id="qrcode" :style="{ width: `${qrcodeSize}px`, height: `${qrcodeSize}px` }" />
<view class="user mtb30 df aic">
<view class="avatar">
<image class="wh80 cir" :src="userinfo.userPortrait" mode="aspectFill" />
</view>
<view class="nickname f1 ml20 c333 f32">{{userinfo.userNickname}}</view>
<view class="nickname f1 ml20 c333 f32">{{ userinfo.userNickname }}</view>
</view>
<view class="hint mtb30 tac c999">扫一扫添加我为好友</view>
@ -80,5 +79,4 @@
</template>
<style lang="scss">
//
</style>
// </style>

View File

@ -5,6 +5,7 @@ import uni from '@dcloudio/vite-plugin-uni';
// let target = 'http://91f.xyz:8080'
let target = 'https://b433d23.r24.cpolar.top/'
// let target = 'http://hvw2rn.natappfree.cc'
export default defineConfig({

View File

@ -8,20 +8,21 @@ export default {
//
const token = uni.getStorageSync('token')
//
const userinfo = uni.getStorageSync('userinfo')
const userinfo = JSON.parse(uni.getStorageSync('userinfo'))
//
if (token) {
//
if (userinfo) store.commit('setState', {
key: 'userinfo',
value: userinfo
})
if (userinfo) {
store.commit('setState', {
key: 'userinfo',
value: userinfo
})
// // im
// util.getUserinfo().then(rs => {
// util.loginTencent(userinfo)
// })
// IM
// util.loginTencent(userinfo)
}
} else {
//
uni.redirectTo({

View File

@ -35,7 +35,8 @@ const login = {
userLoginOut(param) {
return util.request({
url: '/user/customerService/logout',
data: param.data,
method: 'POST',
query: param,
load: true,
})
},

View File

@ -2,7 +2,7 @@
const config = {
// 接口域名
// #ifdef H5
host: 'http://localhost:5173',
host: 'http://localhost:8888',
// #endif
// #ifndef H5
// host: 'http://91f.xyz:8080',

View File

@ -1433,31 +1433,33 @@ const util = {
// 登录腾讯聊天
loginTencent(userinfo) {
api.login.getIMToken({}).then(rs => {
//
console.log(rs);
const imSig = rs.msg
// #ifdef APP
// 音视频登录
const loginParams = {
SDKAppID: util.config.TChat.SDKAppID,
userID: userinfo.id + '',
userSig: imSig,
}
uni.$TUICallKit.login(loginParams, res => {
if (res.code === 0) {
console.log('[TUICallKit] login success.');
} else {
console.error('[TUICallKit] login failed, failed message = ', res.msg, params);
}
})
// #endif
uni.$chat.login({
userID: userinfo.id + '',
userID: userinfo.serviceId + '',
userSig: imSig,
}).then(rs => {
console.log('im login success', rs)
})
// // #ifdef APP
// // 音视频登录
// const loginParams = {
// SDKAppID: util.config.TChat.SDKAppID,
// userID: userinfo.id + '',
// userSig: imSig,
// }
// uni.$TUICallKit.login(loginParams, res => {
// if (res.code === 0) {
// console.log('[TUICallKit] login success.');
// } else {
// console.error('[TUICallKit] login failed, failed message = ', res.msg, params);
// }
// })
// // #endif
})
},
@ -1545,10 +1547,13 @@ const util = {
*/
logout(cb) {
// 用户信息
const userinfo = store.state.userinfo
const userinfo = JSON.parse(uni.getStorageSync('userinfo'))
console.log(userinfo.serviceId);
// 用户id
if (userinfo.id) {
if (userinfo.serviceId) {
uni.$emit('logout') // 触发自定义事件监听
// tim登出
@ -1558,7 +1563,7 @@ const util = {
console.log('tim logout error:', rs);
});
api.login.userLoginOut().then(rs => {
api.login.userLoginOut({ serviceId: userinfo.serviceId }).then(rs => {
setTimeout(() => {
uni.navigateTo({
url: '/pages/login/login',

View File

@ -17,31 +17,28 @@ import {
} from '@dcloudio/uni-app'
//
import util from '@/common/js/util.js'
//
import TencentCloudChat from '@tencentcloud/chat';
const chatList = reactive([{
id: 1,
avatar: 'https://p3-flow-imagex-sign.byteimg.com/user-avatar/9f4488a87a17f6f31b9716331e14fe26~tplv-a9rns2rl98-icon-tiny.jpeg?rk3s=98c978ad&x-expires=1740537084&x-signature=OrjX8tZaafN4XJE2o8QzZDs3Q20%3D',
name: '客户 A',
lastMessage: '您好,商品什么时候发货?',
dot: 1,
},
{
id: 2,
avatar: 'https://p3-flow-imagex-sign.byteimg.com/user-avatar/9f4488a87a17f6f31b9716331e14fe26~tplv-a9rns2rl98-icon-tiny.jpeg?rk3s=98c978ad&x-expires=1740537084&x-signature=OrjX8tZaafN4XJE2o8QzZDs3Q20%3D',
name: '客户 B',
lastMessage: '这个商品有优惠吗?',
dot: '',
}
])
const chatList = reactive([])
//
const userinfo = JSON.parse(uni.getStorageSync('userinfo'))
console.log(userinfo);
//
const rightOption = [{
text: '删除',
style: {
backgroundColor: '#F85050'
},
fn: (item) => delMsg(item)
}, {
text: '设为已读',
style: {
backgroundColor: '#00ADEE'
},
fn: (item) => setRead(item)
},]
onMounted(() => {
getList()
@ -74,7 +71,27 @@ function getList() {
}
}).then(rs => {
if (rs.code == 200) {
// list.data = handleList(rs.data);
chatList.push(...rs.data.map(item => {
item.callbackData = JSON.parse(item.callbackJson)
if (item.callbackData.callback_json.length) {
let msgType = item.callbackData.callback_json[0].MsgType;
if (msgType == TencentCloudChat.TYPES.MSG_TEXT) {
item.chatText = item.callbackData.callback_json[0].MsgContent.Text
} else if (msgType == TencentCloudChat.TYPES.MSG_IMAGE) {
item.chatText = '[图片]'
} else if (msgType == TencentCloudChat.TYPES.MSG_AUDIO) {
item.chatText = '[语音]'
} else if (msgType == TencentCloudChat.TYPES.MSG_VIDEO) {
item.chatText = '[视频]'
} else if (msgType == TencentCloudChat.TYPES.MSG_CUSTOM) {
if (item.callbackData.callback_json[0].businessType == 'redPacket') {
item.chatText = `[红包] ${item.callbackData.blessing}`
}
}
}
return item
}))
return
}
util.alert({
@ -84,26 +101,23 @@ function getList() {
})
}
// /**
// *
// * @param {Number} item
// */
// function handleChat(item) {
// //
// }
/**
* 去聊天
* @param {Number} item 聊天对象
*/
function handleChat(item) {
//
}
/**
* 跳转
* @param {String} url 路由地址
*/
function link(url) {
uni.navigateTo({
url,
})
}
// /**
// *
// * @param {String} url
// */
// function link(url) {
// uni.navigateTo({
// url,
// })
// }
// 退
@ -120,6 +134,78 @@ function handleLogout() {
})
})
}
/**
* 去聊天
* @param {Object} item
*/
function handleChat(item) {
let param = {};
//
if (item.groupId == null) {
param.type = 'C2C'
param.name = `${item.callbackJson.from_name}`
param.msgId = `${item.callbackJson.from_id}`
} else {
//
param.type = 'GROUP'
param.name = `${item.groupChatDTO.name}`
param.msgId = `${item.groupId}`
param.num = `${item.groupChatDTO.memberCount}`
}
//
util.toChat(param)
}
/**
* 菜单
* @param {Object} ev 默认事件
* @param {Object} item 单项
*/
function handleMenu(ev, item) {
console.log('ev', ev, item)
ev.content.fn(item)
proxy.$refs.swipeAction.closeAll()
}
//
function delMsg(item) {
// sdk
let isReady = uni.$chat.isReady();
if (!isReady) {
setTimeout(function () {
delMsg(item);
}, 200);
return
}
let conversationId = item.groupId == null ? `C2C${item.fromId}` : `GROUP${item.groupId}`;
uni.$chat.deleteConversation(conversationId).then(rs => {
getList()
})
}
//
function setRead(item) {
// sdk
let isReady = uni.$chat.isReady();
if (!isReady) {
setTimeout(function () {
setRead(item);
}, 200);
return
}
let conversationId = item.groupId == null ? `C2C${item.fromId}` : `GROUP${item.groupId}`;
uni.$chat.setMessageRead({
conversationID: conversationId,
}).then(rs => {
getList()
})
}
</script>
<template>
@ -148,7 +234,7 @@ function handleLogout() {
<uni-icons type="right" />
</view>
<view class="list">
<!-- <view class="list">
<view class="item rows ptb20 plr20" v-for="(item, index) in chatList" :key="index"
@click="handleChat(item)">
<view class="avatar">
@ -169,6 +255,47 @@ function handleLogout() {
</view>
</view>
</view>
</view> -->
<view class="firendBox pr">
<scroll-view scroll-y="true" class="scroll">
<uni-swipe-action ref="swipeAction">
<view class="list pb30">
<uni-swipe-action-item :right-options="rightOption" v-for="(item, index) in chatList"
:key="index" @click="handleMenu($event, item)">
<view class="item rows ptb20 plr30" @click="handleChat(item)">
<view class="image wh90 pr">
<template v-if="item.groupId == null">
<image class="cir wh90" :src="item.callbackJson.from_url" mode="aspectFill" />
</template>
<template v-else>
<image class="cir wh90" :src="item.groupChatDTO.groupFaceUrl"
mode="aspectFill" />
</template>
<view class="mark pa t0 r0 cfff f22 cir" v-if="item.unreadCount">{{ item.unreadCount
}}
</view>
</view>
<view class="col f1 ml20">
<view class="rows">
<template v-if="item.groupId == null">
<view class="name f1 thd c333 f32">{{ item.callbackJson.from_name }}</view>
</template>
<template v-else>
<view class="name f1 thd c333 f32">{{ item.groupChatDTO.name }}</view>
</template>
<view class="datetime c999 f22">
{{ util.formatTime('MM-dd HH:mm', item.createTime) }}</view>
</view>
<view class="desc thd mt10 c666 f24">{{ item.chatText }}</view>
</view>
</view>
</uni-swipe-action-item>
<view class="mtb20 tac c999 f20">到底啦~</view>
</view>
</uni-swipe-action>
</scroll-view>
</view>
</view>
</template>
@ -194,25 +321,56 @@ function handleLogout() {
}
}
//
.list {
.item {
border-top: 1rpx solid #eee;
//
.firendBox {
height: 100%;
.scroll {
height: 100%;
}
//
.list {
//
.mark,
.dot {
background-color: #FF6B17;
text-align: center;
line-height: 30rpx;
}
.mark {
width: 30rpx;
height: 30rpx;
}
.dot {
padding: 5rpx;
border-radius: 100rpx;
background-color: #f00;
//
.content {
display: flex;
justify-content: center;
align-items: center;
width: 20rpx;
height: 20rpx;
}
width: 20rpx;
height: 20rpx;
}
}
}
</style>
// //
// .list {
// .item {
// border-top: 1rpx solid #eee;
// .dot {
// padding: 5rpx;
// border-radius: 100rpx;
// background-color: #f00;
// //
// .content {
// display: flex;
// justify-content: center;
// align-items: center;
// width: 20rpx;
// height: 20rpx;
// }
// }
// }
// }</style>

View File

@ -10,7 +10,7 @@ export default defineConfig({
plugins: [uni()],
server: {
host: "0.0.0.0",
port: 5173,
port: 8888,
proxy: {
"/system": {
target,