questionnaire.vue 4.5 KB

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