inspectionScanning.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <template>
  2. <view class="incidentList">
  3. <view class="title">{{dataInfo.inspectionNodeName}}</view>
  4. <view class="head">
  5. <view class="tab" :class="{active: tab.id === dataInfo.tabActiveId}" v-for="tab in dataInfo.tabs" :key="tab.id" @click="clickTab(tab.id)">
  6. {{tab.name}}<text v-if="tab.num !== ''">({{tab.num}})</text>
  7. </view>
  8. </view>
  9. <view class="body" v-if="dataInfo.list.length">
  10. <view class="body_item" v-for="data in dataInfo.list" :key="data.id" @click="toInspectionTaskDetail(data)">
  11. <view class="body_item_head ellipsis-multiline">
  12. <text class="sign" v-if="data.status.value == 2" :class="{signRed: data.exception == 1}">{{data.exception == 1 ? '异常' : '正常'}}</text>{{ data.inspectionDTO?.inspectionFormDTO?.name }}-{{ data.inspectionNodeDTO?.name }}-{{ data.batchNo }}
  13. </view>
  14. <view class="body_item_content">
  15. <view class="body_item_content_p" v-if="data.inspectionDTO">
  16. <text class="name ellipsis">计划标题:{{data.inspectionDTO.name}}</text>
  17. </view>
  18. <view class="body_item_content_p" v-if="data.signType">
  19. <text class="name ellipsis">签到方式:{{data.signType.name}}</text>
  20. </view>
  21. <view class="body_item_content_p" v-if="data.userDTO || data.groupDTO">
  22. <text class="name ellipsis">执行人或组:{{ data.userDTO?.name || data.groupDTO?.groupName }}</text>
  23. </view>
  24. <view class="body_item_content_p" v-if="data.status || data.addTime">
  25. <text class="name ellipsis">状态:{{ data.status?.name}}</text>
  26. <text class="date">{{formatDate(data.addTime, 'yyyy-MM-dd HH:mm')}}</text>
  27. </view>
  28. <view class="body_item_content_p" v-if="data.incidentDTO">
  29. <text class="name ellipsis">故障单号:{{ data.incidentDTO.incidentsign}}</text>
  30. <text class="date">{{ data.incidentDTO.state?.name}}</text>
  31. </view>
  32. </view>
  33. <view class="body_item_foot">
  34. <view class="btns pt0">
  35. <button v-if="data.status.value === '1' && dataInfo.tabActiveId === 0" @click.stop="toInspectionValue(data)" type="default" class="primaryButton btn">执行</button>
  36. <button v-if="data.status.value === '2' && data.exception == 1 && !data.incidentId && data.inspectionDTO.inspectionFormDTO.showOrder == 1" @click.stop="toBuildIncident(data)" type="default" class="primaryButton btn">生成维修单</button>
  37. </view>
  38. </view>
  39. </view>
  40. </view>
  41. <view class="zanwu" v-else>
  42. <text class="newicon newicon-zanwu"></text>
  43. </view>
  44. </view>
  45. </template>
  46. <script setup>
  47. import { startOfDay, endOfDay, format, add } from 'date-fns'
  48. import { ref, reactive, computed } from 'vue'
  49. import { onLoad, onPullDownRefresh, onReachBottom, onTabItemTap } from '@dcloudio/uni-app'
  50. import { SM } from "@/http/http.js"
  51. import { api_getDictionary, api_inspectionTask, api_listCount, api_scanCode, api_inspectionNode, api_listAttachment } from "@/http/api.js"
  52. import { filterFormatDate } from '@/filters/filterFormatDate.js'
  53. import { computedPriorityStyle } from '@/filters/computedPriorityStyle.js'
  54. import { computedStateStyle } from '@/filters/computedStateStyle.js'
  55. import { computedCurrentLogOverTime } from '@/filters/computedCurrentLogOverTime.js'
  56. import { defaultColor } from '@/static/js/theme.js'
  57. import { useSetTitle } from '@/share/useSetTitle.js'
  58. import { useMakePhoneCall } from '@/share/useMakePhoneCall.js'
  59. import { useLoginUserStore } from '@/stores/loginUser'
  60. import { useIncidentNumStore } from '@/stores/incidentNum'
  61. import { useInspectionListSearchStore } from '@/stores/inspectionListSearch'
  62. import { useInspectionValueStore } from '@/stores/inspectionValue'
  63. import { useSetTabbar } from '@/share/useSetTabbar.js'
  64. import { useIncidentBuildStore } from '@/stores/incidentBuild'
  65. useSetTitle();
  66. const loginUserStore = useLoginUserStore();
  67. const incidentNumStore = useIncidentNumStore();
  68. const inspectionListSearchStore = useInspectionListSearchStore();
  69. const inspectionValueStore = useInspectionValueStore();
  70. const { formatDate } = filterFormatDate();
  71. const { priorityStyle } = computedPriorityStyle();
  72. const { stateStyle } = computedStateStyle();
  73. const { currentLogOverTime } = computedCurrentLogOverTime();
  74. const { makePhoneCall } = useMakePhoneCall();
  75. const { setTabbar } = useSetTabbar();
  76. const incidentBuildStore = useIncidentBuildStore();
  77. // 主题颜色
  78. const primaryColor = ref(defaultColor)
  79. // 故障来源列表
  80. const defaultSourceValue = ref();
  81. // 数据
  82. const dataInfo = reactive({
  83. tabs: [{id: 0, name: '巡检工单', value: 'todo', num: ''}, {id: 1, name: '历史工单', value: '', num: ''}],
  84. tabActiveId: 0,//当前选择的tab
  85. list: [],//工单列表
  86. idx: 0,//页码
  87. hasMore: true,//是否有更多数据
  88. inspectionNodeDTO: {},
  89. inspectionNodeNewCode: '',//巡检点二维码
  90. inspectionNodeCode: '',//巡检点原始二维码
  91. inspectionNodeName: '',
  92. })
  93. // 详情
  94. function toInspectionTaskDetail(data){
  95. uni.navigateTo({
  96. url: `/pages/inspection/inspectionDetail/inspectionDetail?inspectionTaskId=${data.id}`
  97. })
  98. }
  99. // 获取故障来源列表
  100. function getSources(){
  101. let postData = {
  102. "key": 'incident_source',
  103. "type": "list",
  104. };
  105. api_getDictionary(postData).then(res => {
  106. res = res || [];
  107. let discover = res.find(v => v.value === 'inspection');
  108. if(discover){
  109. defaultSourceValue.value = discover.id;
  110. }
  111. })
  112. }
  113. // 新建事件
  114. async function toBuildIncident(res){
  115. incidentBuildStore.clearIncidentBuildData();
  116. let imgObj = res.inspectionFormValuesList.find(v => v.inspectionFormItemDTO.type.value == 7);
  117. let repairImgList = [];
  118. if(imgObj){
  119. let result = await api_listAttachment('inspection', res.id);
  120. result.data = result.data || [];
  121. result.data = result.data.filter(v => v.recordId == imgObj.itemId);
  122. result.data = result.data.map(v => ({
  123. url: location.origin + "/file" + v.relativeFilePath,
  124. path: location.origin + "/file" + v.relativeFilePath,
  125. size: v.size,
  126. name: v.name,
  127. extname: v.suffix,
  128. }))
  129. repairImgList = result.data;
  130. }
  131. console.log(repairImgList, 'repairImgList')
  132. let incidentData = {
  133. place: res.inspectionNodeDTO.floorDTO,
  134. houseNumber: res.inspectionNodeDTO.address,
  135. source: defaultSourceValue.value,
  136. description: res.inspectionFormValuesList.filter(v => v.exception == 1).map(v => `${v.name}填写值为${v.valuex ? v.valuex : (v.formItemConfigList ? v.formItemConfigList.map(vv => vv.name).join(',') : '')}`).join(';'),
  137. requester: loginUserStore.loginUser.user,
  138. branch: loginUserStore.loginUser.user.currentHospital.parent ? loginUserStore.loginUser.user.currentHospital.parent.id : loginUserStore.loginUser.user.currentHospital.id,
  139. contacts: loginUserStore.loginUser.user.name,
  140. contactsInformation: loginUserStore.loginUser.user.phone,
  141. category: res.inspectionDTO.inspectionFormDTO.categoryDTO,
  142. department: res.inspectionDTO.inspectionFormDTO.repairDeptDTO,
  143. priority: res.inspectionDTO.inspectionFormDTO.priorityDTO,
  144. repairImgList,
  145. inspectionTaskId: res.id,
  146. }
  147. console.log(incidentData, 'incidentData')
  148. incidentBuildStore.setIncidentBuildData(incidentData, 'buildIncident');
  149. uni.navigateTo({
  150. url: `/pages/buildIncident/buildIncident?type=inspection`
  151. })
  152. }
  153. // 巡检项
  154. function toInspectionValue(data){
  155. uni.showLoading({
  156. title: "加载中",
  157. mask: true,
  158. });
  159. let postData = {
  160. code: dataInfo.inspectionNodeNewCode,
  161. taskId: data.id,
  162. account: loginUserStore.loginUser.user.account,
  163. };
  164. // 'inspection|$|1bd0c704-0962-4ed4-b5a6-b5bda3d78231'
  165. // 'inspection|$|bc9f61af-99c8-4c86-88f9-f29dd3fc43c0'
  166. // 'inspection|$|92e7bb9a-5f58-42f6-991a-fcd67247e295'
  167. api_scanCode(postData).then((res) => {
  168. uni.hideLoading();
  169. if (res.status == 200) {
  170. inspectionValueStore.setInspectionValueData(res.data);
  171. uni.navigateTo({
  172. url: `/pages/inspection/inspectionValue/inspectionValue?inspectionExecuteId=${data.id}`
  173. })
  174. } else {
  175. uni.showToast({
  176. icon: 'none',
  177. title: res.msg || '请求数据失败!'
  178. });
  179. }
  180. });
  181. }
  182. // 点击tab
  183. function clickTab(tabId){
  184. dataInfo.tabActiveId = tabId;
  185. getList(0);
  186. }
  187. // 获取列表信息
  188. function getList(idx){
  189. uni.showLoading({
  190. title: "加载中",
  191. mask: true,
  192. });
  193. dataInfo.idx = idx === undefined ? dataInfo.idx : idx;
  194. if(dataInfo.idx === 0){
  195. dataInfo.list = [];
  196. }
  197. let tabActiveObj = dataInfo.tabs.find(v => v.id == dataInfo.tabActiveId);
  198. let tabActiveObjIndex = dataInfo.tabs.findIndex(v => v.id == dataInfo.tabActiveId);
  199. let postData = {
  200. "idx": dataInfo.idx,
  201. "sum": 10,
  202. "inspectionTask": {
  203. "queryTask": tabActiveObj.value || undefined,
  204. "status": tabActiveObj.value ? undefined : { "value": 2 },
  205. "assignAccount": tabActiveObj.id == 0 ? loginUserStore.loginUser.user.account : undefined,
  206. "inspectionNodeDTO":{
  207. code: dataInfo.inspectionNodeCode,
  208. }
  209. }
  210. }
  211. api_inspectionTask(postData).then(res => {
  212. uni.hideLoading();
  213. uni.stopPullDownRefresh();
  214. if(res.status == 200){
  215. let list = res.list || [];
  216. dataInfo.tabs[tabActiveObjIndex].num = res.totalNum;
  217. if(list.length){
  218. dataInfo.hasMore = true;
  219. dataInfo.list = dataInfo.idx === 0 ? list : dataInfo.list.concat(list);
  220. dataInfo.inspectionNodeDTO = list[0].inspectionNodeDTO;
  221. }else{
  222. dataInfo.hasMore = false;
  223. dataInfo.inspectionNodeDTO = {};
  224. }
  225. }else{
  226. uni.showToast({
  227. icon: 'none',
  228. title: res.msg || '请求数据失败!'
  229. });
  230. }
  231. })
  232. getCount(tabActiveObj.id);
  233. }
  234. // 获取列表数量
  235. function getCount(id){
  236. dataInfo.tabs.forEach(v => {
  237. if(v.id != id){
  238. let tabActiveObj = v;
  239. let postData = {
  240. "idx": 0,
  241. "sum": 1,
  242. "inspectionTask": {
  243. "queryTask": tabActiveObj.value || undefined,
  244. "status": tabActiveObj.value ? undefined : { "value": 2 },
  245. "assignAccount": tabActiveObj.id == 0 ? loginUserStore.loginUser.user.account : undefined,
  246. "inspectionNodeDTO":{
  247. code: dataInfo.inspectionNodeCode,
  248. }
  249. }
  250. }
  251. api_inspectionTask(postData).then(res => {
  252. if(res.status == 200){
  253. v.num = res.totalNum;
  254. }else{
  255. uni.showToast({
  256. icon: 'none',
  257. title: res.msg || '请求数据失败!'
  258. });
  259. }
  260. })
  261. }
  262. })
  263. }
  264. onLoad((option) => {
  265. getSources();
  266. dataInfo.inspectionNodeCode = option.inspectionNodeCode;
  267. dataInfo.inspectionNodeNewCode = option.inspectionNodeNewCode;
  268. dataInfo.inspectionNodeName = option.inspectionNodeName;
  269. getList(0);
  270. })
  271. onPullDownRefresh(() => {
  272. getList(0)
  273. })
  274. onReachBottom(() => {
  275. dataInfo.idx += 1;
  276. if (dataInfo.hasMore) {
  277. getList(); // 当触底时加载更多数据
  278. }
  279. })
  280. </script>
  281. <style lang="scss" scoped>
  282. .toolbar {
  283. position: fixed;
  284. left: 0;
  285. bottom: var(--window-bottom);
  286. z-index: 99;
  287. width: 100%;
  288. height: 88rpx;
  289. display: flex;
  290. justify-content: center;
  291. align-items: center;
  292. box-sizing: border-box;
  293. border-radius: 4rpx;
  294. background-color: #E5E8ED;
  295. .toolbar-icon {
  296. font-size: 52rpx;
  297. margin-right: 16rpx;
  298. color: #49B856;
  299. }
  300. .toolbar-sao {
  301. font-size: 36rpx;
  302. color: #333;
  303. }
  304. }
  305. .incidentList{
  306. display: flex;
  307. flex-direction: column;
  308. justify-content: space-between;
  309. .title{
  310. width: 100%;
  311. height: 88rpx;
  312. position: fixed;
  313. z-index: 99;
  314. display: flex;
  315. align-items: center;
  316. justify-content: center;
  317. background-color: #EBEBEB;
  318. font-weight: bold;
  319. font-size: 32rpx;
  320. }
  321. .head{
  322. height: 88rpx;
  323. display: flex;
  324. top: 88rpx;
  325. position: fixed;
  326. z-index: 99;
  327. width: 100%;
  328. background-color: #fff;
  329. font-size: 30rpx;
  330. .tab{
  331. flex: 1;
  332. display: flex;
  333. justify-content: center;
  334. align-items: center;
  335. border-bottom: 4rpx solid transparent;
  336. &.active{
  337. color: $uni-primary;
  338. border-color: $uni-primary;
  339. }
  340. }
  341. .filter{
  342. width: 84rpx;
  343. display: flex;
  344. justify-content: center;
  345. align-items: center;
  346. .newicon-shaixuan{
  347. font-size: 36rpx;
  348. color: #2C2C2C;
  349. }
  350. }
  351. }
  352. .body{
  353. margin-top: 176rpx;
  354. border-top: 6rpx solid #EBEBEB;
  355. .body_item{
  356. border-bottom: 8rpx solid #EBEBEB;
  357. .body_item_head{
  358. word-break: break-all;
  359. text-align: justify;
  360. text-align: left;
  361. margin: 24rpx;
  362. font-size: 30rpx;
  363. .sign{
  364. margin-right: 16rpx;
  365. font-weight: bold;
  366. color: #49B856;
  367. &.signRed{
  368. color: #FF0000;
  369. }
  370. }
  371. }
  372. .body_item_content{
  373. border-top: 1rpx solid #D8D8D8;
  374. padding: 24rpx 24rpx 24rpx 48rpx;
  375. .body_item_content_p{
  376. color: #6A6A6A;
  377. font-size: 26rpx;
  378. display: flex;
  379. justify-content: space-between;
  380. align-items: center;
  381. margin-bottom: 24rpx;
  382. &:last-of-type{
  383. margin-bottom: 0;
  384. }
  385. .name{
  386. flex: 1;
  387. }
  388. .status{
  389. padding: 4rpx 10rpx;
  390. border-radius: 20rpx;
  391. background-color: #DBE8FE;
  392. font-size: 22rpx;
  393. color: #006CF9;
  394. }
  395. .icon_all{
  396. .mic-filled,
  397. .image-filled
  398. {
  399. margin-left: 16rpx;
  400. }
  401. }
  402. }
  403. }
  404. .body_item_foot{
  405. border-top: 1rpx solid #D8D8D8;
  406. font-size: 26rpx;
  407. padding: 24rpx;
  408. .foot_info{
  409. display: flex;
  410. justify-content: space-between;
  411. align-items: center;
  412. .phone-filled{
  413. margin-left: 5rpx;
  414. }
  415. }
  416. }
  417. }
  418. }
  419. .zanwu{
  420. box-sizing: border-box;
  421. margin-top: 176rpx;
  422. border-top: 6rpx solid #EBEBEB;
  423. height: calc(100vh - 88rpx);
  424. display: flex;
  425. justify-content: center;
  426. background-color: #F7F7F7;
  427. .newicon-zanwu{
  428. font-size: 256rpx;
  429. color: #D6D6D6;
  430. margin-top: 140rpx;
  431. }
  432. }
  433. }
  434. </style>