details.vue 11 KB

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