Merge commit 'c56580d6c019eb82019b2fe4b9e821edea3d2d14' into dev-wdb

# Conflicts:
#	pages/message/message.vue
This commit is contained in:
wangdongbo 2026-02-10 17:36:30 +08:00
commit 03aac339d8
13 changed files with 84 additions and 90 deletions

View File

@ -9,12 +9,12 @@
</common-cell> </common-cell>
</template> </template>
<script setup> <script setup>
import { computed } from 'vue'; import { computed, onMounted } from 'vue';
import { set } from '@/utils/cache'; import { set } from '@/utils/cache';
import commonCell from '../common-cell.vue'; import commonCell from '../common-cell.vue';
const emits = defineEmits(['change']); const emits = defineEmits(['change', 'addRule']);
const props = defineProps({ const props = defineProps({
form: { form: {
type: Object, type: Object,
@ -52,6 +52,18 @@ function select() {
}) })
} }
onMounted(() => {
if (props.required && props.title) {
emits('addRule', {
title: props.title,
fn: () => {
if (value.value.length > 0) return true;
return `请选择${props.name || ''}`
}
})
}
})
</script> </script>
<style> <style>
@import '../cell-style.css'; @import '../cell-style.css';

View File

@ -12,10 +12,10 @@
@change="change" /> @change="change" />
<form-textarea v-else-if="attrs.type === 'textarea'" v-bind="attrs" :form="form" :disableChange="disableChange" <form-textarea v-else-if="attrs.type === 'textarea'" v-bind="attrs" :form="form" :disableChange="disableChange"
@change="change" /> @change="change" />
<form-mult-disease v-else-if="attrs.type === 'selfMultipleDiseases'" v-bind="attrs" :form="form" <form-mult-disease v-else-if="attrs.type === 'selfMultipleDiseases'" v-bind="attrs" :form="form" @change="change"
@change="change"></form-mult-disease> @addRule="addRule"></form-mult-disease>
<form-mult-disease v-else-if="attrs.type === 'diagnosis'" v-bind="attrs" :form="form" <form-mult-disease v-else-if="attrs.type === 'diagnosis'" v-bind="attrs" :form="form" @change="change"
@change="change"></form-mult-disease> @addRule="addRule"></form-mult-disease>
<form-upload v-else-if="attrs.type === 'files'" v-bind="attrs" :form="form" @change="change" /> <form-upload v-else-if="attrs.type === 'files'" v-bind="attrs" :form="form" @change="change" />
<form-mult-other v-else-if="attrs.type === 'multiSelectAndOther'" v-bind="attrs" :form="form" @change="change" /> <form-mult-other v-else-if="attrs.type === 'multiSelectAndOther'" v-bind="attrs" :form="form" @change="change" />
<!-- <!--
@ -52,11 +52,14 @@ defineProps({
}) })
const attrs = useAttrs(); const attrs = useAttrs();
const emits = defineEmits(['change']); const emits = defineEmits(['change', 'addRule']);
function change(data) { function change(data) {
emits('change', data) emits('change', data)
} }
function addRule(data) {
emits('addRule', data)
}
</script> </script>
<!-- <script> <!-- <script>

View File

@ -42,7 +42,6 @@ const disabledMap = computed(() => props.disableTitles.reduce((m, i) => {
return m return m
}, {})) }, {}))
provide('addRule', addRule);
const customRule = ref({}); const customRule = ref({});

View File

@ -152,7 +152,11 @@ async function bindArchive(customerId) {
const res = await api('bindMiniAppArchive', { id: customerId, corpId: corpId.value, teamId: teamId.value, miniAppId: account.value.openid }); const res = await api('bindMiniAppArchive', { id: customerId, corpId: corpId.value, teamId: teamId.value, miniAppId: account.value.openid });
if (res && res.success) { if (res && res.success) {
await toast('绑定成功'); await toast('绑定成功');
uni.reLaunch({ url: `/pages/home/home?corpId=${corpId.value}&teamId=${teamId.value}` }) set('home-invite-teamId', teamId.value);
uni.switchTab({
url:'/pages/home/home'
})
// uni.reLaunch({ url: `/pages/home/home?corpId=${corpId.value}&teamId=${teamId.value}` })
} else { } else {
toast(res?.message || '绑定失败'); toast(res?.message || '绑定失败');
} }
@ -195,7 +199,7 @@ async function getBaseForm() {
formItems.value = Array.isArray(res.data) ? res.data : []; formItems.value = Array.isArray(res.data) ? res.data : [];
const mobileIndex = formItems.value.findIndex(item => item.title === 'mobile'); const mobileIndex = formItems.value.findIndex(item => item.title === 'mobile');
if (mobileIndex > -1) { if (mobileIndex > -1) {
formItems.value[mobileIndex].appendText = `(授权手机号不可修改)`; formItems.value[mobileIndex].appendText = `(授权手机号)`;
} }
} else { } else {

View File

@ -137,7 +137,11 @@ function addArchive() {
function getTempRows(type, data) { function getTempRows(type, data) {
if (config[type] && tempShowField.value && tempShowField.value[type]) { if (config[type] && tempShowField.value && tempShowField.value[type]) {
const list = []; const list = [];
config[type].forEach(i => { let titles = config[type];
if (data.corp === '其他') {
titles = ['corpName', 'diagnosisName', 'files']
}
titles.forEach(i => {
if (tempShowField.value[type][i]) { if (tempShowField.value[type][i]) {
list.push({ title: i, label: tempShowField.value[type][i], value: data[i], key: `${i}_${data._id}` }) list.push({ title: i, label: tempShowField.value[type][i], value: data[i], key: `${i}_${data._id}` })
} }

View File

@ -22,7 +22,8 @@
<script setup> <script setup>
import { computed, ref } from "vue"; import { computed, ref } from "vue";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import useGuard from "@/hooks/useGuard"; import { onLoad, onShow } from "@dcloudio/uni-app";
// 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 } from "@/utils/widget";
@ -37,12 +38,13 @@ import teamMate from "./team-mate.vue";
import ycHome from "./yc-home.vue"; import ycHome from "./yc-home.vue";
import pageLoading from "./loading.vue"; import pageLoading from "./loading.vue";
const { useLoad, useShow } = useGuard(); // const { useLoad, useShow } = useGuard();
const { account } = storeToRefs(useAccount()); const { account } = storeToRefs(useAccount());
const { login } = useAccount();
const team = ref(null); const team = ref(null);
const teams = ref([]); const teams = ref([]);
const loading = ref(true); const loading = ref(false);
const customers = ref([]); const customers = ref([]);
const corpId = computed(() => team.value?.corpId); const corpId = computed(() => team.value?.corpId);
@ -83,14 +85,23 @@ async function getTeams() {
loading.value = false; loading.value = false;
} }
useLoad((opts) => { // useLoad((opts) => {
if (opts.teamId) { // if (opts.teamId) {
team.value = { teamId: opts.teamId, corpId: opts.corpId }; // team.value = { teamId: opts.teamId, corpId: opts.corpId };
} // }
}); // });
useShow(() => { onLoad(() => {
getTeams(); if (!account.value) login();
})
onShow(async () => {
if (!account.value) await login();
if (account.value && account.value.openid) {
getTeams();
} else {
teams.value = [];
}
}); });
</script> </script>
<style scoped> <style scoped>

View File

@ -7,7 +7,7 @@
<image class="logo" src="/static/logo-plain.png"></image> <image class="logo" src="/static/logo-plain.png"></image>
</view> </view>
<view class="w-0 flex-grow"> <view class="w-0 flex-grow">
<view class="text-lg font-semibold text-white">健康 </view> <view class="text-lg font-semibold text-white">健康</view>
<view class="leading-normal text-base text-white truncate">全周期健康管理伙伴</view> <view class="leading-normal text-base text-white truncate">全周期健康管理伙伴</view>
</view> </view>
<view v-if="menuButtonInfo && menuButtonInfo.width > 0" class="flex-shrink-0" <view v-if="menuButtonInfo && menuButtonInfo.width > 0" class="flex-shrink-0"

View File

@ -13,7 +13,7 @@
<view v-else class="doctor-card doctor-card-empty"> <view v-else class="doctor-card doctor-card-empty">
<view class="doctor-info"> <view class="doctor-info">
<image class="logo" src="/static/logo-plain.png" mode="aspectFill" /> <image class="logo" src="/static/logo-plain.png" mode="aspectFill" />
<view class="doctor-name">健康</view> <view class="doctor-name">健康</view>
<view class="login-tip">全周期健康管理伙伴</view> <view class="login-tip">全周期健康管理伙伴</view>
</view> </view>
</view> </view>

View File

@ -5,57 +5,31 @@
</text> </text>
<!-- 图片消息 --> <!-- 图片消息 -->
<image <image v-else-if="message.type === 'TIMImageElem'" class="message-image" :src="message.payload.imageInfoArray[0].LocalURL ||
v-else-if="message.type === 'TIMImageElem'" message.payload.imageInfoArray[0].url
class="message-image" " mode="aspectFill" :style="getImageStyle(message.payload.imageInfoArray[0])" @click="
:src="
message.payload.imageInfoArray[0].LocalURL ||
message.payload.imageInfoArray[0].url
"
mode="aspectFill"
:style="getImageStyle(message.payload.imageInfoArray[0])"
@click="
$emit( $emit(
'previewImage', 'previewImage',
message.payload.imageInfoArray[0].LocalURL || message.payload.imageInfoArray[0].LocalURL ||
message.payload.imageInfoArray[0].url message.payload.imageInfoArray[0].url
) )
" " />
/>
<!-- 语音消息 --> <!-- 语音消息 -->
<view <view v-else-if="message.type === 'TIMSoundElem'" class="voice-message" :class="{ 'voice-playing': isPlaying }"
v-else-if="message.type === 'TIMSoundElem'" :style="getVoiceStyle(message.payload.second)" @click="$emit('playVoice', message)">
class="voice-message"
:class="{ 'voice-playing': isPlaying }"
:style="getVoiceStyle(message.payload.second)"
@click="$emit('playVoice', message)"
>
<view class="voice-content"> <view class="voice-content">
<view class="voice-icon-wrapper"> <view class="voice-icon-wrapper">
<uni-icons <uni-icons type="sound" size="20" :color="message.flow === 'out' ? '#fff' : '#333'"
type="sound" :class="{ 'icon-animate': isPlaying }" />
size="20"
:color="message.flow === 'out' ? '#fff' : '#333'"
:class="{ 'icon-animate': isPlaying }"
/>
<!-- 播放中的声波动画 --> <!-- 播放中的声波动画 -->
<view v-if="isPlaying" class="sound-wave"> <view v-if="isPlaying" class="sound-wave">
<view <view class="wave-bar" :style="{ background: message.flow === 'out' ? '#fff' : '#0877f1' }"
class="wave-bar" style="animation-delay: 0s"></view>
:style="{ background: message.flow === 'out' ? '#fff' : '#0877f1' }" <view class="wave-bar" :style="{ background: message.flow === 'out' ? '#fff' : '#0877f1' }"
style="animation-delay: 0s" style="animation-delay: 0.2s"></view>
></view> <view class="wave-bar" :style="{ background: message.flow === 'out' ? '#fff' : '#0877f1' }"
<view style="animation-delay: 0.4s"></view>
class="wave-bar"
:style="{ background: message.flow === 'out' ? '#fff' : '#0877f1' }"
style="animation-delay: 0.2s"
></view>
<view
class="wave-bar"
:style="{ background: message.flow === 'out' ? '#fff' : '#0877f1' }"
style="animation-delay: 0.4s"
></view>
</view> </view>
</view> </view>
<text class="voice-duration">{{ message.payload.second }}"</text> <text class="voice-duration">{{ message.payload.second }}"</text>
@ -65,39 +39,24 @@
<!-- 自定义消息卡片 --> <!-- 自定义消息卡片 -->
<template v-else-if="message.type === 'TIMCustomElem'"> <template v-else-if="message.type === 'TIMCustomElem'">
<!-- 文章消息 --> <!-- 文章消息 -->
<view <view v-if="getCustomMessageType(message) === 'article'" class="article-card" @click="handleArticleClick(message)">
v-if="getCustomMessageType(message) === 'article'"
class="article-card"
@click="handleArticleClick(message)"
>
<view class="article-content"> <view class="article-content">
<view class="article-title">{{ getArticleData(message).title }}</view> <view class="article-title">{{ getArticleData(message).title }}</view>
<view class="article-desc">{{ getArticleData(message).desc }}</view> <view class="article-desc">{{ getArticleData(message).desc }}</view>
</view> </view>
<image <image v-if="getArticleData(message).imgUrl" class="article-image" :src="getArticleData(message).imgUrl"
v-if="getArticleData(message).imgUrl" mode="aspectFill" />
class="article-image"
:src="getArticleData(message).imgUrl"
mode="aspectFill"
/>
</view> </view>
<!-- 问卷消息 --> <!-- 问卷消息 -->
<view <view v-else-if="getCustomMessageType(message) === 'survey'" class="survey-card"
v-else-if="getCustomMessageType(message) === 'survey'" @click="handleSurveyClick(message)">
class="survey-card"
@click="handleSurveyClick(message)"
>
<view class="survey-content"> <view class="survey-content">
<view class="survey-title">{{ getSurveyData(message).title }}</view> <view class="survey-title">{{ getSurveyData(message).title }}</view>
<view class="survey-desc">{{ getSurveyData(message).desc }}</view> <view class="survey-desc">{{ getSurveyData(message).desc }}</view>
</view> </view>
<image <image v-if="getSurveyData(message).imgUrl" class="survey-image" :src="getSurveyData(message).imgUrl"
v-if="getSurveyData(message).imgUrl" mode="aspectFill" />
class="survey-image"
:src="getSurveyData(message).imgUrl"
mode="aspectFill"
/>
</view> </view>
<!-- 其他自定义消息 --> <!-- 其他自定义消息 -->
@ -122,6 +81,7 @@ import { getParsedCustomMessage } from "@/utils/chat-utils.js";
// import MessageCard from "./message-card/message-card.vue"; // import MessageCard from "./message-card/message-card.vue";
const props = defineProps({ const props = defineProps({
corpId: String,
message: Object, message: Object,
patientInfo: Object, patientInfo: Object,
formatTime: Function, formatTime: Function,
@ -237,7 +197,7 @@ const getArticleData = (message) => {
const handleArticleClick = (message) => { const handleArticleClick = (message) => {
const { articleId } = getArticleData(message); const { articleId } = getArticleData(message);
uni.navigateTo({ uni.navigateTo({
url: `/pages/article/article-detail?id=${articleId}`, url: `/pages/article/article-detail?id=${articleId}&corpId=${props.corpId}`,
}); });
}; };

View File

@ -103,6 +103,7 @@
<view class="message-bubble" :class="getBubbleClass(message)"> <view class="message-bubble" :class="getBubbleClass(message)">
<!-- 消息内容 --> <!-- 消息内容 -->
<MessageTypes <MessageTypes
:corpId="corpId"
:message="message" :message="message"
:formatTime="formatTime" :formatTime="formatTime"
:playingVoiceId="playingVoiceId" :playingVoiceId="playingVoiceId"

View File

@ -1,7 +1,6 @@
<template> <template>
<view class="message-page"> <view class="message-page">
<!-- 消息列表 --> <!-- 消息列表 -->
<scroll-view <scroll-view
class="message-list" class="message-list"

View File

@ -29,7 +29,7 @@ export default defineStore("accountStore", () => {
code code
}); });
loading.value = false loading.value = false
if (res.success && res.data && res.data.mobile) { if (res.success && res.data) {
account.value = res.data; account.value = res.data;
openid.value = res.data.openid; openid.value = res.data.openid;

View File

@ -35,7 +35,8 @@ const urlsConfig = {
getArticle: 'getArticle', getArticle: 'getArticle',
addArticleSendRecord: 'addArticleSendRecord', addArticleSendRecord: 'addArticleSendRecord',
addArticleReadRecord: 'addArticleReadRecord', addArticleReadRecord: 'addArticleReadRecord',
getMiniAppReceivedArticleList: 'getMiniAppReceivedArticleList' getMiniAppReceivedArticleList: 'getMiniAppReceivedArticleList',
getPageDisease:'getPageDisease'
}, },
member: { member: {
addCustomer: 'add', addCustomer: 'add',