Commit ecd0dc79 by cwy

多个pdf文件问题

parent dc12e4f0
......@@ -49,6 +49,13 @@ export function claimTasksApi() {
data,
});
},
normGetPdfList: (data) => {
return request({
url: '/api/normCollects/getPdfList',
method: 'post',
data,
});
},
normReceivesRevoke: (data) => {
return request({
url: '/api/normReceives/revoke',
......
<template>
<div class="system-role-dialog-container">
<el-dialog :title="state.dialog.title" v-model="state.dialog.isShowDialog" width="60%" @close="closeDialog" :close-on-click-modal="false">
<el-form ref="dialogFormRef" :model="state.formItem.addItem" :rules="state.rules" size="default" label-width="100px"
v-loading="state.dataLoading" label-position="right" style="width: 90%;text-align: center;">
<el-form-item label="子任务名称" prop="name">
<el-input type="textarea" v-model="state.formItem.addItem.name" placeholder="请输入指标名称" clearable :disabled="true"></el-input>
</el-form-item>
<el-form-item label="难度等级">
<el-select v-model="state.formItem.addItem.level" :disabled="true" placeholder="请选择难度等级">
<el-option label="1" value="1"></el-option>
<el-option label="2" value="2"></el-option>
<el-option label="3" value="3"></el-option>
</el-select>
</el-form-item>
<el-form-item label="优先级">
<el-select v-model="state.formItem.addItem.sort" :disabled="true" placeholder="请选择优先级">
<el-option label="低" value="1"></el-option>
<el-option label="中" value="2"></el-option>
<el-option label="高" value="3"></el-option>
</el-select>
</el-form-item>
<el-form-item label="参考信源" prop="refer">
<el-input type="textarea" v-model="state.formItem.addItem.refer" placeholder="请输入参考信源" clearable :disabled="true"></el-input>
</el-form-item>
<el-form-item label="price" prop="price">
<el-input-number v-model="state.formItem.addItem.price" :precision="2" :step="0.1" :max="10" placeholder="请输入单价" :disabled="true"></el-input-number>
</el-form-item>
<el-form-item label="参考指南" prop="guide">
<el-input type="textarea" v-model="state.formItem.addItem.guide" placeholder="请输入参考指南" clearable :disabled="true"></el-input>
</el-form-item>
<el-form-item label="名称" :prop="'dynamicItem.' + index+ '.name'" v-for="(item, index) in state.formItem.dynamicItem" :key="index">
<el-input v-model="item.name" placeholder="请输入标题" clearable style="width: 40%;" :disabled="true"></el-input>
<div style="width: 20%;">内容:</div>
<el-input v-model="item.value" placeholder="请输入标题对应的值" clearable style="width: 40%;" :disabled="true"></el-input>
</el-form-item>
<el-divider><span style="color: #F56C6C;">用户需填写区域</span></el-divider>
<el-form-item label="标题" :prop="'userFilled.' + index+ '.name'" v-for="(item, index) in state.formItem.userFilled" :key="index">
<el-row style="width: 100% !important;">
<el-col :span="12">
<el-input v-model="item.name" placeholder="请输入标题" clearabl :disabled="true"></el-input>
</el-col>
<el-col :span="6">
<div>是否必填:</div>
</el-col>
<el-col :span="6">
<div class="system-menu-container">
<div class="breadcrumb-box">
<Breadcrumb />
</div>
<div class="header-search flex space-between">
<div>
<el-radio v-model="item.radio" label="1" :disabled="true"></el-radio>
<el-radio v-model="item.radio" label="0" :disabled="true"></el-radio>
<el-page-header @back="backToPreviousPage">
</el-page-header>
</div>
</el-col>
<div style="margin-right: 20px;">
<el-button type="primary" size="small" @click="whole">查看详细信息</el-button>
</div>
</div>
<div class="page-main" ref="pageMain" v-loading="state.loading">
<el-card shadow="hover" style="height:100%; overflow: scroll">
<div class="box_info">
<el-row :gutter="20">
<el-col :span="8"><sapn class="box_title">任务名称:</sapn><span></span></el-col>
<el-col :span="8"><sapn class="box_title">子任务名称:</sapn><span>{{state.formItem.addItem.name }}</span></el-col>
<el-col :span="8"><sapn class="box_title">难度等级:</sapn><span>{{state.formItem.addItem.level }}</span></el-col>
</el-row>
<el-row style="width: 100% !important; margin-left: -8%; margin-top: 10 !important;">
<el-col :span="2">
<div>备注:</div>
</div>
<div class="box_info">
<el-row :gutter="20">
<el-col :span="8"><sapn class="box_title">优先级:</sapn><span>{{formatOutputSort(state.formItem.addItem.sort)}}</span></el-col>
<el-col :span="8"><sapn class="box_title">单价:</sapn><span>{{state.formItem.addItem.price }}/元</span></el-col>
<el-col :span="8"><sapn class="box_title">参考信源:</sapn>
<el-link type="danger" v-if="checkUrl(state.formItem.addItem.refer)" :href="state.formItem.addItem.refer" target ="_blank">点击查看</el-link>
<span v-else>{{state.formItem.addItem.refer}}</span>
</el-col>
<el-col :span="18">
<el-input v-model="item.remarks" placeholder="请输入备注(选填)" clearabl :disabled="true"></el-input>
</el-row>
</div>
<div class="box_info">
<el-row :gutter="20">
<el-col :span="8">
<sapn class="box_title">参考指南:</sapn>
<el-link type="danger" v-if="checkUrl(state.formItem.addItem.guide)" :href="state.formItem.addItem.guide" target ="_blank">点击查看</el-link>
<span v-else>{{state.formItem.addItem.guide}}</span>
</el-col>
</el-row>
</el-form-item>
</el-form>
<el-divider style="width: 90%;"><span style="color: #F56C6C;">用户已领取列表</span></el-divider>
<el-table :data="state.tableData" border style="width: 100%" :height="state.tableHeight"
ref="multipleTableRef">
<el-table-column v-for="column in state.columns" :key="column.prop" :label="column.label" :prop="column.prop" :width="column.width" show-overflow-tooltip align="center">
<template #default="scope">
<!-- <span style="color:#409EFF" v-if="column.label =='用户名称'">{{scope.row[column.prop]}}</span> -->
<span style="color:#909399" v-if="column.label =='指标状态' && scope.row[column.prop] ==0">已领取、未完成</span>
<span style="color:#E6A23C" v-if="column.label =='指标状态' && scope.row[column.prop] ==1">已完成、未审核</span>
<span style="color:#409EFF" v-if="column.label =='指标状态' && scope.row[column.prop] ==2">审核不通过</span>
<span style="color:#409EFF" v-if="column.label =='指标状态' && scope.row[column.prop] ==3">审核通过、未结算</span>
<span style="color:#409EFF" v-if="column.label =='指标状态' && scope.row[column.prop] ==4">审核通过、已结算</span>
<span style="color:#909399" v-if="scope.row[column.prop] =='' && column.label !='指标状态'">/</span>
<!-- <span v-else>{{scope.row[column.prop]}}</span> -->
</template>
</el-table-column>
</el-table>
</el-dialog>
</div>
<el-divider><span style="color: #F56C6C;">展示端</span></el-divider>
<div class="custom">
<div style="width: 100%; margin-bottom: 20px;" v-for="(item, index) in state.formItem.dynamicItem">
<sapn class="box_title">{{item.name}}</sapn>
<span v-html="formatOutputCustom(item.value)"></span>
</div>
</div>
<el-divider><span style="color: #F56C6C;">用户端</span></el-divider>
<div class="custom">
<div style="width: 30%; margin-bottom: 20px; float: left;" v-for="(item, index) in state.formItem.userFilled">
<div>名称:{{item.name}}</div>
<div>内容:</div>
<div>是否必填:
<span style="color:#F56C6C" v-if="item.radio==1">必填</span>
<span style="color:#909399" v-if="item.radio==0">选填</span>
</div>
<div>备注:{{item.remarks}}</div>
</div>
</div>
</el-card>
</div>
</div>
</template>
<script setup name="systemRoleDialog">
<script setup name="taskPackage-list">
import { getCurrentInstance } from 'vue';
import { normApi } from '/@/api/norm'
import { ElMessage } from 'element-plus';
import { toolsApi } from '/@/api/tools'
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
// 定义变量内容
const dialogFormRef = ref();
import { ElMessageBox, ElMessage } from 'element-plus';
import { Session } from '/@/utils/storage';
// 引入组件
const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/breadcrumb.vue'));
const router = useRouter();
const state = reactive({
userId: null,
index:0,
userIndex:0,
apiData: {
apiData:{
id:'',
},
rules: {
},
dialog: {
isShowDialog: false,
title: '',
submitTxt: '',
},
tableData:[
],
columns:[
],
collectsTableData:[],
collectsColumns:[],
dataLoading: false,
btnLoading: false,
loading: false,
// 填写内容及自定义文本框
formItem: {
addItem:{
name:'',
......@@ -125,42 +89,18 @@ const state = reactive({
task_id:'',
},
dynamicItem: [
//默认显示一条
// {
// name: '',
// value:''
// }
],
userFilled: [
//默认显示一条
// {
// name: '',
// radio:'1',
// }
]
}
});
// 打开弹窗
const openDialog = (norm_id) => {
state.dialog.isShowDialog = true;
state.dialog.title = '子任务详情';
state.apiData.id = norm_id;
/**
* 获取指标详情
*/
const getInfo = ()=>{
state.loading = true
// 清空数据
state.formItem.addItem.name = '';
state.formItem.addItem.level = '';
state.formItem.addItem.sort = '';
state.formItem.addItem.refer = '';
state.formItem.addItem.price = '';
state.formItem.addItem.task_id = '';
state.formItem.addItem.guide = '';
state.formItem.dynamicItem = [];
state.formItem.userFilled = [];
state.tableData=[];
state.columns=[];
state.collectsTableData=[];
state.collectsColumns=[];
normApi().normDetail(state.apiData).then(res => {
normApi().normPartDetail(state.apiData).then(res => {
let addItem = res.data.addItem;
let custom = res.data.custom;
// 数据详情
......@@ -170,144 +110,115 @@ const openDialog = (norm_id) => {
state.formItem.addItem.refer = addItem.refer;
state.formItem.addItem.price =addItem.price;
state.formItem.addItem.task_id= addItem.task_id
state.formItem.addItem.guide= addItem.guide
state.userIndex = 0;
state.index = 0;
state.formItem.addItem.guide= addItem.guide;
custom.forEach(item => {
if(item.user_filled==1){
state.formItem.userFilled.push({name:item.extend_name,radio:item.required+"",remarks:item.extend_remarks});
state.userIndex++
}else{
state.formItem.dynamicItem.push({name:item.extend_name,value:item.extend_value});
state.index++
}
});
state.loading = false
}).catch(() => {
})
}
//领取列表
let receivesList = res.data.receivesList
if(receivesList){
let arr = [
{ label:'序号', prop: 'index',width:'80px'},
// { label:'ID', prop: 'id'},
{ label:'用户名称', prop: 'userInfo.name',width:120},
{ label:'任务名称', prop: 'task_info.name',width:180},
{ label:'指标名称', prop: 'norm_list_info.name',width:180},
];
state.columns = arr;
receivesList.forEach(function(item, index, arr) {
let list = {
'index': index+1,
// 'id':item.id,
'userInfo.name': item.userInfo.name,
'task_info.name': item.task_info.name,
'norm_list_info.name': item.norm_list_info.name,
'status': item.status,
'not_collectible_remarks': item.not_collectible_remarks?item.not_collectible_remarks:"是",
'remark': item.remark,
//校验链接
const checkUrl = (vlaue) =>{
if (/^https?:\/\//.test(vlaue)) {
return true;
} else {
return false;
}
if(item.refer_type == 1){
list['refer_type']='官网/政府';
}else if(item.refer_type ==2 ){
list['refer_type']='权威媒体';
}else if(item.refer_type ==3 ){
list['refer_type']='其他可信信源';
}
/**
* 优先级格式化输出
* @param {*} vlaue
*/
const formatOutputSort = (vlaue) =>{
if (vlaue==1) {
return '低';
} else if(vlaue==2) {
return '中';
}else{
list['refer_type']='/';
return '高';
}
state.tableData.push(list);
item.norm_list_extend.forEach(function(items, indexs, arrs) {
state.columns.forEach(function(itemss, indexss, arrss) {
let vlues = state.columns.map(itemsss => itemsss.prop).indexOf('extend_value'+indexs)
if(vlues== -1){
state.columns.push( { label: items.extend_name, prop: 'extend_value'+indexs,width:180 })
}
/**
* 自定义内容格式化输出
* @param {*} vlaue
*/
const formatOutputCustom = (vlaue) =>{
if(vlaue){
let arr = vlaue.split(",");
let txt = '';
if(arr.length>1){
arr.map((item, index) => {
let str = checkUrl(item);
if(str){
txt+= "<div><a style='color:#409EFF;' href='"+item+"' target ='_blank'>"+(index+1)+"、"+item+"</a></div>";
}else{
txt+= "<div>"+(index+1)+"、"+item+"</div>";
}
});
list['extend_value'+indexs] =items.extend_value;
});
let sign = 0;
item.normCollectsExtend.forEach(function(items, indexs, arrs) {
state.columns.forEach(function(itemss, indexss, arrss) {
let vlues = state.columns.map(iteml => iteml.prop).indexOf('extend_value'+sign+'_')
if(vlues== -1){
state.columns.push( { label: items.extend_name, prop: 'extend_value'+sign+'_',width:180 })
})
return txt;
}else{
return vlaue;
}
});
list['extend_value'+sign+'_'] =items.extend_value;
sign++
// list['extend_value'+'_'+sign] =items.extend_value;
});
});
state.columns.push( { label: '信源类型', prop:'refer_type',width:200 })
state.columns.push( { label: '采集备注', prop:'remark',width:230 })
state.columns.push( { label: '指标状态', prop:'status',width:300 })
// state.columns.push( { label: '图片', prop:'imgPath',width:230 })
// state.columns.push( { label: '是否可采集', prop:'not_collectible_remarks',width:200 })
}else{
return vlaue;
}
}).catch(() => {
})
};
// 关闭弹窗
const closeDialog = () => {
dialogFormRef.value.resetFields();
state.dialog.isShowDialog = false;
};
// 暴露变量
defineExpose({
openDialog,
});
}
// 页面加载时
onMounted(() => {
if(router.currentRoute.value.query.task_id){
state.formItem.addItem.task_id = router.currentRoute.value.query.task_id
// getDepatment()
if(router.currentRoute.value.query.norm_id){
state.apiData.id = router.currentRoute.value.query.norm_id
// state.isHide = true // 如果有任务ID才允许发布
getInfo()
}else{
router.go(-1);
}
state.tableHeight = getCurrentInstance().refs.pageMain.offsetHeight - 80 - 52 + "px";
})
/**
* 返回上一级页面
*/
const backToPreviousPage = () => {
// this.$router.push('/target')
router.go(-1);
}
// 详情信息
const whole= () => {
router.push({
path: '/dataScreening/list/whole',query: {norm_id:state.apiData.id}
});
}
});
</script>
<style scoped lang="scss">
.el-dialog__body {
display: flex;
justify-content: center;
align-content: center;
<style lang="scss" scoped>
.page-main {
height: calc(100vh - 50px - 116px);
}
.el-input.is-disabled{
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
.norm_title{
font-weight:bold;color: #409EFF;
}
:deep(.el-input .el-input__inner){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
.box_info{
margin-bottom: 20px;
}
:deep(.el-input .el-input__wrapper){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
.box_title{
// color: #409EFF;
font-weight: 600;
}
.custom_a{
text-decoration: none !important;
float: left;
}
.el-textarea.is-disabled{
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
:deep(.el-textarea .el-textarea__inner){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
:deep(.el-textarea .el-textarea__wrapper){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
</style>
......@@ -10,11 +10,6 @@
<el-option v-for="(item, index) in state.taskList" :key="index" :label="item.name"
:value="item.id"></el-option>
</el-select>
<!-- <el-input class="search-item" placeholder="请输入子任务名称" v-model="state.apiData.name" size="default"
style="width: 220px;" clearable @change="searchChange()">
</el-input>
<el-button size="default" type="primary" @click="searchChange()" >查询</el-button>
<el-button size="default" @click="reset()" >重置</el-button> -->
</div>
</div>
......@@ -46,10 +41,6 @@
:total="state.tableData.total">
</el-pagination>
</div>
<DetailDialog ref="DetailDialogRef" @refresh="getList()" />
<AddDialog ref="AddDialogRef" @refresh="getList()" />
<EditDialog ref="EditDialogRef" @refresh="getList()" />
<ImporDialog ref="ImporDialogRef" @refresh="getList()" />
</el-card>
</div>
</div>
......@@ -64,17 +55,9 @@ import { ElMessageBox, ElMessage } from 'element-plus';
// 引入组件
const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/breadcrumb.vue'));
const AddDialog = defineAsyncComponent(() => import('/@/views/norm/list/dialog.vue'));
const DetailDialog = defineAsyncComponent(() => import('/@/views/dataScreening/list/details.vue'));
const EditDialog = defineAsyncComponent(() => import('/@/views/norm/list/edit.vue'));
const ImporDialog = defineAsyncComponent(() => import('/@/views/norm/list/impor.vue'));
const router = useRouter();
// 定义变量内容
const AddDialogRef = ref()
const DetailDialogRef = ref()
const EditDialogRef = ref()
const ImporDialogRef = ref()
const multipleTableRef = ref()
const state = reactive({
......@@ -210,8 +193,10 @@ const tableSelection = (val) => {
}
// 详情弹窗
const details= (norm_id) => {
DetailDialogRef.value.openDialog(norm_id);
const details= (id) => {
router.push({
path: '/dataScreening/list/details',query: {norm_id:id}
});
}
......@@ -252,12 +237,9 @@ const multipleExports= () => {
ElMessage.error('导出失败!');
}
multipleTableRef.value.clearSelection();
getList();
}).catch(() => {
getList();
})
}).catch(() => {
getList();
})
}
</script>
......
<template>
<div class="system-role-dialog-container">
<el-dialog title="所有文件" v-model="state.isShowDialog" width="60%" @close="closeDialog" :close-on-click-modal="false">
<el-table border :data="state.tableData" style="width: 100%"
ref="multipleTableRef">
<el-table-column label="序号" type="index" width="100" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="name" width="500" label="文件名称" show-overflow-tooltip align="center">
</el-table-column>
<el-table-column prop="fileurl" width="300" label="地址" show-overflow-tooltip align="center"></el-table-column>
<el-table-column width="200" label="操作" show-overflow-tooltip align="center">
<template #default="scope">
<el-link type="primary" :href="scope.row.url" target="_blank">查看文件</el-link>
</template>
</el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script setup name="systemRoleDialog">
import { claimTasksApi } from '/@/api/claimTasks'
import { ElMessage } from 'element-plus';
import { toolsApi } from '/@/api/tools'
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
// 定义变量内容
const dialogFormRef = ref();
const router = useRouter();
const state = reactive({
isShowDialog:false,
tableData:[],
});
// 打开弹窗
const openDialog = (id) => {
state.tableData = [];
let query = { id:id}
claimTasksApi().normGetPdfList(query).then(res => {
console.log(res)
if(res){
let pdfList = '';
let pdfNameList = '';
if(res.data.fileListPdf&&typeof res.data.fileListPdf =="string"){
pdfList = res.data.fileListPdf.split(',');
}
if(res.data.file_name&&typeof res.data.file_name =="string"){
pdfNameList = res.data.file_name.split(',');
}
pdfList.forEach(function(item, index, arr) {
state.tableData.push({ name:pdfNameList[index],fileurl:item,url:item});
});
console.log(state.tableData)
}else{
ElMessage.success('获取不到相关信息!');
}
state.isShowDialog=true
}).catch(() => {
})
};
// 关闭弹窗
const closeDialog = () => {
state.isShowDialog = false;
};
// 暴露变量
defineExpose({
openDialog,
});
onMounted(() => {
if(router.currentRoute.value.query.task_id){
state.formItem.addItem.task_id = router.currentRoute.value.query.task_id
}
});
</script>
<style scoped lang="scss">
.el-dialog__body {
display: flex;
justify-content: center;
align-content: center;
}
.el-input.is-disabled{
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
:deep(.el-input .el-input__inner){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
:deep(.el-input .el-input__wrapper){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
.el-textarea.is-disabled{
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
:deep(.el-textarea .el-textarea__inner){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
:deep(.el-textarea .el-textarea__wrapper){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
</style>
\ No newline at end of file
<template>
<div class="system-menu-container">
<div class="breadcrumb-box">
<Breadcrumb />
</div>
<div class="header-search flex space-between">
<div>
<el-select v-model="state.apiData.search_task_id" placeholder="请选择任务" size="default" @change="searchChange" clearable filterable style="width:200px;margin-right: 20px;">
<el-option v-for="(item, index) in state.taskList" :key="index" :label="item.name"
:value="item.id"></el-option>
</el-select>
<!-- <el-input class="search-item" placeholder="请输入子任务名称" v-model="state.apiData.name" size="default"
style="width: 220px;" clearable @change="searchChange()">
</el-input>
<el-button size="default" type="primary" @click="searchChange()" >查询</el-button>
<el-button size="default" @click="reset()" >重置</el-button> -->
</div>
</div>
<div class="page-main" v-loading="state.tableData.loading" ref="pageMain">
<el-card shadow="hover" style="height:100%;">
<el-button size="default" type="danger" @click="multipleExports" style="margin-bottom: 10px;">导出</el-button>
<el-table :scrollbar-always-on="true" :row-key="(row) => row.id" :data="state.tableData.data" style="width: 100%" :height="state.tableHeight" @selection-change="tableSelection"
ref="multipleTableRef">
<el-table-column type="selection" width="55" :reserve-selection="true" />
<el-table-column label="序号" type="index" width="100" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="taskPackageInfo.name" width="200"label="任务名称" show-overflow-tooltip align="center">
<template #default="scope">
<el-tag type='danger' effect="plain">{{scope.row.taskPackageInfo.name}}</el-tag>
</template>
</el-table-column>
<el-table-column prop="taskPackageInfo.unit" width="200"label="单位名称" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="name" label="子任务名称" width="200" show-overflow-tooltip align="center">
<template #default="scope">
<span @click="details(scope.row.id)">{{scope.row.name}}</span>
</template>
</el-table-column>
<el-table-column prop="level" label="难度等级" width="100" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="refer" label="参考信源" width="200" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="price" label="单价" width="100" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="sort" label="优先级" width="100" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="created_at" width="180" label="发布时间" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="receivedQuantity" width="200" label="领取进度" show-overflow-tooltip align="center">
<template #default="scope">
<span style="color:#409EFF" v-if="scope.row.type==1">--</span>
<span style="color:#409EFF" v-else>{{scope.row.receivedQuantity}}</span>
</template>
</el-table-column>
<el-table-column prop="name" label="完成进度" width="200"show-overflow-tooltip align="center">
<template #default="scope">
<span style="color:#F56C6C" v-if="scope.row.type==1">--</span>
<span style="color:#F56C6C" v-else>{{scope.row.collectsQuantity}}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right" align="center">
<template #default="scope">
<el-button size="small" type="primary" @click="details(scope.row.id)">查看详情</el-button>
<el-button size="small" type="warning" @click="exportFile(scope.row.id)">导出数据</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-box">
<el-pagination @size-change="onHandleSizeChange" @current-change="onHandleCurrentChange" class="mt15"
:pager-count="5" :page-sizes="[10, 20, 30]" v-model:current-page="state.apiData.page" background
v-model:page-size="state.apiData.limit" layout="total, sizes, prev, pager, next, jumper"
:total="state.tableData.total">
</el-pagination>
</div>
<DetailDialog ref="DetailDialogRef" @refresh="getList()" />
<AddDialog ref="AddDialogRef" @refresh="getList()" />
<EditDialog ref="EditDialogRef" @refresh="getList()" />
<ImporDialog ref="ImporDialogRef" @refresh="getList()" />
</el-card>
</div>
</div>
</template>
<script setup name="taskPackage-list">
import { getCurrentInstance } from 'vue';
import { normApi } from '/@/api/norm/index';
import { taskPackageApi } from '/@/api/taskPackage/index';
import { excelFileApi } from '/@/api/excelFile/index';
import { ElMessageBox, ElMessage } from 'element-plus';
// 引入组件
const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/breadcrumb.vue'));
const AddDialog = defineAsyncComponent(() => import('/@/views/norm/list/dialog.vue'));
// const DetailDialog = defineAsyncComponent(() => import('/@/views/norm/list/details.vue'));
const EditDialog = defineAsyncComponent(() => import('/@/views/norm/list/edit.vue'));
const ImporDialog = defineAsyncComponent(() => import('/@/views/norm/list/impor.vue'));
const router = useRouter();
// 定义变量内容
const AddDialogRef = ref()
const DetailDialogRef = ref()
const EditDialogRef = ref()
const ImporDialogRef = ref()
const multipleTableRef = ref()
const state = reactive({
apiData: {
page: 1,
limit: 10,
name: '',
task_id:'',
search_task_id:'',
},
tableData: {
data: [],
loading: false,
total: 0
},
tableHeight: '30vh',
isHide:false,
taskList:[],
Ids:[],
});
// 获取任务列表
const getTaskList = () => {
taskPackageApi().taskPackageList({page:-1,limit:-1}).then(res => {
state.taskList = res.data
})
}
// 页面加载时
onMounted(() => {
// getDepatment()
if(router.currentRoute.value.query.task_id){
state.apiData.task_id = router.currentRoute.value.query.task_id
state.isHide = true // 如果有任务ID才允许发布
}
getList()
getTaskList()
state.tableHeight = getCurrentInstance().refs.pageMain.offsetHeight - 120 - 32 + "px";
});
const searchChange = () => {
state.apiData.page = 1
getList()
}
// 分页改变
const onHandleSizeChange = (val) => {
state.apiData.limit = val;
getList();
};
const onHandleCurrentChange = (val) => {
state.apiData.page = val;
getList();
};
/**
* 重置按钮
*/
const reset = () => {
state.apiData.page = 1
state.apiData.name = '';
state.apiData.search_task_id = '';
getList()
}
// 获取列表
const getList = () => {
state.tableData.loading = true
normApi().normList(state.apiData).then(res => {
state.tableData.loading = false
state.tableData.data = res.data.data
state.tableData.total = res.data.total
}).catch(() => {
state.tableData.loading = false
})
}
const tableSelection = (val) => {
if(val){
state.Ids = [];
val.forEach(item => {
state.Ids.push(item.id);
});
}
console.log(state.Ids)
}
/**
* 返回上一级页面
*/
const backToPreviousPage = () => {
// this.$router.push('/target')
router.go(-1);
}
// 发布指标弹窗
const release= () => {
AddDialogRef.value.openDialog();
}
// 详情弹窗
const details= (norm_id) => {
DetailDialogRef.value.openDialog(norm_id);
}
// 编辑弹窗
const edit= (norm_id) => {
EditDialogRef.value.openDialog(norm_id);
}
// 导入数据窗口
const importFile= () => {
ImporDialogRef.value.openDialog(state.apiData.task_id);
}
// 导出文件
const exportFile= (id) => {
let query = {id:id}
excelFileApi().normExportFile(query).then(res => {
if(res.data){
let url = res.data;
const iframe = document.createElement('iframe'); // 创建一个HTML 元素
iframe.style.display = 'none'; // 隐藏iframe 防止影响页面
iframe.style.height = 0; // 高度设置0 防止影响页面
iframe.src = url;// 下载链接
document.body.appendChild(iframe); // 这一行必须,iframe挂在到dom树上才会发请求 // 5分钟之后删除
setTimeout(() => { iframe.remove(); }, 5 * 60 * 1000);
ElMessage.success('导出成功,请点击下载列表查看!');
}else{
ElMessage.error('导出失败!');
}
}).catch(() => {
})
}
// 多选导出
const multipleExports= () => {
excelFileApi().multipleExportFile({ids:state.Ids}).then(res => {
excelFileApi().multipleExportFile({ids:state.Ids}).then(res => {
if(res.data){
let url = res.data;
const iframe = document.createElement('iframe'); // 创建一个HTML 元素
iframe.style.display = 'none'; // 隐藏iframe 防止影响页面
iframe.style.height = 0; // 高度设置0 防止影响页面
iframe.src = url;// 下载链接
document.body.appendChild(iframe); // 这一行必须,iframe挂在到dom树上才会发请求 // 5分钟之后删除
setTimeout(() => { iframe.remove(); }, 5 * 60 * 1000);
ElMessage.success('导出成功,请点击下载列表查看!');
}else{
ElMessage.error('导出失败!');
}
multipleTableRef.value.clearSelection();
getList();
}).catch(() => {
getList();
})
}).catch(() => {
getList();
})
}
</script>
<style lang="scss" scoped>
.page-main {
height: calc(100vh - 90px - 75px);
}
</style>
<template>
<div class="system-menu-container">
<div class="breadcrumb-box">
<Breadcrumb />
</div>
<div class="header-search flex space-between">
<div>
<el-page-header @back="backToPreviousPage">
</el-page-header>
</div>
</div>
<div class="page-main" ref="pageMain" v-loading="state.loading">
<el-card shadow="hover">
<el-table :data="state.tableData" border style="width: 100%;" :height="state.tableHeight"
ref="multipleTableRef">
<el-table-column :cell-style="{ 'white-space': 'normal' }" v-for="column in state.columns" :key="column.prop" :label="column.label" :prop="column.prop" :width="column.width" show-overflow-tooltip align="center">
<template #default="scope"><div v-html="formatOutputCustom(scope.row[column.prop],scope.row.id)"></div>
<!-- <span style="color:#409EFF" v-if="column.label =='用户名称'">{{scope.row[column.prop]}}</span>
<span style="color:#909399" v-else-if="column.label =='领取状态' && scope.row[column.prop] ==1">已领取</span>
<span style="color:#E6A23C" v-else-if="column.label =='完成状态' && scope.row[column.prop] ==0">未完成</span>
<span style="color:#409EFF" v-else-if="column.label =='完成状态' && scope.row[column.prop] ==1">已完成</span>
<span v-else>{{scope.row[column.prop]}}</span> -->
</template>
</el-table-column>
</el-table>
<div class="pagination-box">
<el-pagination @size-change="onHandleSizeChange" @current-change="onHandleCurrentChange" class="mt15"
:pager-count="5" :page-sizes="[10, 20, 30]" v-model:current-page="state.apiData.page" background
v-model:page-size="state.apiData.limit" layout="total, sizes, prev, pager, next, jumper"
:total="state.total">
</el-pagination>
</div>
</el-card>
<PdfDialog ref="PdfDialogRef"/>
<!-- @refresh="getList()" -->
</div>
</div>
</template>
<script setup name="systemRoleDialog">
import { normApi } from '/@/api/norm'
import { ElMessage } from 'element-plus';
import { toolsApi } from '/@/api/tools'
import { getPdfUrl } from "/@/utils/getHost.js";
const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/breadcrumb.vue'));
const PdfDialog = defineAsyncComponent(() => import('/@/views/norm/list/pdf.vue'));
const router = useRouter();
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
const PdfDialogRef = ref()
const state = reactive({
loading:false,
apiData: {
id:'',
page: 1,
limit: 10,
},
total: 0,
tableData:[],
columns:[],
collectsTableData:[],
collectsColumns:[],
pdfUrl:'', // 访问pdf列表
});
// 打开页面
const getInfo = () => {
state.tableData=[],
state.columns=[],
state.collectsTableData=[],
state.collectsColumns=[],
state.loading = true
normApi().normWhole(state.apiData).then(res => {
state.total = res.data.total;
let custom = res.data.custom;
let addItem = res.data.addItem
let titleColumn = []; // 表格列标题
custom.forEach(item => {
titleColumn.push(item.extend_name);
});
// 表格列名称
state.columns = [
{ label:'序号', prop: 'index',width:'80px'},
{ label:'ID', prop: 'id'},
{ label:'领取用户', prop: 'userInfo.name',width:120},
{ label:'任务名称', prop: 'task_info.name',width:180},
{ label:'子任务名称', prop: 'norm_info.name',width:180},
{ label:'指标名称', prop: 'norm_list_info.name',width:280},
{ label:'难度等级', prop: 'norm_info.level',width:180},
{ label:'参考信源', prop: 'norm_info.refer',width:180},
{ label:'单价', prop: 'norm_info.price',width:180},
{ label:'参考指南', prop: 'norm_info.guide',width:180},
{ label:'上传文件', prop: 'fileListPdf',width:280},
];
titleColumn.forEach(function(item, index, arr) {
state.columns.push({ label:item, prop: 'extend_name'+index,width:350});
});
//领取列表
let receivesList = res.data.receivesList
receivesList.forEach(function(item, index, arr) {
let list = {
'index': index+1,
'id': item.id,
'userInfo.name': item.userInfo.name,
'task_info.name': item.task_info.name,
'norm_info.name': addItem.name,
'norm_info.level': addItem.level,
'norm_info.refer': addItem.refer?addItem.refer:'/',
'norm_info.price': addItem.price,
'norm_info.guide': addItem.guide?addItem.guide:'/',
'norm_list_info.name': item.norm_list_info.name,
'fileListPdf': item.fileListPdf?item.fileListPdf:'/',
}
state.tableData.push(list);
item.norm_list_extend.forEach(function(items, indexs, arrs) {
// list['extend_name'+indexs] =items.extend_value;
let indexInfo = titleColumn.indexOf(items.extend_name);
if( indexInfo != "-1"){
list['extend_name'+indexInfo] =items.extend_value;
}
});
item.normCollectsExtend.forEach(function(items, indexs, arrs) {
let indexInfo = titleColumn.indexOf(items.extend_name);
if( indexInfo != "-1"){
if(items.extend_value){
list['extend_name'+indexInfo] =items.extend_value;
}else{
list['extend_name'+indexInfo] ='/';
}
}
});
if(item.status == 0){
list['status'] ='已领取、未填写'
}
if(item.status == 1){
list['status'] ='已完成、未审核'
}
if(item.status == 2){
list['status'] ='已审核、未通过'
}
if(item.status == 3){
list['status'] ='已通过、未结算'
}
if(item.status == 4){
list['status'] ='已通过、已结算'
}
console.log(item)
if(item.not_collectible==null){
list['not_collectible'] ='待采集'
list['not_collectible_remarks'] ='/'
}else if(item.not_collectible==0){
list['not_collectible'] ='可采集'
list['not_collectible_remarks'] ='/'
}else{
list['not_collectible'] ='不可采集'
list['not_collectible_remarks'] ='/'
}
});
state.columns.push( { label: '状态', prop:'status',width:350 })
state.columns.push( { label: '是否可采集', prop:'not_collectible',width:200 })
state.columns.push( { label: '不可采集原因', prop:'not_collectible_remarks',width:350 })
state.loading = false
}).catch(() => {
})
};
// 分页改变
const onHandleSizeChange = (val) => {
state.apiData.limit = val;
getInfo();
};
const onHandleCurrentChange = (val) => {
state.apiData.page = val;
getInfo();
};
//校验链接
const checkUrl = (vlaue) =>{
if (/^https?:\/\//.test(vlaue)) {
return true;
} else {
return false;
}
}
//校验链接
function handleClick(id){
PdfDialogRef.value.openDialog(id);
}
/**
* 自定义内容格式化输出
* @param {*} vlaue
*/
const formatOutputCustom = (value,id) =>{
if(value&&typeof value =="string"){
let arr = value.split(',');
let txt = '';
arr.map((item, index) => {
let str = checkUrl(item);
if(str){
if(index==0){
txt+= "<a style='color:#409EFF;cursor:pointer' href='"+item+"' target ='_blank'>"+item+"</a>";
}else if(index>4){
txt= "<div style='color:#409EFF;cursor:pointer' onclick='handleClick("+id+")'>查看所有文件</div>";
}else{
txt+= "<br><br><a style='color:#409EFF;cursor:pointer' href='"+item+"' target ='_blank'>"+item+"</a>";
}
}else{
txt+= item;
}
})
return txt;
}else{
return value;
}
}
// /**
// * 检查数据类型并且将多个逗号分隔成数组
// * @param {*} value
// */
// const inspectionType = (value) =>{
// if(typeof value =="string"){
// let arr = value.split(',');
// return arr;
// }else{
// return [value];
// }
// }
// 暴露变量
defineExpose({
});
onMounted(() => {
window.handleClick = handleClick
if(router.currentRoute.value.query.norm_id){
state.apiData.id = router.currentRoute.value.query.norm_id
// state.isHide = true // 如果有任务ID才允许发布
getInfo()
state.pdfUrl = getPdfUrl()
}else{
router.go(-1);
}
state.tableHeight = getCurrentInstance().refs.pageMain.offsetHeight - 80 - 22 + "px";
});
</script>
<style scoped lang="scss">
.page-main {
height: calc(100vh - 50px - 116px);
}
.norm_title{
font-weight:bold;color: #409EFF;
}
.box_info{
margin-bottom: 20px;
}
.box_title{
// color: #409EFF;
font-weight: 600;
}
.custom_a{
text-decoration: none !important;
float: left;
}
</style>
\ No newline at end of file
......@@ -10,6 +10,10 @@
<el-option v-for="(item, index) in state.taskList" :key="index" :label="item.name"
:value="item.id"></el-option>
</el-select>
<el-select v-model="state.apiData.norm_id" placeholder="请选择子任务" size="default" @change="searchChange" clearable filterable style="width:300px;margin-right: 20px;">
<el-option v-for="(item, index) in state.normList" :key="index" :label="item.name"
:value="item.id"></el-option>
</el-select>
<el-input class="search-item" placeholder="请输入子任务名称" v-model="state.apiData.name" size="default"
style="width: 220px;" clearable @change="searchChange()">
</el-input>
......@@ -63,10 +67,16 @@
<span style="color:#F56C6C" v-else>{{scope.row.collectsQuantity}}</span>
</template>
</el-table-column>
<el-table-column prop="created_at" width="180" label="类型" show-overflow-tooltip align="center">
<template #default="scope">
<span style="color:#F56C6C" v-if="scope.row.type==1">文件导入</span>
<span style="color:#409EFF" v-else>手动发布</span>
</template>
</el-table-column>
<el-table-column label="操作" width="480" fixed="right" align="center">
<template #default="scope">
<el-button size="small" type="primary" @click="details(scope.row.id)">查看详情</el-button>
<el-button size="small" @click="edit(scope.row.id)">修改子任务</el-button>
<el-button size="small" v-if="scope.row.type!=1" @click="edit(scope.row.id)">修改子任务</el-button>
<el-button size="small" type="warning" @click="exportFile(scope.row.id)">导出数据</el-button>
<el-button size="small" v-if="state.admin==1" type="danger" @click="deleteNorm(scope.row.id)">删除子任务</el-button>
</template>
......@@ -115,6 +125,7 @@ const state = reactive({
limit: 10,
name: '',
task_id:'',
norm_id:'',
search_task_id:'',
},
tableData: {
......@@ -127,6 +138,7 @@ const state = reactive({
taskList:[],
Ids:[],
admin:Session.get('userInfo').id, // 1管理员
normList:[],
});
// 获取任务列表
const getTaskList = () => {
......@@ -134,7 +146,12 @@ const getTaskList = () => {
state.taskList = res.data
})
}
// 获取指标列表
const getNormList = () => {
normApi().normList({page:-1,limit:-1}).then(res => {
state.normList = res.data
})
}
// 页面加载时
onMounted(() => {
// getDepatment()
......@@ -144,6 +161,7 @@ onMounted(() => {
}
getList()
getTaskList()
getNormList();
state.tableHeight = getCurrentInstance().refs.pageMain.offsetHeight - 100 - 52 + "px";
});
......@@ -283,9 +301,7 @@ const multipleExports= () => {
ElMessage.error('导出失败!');
}
multipleTableRef.value.clearSelection();
getList();
}).catch(() => {
getList();
})
}
</script>
......
<template>
<div class="system-menu-container">
<div class="page-main" ref="pageMain">
<el-card shadow="hover" style="height:100%;">
asdsad
</el-card>
<div class="system-role-dialog-container">
<el-dialog title="所有文件" v-model="state.isShowDialog" width="60%" @close="closeDialog" :close-on-click-modal="false">
<el-table border :data="state.tableData" style="width: 100%"
ref="multipleTableRef">
<el-table-column label="序号" type="index" width="100" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="name" width="500" label="文件名称" show-overflow-tooltip align="center">
</el-table-column>
<el-table-column prop="fileurl" width="300" label="地址" show-overflow-tooltip align="center"></el-table-column>
<el-table-column width="200" label="操作" show-overflow-tooltip align="center">
<template #default="scope">
<el-link type="primary" :href="scope.row.url" target="_blank">查看文件</el-link>
</template>
</el-table-column>
</el-table>
</el-dialog>
</div>
</div>
</template>
<script setup name="taskPackage-list">
const router = useRouter();
const state = reactive({
apiData: {
page: 1,
},
});
// 页面加载时
onMounted(() => {
// getDepatment()
// if(router.currentRoute.value.query.task_id){
// state.apiData.task_id = router.currentRoute.value.query.task_id
// state.isHide = true // 如果有任务ID才允许发布
// }
// getList()
// getTaskList()
state.tableHeight = getCurrentInstance().refs.pageMain.offsetHeight - 100 - 52 + "px";
});
</script>
<style lang="scss" scoped>
.page-main {
height: calc(100vh - 50px - 126px);
}
</style>
</template>
<script setup name="systemRoleDialog">
import { claimTasksApi } from '/@/api/claimTasks'
import { ElMessage } from 'element-plus';
import { toolsApi } from '/@/api/tools'
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
// 定义变量内容
const dialogFormRef = ref();
const router = useRouter();
const state = reactive({
isShowDialog:false,
tableData:[],
});
// 打开弹窗
const openDialog = (id) => {
state.tableData = [];
let query = { id:id}
claimTasksApi().normGetPdfList(query).then(res => {
console.log(res)
if(res){
let pdfList = '';
let pdfNameList = '';
if(res.data.fileListPdf&&typeof res.data.fileListPdf =="string"){
pdfList = res.data.fileListPdf.split(',');
}
if(res.data.file_name&&typeof res.data.file_name =="string"){
pdfNameList = res.data.file_name.split(',');
}
pdfList.forEach(function(item, index, arr) {
state.tableData.push({ name:pdfNameList[index],fileurl:item,url:item});
});
console.log(state.tableData)
}else{
ElMessage.success('获取不到相关信息!');
}
state.isShowDialog=true
}).catch(() => {
})
};
// 关闭弹窗
const closeDialog = () => {
state.isShowDialog = false;
};
// 暴露变量
defineExpose({
openDialog,
});
onMounted(() => {
if(router.currentRoute.value.query.task_id){
state.formItem.addItem.task_id = router.currentRoute.value.query.task_id
}
});
</script>
<style scoped lang="scss">
.el-dialog__body {
display: flex;
justify-content: center;
align-content: center;
}
.el-input.is-disabled{
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
:deep(.el-input .el-input__inner){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
:deep(.el-input .el-input__wrapper){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
.el-textarea.is-disabled{
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
:deep(.el-textarea .el-textarea__inner){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
:deep(.el-textarea .el-textarea__wrapper){
background:#fff !important;
color: var(--el-radio-text-color) !important;
-webkit-text-fill-color: var(--el-radio-text-color) !important;
}
</style>
\ No newline at end of file
......@@ -4,7 +4,6 @@
<Breadcrumb />
</div>
<div class="header-search flex space-between">
<div @click="getPdfList">123123</div>
<div>
<el-page-header @back="backToPreviousPage">
</el-page-header>
......@@ -32,6 +31,8 @@
</el-pagination>
</div>
</el-card>
<PdfDialog ref="PdfDialogRef"/>
<!-- @refresh="getList()" -->
</div>
</div>
</template>
......@@ -42,12 +43,11 @@
import { toolsApi } from '/@/api/tools'
import { getPdfUrl } from "/@/utils/getHost.js";
const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/breadcrumb.vue'));
const PdfDialog = defineAsyncComponent(() => import('/@/views/norm/list/pdf.vue'));
const router = useRouter();
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
// 定义变量内容
const dialogFormRef = ref();
const PdfDialogRef = ref()
const state = reactive({
loading:false,
......@@ -183,7 +183,10 @@
return false;
}
}
//校验链接
function handleClick(id){
PdfDialogRef.value.openDialog(id);
}
/**
* 自定义内容格式化输出
* @param {*} vlaue
......@@ -196,11 +199,11 @@
let str = checkUrl(item);
if(str){
if(index==0){
txt+= "<a style='color:#409EFF;' href='"+item+"' target ='_blank'>"+item+"</a>";
txt+= "<a style='color:#409EFF;cursor:pointer' href='"+item+"' target ='_blank'>"+item+"</a>";
}else if(index>4){
txt= "<a style='color:#409EFF;' href='"+state.pdfUrl+id+"' target ='_blank'>查看所有文件</a>";
txt= "<div style='color:#409EFF;cursor:pointer' onclick='handleClick("+id+")'>查看所有文件</div>";
}else{
txt+= "<br><br><a style='color:#409EFF;' href='"+item+"' target ='_blank'>"+item+"</a>";
txt+= "<br><br><a style='color:#409EFF;cursor:pointer' href='"+item+"' target ='_blank'>"+item+"</a>";
}
}else{
txt+= item;
......@@ -231,6 +234,7 @@
onMounted(() => {
window.handleClick = handleClick
if(router.currentRoute.value.query.norm_id){
state.apiData.id = router.currentRoute.value.query.norm_id
// state.isHide = true // 如果有任务ID才允许发布
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment