Merge pull request 'master' (#974) from master into dj

Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/974
This commit is contained in:
2025-04-08 16:16:26 +00:00
10 changed files with 251 additions and 97 deletions

View File

@@ -86,3 +86,15 @@ export const shareExportExcel = (allocationId) => {
} }
); );
}; };
export const shareDetailExport= (data) => {
return axios.post(
`${import.meta.env.VITE_BASE_URL}/workflow/mosr/cost/share/export`,
data, {
responseType: 'blob',
headers: {
Authorization: getToken()
}
}
);
};

View File

@@ -32,7 +32,8 @@
<!-- <el-button color="#DED0B2" @click="handleUpload">上传附件</el-button>--> <!-- <el-button color="#DED0B2" @click="handleUpload">上传附件</el-button>-->
<file-upload v-if="!isLineBtn&&uploadState" @getFile="getFile"/> <file-upload v-if="!isLineBtn&&uploadState" @getFile="getFile"/>
<el-button color="#DED0B2" @click="handleEditTag" v-if="activeName!='all'&&activeName!='plus'" style="margin-left: 10px;">编辑 <el-button color="#DED0B2" @click="handleEditTag" v-if="activeName!='all'&&activeName!='plus'&&uploadState"
style="margin-left: 10px;">编辑
</el-button> </el-button>
</div> </div>
<fvTable style="width: 100%;min-height:311px;max-height: 311px" v-if="showAttachmentTable" height="311" <fvTable style="width: 100%;min-height:311px;max-height: 311px" v-if="showAttachmentTable" height="311"
@@ -128,8 +129,8 @@ const executeTableConfig = reactive({
<el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button> <el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button>
{ {
uploadState.value ? uploadState.value ?
<popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'} <popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
onDelete={() => deleteSingleFile(row)}/>:'' onDelete={() => deleteSingleFile(row)}/> : ''
} }
</div> </div>
) )
@@ -241,9 +242,9 @@ const handleTabClick = (item) => {
isEdit.value = false isEdit.value = false
} }
if (item.props.name != 'plus') { if (item.props.name != 'plus') {
if(item.props.name == 'all'){ if (item.props.name == 'all') {
changeFileList('all') changeFileList('all')
}else{ } else {
changeFileList(getTagName(item.props.name)) changeFileList(getTagName(item.props.name))
} }
// if (item.props.name == 'all') { // if (item.props.name == 'all') {
@@ -269,10 +270,9 @@ const compositeParam = (item) => {
} }
} }
const getFile = (val) => { const getFile = (val) => {
// console.log('上传文件', val) console.log('上传文件', val)
let fileObj = compositeParam(val) let fileObj = compositeParam(val)
fileList.value.push(fileObj) fileList.value.push(fileObj)
otherAttachmentList.value.push(fileObj)
handleSubmit(fileList.value) handleSubmit(fileList.value)
} }
@@ -283,12 +283,17 @@ const handleSubmit = async (list) => {
targetState: "30" targetState: "30"
} }
let res = await uploadFileList(params) let res = await uploadFileList(params)
if(res.code !== 1000){ if (res.code !== 1000) {
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: res.msg, message: res.msg,
type: 'error' type: 'error'
}) })
fileList.value=[]
}else{
list.forEach(item => {
otherAttachmentList.value.push(item)
})
} }
getTagsOption() getTagsOption()
} }
@@ -303,18 +308,18 @@ const clickToPreview = (row) => {
filePreviewShow.value = true filePreviewShow.value = true
}) })
} }
const changeFileList=(tag)=>{ const changeFileList = (tag) => {
let params = {} let params = {}
if(tag=='all'){ if (tag == 'all') {
params = { params = {
targetId: route.query.projectId, targetId: route.query.projectId,
targetState: "30", targetState: "30",
} }
}else{ } else {
params = { params = {
targetId: route.query.projectId, targetId: route.query.projectId,
targetState: "30", targetState: "30",
tag:tag tag: tag
} }
} }
showAttachmentTable.value = false showAttachmentTable.value = false

View File

@@ -5,7 +5,7 @@
<div class="article-title"> <div class="article-title">
<Tag dictType="article_type" :value="formData.articleType"/> <Tag dictType="article_type" :value="formData.articleType"/>
<span>{{ formData.articleTime }}</span> <span>{{ formData.articleTime }}</span>
<span>备注{{ formData.remarks }}</span> <span>发文单位{{ formData.remarks }}</span>
</div> </div>
<el-row gutter="20"> <el-row gutter="20">
<el-col :span="24"> <el-col :span="24">

View File

@@ -93,7 +93,7 @@ const articleTableConfig = reactive({
}, },
{ {
prop: 'remarks', prop: 'remarks',
label: '备注', label: '发文单位',
align: 'center' align: 'center'
}, },
{ {

View File

@@ -1,8 +1,8 @@
<template> <template>
<!-- <fvSearchForm :searchConfig="searchConfig" @search="search" style="margin-left: 16px"></fvSearchForm>--> <fvSearchForm :searchConfig="searchConfig" @search="search" style="margin-left: 16px"></fvSearchForm>
<!-- <el-button color="#DED0B2" style="float: left;margin: 0 10px 10px 0" @click="exportTable">导出</el-button>--> <!-- <el-button color="#DED0B2" style="float: left;margin: 0 10px 10px 0" @click="exportTable">导出</el-button>-->
<fvTable ref="tableIns" :tableConfig="tableConfig" @headBtnClick="headBtnClick" style="margin-top: 15px"> <fvTable ref="tableIns" :tableConfig="tableConfig" @headBtnClick="headBtnClick" style="margin-top: 15px" @selectionChange="selectionChange">
<template #empty> <template #empty>
<el-empty description="暂无数据"/> <el-empty description="暂无数据"/>
</template> </template>
@@ -11,51 +11,58 @@
<script setup lang="jsx"> <script setup lang="jsx">
import fvSelect from '@/fvcomponents/fvSelect/index.vue' import fvSelect from '@/fvcomponents/fvSelect/index.vue'
import {toThousands} from '@/utils/changePrice.js'
import { getSubCompOpt } from '@/api/user/user.js'; import { getSubCompOpt } from '@/api/user/user.js';
import {reactive, ref} from "vue"; import {reactive, ref} from "vue";
import {shareExportExcel} from "@/api/expense-manage"; import {shareDetailExport, shareExportExcel} from "@/api/expense-manage";
import {ElMessage} from "element-plus";
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const searchConfig = reactive([ const searchConfig = reactive([
// {
// label: '分摊名称',
// prop: 'shareName',
// component: 'el-input',
// props: {
// placeholder: '请输入分摊名称查询',
// clearable: true,
// filterable: true,
// checkStrictly: true
// }
// },
{ {
label: '支付月份', label: '子项目',
prop: 'apportionmentMonth', prop: 'subProjectName',
component: 'el-date-picker', component: 'el-input',
props: { props: {
placeholder: '请选择支付月份', placeholder: '请输入子项目查询',
clearable: true, clearable: true,
type:'month', filterable: true,
format: 'YYYY-MM', checkStrictly: true
valueFormat:"YYYY-MM" }
},
colProps: {}
}, },
// { // {
// label: '状态', // label: '支付月份',
// prop: 'state', // prop: 'apportionmentMonth',
// component: 'el-date-picker',
// props: {
// placeholder: '请选择支付月份',
// clearable: true,
// type:'month',
// format: 'YYYY-MM',
// valueFormat:"YYYY-MM"
// },
// colProps: {}
// },
// {
// label: '人员性质',
// prop: 'personnelNature',
// component: shallowRef(fvSelect), // component: shallowRef(fvSelect),
// props: { // props: {
// placeholder: '请选择状态', // placeholder: '请选择人员性质',
// clearable: true, // clearable: true,
// cacheKey: 'special_fund' // filterable: true,
// cacheKey: 'nature_of_personnel'
// } // }
// }, // },
]) ])
const tableIns = ref() const tableIns = ref()
const selectData = ref([])
const tableConfig = reactive({ const tableConfig = reactive({
columns: [ columns: [
{
type: 'selection',
prop: 'selection',
},
// { // {
// prop: 'name', // prop: 'name',
// type: 'index', // type: 'index',
@@ -100,7 +107,16 @@ const tableConfig = reactive({
{ {
prop: 'personnelNature', prop: 'personnelNature',
label: '人员性质', label: '人员性质',
align: 'center' align: 'center',
width: 120,
showOverflowTooltip: false,
currentRender: ({row, index}) => {
if (row.personnelNature&&row.personnelNature !== null&&row.personnelNature!==undefined) {
return (<Tag dictType={'nature_of_personnel'} value={row.personnelNature}/>)
} else {
return '--'
}
}
}, },
{ {
prop: 'researchDuration', prop: 'researchDuration',
@@ -126,23 +142,15 @@ const tableConfig = reactive({
api: '/workflow/mosr/cost/share', api: '/workflow/mosr/cost/share',
params: {}, params: {},
btns: [ btns: [
{name: '添加分摊', key: 'add', color: '#DED0B2'} {name: '添加分摊', key: 'add', color: '#DED0B2'},
{name: '导出', key: 'export', color: '#DED0B2'}
], ],
export:{ export:{
open :false, open :false,
} }
}) })
// const exportTable = () => {
// shareExportExcel().then(res => {
// console.log(res)
// let fileName = `科技研发项目工时及成本分摊汇总表.xlsx`
// const blob = new Blob([res.data])
// let a = document.createElement('a')
// a.href = URL.createObjectURL(blob)
// a.download = fileName
// a.click()
// })
// }
const search = (val) => { const search = (val) => {
tableConfig.params = {...val} tableConfig.params = {...val}
tableIns.value.refresh() tableIns.value.refresh()
@@ -152,8 +160,32 @@ const headBtnClick = (key) => {
case 'add': case 'add':
handleAdd() handleAdd()
break; break;
case 'export':
exportTable()
break;
} }
} }
const selectionChange = (data) => {
console.log('data', data)
selectData.value=data.map(item=>item.allocationId)
}
const exportTable = () => {
console.log('selectData',selectData.value)
if (selectData.value.length === 0) {
ElMessage.warning('请选择要导出的费用分摊')
return
}
shareDetailExport(selectData.value).then(res => {
console.log(res)
let fileName = `科技研发项目工时及成本分摊汇总表.xlsx`
const blob = new Blob([res.data])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = fileName
a.click()
})
}
const handleAdd = () => { const handleAdd = () => {
router.push({ router.push({
name: 'Sharedetail/add', name: 'Sharedetail/add',
@@ -172,7 +204,7 @@ const init = async () => {
:deep(.el-table__header) { :deep(.el-table__header) {
.is-leaf:first-child { .is-leaf:first-child {
.cell { .cell {
margin-left: -25px !important; //margin-left: -25px !important;
} }
} }
} }
@@ -180,7 +212,7 @@ const init = async () => {
:deep(.el-table__body) { :deep(.el-table__body) {
.el-table__cell:first-child { .el-table__cell:first-child {
.cell { .cell {
margin-left: -13px !important; //margin-left: -13px !important;
} }
} }
} }

View File

@@ -4,7 +4,8 @@
<el-col :xs="24" :sm="24" :md="24" :lg="17" :xl="17"> <el-col :xs="24" :sm="24" :md="24" :lg="17" :xl="17">
<div class="top-left" id="topLeft"> <div class="top-left" id="topLeft">
<el-card shadow="never"> <el-card shadow="never">
<div class="notice-title">{{getTimePeriod()}}提醒您<span><span>{{ taskTabList[0].num }}</span>个项目待立项</span></div> <div class="notice-title">{{ getTimePeriod() }}提醒您<span><span>{{ taskTabList[0].num }}</span>个项目待立项</span>
</div>
<el-row class="statistics"> <el-row class="statistics">
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6" v-for="(item,index) in taskTabList" :key="index"> <el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6" v-for="(item,index) in taskTabList" :key="index">
<div class="block" :style="{'background-image':'url('+getImgUrl(item.icon)+')'}" <div class="block" :style="{'background-image':'url('+getImgUrl(item.icon)+')'}"
@@ -132,13 +133,16 @@
</el-icon> </el-icon>
</div> </div>
</div> </div>
<div class="notice-block"> <div class="notice-block notice-box">
<div v-if="noticeList&&noticeList.length==0"> <div v-if="noticeList&&noticeList.length==0">
<el-empty image-size="135" description="暂无通知公告~"/> <el-empty image-size="135" description="暂无通知公告~"/>
</div> </div>
<div v-for="(item,index) in noticeList" class="notice" @click="handleGoToArticleDetail(item)"> <div v-for="(item,index) in noticeList" class="notice" @click="handleGoToArticleDetail(item)">
<span>{{ index > 8 ? '' : 0 }}{{ index + 1 }}</span> <span>{{ index > 8 ? '' : 0 }}{{ index + 1 }}</span>
{{ item.articleTitle }} <span>{{ item.articleTitle }}</span>
<span>
{{ item.articleTime }}
</span>
</div> </div>
</div> </div>
</div> </div>
@@ -521,7 +525,7 @@ onMounted(async () => {
helpDocList.value = await getArticleList(2) helpDocList.value = await getArticleList(2)
problemList.value = await getArticleList(3) problemList.value = await getArticleList(3)
}) })
const getTimePeriod=()=>{ const getTimePeriod = () => {
// 获取当前日期和时间 // 获取当前日期和时间
const now = new Date(); const now = new Date();
// 获取当前小时数 // 获取当前小时数
@@ -536,11 +540,11 @@ const getTimePeriod=()=>{
return "中午好"; return "中午好";
} else if (hour >= 14 && hour < 18) { } else if (hour >= 14 && hour < 18) {
return "下午好"; return "下午好";
} else if (hour >= 18 && hour <= 22) { } else if (hour >= 18 && hour <= 22) {
return "晚上好"; return "晚上好";
} else if (hour >= 23 || hour <= 1) { } else if (hour >= 23 || hour <= 1) {
return "午夜好"; return "午夜好";
} else if (hour > 1&& hour <= 5) { } else if (hour > 1 && hour <= 5) {
return "夜深了"; return "夜深了";
} }
} }
@@ -549,7 +553,7 @@ const handleTodoList = (type) => {
router.push({ router.push({
path: '/todolist', path: '/todolist',
}) })
} else if (type == 2){ } else if (type == 2) {
router.push({ router.push({
path: '/donelist', path: '/donelist',
}) })
@@ -563,23 +567,23 @@ const handleGoToArticleDetail = (row) => {
} }
}) })
} }
const goToArticleList = (type,otherHelpType) => { const goToArticleList = (type, otherHelpType) => {
let queryType='' let queryType = ''
if(type){ if (type) {
queryType=type queryType = type
}else{ } else {
console.info("🚀 ~method:'otherHelpType' -----", otherHelpType) console.info("🚀 ~method:'otherHelpType' -----", otherHelpType)
if(otherHelpType=='first'){ if (otherHelpType == 'first') {
queryType= '1' queryType = '1'
}else if(otherHelpType=='second'){ } else if (otherHelpType == 'second') {
queryType= '2' queryType = '2'
}else if(otherHelpType=='third'){ } else if (otherHelpType == 'third') {
queryType= '3' queryType = '3'
} }
} }
router.push({ router.push({
name: 'Manage', name: 'Manage',
query:{ query: {
type: queryType type: queryType
} }
}) })
@@ -784,17 +788,17 @@ const handleView = (row) => {
} }
}) })
} }
// else if (row.targetState == '10' && row.targetId) { // else if (row.targetState == '10' && row.targetId) {
// router.push({ // router.push({
// name: 'Summary/detail', // name: 'Summary/detail',
// query: { // query: {
// projectId: row.targetId, // projectId: row.targetId,
// state: row.state, // state: row.state,
// source: 'home' // source: 'home'
// } // }
// }) // })
// } // }
else if (row.targetState == '10'||row.targetState == '20' || row.targetState == '40' || row.targetState == '50') { else if (row.targetState == '10' || row.targetState == '20' || row.targetState == '40' || row.targetState == '50') {
router.push({ router.push({
name: 'Implementation/detail', name: 'Implementation/detail',
query: { query: {
@@ -1457,6 +1461,34 @@ const handleView = (row) => {
} }
} }
.notice-box {
.notice {
display: flex;
justify-content: space-between;
> span:first-child {
margin-right: 10px;
margin-left: 10px;
color: #1476E3;
font-weight: bold;
font-size: 16px;
}
> span:nth-child(2) {
display: block;
width: 65%;
overflow: hidden;
text-overflow: ellipsis;
}
&:hover {
color: #1476E3;
background: #F6FBFE;
}
}
}
.notice-block { .notice-block {
height: 452px; height: 452px;
//height: 100%; //height: 100%;

View File

@@ -393,7 +393,7 @@ const getTagName = (type) => {
case 'approval': case 'approval':
return '项目立项' return '项目立项'
case 'execute': case 'execute':
return '项目实施' return '项目验收'
case 'archivist': case 'archivist':
return '项目归档' return '项目归档'
case 'phase': case 'phase':

View File

@@ -21,15 +21,24 @@
<span>{{ toThousands(formData.residualAmount) }}</span> <span>{{ toThousands(formData.residualAmount) }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<baseTitle title="介绍"></baseTitle> <!-- <baseTitle title="介绍"></baseTitle>-->
<!-- <el-col :span="24">-->
<!-- <el-form-item>-->
<!-- <el-card style="width: 100%">-->
<!-- <div v-html="formData.introduce">-->
<!-- </div>-->
<!-- </el-card>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="24"> <el-col :span="24">
<el-form-item> <el-form-item label="专项资金情况说明" >
<el-card style="width: 100%"> <div style="white-space: pre-wrap">{{formData.introduce}}
<div v-html="formData.introduce"> </div>
</div>
</el-card>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row style="margin-top: -18px;" class="projects">
<baseTitle title="关联项目"></baseTitle> <baseTitle title="关联项目"></baseTitle>
<el-col :span="24"> <el-col :span="24">
<el-form-item> <el-form-item>
@@ -41,6 +50,8 @@
</fvTable> </fvTable>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row style="margin-top: -18px;" class="projects">
<baseTitle title="附件文件"></baseTitle> <baseTitle title="附件文件"></baseTitle>
<el-col :span="24"> <el-col :span="24">
<el-form-item> <el-form-item>
@@ -137,7 +148,7 @@ const projectTable = reactive({
prop: 'startTime', prop: 'startTime',
label: '项目时间', label: '项目时间',
align: 'center', align: 'center',
width: 150, width: 180,
}, },
// { // {
// prop: 'oper', // prop: 'oper',

View File

@@ -211,7 +211,7 @@ const schema = computed(() => {
) )
}, },
{ {
label: '所属业务板块', label: '业务板块',
prop: 'businessSegment', prop: 'businessSegment',
colProps: { colProps: {
span: 24 span: 24
@@ -258,6 +258,7 @@ const schema = computed(() => {
</div> </div>
) )
}, },
{ {
label: '预估经费预算', label: '预估经费预算',
prop: 'economicEstimate', prop: 'economicEstimate',
@@ -274,6 +275,22 @@ const schema = computed(() => {
</div> </div>
) )
}, },
{
label: '实际经费预算',
prop: 'actualEconomicEstimate',
colProps: {
span: 6
},
component: () => (
<div>
{
baseFormData.value?.actualEconomicEstimate ?
<span>{toThousands(baseFormData.value?.actualEconomicEstimate)}</span>
: <span>{'--'}</span>
}
</div>
)
},
{ {
label: '产学研联合', label: '产学研联合',
prop: 'industryUniversityResearch', prop: 'industryUniversityResearch',
@@ -320,9 +337,27 @@ const schema = computed(() => {
span: 24 span: 24
} }
}, },
{ {
label: '预估专项资金(元)', label: '预估专项资金(元)',
prop: 'specialFundAmount', prop: 'forecastSpecialFundAmount',
colProps: {
span: 24
},
component: () => (
<div>
{
baseFormData.value?.forecastSpecialFundAmount ?
<span>{toThousands(baseFormData.value?.forecastSpecialFundAmount)}</span>
: <span>{'--'}</span>
}
</div>
)
},
{
label: '实际专项资金(元)',
prop: 'forecastSpecialFundAmount',
colProps: { colProps: {
span: 24 span: 24
}, },
@@ -336,12 +371,36 @@ const schema = computed(() => {
</div> </div>
) )
}, },
{
label: '是否在预算内',
prop: 'isWithinBudget',
colProps: {
span: 24
},
component: () => (
<div>
{
baseFormData.value?.isWithinBudget!=null ? baseFormData.value?.isWithinBudget?
<span>{'预算内'}</span>
: <span>{'预算外'}</span>:'--'
}
</div>
)
},
{ {
label: '部门分管领导', label: '部门分管领导',
prop: 'optionalChargeLeadership', prop: 'optionalChargeLeadership',
colProps: { colProps: {
span: 24 span: 24
} }
},
{
label: '主项目',
prop: 'masterProjectName',
colProps: {
span: 24
}
} }
] ]
}) })
@@ -579,6 +638,9 @@ watchEffect(() => {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep(.el-step__title){
font-size: 14px;
}
.steps-box { .steps-box {
padding: 10px 0; padding: 10px 0;
} }

View File

@@ -94,7 +94,7 @@
</el-form-item> </el-form-item>
</div> </div>
<div v-if="data.state==='5'" style="margin-bottom: 15px"> <div v-if="data.state==='5'" style="margin-bottom: 15px">
<baseTitle title="前置流程"></baseTitle> <baseTitle title="前置流程" v-if="localFormData.preProcess"></baseTitle>
<div style="display: flex;align-items: center;flex-wrap: wrap;"> <div style="display: flex;align-items: center;flex-wrap: wrap;">
<div v-for="(item,index) in localFormData.preProcess" :key="item.requestId"> <div v-for="(item,index) in localFormData.preProcess" :key="item.requestId">
<a :href="item.baseUrl" target="_blank" <a :href="item.baseUrl" target="_blank"