details.vue 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. <!--
  2. * @Author: liuzhenlin 461480418@qq.ocm
  3. * @Date: 2023-01-12 11:57:48
  4. * @LastEditors: liuzhenlin
  5. * @LastEditTime: 2023-03-06 15:57:46
  6. * @Description: file content
  7. * @FilePath: \oms\pages\schedule\supervise\details.vue
  8. -->
  9. <template>
  10. <view class="home">
  11. <view class="nav">
  12. <view :style="{ paddingTop }">
  13. <view class="title" :style="[{ height }, { lineHeight: height }]">
  14. <view class="back" @click="goBack()">
  15. <u-icon name="arrow-left" color="#ffffff" size="22"></u-icon>
  16. </view>
  17. <text>督办详情</text>
  18. </view>
  19. </view>
  20. </view>
  21. <view class="main">
  22. <view class="main-top">
  23. <view class="customer-box">
  24. <view class="header flex1">
  25. <view class="name flex_l">
  26. <image class="img" src="@/static/images/menu2.png" mode="scaleToFill" />
  27. <text>{{ details.taskTitle }}</text>
  28. </view>
  29. <view class="date">{{ parseTime(details.taskStartDate, '{y}-{m}-{d} {h}:{i}') || '-' }}</view>
  30. </view>
  31. <view class="info">
  32. <view class="info-item">
  33. <u-row>
  34. <u-col span="6">
  35. <view class="flex_l">
  36. <view class="info-label">督办类型:</view>
  37. <text class="info-txt">{{ selectDictLabel(taskTypeOption, details.taskType) }}</text>
  38. </view>
  39. </u-col>
  40. <u-col span="6">
  41. <view class="flex_l">
  42. <view class="info-label">督办状态:</view>
  43. <text class="info-txt">{{ selectDictLabel(taskStatusOption, details.taskStatus) }}</text>
  44. </view>
  45. </u-col>
  46. </u-row>
  47. </view>
  48. <view class="info-item">
  49. <u-row justify="space-between">
  50. <u-col span="6">
  51. <view class="flex_l">
  52. <view class="info-label">是否超期:</view>
  53. <text class="info-txt">
  54. {{ isNotOverdue(parseTime(details.taskEndDate, '{y}-{m}-{d} 23:59:59')) ? '否' : '是' }}
  55. </text>
  56. </view>
  57. </u-col>
  58. <u-col span="6">
  59. <view class="flex_l">
  60. <view class="info-label">事项来源:</view>
  61. <text class="info-txt">{{ selectDictLabel(sourceOption, details.source) }}</text>
  62. </view>
  63. </u-col>
  64. </u-row>
  65. </view>
  66. </view>
  67. </view>
  68. <view class="tabs">
  69. <u-tabs
  70. @change="changeTabs"
  71. :current="curTabIndex"
  72. :scrollable="false"
  73. :list="list"
  74. :activeStyle="{
  75. color: '#3E7EF8',
  76. fontWeight: 'bold',
  77. }"
  78. :inactiveStyle="{
  79. color: '#969696',
  80. }"></u-tabs>
  81. </view>
  82. </view>
  83. <view class="data-list">
  84. <task-details
  85. v-if="curTabIndex == 0"
  86. :detail="details"
  87. :taskTypeOption="taskTypeOption"
  88. :sourceOption="sourceOption"
  89. :userList="userList"></task-details>
  90. </view>
  91. </view>
  92. <!-- 新增按钮 -->
  93. <view class="fixed-btn-group" :style="{ width: openBtnWidth ? '480rpx' : '90rpx' }">
  94. <view class="flex1" v-if="openBtnWidth">
  95. <view class="btn center" @click="linkToLevel(1)">升</view>
  96. </view>
  97. <view class="btn center" @click="openBtnWidth = !openBtnWidth">
  98. <u-icon name="plus" color="#fff" size="20"></u-icon>
  99. </view>
  100. </view>
  101. </view>
  102. </template>
  103. <script>
  104. import taskApi from '@/api/task'
  105. import userApi from '@/api/system/user'
  106. import to from 'await-to-js'
  107. import TaskDetails from './components/taskDetails'
  108. export default {
  109. name: 'omsIndex',
  110. components: { TaskDetails },
  111. data() {
  112. return {
  113. openBtnWidth: false,
  114. height: '',
  115. paddingTop: '',
  116. curTabIndex: 0,
  117. list: [
  118. {
  119. name: '详细信息',
  120. index: 0,
  121. },
  122. {
  123. name: '进展情况',
  124. index: 1,
  125. },
  126. {
  127. name: '联系人',
  128. index: 2,
  129. },
  130. ],
  131. taskId: 0, //项目id
  132. details: {}, //督办列表
  133. taskTypeOption: [], //督办类型
  134. sourceOption: [], //来源列表
  135. userList: [], //用户列表
  136. taskStatusOption: [
  137. {
  138. key: '10',
  139. value: '发起',
  140. },
  141. {
  142. key: '20',
  143. value: '进行中',
  144. },
  145. {
  146. key: '30',
  147. value: '流程完成',
  148. },
  149. {
  150. key: '40',
  151. value: '审批拒绝',
  152. },
  153. {
  154. key: '50',
  155. value: '撤销',
  156. },
  157. ], //督办状态
  158. }
  159. },
  160. onLoad(option) {
  161. this.taskId = option.id
  162. this.getOptions()
  163. },
  164. created() {
  165. const navData = uni.getMenuButtonBoundingClientRect()
  166. this.height = navData.height + 'px'
  167. this.paddingTop = navData.top + 'px'
  168. },
  169. onShow() {
  170. this.getOptions()
  171. },
  172. methods: {
  173. // 改变tab
  174. changeTabs(data) {
  175. this.curTabIndex = data.index
  176. },
  177. getOptions() {
  178. Promise.all([this.getDicts('task_type'), this.getDicts('plat_task_source'), userApi.getList()])
  179. .then(([types, source, user]) => {
  180. this.taskTypeOption = types.data.values || []
  181. this.sourceOption = source.data.values || []
  182. this.userList = user.data.list.map((item) => ({ key: '' + item.id, value: item.nickName }))
  183. this.getDetails()
  184. })
  185. .catch((err) => console.log(err))
  186. },
  187. // 判断是否没有超期
  188. isNotOverdue(date) {
  189. return new Date() <= new Date(date)
  190. },
  191. // 协办人
  192. generateOwnerUser(ids = null) {
  193. let nameArr = []
  194. if (ids) {
  195. let idList = ids.split(',')
  196. console.log(idList)
  197. idList.forEach((item) => {
  198. let findUser = this.userList.find((user) => user.key == item)
  199. console.log(findUser)
  200. if (findUser.value) nameArr.push(findUser.value)
  201. })
  202. }
  203. return nameArr.join(',')
  204. },
  205. async getDetails() {
  206. let params = {
  207. taskId: this.taskId,
  208. }
  209. const [err, res] = await to(taskApi.getList(params))
  210. if (err) {
  211. return
  212. }
  213. if (res && res.code == 200) {
  214. this.details = res.data.list[0] || {}
  215. }
  216. },
  217. goBack() {
  218. uni.navigateBack({
  219. //关闭当前页面,返回上一页面或多级页面。
  220. delta: 1,
  221. })
  222. },
  223. },
  224. }
  225. </script>
  226. <style>
  227. page {
  228. background: #f2f3f5;
  229. }
  230. </style>
  231. <style lang="scss" scoped>
  232. .home {
  233. padding-top: 200rpx;
  234. .nav {
  235. position: absolute;
  236. left: 0;
  237. top: 0;
  238. width: 100%;
  239. height: 356rpx;
  240. background: #3e7ef8;
  241. border-radius: 0 0 31rpx 31rpx;
  242. .title {
  243. position: relative;
  244. text-align: center;
  245. font-size: 32rpx;
  246. font-weight: bold;
  247. color: #ffffff;
  248. .back {
  249. position: absolute;
  250. top: 0;
  251. bottom: 0;
  252. margin: auto;
  253. left: 70rpx;
  254. display: flex;
  255. }
  256. }
  257. }
  258. .main {
  259. position: absolute;
  260. width: 100%;
  261. height: calc(100vh - 200rpx);
  262. overflow: hidden;
  263. padding-bottom: 64rpx;
  264. .main-top {
  265. padding: 0 32rpx;
  266. }
  267. .customer-box {
  268. width: 100%;
  269. background: #ffffff;
  270. box-shadow: 0 6rpx 19rpx 2rpx rgba(0, 45, 132, 0.15);
  271. border-radius: 32rpx;
  272. padding: 22rpx 38rpx 68rpx 40rpx;
  273. .header {
  274. .name {
  275. .img {
  276. width: 46rpx;
  277. height: 46rpx;
  278. border-radius: 50%;
  279. margin-right: 8rpx;
  280. }
  281. text {
  282. font-size: 28rpx;
  283. font-weight: bold;
  284. color: #323232;
  285. }
  286. }
  287. .date {
  288. font-size: 24rpx;
  289. color: #3e7ef8;
  290. }
  291. }
  292. .info {
  293. .info-item {
  294. margin-top: 18rpx;
  295. .info-label {
  296. width: 120rpx;
  297. text-align: left;
  298. font-size: 24rpx;
  299. color: #646464;
  300. }
  301. .info-txt {
  302. flex: 1;
  303. font-size: 24rpx;
  304. color: #323232;
  305. }
  306. }
  307. }
  308. }
  309. .data-list {
  310. margin-top: 16rpx;
  311. width: 100%;
  312. height: calc(100vh - 532rpx);
  313. background: #ffffff;
  314. padding: 32rpx;
  315. overflow: auto;
  316. padding-bottom: 145rpx;
  317. }
  318. .details-wrap {
  319. background: #f6f7fb;
  320. border: 1px solid #ceccca;
  321. border-radius: 20rpx;
  322. margin-bottom: 32rpx;
  323. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
  324. .header {
  325. padding: 30rpx 30rpx 15rpx;
  326. border-bottom: 2rpx solid #ceccca;
  327. }
  328. .content {
  329. padding: 15rpx 30rpx 30rpx;
  330. }
  331. }
  332. }
  333. .fixed-btn-group {
  334. position: fixed;
  335. display: flex;
  336. justify-content: space-around;
  337. align-items: center;
  338. width: 90rpx;
  339. height: 90rpx;
  340. bottom: 50rpx;
  341. right: 50rpx;
  342. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  343. border-radius: 20px;
  344. transition: all 0.2s;
  345. background: #fff;
  346. .red {
  347. background: #ff4d4f !important;
  348. }
  349. .btn {
  350. width: 60rpx;
  351. height: 60rpx;
  352. background: #3e7ef8;
  353. border-radius: 50%;
  354. margin: 10rpx;
  355. font-size: 26rpx;
  356. font-weight: bold;
  357. color: #ffffff;
  358. }
  359. }
  360. }
  361. </style>