Commit 7f2dbeee authored by wangxl's avatar wangxl
parents a56b3b23 6d7bfffb
...@@ -205,6 +205,9 @@ export default { ...@@ -205,6 +205,9 @@ export default {
getPersonById (params) { getPersonById (params) {
return fetch(`/v1/science-admin/com-person/getPersonById`, params) return fetch(`/v1/science-admin/com-person/getPersonById`, params)
}, },
getPersonByCertId (params) {
return fetch(`/v1/science-admin/com-person/getPersonByCertId`, params)
},
getAppPersonInfo () { getAppPersonInfo () {
return fetch('/v1/science-admin/com-person/getAppPersonInfo') return fetch('/v1/science-admin/com-person/getAppPersonInfo')
}, },
...@@ -466,6 +469,23 @@ export default { ...@@ -466,6 +469,23 @@ export default {
return fetch(`/v1/science-admin/com-project/projectExport/${params.id}`, params, 'get', 'json') return fetch(`/v1/science-admin/com-project/projectExport/${params.id}`, params, 'get', 'json')
}, },
}, },
talent: {
getListByPage (params) {
return fetch(`/v1/science-admin/com-talent-apply/getListByPage`, params)
},
getCount (params) {
return fetch(`/v1/science-admin/com-talent-apply/getCount`, params)
},
getNewTalentApply () {
return fetch(`/v1/science-admin/com-talent-apply/getNewTalentApply`)
},
getTalentApplyById (params) {
return fetch(`/v1/science-admin/com-talent-apply/getTalentApplyById`, params)
},
save (params) {
return fetch(`/v1/science-admin/com-talent-apply/save`, params, 'post', 'json')
},
},
task: { task: {
getListByPage (params) { getListByPage (params) {
return fetch(`/v1/science-admin/com-project-task/getListByPage`, params) return fetch(`/v1/science-admin/com-project-task/getListByPage`, params)
...@@ -610,7 +630,10 @@ export default { ...@@ -610,7 +630,10 @@ export default {
}, },
getBatchList (params) { getBatchList (params) {
return fetch('/v1/science-admin/com-batch/getBatchList', params) return fetch('/v1/science-admin/com-batch/getBatchList', params)
} },
getCurrentYearTalentBatch (params) {
return fetch('/v1/science-admin/com-batch/getCurrentYearTalentBatch', params)
},
}, },
//系统管理接口 //系统管理接口
systemManage: { systemManage: {
......
...@@ -119,6 +119,7 @@ export const routes = [ ...@@ -119,6 +119,7 @@ export const routes = [
{ path: '/query/project', name: '项目申报查询1', component: () => import('@/views/query/project/Index.vue'), meta: { title: '项目申报查询', icon: '', noCache: true } }, { path: '/query/project', name: '项目申报查询1', component: () => import('@/views/query/project/Index.vue'), meta: { title: '项目申报查询', icon: '', noCache: true } },
{ path: '/query/task', name: '合同书查询1', component: () => import('@/views/query/task/Index.vue'), meta: { title: '合同书查询', icon: '', noCache: true } }, { path: '/query/task', name: '合同书查询1', component: () => import('@/views/query/task/Index.vue'), meta: { title: '合同书查询', icon: '', noCache: true } },
{ path: '/query/check', name: '中期考核上报查询1', component: () => import('@/views/query/check/Index.vue'), meta: { title: '中期考核上报查询', icon: '', noCache: true } }, { path: '/query/check', name: '中期考核上报查询1', component: () => import('@/views/query/check/Index.vue'), meta: { title: '中期考核上报查询', icon: '', noCache: true } },
{ path: '/report/talent', name: '人才申报', component: () => import('@/views/report/talent/Index.vue'), meta: { title: '人才申报', icon: '', noCache: true } },
] ]
}, },
{ {
...@@ -244,7 +245,7 @@ export const routes = [ ...@@ -244,7 +245,7 @@ export const routes = [
hidden: false, hidden: false,
children: [ children: [
{ path: '/timeSet/task', name: '合同书时间设置', component: () => import('@/views/timeSet/taskTimeSet/Index.vue'), meta: { title: '合同书时间设置', icon: '', noCache: true } }, { path: '/timeSet/task', name: '合同书时间设置', component: () => import('@/views/timeSet/taskTimeSet/Index.vue'), meta: { title: '合同书时间设置', icon: '', noCache: true } },
{ path: '/setting/batch', name: '申报批次设置', component: () => import('@/views/timeSet/batch/Index.vue'), meta: { title: '申报批次设置', icon: '', noCache: true } }, { path: '/setting/batch', name: '项目申报批次设置', component: () => import('@/views/timeSet/batch/Index.vue'), meta: { title: '项目申报批次设置', icon: '', noCache: true } },
{ path: '/system/evaluationStandard', name: '年度评审标准设置', component: () => import('@/views/system/evaluationStandard/index.vue'), meta: { title: '年度评审标准设置', icon: '', noCache: true } }, { path: '/system/evaluationStandard', name: '年度评审标准设置', component: () => import('@/views/system/evaluationStandard/index.vue'), meta: { title: '年度评审标准设置', icon: '', noCache: true } },
//后台 //后台
{ path: '/system/role', name: '角色管理', component: () => import('@/views/system/role/index.vue'), meta: { title: '角色管理', icon: '', noCache: true } }, { path: '/system/role', name: '角色管理', component: () => import('@/views/system/role/index.vue'), meta: { title: '角色管理', icon: '', noCache: true } },
...@@ -252,6 +253,7 @@ export const routes = [ ...@@ -252,6 +253,7 @@ export const routes = [
{ path: '/system/role/menu', name: '角色菜单管理', component: () => import('@/views/system/role/roleRight.vue'), meta: { title: '角色权限管理', icon: '', noCache: true } }, { path: '/system/role/menu', name: '角色菜单管理', component: () => import('@/views/system/role/roleRight.vue'), meta: { title: '角色权限管理', icon: '', noCache: true } },
{ path: '/system/evaluation', name: '评审表设置', component: () => import('@/views/system/evaluation/index.vue'), meta: { title: '评审表设置', icon: '', noCache: true } }, { path: '/system/evaluation', name: '评审表设置', component: () => import('@/views/system/evaluation/index.vue'), meta: { title: '评审表设置', icon: '', noCache: true } },
{ path: '/system/set', name: '系统设置', component: () => import('@/views/system/set/index.vue'), meta: { title: '系统配置', icon: '', noCache: true } }, { path: '/system/set', name: '系统设置', component: () => import('@/views/system/set/index.vue'), meta: { title: '系统配置', icon: '', noCache: true } },
{ path: '/setting/talentBatch', name: '人才申报批次设置', component: () => import('@/views/timeSet/batch/talentBatch.vue'), meta: { title: '人才申报批次设置', icon: '', noCache: true } },
] ]
}, },
{ {
......
...@@ -335,8 +335,24 @@ export default { ...@@ -335,8 +335,24 @@ export default {
if (data) { if (data) {
const { dataList = [], total = 0 } = data const { dataList = [], total = 0 } = data
dataList.forEach(e => { dataList.forEach(e => {
e.projClassName = e.projClass === 1 ? "一般项目" : "重点项目"
e.startDate = moment(e.startDate).format('YYYY-MM-DD') e.startDate = moment(e.startDate).format('YYYY-MM-DD')
e.endDate = moment(e.endDate).format('YYYY-MM-DD') e.endDate = moment(e.endDate).format('YYYY-MM-DD')
// 技术专家
if (!!e.technologyScore)
e.gradeScore1 = e.technologyScore + '/' + e.technologyAverageScore
else
e.gradeScore1 = ' 0/0'
// 财务专家
if (!!e.economyScore)
e.gradeScore2 = e.economyScore + '/' + e.economyAverageScore
else
e.gradeScore2 = ' 0/0'
// 最后得分
if (!!e.calculateScore)
e.gradeScore = e.calculateScore + ''
else
e.gradeScore = '0'
}) })
this.$ToDoExcel(`项目审核列表`, tableColumnsName(this.excelCol), filterExportExcelData(this.excelCol, dataList)) this.$ToDoExcel(`项目审核列表`, tableColumnsName(this.excelCol), filterExportExcelData(this.excelCol, dataList))
this.loading = false this.loading = false
......
...@@ -53,13 +53,13 @@ export default { ...@@ -53,13 +53,13 @@ export default {
}) })
}, },
getSpecInfo (key) { getSpecInfo (key) {
console.log(this.specArray, this.value,1) //console.log(this.specArray, this.value,1)
let newArray = this.specArray.filter( let newArray = this.specArray.filter(
function (el) { function (el) {
return el.key == key return el.key == key
} }
); );
console.log(this.specArray, newArray, this.value,2) //console.log(this.specArray, newArray, this.value,2)
if (!!newArray && newArray.length > 0) if (!!newArray && newArray.length > 0)
return [newArray[0].ppkey, newArray[0].pkey, newArray[0].key] return [newArray[0].ppkey, newArray[0].pkey, newArray[0].key]
else else
...@@ -85,6 +85,7 @@ export default { ...@@ -85,6 +85,7 @@ export default {
value: { value: {
handler (value) { handler (value) {
if (!!value) { if (!!value) {
this.loadSpecList()
// this.selected = getSpecArray(this.value) // this.selected = getSpecArray(this.value)
// if (!!this.selected && this.selected.length == 3) { // if (!!this.selected && this.selected.length == 3) {
// this.$emit("input", this.selected[2]) // this.$emit("input", this.selected[2])
......
...@@ -400,35 +400,58 @@ export default { ...@@ -400,35 +400,58 @@ export default {
}, },
exportEvaluationExcel () { exportEvaluationExcel () {
this.loading = true this.loading = true
const rowMarks = ['A', 'B', 'C', 'D', 'E', 'P', 'Q']
const rowMarks = ['A', 'B', 'C', 'D', 'K']
this.$api.statistical.getEvaluationExportExcel({ reportYear: this.reportYear, startRow: 3, rowMarks: rowMarks }).then(({ data = {} }) => { this.$api.statistical.getEvaluationExportExcel({
reportYear: this.reportYear,
startRow: 3,
rowMarks: rowMarks
}).then(({ data = {} }) => {
if (data) { if (data) {
this.eTableData = data.evaluationList this.eTableData = data.evaluationList
this.eMergeList = data.mergeList this.eMergeList = data.mergeList
import('@/views/utils/Export2Excel').then(excel => { import('@/views/utils/Export2Excel').then(excel => {
const multiHeader = [[this.reportYear + '项目评审结果列表', '', '']] // 标题 try {
const header = ['项目编号', '项目名称', '二级学科', '所属市州', '证件号', '专家姓名', '专家单位', '手机号', '评分', '评审内容', '平均分'] // 表头 const multiHeader = [[this.reportYear + '项目评审结果列表', '', '']]
const filterVal = ['projNo', 'projName', 'knowledgeName', 'unitName', 'certId', 'personName', 'expertUnitName', 'mobile', 'totalScore', 'remark', 'averageScore'] // 数据属性 const header = ['项目编号', '项目名称', '一级学科', '二级学科', '所属市州', '证件号', '专家姓名', '专家单位', '手机号', '专家类型', '专家评分', '评审类别', '是否支持立项', '评审内容', '评审状态', '总分', '最终得分']
const list = this.eTableData //请求来的数据 const filterVal = ['projNo', 'projName', 'parentName', 'knowledgeName', 'unitName', 'certId', 'personName', 'expertUnitName', 'mobile', 'expertTypeName', 'evaluationScore', 'evaluationTypeName', 'supportStateName', 'remark', 'auditStateName', 'totalScore', 'calculateScore']
const merges = ['A1:K1'].concat(this.eMergeList) //需要合并的单元格 const list = this.eTableData
const data = list.map(item => filterVal.map(j => item[j])) // 转换二维数组 const merges = ['A1:Q1'].concat(this.eMergeList)
const filename = this.reportYear + '项目评审结果列表' const data = list.map(item => filterVal.map(j => item[j]))
excel.exportJsonToExcel({ const filename = this.reportYear + '项目评审结果列表'
multiHeader, // 标题--非必要
header, // 表头 excel.exportJsonToExcel({
data, // 具体数据--二维数组 multiHeader,
merges, // 合并--非必要 header,
filename, // 下载文件名 data,
autoWidth: true, // 不自动调整列宽 merges,
}) filename,
autoWidth: true,
})
this.$message.success('导出成功')
} catch (err) {
console.error('Excel导出错误:', err)
this.$message.error(`导出失败: ${err.message || '未知错误'}`)
}
this.loading = false this.loading = false
this.eTableData = [] this.eTableData = []
this.eMergeList = [] this.eMergeList = []
}).catch(() => { this.loading = false }) }).catch(err => {
console.error('加载Export2Excel模块错误:', err)
this.$message.error(`加载导出模块失败: ${err.message || '未知错误'}`)
this.loading = false
})
} }
}).catch(() => { this.loading = false }) }).catch(err => {
console.error('获取评审数据错误:', err)
this.$message.error(`获取评审数据失败: ${err.message || '未知错误'}`)
this.loading = false
this.eTableData = []
this.eMergeList = []
})
}, },
exportProjGroupScoreExcel () { exportProjGroupScoreExcel () {
this.loading = true this.loading = true
...@@ -441,10 +464,10 @@ export default { ...@@ -441,10 +464,10 @@ export default {
import('@/views/utils/Export2Excel').then(excel => { import('@/views/utils/Export2Excel').then(excel => {
const multiHeader = [[this.reportYear + '项目分组排名列表', '', '']] // 标题 const multiHeader = [[this.reportYear + '项目分组排名列表', '', '']] // 标题
const header = ['组名', '组内排名', '项目编号', '项目名称', '一级学科', '二级学科', '申报单位', '申报人', '所属市(州)', '总分', '平均分'] // 表头 const header = ['组名', '组内排名', '项目编号', '项目名称', '一级学科', '二级学科', '申报单位', '申报人', '所属市(州)', '技术专家评分', '财务专家评分', '最终得分'] // 表头
const filterVal = ['groupName', 'orderNo', 'projNo', 'projName', 'knowledgeParentName', 'knowledgeName', 'appUnitName', 'personName', 'unitName', 'totalScore', 'averageScore'] // 数据属性 const filterVal = ['groupName', 'orderNo', 'projNo', 'projName', 'parentName', 'knowledgeName', 'appUnitName', 'personName', 'unitName', 'gradeScore1', 'gradeScore2', 'calculateScore'] // 数据属性
const list = this.eTableData //请求来的数据 const list = this.eTableData //请求来的数据
const merges = ['A1:I1'].concat(this.eMergeList) //需要合并的单元格 const merges = ['A1:L1'].concat(this.eMergeList) //需要合并的标题头单元格
const data = list.map(item => filterVal.map(j => item[j])) // 转换二维数组 const data = list.map(item => filterVal.map(j => item[j])) // 转换二维数组
const filename = this.reportYear + '项目分组排名列表' const filename = this.reportYear + '项目分组排名列表'
excel.exportJsonToExcel({ excel.exportJsonToExcel({
......
<template>
<div class="app-content">
<a-form :form="form" :model="searchForm" layout="inline" class="search_form">
<a-form-item>
<a-input placeholder="身份证号" v-model="searchForm.certId" :maxLength="100" style="width: 180px" />
</a-form-item>
<a-form-item>
<a-input placeholder="姓名" v-model="searchForm.personName" :maxLength="100" style="width: 180px" />
</a-form-item>
<a-form-item>
<a-button type="primary" icon="search" @click="search">搜索</a-button>
<a-button icon="reload" style="margin-left: 10px" @click="reset" class="bt-normal">重置</a-button>
</a-form-item>
</a-form>
<div style="width:100%;margin-bottom: 8px;">
<div style="display: inline-block;;width:50%">
<btn-group :data="tabDate" :itemCount="itemCount" v-model="activekey" @change="callback" />
</div>
<div style="display: inline-block;;width:50%;text-align: right;">
<a-button type="primary" style="margin-right:8px;" v-if="(display && isButten)" @click="ApplyTalent">人才申报</a-button>
<a-button type="primary" @click="exportData" icon="download">Excel</a-button>
</div>
</div>
<a-divider style="height: 1px; background-color: #e8e8e8;" />
<span class="form-description"> ※填报时间:{{ description }}</span>
<a-table :dataSource="tableData" :columns="columns" rowKey="id" :pagination="false" :loading="loading">
<template slot="stateSwitch" slot-scope="record">
<a-switch checked-children="启用" un-checked-children="停用" :checked="checkedState(record)" @change="switchChange($event, record)" />
</template>
<template slot="option" slot-scope="record">
<a-button type="link" size="small" @click="recordClick(record,'view')">查看</a-button>
<a-button type="link" size="small" @click="recordClick(record,'edit')">修改</a-button>
<a-button type="link" size="small" @click="recordClick(record,'reset')">重置密码</a-button>
</template>
</a-table>
<a-pagination v-if="pagination.total > 0" :total="pagination.total" show-size-changer show-quick-jumper v-model="pagination.pageIndex" :page-size="pagination.pageSize" :page-size-options="pagination.pageSizeOptions" @showSizeChange="showSizeChange" @change="change" :showTotal="() => `共 ${pagination.total} 条`" />
<a-modal v-model="visibleEdit" v-if="visibleEdit" title="人才申报创建/修改" width="94%" :footer="null" :dialog-style="{ top: '8%' }" destroyOnClose :maskClosable="false">
<talent-create v-model="id" @close="closeWindow"></talent-create>
</a-modal>
</div>
</template>
<script>
import { isEmptyParams, filterExportExcelData, tableColumnsName } from "@/views/utils/common"
import talentCreate from "@/views/report/talent/components/talentCreate"
export default {
name: "reportTalent",
components: {
talentCreate
},
data() {
return {
form: this.$form.createForm(this, { name: 'advanced_search' }),
activekey: '1',
tabDate: [
{ key: "1", tab: "未上报" },
{ key: "2", tab: "返回修改" },
{ key: "3", tab: "已上报" },
{ key: "4", tab: "所有" },
],
itemCount: [0, 0, 0, 0, 0],
// 表单
searchForm: { certId: null, personName: null, talentState: 1, reportYear: null, knowledgeId: null },
tableData: [],
columns: [
{ title: "身份证号", dataIndex: 'certId', align: 'center' },
{ title: '姓名', scopedSlots: { customRender: 'personInfo' }, align: 'center' },
{ title: '性别', dataIndex: 'sex', align: 'center' },
{ title: '手机号', dataIndex: 'mobile', align: 'center' },
{ title: '专业', dataIndex: 'specName', align: 'center' },
{ title: '职称', dataIndex: 'titleName', align: 'center' },
{ title: '申报年度', dataIndex: 'reportYear', align: 'center' },
{ title: '状态', scopedSlots: { customRender: 'state' }, align: 'center' },
{ title: '操作', scopedSlots: { customRender: 'option' }, align: 'center', fixed: 'right', width: 180, },
],
pagination: {
pageIndex: 1, pageSize: this.$defaultPageSize, total: 0, pageSizeOptions: this.$defaultPageSizeOptions,
},
id: null,
isButten: true,//false
display: true,
loading: false,
visibleView: false,
visibleEdit: false,
description: '',
};
},
created () {
this.getYear()
},
methods: {
getYear () {
this.$api.batch.getCurrentYearTalentBatch({ type: 1 }).then(({ data = {} }) => {
if (data) {
this.isButten = data.disabled
this.description = data.description
this.searchForm.reportYear = data.year
this.getListByPage()
}
}).catch(() => { })
},
getListByPage () {
this.getCount()
this.loading = true
let pars = isEmptyParams(this.searchForm)
let par = { ...pars, pageIndex: this.pagination.pageIndex, pageSize: this.pagination.pageSize }
this.$api.talent.getListByPage(par).then(({ data = {} }) => {
if (data) {
const { dataList = [], total = 0 } = data
this.tableData = dataList
this.pagination.total = total
this.loading = false
} this.loading = false
}).catch(() => { this.loading = false })
},
getCount () {
this.$api.talent.getCount({ reportYear: this.searchForm.reportYear }).then(({ data = {} }) => {
if (data) {
this.itemCount = [data.count1, data.count2, data.count3, data.count4, data.count5]
}
}).catch(() => { })
},
showSizeChange (current, pageSize) {
this.pagination.pageSize = pageSize
this.getListByPage()
},
change () {
this.getListByPage()
},
search () {
this.pagination.pageIndex = 1
this.getListByPage()
},
reset () {
this.searchForm.certId = null
this.searchForm.personName = null
this.searchForm.knowledgeId = null
this.pagination.pageIndex = 1
this.getListByPage()
},
callback (key) {
if (key == '1')
this.display = true
else
this.display = false
this.searchForm.projState = key
this.getListByPage()
},
ApplyTalent () {
this.id = null
this.visibleEdit = true
},
closeWindow (value) {
if (value === 'submit') {
this.visibleEdit = false
this.getListByPage()
} else if (value === 'save') {
this.getListByPage()
}
else if (value === 'error') {
this.id = null
this.visibleEdit = false
this.visibleView = false
}
},
recordClick (record, type) {
if (type === 'view') {
this.id = record.id
this.visibleView = true
} else if (type === 'edit') {
this.id = record.id
this.visibleEdit = true
} else if (type === 'delete') {
}
},
exportData() {
}
}
};
</script>
<template>
<div class="app-content" style="height: 76vh;overflow: auto;">
<a-spin :spinning="loading" style="width: 100%;height: 100%;">
<div class="page-steps">
<a-steps size="small" :current="current" @change="onChange">
<a-step :status="item.status" v-for="(item,index) in stepsArray" :key="index+'stepsArray'" :title="item.title" />
</a-steps>
</div>
<div class="page-content">
<talent-edit v-model="value" @close="closeWindow" @load="onLoad" @onStepChange="onStepChange" :completeStatus.sync=completeStatus :stepsArray.sync="stepsArray" ref="talentCreate"></talent-edit>
</div>
<div class="page-footer">
<a-button v-if="currSteps > 0" style="margin-left: 40px" type="primary" @click="prev">上一步</a-button>
<a-button style="margin-left: 40px" type="primary" @click="save">保 存</a-button>
<a-button v-if="currSteps < stepsArray.length - 1" style="margin-left: 40px" type="primary" @click="next">下一步</a-button>
<a-button v-if="currSteps == stepsArray.length - 1" style="margin-left: 40px" type="primary" @click="submit">完成填写</a-button>
</div>
</a-spin>
</div>
</template>
<script>
import talentEdit from "@/views/report/talent/components/talentEdit"
export default {
name: "talentCreate",
components: {
talentEdit
},
props: {
value: {
type: String,
default: () => {
return null
}
},
},
data() {
return {
loading: false,
current: 10,
currSteps: 0,
stepsArray: [
{ status: "process", title: '申报人基本情况', showStatus: true },
{ status: "wait", title: '申报人简历', showStatus: false },
{ status: "wait", title: '申报人科研成绩', showStatus: false },
{ status: "wait", title: '科学研究规划及团队人员名单', showStatus: false },
{ status: "wait", title: '经费预算及培养计划和目标', showStatus: false },
{ status: "wait", title: '附件', showStatus: false }
],
completeStatus: "0,0,0,0,0,0"
};
},
created() {
},
methods: {
stepsChange (e) {
this.currSteps = e
this.changeSteps(this.currSteps)
},
next () {
this.$refs.talentCreate.submit(this.currSteps, true)
},
prev () {
this.currSteps--;
this.changeSteps(this.currSteps)
},
onChange (e) {
if (e != this.currSteps) {
var arr = this.completeStatus.split(',')
if (arr[e] == "1") {
this.loading = true
this.changeSteps(e)
this.loading = false
} else {
this.$message.error('所选步骤没填写完成,请填写当前步骤后点【下一步】跳转!')
}
}
},
onStepChange (e) {
this.completeStatus = e.state
this.changeSteps(e.step)
},
changeSteps (e) {
this.currSteps = e
var clone = [].concat(this.stepsArray)
clone.forEach(e => {
e.showStatus = false
})
clone[e].showStatus = true;
this.stepsArray = clone
this.getCompleteStatus(e, this.completeStatus)
},
getCompleteStatus (step, completeStatus) {
var arr = completeStatus.split(',')
if (!!arr && arr.length > 0) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == "1") {
this.stepsArray[i].status = "finish"
} else {
this.stepsArray[i].status = "wait"
}
}
this.stepsArray[step].status = "process"
}
},
save () {
this.$refs.talentCreate.save(this.currSteps)
},
submit () {
this.$refs.talentCreate.submit(this.currSteps, false)
},
closeWindow (value) {
this.$emit('close', value)
},
onLoad (value) {
this.loading = value
},
},
};
</script>
<style scoped lang="less">
::v-deep .ant-spin-container {
width: 100%;
height: 100%;
}
::-webkit-scrollbar {
width: 8px;
height: 6px;
}
.page-steps {
width: 100%;
height: 40px;
padding: 8px 20px 5px 20px;
background: rgb(248, 248, 248);
border: 1px 1px 0px 1px solid #e8e8e8;
}
.page-content {
width: 100%;
height: calc(100% - 80px);
overflow: auto;
}
.page-footer {
width: 100%;
height: 40px;
line-height: 40px;
background: rgb(248, 248, 248);
text-align: center;
}
</style>
\ No newline at end of file
<template>
<div>
<a-form-model ref="form" :model="formData" :rules="rules" style="border-top: 0px" class="from-table font-line-space">
<div v-if="stepsArray[0].showStatus">
<a-row>
<a-col :span="24" style="border-top: 0px;text-align: center;">
<div class="main-title">
<span>申报人基本情况</span>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>身份证号</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="address">
<a-input v-model="formData.certId" @change="onCertIdChange" :maxLength="18" style="width: 200px;" />
</a-form-model-item>
</div>
</div>
</a-col>
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>人才类别</div>
</div>
</a-col>
<a-col :span="13">
<div class="special-middle">
<div>
<a-form-model-item prop="talentCategory">
<para-select v-model="formData.talentCategory" :typeId="21" :width="180" />
</a-form-model-item>
</div>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>姓名</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="personName">
<a-input placeholder="姓名(限10字)" v-model="formData.personName" :maxLength="10" style="width:80%" />
</a-form-model-item>
</div>
</div>
</a-col>
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>性别</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="sex">
<base-select v-model="formData.sex" :type="16" :isAll="true" :width="120" />
</a-form-model-item>
</div>
</div>
</a-col>
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>民族</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="nation">
<para-select v-model="formData.nation" :typeId="11" :width="180" />
</a-form-model-item>
</div>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>出生年月</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="birthday">
<a-date-picker format="YYYY-MM-DD" valueFormat="YYYY-MM-DD HH:mm:ss" v-model="formData.birthday" style="width: 60%" />
</a-form-model-item>
</div>
</div>
</a-col>
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>最高学位</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="degree">
<para-select v-model="formData.degree" :typeId="9" :width="120" @changeTitle="(e)=>{ formData.degreeName = e}" />
</a-form-model-item>
</div>
</div>
</a-col>
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>最高学位授予时间</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="degreeTime">
<a-date-picker format="YYYY-MM-DD" valueFormat="YYYY-MM-DD HH:mm:ss" v-model="formData.degreeTime" style="width: 60%" />
</a-form-model-item>
</div>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>最高学位授予单位</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="degreeUnit">
<a-input placeholder="最高学位授予单位(限50字)" v-model="formData.degreeUnit" :maxLength="50" style="width:80%" />
</a-form-model-item>
</div>
</div>
</a-col>
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>目前从事专业</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="spec">
<cascader-select v-model="formData.spec" />
</a-form-model-item>
</div>
</div>
</a-col>
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>是否为研究生导师</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="graduateTeacher">
<para-check v-model="formData.graduateTeacher" :typeId="18" :disabled="false" />
</a-form-model-item>
</div>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>专业技术职称</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="title">
<para-multi-select v-model="formData.title" :typeId="7" :width="120" @changeTitle="(e)=>{ formData.titleName = e}" />
</a-form-model-item>
</div>
</div>
</a-col>
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>党派</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="politicalParty">
<a-input placeholder="党派(限20字)" v-model="formData.politicalParty" :maxLength="20" style="width:80%" />
</a-form-model-item>
</div>
</div>
</a-col>
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>行政职务</div>
</div>
</a-col>
<a-col :span="5">
<div class="special-middle">
<div>
<a-form-model-item prop="duty">
<a-input placeholder="行政职务(限20字)" v-model="formData.duty" :maxLength="20" style="width:80%" />
</a-form-model-item>
</div>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>是否是省级或省级以上人才</div>
</div>
</a-col>
<a-col :span="21">
<div class="special-middle">
<div>
<a-form-model-item prop="talentType">
<para-check v-model="formData.talentType" :typeId="16" :disabled="false" />
</a-form-model-item>
</div>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>省级及以上劳动模范、先进工作者等荣誉称号</div>
</div>
</a-col>
<a-col :span="21">
<div class="special-middle">
<div>
<a-form-model-item prop="honoraryTitle">
<a-textarea placeholder="荣誉称号(限1000字)" v-model="formData.honoraryTitle" :maxLength="1000" style="width: 80%; height: 160px; margin-top: 12px" />
</a-form-model-item>
</div>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>在国家、省级一级学术团体任职情况(包括任职时间和职务)</div>
</div>
</a-col>
<a-col :span="21">
<div class="special-middle">
<div>
<a-form-model-item prop="holdPost1">
<a-textarea placeholder="任职情况(限1000字)" v-model="formData.holdPost1" :maxLength="1000" style="width: 80%; height: 160px; margin-top: 12px" />
</a-form-model-item>
</div>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>担任国内统计源期刊职务情况(包括任职时间和职务)</div>
</div>
</a-col>
<a-col :span="21">
<div class="special-middle">
<div>
<a-form-model-item prop="holdPost2">
<a-textarea placeholder="职务情况(限1000字)" v-model="formData.holdPost2" :maxLength="1000" style="width: 80%; height: 160px; margin-top: 12px" />
</a-form-model-item>
</div>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>担任国家或省级重点学科/专科、重点实验室、内设研究机构负责人情况(包括任职时间和职务)</div>
</div>
</a-col>
<a-col :span="21">
<div class="special-middle">
<div>
<a-form-model-item prop="holdPost3">
<a-textarea placeholder="机构负责人情况(限1000字)" v-model="formData.holdPost3" :maxLength="1000" style="width: 80%; height: 160px; margin-top: 12px" />
</a-form-model-item>
</div>
</div>
</a-col>
</a-row>
<a-row type="flex">
<a-col :span="3" class="bg-gray">
<div class="special-middle">
<div>联系方式</div>
</div>
</a-col>
<a-col :span="21">
<a-row>
<a-col :span="4" class="bg-gray">
<div style="margin-top: 10px;">电话</div>
</a-col>
<a-col :span="8">
<div>
<a-form-model-item prop="mobile">
<a-input v-model="formData.mobile" :maxLength="50" style="width:80%" />
</a-form-model-item>
</div>
</a-col>
<a-col :span="4" class="bg-gray">
<div style="margin-top: 10px;">传真</div>
</a-col>
<a-col :span="8">
<div>
<a-form-model-item prop="fax">
<a-input v-model="formData.fax" :maxLength="50" style="width:80%" />
</a-form-model-item>
</div>
</a-col>
</a-row>
<a-row>
<a-col :span="4" class="bg-gray">
<div style="margin-top: 10px;">Email</div>
</a-col>
<a-col :span="20">
<div>
<a-form-model-item prop="email">
<a-input v-model="formData.email" :maxLength="50" style="width:40%" />
</a-form-model-item>
</div>
</a-col>
</a-row>
</a-col>
</a-row>
</div>
<div v-if="stepsArray[1].showStatus">
<a-row>
<a-col :span="24" style="border-top: 0px;text-align: center;">
<div class="main-title">
<span>申报人简历</span>
</div>
</a-col>
</a-row>
</div>
<div v-if="stepsArray[2].showStatus">
</div>
<div v-if="stepsArray[3].showStatus">
</div>
<div v-if="stepsArray[4].showStatus">
</div>
<div v-if="stepsArray[5].showStatus">
</div>
</a-form-model>
</div>
</template>
<script>
import moment from 'moment'
import { isEmptyParams } from "@/views/utils/common"
import paraRadio from '@/views/components/common/paraRadio'
import paraCheck from '@/views/components/common/paraCheck'
import cascaderSelect from '@/views/components/common/cascaderSelect'
export default {
name: "talentEdit",
components: {
paraRadio, paraCheck, cascaderSelect
},
props: {
value: {
type: String,
default: () => {
return null
}
},
stepsArray: {
type: Array,
default () {
return []
}
},
completeStatus: {
type: String,
default () {
return "0,0,0,0,0,0"
}
},
},
data() {
return {
formData: {
id: null,
talentCategory: null,
reportYear: null,
certId: null,
personId: null,
personName: null,
nation: null,
sex: null,
birthday: null,
degree: null,
degreeTime: null,
degreeUnit: null,
spec: null,
graduateTeacher: null,
title: null,
politicalParty: null,
duty: null,
talentType: null,
honoraryTitle: null,
holdPost1: null,
holdPost2: null,
holdPost3: null,
mobile: null,
fax: null,
email: null,
resumeList: [],
membersList: [],
budgetList: [],
scientificList: [],
fileList: [],
},
rules: {
talentCategory: [{ required: true, message: '*', trigger: 'change' },],
certId: [{ required: true, message: '*', trigger: 'blur' },],
personName: [{ required: true, message: '*', trigger: 'blur' },],
nation: [{ required: true, message: '*', trigger: 'change' },],
sex: [{ required: true, message: '*', trigger: 'change' },],
birthday: [{ required: true, message: '*', trigger: 'change' },],
degree: [{ required: true, message: '*', trigger: 'change' },],
degreeTime: [{ required: true, message: '*', trigger: 'change' },],
degreeUnit: [{ required: true, message: '*', trigger: 'blur' },],
spec: [{ required: true, message: '*', trigger: 'change' }],
graduateTeacher: [{ required: true, message: '*', trigger: 'change' }],
title: [{ required: true, message: '*', trigger: 'change' },],
politicalParty: [{ required: true, message: '*', trigger: 'blur' },],
duty: [{ required: true, message: '*', trigger: 'blur' }],
talentType: [{ required: true, message: '*', trigger: 'change' }],
honoraryTitle: [{ required: true, message: '*', trigger: 'blur' },],
holdPost1: [{ required: true, message: '*', trigger: 'blur' },],
holdPost2: [{ required: true, message: '*', trigger: 'blur' },],
holdPost3: [{ required: true, message: '*', trigger: 'blur' },],
mobile: [{ required: true, message: '*', trigger: 'blur' }],
fax: [{ required: true, message: '*', trigger: 'blur' }],
email: [{ required: true, message: '*', trigger: 'blur' }],
},
};
},
created () {
if (this.value)
this.getTalentApplyById()
else
this.getNewTalentApply()
},
methods: {
moment,
getNewTalentApply() {
this.$api.talent.getNewTalentApply({ }).then(({ data = {} }) => {
if (data) {
this.formData = data
this.formData.sex = ''
this.$emit('onStepChange', { step: 0, state: data.completeStatus })
this.loadList()
} else {
this.$emit('close', 'error')
}
this.$emit('load', false)
}).catch(() => {
this.$emit('close', 'error')
this.$emit('load', false)
})
},
getTalentApplyById() {
this.$api.talent.getTalentApplyById({ id: this.value }).then(({ data = {} }) => {
if (data) {
console.log(data)
// 处理字符串转数组
if (typeof data.talentType === 'string' && data.talentType) {
data.talentType = data.talentType.split(',')
}
if (typeof data.graduateTeacher === 'string' && data.graduateTeacher) {
data.graduateTeacher = data.graduateTeacher.split(',')
}
this.formData = data
this.$emit('onStepChange', { step: 0, state: data.completeStatus })
this.loadList()
} else {
this.$emit('close', 'error')
}
this.$emit('load', false)
}).catch(() => {
this.$emit('close', 'error')
this.$emit('load', false)
})
},
getPersonByCertId() {
if (this.formData.certId == "" || this.formData.certId == null)
return
this.loading = true
this.$api.person.getPersonByCertId({ certId: this.formData.certId }).then(({ data = {} }) => {
if (data) {
this.formData.personId = data.id
this.formData.personName = data.personName
this.formData.sex = data.sex
this.formData.nation = data.nation
this.formData.birthday = data.birthday
this.formData.degree = data.degree
this.formData.degreeTime = data.degreeTime
this.formData.degreeUnit = data.degreeUnit
this.formData.graduateTeacher = data.graduateTeacher
//this.formData.politicalParty = data.politicalParty
this.formData.title = data.title
this.formData.spec = data.spec
this.formData.mobile = data.mobile
this.formData.email = data.email
this.formData.fax = data.fax
}
this.loading = false
}).catch(() => { this.loading = false })
},
loadList () {
if (!!!this.formData.membersList || this.formData.membersList.length == 0)
this.formData.membersList = []
if (!!!this.formData.budgetList || this.formData.budgetList.length == 0)
this.formData.budgetList = []
if (!!!this.formData.resumeList || this.formData.resumeList.length == 0)
this.formData.resumeList = []
if (!!!this.formData.scientificList || this.formData.scientificList.length == 0)
this.formData.scientificList = []
if (!!!this.formData.fileList || this.formData.fileList.length == 0)
this.formData.fileList = []
},
onCertIdChange () {
this.getPersonByCertId()
},
save (step) {
if (this.checkInfo(step)) {
var obj = this.getObj(step)
obj.step = step
this.$emit('load', true)
let pars = isEmptyParams(obj)
let par = { ...pars }
this.$api.talent.save(par).then(({ data = {} }) => {
if (data) {
this.formData.id = data
this.$message.success('保存成功!')
this.$emit('close', 'save')
}
this.$emit('load', false)
}).catch(() => {
this.$emit('load', false)
})
}
},
submit (step, next) {
if (this.checkInfo(step)) {
this.$refs.form.validate(valid => {
if (valid) {
this.$emit('load', true)
var arr = this.completeStatus.split(',')
arr[step] = "1"
this.formData.completeStatus = arr.toString()
var obj = this.getObj(step)
obj.step = step
let state = obj.projState
if (state != 30 && step == 5)
obj.projState = 10
let pars = isEmptyParams(obj)
let par = { ...pars }
this.$api.talent.save(par).then(({ data = {} }) => {
if (data) {
this.formData.id = data
if (next) {
this.$emit('close', 'save')
this.$emit('onStepChange', { step: step + 1, state: arr.toString() })
} else {
this.$message.success('成功!')
this.$emit('close', 'submit')
}
}
this.$emit('load', false)
}).catch(() => {
this.$emit('load', false)
})
} else {
this.$message.error('信息未填写完全!')
return false
}
})
}
},
getObj (step) {
var obj = null
switch (step) {
case 0:
obj = {
id: null, reportYear: null, certId: null, personId: null, personName: null, nation: null, sex: null, birthday: null, degree: null, degreeTime: null,
degreeUnit: null, spec: null, graduateTeacher: null, title: null, politicalParty: null, duty: null, talentType: null, honoraryTitle: null,
holdPost1: null, holdPost2: null, holdPost3: null, mobile: null, fax: null, email: null, completeStatus: null, talentState: null,
appPersonId: null, appUnitId: null, talentCategory: null,
}
break;
case 1:
obj = { id: null, resumeList: [] }
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
}
Object.keys(obj).forEach(key => {
let value = this.formData[key]
if ((key === 'talentType' || key === 'graduateTeacher') && Array.isArray(value)) {
obj[key] = value.join(',')
} else {
obj[key] = value
}
})
//console.log('getObj处理后的数据:', obj)
return obj
},
checkInfo (step) {
switch (step) {
case 0:
if (this.formData.certId == "" || this.formData.certId == null) {
alert('身份证号不能为空')
return false
}
if (this.formData.personName == "" || this.formData.personName == null) {
alert('人员姓名不能为空')
return false
} else return true
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
}
},
loadList () {
},
}
};
</script>
<template>
<div></div>
</template>
<script>
export default {
name: "talentInfo",
data() {
return {};
},
methods: {
}
};
</script>
\ No newline at end of file
<template>
<div class="app-content layoutEmbedded" style="height: 76vh;overflow: auto;">
<a-spin :spinning="loading" style="width: 100%;height: 100%;">
<div class="page-content">
<a-tabs type="card" hideAdd size="small" @change="callback">
<a-tab-pane :key="item.key" :tab="item.title" v-for="(item) in tabsData">
</a-tab-pane>
</a-tabs>
</div>
<div class="page-footer">
<a-button type="primary" @click="onTalentExport">导出</a-button>
<talent-info v-model="formData" :tabsData.sync="tabsData" />
</div>
</a-spin>
</div>
</template>
<script>
import talentInfo from '@/views/report/talent/components/talentInfo'
export default {
name: "talentView",
components: {
talentInfo
},
props: {
value: {
type: String,
default: () => {
return null
}
},
},
data() {
return {
tabsData: [
{ title: '全部', key: '0', isShow: true },
{ title: '申报人基本情况', key: '1', isShow: true },
{ title: '申报人简历', key: '2', isShow: true },
{ title: '申报人科研成绩', key: '3', isShow: true },
{ title: '科学研究规划及团队人员名单', key: '4', isShow: true },
{ title: '经费预算及培养计划和目标', key: '5', isShow: true },
{ title: '附件', key: '6', isShow: true },
{ title: '项目审核记录', key: '7', isShow: true },
],
formData: {
},
loading: false,
};
},
created() {
},
methods: {
callback () {
},
onTalentExport () {
},
}
};
</script>
<style scoped lang="less">
::v-deep .ant-spin-container {
width: 100%;
height: 100%;
}
::-webkit-scrollbar {
width: 8px;
height: 6px;
}
.page-content {
width: 100%;
height: 50px;
}
.page-footer {
width: 100%;
height: calc(100% - 50px);
overflow: auto;
}
</style>
\ No newline at end of file
<template>
<div class="app-content" style="height:330px;overflow:auto;">
<a-spin :spinning="loading" style="width: 100%;height: 100%;">
<a-form-model ref="formRef" :model="formData" :rules="formRules" class="from-table">
<a-row>
<a-col :span="6" class="bg-gray">
<div class="required">申报年度</div>
</a-col>
<a-col :span="6">
<a-form-model-item ref="year" prop="year">
<base-select v-model="formData.year" :type="8" :width="160" />
</a-form-model-item>
</a-col>
<a-col :span="4" class="bg-gray">
<div class="required">申报批次</div>
</a-col>
<a-col :span="8">
<a-form-model-item ref="batch" prop="batch">
<base-select v-model="formData.batch" :type="10" :width="160" />
</a-form-model-item>
</a-col>
</a-row>
<a-row>
<a-col :span="6" class="bg-gray">
<div class="required">项目申报时间</div>
</a-col>
<a-col :span="18">
<a-form-model-item ref="reportRange" prop="reportRange">
<a-range-picker v-model="formData.reportRange" show-time format="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss" @change="reportDateChange" :placeholder="['开始时间', '结束时间']" />
</a-form-model-item>
</a-col>
</a-row>
<a-row>
<a-col :span="6" class="bg-gray">
<div class="required">审核时间</div>
</a-col>
<a-col :span="18">
<a-form-model-item ref="unitRange" prop="unitRange">
<a-range-picker v-model="formData.auditRange" show-time format="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss" @change="auditDateChange" :placeholder="['开始时间', '结束时间']" />
</a-form-model-item>
</a-col>
</a-row>
<!-- <a-row>
<a-col :span="6" class="bg-gray">
<div class="required">专家审核时间</div>
</a-col>
<a-col :span="18">
<a-form-model-item ref="expertRange" prop="expertRange">
<a-range-picker v-model="formData.expertRange" show-time format="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss" @change="expertDateChange" :placeholder="['开始时间', '结束时间']" />
</a-form-model-item>
</a-col>
</a-row> -->
<a-row>
<a-col :span="6" class="bg-gray">
<div>备注</div>
</a-col>
<a-col :span="18">
<a-form-model-item ref="remark" prop="remark">
<a-input v-model="formData.remark" style="width:450px" />
</a-form-model-item>
</a-col>
</a-row>
<a-row>
<a-col style="text-align: center;width:100%;">
<a-button type="primary" style="width:68px;" @click="submit">提交</a-button>
</a-col>
</a-row>
</a-form-model>
</a-spin>
</div>
</template>
<script>
import { getType } from '@/views/utils/auth'
import { isEmptyParams, checkDateRange } from '@/views/utils/common'
import moment from 'moment'
import baseSelect from '@/views/components/common/baseSelect'
export default {
name: "batchEdit",
components: {
baseSelect
},
data () {
return {
formData: {
id: null,
year: moment().format('YYYY'),
batch: '1',
timeType: 4,
reportStart: '',
reportEnd: '',
auditStart: '',
auditEnd: '',
expertStart: '',
expertEnd: '',
remark: '',
reportRange: [],
auditRange: [],
expertRange: [],
projType: null,
},
formRules: {
id: [{ required: false }],
year: { required: true, message: '请输入申报年度' },
batch: { required: true, message: '请输入申报批次' },
reportRange: [{ required: true, validator: checkDateRange, trigger: 'blur' }],
auditRange: [{ required: true, validator: checkDateRange, trigger: 'blur' }],
// prefectureRange: [{ required: true, validator: checkDateRange, trigger: 'blur' }],
// provinceRange: [{ required: true, validator: checkDateRange, trigger: 'blur' }],
expertRange: [{ required: true, validator: checkDateRange, trigger: 'blur' }],
remark: [{ required: false }]
},
loading: false,
}
},
props: {
value: {
type: String,
default: () => {
return null
}
},
},
created () {
if (this.value) {
this.loading = true
this.getBatchById()
}
},
methods: {
moment,
getBatchById () {
this.$api.batch.getBatchById({ id: this.value }).then(({ data = {} }) => {
if (data) {
this.formData.id = data.id
this.formData.year = data.year + ''
this.formData.timeType = data.timeType
this.formData.projType = null
this.formData.reportStart = data.reportStart
this.formData.reportEnd = data.reportEnd
this.formData.auditStart = data.auditStart
this.formData.auditEnd = data.auditEnd
//this.formData.expertStart = data.expertStart
//this.formData.expertEnd = data.expertEnd
this.formData.remark = data.remark
this.formData.reportRange = [data.reportStart, data.reportEnd]
this.formData.auditRange = [data.auditStart, data.auditEnd]
//this.formData.expertRange = [data.expertStart, data.expertEnd]
}
this.loading = false
}).catch(() => { this.loading = false })
},
submit () {
this.$refs.formRef.validate(valid => {
if (valid) {
this.loading = true
let pars = isEmptyParams(this.formData)
if (this.value) {
this.$api.batch.updateBatch({ ...pars }).then(({ data }) => {
if (data) {
this.$message.success('修改成功!')
this.$emit('close', 'edit')
}
}).catch(() => { this.loading = false })
} else {
this.$api.batch.addBatch({ ...pars }).then(({ data }) => {
if (data) {
this.$message.success('添加成功!')
this.$emit('close', 'edit')
}
}).catch(() => { this.loading = false })
}
}
})
},
//起止日期选择处理
reportDateChange (dates, dateStrings) {
if (dateStrings[0] != '' && dateStrings[1] != '') {
this.formData.reportStart = dateStrings[0]
this.formData.reportEnd = dateStrings[1]
}
},
auditDateChange (dates, dateStrings) {
if (dateStrings[0] != '' && dateStrings[1] != '') {
this.formData.auditStart = dateStrings[0]
this.formData.auditEnd = dateStrings[1]
}
},
expertDateChange (dates, dateStrings) {
if (dateStrings[0] != '' && dateStrings[1] != '') {
this.formData.expertStart = dateStrings[0]
this.formData.expertEnd = dateStrings[1]
}
},
}
}
</script>
\ No newline at end of file
<template>
<div class="app-content">
<a-form :form="form" :model="searchForm" layout="inline" class="search_form">
<a-form-item>
<a-button type="primary" class="search_input" style="margin-right: 10px;" @click="createBatch">添加</a-button>
<a-button type="primary" @click="search">刷新</a-button>
</a-form-item>
</a-form>
<a-table :dataSource="tableData" :columns="columns" rowKey="id" :pagination="false" :loading="loading" bordered>
<template slot="option" slot-scope="record">
<a-button type="link" size="small" @click="recordClick(record,'edit')">修改</a-button>&nbsp;
<a-button type="link" size="small" @click="recordClick(record,'delete')">删除</a-button>
</template>
</a-table>
<a-pagination v-if="pagination.total > 0" :total="pagination.total" show-size-changer show-quick-jumper v-model="pagination.pageIndex" :page-size="pagination.pageSize" :page-size-options="pagination.pageSizeOptions" @showSizeChange="showSizeChange" @change="change" :showTotal="() => `共 ${pagination.total} 条`" />
<a-modal :visible="visibleEdit" v-model="visibleEdit" :title="'添加/修改'" :footer="null" :maskClosable="false" :dialog-style="{ top: '15%' }" :width="800" destroyOnClose>
<talent-batch-edit v-model="id" @close="closeWindow" ref="childEdit" />
</a-modal>
</div>
</template>
<script>
import talentBatchEdit from '@/views/timeSet/batch/components/talentBatchEdit'
import moment from 'moment'
import { isEmptyParams} from "@/views/utils/common"
export default {
name: 'talentBatch',
components: { talentBatchEdit },
data () {
return {
searchForm: { timeType: 4, },
form: this.$form.createForm(this, { name: 'advanced_search' }),
tableData: [],
columns: [
{ key: '1', title: '申报年度', dataIndex: 'year', align: 'center' },
{ key: '2', title: '批次', dataIndex: 'batch', align: 'center' },
{ key: '3', title: '项目申报时间', dataIndex: 'reportStart', colSpan: 2, ellipsis: true },
{ key: '4', title: '项目申报时间', dataIndex: 'reportEnd', colSpan: 0, ellipsis: true },
{ key: '5', title: '审核时间', dataIndex: 'auditStart', colSpan: 2, ellipsis: true },
{ key: '6', title: '审核时间', dataIndex: 'auditEnd', colSpan: 0, ellipsis: true },
// { key: '11', title: '专家评审时间', dataIndex: 'expertStart', colSpan: 2, ellipsis: true },
// { key: '12', title: '专家评审时间', dataIndex: 'expertEnd', colSpan: 0, ellipsis: true },
{ key: '13', title: '备注', dataIndex: 'remark', align: 'center', ellipsis: true },
{ key: '14', title: '操作', scopedSlots: { customRender: 'option' }, align: 'center', fixed: 'right', width: 120, },
],
pagination: { pageIndex: 1, pageSize: this.$defaultPageSize, total: 0, pageSizeOptions: this.$defaultPageSizeOptions, },
// 弹窗标志
visibleEdit: false,
id: null,
loading: false,
}
},
created () {
this.getListByPage()
},
computed: {
},
methods: {
moment,
getListByPage () {
this.loading = true
let pars = isEmptyParams(this.searchForm)
let par = { ...pars, pageIndex: this.pagination.pageIndex, pageSize: this.pagination.pageSize }
this.$api.batch.getListByPage(par).then(({ data = {} }) => {
if (data) {
const { dataList = [], total = 0 } = data
this.tableData = dataList
this.pagination.total = total
this.loading = false
}
}).catch(() => { this.loading = false })
},
search () {
this.pagination.pageIndex = 1
this.getListByPage()
},
reset () {
this.pagination.pageIndex = 1
this.getListByPage()
},
change () {
this.getListByPage()
},
showSizeChange (current, pageSize) {
this.pagination.pageIndex = current
this.pagination.pageSize = pageSize
this.getListByPage()
},
createBatch () {
this.id = null
this.visibleEdit = true
},
recordClick (record, type) {
if (type === 'edit') {
this.id = record.id
this.visibleEdit = true
} else if (type === 'delete') {
let self = this
this.$confirm({
title: '',
content: '确定要删除该批次?',
okText: '确定',
okType: 'danger',
cancelText: '取消',
onOk () {
let pars = { id: record.id }
self.$api.batch.deleteBatch(pars).then(({ data = {} }) => {
if (data) {
self.getListByPage()
}
})
},
onCancel () {
},
})
}
},
closeWindow () {
this.visibleEdit = false
this.getListByPage()
}
},
watch: {
$route () {
}
}
}
</script>
...@@ -132,7 +132,7 @@ function sheet_from_array_of_arrays(data, opts) { ...@@ -132,7 +132,7 @@ function sheet_from_array_of_arrays(data, opts) {
var cell = { var cell = {
v: data[R][C] v: data[R][C]
} }
// 如果单元格所在的值为空,让其值为“” // 如果单元格所在的值为空,让其值为""
if (cell.v == null) { if (cell.v == null) {
cell.v = '' cell.v = ''
} }
...@@ -289,218 +289,181 @@ export function exportJsonToExcel({ ...@@ -289,218 +289,181 @@ export function exportJsonToExcel({
autoWidth = true, autoWidth = true,
bookType = 'xlsx', bookType = 'xlsx',
XlsWidth XlsWidth
} = {}) { } = {}) {
filename = filename || '导出excel文件' try {
data = [...data] filename = filename || '导出excel文件'
data.unshift(header) data = [...data]
for (let i = multiHeader.length - 1; i > -1; i--) { data.unshift(header)
data.unshift(multiHeader[i]) for (let i = multiHeader.length - 1; i > -1; i--) {
} data.unshift(multiHeader[i])
var wsName = 'SheetJS' }
var wb = new Workbook()
var ws = sheetFromArrayOfArrays(data)
if (merges.length > 0) { var wsName = 'SheetJS'
// ws[!merges]:存放一些单元格合并信息,是一个数组,每个数组由包含s和e构成的对象组成,s表示开始,e表示结束,r表示行,c表示列 var wb = new Workbook()
if (!ws['!merges']) ws['!merges'] = [] var ws = sheetFromArrayOfArrays(data)
merges.forEach(item => {
ws['!merges'].push(XLSX.utils.decode_range(item))
})
}
if (autoWidth) { if (merges.length > 0) {
/* 设置worksheet每列的最大宽度 */ if (!ws['!merges']) ws['!merges'] = []
const colWidth = data.map(row => row.map(val => { merges.forEach(item => {
/* 先判断是否为null/undefined */ ws['!merges'].push(XLSX.utils.decode_range(item))
if (val == null) { })
return { 'wch': 10 } }
} else if (val.toString().charCodeAt(0) > 255) { /* 再判断是否为中文 */
return { if (autoWidth) {
'wch': val.toString().length * 2 /* 设置worksheet每列的最大宽度 */
} const colWidth = data.map(row => row.map(val => {
} else { /* 先判断是否为null/undefined */
return { if (val == null) {
'wch': val.toString().length return { 'wch': 10 }
} else if (val.toString().charCodeAt(0) > 255) { /* 再判断是否为中文 */
return {
'wch': val.toString().length * 2
}
} else {
return {
'wch': val.toString().length
}
} }
} }))
}))
/* 以第一行为初始值 */ /* 以第一行为初始值 */
let result = colWidth[0] let result = colWidth[0]
for (let i = 1; i < colWidth.length; i++) { for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) { for (let j = 0; j < colWidth[i].length; j++) {
if (result[j] && result[j]['wch'] < colWidth[i][j]['wch']) { if (result[j] && result[j]['wch'] < colWidth[i][j]['wch']) {
result[j]['wch'] = colWidth[i][j]['wch'] result[j]['wch'] = colWidth[i][j]['wch']
}
} }
} }
}
// ws['!cols']设置单元格宽度, [{'wch': 10},{'wch': 10}] ===> 第一列和第二列设置了宽度 // ws['!cols']设置单元格宽度, [{'wch': 10},{'wch': 10}] ===> 第一列和第二列设置了宽度
ws['!cols'] = result ws['!cols'] = result
ws['!cols'] = XlsWidth;
}
/* add worksheet to workbook */
wb.SheetNames.push(wsName)
wb.Sheets[wsName] = ws
var dataInfo = wb.Sheets[wb.SheetNames[0]]
// 设置单元格框线 ws['!cols'] = XlsWidth;
const borderAll = {
top: {
style: 'thin'
},
bottom: {
style: 'thin'
},
left: {
style: 'thin'
},
right: {
style: 'thin'
} }
}
// 给所有单元格加上边框,内容居中,字体,字号,标题表头特殊格式部分后面替换 /* add worksheet to workbook */
for (var i in dataInfo) { wb.SheetNames.push(wsName)
if ( wb.Sheets[wsName] = ws
i == '!ref' || var dataInfo = wb.Sheets[wb.SheetNames[0]]
i == '!merges' ||
i == '!cols' || // 设置单元格框线
i == '!rows' || const borderAll = {
i == 'A1' top: {
) {} else { style: 'thin'
dataInfo[i + ''].s = { },
border: borderAll, bottom: {
alignment: { style: 'thin'
horizontal: 'center', },
vertical: 'center' left: {
}, style: 'thin'
font: { },
name: '微软雅黑', right: {
sz: 12 style: 'thin'
}
} }
} }
}
const arrabc = [ 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' ] // 给所有单元格加上边框,内容居中,字体,字号,标题表头特殊格式部分后面替换
for (var i in dataInfo) {
// 给标题、表格描述信息、表头等部分加上特殊格式 if (
arrabc.some(function(v) { i == '!ref' ||
for (let j = 1; j < (data.length + 1); j++) { i == '!merges' ||
const _v = v + j i == '!cols' ||
if (dataInfo[_v]) { i == '!rows' ||
dataInfo[_v].s = {} i == 'A1'
// 标题部分A1-Z1 ) {} else {
dataInfo['A' + j].s = { dataInfo[i + ''].s = {
border: borderAll, border: borderAll,
font: {
name: '微软雅黑',
sz: 12,
color: {
rgb: '000000'
},
bold: true
},
alignment: { alignment: {
horizontal: 'center', horizontal: 'center',
vertical: 'center' vertical: 'center'
}
}
dataInfo['B' + j].s = {
border: borderAll,
numFmt: '0',
font: {
name: '微软雅黑',
sz: 12,
color: {
rgb: '000000'
}
}, },
alignment: {
horizontal: 'right',
vertical: 'center'
}
}
dataInfo[v + j].s = {
border: borderAll,
numFmt: '0.00',
font: { font: {
name: '微软雅黑', name: '微软雅黑',
sz: 12, sz: 12
color: {
rgb: '000000'
}
},
alignment: {
horizontal: 'right',
vertical: 'center'
} }
} }
// 头部 }
if (j == 1) { }
dataInfo[v + j].s = {
const arrabc = [ 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' ]
// 给标题、表格描述信息、表头等部分加上特殊格式
arrabc.some(function(v) {
for (let j = 1; j < (data.length + 1); j++) {
const _v = v + j
if (dataInfo[_v]) { // 确保单元格存在
// 设置基础样式
dataInfo[_v].s = {
border: borderAll, border: borderAll,
font: { font: {
name: '微软雅黑', name: '微软雅黑',
sz: 18, sz: 12,
color: { color: { rgb: '000000' }
rgb: '000000'
},
bold: true
}, },
alignment: { alignment: {
horizontal: 'center', horizontal: 'center',
vertical: 'center' vertical: 'center'
}, }
fill: { }
fgColor: {
rgb: 'f0f0f0' // 设置第一行(标题)的特殊样式
if (j === 1) {
dataInfo[_v].s = {
border: borderAll,
font: {
name: '微软雅黑',
sz: 18,
color: { rgb: '000000' },
bold: true
},
alignment: {
horizontal: 'center',
vertical: 'center'
},
fill: {
fgColor: { rgb: 'f0f0f0' }
} }
} }
} }
}
// 百分比 % // 设置数值列的格式(如果需要)
if (percent.length != 0) { if (v !== 'A') { // 非第一列
for (let index = 0; index < percent.length; index++) { dataInfo[_v].s = {
if (j == percent[index]) { ...dataInfo[_v].s,
dataInfo[v + percent[index]].s = { numFmt: '0.00'
numFmt: '0.00%', }
border: borderAll, }
font: {
name: '微软雅黑', // 设置百分比列的格式
sz: 12, if (percent.includes(j)) {
color: { dataInfo[_v].s = {
rgb: '000000' ...dataInfo[_v].s,
} numFmt: '0.00%',
}, fill: {
alignment: { fgColor: { rgb: 'FFF8DC' }
horizontal: 'right',
vertical: 'center'
},
fill: {
fgColor: {
rgb: 'FFF8DC'
}
}
} }
} }
} }
} }
} }
} })
})
var wbout = XLSX.write(wb, { var wbout = XLSX.write(wb, {
bookType: bookType, bookType: bookType,
bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性 bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
type: 'binary' type: 'binary'
}) })
saveAs( saveAs(
new Blob([s2ab(wbout)], { type: 'application/octet-stream' }), new Blob([s2ab(wbout)], { type: 'application/octet-stream' }),
`${filename}.${bookType}` `${filename}.${bookType}`
) )
return true
} catch (error) {
console.error('Excel导出错误:', error)
throw error // 抛出错误以便调用者处理
}
} }
// 主要修改内容在这里 // 主要修改内容在这里
......
import moment from 'moment' import moment from 'moment'
import storeInfo from '../../store/index' import storeInfo from '../../store/index'
import router from "../../router" import router from "../../router"
......
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