doctorDetail.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038
  1. <template>
  2. <view class="content es-pt-34">
  3. <view class="info">
  4. <view :style="{ height: statusBarHeight + 44 + 'px' }"></view>
  5. <view style="position: fixed; top: 0; left: 0; right: 0; z-index: 9999; background-color: #fff">
  6. <view :style="{ height: statusBarHeight + 'px' }"></view>
  7. <view class="u-f-ajc u-f-jsb" style="height: 44px; padding: 0 24rpx">
  8. <view class="u-f-ajc">
  9. <view class="es-mr-14" @tap="goBack">
  10. <image class="es-icon-64" src="/static/image/agent/back_black_icon.png" mode=""></image>
  11. </view>
  12. <view class="es-mr-24 avatar es-br-ban u-f-ajc">
  13. <image class="es-icon-60 es-br-ban" :src="data.avatar || '/static/image/hall/my_heads_icon.png'" mode=""></image>
  14. </view>
  15. <view class="">
  16. <view class="u-f-ajc">
  17. <view class="es-fs-28 es-c-22 es-fw-600 es-mr-12 u-f-ajc">
  18. {{ data.doctorName || '' }}
  19. </view>
  20. <view class="u-f-ajc">
  21. <image class="es-icon-36" src="/static/image/agent/ai_icon.png" mode=""></image>
  22. </view>
  23. </view>
  24. <view class="es-c-99 es-fs-24">
  25. {{ data.deptName || '' }}
  26. </view>
  27. </view>
  28. </view>
  29. <view class="">
  30. <!-- <image class="es-icon-48 es-mr-32" src="/static/image/agent/dialogue_icom.png" mode=""> -->
  31. <!-- </image> -->
  32. <image @tap="doShare(data.doctorName || '')" class="es-icon-48" src="/static/image/agent/share_icom.png" mode=""></image>
  33. </view>
  34. </view>
  35. </view>
  36. <view class="es-fw es-c-22 es-fs-48 es-mt-44">{{ data.doctorName || '' }}</view>
  37. <view class="es-mt-8 es-c-75 es-fs-24" v-if="data.deptName">{{ data.deptName || '' }} · 主任{{ data.doctorType && data.doctorType == 2 ? '药师' : '医师' }}</view>
  38. <!-- 医生智能体 -->
  39. <view class="es-mt-26 agentBox">
  40. <view class="agentBox-avatar">
  41. <image class="es-icon-60" :src="data.sex == 2 ? '/static/image/agent/ai_doctor.png' : '/static/image/agent/ai_doctor2.png'" mode="top"></image>
  42. </view>
  43. <view class="es-fw es-c-33 es-fs-40">医生智能体</view>
  44. <view class="es-mt-40 es-c-22 es-fs-28 textTwo">
  45. {{ data.reminderWords || '' }}
  46. </view>
  47. <view class="es-mt-40 u-f-ajc u-f-jsb">
  48. <view class="u-f">
  49. <view class="u-f-ajc" @tap="copyContent(data.reminderWords)">
  50. <image class="es-icon-32 es-mr-28" src="/static/image/agent/copy_icon.png" mode=""></image>
  51. </view>
  52. <!-- <view class="u-f-ajc es-mr-28">
  53. <u-icon name="thumb-up" color="#222222" size="38rpx"></u-icon>
  54. </view>
  55. <view class="u-f-ajc es-mr-28">
  56. <u-icon name="thumb-down" color="#222222" size="38rpx"></u-icon>
  57. </view> -->
  58. <view
  59. class="u-f-ajc"
  60. @tap="
  61. doShare(
  62. `您好!我是${data.deptName || ''}${data.doctorName || ''}医生智能体,我的知识和经验都来自多年的临床实践。擅长${
  63. data.speciality || ''
  64. }。今天有什么可以帮您的吗?`
  65. )
  66. "
  67. >
  68. <image class="es-icon-32" src="/static/image/agent/share_icom.png" mode=""></image>
  69. </view>
  70. </view>
  71. <view class="es-c-99 es-fs-24">AI生成仅供参考</view>
  72. </view>
  73. </view>
  74. </view>
  75. <!-- 消息 -->
  76. <view class="msgBox">
  77. <template v-for="(item, index) in msgs">
  78. <!-- <view class="msgBox-item" v-if="item.type == 1">
  79. <view class="es-mt-40 es-fs-28 es-c-22 leftMsg es-bc-white">
  80. {{item.content}}
  81. </view>
  82. </view> -->
  83. <view class="answer es-mt-40 es-bg-white" v-if="item.type == 1">
  84. <view class="es-c-22 es-fs-32">
  85. {{ item.content }}
  86. </view>
  87. <view class="es-fs-24 es-mt-30 es-c-99">内容由AI生成,非诊疗意见,不适请及时就医</view>
  88. <view class="line"></view>
  89. <view class="es-mt-40 u-f-ajc u-f-jsb">
  90. <view class="u-f">
  91. <view class="u-f-ajc" @tap="copyContent(item.content)">
  92. <image class="es-icon-32 es-mr-28" src="/static/image/agent/copy_icon.png" mode=""></image>
  93. </view>
  94. <!-- <view class="u-f-ajc es-mr-28">
  95. <u-icon name="thumb-up" color="#222222" size="38rpx"></u-icon>
  96. </view>
  97. <view class="u-f-ajc es-mr-28">
  98. <u-icon name="thumb-down" color="#222222" size="38rpx"></u-icon>
  99. </view> -->
  100. </view>
  101. <view class="es-c-99 es-fs-24"></view>
  102. </view>
  103. </view>
  104. <view class="msgBox-item jcEnd" v-if="item.type == 2">
  105. <view class="es-fs-32 es-c-white rightMsg es-mt-40">
  106. {{ item.content }}
  107. </view>
  108. </view>
  109. </template>
  110. <!-- <view class="msgBox-item jcEnd" v-if="rewardDoctor==1">
  111. <view class="es-fs-32 es-c-white rightMsg es-mt-40">
  112. 打赏医生
  113. </view>
  114. </view> -->
  115. </view>
  116. <view class="footerBox">
  117. <view class="u-f">
  118. <view class="u-f-ajc footerBox-tips es-mr-16" v-for="(item, index) in problemArr" :key="index" @tap="sendFixedTextFun(item)">
  119. <view class="u-f-ajc es-mr-12">
  120. <image class="es-icon-32" :src="item.imageUrl" mode=""></image>
  121. </view>
  122. <view class="es-c-22 es-fs-26">
  123. {{ item.title }}
  124. </view>
  125. </view>
  126. </view>
  127. <view class="es-mt-24 footerBox-btn u-f-ajc u-f-jsb">
  128. <view class="es-mr-16 u-f-ajc u-f-jsb footerBox-btnBox">
  129. <!-- <view class="footerBox-btnBox-recording u-f-ajc">
  130. <image class="es-icon-48" src="/static/image/agent/voice_icon.png" mode=""></image>
  131. </view> -->
  132. <view class="es-h-100 es-wp-100">
  133. <input class="es-fs-32 sendInput" type="text" placeholder="健康问题尽管问我" v-model="inputText" @confirm="handleInput" placeholder-style="color:#999999" />
  134. </view>
  135. <!-- <view class="es-mr-26" @click="handleInput()">
  136. <image class="es-icon-48" src="/static/image/agent/expand_function_icon.png" mode=""></image>
  137. </view> -->
  138. </view>
  139. <view class="" :style="{ whiteSpace: 'nowrap' }" @click="handleInput()">发送</view>
  140. <!-- <view class="u-f-ajc" @tap="navTo('/pages/agent/doctorCommunication')">
  141. <image class="es-icon-100" src="/static/image/agent/phone_icon50.png" mode=""></image>
  142. </view> -->
  143. </view>
  144. <!-- <view class="chat_action_bar">
  145. <u-row class="action_row">
  146. <u-col v-for="item in actionList" :key="item.idx" @click="actionClick(item)" span="3">
  147. <view class="action_item">
  148. <image :src="item.icon" alt="" srcset="" />
  149. <text class="action_item_title">{{ item.title }}</text>
  150. </view>
  151. </u-col>
  152. </u-row>
  153. </view> -->
  154. </view>
  155. <u-popup :show="rewardShow" mode="center" round="32rpx" @close="rewardShow = false" :customStyle="{ margin: '0 24rpx' }">
  156. <rewardDoctor ref="rewardDoctorRef" :rewardDoctor="rewardDoctor" :doctorId="doctorId" @close="rewardShow = false" />
  157. </u-popup>
  158. <!-- 分享弹窗 -->
  159. <u-popup :show="showShare" @close="showShare = false">
  160. <share-box :shareItem="shareItem" @closeShare="showShare = false"></share-box>
  161. </u-popup>
  162. <u-popup :show="showPatient" mode="center" round="32rpx" @close="showPatient = false">
  163. <view class="chose-patient">
  164. <view class="title-box" @click="navTo('/pages/user/patient')" v-if="patient == null">
  165. <view class="title">选择就诊人</view>
  166. <view class="right">
  167. <text class="value">请点击添加</text>
  168. <image src="/static/images/arrow_gray.png" mode=""></image>
  169. </view>
  170. </view>
  171. <view class="patient" @click="navTo('/pages/user/patient')" v-if="patient != null">
  172. <view class="left">
  173. <view class="name">{{ patient.patientName }}</view>
  174. <view class="info">
  175. <text class="text" v-if="patient.sex == 1">男</text>
  176. <text class="text" v-if="patient.sex == 2">女</text>
  177. <text class="text">{{ $getAge(patient.birthday) }}岁</text>
  178. <text class="text">{{ $parseIdCard(patient.idCard) }}</text>
  179. </view>
  180. </view>
  181. <view class="right">
  182. <image src="/static/images/arrow_gray.png" mode=""></image>
  183. </view>
  184. </view>
  185. </view>
  186. </u-popup>
  187. <!-- <chating-footer ref="chatingFooterRef" :footerOutsideFlag="footerOutsideFlag"
  188. @scrollToBottom="scrollToBottom" /> -->
  189. </view>
  190. </template>
  191. <script>
  192. import { aiChatListByUser } from '@/api/index.js';
  193. import rewardDoctor from '@/pages/agent/components/rewardDoctor.vue';
  194. import { getUserInfo } from '@/api/user';
  195. import { ChatingFooterActionTypes, ContactChooseTypes, PageEvents } from '@/pages_im/constant/index.js';
  196. import { premissionCheck } from '@/js_sdk/wa-permission/permission.js';
  197. import ChatingFooter from '@/pages_im/pages/conversation/chating/components/ChatingFooter/index.vue';
  198. import { getAiDoctorForDetails, getDictByKey, rewardAiDoctor } from '@/api/agent.js';
  199. export default {
  200. components: {
  201. ChatingFooter,
  202. rewardDoctor
  203. },
  204. data() {
  205. return {
  206. data: {},
  207. problemArr: [
  208. {
  209. imageUrl: '/static/image/agent/health_counseling_icon.png',
  210. title: '健康咨询',
  211. url: '/pages/doctor/doctorDetails'
  212. },
  213. {
  214. imageUrl: '/static/image/agent/course_study_icon.png',
  215. title: '课程学习',
  216. url: '/pages/course/index?activeTab=1'
  217. },
  218. {
  219. imageUrl: '/static/image/agent/fanghua_coin_icon.png',
  220. title: '打赏医生'
  221. }
  222. ],
  223. readFilePermission: false,
  224. actionList: [
  225. {
  226. idx: 0,
  227. type: ChatingFooterActionTypes.takePhoto,
  228. title: '拍照',
  229. icon: require('@/pages_im/static/images/chating_action_camera.png')
  230. },
  231. {
  232. idx: 1,
  233. type: ChatingFooterActionTypes.Album,
  234. title: '相册',
  235. icon: require('@/pages_im/static/images/chating_action_image.png')
  236. },
  237. {
  238. idx: 2,
  239. type: ChatingFooterActionTypes.Camera,
  240. title: '视频',
  241. icon: require('@/pages_im/static/images/take-photo.svg')
  242. },
  243. {
  244. idx: 3,
  245. type: ChatingFooterActionTypes.pickCamera,
  246. title: '录像',
  247. icon: require('@/pages_im/static/images/take-video.svg')
  248. }
  249. ],
  250. rewardDoctor: 0,
  251. showShare: false,
  252. shareItem: {
  253. imageUrl: '',
  254. title: '',
  255. path: '',
  256. isMini: true
  257. },
  258. content: '',
  259. msgEnd: false, //发送信息
  260. isSocketOpen: false,
  261. msgs: [],
  262. inputText: '',
  263. isSend: true,
  264. showPatient: false,
  265. patient: null,
  266. userInfo: null,
  267. statusBarHeight: '',
  268. doctorId: null,
  269. rewardShow: false
  270. };
  271. },
  272. onLoad(options) {
  273. const systemInfo = uni.getSystemInfoSync();
  274. this.statusBarHeight = systemInfo.statusBarHeight;
  275. if (options.doctorId != null) {
  276. this.doctorId = options.doctorId;
  277. this.problemArr[0].url = `/pages/doctor/doctorDetails?doctorId=${this.doctorId}&isAidoctor=1`;
  278. this.getDetailFun(this.doctorId);
  279. }
  280. let info = uni.getStorageSync('userInfo');
  281. this.userInfo = info && JSON.parse(info);
  282. this.getMsgList();
  283. this.initSocket();
  284. if (!this.patient) this.showPatient = true;
  285. uni.$on('refreshOrderPatient', (res) => {
  286. if (this.patient && this.patient.patientId == res.patientId) {
  287. return;
  288. }
  289. this.showPatient = false;
  290. this.msgEnd = false;
  291. this.patient = res;
  292. this.getMsgList();
  293. });
  294. },
  295. onShow() {},
  296. methods: {
  297. handleInput() {
  298. if (this.patient && this.patient.patientId) {
  299. if (this.msgEnd || !this.isSocketOpen) {
  300. // 重新发起会话
  301. this.initSocket();
  302. } else {
  303. this.sendMsg();
  304. }
  305. } else {
  306. uni.showToast({
  307. title: '请选择就诊人',
  308. icon: 'none'
  309. });
  310. if (!this.patient) this.showPatient = true;
  311. }
  312. },
  313. initSocket() {
  314. //创建一个socket连接
  315. var userId = this.userInfo.userId;
  316. var that = this;
  317. if (this.socket) {
  318. this.socket.close();
  319. this.socket = null;
  320. }
  321. this.socket = uni.connectSocket({
  322. url: getApp().globalData.wsUrl + '/app/webSocket/' + userId,
  323. multiple: true,
  324. success: (res) => {
  325. console.log('WebSocket连接已打开1!');
  326. that.isSocketOpen = true;
  327. },
  328. error: (res) => {
  329. console.log(res);
  330. }
  331. });
  332. this.socket.onMessage((res) => {
  333. console.log('收到消息', res);
  334. that.isSend = true;
  335. that.addMsg(1, res.data, null, 2);
  336. });
  337. //监听socket打开
  338. this.socket.onOpen(() => {
  339. console.log('WebSocket连接已打开2!', that.msgEnd);
  340. that.isSocketOpen = true;
  341. if (that.msgEnd) {
  342. // 重新发起会话
  343. that.isSend = true;
  344. that.sendMsg();
  345. }
  346. });
  347. //监听socket关闭
  348. this.socket.onClose(() => {
  349. that.isSocketOpen = false;
  350. that.socket = null;
  351. console.log('WebSocket连接已关闭!');
  352. that.msgEnd = true;
  353. that.scrollToBottom();
  354. if (that.msgTimes) {
  355. clearInterval(that.msgTimes);
  356. that.msgTimes = null;
  357. }
  358. });
  359. //监听socket错误
  360. this.socket.onError(() => {
  361. that.isSocketOpen = false;
  362. that.socket = null;
  363. that.msgEnd = true;
  364. console.log('WebSocket连接打开失败');
  365. if (that.msgTimes) {
  366. clearInterval(that.msgTimes);
  367. that.msgTimes = null;
  368. }
  369. });
  370. },
  371. sendMsg() {
  372. if (this.inputText == '') {
  373. return;
  374. }
  375. if (!this.isSend) {
  376. return;
  377. }
  378. if (this.isSocketOpen) {
  379. var userId = this.userInfo.userId;
  380. var data = {
  381. userId: this.userInfo.userId,
  382. doctorId: this.doctorId,
  383. message: this.inputText,
  384. sessionId: this.sessionId,
  385. patientId: this.patient.patientId
  386. };
  387. this.socket.send({
  388. data: JSON.stringify(data),
  389. success: () => {
  390. console.log('发送成功');
  391. this.addMsg(2, this.inputText, null, 1);
  392. this.addMsg(1, '正在思考中...', null, 1);
  393. this.isSend = false;
  394. },
  395. fail: () => {
  396. console.log('发送失败');
  397. }
  398. });
  399. }
  400. },
  401. addMsg(type, content, msg, inputType) {
  402. this.msgEnd = false;
  403. var obj = {
  404. type: type,
  405. content: content,
  406. msg: msg
  407. };
  408. if (inputType == 2) {
  409. this.msgs.splice(-1);
  410. this.msgs.push(obj);
  411. } else if (inputType == 1) {
  412. this.msgs.push(obj);
  413. }
  414. this.inputText = '';
  415. var that = this;
  416. this.scrollToBottom();
  417. //先确保清除了之前的消息定时器
  418. if (that.msgTimes) {
  419. clearInterval(that.msgTimes);
  420. that.msgTimes = null;
  421. }
  422. // 5分钟无消息自动结束
  423. that.msgTimes = setInterval(() => {
  424. console.log('5分钟无消息自动结束');
  425. clearInterval(that.msgTimes);
  426. if (this.socket != null) {
  427. this.socket.close();
  428. }
  429. that.msgTimes = null;
  430. }, 300000);
  431. },
  432. scrollToBottom() {
  433. this.$nextTick(() => {
  434. uni.createSelectorQuery()
  435. .in(this)
  436. .select('.content')
  437. .boundingClientRect((res) => {
  438. if (res) {
  439. uni.pageScrollTo({
  440. scrollTop: res.height,
  441. duration: 100
  442. });
  443. }
  444. })
  445. .exec();
  446. });
  447. },
  448. getMsgList() {
  449. if (this.patient && this.patient.patientId) {
  450. const that = this;
  451. const userId = this.userInfo.userId;
  452. const param = {
  453. doctorId: this.doctorId,
  454. userId: this.userInfo.userId,
  455. patientId: this.patient.patientId
  456. };
  457. aiChatListByUser(param)
  458. .then((res) => {
  459. // setTimeout(() => {
  460. // this.getHeight()
  461. // }, 200)
  462. let list = [];
  463. if (res.data && res.data.length > 0) {
  464. list = list.concat(res.data);
  465. that.sessionId = res.data && res.data.length > 0 ? res.data[0].sessionId : undefined;
  466. }
  467. list.forEach(function (value, index, array) {
  468. that.addMsg(value.msgType == 1 ? 2 : 1, value.content, value, 1);
  469. });
  470. })
  471. .catch(() => {});
  472. }
  473. },
  474. async requestPressmition() {
  475. let result = await premissionCheck('EXTERNAL_STORAGE');
  476. console.log('premission result:' + result);
  477. if (result == 1) {
  478. this.readFilePermission = true;
  479. }
  480. },
  481. async actionClick(action) {
  482. switch (action.type) {
  483. case ChatingFooterActionTypes.takePhoto:
  484. if (uni.$u.os() != 'ios') {
  485. this.requestPressmition();
  486. if (!this.readFilePermission) {
  487. return;
  488. }
  489. }
  490. this.$emit('prepareMediaMessage', {
  491. type: ChatingFooterActionTypes.Camera,
  492. index: 0
  493. });
  494. break;
  495. case ChatingFooterActionTypes.Album:
  496. if (uni.$u.os() != 'ios') {
  497. this.requestPressmition();
  498. if (!this.readFilePermission) {
  499. return;
  500. }
  501. }
  502. this.$emit('prepareMediaMessage', {
  503. type: ChatingFooterActionTypes.Album,
  504. index: 0
  505. });
  506. break;
  507. case ChatingFooterActionTypes.Camera:
  508. if (uni.$u.os() != 'ios') {
  509. this.requestPressmition();
  510. if (!this.readFilePermission) {
  511. return;
  512. }
  513. }
  514. this.$emit('prepareMediaMessage', {
  515. type: ChatingFooterActionTypes.Album,
  516. index: 1
  517. });
  518. break;
  519. case ChatingFooterActionTypes.pickCamera:
  520. if (uni.$u.os() != 'ios') {
  521. this.requestPressmition();
  522. if (!this.readFilePermission) {
  523. return;
  524. }
  525. }
  526. this.$emit('prepareMediaMessage', {
  527. type: ChatingFooterActionTypes.Camera,
  528. index: 1
  529. });
  530. break;
  531. case ChatingFooterActionTypes.Call:
  532. if (!this.$store.getters.storeCurrentConversation.groupID) {
  533. uni.$emit(PageEvents.RtcCall, 'audio');
  534. return;
  535. }
  536. IMSDK.asyncApi('signalingGetRoomByGroupID', IMSDK.uuid(), this.$store.getters.storeCurrentConversation.groupID).then(({ data }) => {
  537. if (data.invitation) {
  538. uni.showModal({
  539. title: '提示',
  540. content: '群通话进行中,是否直接加入?',
  541. confirmText: '确认',
  542. cancelText: '取消',
  543. success: (res) => {
  544. if (res.confirm) {
  545. callingModule.joinRoomLiveChat(data);
  546. }
  547. }
  548. });
  549. } else {
  550. uni.$emit(PageEvents.RtcCall, 'audio');
  551. }
  552. });
  553. break;
  554. case ChatingFooterActionTypes.VideoCall:
  555. if (!this.$store.getters.storeCurrentConversation.groupID) {
  556. uni.$emit(PageEvents.RtcCall, 'video');
  557. return;
  558. }
  559. IMSDK.asyncApi('signalingGetRoomByGroupID', IMSDK.uuid(), this.$store.getters.storeCurrentConversation.groupID).then(({ data }) => {
  560. if (data.invitation) {
  561. uni.showModal({
  562. title: '提示',
  563. content: '群通话进行中,是否直接加入?',
  564. confirmText: '确认',
  565. cancelText: '取消',
  566. success: (res) => {
  567. if (res.confirm) {
  568. callingModule.joinRoomLiveChat(data);
  569. }
  570. }
  571. });
  572. } else {
  573. uni.$emit(PageEvents.RtcCall, 'video');
  574. }
  575. });
  576. break;
  577. case ChatingFooterActionTypes.Order:
  578. {
  579. if (this.$companyUserIsLogin()) {
  580. uni.navigateTo({
  581. url: '/pages/company/inquiryOrderIMList?userId=' + this.userID
  582. });
  583. } else {
  584. uni.navigateTo({
  585. url: '/pages/store/inquiryOrderDetails?orderId=' + this.timStore.orderId
  586. });
  587. }
  588. }
  589. break;
  590. case ChatingFooterActionTypes.Follow:
  591. uni.navigateTo({
  592. url: '/pages/user/followDetails?followId=' + this.timStore.followId
  593. });
  594. break;
  595. case ChatingFooterActionTypes.StoreOrder:
  596. {
  597. if (this.$companyUserIsLogin()) {
  598. uni.navigateTo({
  599. url: '/pages/company/storeOrderList?userId=' + this.userID
  600. });
  601. } else {
  602. uni.navigateTo({
  603. url: '/pages/store/storeOrderDetail?orderId=' + this.timStore.orderId
  604. });
  605. }
  606. }
  607. break;
  608. case ChatingFooterActionTypes.Package: //疗法
  609. {
  610. if (this.$companyUserIsLogin()) {
  611. uni.navigateTo({
  612. url: '/pages/company/packageList?isIM=1'
  613. });
  614. }
  615. }
  616. break;
  617. case ChatingFooterActionTypes.CouponPackage:
  618. {
  619. if (this.$companyUserIsLogin()) {
  620. uni.navigateTo({
  621. url: '/pages/company/couponList?couponType=5&isIM=1'
  622. });
  623. }
  624. }
  625. break;
  626. case ChatingFooterActionTypes.InquirySelect:
  627. {
  628. if (this.$companyUserIsLogin()) {
  629. let companyId = uni.getStorageSync('companyId');
  630. let companyUserId = uni.getStorageSync('companyUserId');
  631. uni.navigateTo({
  632. url: '/pages/store/inquirySelectType?companyId=' + companyId + '&companyUserId=' + companyUserId + '&isIM=1'
  633. });
  634. }
  635. }
  636. break;
  637. case ChatingFooterActionTypes.Card:
  638. uni.navigateTo({
  639. url: `/pages_im/pages/common/contactChoose/index?type=${ContactChooseTypes.Card}`
  640. });
  641. break;
  642. case ChatingFooterActionTypes.File:
  643. if (uni.$u.os() != 'ios') {
  644. this.requestPressmition();
  645. if (!this.readFilePermission) {
  646. return;
  647. }
  648. }
  649. IMSDK.pickFile().then(async (path) => {
  650. console.log(path);
  651. const idx = path.lastIndexOf('/');
  652. const fileName = path.slice(idx + 1);
  653. const message = await IMSDK.asyncApi(IMMethods.CreateFileMessageFromFullPath, IMSDK.uuid(), {
  654. filePath: getPurePath(path),
  655. fileName
  656. });
  657. this.$emit('sendMessage', message);
  658. });
  659. break;
  660. case ChatingFooterActionTypes.Location:
  661. uni.chooseLocation({
  662. success: async (res) => {
  663. if (res) {
  664. const options = {
  665. name: res.name,
  666. latng: `${res.latitude},${res.longitude}`,
  667. addr: res.address,
  668. city: res.address,
  669. module: 'locationPicker',
  670. latitude: res.latitude,
  671. longitude: res.longitude,
  672. url: `https://restapi.amap.com/v3/staticmap?size=600*300&markers=-1,https://cache.amap.com/lbs/static/cuntom_marker1.png,0:${res.longitude},${res.latitude}&key=${AmapWebKey}`
  673. };
  674. const message = await IMSDK.asyncApi(IMMethods.CreateLocationMessage, IMSDK.uuid(), {
  675. description: JSON.stringify(options),
  676. longitude: res.longitude,
  677. latitude: res.latitude
  678. });
  679. this.$emit('sendMessage', message);
  680. } else {
  681. uni.$u.toast('获取位置失败');
  682. }
  683. },
  684. fail: ({ errMsg }) => {
  685. if (!errMsg.includes('cancel')) {
  686. uni.$u.toast('获取位置失败');
  687. }
  688. }
  689. });
  690. break;
  691. default:
  692. break;
  693. }
  694. },
  695. copyContent(content) {
  696. if (!content) return;
  697. uni.setClipboardData({
  698. data: content,
  699. success: () => {
  700. uni.showToast({
  701. title: '复制成功',
  702. icon: 'none'
  703. });
  704. },
  705. fail: () => {
  706. uni.showToast({
  707. title: '复制失败',
  708. icon: 'none'
  709. });
  710. }
  711. });
  712. },
  713. sendFixedTextFun(e) {
  714. if (e.title == '健康咨询') {
  715. return uni.navigateTo({
  716. url: e.url
  717. });
  718. }
  719. if (e.title == '课程学习') {
  720. uni.setStorageSync('activeTabCourse', true);
  721. return uni.switchTab({
  722. url: e.url
  723. });
  724. }
  725. if (e.title == '打赏医生') {
  726. this.rewardDoctor = 1;
  727. this.rewardShow = true;
  728. }
  729. },
  730. async getDetailFun(doctorId) {
  731. const res = await getAiDoctorForDetails({
  732. doctorId
  733. });
  734. if (res.code == 200) {
  735. this.data = res.data;
  736. } else {
  737. uni.showToast({
  738. icon: 'none',
  739. title: res.msg
  740. });
  741. }
  742. },
  743. goBack() {
  744. uni.navigateBack();
  745. },
  746. navTo(url) {
  747. uni.navigateTo({
  748. url: url
  749. });
  750. },
  751. doShare(title) {
  752. this.shareItem.title = title;
  753. this.shareItem.imageUrl = (this.doctor && this.doctor.avatar) || '';
  754. this.shareItem.compressImage = 1;
  755. this.shareItem.isMini = true;
  756. this.shareItem.path = '/pages_doctor/doctorDetails?doctorId=' + this.doctorId;
  757. let cdn = uni.getStorageSync('h5Path');
  758. this.shareItem.url = cdn + '/pages/doctor/doctorDetails?doctorId=' + this.doctorId;
  759. this.showShare = true;
  760. }
  761. }
  762. };
  763. </script>
  764. <style scoped lang="scss">
  765. .content {
  766. height: auto;
  767. min-height: 100vh;
  768. overflow-y: scroll;
  769. width: 100%;
  770. background: url('/static/image/agent/doctor-bg1.png') center top / 100% 50% no-repeat, url('/static/image/agent/doctor-bg2.png') center bottom / 100% 50% no-repeat;
  771. padding-bottom: 268rpx;
  772. }
  773. .info {
  774. margin: 0 24rpx;
  775. .avatar {
  776. padding: 4rpx;
  777. background: linear-gradient(180deg, #fff5eb 0%, #ffefdd 48.08%, #ffe9cd 100%);
  778. }
  779. .agentBox {
  780. background-image: url('/static/image/agent/znt_jj_bg.png');
  781. background-repeat: no-repeat;
  782. background-size: 100% 100%;
  783. height: 314rpx;
  784. padding: 24rpx 32rpx;
  785. position: relative;
  786. z-index: 1000;
  787. .agentBox-avatar {
  788. position: absolute;
  789. top: -204rpx;
  790. right: 20rpx;
  791. z-index: -1;
  792. width: 268rpx;
  793. height: 332rpx;
  794. image {
  795. width: 268rpx;
  796. height: 270rpx;
  797. }
  798. }
  799. }
  800. }
  801. .msgBox {
  802. margin: 0 24rpx;
  803. .msgBox-item {
  804. display: flex;
  805. align-items: flex-start;
  806. width: 100%;
  807. }
  808. .leftMsg {
  809. display: inline-block;
  810. padding: 16rpx 32rpx;
  811. border-radius: 16rpx;
  812. max-width: 80%;
  813. word-wrap: break-word;
  814. word-break: break-all;
  815. }
  816. .rightMsg {
  817. display: inline-block;
  818. max-width: 80%;
  819. word-wrap: break-word;
  820. word-break: break-all;
  821. background: linear-gradient(89deg, #FF5030 0%, #ffab3b 100%);
  822. border-radius: 32rpx 8rpx 32rpx 32rpx;
  823. padding: 30rpx 24rpx;
  824. }
  825. .jcEnd {
  826. justify-content: flex-end;
  827. }
  828. .answer {
  829. border-radius: 32rpx;
  830. padding: 32rpx;
  831. background: #ffffff;
  832. .line {
  833. margin: 32rpx 0;
  834. background: #ececec;
  835. height: 2rpx;
  836. }
  837. }
  838. }
  839. .es-icon-36 {
  840. width: 36rpx;
  841. height: 36rpx;
  842. }
  843. .es-mt-60 {
  844. margin-top: 60rpx;
  845. }
  846. .footerBox {
  847. position: fixed;
  848. bottom: 0;
  849. width: 100%;
  850. z-index: 999;
  851. background-color: #ffffff;
  852. background-image: url('/static/image/agent/doctor-bg2.png');
  853. overflow: hidden;
  854. background-size: 100% 200%;
  855. background-position: bottom;
  856. background-repeat: no-repeat;
  857. box-sizing: border-box;
  858. padding: 32rpx 24rpx;
  859. .footerBox-tips {
  860. padding: 16rpx 24rpx;
  861. background: linear-gradient(180deg, #fff4ed 0%, #ffffff 17%, #ffffff 100%);
  862. box-shadow: inset 0rpx 16rpx 8rpx 0rpx rgba(230, 192, 172, 0.1);
  863. border-radius: 32rpx 32rpx 32rpx 32rpx;
  864. border: 2rpx solid #ffffff;
  865. }
  866. .footerBox-btn {
  867. width: 100%;
  868. height: 100rpx;
  869. box-sizing: border-box;
  870. .footerBox-btnBox {
  871. width: calc(100% - 64rpx);
  872. border-radius: 50rpx 50rpx 50rpx 50rpx;
  873. background: #ffffff;
  874. .footerBox-btnBox-recording {
  875. border-radius: 50rpx 50rpx 50rpx 50rpx;
  876. width: 100rpx;
  877. height: 100rpx;
  878. box-sizing: border-box;
  879. background: #ffffff;
  880. box-shadow: 4rpx 0rpx 8rpx 0rpx rgba(159, 64, 11, 0.05);
  881. }
  882. }
  883. }
  884. }
  885. .chat_action_bar {
  886. position: relative;
  887. // background: #f0f2f6;
  888. padding: 24rpx 36rpx;
  889. .action_row {
  890. flex-wrap: wrap;
  891. margin-bottom: 24rpx;
  892. }
  893. .action_item {
  894. @include centerBox();
  895. flex-direction: column;
  896. margin-top: 24rpx;
  897. image {
  898. width: 96rpx;
  899. height: 96rpx;
  900. }
  901. &_title {
  902. font-size: 24rpx;
  903. color: #999;
  904. margin-top: 6rpx;
  905. }
  906. }
  907. }
  908. .sendInput {
  909. padding: 28rpx 20rpx;
  910. width: 90%;
  911. }
  912. .chose-patient {
  913. // margin: 15rpx 15rpx;
  914. margin-bottom: 15rpx;
  915. padding: 30rpx 40rpx;
  916. box-shadow: 0px 0px 5px 2px rgba(0, 0, 0, 0.05);
  917. background-color: #fff;
  918. border-radius: 15rpx;
  919. width: 622rpx;
  920. height: 200rpx;
  921. .title-box {
  922. margin-top: 40rpx;
  923. display: flex;
  924. align-items: center;
  925. justify-content: space-between;
  926. .title {
  927. font-size: 32upx;
  928. font-family: PingFang SC;
  929. font-weight: bold;
  930. color: #111111;
  931. }
  932. .right {
  933. height: 100%;
  934. display: flex;
  935. align-items: center;
  936. justify-content: center;
  937. .value {
  938. font-size: 28upx;
  939. font-family: PingFang SC;
  940. color: #999;
  941. margin-right: 10rpx;
  942. }
  943. image {
  944. width: 15upx;
  945. height: 30upx;
  946. }
  947. }
  948. }
  949. .patient {
  950. display: flex;
  951. align-items: center;
  952. justify-content: space-between;
  953. height: 110upx;
  954. .left {
  955. .name {
  956. font-size: 30upx;
  957. line-height: 1;
  958. font-family: PingFang SC;
  959. font-weight: bold;
  960. color: #111111;
  961. }
  962. .info {
  963. margin-top: 30rpx;
  964. display: flex;
  965. align-items: center;
  966. .text {
  967. font-size: 26upx;
  968. font-family: PingFang SC;
  969. line-height: 1;
  970. font-weight: 500;
  971. color: #999;
  972. margin-right: 19upx;
  973. }
  974. }
  975. }
  976. .right {
  977. display: flex;
  978. align-items: center;
  979. image {
  980. width: 15upx;
  981. height: 30upx;
  982. }
  983. }
  984. }
  985. }
  986. </style>