App.vue 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. <script>
  2. import { mapGetters, mapActions } from 'vuex';
  3. import IMSDK, { IMMethods, MessageReceiveOptType, MessageType, SessionType } from 'openim-uniapp-polyfill';
  4. import { config } from '@/pages_im/common/config';
  5. import { getDbDir, Igexin, toastWithCallback } from '@/pages_im/util/common.js';
  6. import { conversationSort, secFormat, callingModule, meetingModule, parseMessageByType, prepareConversationState } from '@/pages_im/util/imCommon';
  7. import { PageEvents, UpdateMessageTypes, CustomType, ContactChooseTypes } from '@/pages_im/constant';
  8. import { openImLoginApi } from '@/pages_im/api/imBll';
  9. import NotificationUtil from '@/pages_im/util/notification';
  10. import newMessage from '@/pages_im/static/audio/newMessage.wav';
  11. import { getTlsSig } from '@/api/common.js'
  12. import { checkLogin } from '@/api/user.js'
  13. let cacheConversationList = [];
  14. let updateDownloadTask = null;
  15. let notificationIntance = null;
  16. let pausing = false;
  17. let innerAudioContext;
  18. let notification;
  19. let uPushPlugin;
  20. export default {
  21. globalData: {
  22. appId: 'wxb2d969ad2a2e71f3', // 银川鑫泰互联网医院服务
  23. wsDanmuUrl:'wss://userapp.tytzhongyi.cn',
  24. imgpath:'https://obs.jnmyunl.com',
  25. uploadFile:'https://userapp.tytzhongyi.cn',
  26. isSpare: 0, // 0 主要,1备选
  27. },
  28. onLaunch: function () {
  29. this.checkUpdate()
  30. this.initOpenIm();
  31. var that=this;
  32. uni.$on('refreshIM', () => {
  33. this.checkLogin();
  34. });
  35. // 御君方、御君方中医、彩虹惠医
  36. var urls="https://17010831189.cdwjyyh.com;https://16946746017.cdwjyyh.com;https://13708196565.cdwjyyh.com;https://1700206673.cdwjyyh.com;https://17233317680.cdwjyyh.com;https://1700575323.cdwjyyh.com;https://17069749252.cdwjyyh.com;https://16973148962.cdwjyyh.com;https://1722131630.cdwjyyh.com;https://17146969562.cdwjyyh.com;https://1695072024.cdwjyyh.com;https://17203639647.cdwjyyh.com;https://16954404159.cdwjyyh.com;https://1707741400.cdwjyyh.com;https://17408937934.cdwjyyh.com;https://17180847536.cdwjyyh.com;https://17244394814.cdwjyyh.com;https://1703101076.cdwjyyh.com;https://17124251670.cdwjyyh.com;https://17017634981.cdwjyyh.com;https://1709430520.cdwjyyh.com;https://17163564434.cdwjyyh.com;https://17168038011.cdwjyyh.com;https://1710609621.cdwjyyh.com;https://1705257092.cdwjyyh.com;https://17211347588.cdwjyyh.com;https://17035647784.cdwjyyh.com;https://1721509816.cdwjyyh.com;https://1720396718.cdwjyyh.com;https://17214936263.cdwjyyh.com;https://1716050799.cdwjyyh.com;https://1713109810.cdwjyyh.com;https://172542243167.cdwjyyh.com;https://172240149208.cdwjyyh.com;https://1702848339.cdwjyyh.com;https://1707911907.cdwjyyh.com;https://1717849419.cdwjyyh.com;https://17038049724.cdwjyyh.com;https://1724650239.cdwjyyh.com;https://1707113459.cdwjyyh.com;https://1715669104.cdwjyyh.com;https://1710051545.cdwjyyh.com;https://1722269330.cdwjyyh.com;https://1710003925.cdwjyyh.com;https://17145545145.cdwjyyh.com;https://1720634288.cdwjyyh.com;https://1696593184.cdwjyyh.com;https://1704962208.cdwjyyh.com;https://1703146177.cdwjyyh.com;https://1704346325.cdwjyyh.com;https://1697387624.cdwjyyh.com;https://1702551094.cdwjyyh.com;https://1720523201.cdwjyyh.com;https://1714391651.cdwjyyh.com;https://16989457834.cdwjyyh.com;https://1710582715.cdwjyyh.com;https://1696073814.cdwjyyh.com;https://1701427000.cdwjyyh.com;https://1703620825.cdwjyyh.com;https://1716954881.cdwjyyh.com;https://1709258681.cdwjyyh.com;https://1702178349.cdwjyyh.com;https://1696037454.cdwjyyh.com;https://1707163288.cdwjyyh.com;https://1698272613.cdwjyyh.com;https://1695736399.cdwjyyh.com;https://1707979666.cdwjyyh.com;https://1699631662.cdwjyyh.com;https://1725584568.cdwjyyh.com;https://1709711499.cdwjyyh.com;https://1707988905.cdwjyyh.com;https://1709289861.cdwjyyh.com;https://1720027873.cdwjyyh.com;https://1723979172.cdwjyyh.com;https://1711804525.cdwjyyh.com;https://1702653210.cdwjyyh.com;https://1711075739.cdwjyyh.com;https://1710979987.cdwjyyh.com;https://1724292527.cdwjyyh.com;https://1704964596.cdwjyyh.com;https://1703840482.cdwjyyh.com;https://1709061808.cdwjyyh.com;https://1718492957.cdwjyyh.com;https://1708829102.cdwjyyh.com;https://1716362553.cdwjyyh.com;https://1710541443.cdwjyyh.com;https://1715811900.cdwjyyh.com;https://1718208786.cdwjyyh.com;https://1704651745.cdwjyyh.com;https://1699759405.cdwjyyh.com;https://1713080422.cdwjyyh.com;https://1715403843.cdwjyyh.com;https://1696900518.cdwjyyh.com;https://1707770189.cdwjyyh.com;https://1700034515.cdwjyyh.com;https://1715466167.cdwjyyh.com;https://1709976677.cdwjyyh.com;https://1712370330.cdwjyyh.com;https://1706087997.cdwjyyh.com;https://1703496196.cdwjyyh.com;https://17122663469.cdwjyyh.com;https://1712318592.cdwjyyh.com;https://1712812440.cdwjyyh.com;https://1715678161.cdwjyyh.com;https://1702028001.cdwjyyh.com;https://17216467850.cdwjyyh.com;https://1696462985.cdwjyyh.com;https://1707192149.cdwjyyh.com;https://17048421512.cdwjyyh.com;https://1723797034.cdwjyyh.com;https://1704429569.cdwjyyh.com;https://17092443255.cdwjyyh.com;https://1722028860.cdwjyyh.com;https://17129467809.cdwjyyh.com;https://1705848887.cdwjyyh.com;https://16945675535.cdwjyyh.com;https://17257464755.cdwjyyh.com;https://1723025937.cdwjyyh.com;https://17234848798.cdwjyyh.com;https://1700104177.cdwjyyh.com;https://17242943219.cdwjyyh.com;https://17262404998.cdwjyyh.com;https://17140341757.cdwjyyh.com;https://17134130421.cdwjyyh.com;https://1723148318.cdwjyyh.com;https://17257455505.cdwjyyh.com;https://17207640127.cdwjyyh.com;https://1709058929.cdwjyyh.com;https://17069353822.cdwjyyh.com;https://1698429582.cdwjyyh.com;https://17253124611.cdwjyyh.com;https://1709158760.cdwjyyh.com;https://17124964042.cdwjyyh.com;https://1707326074.cdwjyyh.com;https://17046524832.cdwjyyh.com;https://1722471447.cdwjyyh.com;https://1715081607.cdwjyyh.com;https://1722709008.cdwjyyh.com;https://1705411096.cdwjyyh.com;https://17221412356.cdwjyyh.com;https://173131762485.cdwjyyh.com;https://17106348388.cdwjyyh.com;https://1703201862.cdwjyyh.com;https://171645204084.cdwjyyh.com;https://17316201102.cdwjyyh.com;https://1714278120.cdwjyyh.com;https://169458141036.cdwjyyh.com;https://16966142587.cdwjyyh.com;https://1720738395.cdwjyyh.com;https://1722208363.cdwjyyh.com;https://169714438661.cdwjyyh.com;https://1717887413.cdwjyyh.com;https://1715113705.cdwjyyh.com;https://16960448580.cdwjyyh.com;https://16961466861.cdwjyyh.com;https://1707853597.cdwjyyh.com;https://1709274679.cdwjyyh.com;https://1722858089.cdwjyyh.com;https://1715419874.cdwjyyh.com;https://17151136007.cdwjyyh.com;https://1722314568.cdwjyyh.com;https://1724746541.cdwjyyh.com;https://1718762128.cdwjyyh.com;https://1720163684.cdwjyyh.com;https://17247470857.cdwjyyh.com;https://1708580403.cdwjyyh.com;https://1705948747.cdwjyyh.com;https://1700682425.cdwjyyh.com;https://170284458903.cdwjyyh.com;https://1725605169.cdwjyyh.com;https://16990645003.cdwjyyh.com;https://16946786637.cdwjyyh.com;https://17083564387.cdwjyyh.com;https://16994525562.cdwjyyh.com;https://1720968292.cdwjyyh.com;https://1710909698.cdwjyyh.com;https://1700467361.cdwjyyh.com;https://16953683561.cdwjyyh.com;https://17258458080.cdwjyyh.com;https://1702911871.cdwjyyh.com";
  37. var urlList=urls.split(";");
  38. console.log(this.getRandomInt(0,urlList.length-1))
  39. var path = urlList[this.getRandomInt(0,urlList.length-1)];
  40. //path="https://api.cdwjyyh.com";
  41. //path="https://test.userapp.his.cdwjyyh.com";
  42. uni.setStorageSync('requestPath',path);
  43. },
  44. onUnload() {
  45. },
  46. onShow() {
  47. uni.getSystemInfo({
  48. success: (result) => {
  49. // 获取手机系统的状态栏高度(不同手机的状态栏高度不同)
  50. // console.log('当前手机的状态栏高度',result.statusBarHeight)
  51. let statusBarHeight = result.statusBarHeight + 'px'
  52. // 获取右侧胶囊的信息 单位px
  53. //#ifndef H5 || APP-PLUS
  54. const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
  55. //bottom: 胶囊底部距离屏幕顶部的距离
  56. //height: 胶囊高度
  57. //left: 胶囊左侧距离屏幕左侧的距离
  58. //right: 胶囊右侧距离屏幕左侧的距离
  59. //top: 胶囊顶部距离屏幕顶部的距离
  60. //width: 胶囊宽度
  61. // console.log(menuButtonInfo.width, menuButtonInfo.height, menuButtonInfo.top)
  62. // console.log('计算胶囊右侧距离屏幕右边距离', result.screenWidth - menuButtonInfo.right)
  63. let menuWidth = menuButtonInfo.width + 'px'
  64. let menuHeight = menuButtonInfo.height + 'px'
  65. let menuBorderRadius = menuButtonInfo.height / 2 + 'px'
  66. let menuRight = result.screenWidth - menuButtonInfo.right + 'px'
  67. let menuTop = menuButtonInfo.top + 'px'
  68. let contentTop = result.statusBarHeight + 44 + 'px'
  69. let menuInfo = {
  70. statusBarHeight: statusBarHeight,//状态栏高度----用来给自定义导航条页面的顶部导航条设计padding-top使用:目的留出系统的状态栏区域
  71. menuWidth: menuWidth,//右侧的胶囊宽度--用来给自定义导航条页面的左侧胶囊设置使用
  72. menuHeight: menuHeight,//右侧的胶囊高度--用来给自定义导航条页面的左侧胶囊设置使用
  73. menuBorderRadius: menuBorderRadius,//一半的圆角--用来给自定义导航条页面的左侧胶囊设置使用
  74. menuRight: menuRight,//右侧的胶囊距离右侧屏幕距离--用来给自定义导航条页面的左侧胶囊设置使用
  75. menuTop: menuTop,//右侧的胶囊顶部距离屏幕顶部的距离--用来给自定义导航条页面的左侧胶囊设置使用
  76. contentTop: contentTop,//内容区距离页面最上方的高度--用来给自定义导航条页面的内容区定位距离使用
  77. }
  78. uni.setStorageSync('menuInfo', menuInfo);
  79. setTimeout(()=>{
  80. console.log("qxj getSystemInfo",result);
  81. let info=" 型号:"+result.model+" 品牌:"+result.brand+" 类型:"+result.deviceType+" 设备品牌:"+result.deviceBrand+" 设备id:"+result.deviceId;
  82. // uni.showToast({ title:info,icon:'none', duration: 5000 });
  83. },2000);
  84. //#endif
  85. },
  86. fail: (error) => {
  87. console.log(error)
  88. }
  89. })
  90. },
  91. onHide() {
  92. },
  93. computed: {
  94. ...mapGetters([
  95. 'storeConversationList',
  96. 'storeCurrentConversation',
  97. 'storeCurrentUserID',
  98. 'storeSelfInfo',
  99. 'storeRecvFriendApplications',
  100. 'storeRecvGroupApplications',
  101. 'storeHistoryMessageList',
  102. 'storeIsSyncing',
  103. 'storeGroupList'
  104. ]),
  105. contactBadgeRely() {
  106. return {
  107. recvFriendApplications: this.storeRecvFriendApplications,
  108. recvGroupApplications: this.storeRecvGroupApplications,
  109. userKey: this.storeCurrentUserID
  110. };
  111. }
  112. },
  113. methods: {
  114. ...mapActions('message', ['pushNewMessage', 'updateOneMessage', 'updateQuoteMessageRevoke', 'updateMessageNicknameAndFaceUrl']),
  115. ...mapActions('conversation', ['updateCurrentMemberInGroup']),
  116. ...mapActions('contact', [
  117. 'updateFriendInfo',
  118. 'pushNewFriend',
  119. 'updateBlackInfo',
  120. 'pushNewBlack',
  121. 'pushNewGroup',
  122. 'updateGroupInfo',
  123. 'pushNewRecvFriendApplition',
  124. 'updateRecvFriendApplition',
  125. 'pushNewSentFriendApplition',
  126. 'updateSentFriendApplition',
  127. 'pushNewRecvGroupApplition',
  128. 'updateRecvGroupApplition',
  129. 'pushNewSentGroupApplition',
  130. 'updateSentGroupApplition'
  131. ]),
  132. getRandomInt(min, max) {
  133. const minCeiled = Math.ceil(min);
  134. const maxFloored = Math.floor(max);
  135. return Math.floor(Math.random() * (maxFloored - minCeiled + 1) + minCeiled); // 包含最小值和最大值
  136. },
  137. checkLogin(){
  138. var data={};
  139. checkLogin(data).then(
  140. res => {
  141. if(res.code==200){
  142. this.openImLogin();
  143. }
  144. },
  145. rej => {}
  146. );
  147. },
  148. checkUpdate() {
  149. const updateManager = uni.getUpdateManager();
  150. updateManager.onCheckForUpdate(function(res) {
  151. // 请求完新版本信息的回调
  152. console.log('是否有新版本:', res.hasUpdate);
  153. });
  154. updateManager.onUpdateReady(function() {
  155. uni.showModal({
  156. title: '更新提示',
  157. content: '新版本已经准备好,是否重启小程序?',
  158. confirmText: '立即重启',
  159. confirmColor: '#2179f5',
  160. showCancel: false,
  161. success(res) {
  162. if (res.confirm) {
  163. // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
  164. updateManager.applyUpdate();
  165. }
  166. }
  167. });
  168. });
  169. updateManager.onUpdateFailed(function() {
  170. // 新的版本下载失败
  171. uni.showModal({
  172. title: '更新提示',
  173. content: '新版本下载失败,请检查网络后重试。',
  174. showCancel: false
  175. });
  176. });
  177. },
  178. initOpenIm() {
  179. innerAudioContext = uni.createInnerAudioContext();
  180. innerAudioContext.autoplay = false;
  181. innerAudioContext.src = newMessage;
  182. this.setGlobalIMlistener();
  183. this.tryLogin();
  184. },
  185. setGlobalIMlistener() {
  186. // init
  187. const kickHander = (message) => {
  188. toastWithCallback(message, () => {
  189. uni.setStorageSync('AppToken',null);
  190. uni.removeStorage({key: "IMToken",});
  191. uni.removeStorage({key: "IMUserID",});
  192. uni.removeStorage({key: "IMHasLogin"});
  193. uni.$emit('loginOut');
  194. //callingModule?.endCall();
  195. //meetingModule?.endCall();
  196. });
  197. };
  198. let that=this;
  199. IMSDK.subscribe(IMSDK.IMEvents.OnKickedOffline, (data) => {
  200. kickHander('您的账号在其他设备登录,请重新登陆!');
  201. //that.removeImData();
  202. //that.openImLogin();
  203. });
  204. IMSDK.subscribe(IMSDK.IMEvents.OnUserTokenExpired, (data) => {
  205. //kickHander('您的登录已过期,请重新登陆!');
  206. that.removeImData();
  207. that.openImLogin();
  208. });
  209. IMSDK.subscribe(IMSDK.IMEvents.OnUserTokenInvalid, (data) => {
  210. //kickHander('您的登录已无效,请重新登陆!');
  211. that.removeImData();
  212. that.openImLogin();
  213. });
  214. // sync
  215. const syncStartHandler = ({ data }) => {
  216. this.$store.commit('user/SET_IS_SYNCING', true);
  217. this.$store.commit('user/SET_REINSTALL', data);
  218. };
  219. const syncProgressHandler = ({ data }) => {
  220. this.$store.commit('user/SET_PROGRESS', data);
  221. };
  222. const syncFinishHandler = () => {
  223. this.$store.dispatch('conversation/getConversationList');
  224. this.$store.dispatch('contact/getFriendList');
  225. this.$store.dispatch('contact/getGrouplist');
  226. this.$store.dispatch('conversation/getUnReadCount');
  227. this.$store.commit('user/SET_IS_SYNCING', false);
  228. uni.hideLoading();
  229. };
  230. const syncFailedHandler = () => {
  231. uni.hideLoading();
  232. //uni.$u.toast('同步消息失败');
  233. this.$store.dispatch('conversation/getConversationList');
  234. this.$store.dispatch('conversation/getUnReadCount');
  235. this.$store.commit('user/SET_IS_SYNCING', false);
  236. };
  237. IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerStart, syncStartHandler);
  238. IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerFinish, syncFinishHandler);
  239. IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerFailed, syncFailedHandler);
  240. IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerProgress, syncProgressHandler);
  241. // self
  242. const selfInfoUpdateHandler = ({ data }) => {
  243. this.$store.commit('user/SET_SELF_INFO', {
  244. ...this.storeSelfInfo,
  245. ...data
  246. });
  247. this.updateMessageNicknameAndFaceUrl({
  248. sendID: data.userID,
  249. senderNickname: data.nickname,
  250. senderFaceUrl: data.faceURL
  251. });
  252. };
  253. IMSDK.subscribe(IMSDK.IMEvents.OnSelfInfoUpdated, selfInfoUpdateHandler);
  254. // message
  255. const newMessagesHandler = ({ data }) => {
  256. if (this.storeIsSyncing) {
  257. return;
  258. }
  259. data.forEach(this.handleNewMessage);
  260. };
  261. const c2cReadReceiptHandler = ({ data: receiptList }) => {
  262. if (receiptList[0].userID !== this.storeCurrentConversation.userID) {
  263. return;
  264. }
  265. receiptList.forEach((item) => {
  266. item.msgIDList.forEach((msgID) => {
  267. this.updateOneMessage({
  268. message: {
  269. clientMsgID: msgID
  270. },
  271. type: UpdateMessageTypes.KeyWords,
  272. keyWords: {
  273. key: 'isRead',
  274. value: true
  275. }
  276. });
  277. });
  278. });
  279. };
  280. const groupReadReceiptHandler = ({ data }) => {
  281. if (data.conversationID !== this.storeCurrentConversation.conversationID) {
  282. return;
  283. }
  284. data.groupMessageReadInfo.map((receipt) => {
  285. const oldMessage = this.storeHistoryMessageList.find((msg) => msg.clientMsgID === receipt.clientMsgID);
  286. if (oldMessage) {
  287. uni.$emit(PageEvents.GroupMessageReceipt, receipt);
  288. const newMessage = {
  289. ...oldMessage,
  290. isRead: true,
  291. attachedInfoElem: {
  292. ...oldMessage.attachedInfoElem,
  293. groupHasReadInfo: {
  294. hasReadCount: receipt.hasReadCount,
  295. unreadCount: receipt.unreadCount
  296. }
  297. }
  298. };
  299. console.log(newMessage);
  300. this.updateOneMessage({ message: newMessage });
  301. }
  302. });
  303. console.log(data);
  304. };
  305. const newRecvMessageRevokedHandler = ({ data: revokedMessage }) => {
  306. if (!this.storeCurrentConversation.conversationID) {
  307. return;
  308. }
  309. this.updateOneMessage({
  310. message: { clientMsgID: revokedMessage.clientMsgID },
  311. type: UpdateMessageTypes.KeyWords,
  312. keyWords: [
  313. {
  314. key: 'contentType',
  315. value: MessageType.RevokeMessage
  316. },
  317. {
  318. key: 'notificationElem',
  319. value: {
  320. detail: JSON.stringify(revokedMessage)
  321. }
  322. }
  323. ]
  324. });
  325. this.updateQuoteMessageRevoke({
  326. clientMsgID: revokedMessage.clientMsgID
  327. });
  328. };
  329. const inputStatusChanged = ({ data }) => {
  330. if (data.userID === this.storeCurrentConversation.userID && data.conversationID === this.storeCurrentConversation.conversationID) {
  331. if (data.platformIDs.length > 0) {
  332. uni.$emit(PageEvents.TypingUpdate);
  333. }
  334. }
  335. };
  336. IMSDK.subscribe(IMSDK.IMEvents.OnRecvNewMessages, newMessagesHandler);
  337. IMSDK.subscribe(IMSDK.IMEvents.OnInputStatusChanged, inputStatusChanged);
  338. IMSDK.subscribe(IMSDK.IMEvents.OnRecvC2CReadReceipt, c2cReadReceiptHandler);
  339. IMSDK.subscribe(IMSDK.IMEvents.OnRecvGroupReadReceipt, groupReadReceiptHandler);
  340. IMSDK.subscribe(IMSDK.IMEvents.OnNewRecvMessageRevoked, newRecvMessageRevokedHandler);
  341. // friend
  342. const friendInfoChangeHandler = ({ data }) => {
  343. uni.$emit(IMSDK.IMEvents.OnFriendInfoChanged, { data });
  344. if (data.userID === this.storeCurrentConversation?.userID) {
  345. this.updateMessageNicknameAndFaceUrl({
  346. sendID: data.userID,
  347. senderNickname: data.remark || data.nickname,
  348. senderFaceUrl: data.faceURL
  349. });
  350. this.$store.commit('conversation/SET_CURRENT_CONVERSATION', { ...this.storeCurrentConversation, showName: data.remark || data.nickname });
  351. }
  352. console.log(this.storeConversationList);
  353. this.updateFriendInfo({friendInfo: data});
  354. };
  355. const friendAddedHandler = ({ data }) => {
  356. this.pushNewFriend(data);
  357. };
  358. const friendDeletedHander = ({ data }) => {
  359. this.updateFriendInfo({
  360. friendInfo: data,
  361. isRemove: true
  362. });
  363. };
  364. IMSDK.subscribe(IMSDK.IMEvents.OnFriendInfoChanged, friendInfoChangeHandler);
  365. IMSDK.subscribe(IMSDK.IMEvents.OnFriendAdded, friendAddedHandler);
  366. IMSDK.subscribe(IMSDK.IMEvents.OnFriendDeleted, friendDeletedHander);
  367. // blacklist
  368. const blackAddedHandler = ({ data }) => {
  369. this.pushNewBlack(data);
  370. };
  371. const blackDeletedHandler = ({ data }) => {
  372. this.updateBlackInfo({
  373. blackInfo: data,
  374. isRemove: true
  375. });
  376. };
  377. IMSDK.subscribe(IMSDK.IMEvents.OnBlackAdded, blackAddedHandler);
  378. IMSDK.subscribe(IMSDK.IMEvents.OnBlackDeleted, blackDeletedHandler);
  379. // group
  380. const joinedGroupAddedHandler = ({ data }) => {
  381. uni.$emit(IMSDK.IMEvents.OnJoinedGroupAdded, { data });
  382. this.pushNewGroup(data);
  383. };
  384. const joinedGroupDeletedHandler = ({ data }) => {
  385. uni.$emit(IMSDK.IMEvents.OnJoinedGroupDeleted, { data });
  386. this.updateGroupInfo({
  387. groupInfo: data,
  388. isRemove: true
  389. });
  390. };
  391. const groupInfoChangedHandler = ({ data }) => {
  392. this.updateGroupInfo({
  393. groupInfo: data
  394. });
  395. };
  396. const groupMemberInfoChangedHandler = ({ data }) => {
  397. uni.$emit(IMSDK.IMEvents.OnGroupMemberInfoChanged, { data });
  398. if (data.groupID === this.storeCurrentConversation?.groupID) {
  399. this.updateMessageNicknameAndFaceUrl({
  400. sendID: data.userID,
  401. senderNickname: data.nickname,
  402. senderFaceUrl: data.faceURL
  403. });
  404. this.updateCurrentMemberInGroup(data);
  405. }
  406. };
  407. IMSDK.subscribe(IMSDK.IMEvents.OnJoinedGroupAdded, joinedGroupAddedHandler);
  408. IMSDK.subscribe(IMSDK.IMEvents.OnJoinedGroupDeleted, joinedGroupDeletedHandler);
  409. IMSDK.subscribe(IMSDK.IMEvents.OnGroupInfoChanged, groupInfoChangedHandler);
  410. IMSDK.subscribe(IMSDK.IMEvents.OnGroupMemberInfoChanged, groupMemberInfoChangedHandler);
  411. // application
  412. const friendApplicationNumHandler = ({ data }) => {
  413. const isRecv = data.toUserID === this.storeCurrentUserID;
  414. if (isRecv) {
  415. this.pushNewRecvFriendApplition(data);
  416. } else {
  417. this.pushNewSentFriendApplition(data);
  418. }
  419. };
  420. const friendApplicationAccessHandler = ({ data }) => {
  421. const isRecv = data.toUserID === this.storeCurrentUserID;
  422. if (isRecv) {
  423. this.updateRecvFriendApplition({
  424. application: data
  425. });
  426. } else {
  427. this.updateSentFriendApplition({
  428. application: data
  429. });
  430. }
  431. };
  432. const groupApplicationNumHandler = ({ data }) => {
  433. const isRecv = data.userID !== this.storeCurrentUserID;
  434. if (isRecv) {
  435. this.pushNewRecvGroupApplition(data);
  436. } else {
  437. this.pushNewSentGroupApplition(data);
  438. }
  439. };
  440. const groupApplicationAccessHandler = ({ data }) => {
  441. const isRecv = data.userID !== this.storeCurrentUserID;
  442. if (isRecv) {
  443. this.updateRecvGroupApplition({
  444. application: data
  445. });
  446. } else {
  447. this.updateSentGroupApplition({
  448. application: data
  449. });
  450. }
  451. };
  452. IMSDK.subscribe(IMSDK.IMEvents.OnFriendApplicationAdded, friendApplicationNumHandler);
  453. IMSDK.subscribe(IMSDK.IMEvents.OnFriendApplicationAccepted, friendApplicationAccessHandler);
  454. IMSDK.subscribe(IMSDK.IMEvents.OnFriendApplicationRejected, friendApplicationAccessHandler);
  455. IMSDK.subscribe(IMSDK.IMEvents.OnGroupApplicationAdded, groupApplicationNumHandler);
  456. IMSDK.subscribe(IMSDK.IMEvents.OnGroupApplicationAccepted, groupApplicationAccessHandler);
  457. IMSDK.subscribe(IMSDK.IMEvents.OnGroupApplicationRejected, groupApplicationAccessHandler);
  458. // conversation
  459. const totalUnreadCountChangedHandler = ({ data }) => {
  460. if (this.storeIsSyncing) {
  461. return;
  462. }
  463. this.$store.commit('conversation/SET_UNREAD_COUNT', data);
  464. };
  465. const newConversationHandler = ({ data }) => {
  466. if (this.storeIsSyncing) {
  467. return;
  468. }
  469. const result = [...data, ...this.storeConversationList];
  470. this.$store.commit('conversation/SET_CONVERSATION_LIST', conversationSort(result));
  471. };
  472. const conversationChangedHandler = ({ data }) => {
  473. if (this.storeIsSyncing) {
  474. return;
  475. }
  476. let filterArr = [];
  477. console.log("qxj conversationChangedHandler:::");
  478. console.log(data);
  479. const chids = data.map((ch) => ch.conversationID);
  480. filterArr = this.storeConversationList.filter((tc) => !chids.includes(tc.conversationID));
  481. const idx = data.findIndex((c) => c.conversationID === this.storeCurrentConversation.conversationID);
  482. if (idx !== -1) this.$store.commit('conversation/SET_CURRENT_CONVERSATION', data[idx]);
  483. const result = [...data, ...filterArr];
  484. this.$store.commit('conversation/SET_CONVERSATION_LIST', conversationSort(result));
  485. };
  486. IMSDK.subscribe(IMSDK.IMEvents.OnTotalUnreadMessageCountChanged, totalUnreadCountChangedHandler);
  487. IMSDK.subscribe(IMSDK.IMEvents.OnNewConversation, newConversationHandler);
  488. IMSDK.subscribe(IMSDK.IMEvents.OnConversationChanged, conversationChangedHandler);
  489. const insertInCurrentConversation = (newServerMsg) => {
  490. return newServerMsg.sendID === this.$store.getters.storeCurrentConversation.userID || newServerMsg.recvID === this.$store.getters.storeCurrentConversation.userID;
  491. };
  492. const onNativeCallEndHandler = async ({ invitation, duration, status }) => {
  493. uni.$emit(PageEvents.NativeCallEnd);
  494. if (!status || invitation.groupID) {
  495. return;
  496. }
  497. const type = invitation.mediaType === 'video' ? CustomType.VideoCall : CustomType.VoiceCall;
  498. const customData = {
  499. customType: CustomType.Call,
  500. data: { type, duration: secFormat(duration), status }
  501. };
  502. // uni.clearStorageSync();
  503. const nativeCallList = uni.getStorageSync(`${this.$store.getters.storeCurrentUserID}_nativecall`) || [];
  504. const isSelf = invitation.inviterUserID === this.$store.getters.storeCurrentUserID;
  505. const data = { ...invitation, duration, isSelf, type, time: new Date().getTime() };
  506. uni.setStorage({
  507. key: `${this.$store.getters.storeCurrentUserID}_nativecall`,
  508. data: [...nativeCallList, data]
  509. });
  510. const message = await IMSDK.asyncApi(IMMethods.CreateCustomMessage, IMSDK.uuid(), {
  511. data: JSON.stringify(customData),
  512. extension: '',
  513. description: 'RTC'
  514. });
  515. const recvID = invitation.inviteeUserIDList[0];
  516. IMSDK.asyncApi(IMSDK.IMMethods.InsertSingleMessageToLocalStorage, IMSDK.uuid(), {
  517. message,
  518. recvID,
  519. sendID: invitation.inviterUserID
  520. }).then(({ data }) => {
  521. if (insertInCurrentConversation(data)) {
  522. this.$store.dispatch('message/pushNewMessage', data);
  523. setTimeout(() => uni.$emit(PageEvents.ScrollToBottom, true));
  524. }
  525. }).catch((err) => {
  526. console.log(err);
  527. });
  528. };
  529. const onNativeInviteHandler = async (data) => {
  530. // uni.$u.toast("onNativeInviteHandler")
  531. uni.$u.route('/pages_im/pages/common/contactChoose/index', {
  532. type: ContactChooseTypes.InviteMeeting,
  533. forwardMessage: encodeURIComponent(JSON.stringify(data.data))
  534. });
  535. };
  536. IMSDK.subscribe('onNativeCallEnd', onNativeCallEndHandler);
  537. IMSDK.subscribe('Native_InviteUser', onNativeInviteHandler);
  538. },
  539. openImLogin() {
  540. let that = this;
  541. var userId=uni.getStorageSync('userId');
  542. var avatar=uni.getStorageSync('avatar');
  543. var nickName=uni.getStorageSync('nickName');
  544. var uid = 'U' + userId;
  545. let IMToken = uni.getStorageSync('IMToken');
  546. let IMUserID = uid
  547. let reqData = { userID: uid, nickName: nickName, avatar: avatar };
  548. //if(!!IMToken){
  549. openImLoginApi(
  550. reqData,
  551. IMToken,
  552. IMUserID,
  553. function (token) {
  554. that.tryLogin();
  555. },
  556. function () {}
  557. );
  558. //}
  559. },
  560. async tryLogin() {
  561. const initStore = () => {
  562. uni.setStorageSync('IMHasLogin', 1);
  563. this.$store.dispatch('user/initCache');
  564. this.$store.dispatch('user/getSelfInfo');
  565. //this.$store.dispatch('conversation/getConversationList');
  566. this.$store.dispatch('conversation/getUnReadCount');
  567. // this.$store.dispatch("contact/getFriendList");
  568. // this.$store.dispatch("contact/getGrouplist");
  569. // this.$store.dispatch('contact/getBlacklist');
  570. // this.$store.dispatch('contact/getRecvFriendApplications');
  571. // this.$store.dispatch('contact/getSentFriendApplications');
  572. // this.$store.dispatch('contact/getRecvGroupApplications');
  573. // this.$store.dispatch('contact/getSentGroupApplications');
  574. };
  575. let IMToken = uni.getStorageSync('IMToken');
  576. let IMUserID = uni.getStorageSync('IMUserID');
  577. //1 未登录 2 登录中 3 已登录
  578. const loginStatus = await IMSDK.asyncApi(IMSDK.IMMethods.GetLoginStatus, IMSDK.uuid());
  579. console.log("qxj loginStatus:"+loginStatus);
  580. if (loginStatus === 3) {
  581. initStore();
  582. return;
  583. }
  584. //callingModule?.initModule();
  585. let platformID=5
  586. // #ifdef H5
  587. platformID=5
  588. // #endif
  589. // #ifdef MP-WEIXIN
  590. platformID=6
  591. // #endif
  592. console.log("qxj platformID:"+platformID);
  593. if (IMToken && IMUserID) {
  594. IMSDK.asyncApi(IMSDK.IMMethods.Login, IMSDK.uuid(), {
  595. userID: IMUserID,
  596. token: IMToken,
  597. platformID:platformID,
  598. apiAddr: config.getApiUrl(),
  599. wsAddr: config.getWsUrl(),
  600. logLevel: 1,
  601. }).then(initStore).catch((err) => {
  602. console.log('qxj initStore error:' + JSON.stringify(err));
  603. uni.removeStorage({ key: 'IMToken' });
  604. });
  605. } else{
  606. this.checkLogin()
  607. }
  608. },
  609. async newMessageNotify(newServerMsg) {
  610. if (this.storeIsSyncing) {
  611. return;
  612. }
  613. const disableNotify = uni.getStorageSync(`${this.storeCurrentUserID}_DisableNotify`);
  614. if (disableNotify || this.storeSelfInfo.globalRecvMsgOpt !== MessageReceiveOptType.Nomal) {
  615. return;
  616. }
  617. let cveItem = [...this.storeConversationList, ...cacheConversationList].find((conversation) => {
  618. if (newServerMsg.sessionType === SessionType.WorkingGroup) {
  619. return newServerMsg.groupID === conversation.groupID;
  620. }
  621. return newServerMsg.sendID === conversation.userID;
  622. });
  623. if (!cveItem) {
  624. try {
  625. const { data } = await IMSDK.asyncApi(IMSDK.IMMethods.GetOneConversation, IMSDK.uuid(), {
  626. sourceID: newServerMsg.groupID || newServerMsg.sendID,
  627. sessionType: newServerMsg.sessionType
  628. });
  629. cveItem = data;
  630. cacheConversationList = [...cacheConversationList, data];
  631. } catch (e) {
  632. return;
  633. }
  634. }
  635. if (cveItem.recvMsgOpt !== MessageReceiveOptType.Nomal) {
  636. return;
  637. }
  638. // uni.createPushMessage({
  639. // content: `${newServerMsg.senderNickname}: ${parseMessageByType(newServerMsg)}`,
  640. // payload: {
  641. // sessionType: newServerMsg.sessionType,
  642. // sourceID: newServerMsg.groupID || newServerMsg.sendID,
  643. // }
  644. // });
  645. // const notificationFun = () => {
  646. // const isSelf = newServerMsg.sendID === this.$store.getters.storeCurrentUserID;
  647. // if (isSelf) return;
  648. // const isSingle = newServerMsg.groupID ? false : true;
  649. // console.log(this.storeGroupList, newServerMsg);
  650. // const group = this.storeGroupList.filter((group) => group.groupID === newServerMsg.groupID);
  651. // const title = isSingle ? newServerMsg.senderNickname : group[0].groupName;
  652. // const desc = parseMessageByType(newServerMsg);
  653. // console.log('notification', title, desc);
  654. // notification.showNotice(0, title, desc, () => {
  655. // prepareConversationState(cveItem);
  656. // });
  657. // };
  658. // notificationFun();
  659. // const platform = uni.getSystemInfoSync().platform;
  660. // if (platform == 'ios') {
  661. // if (this.storeSelfInfo.allowVibration === 1) {
  662. // plus.device.vibrate();
  663. // }
  664. // if (this.storeSelfInfo.allowBeep === 1) {
  665. // innerAudioContext.play();
  666. // // plus.device.beep();
  667. // }
  668. // } else if (platform == 'android') {
  669. // if (this.storeSelfInfo.allowVibration === 1) {
  670. // plus.device.vibrate(500);
  671. // }
  672. // if (this.storeSelfInfo.allowBeep === 1) {
  673. // let main = plus.android.runtimeMainActivity();
  674. // let RingtoneManager = plus.android.importClass('android.media.RingtoneManager');
  675. // let uri = RingtoneManager.getActualDefaultRingtoneUri(main, RingtoneManager.TYPE_NOTIFICATION);
  676. // let MediaPlayer = plus.android.importClass('android.media.MediaPlayer');
  677. // let player = MediaPlayer.create(main, uri);
  678. // player.setLooping(false);
  679. // player.prepare();
  680. // player.start();
  681. // }
  682. // }
  683. },
  684. handleNewMessage(newServerMsg) {
  685. console.log("---qxj newServerMsg");
  686. console.log(newServerMsg);
  687. if (this.inCurrentConversation(newServerMsg)) {
  688. const isSingleMessage = newServerMsg.sessionType === SessionType.Single;
  689. if (isSingleMessage) {
  690. uni.$u.throttle(() => uni.$emit(PageEvents.OnlineStateCheck), 2000);
  691. if(newServerMsg.ex!=null&&newServerMsg.ex!=''){
  692. var json=JSON.parse(newServerMsg.ex);
  693. this.$store.commit("timStore/setType",json.type);
  694. this.$store.commit("timStore/setImType", json.imType);
  695. this.$store.commit("timStore/setOrderId",json.orderId);
  696. this.$store.commit("timStore/setOrderType",json.orderType);
  697. this.$store.commit("timStore/setFollowId",json.followId);
  698. if(json.type==="finishInquiry"){
  699. this.$store.commit("timStore/setImType", 0);
  700. uni.navigateTo({ url: "/pages_order/pingOrder?orderId="+json.orderId })
  701. }
  702. else if(json.type==="startInquiry"){
  703. }
  704. else if(json.type==="inquiry"){
  705. }
  706. else if(json.type==="startFollow"){
  707. }
  708. else if(json.type==="follow"){
  709. }
  710. else if(json.type==="finishFollow"){
  711. }
  712. else if(json.type==="startDrugReport"){
  713. }
  714. else if(json.type==="finishDrugReport"){
  715. }
  716. else if(json.type==="drugReport"){
  717. }
  718. }
  719. }
  720. if (newServerMsg.contentType === MessageType.TypingMessage) {
  721. if (isSingleMessage) {
  722. uni.$emit(PageEvents.TypingUpdate);
  723. }
  724. }
  725. else {
  726. if (newServerMsg.contentType === MessageType.RevokeMessage) {
  727. }
  728. else {
  729. newServerMsg.isAppend = true;
  730. this.pushNewMessage(newServerMsg);
  731. setTimeout(() => uni.$emit(PageEvents.ScrollToBottom, true));
  732. }
  733. uni.$u.debounce(this.markConversationAsRead, 2000);
  734. }
  735. }
  736. else {
  737. if (newServerMsg.contentType !== MessageType.TypingMessage) {
  738. console.log("---qxj not inCurrentConversation");
  739. uni.$u.throttle(() => this.newMessageNotify(newServerMsg), 500);
  740. setTimeout(() => {
  741. this.$store.dispatch('conversation/getUnReadCount');
  742. },500);
  743. }
  744. }
  745. },
  746. inCurrentConversation(newServerMsg) {
  747. switch (newServerMsg.sessionType) {
  748. case SessionType.Single:
  749. return (
  750. newServerMsg.sendID === this.storeCurrentConversation.userID ||
  751. (newServerMsg.sendID === this.storeCurrentUserID && newServerMsg.recvID === this.storeCurrentConversation.userID)
  752. );
  753. case SessionType.WorkingGroup:
  754. return newServerMsg.groupID === this.storeCurrentConversation.groupID;
  755. case SessionType.Notification:
  756. return newServerMsg.sendID === this.storeCurrentConversation.userID;
  757. default:
  758. return false;
  759. }
  760. },
  761. markConversationAsRead() {
  762. IMSDK.asyncApi(IMSDK.IMMethods.MarkConversationMessageAsRead, IMSDK.uuid(), this.storeCurrentConversation.conversationID);
  763. },
  764. removeImData(){
  765. uni.removeStorage({ key: 'IMToken' });
  766. uni.removeStorage({ key: 'IMUserID' });
  767. },
  768. getRuntimePlatform() {
  769. const systemInfo = uni.getSystemInfoSync();
  770. const compilePlatform = process.env.UNI_PLATFORM;
  771. //1:iOS,2:Android,3:Windows,4:OSX,5:WEB,6:小程序,7:linux,8:AndroidPad,9:IPad,10:Admin
  772. let platformType=5;
  773. // H5 环境
  774. if (compilePlatform === 'h5') platformType= 5;
  775. // 小程序环境
  776. if (compilePlatform.startsWith('mp-')) {
  777. const mpType = compilePlatform.split('-')[1]; // 如 weixin/alipay
  778. platformType=6;
  779. }
  780. // App 环境
  781. if (compilePlatform === 'app-plus') {
  782. if(systemInfo.platform.toLowerCase() === 'android'){
  783. platformType=2;
  784. }
  785. if(systemInfo.platform.toLowerCase() === 'ios'){
  786. platformType=1;
  787. }
  788. }
  789. console.log("----qxj platformType:"+platformType);
  790. uni.showToast({ title:" platformType:"+platformType,icon:'none', duration: 2000 });
  791. return platformType;
  792. },
  793. }
  794. };
  795. </script>
  796. <style lang="scss">
  797. /*每个页面公共css */
  798. // #ifdef VUE3
  799. @import "@/uni_modules/uview-plus/index.scss";
  800. // #endif
  801. // #ifndef VUE3
  802. @import "uview-ui/index.scss";
  803. // #endif
  804. view{
  805. box-sizing: border-box;
  806. }
  807. .ellipsis{
  808. overflow: hidden;
  809. text-overflow: ellipsis;
  810. white-space: nowrap;
  811. }
  812. .ellipsis2{
  813. overflow:hidden;
  814. text-overflow:ellipsis;
  815. display:-webkit-box;
  816. -webkit-box-orient:vertical;
  817. -webkit-line-clamp:2;
  818. }
  819. .no-data-box{
  820. box-sizing: border-box;
  821. width: 100%;
  822. padding: 200rpx 50rpx;
  823. text-align: center;
  824. flex-direction: column;
  825. justify-content: center;
  826. align-items: center;
  827. image{
  828. width: 200upx;
  829. height: 150upx;
  830. }
  831. .empty-title{
  832. margin-top: 20rpx;
  833. font-size: 28rpx;
  834. color: #bbbbbb;
  835. }
  836. }
  837. .doctor-box{
  838. margin-top: 15rpx;
  839. padding: 20rpx 0rpx 0rpx;
  840. display: flex;
  841. flex-direction: column;
  842. align-items: flex-start;
  843. justify-content: flex-start;
  844. .doctor{
  845. width: 100%;
  846. margin-bottom: 15rpx;
  847. background: #f9f8fe;
  848. padding: 15rpx;
  849. display: flex;
  850. flex-direction: column;
  851. align-items: flex-start;
  852. justify-content: flex-start;
  853. &:last-child{
  854. margin-bottom: 0rpx;
  855. }
  856. .item{
  857. width: 100%;
  858. display: flex;
  859. align-items: flex-start;
  860. justify-content: flex-start;
  861. .left{
  862. .head-box{
  863. width:92rpx;
  864. height:92rpx;
  865. position: relative;
  866. .isline{
  867. width:92rpx;
  868. height:92rpx;
  869. border-radius: 50%;
  870. border: 2rpx solid #E69A22;
  871. display: flex;
  872. align-items: center;
  873. justify-content: center;
  874. position: absolute;
  875. bottom: 0rpx;
  876. .img{
  877. position: absolute;
  878. bottom: 1rpx;
  879. width:75rpx;
  880. height:35rpx;
  881. image{
  882. width:75rpx;
  883. height:35rpx;
  884. }
  885. .name{
  886. width:75rpx;
  887. height:35rpx;
  888. bottom: -3rpx;
  889. text-align: center;
  890. position: absolute;
  891. font-size: 16upx;
  892. font-family: PingFang SC;
  893. font-weight: bold;
  894. color: #ffffff;
  895. }
  896. }
  897. }
  898. .doc-img{
  899. border-radius: 50%;
  900. width:100%;
  901. height:100%;
  902. }
  903. }
  904. }
  905. .right{
  906. width: calc(100% - 100rpx);
  907. margin-left: 20rpx;
  908. display: flex;
  909. flex-direction: column;
  910. align-items: flex-start;
  911. justify-content: flex-start;
  912. .doc-box{
  913. display: flex;
  914. align-items: center;
  915. justify-content: space-between;
  916. .doc-name{
  917. font-size: 32upx;
  918. font-family: PingFang SC;
  919. font-weight: bold;
  920. color: #111111;
  921. }
  922. .doc-position{
  923. margin-left: 16rpx;
  924. font-size: 26upx;
  925. font-weight: bold;
  926. font-family: PingFang SC;
  927. color: #2A2B2E;
  928. }
  929. .doc-dept{
  930. margin-left: 16rpx;
  931. font-size: 26upx;
  932. font-weight: bold;
  933. font-family: PingFang SC;
  934. color: #2A2B2E;
  935. }
  936. }
  937. .hospital-box{
  938. display: flex;
  939. align-items: center;
  940. justify-content: flex-start;
  941. margin-top: 10rpx;
  942. .tag{
  943. display: flex;
  944. align-items: center;
  945. justify-content: center;
  946. background-color: #4FC06B;
  947. border-radius: 10rpx;
  948. padding: 5rpx 10rpx;
  949. font-size: 20upx;
  950. font-weight: bold;
  951. font-family: PingFang SC;
  952. color: #ffffff;
  953. }
  954. .name{
  955. margin-left: 6rpx;
  956. font-size: 26upx;
  957. font-weight: bold;
  958. font-family: PingFang SC;
  959. color: #2A2B2E;
  960. }
  961. }
  962. .doc-spec{
  963. width: 100%;
  964. display: flex;
  965. align-items: center;
  966. justify-content: flex-start;
  967. margin-top: 15rpx;
  968. .spec{
  969. font-size: 26upx;
  970. font-family: PingFang SC;
  971. color: #626468;
  972. }
  973. }
  974. .doc-count{
  975. margin-top: 15rpx;
  976. display: flex;
  977. align-items: center;
  978. justify-content: flex-start;
  979. .name{
  980. font-size: 24upx;
  981. font-family: PingFang SC;
  982. color: #9B9B9B;
  983. }
  984. .count{
  985. margin: 0rpx 5rpx;
  986. font-size: 24upx;
  987. font-family: PingFang SC;
  988. color: #2A2B2E;
  989. }
  990. }
  991. .doc-price{
  992. width: 100%;
  993. margin-top: 15rpx;
  994. display: flex;
  995. align-items: center;
  996. justify-content: flex-start;
  997. .btn{
  998. display: flex;
  999. align-items: center;
  1000. justify-content: center;
  1001. background-color: #FEEFD7;
  1002. padding: 15rpx 30rpx;
  1003. border-radius: 30rpx;
  1004. font-size: 26upx;
  1005. font-family: PingFang SC;
  1006. color: #E69A22;
  1007. }
  1008. }
  1009. }
  1010. }
  1011. }
  1012. }
  1013. </style>
  1014. <style lang="less">
  1015. /*每个页面公共css */
  1016. @import './assets/iconfont/iconfont.css';
  1017. @import './assets/css/common.less';
  1018. /* 全局flex样式 */
  1019. @import './common/css/flexCommon.css';
  1020. </style>