hi-ucs/front/src/views/personalCenter/components/AbilityApplication.vue

671 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @Author: hisense.liangjunhua
* @Date: 2022-07-12 09:42:44
* @LastEditors: hisense.liangjunhua
* @LastEditTime: 2022-08-04 10:41:06
* @Description:我的申请 能力申请 查看详情
-->
<template>
<div class="top">
<div class="title">基本信息</div>
<div class="main">
<div>
<p class="item">
<span>申请标题{{ props.refObj.title }}</span>
<span>申请单号{{ props.refObj.applyNumber || '--' }}</span>
<span v-if="props.refObj.applicationSystem">
应用系统{{ props.refObj.applicationSystem }}
</span>
<span v-else></span>
</p>
<p class="item">
<span>申请人信息{{ props.refObj.user }}</span>
<span>电话{{ props.refObj.phone }}</span>
<span>单位{{ props.refObj.unit }}</span>
</p>
<p v-if="props.refObj.applicationScene.length > 0">
<span>应用场景:{{ props.refObj.applicationScene.join('') }}</span>
</p>
<p>
<span>应用背景:{{ props.refObj.applicationBackground }}</span>
</p>
<p>
<span>期望效果:{{ props.refObj.effectWish }}</span>
</p>
<p v-if="props.refObj.enclosure">
<span>
申请单附件:
<span class="enclosure">
{{ props.refObj.enclosureName || '--' }}
<span class="btn" @click="showThis()">预览</span>
</span>
</span>
</p>
</div>
</div>
</div>
<div class="bottom">
<div class="title">申请能力</div>
<div class="main">
<div class="item" v-for="(item, index) in showArr" :key="item + index">
<div class="deptName">
<span class="img"></span>
<span>{{ item.name }}</span>
</div>
<div
style="
display: flex;
justify-content: space-between;
align-items: center;
"
>
<div class="oddNumbers">子单号:{{ item.instanceId }}</div>
<div style="display: flex; align-items: center">
<a-button
type="primary"
@click="modify(props.refObj.id, item)"
v-if="item.backToFirst"
>
修改
</a-button>
<a-popconfirm
v-if="!item.ended"
title="是否终止此流程?"
ok-text="是"
cancel-text="否"
@confirm="endThis(item.instanceId)"
@cancel="cancel"
>
<a-button type="primary" danger style="margin-left: 10px">
流程终止
</a-button>
</a-popconfirm>
</div>
</div>
<div class="box" v-if="item.list.length > 0">
<div
class="ability"
v-for="val in item.list"
:key="val.id"
:class="item.approveStatus === '通过' ? 'clickCursor' : ''"
>
<div
class="left"
:class="
val.type == '应用资源'
? 'yyzy'
: val.infoList.filter(
(val2) => val2.attrType == '组件类型'
)[0].attrValue == '智能算法'
? 'znsf'
: val.infoList.filter(
(val2) => val2.attrType == '组件类型'
)[0].attrValue == '图层服务'
? 'tcfw'
: val.infoList.filter(
(val2) => val2.attrType == '组件类型'
)[0].attrValue == '开发组件'
? 'kfzj'
: val.infoList.filter(
(val2) => val2.attrType == '组件类型'
)[0].attrValue == '业务组件'
? 'ywzj'
: 'yyzy'
"
></div>
<div class="right">
<div class="ability-top">
<div class="name">
<div class="name">
<span class="channelName">{{ val.name }}</span>
<span class="type">
{{
val.type == '应用资源'
? '应用资源'
: val.infoList.filter(
(val2) => val2.attrType == '组件类型'
)[0].attrValue == '智能算法'
? '智能算法'
: val.infoList.filter(
(val2) => val2.attrType == '组件类型'
)[0].attrValue == '图层服务'
? '图层服务'
: val.infoList.filter(
(val2) => val2.attrType == '组件类型'
)[0].attrValue == '开发组件'
? '开发组件'
: val.infoList.filter(
(val2) => val2.attrType == '组件类型'
)[0].attrValue == '业务组件'
? '业务组件'
: '--'
}}
</span>
</div>
</div>
<div></div>
<!-- <div class="btn" v-if="val.type == '组件服务'">技术文档</div> -->
</div>
<div class="ability-bottom">
<div class="dec">资源描述:{{ val.description }}</div>
<div class="result">
申请结果:{{
item.ended ? item.approveStatus || '审核完成' : '审核中'
}}
<a-button
v-if="
item.approveStatus === '通过' &&
val.infoList.filter(
(item) => item.attrType == '上传附件'
)[0]
"
@click.stop="downloadFile(item, '附件下载')"
class="DownloadAttachment"
>
附件下载
</a-button>
<a-button
v-if="item.approveStatus === '通过'"
@click.stop="switchFunction(item)"
>
查看详情
</a-button>
</div>
</div>
</div>
</div>
</div>
<div class="box" v-if="item.list2.length > 0">
<div class="ability" v-for="val in item.list2" :key="val.channelId">
<div class="left sxt"></div>
<div class="right">
<div class="ability-top">
<div class="name">
<span class="channelName">{{ val.channelName }}</span>
<span class="type">基础设施</span>
</div>
<a-button
type="primary"
v-if="item.approveStatus === '通过' && whoShow1.itShowXiHaiAn"
@click.stop="openVideo(val)"
>
视频预览
</a-button>
</div>
<div class="ability-bottom">
<div class="dec2">位置:{{ val.nodeName }}</div>
<div class="result" v-if="item.approveStatus == '通过'">
申请结果:{{
'列表地址:' +
backUrl +
'resource/getApplyCameraList/' +
item.instanceId +
';' +
'视频流地址:' +
backUrl +
'resource/hls/getHls/?key=' +
val.channelId
}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 单个预览弹窗 -->
<a-modal
wrapClassName="single-preview-modal"
v-model:visible="visible"
title="视频预览"
:width="960"
destroyOnClose
>
<template #footer></template>
<div style="width: 100%; display: flex; justify-content: center">
<div style="width: 100%; height: 100%">
<vue3VideoPlay v-bind="options"/>
</div>
</div>
</a-modal>
</div>
</template>
<script setup>
import { ref, defineProps, reactive } from 'vue'
import mybus from '@/myplugins/mybus'
import { message } from 'ant-design-vue'
import { endProcess, getApplyForm } from '@/api/personalCenter.js'
import { useRouter } from 'vue-router'
import {
getStreamByChannelCode,
} from '@/api/videoSurveillance'
const router = useRouter()
const backUrl = ref(window.SITE_CONFIG.apiURL + '/')
const props = defineProps({
refObj: { type: Object, default: null },
})
const whoShow1 = ref(whoShow)
let visible = ref(false)
const options = reactive({
width: '912px', //播放器宽度
height: '513px', //播放器高度
color: '#409eff', //主题色
title: '', //视频名称
src: '', //视频源
type: 'm3u8', // 视频源类型
muted: false, //静音
webFullScreen: false,
speedRate: ['0.75', '1.0', '1.25', '1.5', '2.0'], //播放倍速
autoPlay: true, //自动播放
loop: false, //循环播放
mirror: false, //镜像画面
ligthOff: false, //关灯模式
volume: 0.3, //默认音量大小
control: true, //是否显示控制
controlBtns: [
'audioTrack',
'quality',
'speedRate',
'volume',
'setting',
'pip',
'pageFullScreen',
'fullScreen',
], //显示所有按钮,
})
const dept = reactive({})
// eslint-disable-next-line no-undef
if (infrastructure) {
// eslint-disable-next-line no-undef
dept.deptId = infrastructure.deptId
// eslint-disable-next-line no-undef
dept.deptName = infrastructure.deptName
}
const showThis = () => {
window.open(
window.SITE_CONFIG.previewUrl +
'hisense_office/onlinePreview?url=' +
btoa(encodeURI(props.refObj.enclosure))
)
}
const showArr = ref([])
console.log(props.refObj, '=====================================')
const endThis = (instanceId) => {
endProcess({ instanceId: instanceId }).then((res) => {
if (res.data.code == 0) {
message.success('流程终止成功!')
mybus.emit('closeModal', { type: '能力申请', index: 0 })
} else {
message.warning('流程终止失败!')
}
})
}
const modify = (id, item) => {
getApplyForm(id).then((res) => {
console.log('修改==============>', res.data.data, item)
if (item.list.length > 0) {
let arr = []
item.list.map((val) => {
arr.push({
delFlag: val.delFlag,
description: val.description,
resourceId: val.id,
resourceName: val.name,
time: val.createDate,
type: val.type,
componentType:
(val.infoList.filter((val) => val.attrType == '组件类型')[0] &&
val.infoList.filter((val) => val.attrType == '组件类型')[0]
.attrValue) ||
'',
})
})
localStorage.setItem(
'applyList',
JSON.stringify([
{
arr: arr,
deptId: item.name,
deptName: item.name,
},
])
)
router.push({
path: '/apply',
query: {
id: id,
taskId: item.instanceId,
},
})
} else if (item.list2.length > 0) {
let arr = [
{
arr: [
{
description: '',
note1: JSON.stringify(item.list2),
resourceId: '1522550195055828996',
resourceName: '摄像头列表',
type: '基础设施',
},
],
deptId: dept.deptId,
deptName: dept.deptName,
},
]
localStorage.setItem('applyList', JSON.stringify(arr))
router.push({
path: '/apply',
query: {
id: id,
taskId: item.instanceId,
},
})
}
})
}
if (props.refObj.resourceApplication) {
showArr.value = []
for (const key in props.refObj.resourceApplication) {
if (props.refObj.resourceApplication[key].length > 0) {
let obj = { name: '', instanceId: '', list: [], list2: [] }
obj.name = key
props.refObj.resourceApplication[key].map((item) => {
obj.instanceId = item.instanceId
obj.backToFirst = item.backToFirst
obj.ended = item.ended
obj.approveStatus = item.approveStatus
if (item.resources.length > 0) {
item.resources.map((val) => {
obj.list.push(val)
})
} else {
item.camera.map((val) => {
obj.list2.push(val)
})
}
})
showArr.value.push(obj)
}
}
}
const switchFunction = (data) => {
if (data.approveStatus === '通过') {
let id = data.list[0].id
const applypage = router.resolve({
path: '/details', // 跳转的页面路由
query: {
id: id,
},
})
window.open(applypage.href, '_blank')
}
}
const downloadFile = (data, name) => {
let path = data.list[0].infoList.filter(
(item) => item.attrType === '上传附件'
)[0].attrValue
console.log(path, 'obj')
const xhr = new XMLHttpRequest()
xhr.open('get', path)
xhr.responseType = 'blob'
xhr.send()
xhr.onload = function () {
if (this.status === 200 || this.status === 304) {
// 如果是IE10及以上不支持download属性采用msSaveOrOpenBlob方法但是IE10以下也不支持msSaveOrOpenBlob
if ('msSaveOrOpenBlob' in navigator) {
navigator.msSaveOrOpenBlob(this.response, name)
return
}
// const blob = new Blob([this.response], { type: xhr.getResponseHeader('Content-Type') });
// const url = URL.createObjectURL(blob);
const url = URL.createObjectURL(this.response)
const a = document.createElement('a')
a.style.display = 'none'
a.href = url
a.download = name
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
URL.revokeObjectURL(url)
}
}
}
// 视频预览
const openVideo = (item) => {
console.log('打开视频', item)
const param = {
key: item.cameraId,
}
getStreamByChannelCode(param).then((res) => {
console.log('视频预览------------>', res);
console.log(res)
visible.value = true
options.src = res.data.data || ''
}).catch(err => {
message.error(err)
})
// 视频测试--勿删
// visible.value = true
// options.src = 'http://playertest.longtailvideo.com/adaptive/bipbop/gear4/prog_index.m3u8'
}
</script>
<style lang="less" scoped>
.title {
font-size: 0.18rem;
color: #000;
font-weight: bold;
margin-bottom: 0.2rem;
padding-left: 0.1rem;
border-left: 0.06rem #0058e1 solid;
}
.top {
margin-bottom: 0.1rem;
.main {
background: #eee;
padding: 0.2rem 0.2rem 0.1rem;
p {
display: flex;
justify-content: space-between;
& > span {
width: 100%;
}
.enclosure {
width: 95%;
padding: 0.05rem 0.1rem;
background: #ddd;
display: flex;
justify-content: space-between;
margin-top: 0.05rem;
}
.btn:hover {
color: #0058e1;
cursor: pointer;
}
}
.item {
span {
width: 2.5rem;
}
}
}
}
.bottom {
.main {
.item {
border-top: 1px #eee solid;
.deptName {
color: #0058e1;
font-size: 0.16rem;
margin-top: 0.1rem;
display: flex;
align-items: center;
.img {
width: 0.05rem;
height: 0.05rem;
border-radius: 0.05rem;
background: #0058e1;
margin-right: 0.1rem;
}
}
.oddNumbers {
margin: 0.1rem 0 0 0.15rem;
}
.box {
margin-left: 0.1rem;
.ability {
height: 1.3rem;
display: flex;
border-bottom: 1px #eee solid;
padding: 0.1rem 0;
.left {
display: inline-block;
width: 1.1rem;
height: 1.1rem;
margin-left: 0.1rem;
background: url('~@/assets/home/sxt_square.png') no-repeat;
background-size: 100%;
}
.sxt {
background: url('~@/assets/home/sxt_square.png') no-repeat;
background-size: 100%;
}
.yyzy {
background: url('~@/assets/home/yyzy_square.png') no-repeat;
background-size: 100%;
}
.znsf {
background: url('~@/assets/home/znsf_square.png') no-repeat;
background-size: 100%;
}
.tcfw {
background: url('~@/assets/home/tcfw_square.png') no-repeat;
background-size: 100%;
}
.kfzj {
background: url('~@/assets/home/kfzj_square.png') no-repeat;
background-size: 100%;
}
.ywzj {
background: url('~@/assets/home/ywzj_square.png') no-repeat;
background-size: 100%;
}
.btn {
cursor: pointer;
color: #0087ff;
align-self: flex-end;
padding: 5px 10px;
border: 1px #0087ff solid;
border-radius: 0.2rem;
}
.right {
flex: 1;
margin-left: 0.15rem;
.ability-top {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.name {
width: 6rem;
height: 0.2rem;
display: flex;
.channelName {
max-width: 5rem;
height: 0.2rem;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
word-break: break-all;
}
.type {
background: #0087ff;
color: #fff;
line-height: 14px;
padding: 2px 10px;
border-radius: 10px;
margin-left: 0.1rem;
}
}
}
.ability-bottom {
margin-top: 0.15rem;
// display: flex;
// justify-content: space-between;
.dec {
width: 7rem;
height: 0.44rem;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
word-break: break-all;
}
.dec2 {
width: 7rem;
height: 0.22rem;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
word-break: break-all;
}
// .result:hover {
// color: #0058e1;
// cursor: pointer;
// }
.result {
position: relative;
}
}
}
.DownloadAttachment {
position: absolute;
right: 10px;
top: -150px;
}
.DownloadAttachment2 {
position: absolute;
right: 10px;
top: -110px;
}
}
.clickCursor {
cursor: pointer;
}
}
}
}
}
.single-preview-modal {
.ant-modal-header {
background: url(~@/assets/home/video-background.png) no-repeat;
background-size: cover;
}
.ant-modal-title {
font-size: 0.16rem;
font-weight: 500;
color: #ffffff;
}
.anticon {
color: #ffffff;
}
}
</style>