添加催办按钮
修改看板
This commit is contained in:
@@ -934,5 +934,7 @@ module.exports = {
|
||||
pleaseWaitWhileRunning: 'Please wait while running',
|
||||
roleSwitching: 'Role switching',
|
||||
setCreator: 'Set Creator',
|
||||
documentLibraryDetails: 'Document library details'
|
||||
documentLibraryDetails: 'Document library details',
|
||||
question:'Question',
|
||||
ConfirmQuestion:'Confirm Question',
|
||||
}
|
||||
@@ -604,7 +604,7 @@ module.exports = {
|
||||
StandardImplementationDate: '标准实施日期',
|
||||
regulatoryEngineer: '法规工程师',
|
||||
certifiedEngineer: '认证工程师',
|
||||
regulatoryEngineerOrcertifiedEngineer:'法规工程师/认证工程师',
|
||||
regulatoryEngineerOrcertifiedEngineer: '法规工程师/认证工程师',
|
||||
judge: '判断',
|
||||
engineeringInterfacePerson: '工程接口人',
|
||||
typeOfDeliverables: '交付物类型',
|
||||
@@ -636,7 +636,7 @@ module.exports = {
|
||||
ListOfRelevantPersonnel: '相关人员名单',
|
||||
DeliverableStatus: '交付物状态',
|
||||
CurrentStatusOfTheProject: '项目当前状态',
|
||||
CurrentStatus:'当前状态',
|
||||
CurrentStatus: '当前状态',
|
||||
NonConformance: '未符合项',
|
||||
listSubclauses: '清单条目',
|
||||
fileType: '文件类型',
|
||||
@@ -733,7 +733,7 @@ module.exports = {
|
||||
OneDecimalPlace: '一位小数',
|
||||
TwoDecimalplaces: '两位小数',
|
||||
Threedecimalplaces: '三位小数',
|
||||
FourDecimalplaces:'四位小数',
|
||||
FourDecimalplaces: '四位小数',
|
||||
Positivefloatingpointnumber: '正浮点数',
|
||||
oneconfigurationInformation: '至少含有一个配置信息',
|
||||
Correspondingstandarddeleted: '对应标准已删除',
|
||||
@@ -872,57 +872,57 @@ module.exports = {
|
||||
totalTable: '总数',
|
||||
applicableSupplement: '适用增补件',
|
||||
taskDescription: '任务说明',
|
||||
descriptionDeliverables:'交付物说明',
|
||||
startMonth:'开始日期',
|
||||
endMonth:'结束日期',
|
||||
Importing:'导入中...',
|
||||
projectDeliveryDescription:'工程交付说明',
|
||||
cancelConfirm:'取消确认',
|
||||
currentInformation:'当前信息',
|
||||
deliveryHistory:'交付历史',
|
||||
projectDeliveryRequirements:'工程交付说明',
|
||||
personLiableConfirm:'责任人确认',
|
||||
complianceResults:'符合性结果',
|
||||
noData:'暂无数据',
|
||||
confirmOperation:'确认操作',
|
||||
sponsorReview:'发起人审查',
|
||||
fillInProjectDelivery:'填写工程交付',
|
||||
Resubmit:'重新提交',
|
||||
Quantity:'数量',
|
||||
pleaseConfirmationResults:'请根据工程确认结果选择符合性状态',
|
||||
pleaseReviewTask:'请您添加对该条审查任务的工程确认信息',
|
||||
pleaseWillBeReturned:'请对工程确认结果和责任人审查结果进行再次确认,若符合要求则进行提交,否则进行退回',
|
||||
pleaseSubmitStatus:'请把工程确认的数据都点为确认状态进行提交',
|
||||
modelName:'车型名称',
|
||||
modelYear:'年款',
|
||||
NoteConfirmTheChange:'注意:变更后该条清单变为未审查状态,将从内部审查工作开始从头进行,历史数据都将丢弃是否确认变更',
|
||||
onlyDataChanged:'只能变更任务确认状态为接受的数据',
|
||||
inquiry:'询问',
|
||||
ConfirmationDeadline:'确认截止时间',
|
||||
regulatoryCertificationTaskConfirmation:'法规认证任务确认',
|
||||
confirmationEngineeringInterfacePerson:'工程接口人确认',
|
||||
engineerReply:'工程师回复',
|
||||
catalogFile:'目录文件',
|
||||
testScheme:'试验方案',
|
||||
testReportLocation:'检测报告位置',
|
||||
explain:'说明',
|
||||
dataCannotEmpty:'数据不能为空',
|
||||
documentDynamics:'文档动态',
|
||||
theNumberAgain:'编号已存在不能重复添加',
|
||||
myList:'我的待办',
|
||||
myNews:'我的消息',
|
||||
monthlyReportRegulations:'法规月报',
|
||||
Pending:'待处理',
|
||||
custom:'自定义',
|
||||
notSelected:'未选择',
|
||||
ExportReport:'导出报告',
|
||||
basicInformation:'基础信息',
|
||||
replyFromProjectContact:'工程接口人回复',
|
||||
pleaseUpload:'请上传',
|
||||
fullScreenView:'全屏查看',
|
||||
systemPrompt:'系统提示',
|
||||
loginExpired:'登录已过期',
|
||||
reportNotUploaded:'报告未上传',
|
||||
descriptionDeliverables: '交付物说明',
|
||||
startMonth: '开始日期',
|
||||
endMonth: '结束日期',
|
||||
Importing: '导入中...',
|
||||
projectDeliveryDescription: '工程交付说明',
|
||||
cancelConfirm: '取消确认',
|
||||
currentInformation: '当前信息',
|
||||
deliveryHistory: '交付历史',
|
||||
projectDeliveryRequirements: '工程交付说明',
|
||||
personLiableConfirm: '责任人确认',
|
||||
complianceResults: '符合性结果',
|
||||
noData: '暂无数据',
|
||||
confirmOperation: '确认操作',
|
||||
sponsorReview: '发起人审查',
|
||||
fillInProjectDelivery: '填写工程交付',
|
||||
Resubmit: '重新提交',
|
||||
Quantity: '数量',
|
||||
pleaseConfirmationResults: '请根据工程确认结果选择符合性状态',
|
||||
pleaseReviewTask: '请您添加对该条审查任务的工程确认信息',
|
||||
pleaseWillBeReturned: '请对工程确认结果和责任人审查结果进行再次确认,若符合要求则进行提交,否则进行退回',
|
||||
pleaseSubmitStatus: '请把工程确认的数据都点为确认状态进行提交',
|
||||
modelName: '车型名称',
|
||||
modelYear: '年款',
|
||||
NoteConfirmTheChange: '注意:变更后该条清单变为未审查状态,将从内部审查工作开始从头进行,历史数据都将丢弃是否确认变更',
|
||||
onlyDataChanged: '只能变更任务确认状态为接受的数据',
|
||||
inquiry: '询问',
|
||||
ConfirmationDeadline: '确认截止时间',
|
||||
regulatoryCertificationTaskConfirmation: '法规认证任务确认',
|
||||
confirmationEngineeringInterfacePerson: '工程接口人确认',
|
||||
engineerReply: '工程师回复',
|
||||
catalogFile: '目录文件',
|
||||
testScheme: '试验方案',
|
||||
testReportLocation: '检测报告位置',
|
||||
explain: '说明',
|
||||
dataCannotEmpty: '数据不能为空',
|
||||
documentDynamics: '文档动态',
|
||||
theNumberAgain: '编号已存在不能重复添加',
|
||||
myList: '我的待办',
|
||||
myNews: '我的消息',
|
||||
monthlyReportRegulations: '法规月报',
|
||||
Pending: '待处理',
|
||||
custom: '自定义',
|
||||
notSelected: '未选择',
|
||||
ExportReport: '导出报告',
|
||||
basicInformation: '基础信息',
|
||||
replyFromProjectContact: '工程接口人回复',
|
||||
pleaseUpload: '请上传',
|
||||
fullScreenView: '全屏查看',
|
||||
systemPrompt: '系统提示',
|
||||
loginExpired: '登录已过期',
|
||||
reportNotUploaded: '报告未上传',
|
||||
position: '职位',
|
||||
// 认证权限状态
|
||||
CollectionInitiated: '待发起收集、',
|
||||
@@ -937,7 +937,9 @@ module.exports = {
|
||||
toHavePermission: '才有权限',
|
||||
and: '并且',
|
||||
pleaseWaitWhileRunning: '运行中请稍等',
|
||||
roleSwitching:'角色切换',
|
||||
setCreator:'设置创建人',
|
||||
documentLibraryDetails:'文档库详情',
|
||||
roleSwitching: '角色切换',
|
||||
setCreator: '设置创建人',
|
||||
documentLibraryDetails: '文档库详情',
|
||||
question: '催办',
|
||||
ConfirmQuestion: '确认催办?'
|
||||
}
|
||||
@@ -89,13 +89,17 @@
|
||||
{{ $t('bringInRelevantPersonnel') }}
|
||||
</div>
|
||||
<div class="operator-text-title" @click="ExportReportClick">
|
||||
<a-icon type="user"/>
|
||||
<a-icon type="export" />
|
||||
{{ $t('ExportReport') }}
|
||||
</div>
|
||||
<div class="operator-text-title" @click="batSettingClick">
|
||||
<a-icon type="setting"/>
|
||||
{{ $t('batSetting') }}
|
||||
</div>
|
||||
<div class="operator-text-title" @click="questionClick">
|
||||
<a-icon type="apartment" />
|
||||
{{ $t('question') }}
|
||||
</div>
|
||||
</template>
|
||||
<div class="operator-text" style="position: relative">
|
||||
<span style="position: absolute;left: -13px;top: -4px">...</span>{{ $t('more') }}
|
||||
@@ -971,6 +975,33 @@
|
||||
this.$message.warning(this.$t('selectLeastOne'))
|
||||
}
|
||||
},
|
||||
questionClick() {
|
||||
if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {
|
||||
let selectedRowKeys = JSON.parse(JSON.stringify(this.selectedRowKeys))
|
||||
let _this = this
|
||||
this.$confirm({
|
||||
content: _this.$t('ConfirmQuestion'),
|
||||
onOk() {
|
||||
let query = {
|
||||
ids: selectedRowKeys.join(','),
|
||||
projectLibraryId: _this.$route.query.id
|
||||
}
|
||||
postAction('project/projectLawsInventoryEO/expediting', query).then((res) => {
|
||||
if (res.success) {
|
||||
_this.$message.success(_this.$t('OperationSuccessful'))
|
||||
_this.selectedRowKeys = []
|
||||
_this.getList()
|
||||
} else {
|
||||
_this.$message.warning(_this.$t('operationFailed'))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
this.$message.warning(this.$t('selectLeastOne'))
|
||||
}
|
||||
},
|
||||
fixedPlateClick() {
|
||||
if (this.dataSource && this.dataSource.length > 0) {
|
||||
let isTrue
|
||||
|
||||
+252
-155
@@ -27,9 +27,40 @@
|
||||
</div>
|
||||
</a-range-picker>
|
||||
</span>
|
||||
<div class="box-top-content">
|
||||
<div id="main"></div>
|
||||
<div class="axis-tip"></div>
|
||||
<div class="box-top-content" style="position: relative">
|
||||
<!-- <div id="main"></div>-->
|
||||
<!-- <div class="axis-tip"></div>-->
|
||||
<div class="box-top-content-left">
|
||||
<div class="box-top-content-left-text" :title="item.projectName"
|
||||
v-for="(item,index) in timeData" :key="index">
|
||||
{{item.projectName}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-top-content-right">
|
||||
<div class="box-top-content-right-top">
|
||||
<div class="box-top-content-right-top-text" v-for="(item,index) in timeList" :key="index">{{item}}</div>
|
||||
</div>
|
||||
<div class="box-top-content-right-bottom">
|
||||
<div class="process-content" v-for="(item,index) in timeData" :key="index">
|
||||
<div class="process-content-right-xian"></div>
|
||||
<div class="process-content-content" :style="val.left"
|
||||
v-for="(val,indexOne) in item.data[0]" :key="indexOne">
|
||||
<div class="process-content-right-top">{{val.name}}</div>
|
||||
<img v-if="val.status == 1" src="../../../../assets/wancheng.png" class="process-content-left" alt="">
|
||||
<img v-else-if="val.status == 2" src="../../../../assets/shijian.png" class="process-content-left"
|
||||
alt="">
|
||||
<img v-else-if="val.status == 3" src="../../../../assets/xian.png" class="process-content-left"
|
||||
alt="">
|
||||
<div class="process-content-right-button">{{val.time.slice(0,11)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-top-content-right-xian"></div>
|
||||
<div class="box-top-content-right-text">
|
||||
{{handlingTime}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<JLoading :loading="loadingMain">{{this.$t('dataLoading')}}</JLoading>
|
||||
</div>
|
||||
</div>
|
||||
@@ -57,7 +88,10 @@
|
||||
loadingMain: false,
|
||||
dataSource: [],
|
||||
open: false,
|
||||
getTime: []
|
||||
getTime: [],
|
||||
timeList: [],
|
||||
timeData: [],
|
||||
handlingTime: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -65,6 +99,7 @@
|
||||
},
|
||||
mounted() {
|
||||
this.getTimeline()
|
||||
this.handlingTime = moment(new Date()).format('YYYY-MM-DD')
|
||||
},
|
||||
methods: {
|
||||
getTimeline() {
|
||||
@@ -104,166 +139,100 @@
|
||||
}
|
||||
getAction(this.url.timelineList, query).then((res) => {
|
||||
if (res.success) {
|
||||
this.getEcharts(time, res.result.reverse())
|
||||
this.getEcharts(time, res.result)
|
||||
}
|
||||
})
|
||||
},
|
||||
getEcharts(timeList, timeData) {
|
||||
var chartDom = document.getElementById('main')
|
||||
var myChart = echarts.init(chartDom)
|
||||
var option
|
||||
let list = []
|
||||
let listTime = []
|
||||
for (let i = 0; i < timeList.length; i++) {
|
||||
for (let j = 0; j < 31; j++) {
|
||||
let num
|
||||
if ((j + 1) < 10) {
|
||||
num = '0' + (j + 1)
|
||||
} else {
|
||||
num = (j + 1)
|
||||
this.timeList = []
|
||||
if (timeList.length <= 12) {
|
||||
this.timeList = timeList
|
||||
} else if (timeList.length <= 24) {
|
||||
timeList.forEach((res, index) => {
|
||||
if (index == 0) {
|
||||
this.timeList.push(res)
|
||||
} else if (index == timeList.length - 1) {
|
||||
this.timeList.push(res)
|
||||
} else if (index % 2 == 0) {
|
||||
if (this.timeList.length < 11) {
|
||||
this.timeList.push(res)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if (timeList.length <= 36) {
|
||||
timeList.forEach((res, index) => {
|
||||
if (index == 0) {
|
||||
this.timeList.push(res)
|
||||
} else if (index == timeList.length - 1) {
|
||||
this.timeList.push(res)
|
||||
} else if (index % 3 == 0) {
|
||||
if (this.timeList.length < 11) {
|
||||
this.timeList.push(res)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if (timeList.length <= 48) {
|
||||
timeList.forEach((res, index) => {
|
||||
if (index == 0) {
|
||||
this.timeList.push(res)
|
||||
} else if (index == timeList.length - 1) {
|
||||
this.timeList.push(res)
|
||||
} else if (index % 4 == 0) {
|
||||
if (this.timeList.length < 11) {
|
||||
this.timeList.push(res)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if (timeList.length <= 60) {
|
||||
timeList.forEach((res, index) => {
|
||||
if (index == 0) {
|
||||
this.timeList.push(res)
|
||||
} else if (index == timeList.length - 1) {
|
||||
this.timeList.push(res)
|
||||
} else if (index % 5 == 0) {
|
||||
if (this.timeList.length < 11) {
|
||||
this.timeList.push(res)
|
||||
}
|
||||
}
|
||||
listTime.push(timeList[i])
|
||||
list.push(timeList[i] + '-' + num)
|
||||
}
|
||||
}
|
||||
const hours = listTime
|
||||
const days = []
|
||||
let content = []
|
||||
if (timeData && timeData.length > 0) {
|
||||
timeData.forEach(res => {
|
||||
days.push(res.projectName)
|
||||
content.push(res.data[0])
|
||||
})
|
||||
}
|
||||
let timeDataList = []
|
||||
let data = []
|
||||
for (let j = 0; j < content.length; j++) {
|
||||
for (let k = 0; k < content[j].length; k++) {
|
||||
content[j][k].index = j
|
||||
timeDataList.push(content[j][k])
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
for (let j = 0; j < timeDataList.length; j++) {
|
||||
let time = JSON.stringify(timeDataList[j].time).slice(1, 11)
|
||||
if (time == list[i]) {
|
||||
data.push([i, timeDataList[j].index, 12, j])
|
||||
let dataList = document.getElementsByClassName('box-top-content-right-top-text')
|
||||
let contentRightText = document.getElementsByClassName('box-top-content-right-text')
|
||||
let contentRightXian = document.getElementsByClassName('box-top-content-right-xian')
|
||||
|
||||
setTimeout(() => {
|
||||
let length = timeList.length / dataList.length
|
||||
let clientWidth = dataList[0].clientWidth
|
||||
clientWidth = clientWidth / length
|
||||
for (let i = 0; i < timeData.length; i++) {
|
||||
for (let j = 0; j < timeData[i].data[0].length; j++) {
|
||||
for (let k = 0; k < dataList.length; k++) {
|
||||
let num = (Math.ceil(clientWidth / 31)) * parseInt(timeData[i].data[0][j].time.slice(8, 10))
|
||||
timeList.forEach((res, index) => {
|
||||
if (timeData[i].data[0][j].time.slice(0, 7) == res.slice(0, 7)) {
|
||||
timeData[i].data[0][j].left = 'left:' + ((clientWidth * index + num) + 4) + 'px'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let num = timeList.length * 3
|
||||
if (num < 31) {
|
||||
num = 31
|
||||
}
|
||||
option = {
|
||||
legend: {
|
||||
data: ['Punch Card'],
|
||||
left: 'right'
|
||||
},
|
||||
tooltip: {
|
||||
position: 'left',
|
||||
formatter: function(params) {
|
||||
return (
|
||||
timeDataList[params.value[3]].name + '<br/>' +
|
||||
timeDataList[params.value[3]].time.slice(0, 11)
|
||||
)
|
||||
contentRightText[0].style = 'display:none'
|
||||
contentRightXian[0].style = 'display:none'
|
||||
let clientWidthOne = dataList[0].clientWidth
|
||||
clientWidthOne = clientWidthOne / length
|
||||
let num = Math.ceil(clientWidthOne / 31) * parseInt(this.handlingTime.slice(8, 10))
|
||||
timeList.forEach((res, index) => {
|
||||
if (res.slice(0, 7) == this.handlingTime.slice(0, 7)) {
|
||||
contentRightText[0].style = 'left:' + ((clientWidthOne * index + num) - 24) + 'px;' + 'display:block'
|
||||
contentRightXian[0].style = 'left:' + ((clientWidthOne * index + num) + 10) + 'px;' + 'display:block'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
top: 10,
|
||||
left: 40,
|
||||
right: 40,
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: hours,
|
||||
boundaryGap: false,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
position: 'top',
|
||||
axisLabel: {
|
||||
showMinLabel: true,
|
||||
interval: num,
|
||||
textStyle: {
|
||||
fontFamily: 'Blue Sky Noto',
|
||||
color: '#000F16',
|
||||
fontSize: '16'
|
||||
}
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: days,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
scale: true,
|
||||
triggerEvent: true,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontFamily: 'Blue Sky Noto',
|
||||
color: '#000F16',
|
||||
fontSize: '16'
|
||||
},
|
||||
margin: 50,
|
||||
formatter: function(params) {
|
||||
var val = ''
|
||||
if (params.length > 8) {
|
||||
val = params.substr(0, 8) + '...'
|
||||
return val
|
||||
} else {
|
||||
return params
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'scatter',
|
||||
color:['#21c9cc'],
|
||||
symbolSize: function(val) {
|
||||
return val[2] * 2
|
||||
},
|
||||
data: data,
|
||||
animationDelay: function(idx) {
|
||||
return idx * 5
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
this.loadingMain = false
|
||||
option && myChart.setOption(option, true)
|
||||
window.onresize = () => {
|
||||
myChart.resize()
|
||||
}
|
||||
myChart.on('mouseover', 'yAxis.category', function(e) {
|
||||
console.log(e)
|
||||
let axisTip = document.querySelector('.axis-tip')
|
||||
console.log(axisTip)
|
||||
axisTip.innerText = e.value
|
||||
axisTip.style.left = 100 + 'px'
|
||||
axisTip.style.top = (e.event.event.y) - 180 + 'px'
|
||||
axisTip.style.display = 'block'
|
||||
})
|
||||
myChart.on('mouseout', 'yAxis.category', function(e) {
|
||||
let axisTip = document.querySelector('.axis-tip')
|
||||
axisTip.innerText = ''
|
||||
axisTip.style.display = 'none'
|
||||
})
|
||||
})
|
||||
|
||||
this.timeData = timeData
|
||||
this.timeData = [...this.timeData]
|
||||
this.loadingMain = false
|
||||
}, 500)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,7 +308,7 @@
|
||||
width: 100%;
|
||||
height: calc(100vh - 160px);
|
||||
margin-bottom: 20px;
|
||||
padding: 10px 20px;
|
||||
padding: 25px 20px 10px 20px;
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -373,4 +342,132 @@
|
||||
margin-top: -4px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.box-top-content-left {
|
||||
width: 160px;
|
||||
float: left;
|
||||
padding-top: 100px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.box-top-content-left-text {
|
||||
color: #191E29;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
height: 104px;
|
||||
letter-spacing: 0px;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.box-top-content-right {
|
||||
width: calc(100% - 180px);
|
||||
float: left;
|
||||
}
|
||||
|
||||
.box-top-content-right-top {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.box-top-content-right-top-text {
|
||||
border-left: 1px #EAEAEC solid;
|
||||
border-top: 1px #EAEAEC solid;
|
||||
border-bottom: 1px #EAEAEC solid;
|
||||
flex: 1;
|
||||
height: 36px;
|
||||
padding-left: 10px;
|
||||
color: #54565A;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
letter-spacing: 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.box-top-content-right-top-text:last-child {
|
||||
border-right: 1px #EAEAEC solid;
|
||||
}
|
||||
|
||||
.box-top-content-right-bottom {
|
||||
position: relative;
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
.process-content {
|
||||
position: relative;
|
||||
height: 104px;
|
||||
|
||||
.process-content-content {
|
||||
background: #fff;
|
||||
z-index: 98;
|
||||
/*padding: 0 6px;*/
|
||||
position: absolute;
|
||||
left: 40px;
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
margin-top: 5px;
|
||||
|
||||
.process-content-left {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
/*margin-top: 5px;*/
|
||||
}
|
||||
|
||||
.process-content-right-top {
|
||||
font-size: 14px;
|
||||
color: #040B29;
|
||||
max-width: 155px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.process-content-right-button {
|
||||
width: 70px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #6F7385;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 34px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.process-content-right-xian {
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background: #E6E6E9;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.box-top-content-right-xian {
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
border: 1px #21c9cc dashed;
|
||||
position: absolute;
|
||||
top: -36px;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.box-top-content-right-text {
|
||||
position: absolute;
|
||||
top: -60px;
|
||||
color: #21c9cc;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
width: 100px;
|
||||
}
|
||||
</style>
|
||||
@@ -54,8 +54,37 @@
|
||||
</a-range-picker>
|
||||
</span>
|
||||
<div class="box-top-content" style="position: relative">
|
||||
<div id="main"></div>
|
||||
<div class="axis-tip"></div>
|
||||
<!-- <div id="main"></div>-->
|
||||
<!-- <div class="axis-tip"></div>-->
|
||||
<div class="box-top-content-left">
|
||||
<div class="box-top-content-left-text" :title="item.projectName"
|
||||
v-for="(item,index) in timeData" :key="index">
|
||||
{{item.projectName}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-top-content-right">
|
||||
<div class="box-top-content-right-top">
|
||||
<div class="box-top-content-right-top-text" v-for="(item,index) in timeList" :key="index">{{item}}</div>
|
||||
</div>
|
||||
<div class="box-top-content-right-bottom">
|
||||
<div class="process-content" v-for="(item,index) in timeData" :key="index">
|
||||
<div class="process-content-right-xian"></div>
|
||||
<div class="process-content-content" :style="val.left"
|
||||
v-for="(val,indexOne) in item.data[0]" :key="indexOne">
|
||||
<div class="process-content-right-top">{{val.name}}</div>
|
||||
<img v-if="val.status == 1" src="../../../assets/wancheng.png" class="process-content-left" alt="">
|
||||
<img v-else-if="val.status == 2" src="../../../assets/shijian.png" class="process-content-left" alt="">
|
||||
<img v-else-if="val.status == 3" src="../../../assets/xian.png" class="process-content-left" alt="">
|
||||
<div class="process-content-right-button">{{val.time.slice(0,11)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-top-content-right-xian"></div>
|
||||
<div class="box-top-content-right-text">
|
||||
{{handlingTime}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<JLoading :loading="loadingMain">{{this.$t('dataLoading')}}</JLoading>
|
||||
</div>
|
||||
</div>
|
||||
@@ -116,6 +145,8 @@
|
||||
data() {
|
||||
return {
|
||||
queryParam: {},
|
||||
timeList: [],
|
||||
timeData: [],
|
||||
loading: false,
|
||||
loadingMain: false,
|
||||
dataSource: [],
|
||||
@@ -191,12 +222,14 @@
|
||||
}
|
||||
],
|
||||
startTime: undefined,
|
||||
endTime: undefined
|
||||
endTime: undefined,
|
||||
handlingTime: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getList()
|
||||
this.getTimeline()
|
||||
this.handlingTime = moment(new Date()).format('YYYY-MM-DD')
|
||||
},
|
||||
methods: {
|
||||
getTimeline() {
|
||||
@@ -238,164 +271,100 @@
|
||||
}
|
||||
getAction(this.url.timelineList, query).then((res) => {
|
||||
if (res.success) {
|
||||
this.getEcharts(time, res.result.reverse())
|
||||
this.getEcharts(time, res.result)
|
||||
}
|
||||
})
|
||||
},
|
||||
getEcharts(timeList, timeData) {
|
||||
var chartDom = document.getElementById('main')
|
||||
var myChart = echarts.init(chartDom)
|
||||
var option
|
||||
let list = []
|
||||
let listTime = []
|
||||
for (let i = 0; i < timeList.length; i++) {
|
||||
for (let j = 0; j < 31; j++) {
|
||||
let num
|
||||
if ((j + 1) < 10) {
|
||||
num = '0' + (j + 1)
|
||||
} else {
|
||||
num = (j + 1)
|
||||
this.timeList = []
|
||||
if (timeList.length <= 12) {
|
||||
this.timeList = timeList
|
||||
} else if (timeList.length <= 24) {
|
||||
timeList.forEach((res, index) => {
|
||||
if (index == 0) {
|
||||
this.timeList.push(res)
|
||||
} else if (index == timeList.length - 1) {
|
||||
this.timeList.push(res)
|
||||
} else if (index % 2 == 0) {
|
||||
if (this.timeList.length < 11) {
|
||||
this.timeList.push(res)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if (timeList.length <= 36) {
|
||||
timeList.forEach((res, index) => {
|
||||
if (index == 0) {
|
||||
this.timeList.push(res)
|
||||
} else if (index == timeList.length - 1) {
|
||||
this.timeList.push(res)
|
||||
} else if (index % 3 == 0) {
|
||||
if (this.timeList.length < 11) {
|
||||
this.timeList.push(res)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if (timeList.length <= 48) {
|
||||
timeList.forEach((res, index) => {
|
||||
if (index == 0) {
|
||||
this.timeList.push(res)
|
||||
} else if (index == timeList.length - 1) {
|
||||
this.timeList.push(res)
|
||||
} else if (index % 4 == 0) {
|
||||
if (this.timeList.length < 11) {
|
||||
this.timeList.push(res)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if (timeList.length <= 60) {
|
||||
timeList.forEach((res, index) => {
|
||||
if (index == 0) {
|
||||
this.timeList.push(res)
|
||||
} else if (index == timeList.length - 1) {
|
||||
this.timeList.push(res)
|
||||
} else if (index % 5 == 0) {
|
||||
if (this.timeList.length < 11) {
|
||||
this.timeList.push(res)
|
||||
}
|
||||
}
|
||||
listTime.push(timeList[i])
|
||||
list.push(timeList[i] + '-' + num)
|
||||
}
|
||||
}
|
||||
const hours = listTime
|
||||
const days = []
|
||||
let content = []
|
||||
if (timeData && timeData.length > 0) {
|
||||
timeData.forEach(res => {
|
||||
days.push(res.projectName)
|
||||
content.push(res.data[0])
|
||||
})
|
||||
}
|
||||
let timeDataList = []
|
||||
let data = []
|
||||
for (let j = 0; j < content.length; j++) {
|
||||
for (let k = 0; k < content[j].length; k++) {
|
||||
content[j][k].index = j
|
||||
timeDataList.push(content[j][k])
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
for (let j = 0; j < timeDataList.length; j++) {
|
||||
let time = JSON.stringify(timeDataList[j].time).slice(1, 11)
|
||||
if (time == list[i]) {
|
||||
data.push([i, timeDataList[j].index, 12, j])
|
||||
let dataList = document.getElementsByClassName('box-top-content-right-top-text')
|
||||
let contentRightText = document.getElementsByClassName('box-top-content-right-text')
|
||||
let contentRightXian = document.getElementsByClassName('box-top-content-right-xian')
|
||||
|
||||
setTimeout(() => {
|
||||
let length = timeList.length / dataList.length
|
||||
let clientWidth = dataList[0].clientWidth
|
||||
clientWidth = clientWidth / length
|
||||
for (let i = 0; i < timeData.length; i++) {
|
||||
for (let j = 0; j < timeData[i].data[0].length; j++) {
|
||||
for (let k = 0; k < dataList.length; k++) {
|
||||
let num = (Math.ceil(clientWidth / 31)) * parseInt(timeData[i].data[0][j].time.slice(8, 10))
|
||||
timeList.forEach((res, index) => {
|
||||
if (timeData[i].data[0][j].time.slice(0, 7) == res.slice(0, 7)) {
|
||||
timeData[i].data[0][j].left = 'left:' + ((clientWidth * index + num) + 4) + 'px'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let num = timeList.length * 3
|
||||
if (num < 31) {
|
||||
num = 31
|
||||
}
|
||||
option = {
|
||||
legend: {
|
||||
data: ['Punch Card'],
|
||||
left: 'right'
|
||||
},
|
||||
tooltip: {
|
||||
position: 'left',
|
||||
formatter: function(params) {
|
||||
return (
|
||||
timeDataList[params.value[3]].name + '<br/>' +
|
||||
timeDataList[params.value[3]].time.slice(0, 11)
|
||||
)
|
||||
contentRightText[0].style = 'display:none'
|
||||
contentRightXian[0].style = 'display:none'
|
||||
let clientWidthOne = dataList[0].clientWidth
|
||||
clientWidthOne = clientWidthOne / length
|
||||
let num = Math.ceil(clientWidthOne / 31) * parseInt(this.handlingTime.slice(8, 10))
|
||||
timeList.forEach((res, index) => {
|
||||
if (res.slice(0, 7) == this.handlingTime.slice(0, 7)) {
|
||||
contentRightText[0].style = 'left:' + ((clientWidthOne * index + num) - 24) + 'px;' + 'display:block'
|
||||
contentRightXian[0].style = 'left:' + ((clientWidthOne * index + num) + 10) + 'px;' + 'display:block'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
top: 10,
|
||||
left: 40,
|
||||
right: 40,
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: hours,
|
||||
boundaryGap: false,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
position: 'top',
|
||||
axisLabel: {
|
||||
showMinLabel: true,
|
||||
interval: num,
|
||||
textStyle: {
|
||||
fontFamily: 'Blue Sky Noto',
|
||||
color: '#000F16',
|
||||
fontSize: '16'
|
||||
}
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: days,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
scale: true,
|
||||
triggerEvent: true,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontFamily: 'Blue Sky Noto',
|
||||
color: '#000F16',
|
||||
fontSize: '16'
|
||||
},
|
||||
margin: 50,
|
||||
formatter: function(params) {
|
||||
var val = ''
|
||||
if (params.length > 8) {
|
||||
val = params.substr(0, 8) + '...'
|
||||
return val
|
||||
} else {
|
||||
return params
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'scatter',
|
||||
color:['#21c9cc'],
|
||||
symbolSize: function(val) {
|
||||
return val[2] * 2
|
||||
},
|
||||
data: data,
|
||||
animationDelay: function(idx) {
|
||||
return idx * 5
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
this.loadingMain = false
|
||||
option && myChart.setOption(option, true)
|
||||
window.onresize = () => {
|
||||
myChart.resize()
|
||||
}
|
||||
myChart.on('mouseover', 'yAxis.category', function(e) {
|
||||
let axisTip = document.querySelector('.axis-tip')
|
||||
axisTip.innerText = e.value
|
||||
axisTip.style.left = 100 + 'px'
|
||||
axisTip.style.top = (e.event.event.y) - 180 + 'px'
|
||||
axisTip.style.display = 'block'
|
||||
})
|
||||
myChart.on('mouseout', 'yAxis.category', function(e) {
|
||||
let axisTip = document.querySelector('.axis-tip')
|
||||
axisTip.innerText = ''
|
||||
axisTip.style.display = 'none'
|
||||
})
|
||||
})
|
||||
|
||||
this.timeData = timeData
|
||||
this.timeData = [...this.timeData]
|
||||
this.loadingMain = false
|
||||
}, 500)
|
||||
|
||||
},
|
||||
TaskPlanListClick() {
|
||||
let newUrl = this.$router.resolve({
|
||||
@@ -439,7 +408,7 @@
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
<style scoped lang="less">
|
||||
@import '~@assets/less/common.less';
|
||||
|
||||
.box-title-text {
|
||||
@@ -480,7 +449,7 @@
|
||||
|
||||
.box-top-content {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
height: 500px;
|
||||
margin-bottom: 20px;
|
||||
padding: 20px 0;
|
||||
box-sizing: border-box;
|
||||
@@ -521,4 +490,132 @@
|
||||
color: #21c9cc;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.box-top-content-left {
|
||||
width: 160px;
|
||||
float: left;
|
||||
padding-top: 100px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.box-top-content-left-text {
|
||||
color: #191E29;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
height: 104px;
|
||||
letter-spacing: 0px;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.box-top-content-right {
|
||||
width: calc(100% - 180px);
|
||||
float: left;
|
||||
}
|
||||
|
||||
.box-top-content-right-top {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.box-top-content-right-top-text {
|
||||
border-left: 1px #EAEAEC solid;
|
||||
border-top: 1px #EAEAEC solid;
|
||||
border-bottom: 1px #EAEAEC solid;
|
||||
flex: 1;
|
||||
height: 36px;
|
||||
padding-left: 10px;
|
||||
color: #54565A;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
letter-spacing: 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.box-top-content-right-top-text:last-child {
|
||||
border-right: 1px #EAEAEC solid;
|
||||
}
|
||||
|
||||
.box-top-content-right-bottom {
|
||||
position: relative;
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
.process-content {
|
||||
position: relative;
|
||||
height: 104px;
|
||||
|
||||
.process-content-content {
|
||||
background: #fff;
|
||||
z-index: 98;
|
||||
/*padding: 0 6px;*/
|
||||
position: absolute;
|
||||
left: 40px;
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
margin-top: 5px;
|
||||
|
||||
.process-content-left {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
/*margin-top: 5px;*/
|
||||
}
|
||||
|
||||
.process-content-right-top {
|
||||
font-size: 14px;
|
||||
color: #040B29;
|
||||
max-width: 155px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.process-content-right-button {
|
||||
width: 70px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #6F7385;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 34px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.process-content-right-xian {
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background: #E6E6E9;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.box-top-content-right-xian {
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
border: 1px #21c9cc dashed;
|
||||
position: absolute;
|
||||
top: -36px;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.box-top-content-right-text {
|
||||
position: absolute;
|
||||
top: -60px;
|
||||
color: #21c9cc;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
width: 100px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user