feat:会员动态配置

This commit is contained in:
dzc committed 2025-12-11 13:02:03 +08:00
1 parent 3829bc3ddb
commit c554c4e7c3
3 files changed
+312 -348

No files matched your search

+114 -140
View File
@@ -6,10 +6,7 @@
</template>
<template #right>
<navigator hover-class="navigator-hover">
<view
class="bg-color-theme px-3 py-1 rounded-full c-black h-1/2 line-height-normal"
@click="publishMoments"
>
<view class="bg-color-theme px-3 py-1 rounded-full c-black h-1/2 line-height-normal" @click="publishMoments">
发布
</view>
</navigator>
@@ -21,157 +18,134 @@
<wd-tabs v-model="activeTab">
<wd-tab title="发图文">
<view class="px-4 py-8">
<wd-upload
v-model:file-list="params.coverPic"
:action="baseUrl + apiPath + '/infra/file/upload'"
:header="header"
image-mode="aspectFill"
accept="image"
multiple
:limit="6"
:max-size="500000"
/>
<wd-upload v-model:file-list="params.coverPic" :action="baseUrl + apiPath + '/infra/file/upload'"
:header="header" image-mode="aspectFill" accept="image" multiple :limit="6" :max-size="500000" />
</view>
</wd-tab>
<wd-tab v-if="false" title="发视频">
<view class="px-4 py-8">
<wd-upload
v-model:file-list="params.coverVideo"
:action="baseUrl + apiPath + '/infra/file/upload'"
:header="header"
image-mode="aspectFill"
accept="video"
multiple
:limit="6"
:max-size="2000000"
/>
<wd-upload v-model:file-list="params.coverVideo" :action="baseUrl + apiPath + '/infra/file/upload'"
:header="header" image-mode="aspectFill" accept="video" multiple :limit="6" :max-size="2000000" />
</view>
</wd-tab>
</wd-tabs>
<wd-col-picker
label="选择地址"
title="选择地址"
align-right
v-model="addressValue"
:columns="area"
:column-change="columnChange"
@confirm="areaPickerConfirm"
/>
<wd-col-picker label="选择地址" title="选择地址" align-right v-model="addressValue" :columns="area"
:column-change="columnChange" @confirm="areaPickerConfirm" />
</scroll-view>
</wd-config-provider>
</template>
<script setup lang="ts">
import { computed, reactive, ref } from 'vue';
import RecentApi from '@/sheep/api/member/recent';
import { useColPickerData } from '@/sheep/hooks/use-col-picker-data';
import { type ColPickerColumnChange } from '@/uni_modules/wot-design-uni/components/wd-col-picker/types';
// @ts-ignore
import { baseUrl, apiPath, tenantId } from '@/sheep/config';
// @ts-ignore
import { getAccessToken } from '@/sheep/request';
import { onLoad } from '@dcloudio/uni-app';
import { computed, reactive, ref } from 'vue';
import RecentApi from '@/sheep/api/member/recent';
import { useColPickerData } from '@/sheep/hooks/use-col-picker-data';
import { type ColPickerColumnChange } from '@/uni_modules/wot-design-uni/components/wd-col-picker/types';
// @ts-ignore
import { baseUrl, apiPath, tenantId } from '@/sheep/config';
// @ts-ignore
import { getAccessToken } from '@/sheep/request';
import { onLoad } from '@dcloudio/uni-app';
const { colPickerData, findChildrenByCode } = useColPickerData();
const { colPickerData, findChildrenByCode } = useColPickerData();
const activeTab = ref<0 | 1>(0);
const addressValue = ref<string[]>([]);
const params = reactive({
coverPic: [],
coverVideo: [],
description: '',
issueLong: '0',
issueLat: '0',
issueProvince: '',
issueCity: '',
issueDistrict: '',
});
const coverPic = computed(() => {
return params.coverPic.map((item: any) => JSON.parse(item.response).data);
});
const coverVideo = computed(() => {
return params.coverVideo.map((item: any) => JSON.parse(item.response).data);
});
const area = ref<any[]>([
colPickerData.map((item) => {
return {
value: item.value,
label: item.text,
};
}),
]);
const activeTab = ref<0 | 1>(0);
const addressValue = ref<string[]>([]);
const params = reactive({
coverPic: [],
coverVideo: [],
description: '',
issueLong: '0',
issueLat: '0',
issueProvince: '',
issueCity: '',
issueDistrict: '',
});
const coverPic = computed(() => {
return params.coverPic.map((item: any) => JSON.parse(item.response).data);
});
const coverVideo = computed(() => {
return params.coverVideo.map((item: any) => JSON.parse(item.response).data);
});
const area = ref<any[]>([
colPickerData.map((item) => {
return {
value: item.value,
label: item.text,
};
}),
]);
const columnChange: ColPickerColumnChange = ({ selectedItem, resolve, finish }) => {
const areaData = findChildrenByCode(colPickerData, selectedItem.value);
if (areaData && areaData.length) {
resolve(
areaData.map((item) => {
return {
value: item.value,
label: item.text,
};
}),
);
} else {
finish();
}
};
// 地址选择器确认
const areaPickerConfirm = ({
value,
selectedItems,
}: {
value: string[];
selectedItems: { value: string; label: string }[];
}) => {
params.issueProvince = selectedItems[0].label;
params.issueCity = selectedItems[1].label;
params.issueDistrict = selectedItems[2].label;
};
// 获取经纬度位置信息
const getLocation = () => {
uni.getLocation({
success: (res) => {
params.issueLat = String(res.latitude);
params.issueLong = String(res.longitude);
},
fail: (err) => {
uni.showToast({ title: '位置信息获取失败,请打开系统定位', icon: 'none' });
},
});
};
const header = {
Accept: '*/*',
'tenant-id': tenantId,
Authorization: 'Bearer ' + getAccessToken(),
};
onLoad(() => {
getLocation();
});
// 发布朋友圈
const publishMoments = async () => {
if (!params.description || !params.issueProvince)
return uni.showToast({ title: '请填写内容', icon: 'error' });
if (!params.coverPic || !params.coverPic.length)
return uni.showToast({ title: '请上传图片', icon: 'error' });
getLocation();
await RecentApi.createMoment({
...params,
coverPic: coverPic.value.join(','),
coverVideo: coverVideo.value.join(','),
});
back();
};
// 返回
function back() {
uni.navigateBack();
const columnChange: ColPickerColumnChange = ({ selectedItem, resolve, finish }) => {
const areaData = findChildrenByCode(colPickerData, selectedItem.value);
if (areaData && areaData.length) {
resolve(
areaData.map((item) => {
return {
value: item.value,
label: item.text,
};
}),
);
} else {
finish();
}
};
// 地址选择器确认
const areaPickerConfirm = ({
value,
selectedItems,
}: {
value: string[];
selectedItems: { value: string; label: string }[];
}) => {
params.issueProvince = selectedItems[0].label;
params.issueCity = selectedItems[1].label;
params.issueDistrict = selectedItems[2].label;
};
// 获取经纬度位置信息
const getLocation = () => {
uni.getLocation({
success: (res) => {
params.issueLat = String(res.latitude);
params.issueLong = String(res.longitude);
},
fail: (err) => {
uni.showToast({ title: '位置信息获取失败,请打开系统定位', icon: 'none' });
},
});
};
const header = {
Accept: '*/*',
'tenant-id': tenantId,
Authorization: 'Bearer ' + getAccessToken(),
};
onLoad(() => {
getLocation();
});
// 发布朋友圈
const publishMoments = async () => {
if (!params.description || !params.issueProvince)
return uni.showToast({ title: '请填写内容', icon: 'error' });
if (!params.coverPic || !params.coverPic.length)
return uni.showToast({ title: '请上传图片', icon: 'error' });
getLocation();
await RecentApi.createMoment({
...params,
coverPic: coverPic.value.join(','),
coverVideo: coverVideo.value.join(','),
});
back();
};
// 返回
function back() {
uni.navigateBack();
}
</script>
+21 -1
View File
@@ -93,7 +93,7 @@
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import { computed, ref, reactive } from 'vue';
// @ts-ignore
import { fen2yuan } from '@/sheep/hooks/useGoods';
import { onLoad, onShow } from '@dcloudio/uni-app';
@@ -156,14 +156,34 @@ onLoad(async (params) => {
}
}
});
onShow(async () => {
const { data = null } = await RecentApi.getMemberOpenTypeList();
openTypeList.value = data ?? [];
if (openTypeList.value && openTypeList.value[0]) {
curOpenTypeId.value = openTypeList.value[0].id;
}
getChatConfig()
})
// 查询小程序配置
const getChatConfig = async () => {
try {
const { data } = await RecentApi.reportType()
if (data) {
console.log("data:", data);
if (data.vipLookWechtCout) {
benefits[0].subDesc = `每天${data.vipLookWechtCout == -1 ? '无限制' : data.vipLookWechtCout}个`
}
if (data.vipChatUserCout) {
benefits[1].subDesc = `每天${data.vipChatUserCout == -1 ? '无限制' : data.vipChatUserCout}个`
}
}
} catch (error) {
console.log("|获取聊天配置|,意外的错误error:", error);
}
}
// 开通会员
const handleOpenVip = () => {
if (!curOpenTypeId.value || !currentOpenType.value?.id) {
+177 -207
View File
@@ -9,15 +9,10 @@
</template>
</wd-navbar>
<!-- 用户信息 -->
<view
class="mx-20rpx mt-30rpx bg-color-dark rounded-12rpx flex justify-between items-center px-6 py-4"
>
<view class="mx-20rpx mt-30rpx bg-color-dark rounded-12rpx flex justify-between items-center px-6 py-4">
<view class="flex items-center">
<image
:src="userInfo.avatar"
class="size-50px rounded-full bg-#333 border border-amber border-solid"
mode="aspectFill"
/>
<image :src="userInfo.avatar" class="size-50px rounded-full bg-#333 border border-amber border-solid"
mode="aspectFill" />
<view class="flex-1 ml-20rpx">
<view class="mb-1 text-base">{{ userInfo.nickname }}</view>
<view class="mb-2 text-xs text-#ffffff80 flex items-center">
@@ -27,46 +22,30 @@
</view>
</view>
<view
class="text-color-theme-dark border-color-theme border-1px border-solid active_cl_bg-color-theme text-xs text-center px-2 py-8rpx rounded-full"
>
class="text-color-theme-dark border-color-theme border-1px border-solid active_cl_bg-color-theme text-xs text-center px-2 py-8rpx rounded-full">
退出登录
</view>
</view>
<!-- 提现相关 -->
<view class="mx-20rpx mt-30rpx bg-color-dark rounded-12rpx px-6 py-4">
<view class="flex items-center justify-center">
<view
class="flex-1 flex-col justify-center items-center"
v-for="(v, i) in state.txTab"
:key="i"
@tap="doTxItem(v)"
>
<view class="flex-1 flex-col justify-center items-center" v-for="(v, i) in state.txTab" :key="i"
@tap="doTxItem(v)">
<text class="text-color-theme text-2xl"> {{ v.value }}</text>
<text class="mt-10rpx">{{ v.title }}</text>
</view>
</view>
<view class="flex justify-center items-center mt-30rpx">
<text
class="bg-color-theme-dark active_cl_bg-color-theme text-base text-center px-80rpx py-12rpx rounded-full"
>
<text class="bg-color-theme-dark active_cl_bg-color-theme text-base text-center px-80rpx py-12rpx rounded-full">
立即提现
</text>
</view>
</view>
<!-- tab -->
<view
class="mx-20rpx mt-30rpx bg-color-dark rounded-12rpx py-4 flex justify-evenly items-center"
>
<view
class="flex-1 flex-col justify-center items-center"
v-for="(v, i) in data.menuTab"
:key="i"
@tap="doItem(v)"
>
<div
class="size-100rpx flex justify-center items-center rounded-full"
:style="{ backgroundColor: v.bgColor }"
>
<view class="mx-20rpx mt-30rpx bg-color-dark rounded-12rpx py-4 flex justify-evenly items-center">
<view class="flex-1 flex-col justify-center items-center" v-for="(v, i) in data.menuTab" :key="i"
@tap="doItem(v)">
<div class="size-100rpx flex justify-center items-center rounded-full" :style="{ backgroundColor: v.bgColor }">
<text class="iconfont text-2xl" :class="v.icon" />
</div>
<text class="mt-10rpx">{{ v.title }}</text>
@@ -76,14 +55,8 @@
<view class="mx-20rpx mt-30rpx bg-color-dark rounded-12rpx px-6 py-4">
<view class="text-lg">邀请奖励规则</view>
<view class="mt-30rpx">
<view
class="card-thin flex items-start px-16rpx py-12rpx mb-15rpx"
v-for="(v, i) in state.rule"
:key="i"
>
<view
class="size-40rpx flex justify-center items-center bg-color-theme-dark rounded-8rpx"
>
<view class="card-thin flex items-start px-16rpx py-12rpx mb-15rpx" v-for="(v, i) in state.rule" :key="i">
<view class="size-40rpx flex justify-center items-center bg-color-theme-dark rounded-8rpx">
<text class="text-base">{{ i + 1 }}</text>
</view>
<text class="ml-20rpx text-xs">{{ v.title }}</text>
@@ -97,15 +70,13 @@
<view class="mt-30rpx flex justify-between items-center text-xs">
<view
class="flex-1 text-center px-2 py-8rpx border-1px border-solid rounded-full border-color-theme active_cl_bg-color-theme"
@tap="copyLink"
>
@tap="copyLink">
复制链接
</view>
<view class="w-30rpx" />
<view
class="flex-1 text-center px-2 py-8rpx border-1px border-solid rounded-full border-color-theme-dark bg-color-theme-dark active_cl_bg-color-theme"
@tap="savePoster"
>
@tap="savePoster">
保存海报
</view>
</view>
@@ -115,182 +86,181 @@
</template>
<script setup>
import { computed, reactive, ref } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { computed, reactive, ref } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import sheep from '@/sheep';
import { fen2yuan } from '@/sheep/hooks/useGoods';
import BrokerageApi from '@/sheep/api/trade/brokerage';
import TradeConfigApi from '@/sheep/api/trade/config.js';
import SocialApi from '@/sheep/api/member/social';
import sheep from '@/sheep';
import { fen2yuan } from '@/sheep/hooks/useGoods';
import BrokerageApi from '@/sheep/api/trade/brokerage';
import TradeConfigApi from '@/sheep/api/trade/config.js';
import SocialApi from '@/sheep/api/member/social';
const userInfo = computed(() => sheep.$store('user').userInfo);
const userInfo = computed(() => sheep.$store('user').userInfo);
const data = {
menuTab: [
{
title: '礼物奖励',
icon: 'icon-liwu',
bgColor: '#fad34a',
path: '/pages/wechat/pages/gift/index',
},
{
title: '钻石充值',
icon: 'icon-lv_zuanshi_fill',
bgColor: '#ff5081',
path: '/pages/profile/recharge',
},
{
title: '会员中心',
icon: 'icon-huiyuan',
bgColor: '#ebc26a',
path: '/pages/profile/apply-vip',
},
{
title: '邀请好友',
icon: 'icon-tianjiahaoyou',
bgColor: '#a4e55a',
path: '',
},
],
};
const data = {
menuTab: [
{
title: '礼物奖励',
icon: 'icon-liwu',
bgColor: '#fad34a',
path: '/pages/wechat/pages/gift/index',
},
{
title: '钻石充值',
icon: 'icon-lv_zuanshi_fill',
bgColor: '#ff5081',
path: '/pages/profile/recharge',
},
{
title: '会员中心',
icon: 'icon-huiyuan',
bgColor: '#ebc26a',
path: '/pages/profile/apply-vip',
},
{
title: '邀请好友',
icon: 'icon-tianjiahaoyou',
bgColor: '#a4e55a',
path: '',
},
],
};
const state = reactive({
txTab: [
{
title: '累计收益',
value: '0',
path: '/pages/wechat/pages/gift/history',
},
{
title: '可提现',
value: '0',
path: '/pages/wechat/pages/gift/index',
},
{
title: '成功邀请',
value: '0',
path: '/pages/wechat/pages/inviter/index',
},
],
rule: [
{
title: '通过链接/二维码邀请用户首次充值,可获得**%现金奖励',
},
{
title: '邀请奖励满***元可提现,3个月工作日内到账',
},
],
summary: {},
posterPic: '',
posterUrl: '',
});
const state = reactive({
txTab: [
{
title: '累计收益',
value: '0',
path: '/pages/wechat/pages/gift/history',
},
{
title: '可提现',
value: '0',
path: '/pages/wechat/pages/gift/index',
},
{
title: '成功邀请',
value: '0',
path: '/pages/wechat/pages/inviter/index',
},
],
rule: [
{
title: '通过链接/二维码邀请用户首次充值,可获得**%现金奖励',
},
{
title: '邀请奖励满***元可提现,3个月工作日内到账',
},
],
summary: {},
posterPic: '',
posterUrl: '',
});
onShow(async () => {
// await getTradeConfig()
// await getBrokerageUserSummary()
// getMiniProgramPoster()
});
onShow(async () => {
await getTradeConfig()
await getBrokerageUserSummary()
getMiniProgramPoster()
});
// 获取分销配置
const getTradeConfig = async () => {
try {
let { code, data } = await TradeConfigApi.getTradeConfig();
if (code != 0) {
throw new Error();
}
if (data.brokerageWithdrawMinPrice !== undefined) {
state.rule[1].title = `邀请奖励满${fen2yuan(
data.brokerageWithdrawMinPrice,
)}元可提现,3个月工作日内到账`;
}
if (data.brokerageFirstPercent !== undefined) {
state.rule[0].title = `通过链接/二维码邀请用户首次充值,可获得${
data.brokerageFirstPercent || 50
// 获取分销配置
const getTradeConfig = async () => {
try {
let { code, data } = await TradeConfigApi.getTradeConfig();
if (code != 0) {
throw new Error();
}
if (data.brokerageWithdrawMinPrice !== undefined) {
state.rule[1].title = `邀请奖励满${fen2yuan(
data.brokerageWithdrawMinPrice,
)}元可提现,3个月工作日内到账`;
}
if (data.brokerageFirstPercent !== undefined) {
state.rule[0].title = `通过链接/二维码邀请用户首次充值,可获得${data.brokerageFirstPercent || 50
}%现金奖励`;
}
} catch (error) {
console.error('|获取分销配置|,意外的错误:', error);
}
};
} catch (error) {
console.error('|获取分销配置|,意外的错误:', error);
}
};
// 获取收益统计
const getBrokerageUserSummary = async () => {
let { code, data } = await BrokerageApi.getBrokerageUserSummary();
if (code === 0) {
state.summary = data || {};
// 累计收益
if (state.summary.withdrawPrice !== undefined) {
state.txTab[0].value = fen2yuan(state.summary.withdrawPrice);
}
// 可提现
if (state.summary.brokeragePrice !== undefined) {
state.txTab[1].value = fen2yuan(state.summary.brokeragePrice);
}
// 成功邀请用户
const firstBrokerageUserCount = state.summary.firstBrokerageUserCount ?? 0;
const secondBrokerageUserCount = state.summary.secondBrokerageUserCount ?? 0;
state.txTab[2].value = firstBrokerageUserCount + secondBrokerageUserCount;
// 获取收益统计
const getBrokerageUserSummary = async () => {
let { code, data } = await BrokerageApi.getBrokerageUserSummary();
if (code === 0) {
state.summary = data || {};
// 累计收益
if (state.summary.withdrawPrice !== undefined) {
state.txTab[0].value = fen2yuan(state.summary.withdrawPrice);
}
};
// 获取分销海报
const getMiniProgramPoster = async () => {
try {
let { code, data } = await BrokerageApi.getBrokerageCode();
if (code != 0) throw new Error();
state.posterPic = data?.posterPic || '';
state.posterUrl = data?.url || '';
} catch (error) {
console.error('|获取分销海报|,意外的错误:', error);
// 可提现
if (state.summary.brokeragePrice !== undefined) {
state.txTab[1].value = fen2yuan(state.summary.brokeragePrice);
}
};
// 成功邀请用户
const firstBrokerageUserCount = state.summary.firstBrokerageUserCount ?? 0;
const secondBrokerageUserCount = state.summary.secondBrokerageUserCount ?? 0;
state.txTab[2].value = firstBrokerageUserCount + secondBrokerageUserCount;
}
};
// 复制海报
const copyLink = () => {
uni.setClipboardData({
data: state.posterUrl,
success: () => {
uni.showToast({ title: '复制成功', icon: 'success' });
},
fail: (err) => {
uni.showToast({ title: '复制失败', icon: 'none' });
console.error('|复制链接|,意外的错误:', err);
},
// 获取分销海报
const getMiniProgramPoster = async () => {
try {
let { code, data } = await BrokerageApi.getBrokerageCode();
if (code != 0) throw new Error();
state.posterPic = data?.posterPic || '';
state.posterUrl = data?.url || '';
} catch (error) {
console.error('|获取分销海报|,意外的错误:', error);
}
};
// 复制海报
const copyLink = () => {
uni.setClipboardData({
data: state.posterUrl,
success: () => {
uni.showToast({ title: '复制成功', icon: 'success' });
},
fail: (err) => {
uni.showToast({ title: '复制失败', icon: 'none' });
console.error('|复制链接|,意外的错误:', err);
},
});
};
// 保存海报
const savePoster = () => {
if (!state.posterPic) {
uni.showToast({ title: '海报不存在', icon: 'none' });
return;
}
uni.saveImageToPhotosAlbum({
filePath: state.posterPic,
success: () => {
uni.showToast({ title: '保存成功', icon: 'success' });
},
fail: (err) => {
uni.showToast({ title: '保存失败', icon: 'none' });
console.error('|保存海报|,意外的错误:', err);
},
});
};
const doTxItem = (item) => {
if (item.path) {
uni.navigateTo({
url: item.path,
});
};
}
};
// 保存海报
const savePoster = () => {
if (!state.posterPic) {
uni.showToast({ title: '海报不存在', icon: 'none' });
return;
}
uni.saveImageToPhotosAlbum({
filePath: state.posterPic,
success: () => {
uni.showToast({ title: '保存成功', icon: 'success' });
},
fail: (err) => {
uni.showToast({ title: '保存失败', icon: 'none' });
console.error('|保存海报|,意外的错误:', err);
},
const doItem = (item) => {
if (item.path) {
uni.navigateTo({
url: item.path,
});
};
const doTxItem = (item) => {
if (item.path) {
uni.navigateTo({
url: item.path,
});
}
};
const doItem = (item) => {
if (item.path) {
uni.navigateTo({
url: item.path,
});
}
};
}
};
</script>