| | |
| | | <!-- 工单详情 - 包含待审核、待处理、处理中、已完成 --> |
| | | <template> |
| | | <view class="workDetailContainer"> |
| | | <div class="detailTop"> |
| | | <div class="image-container"> |
| | | <u-image class="detailImage" :src="workDetailData.photo_url" mode="cover" width="100%" height="200px" |
| | | @click="previewImage(workDetailData.photo_url)"></u-image> |
| | | <div class="detailTitle"> |
| | | <div class="titleText"> |
| | | <p>{{workDetailData.event_name}}</p> |
| | | <p>{{workDetailData.create_time}}</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 步骤条 --> |
| | | <div class="stepContainer"> |
| | | <up-steps :current="currentStep" direction="column"> |
| | | <up-steps-item v-for="(step, index) in stepTitles" :key="index"> |
| | | <template #title> |
| | | <div class="horizontal-step"> |
| | | <span class="step-title">{{ step.title }}</span> |
| | | <div class="step-desc" v-if="stepResponse[index]"> |
| | | <span>{{ stepResponse[index].name || '' }}</span> |
| | | <span>{{ stepResponse[index].create_time || '' }}</span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </up-steps-item> |
| | | </up-steps> |
| | | </div> |
| | | <!-- 工单内容 --> |
| | | <div class="workOrderContent"> |
| | | <div class="workOrderTitle">工单内容</div> |
| | | <div class="workOrderContainer"> |
| | | |
| | | <div>工单名称:{{workDetailData.event_name}}</div> |
| | | <div>工单类型:{{workDetailData.type}}</div> |
| | | <div>关联任务:{{workDetailData.job_name}}</div> |
| | | <div>工单创建人:{{workDetailData.event_num?.slice(0, 2) === 'AI' ? 'AI 小飞':workDetailData.creator}}</div> |
| | | <div>事件地址:{{workDetailData.address}}</div> |
| | | |
| | | <div >关联算法:{{workDetailData.ai_types}}</div> |
| | | <div>发起部门:{{workDetailData.dept_name}}</div> |
| | | <div>发起任务时间:{{workDetailData.create_time}}</div> |
| | | <div>工单内容:{{workDetailData.remark}}</div> |
| | | </div> |
| | | </div> |
| | | <!-- 操作按钮 --> |
| | | <div class="actionButton"> |
| | | <div class="leftBtn" @click="leftClick"> |
| | | 上一页 |
| | | </div> |
| | | <div class="btngroups" v-if="workDetailData.status===2"> |
| | | <up-button type="primary" text="通过" @click="approveTicket"></up-button> |
| | | <up-button type="error" text="不通过" @click="rejectTicket"></up-button> |
| | | </div> |
| | | <div class="btngroups" v-else-if="workDetailData.status===0"> |
| | | <up-button type="primary" text="受理" @click="approveAndDispatch"></up-button> |
| | | <up-button type="error" text="不受理" @click="rejectTicket"></up-button> |
| | | </div> |
| | | <div class="btngroups" v-else-if="workDetailData.status===3"> |
| | | <up-button type="primary" text="完成工单" @click="completeTicket"></up-button> |
| | | <up-button type="error" text="取消"></up-button> |
| | | </div> |
| | | <div class="btngroups" v-else="workDetailData.status===4"> |
| | | |
| | | <up-button type="error" text="取消"></up-button> |
| | | </div> |
| | | <div class="leftBtn" @click="rightClick"> |
| | | 下一页 |
| | | </div> |
| | | </div> |
| | | |
| | | </view> |
| | | <div class="workDetailContainer"> |
| | | <WebViewPlus |
| | | ref="sWebViewRef" |
| | | :src="`${viewUrl}`" |
| | | @webMessage="onPostMessage" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { |
| | | getStepInfo, |
| | | getList, |
| | | flowEvent |
| | | } from '/src/api/work/index.js' |
| | | import { getWebViewUrl } from "@/utils/index.js"; |
| | | import { onLoad } from "@dcloudio/uni-app"; |
| | | import { useUserStore } from "@/store/index.js"; |
| | | const userStore = useUserStore(); |
| | | const userInfo = userStore.userInfo; |
| | | const sWebViewRef = ref(null); |
| | | const viewUrl = ref(""); |
| | | onLoad((options) => { |
| | | const eventNum = options.eventNum; |
| | | viewUrl.value = getWebViewUrl("/workDetail", { |
| | | eventNum: eventNum, |
| | | totalNum: options.totalNum, |
| | | keyword: options.keyword, |
| | | aiType: options.aiType, |
| | | wLJobInfoId: options.wLJobInfoId, |
| | | status: options.status, |
| | | current: options.current, |
| | | }); |
| | | }); |
| | | |
| | | const eventNum = ref(''); |
| | | const currentStatus = ref('') |
| | | const stepResponse = ref([]); |
| | | const currentStep = ref(0); |
| | | // 工单内容 |
| | | const workDetailData = ref({}) |
| | | const stepTitles = ref([{ |
| | | title: '待审核', |
| | | status: '2' |
| | | }, |
| | | { |
| | | title: '待处理', |
| | | status: '0' |
| | | }, |
| | | function onPostMessage(data) { |
| | | if (data.type === "workback") { |
| | | // #ifdef MP-WEIXIN |
| | | if ("fun" in data && data.fun === "add") { |
| | | uni.setStorageSync("joinParams", { |
| | | type: "add", |
| | | }); |
| | | } |
| | | // #endif |
| | | |
| | | { |
| | | title: '处理中', |
| | | status: '3' |
| | | }, { |
| | | title: '已完成', |
| | | status: '4' |
| | | } |
| | | ]) |
| | | onLoad(async (options) => { |
| | | eventNum.value = options.eventNum; |
| | | await getDataList(eventNum.value); |
| | | await getStepInfoData(eventNum.value); |
| | | }); |
| | | const getDataList = async (val) => { |
| | | const params = { |
| | | current: 1, |
| | | size: 9999, |
| | | source: 1, |
| | | event_name: val |
| | | } |
| | | const res = await getList(params); |
| | | const response = res.data.data.records; |
| | | workDetailData.value = response[0]; |
| | | currentStatus.value = workDetailData.value.status; |
| | | // console.log('详情',response); |
| | | } |
| | | // 步骤条 |
| | | const calculateCurrentStep = (status) => { |
| | | const statusToStep = { |
| | | '2': 0, // 待审核 -> 第0步 |
| | | '0': 1, // 待处理 -> 第1步 |
| | | '3': 2, // 处理中 -> 第2步 |
| | | '4': 3 // 已完成 -> 第3步 |
| | | } |
| | | return statusToStep[String(status)] || 0 |
| | | } |
| | | |
| | | const getStepInfoData = async (val) => { |
| | | const res = await getStepInfo(val); |
| | | stepResponse.value = res.data.data; |
| | | currentStep.value = calculateCurrentStep(currentStatus.value); |
| | | |
| | | // 动态匹配步骤描述 |
| | | const matchedSteps = {}; |
| | | stepResponse.value.forEach(step => { |
| | | // 找到 stepTitles 中对应的步骤索引 |
| | | const stepIndex = stepTitles.value.findIndex(item => item.status === String(step.status)); |
| | | if (stepIndex !== -1) { |
| | | matchedSteps[stepIndex] = step; |
| | | } |
| | | }); |
| | | |
| | | // 确保 stepResponse 按 stepTitles 顺序填充 |
| | | stepResponse.value = stepTitles.value.map((_, index) => matchedSteps[index] || null); |
| | | }; |
| | | // 图片预览 |
| | | const previewImage = (url) => { |
| | | uni.previewImage({ |
| | | urls: [url], |
| | | current: 0 |
| | | }); |
| | | }; |
| | | // 通过 |
| | | const approveTicket = async () => { |
| | | const data = { |
| | | id: workDetailData.value.id, |
| | | status: workDetailData.value.status, |
| | | isPass: 0, // 0 表示通过 |
| | | eventNum: workDetailData.value.event_num, |
| | | }; |
| | | console.log('data', data) |
| | | const file = workDetailData.value.file || null; |
| | | const response = await flowEvent(data, file); |
| | | console.log('通过', response) |
| | | } |
| | | // // 不通过 |
| | | const rejectTicket = () => {} |
| | | // // 受理 |
| | | const approveAndDispatch = () => {} |
| | | // // 不受理 |
| | | // const rejectTicket=()=>{} |
| | | // // 完成工单 |
| | | // const completeTicket=()=>{} |
| | | // 取消 |
| | | // #ifndef MP-WEIXIN |
| | | uni.setStorageSync("joinParams", { |
| | | type: "add", |
| | | }); |
| | | uni.switchTab({ |
| | | url: `/pages/work/index?addLog=111`, |
| | | // url: '/pages/work/index' |
| | | }); |
| | | // #endif |
| | | } else if (data.type === "jumpMapNav") { |
| | | // #ifndef MP-WEIXIN |
| | | uni.navigateTo({ |
| | | url: `/subPackages/workDetail/mapWork/index?currentItem=${data.eventNum}`, |
| | | }); |
| | | // #endif |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .workDetailContainer { |
| | | padding: 0 10px; |
| | | |
| | | .detailTop { |
| | | .image-container { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 200px; |
| | | |
| | | .detailImage { |
| | | width: 100%; |
| | | height: 100%; |
| | | display: block; |
| | | object-fit: cover |
| | | } |
| | | |
| | | .detailTitle { |
| | | position: absolute; |
| | | left: 0; |
| | | bottom: 0; |
| | | width: 100%; |
| | | } |
| | | |
| | | .titleText { |
| | | display: flex; |
| | | width: 100%; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .stepContainer { |
| | | margin-top: 10px; |
| | | display: flex; |
| | | background-color: antiquewhite; |
| | | border-radius: 5px; |
| | | padding: 10px; |
| | | |
| | | .horizontal-step { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 12px; |
| | | |
| | | .step-title { |
| | | min-width: 60px; |
| | | } |
| | | |
| | | .step-desc { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | gap: 8px; |
| | | // color: #666; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | .actionButton { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 10px; |
| | | |
| | | .btngroups { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | |
| | | .u-button { |
| | | padding: 9px 20px; |
| | | height: 32px; |
| | | |
| | | &:last-child { |
| | | margin-left: 12px; |
| | | margin-right: 12px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .leftBtn { |
| | | width: 70px; |
| | | height: 32px; |
| | | background-color: #999; |
| | | border-radius: 5px; |
| | | text-align: center; |
| | | line-height: 32px; |
| | | color: #fff; |
| | | cursor: pointer; |
| | | opacity: 0.8; |
| | | } |
| | | |
| | | .disableds { |
| | | background: #999 !important; |
| | | cursor: not-allowed !important; |
| | | pointer-events: none; |
| | | opacity: 0.3 !important; |
| | | } |
| | | } |
| | | |
| | | .workOrderContent { |
| | | margin-top: 15px; |
| | | |
| | | .workOrderContainer { |
| | | div { |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .titketName { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | .workDetailContainer { |
| | | width: 100%; |
| | | height: 100%; |
| | | background-size: cover; |
| | | } |
| | | </style> |