uniapp-ZHSQ/pages/user/index.vue

468 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="conatiner">
<!-- 顶部固定头像行吸顶避让胶囊的 paddingTop 移到 header -->
<view class="header" :style="{ paddingTop: top + 15 + 'px' }" @click="toLogin">
<view class="avatar-container">
<image class="avatar" :src="userInfo.userPic || 'https://static.hshuishang.com/person/Group_309.png'"
mode="" />
</view>
<view class="avatar_right">
<view class="avatar_title">
<view class="login-btn">{{ userInfo.nick_name ? userInfo.nick_name : '登录/注册' }}</view>
<view class="avatar_setting">
<view class="avatar_setting_box">
<image src="https://static.hshuishang.com/property-img-file/page_user_Vector13.png" mode=""
@click.stop="headerRefreshClick" />
</view>
<!-- <button class="login-btn" open-type="getPhoneNumber" style="display: none;"
@click="headerLoginClick" @getphonenumber="getPhoneNumber" id="hiddenLoginBtn"></button> -->
<view class="avatar_setting_box">
<image src="https://static.hshuishang.com/property-img-file/page_user_Vector14.png" mode=""
@click.stop="headerSettingsClick" />
</view>
</view>
</view>
<view class="avater_mobile">{{ userInfo.mobile }}</view>
</view>
</view>
<!-- 我的钱包白卡 + 标题/眼睛金额显隐+ 资产横排样式对齐原型个人中心 -->
<view class="wallet-card">
<view class="wallet-head">
<text class="wallet-title">我的钱包</text>
<u-icon :name="walletVisible ? 'eye' : 'eye-off'" color="#888888" size="32"
@click="walletVisible = !walletVisible"></u-icon>
</view>
<view class="wallet-assets">
<view class="asset-item" @click="goWallet(1, userInfo)">
<view class="asset-value">{{ walletVisible ? (userInfo.points || 0) : '****' }}</view>
<view class="asset-label">积分</view>
</view>
<view class="asset-item">
<view class="asset-value">{{ walletVisible ? '0.00' : '****' }}</view>
<view class="asset-label">通宝</view>
</view>
<view class="asset-item" @click="goWallet(2, userInfo)">
<view class="asset-value">{{ walletVisible ? (userInfo.property_housing_fund || 0) + '元' : '****' }}</view>
<view class="asset-label">岁银</view>
</view>
<view class="asset-item" @click="goRedPacket()">
<view class="asset-value">{{ walletVisible ? redPacketMoney + '元' : '****' }}</view>
<view class="asset-label">红包中心</view>
</view>
<view class="asset-item" @click="headerGoldClick">
<view class="asset-value">{{ walletVisible ? '0' : '****' }}</view>
<view class="asset-label">商票</view>
</view>
</view>
</view>
<!-- 物业快捷入口三格横排卡样式对齐原型个人中心 quick-card -->
<view class="quick-card">
<view class="quick-item" @click="handleCommunityClick">
<view class="quick-text">
<text class="quick-title">我的房产</text>
<text class="quick-sub">查看房产 </text>
</view>
<image class="quick-icon"
src="https://static.hshuishang.com/property-img-file/page_user_Group_1382.png" />
</view>
<view class="quick-item" @click="handleApplyOwnerClick">
<view class="quick-text">
<text class="quick-title">物业账单</text>
<text class="quick-sub">去缴费 </text>
</view>
<image class="quick-icon"
src="https://static.hshuishang.com/property-img-file/page_user_Group_1559.png" />
</view>
<view class="quick-item" @click="handleFacilityClick">
<view class="quick-text">
<text class="quick-title">我的工单</text>
<text class="quick-sub">报修进度 </text>
</view>
<image class="quick-icon"
src="https://static.hshuishang.com/property-img-file/page_user_Group_1557.png" />
</view>
</view>
<!-- 我的订单标题 + 全部入口 + 五状态格点击进订单页对应状态 tab -->
<view class="module-card">
<view class="module-head">
<text class="module-title">我的订单</text>
<view class="module-link" @click="goOrderTab(0)">
全部<u-icon name="arrow-right" color="#999999" size="22"></u-icon>
</view>
</view>
<view class="order-status-row">
<view class="status-item" v-for="t in orderTabs" :key="t.label" @click="goOrderTab(t.tab)">
<image class="status-icon" :src="t.icon" />
<text class="status-label">{{ t.label }}</text>
</view>
</view>
</view>
<!-- 服务目录行点击弹出全部功能抽屉并定位到对应分组 -->
<view class="module-card service-card">
<view class="service-row" v-for="g in visibleGroups" :key="g.key" @click="openDrawer(g.key)">
<image class="service-icon" :src="g.icon" />
<text class="service-label">{{ g.title }}</text>
<u-icon name="arrow-right" color="#c0c4cc" size="26"></u-icon>
</view>
</view>
<!-- 全部功能抽屉底部弹出 + 滚动定位到目标分组 -->
<u-popup :show="drawerShow" mode="bottom" round="24rpx" :safe-area-inset-bottom="true"
@close="drawerShow = false" @open="onDrawerOpened">
<view class="fd-wrap">
<view class="fd-head">
<text class="fd-title">全部功能</text>
<u-icon class="fd-close" name="close" color="#999999" size="32"
@click="drawerShow = false"></u-icon>
</view>
<!-- 微信小程序下 scroll-into-view 对插槽内容 id 无效改用 scroll-top 定位 -->
<scroll-view scroll-y class="fd-body" :scroll-top="drawerScrollTop" scroll-with-animation>
<view v-for="g in visibleGroups" :key="g.key" :id="'grp-' + g.key" class="fd-group">
<view class="fd-group-title">{{ g.title }}</view>
<view class="fd-grid">
<view class="fd-item" v-for="it in g.items" :key="it.name" @click="drawerItemClick(it)">
<image class="fd-item-icon" :src="it.icon" />
<text class="fd-item-name">{{ it.name }}</text>
</view>
</view>
</view>
</scroll-view>
</view>
</u-popup>
<!-- <view class="customer" @click="headerCustomerClick">
<image src="https://static.hshuishang.com/property-img-file/page_user_Vector16.png"
mode="" />
<view>客服</view>
</view> -->
<view style="padding-top: 174rpx;"></view>
<nav-footer :current="4" />
</view>
</template>
<script>
import { apiArr } from '../../api/login';
import { apiArr as apiArr2 } from '../../api/v2User';
import { apiArr as apiArr3 } from '../../api/user';
import { menuButtonInfo, NavgateTo, picUrl, request } from '../../utils/index';
import { ORDER_TABS, MENU_GROUPS, FUNC_GROUP_META, FUNC_ICONS } from './profile-menu.js';
export default {
data() {
return {
top: 0,
redPacketMoney: '0.00',
// 我的订单五状态格 + 服务目录分组(数据见 profile-menu.js
orderTabs: ORDER_TABS,
menuGroups: MENU_GROUPS,
// 功能服务(登录态控制显隐,图标按端从 FUNC_ICONS 映射)
shopManagementList: [
{
name: "商家端",
url: "/packages/storeManagement/index/index",
isShow: uni.getStorageSync('is_merchant'),
},
{
name: "物业端",
url: "/packages/workOrderDashboard/guide/index",
isShow: uni.getStorageSync("is_worker"),
},
{
name: "师傅端",
url: "/packages/homeService/worker/index",
isShow: uni.getStorageSync("is_merchant"),
}
],
userInfo: {},
isShop: uni.getStorageSync('is_shop'),
// 钱包金额显隐(眼睛开关,隐藏时显示 ****
walletVisible: true,
// 全部功能抽屉:显隐 + 目标分组 key + 滚动定位scroll-top 像素值)
drawerShow: false,
drawerTargetKey: '',
drawerScrollTop: 0,
}
},
computed: {
// 服务目录5 个固定分组 + 功能服务(有可见项时置于最后)
visibleGroups() {
const groups = [...this.menuGroups];
const funcItems = this.shopManagementList
.filter(item => item.isShow)
.map(item => ({ name: item.name, url: item.url, icon: FUNC_ICONS[item.name] }));
if (funcItems.length) {
groups.push({ ...FUNC_GROUP_META, items: funcItems });
}
return groups;
},
},
methods: {
goWallet(type, item) {
NavgateTo('/packages/user/wallet/index?type=' + type + '&item=' + JSON.stringify(item));
},
goRedPacket() {
NavgateTo('/packages/user/redPacket/index');
},
// 头像点击
toLogin() {
NavgateTo('/packages/user/replenishInfo/index');
},
// 刷新
headerRefreshClick() {
uni.showLoading({
title: '刷新中',
mask: true
})
// 清楚缓存信息
uni.removeStorageSync('ctoken');
uni.removeStorageSync('userId');
uni.removeStorageSync('openId');
uni.removeStorageSync('phone');
uni.removeStorageSync('is_deal');
uni.removeStorageSync('is_dev');
uni.removeStorageSync('is_shop');
uni.removeStorageSync('is_merchant');
uni.removeStorageSync('is_worker');
uni.removeStorageSync('shopId');
uni.removeStorageSync('order_dispatch_permission');
uni.removeStorageSync('work_order_permission');
const button = uni.createSelectorQuery().select('#hiddenLoginBtn');
button.boundingClientRect().exec();
// 执行原headerLoginClick逻辑
this.headerLoginClick();
},
headerLoginClick() {
let that = this;
uni.login({
onlyAuthorize: true,
success: (res) => {
request(apiArr.login, 'POST', {
code: res.code,
phone: '',
password: '',
}, { silent: false }).then((loginRes) => {
// 存储用户信息
uni.setStorageSync('ctoken', loginRes.token);
uni.setStorageSync('is_deal', loginRes.is_deal);
uni.setStorageSync('is_dev', loginRes.is_dev);
uni.setStorageSync('is_shop', loginRes.is_shop);
uni.setStorageSync('is_merchant', loginRes.is_merchant);
uni.setStorageSync('is_worker', loginRes.is_worker);
// 重置用户信息状态
this.userInfo = {};
// 更新功能服务显隐(商家端/师傅端看 is_merchant物业端看 is_worker
this.shopManagementList = this.shopManagementList.map(item => ({
...item,
isShow: item.name === '物业端' ? loginRes.is_worker : loginRes.is_merchant,
}));
// 获取用户信息
request(apiArr.loginInfo, 'POST', {
token: loginRes.token
}, { silent: false }).then((res2) => {
if (res2.error) return;
// 保存userId 后续接口使用
uni.setStorageSync('userId', res2.user_id);
uni.setStorageSync('openId', res2.open_id);
uni.setStorageSync('shopId', res2.wshop_id);
that.getUserInfo(true)
})
}, (err) => {
uni.hideLoading();
console.warn('登录接口错误', err);
})
}
})
},
// 小程序登录获取手机号接口(隐藏登录按钮回调占位,暂无逻辑)
getPhoneNumber() {},
// 设置
headerSettingsClick() {
NavgateTo('/packages/user/index/index');
},
// 客服(入口已注释,占位保留)
headerCustomerClick() {},
// 我的社区跳转
handleCommunityClick() {
NavgateTo('/packages/community/myCommunity/index')
},
// 物业账单跳转
handleApplyOwnerClick() {
NavgateTo(`/packages/community/propertyPayment/index`)
},
// 我的工单跳转
handleFacilityClick() {
const communityId = uni.getStorageSync('changeCommData').id;
NavgateTo(`/packages/workOrderDashboard/index/index?communityId=${communityId}`)
},
headerGoldClick() {
this.NotOpen();
// NavgateTo(`/packages/community/ownerList/index`)
},
// 我的订单:跳订单列表并定位到指定状态 tab0全部/1待付款/2待发货/3已取消/4待评价/6售后
goOrderTab(tab) {
NavgateTo('/packages/myOrders/index/index?tab=' + tab);
},
// 打开全部功能抽屉,目标分组在弹窗动画结束(@open后测量定位
openDrawer(key) {
this.drawerTargetKey = key;
this.drawerShow = true;
},
// 弹窗打开动画完成:测量目标分组位置并滚动定位
onDrawerOpened() {
this.measureDrawerTarget(2);
},
// 测量并滚动到目标分组首次打开时渲染层可能未就绪v-if 懒渲染),查不到节点则短暂重试
measureDrawerTarget(retry) {
const key = this.drawerTargetKey;
if (!key) return;
const query = uni.createSelectorQuery().in(this);
query.select('.fd-body').boundingClientRect();
query.select('.fd-body').scrollOffset();
query.select('#grp-' + key).boundingClientRect();
query.exec((res) => {
const [body, offset, target] = res || [];
if (!body || !offset || !target) {
if (retry > 0) {
setTimeout(() => this.measureDrawerTarget(retry - 1), 50);
}
return;
}
const top = Math.max(0, target.top - body.top + offset.scrollTop);
// scroll-top 相同值不触发滚动:先同步为当前实际位置再赋目标值
this.drawerScrollTop = offset.scrollTop;
this.$nextTick(() => {
this.drawerScrollTop = top;
});
});
},
// 抽屉内功能项点击:关抽屉后按原跳转逻辑处理
drawerItemClick(item) {
this.drawerShow = false;
this.headerOrderClick(item);
},
// 我的订单跳转
headerOrderClick(event) {
if (!event.url) {
this.NotOpen();
return
} else {
// if (!uni.getStorageSync('city')) {
// wx.showModal({
// title: '提示',
// content: '请先选择您的城市',
// confirmText:"去选择",
// complete: (res) => {
// if (res.cancel) {}
// if (res.confirm) {
// NavgateTo( '/pages/index/shopcity')
// }
// }
// })
// return
// }
NavgateTo(`${event.url}`)
}
},
// 暂未开通服务弹窗
NotOpen() {
uni.showModal({
title: '提示',
content: '此功能暂未开通!',
showCancel: false,
complete: (res) => {
if (res.cancel) {
}
}
})
return
},
async getUserInfo(item = false) {
const isCtoken = uni.getStorageSync('ctoken');
if (!isCtoken) return;
const res = await request(apiArr2.getUserInfo, 'POST', {}, { silent: item === true ? false : true });
const newUserInfo = {
...res,
userPic: res.avatar ? `${picUrl}${res.avatar}` : 'https://static.hshuishang.com/person/Group_309.png'
};
this.userInfo = newUserInfo;
if (item) {
const { community_worker } = res;
uni.setStorageSync('order_dispatch_permission', community_worker && community_worker[0].order_dispatch_permission == 1 || false);
uni.setStorageSync('work_order_permission', community_worker && community_worker[0].work_order_permission == 1 || false);
uni.setStorageSync('phone', res.account);
uni.hideLoading();
// uni.showToast({
// title: '刷新成功',
// icon: 'success',
// mask: true,
// duration: 2000,
// })
}
},
async getMyRedPacket() {
const params = {
user_id: uni.getStorageSync('userId'),
}
const res = await request(apiArr3.redPackageMyred, 'POST', params);
let processedList = res.rows
.filter(item => item.status !== 3)
.map(item => {
const newItem = { ...item };
if (newItem?.agent_info?.ad?.ad_name) {
newItem.agent_info.ad.ad_name = newItem.agent_info.ad.ad_name.split(',').join('');
}
return newItem;
});
this.redPacketMoney = processedList.reduce((total, item) =>
item.red_package_config ? total + item.red_package_config.money : total, 0.00
).toFixed(2);
},
},
onLoad() {
const meun = menuButtonInfo();
this.top = meun.height + meun.top;
},
onShow() {
this.getUserInfo();
this.getMyRedPacket();
// this.headerLoginClick();
},
}
</script>
<style>
@import url("./index.css");
</style>