123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603 |
- <template>
- <div v-loading="!isAfterRender" element-loading-text="加载中..." class="hc-full">
- <hc-table
- v-if="isAfterRender" :column="tableColumn" :datas="tableData" :index-style="{ width: 60 }" is-check
- :check-style="{ fixed: true, width: 29 }" class="hc-project-list-table" @selection-change="tableCheckChange"
- >
- <template #name="{ row }">
- <el-link type="primary" @click="rowNameClick(row)">{{ row.name }}</el-link>
- </template>
-
- <template #action="{ row }">
- <el-link v-if="isAdminAuth" type="warning" @click="completion(row)">项目完成情况</el-link>
- <el-link type="primary" @click="examine(row)">查看</el-link>
- <el-link v-if="isAdminAuth" v-del-com:[delTableItem]="row" type="danger">删除</el-link>
- <el-link v-yes-com:[deriveTableItem]="row" type="success">导出</el-link>
- </template>
- </hc-table>
- <!-- 查看详情 -->
- <hc-drawer v-model="isDrawer" to-id="hc-main-box" is-close>
- <hc-card class="hc-project-list-drawer">
- <template #header>
- <div class="flex-1 text-center text-[24px] font-bold">项目详情</div>
- </template>
- <hc-info-table>
- <tr>
- <hc-info-table-td is-title width="30px" center>项目阶段</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.projectStageName }}</hc-info-table-td>
- <hc-info-table-td is-title width="30px" center>项目类型</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.projectTypeName }}</hc-info-table-td>
- </tr>
- <tr>
- <hc-info-table-td is-title width="30px" center>项目名称</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.name }}</hc-info-table-td>
- <hc-info-table-td is-title width="30px" center>建设规模</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.buildScaleName }}</hc-info-table-td>
- </tr>
- <tr>
- <hc-info-table-td is-title width="30px" center>开 工 年</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.startYear }}</hc-info-table-td>
- <hc-info-table-td is-title width="30px" center>完 工 年</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.endYear }}</hc-info-table-td>
- </tr>
- <tr>
- <hc-info-table-td is-title width="30px" center>总投资</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.allInvestMoney }}</hc-info-table-td>
- <hc-info-table-td is-title width="30px" center>“十四五”计划投资</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.fourteenFiveInvest }}</hc-info-table-td>
- </tr>
- <tr>
- <hc-info-table-td is-title width="30px" center>市级重点项目</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail.isFocusProject === 1 ? '是' : '否' }}</hc-info-table-td>
- <hc-info-table-td is-title width="30px" center>交通强国建设试点任务</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.isPilotPlan === 1 ? '是' : '否' }}</hc-info-table-td>
- </tr>
- <tr>
- <hc-info-table-td is-title width="30px" center>牵头单位</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.leaderUnit }}</hc-info-table-td>
- <hc-info-table-td is-title width="30px" center rowspan="2">配合单位</hc-info-table-td>
- <hc-info-table-td center rowspan="2">{{ rowDetail?.assistUnit }}</hc-info-table-td>
- </tr>
- <tr>
- <hc-info-table-td is-title width="30px" center>责任单位</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.dutyUnit }}</hc-info-table-td>
- </tr>
- </hc-info-table>
- <div class="hc-project-list-drawer-year">
- <el-scrollbar>
- <div class="relative p-2 pt-3">
- <hc-card-item class="year-detail">
- <template #header>
- <div class="flex-1 text-center text-[14px]">
- <HcDropdown v-model="yearKey" :datas="yearData.list" text="年" :props="{ key: 'planYear', label: 'planYear' }" @change="yearChange" />
- </div>
- </template>
- <el-table v-if="yearData.list && yearData.list.length > 0" :data="yearData.list[yearIndex].list" border class="w-full" :span-method="tableYearMethod">
- <el-table-column prop="planQuarterName" label="季度" width="100" align="center" />
- <el-table-column prop="planMonthName" class-name="line" width="120" align="center">
- <template #header>
- <div class="hc-table-th-line">
- <span class="left">月份</span>
- <span class="right">完成情况</span>
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="planInvestMoney" label="计划完成投资额(亿元)" width="100" align="center" />
- <el-table-column prop="investMoney" label="投资完成额(亿元)" width="100" align="center" />
- <el-table-column prop="investUnfinishedMoney" label="投资未完成额(亿元)" width="100" align="center" />
- <el-table-column prop="yearlyTarget" label="全年目标" width="100" align="center" />
- <el-table-column prop="workPlan " label="工作计划" width="100" align="center" />
- <el-table-column prop="workProgressAll" label="累计进展计划" align="center" />
- <el-table-column prop="planRatio" label="形象进度百分比(%)" width="100" align="center" />
- <el-table-column prop="workProgress" label="工作计划进展计划" align="center" />
- </el-table>
- <hc-info-table v-if="yearData.list && yearData.list.length > 0" class="mt-[-1px]">
- <tr>
- <hc-info-table-td is-title width="130px" center>该年累计完成投资(亿元)</hc-info-table-td>
- <hc-info-table-td center>{{ yearData.list[yearIndex].yearFinishInvest || "-" }}</hc-info-table-td>
- <hc-info-table-td is-title width="130px" center>该年力争完成投资(亿元)</hc-info-table-td>
- <hc-info-table-td center>{{ yearData.list[yearIndex]?.yearlyInvest || "-" }}</hc-info-table-td>
- <hc-info-table-td is-title width="130px" center>该年累计未完成投资(亿元)</hc-info-table-td>
- <hc-info-table-td center>{{ yearData.list[yearIndex]?.yearUnfinishedInvest || "-" }}</hc-info-table-td>
- </tr>
- </hc-info-table>
- <hc-info-table v-if="yearData.list && yearData.list.length > 0" class="mt-[-1px]">
- <tr>
- <hc-info-table-td is-title width="30px" center>存在问题</hc-info-table-td>
- <hc-info-table-td center>{{ yearData.list[yearIndex]?.questionable || '-' }}</hc-info-table-td>
- <hc-info-table-td is-title width="30px" center>工作建议</hc-info-table-td>
- <hc-info-table-td center>{{ yearData.list[yearIndex]?.workAdvise || '-' }}</hc-info-table-td>
- </tr>
- <tr>
- <hc-info-table-td is-title width="30px" center>填报单位</hc-info-table-td>
- <hc-info-table-td center>{{ yearData.list[yearIndex]?.writeUnit || '-' }}</hc-info-table-td>
- <hc-info-table-td is-title width="30px" center>联系人</hc-info-table-td>
- <hc-info-table-td center>{{ yearData.list[yearIndex]?.linkman || '-' }}</hc-info-table-td>
- </tr>
- </hc-info-table>
- </hc-card-item>
- </div>
- </el-scrollbar>
- </div>
- </hc-card>
- </hc-drawer>
- <!-- 项目完成情况 -->
- <hc-drawer v-model="isCompletionDrawer" to-id="hc-main-box" is-close>
- <hc-card class="hc-project-list-drawer" is-action-btn>
- <template #header>
- <div class="flex-1 text-center text-[24px] font-bold">项目完成情况</div>
- </template>
- <hc-info-table>
- <tr>
- <hc-info-table-td is-title width="30px" center>项目名称</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.name }}</hc-info-table-td>
- <hc-info-table-td is-title width="30px" center>项目类型</hc-info-table-td>
- <hc-info-table-td center>{{ rowDetail?.projectTypeName }}</hc-info-table-td>
- </tr>
- </hc-info-table>
- <div class="hc-project-list-drawer-year detail">
- <el-scrollbar>
- <div class="relative p-2 pt-3">
- <hc-card-item class="year-detail edit">
- <template #header>
- <div class="flex-1 text-center text-[14px]">
- <HcDropdown v-model="yearKey" :datas="yearData.list" text="年" :props="{ key: 'planYear', label: 'planYear' }" @change="yearChange" />
- </div>
- </template>
- <el-table v-if="yearData.list && yearData.list.length > 0" :data="yearData.list[yearIndex].list" border class="w-full" :span-method="tableYearMethod1">
- <el-table-column prop="planQuarterName" label="季度" width="100" align="center" />
- <el-table-column prop="planMonthName" class-name="line" width="120" align="center">
- <template #header>
- <div class="hc-table-th-line">
- <span class="left">月份</span>
- <span class="right">完成情况</span>
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="planInvestMoney" label="计划完成投资额(亿元)" width="100" align="center">
- <template #default="{ row }">
- <hc-body>
- <hc-table-input v-model="row.planInvestMoney" disabled />
- </hc-body>
- </template>
- </el-table-column>
- <el-table-column prop="investMoney" label="投资完成额(亿元)" width="100" align="center">
- <template #default="{ row }">
- <hc-body>
- <hc-table-input v-model="row.investMoney" />
- </hc-body>
- </template>
- </el-table-column>
- <el-table-column prop="investMoneyAll" label="累计投资完成额(亿元)" width="100" align="center">
- <template #default="{ row }">
- <hc-body>
- <hc-table-input v-model="row.investMoneyAll" disabled />
- </hc-body>
- </template>
- </el-table-column>
- <el-table-column prop="workPlan" label="工作计划" width="100" align="center">
- <template #default="{ row }">
- <hc-body>
- <hc-table-input v-model="row.workPlan" type="textarea" disabled resize="none" />
- </hc-body>
- </template>
- </el-table-column>
- <el-table-column prop="workProgress" label="工作计划进展情况" align="center">
- <template #default="{ row }">
- <hc-body>
- <hc-table-input v-model="row.workProgress" type="textarea" resize="none" :disabled="yearData.list[yearIndex].isCanFill === 1 ? false : true" />
- </hc-body>
- </template>
- </el-table-column>
- <el-table-column prop="workProgress" label="累计进展情况" align="center">
- <template #default="{ row }">
- <hc-body>
- <hc-table-input v-model="row.workProgress" type="textarea" resize="none" :disabled="yearData.list[yearIndex].isCanFill === 1 ? false : true" />
- </hc-body>
- </template>
- </el-table-column>
- <el-table-column prop="planRatio" label="形象进度百分比(%)" width="100" align="center">
- <template #default="{ row }">
- <hc-body>
- <hc-table-input v-model="row.planRatio" :disabled="yearData.list[yearIndex].isCanFill === 1 ? false : true" />
- </hc-body>
- </template>
- </el-table-column>
- </el-table>
- <hc-info-table v-if="yearData.list && yearData.list.length > 0" class="mt-[-1px]">
- <tr>
- <hc-info-table-td is-title width="30px" center>存在问题</hc-info-table-td>
- <hc-info-table-td center>
- <el-input v-model="yearData.list[yearIndex].questionable" type="textarea" resize="none" />
- </hc-info-table-td>
- <hc-info-table-td is-title width="30px" center>工作建议</hc-info-table-td>
- <hc-info-table-td center>
- <el-input v-model=" yearData.list[yearIndex].workAdvise" type="textarea" resize="none" />
- </hc-info-table-td>
- </tr>
- <tr>
- <hc-info-table-td is-title width="30px" center>填报单位</hc-info-table-td>
- <hc-info-table-td center>
- <el-input v-model="yearData.list[yearIndex].writeUnit " />
- </hc-info-table-td>
- <hc-info-table-td is-title width="30px" center>联系人</hc-info-table-td>
- <hc-info-table-td center>
- <el-input v-model="yearData.list[yearIndex].linkman" />
- </hc-info-table-td>
- </tr>
- </hc-info-table>
- </hc-card-item>
- </div>
- </el-scrollbar>
- </div>
- <template #action>
- <el-button type="info" @click="isCompletionDrawer = false">取消</el-button>
- <el-button type="warning" :loading="saveCompleLoading" @click="saveComplete">保存</el-button>
- </template>
- </hc-card>
- </hc-drawer>
- </div>
- </template>
- <script setup>
- import { onMounted, ref, watch } from 'vue'
- import mainApi from '~api/project/project'
- import { deepClone, getArrValue, getObjValue, isNullES, newDownBlob } from 'js-fast-way'
- const props = defineProps({
- isAdmin: {
- type: Boolean,
- default: false,
- },
- loading: {
- type: Boolean,
- default: false,
- },
- datas: {
- type: Array,
- default: () => ([]),
- },
- })
- //事件
- const emit = defineEmits(['tap', 'completion', 'examine', 'del', 'export', 'check'])
- //监听权限
- const isAdminAuth = ref(props.isAdmin)
- watch(() => props.isAdmin, (admin) => {
- isAdminAuth.value = admin
- })
- //渲染完成
- const isAfterRender = ref(false)
- onMounted(() => {
- //表格太复杂,渲染较慢,等页面先加载完成,再渲染表格,不然会卡住一下不动。
- //因为表头涉及到年份,如果年份很多,那么会更卡。
- setTimeout(() => {
- isAfterRender.value = true
- }, 200)
- })
- //表头
- const tableColumn = ref([
- { key: 'projectStageName', name: '项目阶段' },
- { key: 'projectTypeName', name: '项目类型' },
- { key: 'name', name: '项目名称' },
- { key: 'buildScaleName', name: '建设规模' },
- { key: 'startYear', name: '开工年' },
- { key: 'endYear', name: '完工年' },
- { key: 'allInvest', name: '总投资(亿元)' },
- { key: 'fourteenFiveInvest', name: '\“十四五”\'计划投资(亿元)' },
- { key: 'isFocusProjectName', name: '市级重点项目' },
- { key: 'isPilotPlanName', name: '交通强国建设试点任务' },
- { key: 'finishedInvestMoney', name: '完成投资金额(亿元)' },
- { key: 'progressRatio', name: '项目进展比例(%)' },
- { key: 'finishedFillRatio', name: '完成情况填写比例(%)' },
- { key: 'leaderUnit', name: '牵头单位' },
- { key: 'assistUnit', name: '配合单位' },
- { key: 'dutyUnit', name: '责任单位' },
- { key: 'action', name: '操作', width: isAdminAuth.value ? 220 : 100, fixed:'right', align: 'center' },
- ])
- //监听数据
- const tableData = ref(props.datas)
- watch(() => props.datas, (data) => {
- tableData.value = data
- })
- //表格被选择
- const tableCheckKeys = ref([])
- const tableCheckChange = (rows) => {
- tableCheckKeys.value = rows
- emit('check', rows)
- }
- //项目名称被点击
- const rowNameClick = (row) => {
- emit('tap', row)
- }
- //项目完成情况
- const isCompletionDrawer = ref(false)
- const completion = (row) => {
- isCompletionDrawer.value = true
- emit('completion', row)
- getDetailData(row.id)
- }
- //查看
- const rowDetail = ref({})
- const isDrawer = ref(false)
- const isDrawerType = ref('view')
- const examine = (row) => {
- isDrawer.value = true
- isDrawerType.value = 'view'
- rowDetail.value = row
- getDetailData(row.id)
- // emit('examine', row)
- }
- const getDetailData = async (id) => {
- const { error, code, data, msg } = await mainApi.detailMore(id)
- if (error || code !== 200) {
- window.$message.error(msg ?? '获取数据失败')
- drawerCancel()
- return
- }
- //处理数据
- const res = getObjValue(data)
- const list = getArrValue(res.list)
- res.list = list
- rowDetail.value = res
- yearData.value = res
- console.log(yearData.value, 'yearData.valu')
- //设置默认数据
- if (list.length > 0) {
- yearKey.value = list[0].planYear
- yearIndex.value = 0
- }
- }
- //删除
- const delTableItem = ({ item }, resolve) => {
- console.log('我被执行了', item)
- //这里可以写一些操作,下面是模拟3秒关闭
- setTimeout(() => {
- resolve()
- emit('del', item)
- }, 3000)
- }
- //关闭抽屉
- const drawerCancel = () => {
- isDrawer.value = false
- isDrawerType.value = ''
- yearData.value = {}
- }
- //导出数据
- const deriveTableItem = ({ item }, resolve) => {
- console.log('我被执行了', item)
- //这里可以写一些操作,下面是模拟3秒关闭
- setTimeout(() => {
- resolve()
- emit('export', item)
- }, 3000)
- }
- //批量删除
- const batchRemove = () => {
- if (!isAdminAuth.value) return
- const rows = tableCheckKeys.value
- console.log('批量删除', rows)
- }
- //批量导出
- const batchExport = () => {
- const rows = tableCheckKeys.value
- console.log('批量导出', rows)
- }
- //年数据
- const yearKey = ref('2023')
- const yearData = ref({})
- const yearIndex = ref(-1)
- const yearChange = (_, index) => {
-
- yearIndex.value = index
- }
- //合并列或行
- const tableYearMethod = ({ rowIndex, columnIndex }) => {
- return setSpanMethod(columnIndex, rowIndex)
- }
- //合并列或行
- const tableYearMethod1 = ({ rowIndex, columnIndex }) => {
- return setSpanMethod(columnIndex, rowIndex, false)
- }
- const saveCompleLoading = ref(false)
- const saveComplete = async ()=>{
- saveCompleLoading.value = true
- //发起请求
- const { error, code, msg } = await mainApi.updateProFin({
- ...yearData.value,
- })
- //判断状态
- saveCompleLoading.value = false
- if (!error && code === 200) {
- window?.$message?.success(msg)
-
- } else {
- window.$message.error(msg ?? '操作失败')
- }
- }
- const setSpanMethod = (column, row, isAllYear = true) => {
- if (column === 0) { //第一列
- const rows = [0, 3, 6, 9], irows = [1, 2, 4, 5, 7, 8, 10, 11]
- if (rows.indexOf(row) !== -1) {
- //主要季度隐藏
- return { rowspan: 3, colspan: 1 }
- } else if (irows.indexOf(row) !== -1) {
- //非主要的季度隐藏
- return { rowspan: 0, colspan: 0 }
- } else {
- return { rowspan: 1, colspan: 1 }
- }
- } else if (column === 2) { //第三列
- const rows = [0, 3, 6, 9], irows = [1, 2, 4, 5, 7, 8, 10, 11]
- if (rows.indexOf(row) !== -1) {
- //主要隐藏
- return { rowspan: 3, colspan: 1 }
- } else if (irows.indexOf(row) !== -1) {
- //非主要的隐藏
- return { rowspan: 0, colspan: 0 }
- } else {
- return { rowspan: 1, colspan: 1 }
- }
- } else if (column === 5) { //第六列
- if (isAllYear) {
- if (row === 0) {
- return { rowspan: 12, colspan: 1 }
- } else if (row > 0 && row < 12) {
- return { rowspan: 0, colspan: 0 }
- } else {
- return { rowspan: 1, colspan: 1 }
- }
- } else {
- const rows = [0, 3, 6, 9], irows = [1, 2, 4, 5, 7, 8, 10, 11]
- if (rows.indexOf(row) !== -1) {
- //主要隐藏
- return { rowspan: 3, colspan: 1 }
- } else if (irows.indexOf(row) !== -1) {
- //非主要的隐藏
- return { rowspan: 0, colspan: 0 }
- } else {
- return { rowspan: 1, colspan: 1 }
- }
- }
- } else if (column === 6) { //第七列
- if (isAllYear) {
- const rows = [0, 3, 6, 9], irows = [1, 2, 4, 5, 7, 8, 10, 11]
- if (rows.indexOf(row) !== -1) {
- //主要隐藏
- return { rowspan: 3, colspan: 1 }
- } else if (irows.indexOf(row) !== -1) {
- //非主要的隐藏
- return { rowspan: 0, colspan: 0 }
- } else {
- return { rowspan: 1, colspan: 1 }
- }
- }
- }
- }
- defineExpose({
- batchRemove,
- batchExport,
- })
- </script>
- <style lang="scss">
- .hc-project-list-table .el-table[hc].new {
- --el-table-header-bg-color: #101010;
- --el-table-header-text-color: #fff;
- --el-table-text-color: #101010;
- thead.is-group th.el-table__cell {
- background: var(--el-table-header-bg-color);
- }
- thead .el-table-fixed-column--left.el-table__cell,
- thead .el-table-fixed-column--right.el-table__cell {
- background: var(--el-table-header-bg-color) !important;
- }
- tbody .el-table-fixed-column--left.el-table__cell,
- tbody .el-table-fixed-column--right.el-table__cell {
- background: var(--el-table-tr-bg-color) !important;
- }
- .el-table__body tr.current-row>td.el-table__cell {
- background-color: var(--el-table-current-row-bg-color) !important;
- }
- }
- .hc-project-list-drawer-year {
- position: relative;
- border: 1px solid #dddddd;
- border-top: 0;
- height: calc(100% - 170px);
- &.detail {
- height: calc(100% - 34px);
- }
- .year-detail {
- padding: 14px;
- background: #f7f7f7;
- border-radius: 5px;
- .hc-card-item-header {
- border-bottom: 1px solid #ecebeb;
- padding-bottom: 10px;
- .item-header {
- justify-content: center;
- }
- }
- .el-table {
- --el-table-border-color: #dcdcdc;
- --el-table-header-text-color: #101010;
- --el-table-row-hover-bg-color: transparent;
- }
- .el-table th.el-table__cell.line {
- padding: 0;
- height: 100%;
- .cell {
- padding: 0;
- height: 100%;
- display: contents;
- }
- .hc-table-th-line {
- position: relative;
- height: 100%;
- font-size: 14px;
- display: contents;
- .left {
- position: absolute;
- bottom: 6px;
- left: 10px;
- }
- .right {
- position: absolute;
- top: 6px;
- right: 6px;
- font-size: 13px;
- }
- &::after {
- content: '';
- position: absolute;
- top: 36px;
- left: -20px;
- width: 180px;
- height: 1px;
- background: #dcdcdc;
- transform: rotate(27deg);
- }
- }
- }
- &.edit .el-table--enable-row-transition .el-table__body td.el-table__cell {
- height: 60px;
- }
- .el-table .el-table__cell .cell {
- .hc-new-main-body_content {
- padding: 4px !important;
- .el-input, .el-textarea {
- height: 100%;
- .el-input__inner {
- text-align: center;
- }
- .el-textarea__inner {
- height: 100%;
- }
- }
- }
- }
- }
- }
- </style>
|