health-education.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <template>
  2. <view>
  3. <view class="header">
  4. <view>{{ memberName }}</view>
  5. <text class="warning">计划阅读:{{ option.ExecDate }}前</text>
  6. <text class="warning" v-if="option.IsRead">
  7. 实际阅读:{{ isAllRead ? '完成' : '未完成' }}
  8. </text>
  9. </view>
  10. <view class="body">
  11. <view v-for="(item, index) in list" :key="index" class="article">
  12. <view class="status" :class="item.IsRead ? 'read' : 'unread'">
  13. {{ item.IsRead ? '已阅读' : '未阅读' }}
  14. </view>
  15. <view class="title">
  16. <text>{{ index + 1 }}、</text>
  17. <text>{{ item.PushContent.Title }}</text>
  18. </view>
  19. <view class="btn" @click="toArticle(item)">
  20. <text>立即阅读</text>
  21. <view class="arrow-right"></view>
  22. </view>
  23. </view>
  24. </view>
  25. </view>
  26. </template>
  27. <script lang="ts" setup>
  28. import { ref, watch } from 'vue';
  29. import Props from './props';
  30. import { PatientRead } from '../../../service';
  31. import { common } from '@kasite/uni-app-base';
  32. import path from '../../../static/path';
  33. const props = defineProps(Props);
  34. const list = ref([]);
  35. const option = ref({} as any);
  36. const isAllRead = ref(0);
  37. const init = async (datas) => {
  38. if (datas && !datas.length) return;
  39. datas.forEach((item) => {
  40. try {
  41. if (typeof item.PushContent == 'string') {
  42. item.PushContent = JSON.parse(item.PushContent);
  43. }
  44. } catch (e) {}
  45. });
  46. let isRead = 1;
  47. for (let i = 0; i < datas.length; i++) {
  48. if (!datas[i].IsRead) {
  49. isRead = 0;
  50. break;
  51. }
  52. }
  53. list.value = datas;
  54. option.value = datas[0];
  55. isAllRead.value = isRead;
  56. };
  57. const toArticle = async (row) => {
  58. const {
  59. PushContent: { Title, Id },
  60. Id: planid,
  61. } = row;
  62. const index = list.value.findIndex((item) => item.Id == planid);
  63. const plan = list.value[index];
  64. let readRes = plan.IsRead;
  65. if (!plan.IsRead) {
  66. const resp = await PatientRead({
  67. Id: planid,
  68. });
  69. readRes = !!resp;
  70. }
  71. list.value[index].IsRead = readRes;
  72. const isAllRead = list.value.reduce((res, item) => {
  73. return res && item.IsRead;
  74. }, true);
  75. const pages = getCurrentPages();
  76. const homePage = pages.find((p: any) => p && p.route && p.route.indexOf('pagesCrm/business/home/home') !== -1);
  77. const target: any = homePage || (pages.length >= 2 ? pages[pages.length - 2] : undefined);
  78. const vm = target && (target as any).$vm;
  79. if (vm && typeof vm.changeItemReadStatus === 'function') {
  80. vm.changeItemReadStatus(props.date, props.index, isAllRead);
  81. } else {
  82. uni.$emit('changeItemReadStatus', { date: props.date, index: props.index, status: isAllRead });
  83. }
  84. common.goToUrl(path.article(Id));
  85. };
  86. watch(
  87. () => props.content,
  88. (v) => {
  89. init(v);
  90. },
  91. {
  92. immediate: true,
  93. deep: true,
  94. }
  95. );
  96. </script>
  97. <style lang="scss" scoped>
  98. @import './common.scss';
  99. .body {
  100. padding: 30rpx;
  101. }
  102. .article {
  103. height: 108rpx;
  104. display: flex;
  105. align-items: center;
  106. justify-content: space-between;
  107. padding: 40rpx 22rpx;
  108. background: #f7f7fb;
  109. border-radius: 16rpx 16rpx 16rpx 16rpx;
  110. margin-bottom: 29rpx;
  111. position: relative;
  112. }
  113. .title {
  114. font-size: 28rpx;
  115. color: #434349;
  116. position: relative;
  117. z-index: 1;
  118. }
  119. .btn {
  120. padding: 20rpx 10rpx;
  121. font-size: 28rpx;
  122. font-weight: normal;
  123. color: var(--uni-color-primary);
  124. background: transparent;
  125. display: inline-flex;
  126. align-items: center;
  127. justify-content: center;
  128. gap: 8rpx;
  129. }
  130. .status {
  131. --is-read: #00a9a9;
  132. --un-read: #f95d3b;
  133. font-size: 20rpx;
  134. color: #fefffe;
  135. padding: 6rpx 13rpx;
  136. position: absolute;
  137. top: 0;
  138. left: 0;
  139. border-radius: 20rpx 20rpx 20rpx 0;
  140. z-index: 0;
  141. }
  142. .status::before {
  143. content: '';
  144. width: 16rpx;
  145. height: 16rpx;
  146. position: absolute;
  147. bottom: -16rpx;
  148. left: 0;
  149. }
  150. .status::after {
  151. content: '';
  152. width: 32rpx;
  153. height: 32rpx;
  154. background-color: #f7f7fb;
  155. position: absolute;
  156. bottom: -32rpx;
  157. left: 0;
  158. border-radius: 32rpx;
  159. }
  160. .status.read,
  161. .status.read::before {
  162. background-color: var(--is-read);
  163. }
  164. .status.unread,
  165. .status.unread::before {
  166. background-color: var(--un-read);
  167. }
  168. .arrow-right {
  169. --width: 13rpx;
  170. --height: 10rpx;
  171. display: inline-block;
  172. width: calc(var(--width));
  173. height: calc(var(--height) * 2);
  174. border-top: var(--height) solid transparent;
  175. border-bottom: var(--height) solid transparent;
  176. border-left: var(--width) solid var(--uni-color-primary);
  177. position: relative;
  178. }
  179. .arrow-right::after {
  180. content: '';
  181. border-top: var(--height) solid transparent;
  182. border-bottom: var(--height) solid transparent;
  183. border-left: var(--width) solid #f7f7fb;
  184. position: absolute;
  185. left: -14rpx;
  186. top: 50%;
  187. transform: translateY(-50%);
  188. }
  189. </style>