details.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <template>
  2. <u-navbar :titleStyle="{ color: '#000' }" :autoBack="true" :title="dataList[0]?.createBy + '的日报'" :placeholder="true" :safeAreaInsetTop="true" bgColor="#fff">
  3. <template #left>
  4. <view class="u-navbar__content__left__item">
  5. <u-icon name="arrow-left" size="20" color="#000"></u-icon>
  6. </view>
  7. </template>
  8. </u-navbar>
  9. <oa-scroll
  10. customClass="record-details-container scroll-height"
  11. :style="{
  12. //#ifdef APP-PLUS || MP-WEIXIN
  13. height: `calc(100vh - (44px + ${proxy.$settingStore.StatusBarHeight}))`,
  14. //#endif
  15. }"
  16. :refresherLoad="false"
  17. :refresherEnabled="false"
  18. :refresherEnabledTitle="false"
  19. :refresherDefaultStyle="'none'"
  20. :refresherThreshold="44"
  21. :refresherBackground="'#f5f6f7'"
  22. :data-theme="'theme-' + proxy.$settingStore.themeColor.name"
  23. >
  24. <template #default>
  25. <view class="content-area radius bg-white" v-for="(item, index) in dataList" :key="index">
  26. <view class="content-area-header flex mb10">
  27. <img :src="item.avatar" class="content-area-header-avatarImg mr10" v-if="item.avatar" />
  28. <u-avatar
  29. v-if="!item.avatar"
  30. class="content-area-header-avatar mr10"
  31. :text="item.createBy.length > 2 ? item.createBy.slice(1, 3) : item.createBy"
  32. shape="square"
  33. size="40"
  34. fontSize="12"
  35. color="#ffffff"
  36. :bgColor="proxy.$settingStore.themeColor.color"
  37. ></u-avatar>
  38. <view>
  39. <view class="content-area-header-title font16 mb5">{{ item.createBy ? item.createBy : " " }} {{ item.submitDate.slice(0, 10) != item.reportDate ? "( " + item.reportDate + " )" : "" }}</view>
  40. <view class="content-area-header-time font14">{{ item.submitDate ? item.submitDate.replace("T", " ") : " " }}</view>
  41. </view>
  42. </view>
  43. <view class="content-area-center mb10" v-for="child in item.workContents" :key="child">
  44. <view class="content-area-center-top flex">
  45. <view class="content-area-center-top-title mr10" style="color: #559aff" @click="toProjectMange(child.projectId)">{{ child.projectName ? child.projectName : " " }}</view>
  46. <view class="content-area-center-top-time" :style="{ color: proxy.$settingStore.themeColor.color }">{{ child.workTime }}h</view>
  47. </view>
  48. <u-text :text="child.workContent" color="#000000" size="14"></u-text>
  49. </view>
  50. <view class="content-area-center mb10">
  51. <view class="content-area-center-top"> 明日计划 </view>
  52. <u-text :text="item.tomorrowPlan ? item.tomorrowPlan : '无'" color="#000000" size="14"></u-text>
  53. </view>
  54. <view class="content-area-center mb10">
  55. <view class="content-area-center-top"> 工作协调 </view>
  56. <u-text :text="item.coordinateWork ? item.coordinateWork : '无'" color="#000000" size="14"></u-text>
  57. </view>
  58. <view class="content-area-center mb10">
  59. <view class="content-area-center-top">图片</view>
  60. <view class="imageBox" v-if="JSON.parse(item.reportImage) && JSON.parse(item.reportImage).length > 0">
  61. <image class="image m5" style="width: 50px" mode="widthFix" v-for="(a, index) in JSON.parse(item.reportImage)" :key="index" :src="a.url" @click="previewImage(index)" />
  62. </view>
  63. <view class="imageBox" v-else>无</view>
  64. </view>
  65. <view class="content-area-center mb10">
  66. <view class="content-area-center-top">附件 </view>
  67. <view v-if="JSON.parse(item.reportFile) && JSON.parse(item.reportFile).length > 0">
  68. <uni-link v-for="(file, index) in JSON.parse(item.reportFile)" :key="index" :href="file.url" text="file.url" style="color: rgba(0, 0, 0, 0.7)">{{ file.name }}</uni-link>
  69. </view>
  70. <view v-else>无</view>
  71. </view>
  72. <view class="content-area-center mb10" style="display: flex; flex-wrap: wrap">
  73. <u-tabs
  74. :list="tabsList"
  75. :current="tabsCurrent"
  76. @click="tabsClick"
  77. lineColor="#333"
  78. :activeStyle="{ color: '#333', fontSize: '14px' }"
  79. :inactiveStyle="{ color: '#909399', fontSize: '14px' }"
  80. :scrollable="false"
  81. style="width: 100%"
  82. ></u-tabs>
  83. <view class="content-area-header mt20 mb10 text-center" style="display: inline-block" v-for="(item, index) in reportDetailData.treeSelectNodes" :key="index">
  84. <img v-if="item.avatar" class="content-area-header-avatarImg mlr5" :src="item.avatar" style="display: block; width: 40px; height: 40px" />
  85. <u-avatar
  86. v-if="!item.avatar"
  87. class="content-area-header-avatar mlr5"
  88. :text="item.nickName.length > 2 ? item.nickName.slice(1, 3) : item.nickName"
  89. shape="square"
  90. size="40"
  91. fontSize="12"
  92. color="#ffffff"
  93. :bgColor="proxy.$settingStore.themeColor.color"
  94. ></u-avatar>
  95. <u-text :text="item.nickName" color="#000000" size="14" align="center"></u-text>
  96. </view>
  97. </view>
  98. </view>
  99. </template>
  100. </oa-scroll>
  101. </template>
  102. <script setup>
  103. /*----------------------------------依赖引入-----------------------------------*/
  104. import { onLoad, onShow, onReady, onHide, onLaunch, onBackPress, onUnload, onNavigationBarButtonTap, onPageScroll } from "@dcloudio/uni-app";
  105. import { ref, reactive, computed, getCurrentInstance, toRefs, inject } from "vue";
  106. /*----------------------------------接口引入-----------------------------------*/
  107. import { projectApi } from "@/api/business/project.js";
  108. import { dUserList } from "@/api/system/user.js";
  109. import { deptUserTreeSelect } from "@/api/system/user.js";
  110. /*----------------------------------组件引入-----------------------------------*/
  111. /*----------------------------------store引入-----------------------------------*/
  112. /*----------------------------------公共方法引入-----------------------------------*/
  113. /*----------------------------------公共变量-----------------------------------*/
  114. const { proxy } = getCurrentInstance();
  115. /*----------------------------------变量声明-----------------------------------*/
  116. const tree = ref({
  117. value: "tree_root",
  118. label: "Root",
  119. children: [],
  120. });
  121. const reportDetailData = ref([]);
  122. const pmReportReaders = ref([]); //已读未读集合
  123. const state = reactive({
  124. loading: true,
  125. dataList: [], //日报列表
  126. options: {
  127. //日报详情参数
  128. reportId: "",
  129. },
  130. userData: [], //用户列表
  131. images: [], //图片列表
  132. files: [], //附件列表
  133. tabsList: [
  134. { name: "已读", value: 0 },
  135. { name: "未读", value: 1 },
  136. ],
  137. tabsCurrent: 0,
  138. });
  139. const { dataList, userData, tabsList, tabsCurrent } = toRefs(state);
  140. /**
  141. * @tabs点击事件
  142. */
  143. function tabsClick(e) {
  144. state.tabsCurrent = e.index;
  145. reportDetailData.value.treeSelectNodes = proxy.$common.findTreeNodes(tree.value, state.tabsCurrent == 0 ? pmReportReaders.value.readAlready : pmReportReaders.value.readNotAlready);
  146. }
  147. function previewImage(index) {
  148. uni.previewImage({
  149. current: index, // 当前显示图片索引
  150. urls: state.images, // 需要预览的图片http链接列表
  151. });
  152. }
  153. /**
  154. * @初始化
  155. */
  156. function init() {
  157. dataList.value = [];
  158. state.loading = true;
  159. /** 查询树结构用户列表 回显抄送人*/
  160. deptUserTreeSelect({ pageNum: "1", pageSize: "1000" }).then((res) => {
  161. tree.value = res.data;
  162. projectApi()
  163. .ReportRecord({
  164. reportId: state.options.reportId,
  165. pageNum: 1,
  166. pageSize: 1,
  167. })
  168. .then((requset) => {
  169. dataList.value = requset.data.records;
  170. state.loading = false;
  171. pmReportReaders.value = requset.data.records[0].pmReportReaders;
  172. state.tabsList[0].name = state.tabsList[0].name + "(" + pmReportReaders.value.read + ")";
  173. state.tabsList[1].name = state.tabsList[1].name + "(" + pmReportReaders.value.unRead + ")";
  174. reportDetailData.value.treeSelectNodes = proxy.$common.findTreeNodes(tree.value, tabsCurrent.value == 0 ? pmReportReaders.value.readAlready : pmReportReaders.value.readNotAlready);
  175. var imgs = JSON.parse(dataList.value[0].reportImage);
  176. var files = JSON.parse(dataList.value[0].reportFile);
  177. imgs.forEach(function (item) {
  178. state.images.push(item.url);
  179. });
  180. files.forEach(function (item) {
  181. state.files.push(item.url);
  182. });
  183. })
  184. .catch((err) => {
  185. state.loading = false;
  186. });
  187. });
  188. }
  189. /**
  190. * 跳转项目概览
  191. * @param id 项目id
  192. */
  193. function toProjectMange(id) {
  194. proxy.$tab.navigateTo(`/pages/business/common/projectMange/overview/index?id=${id}`);
  195. }
  196. onReady(() => {});
  197. onShow(() => {
  198. //调用系统主题颜色
  199. proxy.$settingStore.systemThemeColor([1]);
  200. });
  201. onLoad((options) => {
  202. state.options.reportId = options?.reportId;
  203. init();
  204. });
  205. onUnload(() => {
  206. projectApi()
  207. .ReportRecordReadFlag({ reportId: state.options.reportId })
  208. .then((requset) => {
  209. uni.$emit("projectMange_record", true); //监听器
  210. })
  211. .catch((err) => {
  212. uni.$emit("projectMange_record", true); //监听器
  213. });
  214. });
  215. </script>
  216. <style lang="scss" scoped>
  217. .content-area {
  218. margin: 0;
  219. padding: 15px 20px;
  220. overflow: hidden;
  221. &-header {
  222. &-avatar {
  223. margin: auto 0;
  224. }
  225. &-avatarImg {
  226. width: 35px;
  227. height: 35px;
  228. border-radius: 4px;
  229. }
  230. &-title {
  231. margin: 0 0 15px 0;
  232. font-weight: 600;
  233. color: #000000;
  234. }
  235. }
  236. &-center {
  237. line-height: 25px;
  238. &-top {
  239. color: #000000;
  240. font-weight: 600;
  241. }
  242. }
  243. }
  244. </style>