Compare commits
16 Commits
c1ee2db1d6
...
bf9471cfa9
| Author | SHA1 | Date | |
|---|---|---|---|
| bf9471cfa9 | |||
| 19a70f1134 | |||
| c452ea29e9 | |||
| bb7d294ef6 | |||
| 12d7d093e9 | |||
|
|
72e132ba8d | ||
| 3ff53e7ba7 | |||
|
|
3af5c6750f | ||
|
|
7c43e5bec4 | ||
|
|
42a187459e | ||
| d41bb6cf51 | |||
| f0722190c0 | |||
|
|
87e9cde197 | ||
| 7bc3e9e4c8 | |||
| 9465fd21bf | |||
|
|
64c36a3d60 |
4
App.vue
4
App.vue
@ -216,6 +216,10 @@ page {
|
|||||||
margin-right: 20rpx;
|
margin-right: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ml-10 {
|
||||||
|
margin-left: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.ml-15 {
|
.ml-15 {
|
||||||
margin-left: 30rpx;
|
margin-left: 30rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="full-page" :style="pageStyle">
|
<view class="full-page" :class="pageClass" :style="pageStyle">
|
||||||
<view v-if="hasHeader" class="page-header">
|
<view v-if="hasHeader" class="page-header">
|
||||||
<slot name="header"></slot>
|
<slot name="header"></slot>
|
||||||
</view>
|
</view>
|
||||||
<view class="page-main" :style="mainStyle">
|
<view class="page-main" :class="mainClass" :style="mainStyle">
|
||||||
<view v-if="customScroll" class="page-scroll">
|
<view v-if="customScroll" class="page-scroll">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</view>
|
</view>
|
||||||
@ -21,9 +21,7 @@
|
|||||||
<view v-if="hasFooter" class="page-footer">
|
<view v-if="hasFooter" class="page-footer">
|
||||||
<slot name="footer"></slot>
|
<slot name="footer"></slot>
|
||||||
</view>
|
</view>
|
||||||
<!-- #ifdef MP-->
|
<view v-if="showSafeArea" class="safeareaBottom"></view>
|
||||||
<!-- <view class="safeareaBottom"></view> -->
|
|
||||||
<!-- #endif -->
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -33,8 +31,11 @@ import useDebounce from "@/utils/useDebounce";
|
|||||||
const emits = defineEmits(["reachBottom"]);
|
const emits = defineEmits(["reachBottom"]);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
customScroll: { type: Boolean, default: false },
|
customScroll: { type: Boolean, default: false },
|
||||||
mainStyle: { default: "" },
|
mainClass: { type: String, default: "" },
|
||||||
pageStyle: { default: "" },
|
mainStyle: { default: '' },
|
||||||
|
pageClass: { type: String, default: "" },
|
||||||
|
pageStyle: { default: '' },
|
||||||
|
showSafeArea: { type: Boolean, default: true },
|
||||||
});
|
});
|
||||||
const slots = useSlots();
|
const slots = useSlots();
|
||||||
const hasHeader = computed(() => !!slots.header);
|
const hasHeader = computed(() => !!slots.header);
|
||||||
|
|||||||
@ -25,7 +25,7 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const list = computed(() => props.avatarList.map(i => i || '/static/default-avatar.png'))
|
const list = computed(() => props.avatarList.map(i => i || '/static/default-avatar.svg'))
|
||||||
|
|
||||||
const size = computed(() => {
|
const size = computed(() => {
|
||||||
const val = Number.isInteger(props.size) && props.size > 0 ? props.size : 144;
|
const val = Number.isInteger(props.size) && props.size > 0 ? props.size : 144;
|
||||||
@ -57,7 +57,7 @@ const groups = computed(() => {
|
|||||||
style: `width: ${size.value.md}rpx; height: ${size.value.md}rpx;`
|
style: `width: ${size.value.md}rpx; height: ${size.value.md}rpx;`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { list: [list.value.slice(0, 1)], style: `width: ${size.value.lg}rpx; height: ${size.lg}rpx;` }
|
return { list: [list.value.slice(0, 1)], style: `width: ${size.value.lg}rpx; height: ${size.value.lg}rpx;` }
|
||||||
})
|
})
|
||||||
|
|
||||||
function reGenerate() {
|
function reGenerate() {
|
||||||
|
|||||||
333
pages.json
333
pages.json
@ -1,171 +1,178 @@
|
|||||||
{
|
{
|
||||||
"pages": [
|
"pages": [
|
||||||
{
|
{
|
||||||
"path": "pages/home/home",
|
"path": "pages/home/home",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "首页",
|
"navigationBarTitleText": "首页",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/article/article-list",
|
"path": "pages/article/article-list",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "我的宣教"
|
"navigationBarTitleText": "我的宣教"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/survey/survey-list",
|
"path": "pages/survey/survey-list",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "我的问卷"
|
"navigationBarTitleText": "我的问卷"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/message/message",
|
"path": "pages/message/message",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "消息"
|
"navigationBarTitleText": "消息"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/message/index",
|
"path": "pages/message/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "聊天",
|
"navigationBarTitleText": "聊天",
|
||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/login/login",
|
"path": "pages/login/login",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "柚健康"
|
"navigationBarTitleText": "柚健康",
|
||||||
}
|
"navigationStyle": "custom"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/login/redirect-page",
|
{
|
||||||
"style": {
|
"path": "pages/login/redirect-page",
|
||||||
"navigationBarTitleText": "柚健康"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "柚健康"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/archive/archive-manage",
|
{
|
||||||
"style": {
|
"path": "pages/archive/archive-manage",
|
||||||
"navigationBarTitleText": "档案管理"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "档案管理"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/archive/edit-archive",
|
{
|
||||||
"style": {
|
"path": "pages/archive/edit-archive",
|
||||||
"navigationBarTitleText": "新增档案"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "新增档案"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/health/list",
|
{
|
||||||
"style": {
|
"path": "pages/archive/archive-result",
|
||||||
"navigationBarTitleText": "健康信息"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "团队服务"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/health/record",
|
{
|
||||||
"style": {
|
"path": "pages/health/list",
|
||||||
"navigationBarTitleText": "健康信息"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "健康信息"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/library/diagnosis-list",
|
{
|
||||||
"style": {
|
"path": "pages/health/record",
|
||||||
"navigationBarTitleText": "选择诊断"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "健康信息"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/team/team-detail",
|
{
|
||||||
"style": {
|
"path": "pages/library/diagnosis-list",
|
||||||
"navigationBarTitleText": "团队介绍"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "选择诊断"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/team/homepage",
|
{
|
||||||
"style": {
|
"path": "pages/team/team-detail",
|
||||||
"navigationBarTitleText": "个人主页"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "团队介绍"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/team/friend",
|
{
|
||||||
"style": {
|
"path": "pages/team/homepage",
|
||||||
"navigationBarTitleText": "添加好友"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "个人主页"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/web-view/web-view",
|
{
|
||||||
"style": {
|
"path": "pages/team/friend",
|
||||||
"navigationBarTitleText": ""
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "添加好友"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/mine/mine",
|
{
|
||||||
"style": {
|
"path": "pages/web-view/web-view",
|
||||||
"navigationBarTitleText": "我的"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": ""
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/mine/contact",
|
{
|
||||||
"style": {
|
"path": "pages/mine/mine",
|
||||||
"navigationBarTitleText": "联系客服"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "我的"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/common/privacy",
|
{
|
||||||
"style": {
|
"path": "pages/mine/contact",
|
||||||
"navigationBarTitleText": "隐私政策"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "联系客服"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/common/agreement",
|
{
|
||||||
"style": {
|
"path": "pages/common/privacy",
|
||||||
"navigationBarTitleText": "用户协议"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "隐私政策"
|
||||||
},
|
}
|
||||||
{
|
},
|
||||||
"path": "pages/article/article-detail",
|
{
|
||||||
"style": {
|
"path": "pages/common/agreement",
|
||||||
"navigationBarTitleText": "宣教文章"
|
"style": {
|
||||||
}
|
"navigationBarTitleText": "用户协议"
|
||||||
},
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/article/article-detail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "宣教文章"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/article/send-article",
|
"path": "pages/article/send-article",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "选择宣教文章"
|
"navigationBarTitleText": "选择宣教文章"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "white",
|
"navigationBarTextStyle": "white",
|
||||||
"navigationBarTitleText": "uni-app",
|
"navigationBarTitleText": "uni-app",
|
||||||
"navigationBarBackgroundColor": "#065bd6",
|
"navigationBarBackgroundColor": "#065bd6",
|
||||||
"backgroundColor": "#065bd6"
|
"backgroundColor": "#065bd6"
|
||||||
},
|
},
|
||||||
"tabBar": {
|
"tabBar": {
|
||||||
"color": "#666666",
|
"color": "#666666",
|
||||||
"selectedColor": "#007aff",
|
"selectedColor": "#007aff",
|
||||||
"backgroundColor": "#ffffff",
|
"backgroundColor": "#ffffff",
|
||||||
"borderStyle": "white",
|
"borderStyle": "white",
|
||||||
"list": [
|
"list": [
|
||||||
{
|
{
|
||||||
"pagePath": "pages/home/home",
|
"pagePath": "pages/home/home",
|
||||||
"iconPath": "static/tabbar/home.png",
|
"iconPath": "static/tabbar/home.png",
|
||||||
"selectedIconPath": "static/tabbar/home_selected.png",
|
"selectedIconPath": "static/tabbar/home_selected.png",
|
||||||
"text": "消息"
|
"text": "消息"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pagePath": "pages/message/message",
|
"pagePath": "pages/message/message",
|
||||||
"iconPath": "static/tabbar/consult.png",
|
"iconPath": "static/tabbar/consult.png",
|
||||||
"selectedIconPath": "static/tabbar/consult_selected.png",
|
"selectedIconPath": "static/tabbar/consult_selected.png",
|
||||||
"text": "咨询"
|
"text": "咨询"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pagePath": "pages/mine/mine",
|
"pagePath": "pages/mine/mine",
|
||||||
"iconPath": "static/tabbar/mine.png",
|
"iconPath": "static/tabbar/mine.png",
|
||||||
"selectedIconPath": "static/tabbar/mine_selected.png",
|
"selectedIconPath": "static/tabbar/mine_selected.png",
|
||||||
"text": "我的"
|
"text": "我的"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"uniIdRouter": {}
|
"uniIdRouter": {}
|
||||||
}
|
}
|
||||||
@ -31,8 +31,8 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="px-15 py-12 flex justify-end">
|
<view class="px-15 py-12 flex justify-end">
|
||||||
<view v-if="enableHis && !customer.isConnectHis" class="mr-10 text-base text-primary">关联档案</view>
|
<view v-if="enableHis && !customer.isConnectHis" class="mr-10 text-base text-primary">关联档案</view>
|
||||||
<view class="mr-10 text-base text-success" @click="changeArchive(customer)">完善个人信息</view>
|
<view class="text-base text-success" @click="changeArchive(customer)">完善个人信息</view>
|
||||||
<view class="mr-10 text-base text-danger" @click="unBindArchive(customer)">删除档案</view>
|
<!-- <view class="text-base text-danger" @click="unBindArchive(customer)">删除档案</view> -->
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
142
pages/archive/archive-result.vue
Normal file
142
pages/archive/archive-result.vue
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<full-page mainClass="bg-white">
|
||||||
|
<template #header>
|
||||||
|
<view class="mb-10 py-30 flex items-center justify-center bg-white shadow-lg">
|
||||||
|
<icon class="mr-5" type="success" size="24" />
|
||||||
|
<view class="text-lg font-semibold">建档成功</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<view v-if="friends.length" class="px-15">
|
||||||
|
<view class="py-12 text-base tont-semibold text-dark">
|
||||||
|
您可以加以下人员为好友, 随时提供一对一服务。
|
||||||
|
</view>
|
||||||
|
<template v-if="friends.length > 1">
|
||||||
|
<view v-for="i in friends" :key="i.userid"
|
||||||
|
class="flex items-center mb-10 overflow-hidden border-primary rounded" @click="toFriend(i.userid)">
|
||||||
|
<view class="flex-shrink-0 p-10">
|
||||||
|
<image class="avatar" :src="i.avatar || '/static/default-avatar.png'"></image>
|
||||||
|
</view>
|
||||||
|
<view class="flex-grow w-0 py-10 align-stretch">
|
||||||
|
<view class="truncate">
|
||||||
|
<text class="mr-5 text-lg text-dark font-semibold">{{ i.anotherName }}</text>
|
||||||
|
<text class="text-base text-gray"> {{ memberJob[i.userid] }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="mt-5 text-base line-clamp-2 leading-normal">
|
||||||
|
{{ i.memberTroduce || '暂无简介' }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="px-15 flex items-center align-stretch bg-primary text-base text-white text-center">
|
||||||
|
加好友
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="friends.length === 1 && qrcode">
|
||||||
|
<view class="mt-15 px-15">
|
||||||
|
<view class="flex">
|
||||||
|
<image class="mr-10 avatar" :src="member.avatar || '/static/default-avatar.png'"></image>
|
||||||
|
<view class="w-0 flex-grow leading-normal">
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="mr-5 text-lg font-semibold text-dark">{{ member.anotherName }}</view>
|
||||||
|
<view class="text-base text-warning">@企业微信</view>
|
||||||
|
</view>
|
||||||
|
<view class="truncate text-base text-dark">{{ memberJob[member.userid] }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="mt-12 border-primary qrcode p-15 mx-auto rounded" @click="previewImage()">
|
||||||
|
<image v-if="qrcode" class="h-full w-full" :src="qrcode"></image>
|
||||||
|
</view>
|
||||||
|
<view class="mt-12 text-base text-center text-dark">
|
||||||
|
点击识别下方二维码,加我为好友
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</full-page>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref, watch } from 'vue';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import useGuard from '@/hooks/useGuard';
|
||||||
|
import useJob from '@/hooks/useJob';
|
||||||
|
import useAccount from '@/store/account';
|
||||||
|
import api from '@/utils/api';
|
||||||
|
|
||||||
|
import FullPage from '@/components/full-page.vue';
|
||||||
|
|
||||||
|
const team = ref(null);
|
||||||
|
const { useLoad } = useGuard();
|
||||||
|
const { account } = storeToRefs(useAccount());
|
||||||
|
const { memberJob, memberList: list } = useJob();
|
||||||
|
const qrcode = ref('');
|
||||||
|
|
||||||
|
const friends = computed(() => {
|
||||||
|
const memberList = Array.isArray(team.value?.memberList) ? team.value.memberList : [];
|
||||||
|
const friendlyMembers = Array.isArray(team.value?.friendlyMembers) ? team.value.friendlyMembers : [];
|
||||||
|
return memberList.filter(i => i && i.userid && friendlyMembers.includes(i.userid))
|
||||||
|
})
|
||||||
|
const member = computed(() => friends.value[0])
|
||||||
|
|
||||||
|
function previewImage() {
|
||||||
|
if (!qrcode.value) return;
|
||||||
|
uni.previewImage({
|
||||||
|
urls: [qrcode.value]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function toFriend(userid) {
|
||||||
|
uni.navigateTo({ url: `/pages/team/friend?corpId=${account.value?.corpId}&userid=${userid}` })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getQrcode(userid) {
|
||||||
|
const res = await api('addContactWay', { corpUserId: userid, corpId: account.value?.corpId, unionid: account.value?.openid });
|
||||||
|
if (res && res.data) {
|
||||||
|
qrcode.value = res.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getTeam(corpId, teamId) {
|
||||||
|
const res = await api('getTeamData', { teamId, corpId });
|
||||||
|
if (res && res.data) {
|
||||||
|
team.value = res.data;
|
||||||
|
} else {
|
||||||
|
toast(res?.message || '获取团队信息失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useLoad(options => {
|
||||||
|
if (options.teamId && options.corpId) {
|
||||||
|
getTeam(options.corpId, options.teamId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(friends, n => {
|
||||||
|
list.value = Array.isArray(n) ? n : [];
|
||||||
|
if (n.length === 1) {
|
||||||
|
getQrcode(n[0].userid)
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.py-30 {
|
||||||
|
padding-top: 60rpx;
|
||||||
|
padding-bottom: 60rpx
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 128rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-stretch {
|
||||||
|
align-self: stretch
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-5 {
|
||||||
|
margin-top: 10rpx
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrcode {
|
||||||
|
width: 560rpx;
|
||||||
|
height: 560rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -11,7 +11,8 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<button-footer confirmText="新增档案" :showCancel="false" @confirm="confirm()" />
|
<button-footer :showCancel="customerId" cancelText="删除" confirmText="保存" @cancel="unBindArchive()"
|
||||||
|
@confirm="confirm()" />
|
||||||
</template>
|
</template>
|
||||||
</full-page>
|
</full-page>
|
||||||
<bind-popup :customers="customers" :corpName="corpName" :visible="visible" @close="visible = false"
|
<bind-popup :customers="customers" :corpName="corpName" :visible="visible" @close="visible = false"
|
||||||
@ -26,7 +27,7 @@ import dayjs from 'dayjs';
|
|||||||
import useGuard from '@/hooks/useGuard';
|
import useGuard from '@/hooks/useGuard';
|
||||||
import useAccount from '@/store/account';
|
import useAccount from '@/store/account';
|
||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
import { toast } from '@/utils/widget';
|
import { toast, confirm as uniConfirm } from '@/utils/widget';
|
||||||
import validate from '@/utils/validate';
|
import validate from '@/utils/validate';
|
||||||
|
|
||||||
import ButtonFooter from '@/components/button-footer.vue';
|
import ButtonFooter from '@/components/button-footer.vue';
|
||||||
@ -38,7 +39,8 @@ import formTemplate from '@/components/form-template/index.vue';
|
|||||||
|
|
||||||
const empty = ref(false)
|
const empty = ref(false)
|
||||||
const { useLoad } = useGuard();
|
const { useLoad } = useGuard();
|
||||||
const { account } = storeToRefs(useAccount());
|
const { account, externalUserId } = storeToRefs(useAccount());
|
||||||
|
const { getExternalUserId } = useAccount()
|
||||||
const corpId = ref('');
|
const corpId = ref('');
|
||||||
const corpName = ref('');
|
const corpName = ref('');
|
||||||
const customer = ref({});
|
const customer = ref({});
|
||||||
@ -54,16 +56,12 @@ const customerArchive = ref(null);
|
|||||||
const verifyVisible = ref(false);
|
const verifyVisible = ref(false);
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
|
|
||||||
const formData = computed(() => ({ ...customer.value, ...form.value }));
|
const formData = computed(() => {
|
||||||
|
if (customerId.value) {
|
||||||
function back() {
|
return { ...customer.value, ...form.value }
|
||||||
const pages = getCurrentPages();
|
|
||||||
if (pages.length > 1) {
|
|
||||||
uni.navigateBack();
|
|
||||||
} else {
|
|
||||||
uni.redirectTo({ url: `/pages/home/home?corpId=${corpId.value}&teamId=${teamId.value}` })
|
|
||||||
}
|
}
|
||||||
}
|
return { ...customer.value, ...form.value, mobile: account.value?.mobile }
|
||||||
|
});
|
||||||
|
|
||||||
function change({ title, value }) {
|
function change({ title, value }) {
|
||||||
if (title) {
|
if (title) {
|
||||||
@ -80,7 +78,7 @@ function change({ title, value }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function confirm() {
|
function confirm() {
|
||||||
if (!tempRef.value.verify() || Object.keys(form.value).length === 0) return;
|
if (!tempRef.value.verify()) return;
|
||||||
if (customerId.value) {
|
if (customerId.value) {
|
||||||
updateArchive();
|
updateArchive();
|
||||||
} else {
|
} else {
|
||||||
@ -97,12 +95,16 @@ async function addArchive() {
|
|||||||
teamId: teamId.value,
|
teamId: teamId.value,
|
||||||
corpId: corpId.value,
|
corpId: corpId.value,
|
||||||
mobile: account.value.mobile,
|
mobile: account.value.mobile,
|
||||||
miniAppId: account.value.openid
|
miniAppId: account.value.openid,
|
||||||
|
externalUserId: externalUserId.value,
|
||||||
}
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
const res = await api('addCustomer', { params });
|
const res = await api('addCustomer', { params });
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
back()
|
uni.$emit('reloadTeamCustomers')
|
||||||
|
uni.redirectTo({
|
||||||
|
url: `/pages/archive/archive-result?corpId=${corpId.value}&teamId=${teamId.value}`
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
toast(res?.message || '新增档案失败');
|
toast(res?.message || '新增档案失败');
|
||||||
}
|
}
|
||||||
@ -122,12 +124,15 @@ async function bindArchive(customerId) {
|
|||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
if (customerId.value) {
|
if (customerId.value) {
|
||||||
await getCustomer()
|
await getCustomer();
|
||||||
} else {
|
} else {
|
||||||
const res = await getArchives();
|
const res = await getArchives();
|
||||||
if (res.length > 0) {
|
if (res.length > 0) {
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
}
|
}
|
||||||
|
if (!externalUserId.value) {
|
||||||
|
getExternalUserId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
await getBaseForm();
|
await getBaseForm();
|
||||||
}
|
}
|
||||||
@ -156,7 +161,6 @@ async function getBaseForm() {
|
|||||||
|
|
||||||
async function getCustomer() {
|
async function getCustomer() {
|
||||||
const res = await api('getCustomerByCustomerId', { customerId: customerId.value });
|
const res = await api('getCustomerByCustomerId', { customerId: customerId.value });
|
||||||
console.log(res.data)
|
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
customer.value = res.data;
|
customer.value = res.data;
|
||||||
} else {
|
} else {
|
||||||
@ -166,10 +170,50 @@ async function getCustomer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateArchive() {
|
||||||
|
if (Object.keys(form.value).length > 0) {
|
||||||
|
const res = await api('updateCustomer', { id: customerId.value, params: { ...form.value } });
|
||||||
|
if (res && res.success) {
|
||||||
|
await toast('修改成功');
|
||||||
|
uni.$emit('reloadTeamCustomers')
|
||||||
|
uni.navigateBack();
|
||||||
|
} else {
|
||||||
|
toast(res?.message || '修改失败');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.navigateBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function unBindArchive() {
|
||||||
|
await uniConfirm('确定删除档案吗?')
|
||||||
|
const res = await api('unbindMiniAppArchive', { id: customer.value._id, corpId: corpId.value, teamId: teamId.value, miniAppId: account.value.openid });
|
||||||
|
if (res && res.success) {
|
||||||
|
await toast('删除成功');
|
||||||
|
uni.$emit('reloadTeamCustomers')
|
||||||
|
uni.navigateBack();
|
||||||
|
} else {
|
||||||
|
toast(res?.message || '删除失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// async updateCustomer() {
|
||||||
|
// if (Object.keys(this.form).length === 0) return this.editMemberId;
|
||||||
|
// const { success, message } = await updateCustomer(
|
||||||
|
// this.editMemberId,
|
||||||
|
// this.form
|
||||||
|
// );
|
||||||
|
// if (success) return this.editMemberId;
|
||||||
|
// this.widget.hideLoading();
|
||||||
|
// this.widget.toast(message);
|
||||||
|
// return Promise.reject();
|
||||||
|
// },
|
||||||
|
|
||||||
onLoad(options => {
|
onLoad(options => {
|
||||||
customerId.value = options.id || '';
|
customerId.value = options.id || '';
|
||||||
uni.setNavigationBarTitle({ title: customerId.value ? '编辑档案' : '新增档案' })
|
uni.setNavigationBarTitle({ title: customerId.value ? '编辑档案' : '新增档案' })
|
||||||
})
|
})
|
||||||
|
|
||||||
useLoad(options => {
|
useLoad(options => {
|
||||||
teamId.value = options.teamId;
|
teamId.value = options.teamId;
|
||||||
corpId.value = options.corpId;
|
corpId.value = options.corpId;
|
||||||
|
|||||||
@ -28,8 +28,11 @@
|
|||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
import api from "@/utils/api.js";
|
import api from "@/utils/api.js";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
import useAccountStore from "@/store/account.js";
|
||||||
const env = __VITE_ENV__;
|
const env = __VITE_ENV__;
|
||||||
const corpId = env.MP_CORP_ID;
|
const corpId = env.MP_CORP_ID;
|
||||||
|
const { account } = storeToRefs(useAccountStore());
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const error = ref("");
|
const error = ref("");
|
||||||
const articleData = ref({
|
const articleData = ref({
|
||||||
@ -40,6 +43,16 @@ const articleData = ref({
|
|||||||
|
|
||||||
let articleId = "";
|
let articleId = "";
|
||||||
|
|
||||||
|
const markArticleRead = async () => {
|
||||||
|
const unionid = account.value?.unionid;
|
||||||
|
if (!unionid || !articleId) return;
|
||||||
|
try {
|
||||||
|
await api("addArticleReadRecord", { corpId, articleId, unionid }, false);
|
||||||
|
} catch (err) {
|
||||||
|
console.warn("markArticleRead failed:", err?.message || err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 处理富文本内容,使图片自适应
|
// 处理富文本内容,使图片自适应
|
||||||
const processRichTextContent = (html) => {
|
const processRichTextContent = (html) => {
|
||||||
if (!html) return "";
|
if (!html) return "";
|
||||||
@ -107,6 +120,7 @@ const loadArticle = async () => {
|
|||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
if (options.id) {
|
if (options.id) {
|
||||||
articleId = options.id;
|
articleId = options.id;
|
||||||
|
markArticleRead();
|
||||||
loadArticle();
|
loadArticle();
|
||||||
} else {
|
} else {
|
||||||
error.value = "文章信息不完整";
|
error.value = "文章信息不完整";
|
||||||
|
|||||||
@ -11,16 +11,25 @@
|
|||||||
? 'bg-orange-100 text-orange-500 border-orange-500'
|
? 'bg-orange-100 text-orange-500 border-orange-500'
|
||||||
: 'bg-white text-gray-600 border-gray-200'
|
: 'bg-white text-gray-600 border-gray-200'
|
||||||
]"
|
]"
|
||||||
@click="activeTab = tab.value"
|
@click="selectTab(tab.value)"
|
||||||
>
|
>
|
||||||
{{ tab.name }}
|
{{ tab.name }}
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<!-- Article List -->
|
<!-- Article List -->
|
||||||
<view class="p-15">
|
<view v-if="loading && articles.length === 0" class="loading-container">
|
||||||
|
<uni-icons type="spinner-cycle" size="30" color="#999" />
|
||||||
|
<text class="loading-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-else-if="!loading && articles.length === 0" class="empty-container">
|
||||||
|
<empty-data text="暂无文章" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-else class="p-15">
|
||||||
<view
|
<view
|
||||||
v-for="item in filteredArticles"
|
v-for="item in articles"
|
||||||
:key="item._id"
|
:key="item._id"
|
||||||
class="bg-white rounded-lg p-15 mb-15 shadow-sm"
|
class="bg-white rounded-lg p-15 mb-15 shadow-sm"
|
||||||
@click="goToDetail(item)"
|
@click="goToDetail(item)"
|
||||||
@ -30,7 +39,7 @@
|
|||||||
<view class="flex items-start flex-1 mr-10 relative">
|
<view class="flex items-start flex-1 mr-10 relative">
|
||||||
<!-- Tag -->
|
<!-- Tag -->
|
||||||
<view class="text-xs text-green-600 border border-green-600 px-5 rounded mr-5 flex-shrink-0 mt-1 tag-box">
|
<view class="text-xs text-green-600 border border-green-600 px-5 rounded mr-5 flex-shrink-0 mt-1 tag-box">
|
||||||
{{ item.type }}
|
宣教文章
|
||||||
</view>
|
</view>
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<view class="text-base font-bold text-gray-800 leading-normal line-clamp-2">
|
<view class="text-base font-bold text-gray-800 leading-normal line-clamp-2">
|
||||||
@ -44,86 +53,168 @@
|
|||||||
class="text-sm mr-2"
|
class="text-sm mr-2"
|
||||||
:class="item.status === 'UNREAD' ? 'text-red-500' : 'text-gray-400'"
|
:class="item.status === 'UNREAD' ? 'text-red-500' : 'text-gray-400'"
|
||||||
>
|
>
|
||||||
{{ item.status === 'UNREAD' ? '未阅读' : '查看' }}
|
{{ item.status === 'UNREAD' ? '未阅读' : '已阅读' }}
|
||||||
</text>
|
</text>
|
||||||
<uni-icons type="right" size="14" :color="item.status === 'UNREAD' ? '#ef4444' : '#9ca3af'"></uni-icons>
|
<uni-icons type="right" size="14" :color="item.status === 'UNREAD' ? '#ef4444' : '#9ca3af'"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
<!-- Person -->
|
<view class="text-sm text-gray-600 mb-5 flex items-start">
|
||||||
<view class="text-sm text-gray-600 mb-5 flex items-center">
|
<text class="text-gray-400 mr-2 field-label">人员:</text>
|
||||||
<text class="text-gray-400 mr-2">人员:</text>
|
<text>{{ item.person || '-' }}</text>
|
||||||
<text>{{ item.person }}</text>
|
|
||||||
</view>
|
</view>
|
||||||
<!-- Team -->
|
|
||||||
<view class="text-sm text-gray-600 mb-10 pb-10 border-b border-gray-100 flex items-center">
|
<view class="text-sm text-gray-600 mb-10 pb-10 border-b border-gray-100 flex items-start">
|
||||||
<text class="text-gray-400 mr-2">团队:</text>
|
<text class="text-gray-400 mr-2 field-label">团队:</text>
|
||||||
<text>{{ item.team }}</text>
|
<text>{{ item.team || '-' }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<view class="text-sm text-gray-400">
|
<view class="text-sm text-gray-400">
|
||||||
发送时间: {{ item.time }}
|
发送时间: {{ item.time || '-' }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view v-if="loading && articles.length > 0" class="loading-more">
|
||||||
|
<uni-icons type="spinner-cycle" size="20" color="#999" />
|
||||||
|
<text>加载中...</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="!loading && articles.length >= total" class="no-more">
|
||||||
|
没有更多了
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref } from "vue";
|
||||||
|
import { onShow, onReachBottom } from "@dcloudio/uni-app";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import api from "@/utils/api.js";
|
||||||
|
import useAccountStore from "@/store/account.js";
|
||||||
|
import EmptyData from "@/components/empty-data.vue";
|
||||||
|
|
||||||
// Mock Data
|
const env = __VITE_ENV__;
|
||||||
const tabs = [
|
const corpId = env.MP_CORP_ID;
|
||||||
{ name: '全部', value: 'ALL' },
|
const { account, openid } = storeToRefs(useAccountStore());
|
||||||
{ name: '李珊珊 女 37岁', value: '1' },
|
|
||||||
{ name: '罗小小 女 17岁', value: '2' },
|
|
||||||
];
|
|
||||||
|
|
||||||
const activeTab = ref('ALL');
|
const tabs = ref([{ name: "全部", value: "" }]);
|
||||||
|
const activeTab = ref("");
|
||||||
|
|
||||||
const articles = ref([
|
const articles = ref([]);
|
||||||
{
|
const total = ref(0);
|
||||||
_id: 1,
|
const page = ref(1);
|
||||||
type: '宣教文章',
|
const pageSize = 20;
|
||||||
title: '妊糖管理期注意事项!',
|
const loading = ref(false);
|
||||||
status: 'UNREAD',
|
const inited = ref(false);
|
||||||
person: '李珊珊 女 36岁',
|
|
||||||
team: '妊糖管理服务团队',
|
const selectTab = async (customerId) => {
|
||||||
time: '2026-01-09 15:23',
|
if (activeTab.value === customerId) return;
|
||||||
ownerId: '1'
|
activeTab.value = customerId;
|
||||||
},
|
await loadArticleList(true);
|
||||||
{
|
};
|
||||||
_id: 2,
|
|
||||||
type: '宣教文章',
|
const loadCustomers = async () => {
|
||||||
title: '妊糖管理期注意事项!妊糖管理期注意事项!妊糖管理期注意事项......',
|
const miniAppId = openid.value || uni.getStorageSync("openid");
|
||||||
status: 'READ',
|
if (!miniAppId) return;
|
||||||
person: '李珊珊 女 36岁',
|
try {
|
||||||
team: '妊糖管理服务团队',
|
const res = await api("getMiniAppCustomers", { miniAppId, corpId });
|
||||||
time: '2026-01-09 15:23',
|
if (res && res.success) {
|
||||||
ownerId: '1'
|
const list = Array.isArray(res.data) ? res.data : [];
|
||||||
},
|
tabs.value = [
|
||||||
{
|
{ name: "全部", value: "" },
|
||||||
_id: 3,
|
...list.map((c) => ({ name: c.name || "未命名", value: c._id })),
|
||||||
type: '宣教文章',
|
];
|
||||||
title: '妊糖管理期注意事项!',
|
} else {
|
||||||
status: 'READ',
|
uni.showToast({ title: res?.message || "获取档案失败", icon: "none" });
|
||||||
person: '罗小小 女 16岁',
|
}
|
||||||
team: '妊糖管理服务团队',
|
} catch (err) {
|
||||||
time: '2026-01-09 15:23',
|
console.error("loadCustomers failed:", err);
|
||||||
ownerId: '2'
|
uni.showToast({ title: "获取档案失败", icon: "none" });
|
||||||
}
|
}
|
||||||
]);
|
};
|
||||||
|
|
||||||
const filteredArticles = computed(() => {
|
const mapRowToView = (row) => {
|
||||||
if (activeTab.value === 'ALL') return articles.value;
|
const sendTime = row?.sendTime ? dayjs(row.sendTime).format("YYYY-MM-DD HH:mm") : "";
|
||||||
return articles.value.filter(item => item.ownerId === activeTab.value);
|
return {
|
||||||
});
|
_id: row?._id,
|
||||||
|
articleId: row?.articleId,
|
||||||
|
title: row?.articleInfo?.title || "宣教文章",
|
||||||
|
status: row?.status || "UNREAD",
|
||||||
|
person: row?.customer?.name || "",
|
||||||
|
team: row?.team?.name || "-",
|
||||||
|
time: sendTime,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadArticleList = async (reset = false) => {
|
||||||
|
if (loading.value) return;
|
||||||
|
const unionid = account.value?.unionid;
|
||||||
|
const miniAppId = openid.value || uni.getStorageSync("openid");
|
||||||
|
if (!unionid && !miniAppId) {
|
||||||
|
uni.showToast({ title: "未获取到用户信息,请重新登录", icon: "none" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reset) {
|
||||||
|
page.value = 1;
|
||||||
|
articles.value = [];
|
||||||
|
total.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
corpId,
|
||||||
|
unionid,
|
||||||
|
miniAppId,
|
||||||
|
page: page.value,
|
||||||
|
pageSize,
|
||||||
|
};
|
||||||
|
if (activeTab.value) params.customerId = activeTab.value;
|
||||||
|
|
||||||
|
const res = await api("getMiniAppReceivedArticleList", params);
|
||||||
|
if (res && res.success) {
|
||||||
|
const list = Array.isArray(res.list) ? res.list : [];
|
||||||
|
total.value = Number(res.total) || 0;
|
||||||
|
const mapped = list.map(mapRowToView);
|
||||||
|
if (page.value === 1) articles.value = mapped;
|
||||||
|
else articles.value = [...articles.value, ...mapped];
|
||||||
|
} else {
|
||||||
|
uni.showToast({ title: res?.message || "获取文章失败", icon: "none" });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("loadArticleList failed:", err);
|
||||||
|
uni.showToast({ title: "加载失败,请重试", icon: "none" });
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function goToDetail(item) {
|
function goToDetail(item) {
|
||||||
console.log('Navigate to detail', item);
|
if (!item?.articleId) return;
|
||||||
|
uni.navigateTo({ url: `/pages/article/article-detail?id=${item.articleId}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onShow(async () => {
|
||||||
|
if (!inited.value) {
|
||||||
|
await loadCustomers();
|
||||||
|
await loadArticleList(true);
|
||||||
|
inited.value = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await loadArticleList(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
onReachBottom(() => {
|
||||||
|
if (loading.value) return;
|
||||||
|
if (articles.value.length >= total.value) return;
|
||||||
|
page.value += 1;
|
||||||
|
loadArticleList(false);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -206,4 +297,35 @@ function goToDetail(item) {
|
|||||||
line-clamp: 2;
|
line-clamp: 2;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.field-label {
|
||||||
|
flex-shrink: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-container,
|
||||||
|
.empty-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 100rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-more,
|
||||||
|
.no-more {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
gap: 10rpx;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -68,6 +68,8 @@ watch(articleIds, n => {
|
|||||||
margin: 0 30rpx;
|
margin: 0 30rpx;
|
||||||
margin-top: 24rpx;
|
margin-top: 24rpx;
|
||||||
padding-bottom: 40rpx;
|
padding-bottom: 40rpx;
|
||||||
|
width: calc(100% - 60rpx);
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow-icon {
|
.arrow-icon {
|
||||||
@ -91,6 +93,8 @@ watch(articleIds, n => {
|
|||||||
min-height: 188rpx;
|
min-height: 188rpx;
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-card:active {
|
.article-card:active {
|
||||||
|
|||||||
@ -15,8 +15,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<scroll-view scroll-x="true">
|
<scroll-view scroll-x="true">
|
||||||
<view class="flex flex-nowrap pb-5 ">
|
<view class="flex flex-nowrap pb-5 ">
|
||||||
<view v-for="i in customers" :key="i._id"
|
<view v-for="i in customers" :key="i._id" class="customer-card flex-shrink-0 mr-15 relative"
|
||||||
class="customer-card flex-shrink-0 mr-15 relative"
|
|
||||||
:class="current && i._id === current._id ? 'current-customer' : ''" @click="toggle(i)">
|
:class="current && i._id === current._id ? 'current-customer' : ''" @click="toggle(i)">
|
||||||
<!-- 关系标签 -->
|
<!-- 关系标签 -->
|
||||||
<view v-if="i.relationship" class="relationship-tag"
|
<view v-if="i.relationship" class="relationship-tag"
|
||||||
@ -24,16 +23,13 @@
|
|||||||
{{ i.relationship }}
|
{{ i.relationship }}
|
||||||
</view>
|
</view>
|
||||||
<view class="flex flex-col items-center">
|
<view class="flex flex-col items-center">
|
||||||
<view class="customer-name text-lg leading-normal font-semibold whitespace-nowrap mb-8"
|
<view class="customer-name text-lg leading-normal font-semibold whitespace-nowrap "
|
||||||
:class="current && i._id === current._id ? 'text-primary' : 'text-dark'">
|
:class="current && i._id === current._id ? 'text-primary' : 'text-dark'">
|
||||||
{{ i.name }}
|
{{ i.name }}
|
||||||
</view>
|
</view>
|
||||||
<view class="flex items-center mb-5">
|
<view class="flex items-center mb-5">
|
||||||
<image
|
<image v-if="i.sex" class="sex-icon mr-5"
|
||||||
v-if="i.sex"
|
:src="i.sex === '男' ? '/static/home/male.svg' : '/static/home/female.svg'" />
|
||||||
class="sex-icon mr-5"
|
|
||||||
:src="i.sex === '男' ? '/static/home/male.svg' : '/static/home/female.svg'"
|
|
||||||
/>
|
|
||||||
<view class="customer-age text-base leading-normal text-gray">
|
<view class="customer-age text-base leading-normal text-gray">
|
||||||
{{ i.age > 0 ? i.age + '岁' : '' }}
|
{{ i.age > 0 ? i.age + '岁' : '' }}
|
||||||
</view>
|
</view>
|
||||||
@ -49,24 +45,25 @@
|
|||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view v-if="canAuth" class="px-10 py-5 mt-5 flex items-center bg-danger rounded-sm">
|
<view v-if="canAuth" class="px-10 py-5 mt-5 flex items-center bg-danger rounded-sm">
|
||||||
<view class="mr-5 w-0 flex-grow text-base text-white">
|
<view class="mr-5 w-0 flex-grow text-base text-white">
|
||||||
该档案还未授权本服务团队,点击右侧授权按钮。我们将更精准的为您服务。
|
点击右侧授权按钮, 我们将更精准的为您服务
|
||||||
</view>
|
</view>
|
||||||
<view class="px-12 py-5 text-base rounded-sm text-dark bg-white" @click="auth()">
|
<view class="px-12 py-5 text-base rounded-sm text-dark bg-white" @click="auth()">
|
||||||
授权
|
授权
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="current" class="flex mt-15">
|
<view v-if="current" class="flex mt-15">
|
||||||
<view class="info-card-new flex-grow mr-10" @click="fillBaseInfo()">
|
<view class="info-card-new flex-grow" @click="fillBaseInfo()">
|
||||||
<view class="info-bg info-bg-base"></view>
|
<view class="info-bg info-bg-base"></view>
|
||||||
<view class="info-content">
|
<view class="info-content">
|
||||||
<view class="flex items-center justify-between mb-8">
|
<view class="flex items-center justify-between mb-8">
|
||||||
<view class="info-title">个人基本信息</view>
|
<view class="info-title">个人基本信息</view>
|
||||||
<image class="arrow-icon-small" src="/static/home/arrow-right-blue.png" mode="aspectFit"></image>
|
<image class="arrow-icon-small" src="/static/home/arrow-right-blue.png" mode="aspectFit"></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-subtitle">完善个人信息</view>
|
<view v-if="baseInfoError" class="text-sm text-danger">请完善您的个人信息</view>
|
||||||
|
<view v-else class="info-subtitle">完善个人信息</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-card-new flex-grow" @click="toHealthList()">
|
<view v-if="hasHealthTemp" class="ml-10 info-card-new flex-grow" @click="toHealthList()">
|
||||||
<view class="info-bg info-bg-health"></view>
|
<view class="info-bg info-bg-health"></view>
|
||||||
<view class="info-content">
|
<view class="info-content">
|
||||||
<view class="flex items-center justify-between mb-8">
|
<view class="flex items-center justify-between mb-8">
|
||||||
@ -80,7 +77,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, onMounted, ref, watch } from 'vue';
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import useAccount from '@/store/account';
|
import useAccount from '@/store/account';
|
||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
@ -114,6 +111,17 @@ const canAuth = computed(() => {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
const qrcode = computed(() => {
|
||||||
|
const qrcodes = props.team && Array.isArray(props.team.qrcodes) ? props.team.qrcodes : [];
|
||||||
|
return qrcodes[0] || ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const hasHealthTemp = computed(() => qrcode.value && Array.isArray(qrcode.value.healthTempList) && qrcode.value.healthTempList.length > 0)
|
||||||
|
const baseInfo = computed(() => qrcode.value && qrcode.value.teamFileds && Array.isArray(qrcode.value.teamFileds.baseInfo) ? qrcode.value.teamFileds.baseInfo : [])
|
||||||
|
const baseInfoError = computed(() => {
|
||||||
|
const requiredTitles = baseInfo.value.filter(i => i.required).map(i => i.title);
|
||||||
|
return current.value && requiredTitles.some(i => !current.value[i]);
|
||||||
|
})
|
||||||
|
|
||||||
function fillBaseInfo() {
|
function fillBaseInfo() {
|
||||||
if (canAuth.value) {
|
if (canAuth.value) {
|
||||||
@ -161,7 +169,6 @@ async function getCustomers() {
|
|||||||
customers.value = res && Array.isArray(res.data) ? res.data : [];
|
customers.value = res && Array.isArray(res.data) ? res.data : [];
|
||||||
const customer = customers.value.find(i => current.value && i._id === current.value._id);
|
const customer = customers.value.find(i => current.value && i._id === current.value._id);
|
||||||
current.value = customer || customers.value[0] || null;
|
current.value = customer || customers.value[0] || null;
|
||||||
|
|
||||||
// 向父组件传递 customers 数据
|
// 向父组件传递 customers 数据
|
||||||
emit('update:customers', customers.value);
|
emit('update:customers', customers.value);
|
||||||
} else {
|
} else {
|
||||||
@ -169,6 +176,10 @@ async function getCustomers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
uni.$on('reloadTeamCustomers', getCustomers)
|
||||||
|
})
|
||||||
|
|
||||||
watch(() => props.corpId, n => {
|
watch(() => props.corpId, n => {
|
||||||
if (n) {
|
if (n) {
|
||||||
getCustomers()
|
getCustomers()
|
||||||
@ -203,7 +214,7 @@ watch(() => props.corpId, n => {
|
|||||||
|
|
||||||
.customer-card {
|
.customer-card {
|
||||||
width: 160rpx;
|
width: 160rpx;
|
||||||
height: 160rpx;
|
height: 110rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -219,9 +230,6 @@ watch(() => props.corpId, n => {
|
|||||||
border: 2rpx solid #065BD6;
|
border: 2rpx solid #065BD6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.customer-name {
|
|
||||||
margin-top: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.relationship-tag {
|
.relationship-tag {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -307,10 +315,6 @@ watch(() => props.corpId, n => {
|
|||||||
margin-bottom: 12rpx;
|
margin-bottom: 12rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sex-icon {
|
|
||||||
width: 32rpx;
|
|
||||||
height: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-card-new {
|
.info-card-new {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@ -1,19 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<page-loading v-if="loading" />
|
<page-loading v-if="loading && teams.length === 0" />
|
||||||
<full-page
|
<full-page v-else-if="teams.length && team" class="home-container" :pageStyle="pageStyle">
|
||||||
v-else-if="teams.length && team"
|
|
||||||
class="home-container"
|
|
||||||
:pageStyle="pageStyle"
|
|
||||||
>
|
|
||||||
<template #header>
|
<template #header>
|
||||||
<team-head :team="team" :teams="teams" @changeTeam="changeTeam" />
|
<team-head :team="team" :teams="teams" @changeTeam="changeTeam" />
|
||||||
</template>
|
</template>
|
||||||
<view class="home-section home-section--first">
|
<view class="home-section home-section--first">
|
||||||
<customer-archive
|
<customer-archive :corpId="corpId" :team="team" @update:customers="handleCustomersUpdate" />
|
||||||
:corpId="corpId"
|
|
||||||
:team="team"
|
|
||||||
@update:customers="handleCustomersUpdate"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="home-section">
|
<view class="home-section">
|
||||||
<consult :corpId="corpId" :teamId="team.teamId" :customers="customers" />
|
<consult :corpId="corpId" :teamId="team.teamId" :customers="customers" />
|
||||||
@ -76,7 +68,7 @@ async function changeTeam({ teamId, corpId, corpName }) {
|
|||||||
|
|
||||||
async function getTeams() {
|
async function getTeams() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const res = await api("queryWxJoinedTeams", { openid: account.value.openid });
|
const res = await api('getWxappRelateTeams', { openid: account.value.openid });
|
||||||
teams.value = res && Array.isArray(res.data) ? res.data : [];
|
teams.value = res && Array.isArray(res.data) ? res.data : [];
|
||||||
const validTeam =
|
const validTeam =
|
||||||
teams.value.find(
|
teams.value.find(
|
||||||
|
|||||||
@ -3,70 +3,48 @@
|
|||||||
<view :style="{ height: statusBarHeight }" class="status-bar"></view>
|
<view :style="{ height: statusBarHeight }" class="status-bar"></view>
|
||||||
<view class="relative z-3 flex items-center px-15 py-12 header-bar">
|
<view class="relative z-3 flex items-center px-15 py-12 header-bar">
|
||||||
<view class="flex-shrink-0 mr-5">
|
<view class="flex-shrink-0 mr-5">
|
||||||
<group-avatar
|
<group-avatar :size="120" :avatarList="currentTeam ? currentTeam.avatarList : []" />
|
||||||
:size="120"
|
|
||||||
:avatarList="currentTeam ? currentTeam.avatarList : []"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="w-0 flex-grow">
|
<view class="w-0 flex-grow">
|
||||||
<view class="flex items-center mb-10">
|
<view class="flex items-center mb-10">
|
||||||
<view class="team-name flex-shrink-0">{{ team.name }}</view>
|
<view class="team-name flex-shrink-0">{{ team.name }}</view>
|
||||||
<view
|
<view v-if="teams.length > 1" class="flex-shrink-0 flex items-center switch-btn ml-10"
|
||||||
v-if="teams.length > 1"
|
@click="showDropDown = true">
|
||||||
class="flex-shrink-0 flex items-center switch-btn ml-10"
|
<image class="switch-icon" src="/static/home/switch-team.png" mode="aspectFit"></image>
|
||||||
@click="showDropDown = true"
|
|
||||||
>
|
|
||||||
<image
|
|
||||||
class="switch-icon"
|
|
||||||
src="/static/home/switch-team.png"
|
|
||||||
mode="aspectFit"
|
|
||||||
></image>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="currentTeam" class="text-base text-white truncate">{{
|
<view v-if="currentTeam" class="text-base text-white truncate">
|
||||||
currentTeam.corpName
|
{{ currentTeam.corpName }}
|
||||||
}}</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view v-if="menuButtonInfo && menuButtonInfo.width > 0" class="flex-shrink-0" :style="{
|
||||||
v-if="menuButtonInfo && menuButtonInfo.width > 0"
|
width: menuButtonInfo.width + 'px',
|
||||||
class="flex-shrink-0"
|
height: menuButtonInfo.height + 'px',
|
||||||
:style="{
|
}">
|
||||||
width: menuButtonInfo.width + 'px',
|
|
||||||
height: menuButtonInfo.height + 'px',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="relative">
|
<view class="relative">
|
||||||
<view v-if="showDropDown" class="team-dropdown py-12 bg-white shadow-lg">
|
<view v-if="showDropDown" class="team-dropdown py-12 bg-white shadow-lg">
|
||||||
<scroll-view scroll-y="true" style="max-height: 50vh">
|
<scroll-view scroll-y="true" style="max-height: 50vh">
|
||||||
<view class="px-15">
|
<view class="px-15">
|
||||||
<view
|
<view v-for="item in teams" :key="item.teamId" class="mb-10 p-10 flex items-center bg-gray rounded-sm"
|
||||||
v-for="item in teams"
|
@click="select(item)">
|
||||||
:key="item.teamId"
|
|
||||||
class="mb-10 p-10 flex items-center bg-gray rounded-sm"
|
|
||||||
@click="select(item)"
|
|
||||||
>
|
|
||||||
<view class="flex-shrink-0 mr-5 rounded-circle">
|
<view class="flex-shrink-0 mr-5 rounded-circle">
|
||||||
<group-avatar :size="96" :avatarList="item.avatarList" />
|
<group-avatar :size="96" :avatarList="item.avatarList" />
|
||||||
</view>
|
</view>
|
||||||
<view class="w-0 flex-grow mr-5">
|
<view class="w-0 flex-grow mr-5">
|
||||||
<view class="mb-5 text-lg font-semibold text-dark">{{
|
<view class="mb-5 text-lg font-semibold text-dark">
|
||||||
item.name
|
{{ item.name }}
|
||||||
}}</view>
|
</view>
|
||||||
<view class="text-base text-gray leading-normal">{{
|
<view class="text-base text-gray leading-normal">
|
||||||
item.corpName
|
{{ item.corpName }}
|
||||||
}}</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex">
|
<view class="flex">
|
||||||
<image
|
<image class="check-icon" :src="team && team.teamId === item.teamId
|
||||||
class="check-icon"
|
? '/static/form/checked.svg'
|
||||||
:src="
|
: '/static/form/uncheck.svg'
|
||||||
team && team.teamId === item.teamId
|
">
|
||||||
? '/static/form/checked.svg'
|
|
||||||
: '/static/form/unchecked.svg'
|
|
||||||
"
|
|
||||||
>
|
|
||||||
</image>
|
</image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -74,20 +52,16 @@
|
|||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="team.teamTroduce" class="team-introduce-wrapper">
|
<view v-if="qrcode && qrcode.guide" class="team-introduce-wrapper">
|
||||||
<view class="team-introduce flex items-center">
|
<view class="team-introduce flex items-center">
|
||||||
<!-- 顶部小三角形 -->
|
<!-- 顶部小三角形 -->
|
||||||
<view class="triangle-wrapper">
|
<view class="triangle-wrapper">
|
||||||
<view class="team-triangle"></view>
|
<view class="team-triangle"></view>
|
||||||
</view>
|
</view>
|
||||||
<image
|
<image class="laba-icon flex-shrink-0" src="/static/home/speaker-intro.png" mode="aspectFit"></image>
|
||||||
class="laba-icon flex-shrink-0"
|
<view class="introduce-text flex-grow line-clamp-2">
|
||||||
src="/static/home/speaker-intro.png"
|
{{ qrcode.guide }}
|
||||||
mode="aspectFit"
|
</view>
|
||||||
></image>
|
|
||||||
<view class="introduce-text flex-grow line-clamp-2">{{
|
|
||||||
team.teamTroduce
|
|
||||||
}}</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -117,6 +91,10 @@ const props = defineProps({
|
|||||||
const currentTeam = computed(() =>
|
const currentTeam = computed(() =>
|
||||||
props.teams.find((i) => props.team && i.teamId === props.team.teamId)
|
props.teams.find((i) => props.team && i.teamId === props.team.teamId)
|
||||||
);
|
);
|
||||||
|
const qrcode = computed(() => {
|
||||||
|
const qrcodes = props.team && Array.isArray(props.team.qrcodes) ? props.team.qrcodes : [];
|
||||||
|
return qrcodes[0] || ''
|
||||||
|
})
|
||||||
|
|
||||||
function select(team) {
|
function select(team) {
|
||||||
emits("changeTeam", team);
|
emits("changeTeam", team);
|
||||||
@ -195,11 +173,9 @@ onMounted(() => {
|
|||||||
width: 690rpx;
|
width: 690rpx;
|
||||||
min-height: 111rpx;
|
min-height: 111rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: linear-gradient(
|
background: linear-gradient(186deg,
|
||||||
186deg,
|
rgba(255, 255, 255, 0.4) 13.34%,
|
||||||
rgba(255, 255, 255, 0.4) 13.34%,
|
rgba(255, 255, 255, 0.6) 99.17%);
|
||||||
rgba(255, 255, 255, 0.6) 99.17%
|
|
||||||
);
|
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
padding: 20rpx 20rpx 20rpx 0;
|
padding: 20rpx 20rpx 20rpx 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -223,11 +199,9 @@ onMounted(() => {
|
|||||||
bottom: -10rpx;
|
bottom: -10rpx;
|
||||||
width: 16rpx;
|
width: 16rpx;
|
||||||
height: 16rpx;
|
height: 16rpx;
|
||||||
background: linear-gradient(
|
background: linear-gradient(186deg,
|
||||||
186deg,
|
rgba(255, 255, 255, 0.4) 13.34%,
|
||||||
rgba(255, 255, 255, 0.4) 13.34%,
|
rgba(255, 255, 255, 0.6) 99.17%);
|
||||||
rgba(255, 255, 255, 0.6) 99.17%
|
|
||||||
);
|
|
||||||
transform: translateX(-50%) rotate(45deg);
|
transform: translateX(-50%) rotate(45deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +233,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
.mask {
|
.mask {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 2;
|
z-index: 99;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
@ -268,7 +242,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.z-3 {
|
.z-3 {
|
||||||
z-index: 3;
|
z-index: 101;
|
||||||
}
|
}
|
||||||
|
|
||||||
.team-dropdown {
|
.team-dropdown {
|
||||||
@ -276,7 +250,7 @@ onMounted(() => {
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 3;
|
z-index: 100;
|
||||||
border-bottom-left-radius: 16rpx;
|
border-bottom-left-radius: 16rpx;
|
||||||
border-bottom-right-radius: 16rpx;
|
border-bottom-right-radius: 16rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<view v-for="i in teamates" :key="i.userid"
|
<view v-for="i in teamates" :key="i.userid"
|
||||||
class="member-card flex flex-shrink-0 min-w-120 mr-15 p-15"
|
class="member-card flex flex-shrink-0 min-w-120 mr-15 p-15"
|
||||||
@click="toHomePage(i)">
|
@click="toHomePage(i)">
|
||||||
<image class="flex-shrink-0 avatar mr-10" :src="i.avatar || '/static/default-avatar.png'" />
|
<image class="flex-shrink-0 avatar mr-10" :src="i.avatar || '/static/default-avatar.svg'" />
|
||||||
<view class="flex-grow flex flex-col justify-between">
|
<view class="flex-grow flex flex-col justify-between">
|
||||||
<view>
|
<view>
|
||||||
<view class="member-name leading-normal h-24 text-base font-semibold text-dark whitespace-nowrap">
|
<view class="member-name leading-normal h-24 text-base font-semibold text-dark whitespace-nowrap">
|
||||||
|
|||||||
@ -1,49 +1,68 @@
|
|||||||
<template>
|
<template>
|
||||||
<view v-if="team" class="pt-lg px-15 flex flex-col items-center text-center">
|
<view class="login-bg">
|
||||||
<group-avatar :avatarList="team.avatars" />
|
<image class="bg-image" src="/static/background.png" mode="aspectFill" />
|
||||||
<view class="mt-15 text-base font-semibold text-dark">
|
<!-- 医生卡片及头像 -->
|
||||||
{{ team.teamName }}
|
<view class="doctor-card-wrap">
|
||||||
|
<view v-if="team" class="doctor-card">
|
||||||
|
<view class="doctor-info">
|
||||||
|
<view class="doctor-name">{{ team.teamName }}</view>
|
||||||
|
<view class="doctor-hospital">{{ team.corpName }}</view>
|
||||||
|
<view class="login-tip">为您提供团队个性化专属服务</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="doctor-card doctor-card-empty">
|
||||||
|
<view class="doctor-info">
|
||||||
|
<image class="logo" src="/static/logo-plain.png" mode="aspectFill" />
|
||||||
|
<view class="doctor-name">柚健康</view>
|
||||||
|
<view class="login-tip">生命全周期健康管理伙伴</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="team" class="doctor-avatar">
|
||||||
|
<group-avatar :avatarList="team.avatars" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 登录按钮 -->
|
||||||
|
<view class="login-btn-wrap">
|
||||||
|
<button v-if="checked && account" class="login-btn" type="primary" @click="getPhoneNumber">
|
||||||
|
手机号快捷登录
|
||||||
|
</button>
|
||||||
|
<button v-else-if="checked" class="login-btn" type="primary" open-type="getPhoneNumber"
|
||||||
|
@getphonenumber="getPhoneNumber">
|
||||||
|
手机号快捷登录
|
||||||
|
</button>
|
||||||
|
<button v-else class="login-btn" type="primary" @click="remind()">
|
||||||
|
手机号快捷登录
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
<!-- 协议 -->
|
||||||
|
<view class="agreement">
|
||||||
|
<checkbox :checked="checked" @click="checked = !checked" />
|
||||||
|
<text>我已阅读并同意</text>
|
||||||
|
<text class="link" @click="openUserAgreement">《用户协议》</text>
|
||||||
|
<text>、</text>
|
||||||
|
<text class="link" @click="openPrivacyPolicy">《隐私政策》</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-12 text-sm text-gray">{{ team.corpName }}</view>
|
|
||||||
<view class="mt-15 text-lg text-dark font-semibold">为您提供团队个性化专属服务</view>
|
|
||||||
</view>
|
|
||||||
<view v-else class="pt-lg px-15 flex flex-col items-center text-center">
|
|
||||||
<image src="/static/logo-plain.png" class="logo"></image>
|
|
||||||
<view class="mt-15 text-xl font-semibold text-dark">柚健康</view>
|
|
||||||
<view class="mt-12 text-base text-dark">生命全周期健康管理伙伴</view>
|
|
||||||
</view>
|
|
||||||
<view class="login-btn-wrap">
|
|
||||||
<button v-if="checked" class="login-btn" type="primary" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">
|
|
||||||
手机号快捷登录
|
|
||||||
</button>
|
|
||||||
<!-- <button v-if="checked" class="login-btn" type="primary" @click="getPhoneNumber()">
|
|
||||||
手机号快捷登录
|
|
||||||
</button> -->
|
|
||||||
<button v-else class="login-btn" type="primary" @click="remind()">
|
|
||||||
手机号快捷登录
|
|
||||||
</button>
|
|
||||||
</view>
|
|
||||||
<view class="flex items-center justify-center mt-12 px-15" @click="checked = !checked">
|
|
||||||
<checkbox :checked="checked" style="transform: scale(0.7)" />
|
|
||||||
<view class="text-sm text-gray">我已阅读并同意</view>
|
|
||||||
<view class="text-sm text-primary">《用户协议》、</view>
|
|
||||||
<view class="text-sm text-primary">《隐私政策》</view>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
import useAccountStore from "@/store/account";
|
import useAccountStore from "@/store/account";
|
||||||
|
import api from '@/utils/api';
|
||||||
import { get } from "@/utils/cache";
|
import { get } from "@/utils/cache";
|
||||||
import { toast } from "@/utils/widget";
|
import { toast } from "@/utils/widget";
|
||||||
|
|
||||||
import groupAvatar from "@/components/group-avatar.vue";
|
import groupAvatar from "@/components/group-avatar.vue";
|
||||||
|
|
||||||
|
const env = __VITE_ENV__;
|
||||||
|
const appid = env.MP_WX_APP_ID;
|
||||||
const team = ref(null);
|
const team = ref(null);
|
||||||
const checked = ref(false);
|
const checked = ref(false);
|
||||||
const redirectUrl = ref("");
|
const redirectUrl = ref("");
|
||||||
|
const { account } = storeToRefs(useAccountStore());
|
||||||
const { login } = useAccountStore();
|
const { login } = useAccountStore();
|
||||||
|
|
||||||
function attempRedirect(url) {
|
function attempRedirect(url) {
|
||||||
@ -71,16 +90,33 @@ function remind() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toHome() {
|
function toHome() {
|
||||||
uni.navigateTo({
|
uni.switchTab({
|
||||||
url: "/pages/home/home",
|
url: "/pages/home/home",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function bindTeam() {
|
||||||
|
const res = await api('bindWxappWithTeam', { appid, corpId: team.value.corpId, teamId: team.value.teamId, openid: account.value.openid });
|
||||||
|
if (!res || !res.success) {
|
||||||
|
return toast("关联团队失败");
|
||||||
|
}
|
||||||
|
const res1 = await api('getWxAppCustomerCount', { miniAppId: account.value.openid, corpId: account.value.corpId, teamId: team.value.teamId });
|
||||||
|
if (res1 && res1.data > 0) {
|
||||||
|
toHome();
|
||||||
|
} else {
|
||||||
|
attempToPage(redirectUrl.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getPhoneNumber(e) {
|
async function getPhoneNumber(e) {
|
||||||
const phoneCode = e && e.detail && e.detail.code;
|
const phoneCode = e && e.detail && e.detail.code;
|
||||||
if (e && !phoneCode) return;
|
if (!account.value) {
|
||||||
const res = await login(phoneCode);
|
const res = await login(phoneCode);
|
||||||
if (res && redirectUrl.value) {
|
if (!res) return;
|
||||||
|
}
|
||||||
|
if (team.value) {
|
||||||
|
bindTeam(account.value)
|
||||||
|
} else if (redirectUrl.value) {
|
||||||
await attempToPage(redirectUrl.value);
|
await attempToPage(redirectUrl.value);
|
||||||
} else if (res) {
|
} else if (res) {
|
||||||
toHome();
|
toHome();
|
||||||
@ -99,7 +135,6 @@ onLoad((opts) => {
|
|||||||
if (opts.source === "teamInvite") {
|
if (opts.source === "teamInvite") {
|
||||||
team.value = get("invite-team-info");
|
team.value = get("invite-team-info");
|
||||||
redirectUrl.value = `/pages/archive/edit-archive?teamId=${team.value.teamId}&corpId=${team.value.corpId}`;
|
redirectUrl.value = `/pages/archive/edit-archive?teamId=${team.value.teamId}&corpId=${team.value.corpId}`;
|
||||||
console.log("redirectUrl", redirectUrl.value);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
redirectUrl.value = opts.redirectUrl || "";
|
redirectUrl.value = opts.redirectUrl || "";
|
||||||
@ -110,11 +145,6 @@ onLoad((opts) => {
|
|||||||
padding-top: 20vh;
|
padding-top: 20vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
|
||||||
width: 160rpx;
|
|
||||||
height: 160rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-btn-wrap {
|
.login-btn-wrap {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -143,4 +173,161 @@ onLoad((opts) => {
|
|||||||
.login-btn:active {
|
.login-btn:active {
|
||||||
background: linear-gradient(270deg, #1b5cc8 2.26%, #0877f1 94.33%);
|
background: linear-gradient(270deg, #1b5cc8 2.26%, #0877f1 94.33%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-bg {
|
||||||
|
min-height: 100vh;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 180rpx;
|
||||||
|
height: 180rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-image {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 500rpx;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-gradient {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 340rpx;
|
||||||
|
background: linear-gradient(270deg, #1b5cc8 2.26%, #0877f1 94.33%);
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctor-card-wrap {
|
||||||
|
width: calc(100vw - 48rpx);
|
||||||
|
max-width: 600rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
margin-top: 320rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctor-card {
|
||||||
|
height: 398rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
background: linear-gradient(180deg, #dbe8ff 0%, #fff 50.25%);
|
||||||
|
box-shadow: 0 8rpx 32rpx rgba(59, 124, 255, 0.08);
|
||||||
|
padding: 100rpx 24rpx 0rpx 24rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctor-avatar {
|
||||||
|
border-radius: 16rpx;
|
||||||
|
background: #f2f2f2;
|
||||||
|
box-shadow: 0 2rpx 8rpx rgba(59, 124, 255, 0.08);
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 0;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
border: 6rpx solid #fff;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctor-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctor-name {
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1d2129;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctor-hospital {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #78808f;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctor-dept {
|
||||||
|
display: inline-block;
|
||||||
|
color: #213e80;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
border: 1rpx solid #1a3e8433;
|
||||||
|
padding: 0 8rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-tip {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #000000;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn-wrap {
|
||||||
|
width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 136rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn-wrap-loading {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn {
|
||||||
|
width: calc(100vw - 112rpx);
|
||||||
|
max-width: 600rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
line-height: 96rpx;
|
||||||
|
background: linear-gradient(270deg, #1b5cc8 2.26%, #0877f1 94.33%);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 32rpx;
|
||||||
|
border-radius: 48rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
box-shadow: 0 4rpx 16rpx rgba(59, 124, 255, 0.08);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn:active {
|
||||||
|
background: linear-gradient(270deg, #1b5cc8 2.26%, #0877f1 94.33%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement {
|
||||||
|
width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: #b2b7c2;
|
||||||
|
font-size: 22rpx;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
gap: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
color: #3b7cff;
|
||||||
|
margin: 0 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement checkbox {
|
||||||
|
transform: scale(0.7);
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -5,49 +5,73 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
import api from "@/utils/api";
|
import api from "@/utils/api";
|
||||||
import { set } from "@/utils/cache";
|
import { set } from "@/utils/cache";
|
||||||
import { toast } from "@/utils/widget";
|
import { toast } from "@/utils/widget";
|
||||||
|
import useAccountStore from "@/store/account";
|
||||||
|
|
||||||
|
const env = __VITE_ENV__;
|
||||||
|
const appid = env.MP_WX_APP_ID;
|
||||||
|
const { account } = storeToRefs(useAccountStore());
|
||||||
|
|
||||||
|
|
||||||
const teamId = ref("");
|
|
||||||
const corpId = ref("");
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const team = ref(null);
|
const team = ref(null);
|
||||||
|
|
||||||
async function changeTeam({ teamId, corpId, corpName }) {
|
async function changeTeam({ teamId, corpId }) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const res = await api("getTeamData", { teamId, corpId, withCorpName: true });
|
const res = await api("getTeamData", { teamId, corpId, withCorpName: true });
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
if (res && res.data) {
|
if (res && res.data) {
|
||||||
team.value = res.data;
|
team.value = res.data;
|
||||||
team.value.corpName = corpName;
|
team.value.corpName = res.data.corpName;
|
||||||
set("invite-team-info", {
|
if (account.value) {
|
||||||
corpId: team.value.corpId,
|
bindTeam()
|
||||||
teamId: team.value.teamId,
|
} else {
|
||||||
corpName: team.value.corpName,
|
set("invite-team-info", {
|
||||||
teamName: team.value.name,
|
corpId: team.value.corpId,
|
||||||
avatars:
|
teamId: team.value.teamId,
|
||||||
team.value && Array.isArray(team.value.memberList)
|
corpName: team.value.corpName,
|
||||||
? team.value.memberList.map((item) => item.avatar || "")
|
teamName: team.value.name,
|
||||||
: [],
|
avatars:
|
||||||
});
|
team.value && Array.isArray(team.value.memberList)
|
||||||
uni.redirectTo({
|
? team.value.memberList.map((item) => item.avatar || "")
|
||||||
url: "/pages/login/login?source=teamInvite",
|
: [],
|
||||||
});
|
});
|
||||||
|
uni.redirectTo({
|
||||||
|
url: "/pages/login/login?source=teamInvite",
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toast(res?.message || "获取团队信息失败");
|
toast(res?.message || "获取团队信息失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function bindTeam() {
|
||||||
|
const res = await api('bindWxappWithTeam', { appid, corpId: team.value.corpId, teamId: team.value.teamId, openid: account.value.openid });
|
||||||
|
if (!res || !res.success) {
|
||||||
|
return toast("关联团队失败");
|
||||||
|
}
|
||||||
|
const res1 = await api('getWxAppCustomerCount', { miniAppId: account.value.openid, corpId: account.value.corpId, teamId: team.value.teamId });
|
||||||
|
if (res1 && res1.data > 0) {
|
||||||
|
uni.switchTab({
|
||||||
|
url: "/pages/home/home",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.redirectTo({
|
||||||
|
url: `/pages/archive/edit-archive?teamId=${team.value.teamId}&corpId=${team.value.corpId}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
const href =
|
const href =
|
||||||
typeof options.q === "string" ? decodeURIComponent(options.q) : "";
|
typeof options.q === "string" ? decodeURIComponent(options.q) : "";
|
||||||
const [, url = ""] = href.split("?");
|
const [, url = ""] = href.split("?");
|
||||||
const data = url.split("&").reduce((acc, cur) => {
|
const data = url.split("&").reduce((acc, cur) => {
|
||||||
console.log(cur);
|
|
||||||
const [key, value] = cur.split("=");
|
const [key, value] = cur.split("=");
|
||||||
console.log(key, "=====", value);
|
|
||||||
acc[key] = value;
|
acc[key] = value;
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import useTeamStore from '@/store/team.js'
|
|||||||
export default function useGroupAvatars() {
|
export default function useGroupAvatars() {
|
||||||
const groupAvatarMap = ref({}) // { groupID: [avatarUrl1, avatarUrl2, ...] }
|
const groupAvatarMap = ref({}) // { groupID: [avatarUrl1, avatarUrl2, ...] }
|
||||||
const teamStore = useTeamStore()
|
const teamStore = useTeamStore()
|
||||||
const patientDefaultAvatar = '/static/default-avatar.png'
|
const patientDefaultAvatar = '/static/default-avatar.svg'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取单个群聊的头像列表
|
* 获取单个群聊的头像列表
|
||||||
|
|||||||
@ -45,8 +45,8 @@ export default function useGroupChat(groupID) {
|
|||||||
const member = chatMember.value[userId]
|
const member = chatMember.value[userId]
|
||||||
if (!member) {
|
if (!member) {
|
||||||
// 如果找不到成员信息,根据是否为团队成员返回默认头像
|
// 如果找不到成员信息,根据是否为团队成员返回默认头像
|
||||||
// 团队成员和患者都使用 default-avatar.png
|
// 团队成员和患者都使用 default-avatar.svg
|
||||||
return '/static/default-avatar.png'
|
return '/static/default-avatar.svg'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果有头像且不为空字符串,返回头像
|
// 如果有头像且不为空字符串,返回头像
|
||||||
@ -55,7 +55,7 @@ export default function useGroupChat(groupID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 否则使用默认头像
|
// 否则使用默认头像
|
||||||
return '/static/default-avatar.png'
|
return '/static/default-avatar.svg'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取群聊信息和成员头像
|
// 获取群聊信息和成员头像
|
||||||
|
|||||||
@ -11,16 +11,25 @@
|
|||||||
? 'bg-orange-100 text-orange-500 border-orange-500'
|
? 'bg-orange-100 text-orange-500 border-orange-500'
|
||||||
: 'bg-white text-gray-600 border-gray-200'
|
: 'bg-white text-gray-600 border-gray-200'
|
||||||
]"
|
]"
|
||||||
@click="activeTab = tab.value"
|
@click="selectTab(tab.value)"
|
||||||
>
|
>
|
||||||
{{ tab.name }}
|
{{ tab.name }}
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<!-- Survey List -->
|
<!-- Survey List -->
|
||||||
<view class="p-15">
|
<view v-if="loading && surveys.length === 0" class="loading-container">
|
||||||
|
<uni-icons type="spinner-cycle" size="30" color="#999" />
|
||||||
|
<text class="loading-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-else-if="!loading && surveys.length === 0" class="empty-container">
|
||||||
|
<empty-data text="暂无问卷" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-else class="p-15">
|
||||||
<view
|
<view
|
||||||
v-for="item in filteredSurveys"
|
v-for="item in surveys"
|
||||||
:key="item._id"
|
:key="item._id"
|
||||||
class="bg-white rounded-lg p-15 mb-15 shadow-sm"
|
class="bg-white rounded-lg p-15 mb-15 shadow-sm"
|
||||||
@click="goToDetail(item)"
|
@click="goToDetail(item)"
|
||||||
@ -30,7 +39,7 @@
|
|||||||
<view class="flex items-start flex-1 mr-10 relative">
|
<view class="flex items-start flex-1 mr-10 relative">
|
||||||
<!-- Tag -->
|
<!-- Tag -->
|
||||||
<view class="text-xs text-green-600 border border-green-600 px-5 rounded mr-5 flex-shrink-0 mt-1 tag-box">
|
<view class="text-xs text-green-600 border border-green-600 px-5 rounded mr-5 flex-shrink-0 mt-1 tag-box">
|
||||||
{{ item.type }}
|
问卷调查
|
||||||
</view>
|
</view>
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<view class="text-base font-bold text-gray-800 leading-normal line-clamp-2">
|
<view class="text-base font-bold text-gray-800 leading-normal line-clamp-2">
|
||||||
@ -38,93 +47,166 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- Status -->
|
<!-- Status (暂不展示未填写/已填写) -->
|
||||||
<view class="flex items-center flex-shrink-0 ml-2">
|
<view class="flex items-center flex-shrink-0 ml-2">
|
||||||
<text
|
<text class="text-sm mr-2 text-gray-400">查看</text>
|
||||||
class="text-sm mr-2"
|
<uni-icons type="right" size="14" color="#9ca3af"></uni-icons>
|
||||||
:class="item.status === 'UNFILLED' ? 'text-red-500' : 'text-gray-400'"
|
|
||||||
>
|
|
||||||
{{ item.status === 'UNFILLED' ? '未填写' : '查看' }}
|
|
||||||
</text>
|
|
||||||
<uni-icons type="right" size="14" :color="item.status === 'UNFILLED' ? '#ef4444' : '#9ca3af'"></uni-icons>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
<!-- Person -->
|
<view class="text-sm text-gray-600 mb-5 flex items-start">
|
||||||
<view class="text-sm text-gray-600 mb-5 flex items-center">
|
<text class="text-gray-400 mr-2 field-label">人员:</text>
|
||||||
<text class="text-gray-400 mr-2">人员:</text>
|
<text>{{ item.person || '-' }}</text>
|
||||||
<text>{{ item.person }}</text>
|
|
||||||
</view>
|
</view>
|
||||||
<!-- Team -->
|
|
||||||
<view class="text-sm text-gray-600 mb-10 pb-10 border-b border-gray-100 flex items-center">
|
<view class="text-sm text-gray-600 mb-10 pb-10 border-b border-gray-100 flex items-start">
|
||||||
<text class="text-gray-400 mr-2">团队:</text>
|
<text class="text-gray-400 mr-2 field-label">团队:</text>
|
||||||
<text>{{ item.team }}</text>
|
<text>{{ item.team || '-' }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<view class="text-sm text-gray-400">
|
<view class="text-sm text-gray-400">
|
||||||
发送时间: {{ item.time }}
|
发送时间: {{ item.time || '-' }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view v-if="loading && surveys.length > 0" class="loading-more">
|
||||||
|
<uni-icons type="spinner-cycle" size="20" color="#999" />
|
||||||
|
<text>加载中...</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="!loading && surveys.length >= total" class="no-more">
|
||||||
|
没有更多了
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref } from "vue";
|
||||||
|
import { onShow, onReachBottom } from "@dcloudio/uni-app";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import api from "@/utils/api.js";
|
||||||
|
import useAccountStore from "@/store/account.js";
|
||||||
|
import EmptyData from "@/components/empty-data.vue";
|
||||||
|
|
||||||
// Mock Data
|
const env = __VITE_ENV__;
|
||||||
const tabs = [
|
const corpId = env.MP_CORP_ID;
|
||||||
{ name: '全部', value: 'ALL' },
|
const { openid } = storeToRefs(useAccountStore());
|
||||||
{ name: '李珊珊 女 37岁', value: '1' },
|
|
||||||
{ name: '罗小小 女 17岁', value: '2' },
|
|
||||||
];
|
|
||||||
|
|
||||||
const activeTab = ref('ALL');
|
const tabs = ref([{ name: "全部", value: "" }]);
|
||||||
|
const activeTab = ref("");
|
||||||
|
|
||||||
const surveys = ref([
|
const surveys = ref([]);
|
||||||
{
|
const total = ref(0);
|
||||||
_id: 1,
|
const page = ref(1);
|
||||||
type: '问卷调查',
|
const pageSize = 20;
|
||||||
title: '门诊满意度调查问卷',
|
const loading = ref(false);
|
||||||
status: 'UNFILLED',
|
const inited = ref(false);
|
||||||
person: '李珊珊 女 36岁',
|
|
||||||
team: '妊糖管理服务团队',
|
const selectTab = async (memberId) => {
|
||||||
time: '2026-01-09 15:23',
|
if (activeTab.value === memberId) return;
|
||||||
ownerId: '1'
|
activeTab.value = memberId;
|
||||||
},
|
await loadSurveyList(true);
|
||||||
{
|
};
|
||||||
_id: 2,
|
|
||||||
type: '问卷调查',
|
const loadCustomers = async () => {
|
||||||
title: 'xxxx术后1周随访调查问卷',
|
const miniAppId = openid.value || uni.getStorageSync("openid");
|
||||||
status: 'FILLED',
|
if (!miniAppId) return;
|
||||||
person: '李珊珊 女 36岁',
|
try {
|
||||||
team: '妊糖管理服务团队',
|
const res = await api("getMiniAppCustomers", { miniAppId, corpId });
|
||||||
time: '2026-01-09 15:23',
|
if (res && res.success) {
|
||||||
ownerId: '1'
|
const list = Array.isArray(res.data) ? res.data : [];
|
||||||
},
|
tabs.value = [
|
||||||
{
|
{ name: "全部", value: "" },
|
||||||
_id: 3,
|
...list.map((c) => ({ name: c.name || "未命名", value: c._id })),
|
||||||
type: '问卷调查',
|
];
|
||||||
title: 'xxxxx术后2周随访调查问卷',
|
} else {
|
||||||
status: 'FILLED',
|
uni.showToast({ title: res?.message || "获取档案失败", icon: "none" });
|
||||||
person: '罗小小 女 16岁',
|
}
|
||||||
team: '妊糖管理服务团队',
|
} catch (err) {
|
||||||
time: '2026-01-09 15:23',
|
console.error("loadCustomers failed:", err);
|
||||||
ownerId: '2'
|
uni.showToast({ title: "获取档案失败", icon: "none" });
|
||||||
}
|
}
|
||||||
]);
|
};
|
||||||
|
|
||||||
const filteredSurveys = computed(() => {
|
const mapRowToView = (row) => {
|
||||||
if (activeTab.value === 'ALL') return surveys.value;
|
const sendTime = row?.createTime ? dayjs(row.createTime).format("YYYY-MM-DD HH:mm") : "";
|
||||||
return surveys.value.filter(item => item.ownerId === activeTab.value);
|
return {
|
||||||
|
_id: row?._id,
|
||||||
|
surveryId: row?.surveryId,
|
||||||
|
title: row?.name || "问卷调查",
|
||||||
|
person: row?.customer?.name || "",
|
||||||
|
team: row?.team?.name || "-",
|
||||||
|
time: sendTime,
|
||||||
|
status: row?.status || "",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadSurveyList = async (reset = false) => {
|
||||||
|
if (loading.value) return;
|
||||||
|
const miniAppId = openid.value || uni.getStorageSync("openid");
|
||||||
|
if (!miniAppId) {
|
||||||
|
uni.showToast({ title: "未获取到用户信息,请重新登录", icon: "none" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reset) {
|
||||||
|
page.value = 1;
|
||||||
|
surveys.value = [];
|
||||||
|
total.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
corpId,
|
||||||
|
miniAppId,
|
||||||
|
page: page.value,
|
||||||
|
pageSize,
|
||||||
|
};
|
||||||
|
if (activeTab.value) params.memberId = activeTab.value;
|
||||||
|
|
||||||
|
const res = await api("getMiniAppReceivedSurveryList", params);
|
||||||
|
if (res && res.success) {
|
||||||
|
const list = Array.isArray(res.list) ? res.list : [];
|
||||||
|
total.value = Number(res.total) || 0;
|
||||||
|
const mapped = list.map(mapRowToView);
|
||||||
|
if (page.value === 1) surveys.value = mapped;
|
||||||
|
else surveys.value = [...surveys.value, ...mapped];
|
||||||
|
} else {
|
||||||
|
uni.showToast({ title: res?.message || "获取问卷失败", icon: "none" });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("loadSurveyList failed:", err);
|
||||||
|
uni.showToast({ title: "加载失败,请重试", icon: "none" });
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function goToDetail() {
|
||||||
|
uni.showToast({ title: "详情暂未接入", icon: "none" });
|
||||||
|
}
|
||||||
|
|
||||||
|
onShow(async () => {
|
||||||
|
if (!inited.value) {
|
||||||
|
await loadCustomers();
|
||||||
|
await loadSurveyList(true);
|
||||||
|
inited.value = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await loadSurveyList(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
function goToDetail(item) {
|
onReachBottom(() => {
|
||||||
console.log('Navigate to detail', item);
|
if (loading.value) return;
|
||||||
// Add actual navigation logic here later
|
if (surveys.value.length >= total.value) return;
|
||||||
}
|
page.value += 1;
|
||||||
|
loadSurveyList(false);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -207,4 +289,35 @@ function goToDetail(item) {
|
|||||||
line-clamp: 2;
|
line-clamp: 2;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.field-label {
|
||||||
|
flex-shrink: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-container,
|
||||||
|
.empty-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 100rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-more,
|
||||||
|
.no-more {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
gap: 10rpx;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -2,7 +2,7 @@
|
|||||||
<view v-if="member" class="flex flex-col h-full items-center justify-center">
|
<view v-if="member" class="flex flex-col h-full items-center justify-center">
|
||||||
<view class="business-card">
|
<view class="business-card">
|
||||||
<view class="flex">
|
<view class="flex">
|
||||||
<image class="mr-10 avatar" :src="member.avatar || '/static/default-avatar.png'"></image>
|
<image class="mr-10 avatar" :src="member.avatar || '/static/default-avatar.svg'"></image>
|
||||||
<view class="w-0 flex-grow leading-normal">
|
<view class="w-0 flex-grow leading-normal">
|
||||||
<view class="flex items-center">
|
<view class="flex items-center">
|
||||||
<view class="mr-5 text-lg font-semibold text-dark">{{ member.anotherName }}</view>
|
<view class="mr-5 text-lg font-semibold text-dark">{{ member.anotherName }}</view>
|
||||||
@ -14,13 +14,18 @@
|
|||||||
<view class="mt-12 border-primary qrcode p-15 mx-auto rounded" @click="previewImage()">
|
<view class="mt-12 border-primary qrcode p-15 mx-auto rounded" @click="previewImage()">
|
||||||
<image v-if="qrcode" class="h-full w-full" :src="qrcode"></image>
|
<image v-if="qrcode" class="h-full w-full" :src="qrcode"></image>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="mt-12 text-base text-center text-dark">
|
||||||
|
点击识别下方二维码,加我为好友
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
import useJob from '@/hooks/useJob';
|
import useJob from '@/hooks/useJob';
|
||||||
|
import useAccount from '@/store/account';
|
||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
import { toast } from '@/utils/widget';
|
import { toast } from '@/utils/widget';
|
||||||
|
|
||||||
@ -29,6 +34,7 @@ const userid = ref('');
|
|||||||
const qrcode = ref('')
|
const qrcode = ref('')
|
||||||
const member = ref(null);
|
const member = ref(null);
|
||||||
const { memberJob, memberList } = useJob();
|
const { memberJob, memberList } = useJob();
|
||||||
|
const { account } = storeToRefs(useAccount());
|
||||||
|
|
||||||
function previewImage() {
|
function previewImage() {
|
||||||
if (!qrcode.value) return;
|
if (!qrcode.value) return;
|
||||||
@ -50,7 +56,7 @@ async function getMember() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getQrcode() {
|
async function getQrcode() {
|
||||||
const res = await api('addContactWay', { corpUserId: userid.value, corpId: corpId.value });
|
const res = await api('addContactWay', { corpUserId: userid.value, corpId: corpId.value, unionid: account.value?.openid });
|
||||||
if (res && res.data) {
|
if (res && res.data) {
|
||||||
qrcode.value = res.data;
|
qrcode.value = res.data;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view v-if="qrcode" class="p-15 mt-12 leading-normal bg-white shadow-lg">
|
<view v-if="qrcode" class="p-15 mt-12 leading-normal bg-white shadow-lg">
|
||||||
<view class="text-lg font-semibold text-center text-dark">
|
<view class="text-lg font-semibold text-center text-dark">
|
||||||
点击下方二维码,加我为好友
|
点击识别下方二维码,加我为好友
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-12 border-primary qrcode p-15 mx-auto rounded" @click="previewImage()">
|
<view class="mt-12 border-primary qrcode p-15 mx-auto rounded" @click="previewImage()">
|
||||||
<image :src="qrcode" class="h-full w-full"></image>
|
<image :src="qrcode" class="h-full w-full"></image>
|
||||||
@ -63,6 +63,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import useAccount from "@/store/account";
|
||||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
import useJob from '@/hooks/useJob';
|
import useJob from '@/hooks/useJob';
|
||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
@ -75,6 +77,7 @@ const qrcode = ref('')
|
|||||||
const member = ref(null);
|
const member = ref(null);
|
||||||
const expand = ref(false);
|
const expand = ref(false);
|
||||||
const { memberJob, memberList } = useJob();
|
const { memberJob, memberList } = useJob();
|
||||||
|
const { account } = storeToRefs(useAccount());
|
||||||
|
|
||||||
const corpNames = computed(() => {
|
const corpNames = computed(() => {
|
||||||
const corpNames = member.value && Array.isArray(member.value.corpNames) ? member.value.corpNames : [];
|
const corpNames = member.value && Array.isArray(member.value.corpNames) ? member.value.corpNames : [];
|
||||||
@ -128,7 +131,7 @@ async function getMember() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getQrcode() {
|
async function getQrcode() {
|
||||||
const res = await api('addContactWay', { corpUserId: userid.value, corpId: corpId.value });
|
const res = await api('addContactWay', { corpUserId: userid.value, corpId: corpId.value, unionid: account.value?.openid });
|
||||||
if (res && res.data) {
|
if (res && res.data) {
|
||||||
qrcode.value = res.data;
|
qrcode.value = res.data;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="team.teamTroduce" class="mt-12 text-base text-dark leading-normal break-all">
|
<view v-if="team.teamTroduce" class="mt-12 text-base text-dark leading-normal break-all pre-wrap">
|
||||||
{{ team.teamTroduce }}
|
{{ team.teamTroduce }}
|
||||||
</view>
|
</view>
|
||||||
<template v-if="teammate.leaders.length">
|
<template v-if="teammate.leaders.length">
|
||||||
@ -20,7 +20,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view v-for="i in teammate.leaders" :key="i._id" class="mt-12 flex p-10 border-primary rounded-sm"
|
<view v-for="i in teammate.leaders" :key="i._id" class="mt-12 flex p-10 border-primary rounded-sm"
|
||||||
@click="toHomePage(i.userid)">
|
@click="toHomePage(i.userid)">
|
||||||
<image class="flex-shrink-0 mr-10 avatar" :src="i.avatar || '/static/default-avatar.png'"></image>
|
<image class="flex-shrink-0 mr-10 avatar" :src="i.avatar || '/static/default-avatar.svg'"></image>
|
||||||
<view class="w-0 flex-grow leading-normal">
|
<view class="w-0 flex-grow leading-normal">
|
||||||
<view class="flex items-center justify-between">
|
<view class="flex items-center justify-between">
|
||||||
<view class="flex-shrink-0 mr-5 view-lg text-dark font-semibold">{{ i.anotherName }}</view>
|
<view class="flex-shrink-0 mr-5 view-lg text-dark font-semibold">{{ i.anotherName }}</view>
|
||||||
@ -45,7 +45,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view v-for="i in teammate.members" :key="i._id" class="mt-12 flex p-10 border-primary rounded-sm"
|
<view v-for="i in teammate.members" :key="i._id" class="mt-12 flex p-10 border-primary rounded-sm"
|
||||||
@click="toHomePage(i.userid)">
|
@click="toHomePage(i.userid)">
|
||||||
<image class="flex-shrink-0 mr-10 avatar" :src="i.avatar || '/static/default-avatar.png'"></image>
|
<image class="flex-shrink-0 mr-10 avatar" :src="i.avatar || '/static/default-avatar.svg'"></image>
|
||||||
<view class="w-0 flex-grow leading-normal">
|
<view class="w-0 flex-grow leading-normal">
|
||||||
<view class="flex items-center justify-between">
|
<view class="flex items-center justify-between">
|
||||||
<view class="flex-shrink-0 mr-5 view-lg text-dark font-semibold">{{ i.anotherName }}</view>
|
<view class="flex-shrink-0 mr-5 view-lg text-dark font-semibold">{{ i.anotherName }}</view>
|
||||||
@ -83,7 +83,7 @@ const { memberJob, memberList: list } = useJob();
|
|||||||
|
|
||||||
const memberList = computed(() => team.value && Array.isArray(team.value.memberList) ? team.value.memberList : [])
|
const memberList = computed(() => team.value && Array.isArray(team.value.memberList) ? team.value.memberList : [])
|
||||||
|
|
||||||
const avatarList = computed(() => memberList.value.map(i => i.avatar || '/static/default-avatar.png').filter(Boolean))
|
const avatarList = computed(() => memberList.value.map(i => i.avatar || '/static/default-avatar.svg').filter(Boolean))
|
||||||
|
|
||||||
const teammate = computed(() => {
|
const teammate = computed(() => {
|
||||||
const memberLeaderList = team.value && Array.isArray(team.value.memberLeaderList) ? team.value.memberLeaderList : [];
|
const memberLeaderList = team.value && Array.isArray(team.value.memberLeaderList) ? team.value.memberLeaderList : [];
|
||||||
@ -152,4 +152,8 @@ page {
|
|||||||
width: 120rpx;
|
width: 120rpx;
|
||||||
height: 128rpx;
|
height: 128rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pre-wrap {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -6,7 +6,7 @@ export default [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'pages/login/login',
|
path: 'pages/login/login',
|
||||||
meta: { title: '柚健康' },
|
meta: { title: '柚健康', navigationStyle: 'custom' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'pages/login/redirect-page',
|
path: 'pages/login/redirect-page',
|
||||||
@ -20,6 +20,10 @@ export default [
|
|||||||
path: 'pages/archive/edit-archive',
|
path: 'pages/archive/edit-archive',
|
||||||
meta: { title: '新增档案', login: true }
|
meta: { title: '新增档案', login: true }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'pages/archive/archive-result',
|
||||||
|
meta: { title: '团队服务' }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'pages/article/article-list',
|
path: 'pages/article/article-list',
|
||||||
meta: { title: '健康宣教', login: true }
|
meta: { title: '健康宣教', login: true }
|
||||||
|
|||||||
BIN
static/background.png
Normal file
BIN
static/background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@ -1,11 +1,10 @@
|
|||||||
import { ref } from "vue";
|
import { ref, watch } from "vue";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
import { toast } from '@/utils/widget';
|
import { toast } from '@/utils/widget';
|
||||||
import { initGlobalTIM, globalTimChatManager } from "@/utils/tim-chat.js";
|
import { initGlobalTIM, globalTimChatManager } from "@/utils/tim-chat.js";
|
||||||
const env = __VITE_ENV__;
|
const env = __VITE_ENV__;
|
||||||
|
|
||||||
|
|
||||||
export default defineStore("accountStore", () => {
|
export default defineStore("accountStore", () => {
|
||||||
const appid = env.MP_WX_APP_ID;
|
const appid = env.MP_WX_APP_ID;
|
||||||
const corpId = env.MP_CORP_ID;
|
const corpId = env.MP_CORP_ID;
|
||||||
@ -13,11 +12,11 @@ export default defineStore("accountStore", () => {
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const isIMInitialized = ref(false);
|
const isIMInitialized = ref(false);
|
||||||
const openid = ref("");
|
const openid = ref("");
|
||||||
async function login(phoneCode = '') {
|
const externalUserId = ref('');
|
||||||
|
|
||||||
|
async function login(phoneCode = '') {
|
||||||
if (loading.value) return;
|
if (loading.value) return;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { code } = await uni.login({
|
const { code } = await uni.login({
|
||||||
appid,
|
appid,
|
||||||
@ -26,10 +25,10 @@ export default defineStore("accountStore", () => {
|
|||||||
});
|
});
|
||||||
if (code) {
|
if (code) {
|
||||||
const res = await api('wxAppLogin', {
|
const res = await api('wxAppLogin', {
|
||||||
appId:appid,
|
appId: appid,
|
||||||
phoneCode,
|
phoneCode,
|
||||||
code,
|
code,
|
||||||
corpId
|
corpId
|
||||||
});
|
});
|
||||||
loading.value = false
|
loading.value = false
|
||||||
if (res.success && res.data && res.data.mobile) {
|
if (res.success && res.data && res.data.mobile) {
|
||||||
@ -108,5 +107,20 @@ export default defineStore("accountStore", () => {
|
|||||||
uni.removeStorageSync('openid');
|
uni.removeStorageSync('openid');
|
||||||
}
|
}
|
||||||
|
|
||||||
return { account, login, initIMAfterLogin, logout, openid, isIMInitialized }
|
async function getExternalUserId() {
|
||||||
|
const corpId = account.value?.corpId;
|
||||||
|
const unionid = account.value?.unionid;
|
||||||
|
const openid = account.value?.openid;
|
||||||
|
if (!(corpId && unionid && openid) || externalUserId.value) return;
|
||||||
|
const res = await api('getUnionidToExternalUserid', { unionid, openid, corpId }, false);
|
||||||
|
if (res && res.success && typeof res.data === 'string' && res.data.trim()) {
|
||||||
|
externalUserId.value = res.data.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(account, n => {
|
||||||
|
getExternalUserId()
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
return { account, login, initIMAfterLogin, logout, openid, isIMInitialized, externalUserId, getExternalUserId }
|
||||||
})
|
})
|
||||||
12
utils/api.js
12
utils/api.js
@ -10,6 +10,8 @@ const urlsConfig = {
|
|||||||
getTeamHealthTemplate: 'getTeamHealthTemplate',
|
getTeamHealthTemplate: 'getTeamHealthTemplate',
|
||||||
getTeamHealthTemps: "getTeamHealthTemps",
|
getTeamHealthTemps: "getTeamHealthTemps",
|
||||||
getCorpMemberJob: "getCorpMemberJob",
|
getCorpMemberJob: "getCorpMemberJob",
|
||||||
|
bindWxappWithTeam: 'bindWxappWithTeam',
|
||||||
|
getWxappRelateTeams: 'getWxappRelateTeams',
|
||||||
getTeamMemberAvatarsAndName: "getTeamMemberAvatarsAndName"
|
getTeamMemberAvatarsAndName: "getTeamMemberAvatarsAndName"
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -31,7 +33,9 @@ const urlsConfig = {
|
|||||||
getArticleCateList: 'getArticleCateList',
|
getArticleCateList: 'getArticleCateList',
|
||||||
getArticleList: 'getArticleList',
|
getArticleList: 'getArticleList',
|
||||||
getArticle: 'getArticle',
|
getArticle: 'getArticle',
|
||||||
addArticleSendRecord: 'addArticleSendRecord'
|
addArticleSendRecord: 'addArticleSendRecord',
|
||||||
|
addArticleReadRecord: 'addArticleReadRecord',
|
||||||
|
getMiniAppReceivedArticleList: 'getMiniAppReceivedArticleList'
|
||||||
},
|
},
|
||||||
member: {
|
member: {
|
||||||
addCustomer: 'add',
|
addCustomer: 'add',
|
||||||
@ -46,6 +50,9 @@ const urlsConfig = {
|
|||||||
getMedicalRecordById: 'getMedicalRecordById',
|
getMedicalRecordById: 'getMedicalRecordById',
|
||||||
unbindMiniAppArchive: 'unbindMiniAppArchive',
|
unbindMiniAppArchive: 'unbindMiniAppArchive',
|
||||||
updateMedicalRecord: 'updateMedicalRecord',
|
updateMedicalRecord: 'updateMedicalRecord',
|
||||||
|
getUnionidToExternalUserid: 'getUnionidToExternalUserid',
|
||||||
|
getWxAppCustomerCount: "getWxAppCustomerCount",
|
||||||
|
updateCustomer: 'update'
|
||||||
},
|
},
|
||||||
wecom: {
|
wecom: {
|
||||||
addContactWay: 'addContactWay'
|
addContactWay: 'addContactWay'
|
||||||
@ -60,6 +67,9 @@ const urlsConfig = {
|
|||||||
createConsultGroup: "createConsultGroup",
|
createConsultGroup: "createConsultGroup",
|
||||||
cancelConsultApplication: "cancelConsultApplication",
|
cancelConsultApplication: "cancelConsultApplication",
|
||||||
getGroupList: "getGroupList"
|
getGroupList: "getGroupList"
|
||||||
|
},
|
||||||
|
survery: {
|
||||||
|
getMiniAppReceivedSurveryList: 'getMiniAppReceivedSurveryList'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const urls = Object.keys(urlsConfig).reduce((acc, path) => {
|
const urls = Object.keys(urlsConfig).reduce((acc, path) => {
|
||||||
|
|||||||
@ -144,7 +144,7 @@ function mergeConversationData(conversation, groupDetailsMap) {
|
|||||||
name: formatConversationName(groupDetail),
|
name: formatConversationName(groupDetail),
|
||||||
|
|
||||||
// 更新头像(优先使用已有头像,避免闪动)
|
// 更新头像(优先使用已有头像,避免闪动)
|
||||||
avatar: conversation.avatar || groupDetail.patient?.avatar || '/static/default-avatar.png'
|
avatar: conversation.avatar || groupDetail.patient?.avatar || '/static/default-avatar.svg'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2625,7 +2625,7 @@ class TimChatManager {
|
|||||||
conversationID,
|
conversationID,
|
||||||
groupID,
|
groupID,
|
||||||
name: patientName ? `${patientName}的问诊` : groupName || '问诊群聊',
|
name: patientName ? `${patientName}的问诊` : groupName || '问诊群聊',
|
||||||
avatar: '/static/default-avatar.png',
|
avatar: '/static/default-avatar.svg',
|
||||||
lastMessage,
|
lastMessage,
|
||||||
lastMessageTime,
|
lastMessageTime,
|
||||||
unreadCount: conversation.unreadCount || 0,
|
unreadCount: conversation.unreadCount || 0,
|
||||||
@ -2638,7 +2638,7 @@ class TimChatManager {
|
|||||||
conversationID: conversation.conversationID,
|
conversationID: conversation.conversationID,
|
||||||
groupID: conversation.conversationID?.replace('GROUP', '') || '',
|
groupID: conversation.conversationID?.replace('GROUP', '') || '',
|
||||||
name: '问诊群聊',
|
name: '问诊群聊',
|
||||||
avatar: '/static/default-avatar.png',
|
avatar: '/static/default-avatar.svg',
|
||||||
lastMessage: '暂无消息',
|
lastMessage: '暂无消息',
|
||||||
lastMessageTime: Date.now(),
|
lastMessageTime: Date.now(),
|
||||||
unreadCount: 0,
|
unreadCount: 0,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user