Commit cec29ea6 authored by 高滢's avatar 高滢

Merge remote-tracking branch 'origin/develop' into develop

parents f462dfc2 5826ca23
......@@ -11,7 +11,7 @@ VITE_BUILD_COMPRESS = 'gzip'
# Basic interface address SPA
VITE_GLOB_API_URL = http://58.223.177.48:8088
VITE_GLOB_API_URL = https://dev.unitj.cn
# File upload address, optional
# It can be forwarded by nginx or write the actual address directly
......
export interface BasicPageParams {
pageNum: number;
pageSize: number;
page: number;
size: number;
}
export interface BasicFetchResult<T> {
......
......@@ -7,7 +7,7 @@ import {
import { defHttp } from '@/utils/http/axios';
enum Api {
GetList = '/pro/tenderManager/list/page',
GetList = '/pro/tenderManager/page',
AddProject = '/pro/tenderManager/add',
UpdateProject = '/pro/tenderManager/update',
DeleteProject = '/pro/tenderManager/del',
......@@ -33,5 +33,8 @@ export const updateItem = (params?: any) =>
'Content-Type': 'application/json;charset=UTF-8',
},
});
export const deleteItem = (params?: any) =>
defHttp.delete<ProjectModel>({ url: Api.DeleteProject, params });
export const getItem = (params?: any) =>
defHttp.get<ListItem[]>({ url: Api.ProjectDetail, params });
import { ProjectPageParams, ListGetResultModel, ProjectModel,ListItem } from './model/biddingPlanModel';
import {
ProjectPageParams,
ListGetResultModel,
ProjectModel,
ListItem,
} from './model/biddingPlanModel';
import { defHttp } from '@/utils/http/axios';
enum Api {
GetList = '/pro/tendePlan/page',
AddProject = '/pro/tendePlan/add',
UpdateProject = '/pro/tendePlan/update',
GetList = '/pro/tenderPlan/page',
AddProject = '/pro/tenderPlan/add',
UpdateProject = '/pro/tenderPlan/update',
DeleteProject = '/pro/tenderPlan/del',
ProjectDetail = '/pro/tendePlan/details',
ProjectDetail = '/pro/tenderPlan/details',
}
export const getListByPage = (params?: ProjectPageParams) =>
defHttp.post<ListGetResultModel>({ url: Api.GetList, data: params });
......@@ -28,5 +33,9 @@ export const updateItem = (params?: any) =>
'Content-Type': 'application/json;charset=UTF-8',
},
});
export const deleteItem = (params?: any) =>
defHttp.delete<ProjectModel>({ url: Api.DeleteProject, params });
export const getItem = (params?: any) =>
defHttp.get<ListItem[]>({ url: Api.ProjectDetail, params });
......@@ -23,7 +23,7 @@ export interface ListItem {
delFlag?: string | number;
}
export interface ProjectModel<T> {
export interface ProjectModel {
id?: string | number;
proNumber?: string | number;
biddingQuarter?: any;
......
......@@ -23,7 +23,7 @@ export interface ListItem {
delFlag?: string | number;
}
export interface ProjectModel<T> {
export interface ProjectModel {
id?: string | number;
proNumber?: string | number;
biddingQuarter?: any;
......
......@@ -24,6 +24,16 @@ const dashboard: AppRouteModule = {
title: '项目库',
},
},
{
path: 'detail',
name: 'project-detail',
component: () => import('@/views/project/detail.vue'),
meta: {
orderNo: 1,
// affix: true,
title: '项目库',
},
},
],
};
......
......@@ -9,9 +9,9 @@ export default {
// support xxx.xxx.xxx
fetchSetting: {
// The field name of the current page passed to the background
pageField: 'pageNum',
pageField: 'page',
// The number field name of each page displayed in the background
sizeField: 'pageSize',
sizeField: 'size',
// Field name of the form data returned by the interface
listField: 'items',
// Total number of tables returned by the interface field name
......
......@@ -41,8 +41,9 @@
import { getListByPage, deleteItem } from '@/api/project/biddingManagement';
import { columns, searchFormSchema } from './biddingManagement.data';
import { useModal } from '@/components/Modal';
import { router } from '@/router';
import yearModal from '@/components/yearModal.vue';
import { useRouter } from 'vue-router';
const { push } = useRouter();
defineOptions({ name: 'RoleManagement' });
const [registerTable, { reload }] = useTable({
......@@ -72,7 +73,7 @@
}
function handleEdit(record: Recordable, disabled: boolean) {
router.push({
push({
path: '/biddingManagement/edit',
query: {
id: record.id,
......@@ -88,7 +89,7 @@
function handleNew(e) {
console.log(e);
router.push({
push({
path: '/biddingManagement/edit',
query: e,
});
......
......@@ -41,9 +41,9 @@
import { getListByPage, deleteItem } from '@/api/project/biddingPlan';
import { useModal } from '@/components/Modal';
import yearModal from '@/components/yearModal.vue';
import { router } from '@/router';
import { columns, searchFormSchema } from './biddingPlan.data';
import { useRouter } from 'vue-router';
const { push } = useRouter();
const [register, { openModal: openModal }] = useModal();
const [registerTable, { reload }] = useTable({
api: getListByPage,
......@@ -57,7 +57,7 @@
bordered: true,
showIndexColumn: false,
actionColumn: {
width: 80,
width: 150,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
......@@ -72,7 +72,7 @@
}
function handleEdit(record: Recordable, disabled: boolean) {
router.push({
push({
path: '/biddingManagement/edit',
query: {
id: record.id,
......@@ -88,7 +88,7 @@
function handleNew(e) {
console.log(e);
router.push({
push({
path: '/biddingPlan/edit',
query: e,
});
......
......@@ -125,53 +125,208 @@ export const searchFormSchema: FormSchema[] = [
},
];
export const formSchema: FormSchema[] = [
export const formSchema: ({ colProps: { offset: number; span: number }; component: string; field: string; componentProps: { readonly: boolean; style: { border: string } }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { readonly: boolean; style: { border: string } }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { readonly: boolean; style: { border: string } }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { readonly: boolean; style: { border: string } }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { readonly: boolean; style: { border: string } }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { readonly: boolean; style: { border: string } }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { readonly: boolean; style: { border: string } }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { readonly: boolean; style: { border: string } }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { readonly: boolean; style: { border: string } }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { valueFormat: string; format: string; style: { width: string }; placeholder: string }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { addonAfter: string }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { addonAfter: string }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { addonAfter: string }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { addonAfter: string }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { options: ({ label: string; value: string } | { label: string; value: string } | { label: string; value: string })[] }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; icon: string; componentProps: { style: { width: string }; placeholder: string[] }; label: string; required: boolean } | { colProps: { offset: number; span: number }; component: string; field: string; componentProps: { options: ({ label: string; value: string } | { label: string; value: string } | { label: string; value: string })[] }; label: string; required: boolean })[] = [
{
field: 'projectName',
label: '项目名称',
component: 'Input',
required: true,
component: 'Input',
componentProps: {
placeholder: 'XXXX项目',
disabled: true,
style: {
background: 'none',
border: 'none',
},
readonly: true,
style: { border: 'none' },
},
colProps: { span: 8 },
colProps: { span: 7, offset: 1 },
},
{
field: 'projectName',
field: 'constructionSite',
label: '建设地点',
component: 'Input',
required: true,
component: 'Input',
componentProps: {
placeholder: '华苑片区',
disabled: true,
style: {
background: 'none',
border: 'none',
},
readonly: true,
style: { border: 'none' },
},
colProps: { span: 8 },
colProps: { span: 7, offset: 1 },
},
{
field: 'projectName',
field: 'constructionMode',
label: '建设模式',
required: true,
component: 'Input',
componentProps: {
readonly: true,
style: { border: 'none' },
},
colProps: { span: 7, offset: 1 },
},
{
field: 'projectType',
label: '项目类型',
required: true,
component: 'Input',
componentProps: {
readonly: true,
style: { border: 'none' },
},
colProps: { span: 7, offset: 1 },
},
{
field: 'constructionScale',
label: '建设规模',
required: true,
component: 'Input',
componentProps: {
readonly: true,
style: { border: 'none' },
},
colProps: { span: 7, offset: 1 },
},
{
field: 'projectOverview',
label: '项目概况:',
required: true,
component: 'Input',
componentProps: {
readonly: true,
style: { border: 'none' },
},
colProps: { span: 7, offset: 1 },
},
{
field: 'fundingSource',
label: '资金来源:',
required: true,
component: 'Input',
componentProps: {
readonly: true,
style: { border: 'none' },
},
colProps: { span: 7, offset: 1 },
},
{
field: 'implementingEntity',
label: '实施主体:',
required: true,
component: 'Input',
componentProps: {
readonly: true,
style: { border: 'none' },
},
colProps: { span: 7, offset: 1 },
},
{
field: 'projectOverview',
label: '项目概况:',
required: true,
component: 'Input',
componentProps: {
placeholder: '自建',
disabled: true,
style: {
background: 'none',
border: 'none',
},
readonly: true,
style: { border: 'none' },
},
colProps: { span: 8 },
colProps: { span: 7, offset: 1 },
},
// {
// field: 'data',
// label: '填报周期:',
// required: true,
// component: 'DatePicker',
// componentProps: {
// placeholder: '选择填报周期',
// style: { width: '100%' },
// valueFormat: 'YYYY-MM-DD',
// format: 'YYYY-MM-DD',
// },
// colProps: { span: 7, offset: 1 },
// },
// {
// field: 'investmentAmount',
// label: '总投资',
// required: true,
// component: 'Input',
// componentProps: {
// addonAfter: '万元',
// },
// colProps: { span: 7, offset: 1 },
// },
// {
// field: 'investmentAmount',
// label: '项目主管部门',
// required: true,
// component: 'Input',
// colProps: { span: 7, offset: 1 },
// },
//
// {
// field: 'investmentAmount',
// label: '2024年财政预算匹配资金',
// required: true,
// component: 'Input',
// componentProps: {
// addonAfter: '万元',
// },
// colProps: { span: 7, offset: 1 },
// },
// {
// field: 'investmentAmount',
// label: '其中专项债项目2024年预计使用专项债资金',
// required: true,
// component: 'Input',
// componentProps: {
// addonAfter: '万元',
// },
// colProps: { span: 7, offset: 1 },
// },
// {
// field: 'investmentAmount',
// label: '2024年计划资金',
// required: true,
// component: 'Input',
// componentProps: {
// addonAfter: '万元',
// },
// colProps: { span: 7, offset: 1 },
// },
// {
// field: 'investmentAmount',
// label: '建设性质',
// required: true,
// component: 'Select',
// componentProps: {
// options: [
// { label: '新建', value: '0' },
// { label: '结转', value: '1' },
// { label: '缓建', value: '2' },
// ],
// },
// colProps: { span: 7, offset: 1 },
// },
// {
// component: 'RangePicker',
// label: '开竣工时间',
// required: true,
// icon: 'healthicons:i-schedule-school-date-time-outline',
// field: '',
// colProps: { span: 7, offset: 1 },
// componentProps: {
// placeholder: ['开始日期', '结束日期'],
// style: { width: '100%' },
// },
// },
// {
// field: 'investmentAmount',
// label: '2024年底预计形象进度',
// required: true,
// component: 'Select',
// componentProps: {
// options: [
// { label: 'A(已经立项实施的跨年工程)', value: '0' },
// { label: 'B(该年度必须建设的项目)', value: '1' },
// { label: 'B(该年度必须建设的项目)', value: '2' },
// ],
// },
// colProps: { span: 7, offset: 1 },
// },
// {
// field: 'isReserveProject',
// label: '是否为储备项目',
// component: 'RadioButtonGroup',
......
<template>
<div>
<PageWrapper :title="getTitle" :contentBackground="false" headerSticky>
<template #extra>
<a-button type="primary" danger @click="delect"> 删除 </a-button>
</template>
<PageCard v-for="(item, index) in tabsFormSchema" :key="index" :title="item.name">
<BasicForm @register="item.Form[0]" />
</PageCard>
<PageWrapper :title="getTitle" :contentBackground="false" headerSticky>
<template #extra>
<a-button type="primary" danger> 删除 </a-button>
<a-button type="primary" @click="handleSubmit"> 提交 </a-button>
</template>
<a-button type="primary" @click="addItem"> 添加 </a-button>
</PageWrapper>
<projectlibraryModel @register="register" @close="handleNew" />
</div>
<PageCard v-for="(item, index) in tabsFormSchema" :key="index" :title="item.name">
<template #right>
<a-button
type="text"
preIcon="ant-design:delete-outlined"
danger
@click="deleteItem(index)"
/>
</template>
<BasicForm :loading="loading" @register="item.Form[0]" />
<div style="width: 500px">
{{ 'tableRefIndex' + index }}
<BasicTable :ref="'tableRefIndex'" @register="item.table" :beforeEditSubmit="beforeEditSubmit(index)" />
</div>
</PageCard>
<a-button type="dashed" @click="add" preIcon="ei:plus"> 从项目库导入 </a-button>
<a-button type="dashed" @click="handleAdd" class="ml-2" preIcon="ei:plus"> 新建项目 </a-button>
<projectDrawer @register="registerDrawer" @success="handleSuccess" />
<projectlibraryModel @register="register" @close="handleNewData" />
</PageWrapper>
</template>
<script lang="ts" setup>
import projectlibraryModel from '@/components/projectlibraryModel/projectlibraryModel.vue';
const [register, { openModal: openModal }] = useModal();
import { unref, computed, onMounted, ref, reactive } from 'vue';
import { BasicTable, useTable } from '@/components/Table';
import { getBasicColumns } from './tableData';
import { ref, nextTick, onMounted, unref, computed, reactive } from 'vue';
import { demoListApi } from '@/api/demo/table';
import projectlibraryModel from '@/components/projectlibraryModel/projectlibraryModel.vue';
import { useRoute } from 'vue-router';
import { PageWrapper } from '@/components/Page';
import PageCard from '@/components/Page/src/PageCard.vue';
import projectDrawer from '@/views/project/projectDrawer.vue';
import { BasicForm, useForm, FormProps, UseFormReturnType } from '@/components/Form';
import { formSchema } from './data';
import {useModal} from "@/components/Modal";
import {router} from "@/router";
import { deepMerge } from '@/utils';
import { useMessage } from '@/hooks/web/useMessage';
import { useDrawer } from '@/components/Drawer';
import { addItem, updateItem, getItem } from '@/api/project/biddingPlan';
import { editModel } from '@/api/project/model/biddingPlanModel';
import { useModal } from '@/components/Modal';
let show = ref<Recordable[]>([]);
// function handleSummary(tableData: Recordable[]) {
// const totalNo = tableData.reduce((prev, next) => {
// prev += next.no;
// return prev;
// }, 0);
// return [
// {
// _row: '合计',
// _index: '平均值',
// no: totalNo,
// },
// {
// _row: '合计',
// _index: '平均值',
// no: totalNo,
// },
// ];
// }
function beforeEditSubmit(index) {
// const tableRefIndex = ref<HTMLElement>([]);
// const setBoxRef = (el: any) => {
// if (el) {
// tableRefIndex.value.push(el);
// }
// };
// console.log('ref节点', setBoxRef);
// let res = getDataSource();
// console.log('res', res);
// console.log('show', show);
// const totalNo = res.reduce((prev, next) => {
// prev += Number(next.no);
// return prev;
// }, 0);
// console.log('totalNo', totalNo);
// show.value = [
// {
// year: '合计',
// // _row: '合计',
// // _index: '合计',
// no: totalNo,
// },
// ];
// return true;
}
// const [registerTable, { getDataSource, setTableData }] = useTable({
// title: '表尾行合计示例',
// // api: demoListApi,
// // rowSelection: { type: 'checkbox' },
// columns: getBasicColumns(),
// showSummary: true,
// summaryData: show,
// maxHeight: 180,
// maxWidth: 200,
// showIndexColumn: false,
// pagination: false,
// // scroll: { x: 2000 },
// // canResize: false,
// // showSelectionBar: true, // 显示多选状态栏
// });
onMounted(async () => {
show.value = [
{
year: '合计',
// _row: '合计',
// _index: '合计',
no: '-',
},
];
// setTableData([
// {
// year: '2022',
// no: '',
// },
// {
// year: '2023',
// no: '',
// },
// {
// year: '2024',
// no: '',
// },
// ]);
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增2024年工程项目投资计划(工程)' : '编辑2024年工程项目投资计划(工程)'));
const [registerDrawer, { openDrawer }] = useDrawer();
const [register, { openModal: openModal }] = useModal();
const { createMessage } = useMessage();
const getTitle = computed(() =>
!unref(isUpdate) ? '新增工程项目投资计划(工程)' : '编辑工程项目投资计划(工程)',
);
const isUpdate = ref(false);
onMounted(() => {
const loading = ref(false);
const formData = ref<editModel>({});
onMounted(async () => {
const route = useRoute();
const id = route.query.id; // 获取名为id的参数
console.log(route.query);
if (!id) {
formData.value.biddingQuarter = route.query.quarter;
formData.value.tenderYear = route.query.year;
formData.value.tenderPlanPro = [];
isUpdate.value = false;
console.log(formData);
} else {
isUpdate.value = true;
let res = await getItem({ id });
formData.value.biddingQuarter = res.data.quarter;
formData.value.tenderYear = res.data.year;
for (let i = 0; i < res.data.tenderPlanPro.length; i++) {
const item = {
name: '序号' + (i + 1),
forceRender: true,
Form: useForm(Object.assign({ schemas: formSchema }, baseFormConfig) as FormProps),
table: useTable({
title: '表尾行合计示例',
// api: demoListApi,
// rowSelection: { type: 'checkbox' },
columns: getBasicColumns(),
showSummary: true,
summaryData: show,
maxHeight: 180,
maxWidth: 200,
showIndexColumn: false,
pagination: false,
// scroll: { x: 2000 },
// canResize: false,
// showSelectionBar: true, // 显示多选状态栏
}),
};
const { setFieldsValue } = item.Form[1];
tabsFormSchema.push(item);
formData.value.tenderPlanPro.push({
proId: info.id,
});
nextTick(() => {
setFieldsValue({
projectName: info.projectName,
constructionSite: info.constructionSite,
constructionMode: info.constructionMode,
projectType: info.projectType,
constructionScale: info.constructionScale,
projectOverview: info.projectOverview,
fundingSource: info.fundingSource,
implementingEntity: info.implementingEntity,
});
});
}
console.log(res);
}
});
type TabsFormType = {
name: string;
forceRender?: boolean;
Form: UseFormReturnType;
table: any;
};
const baseFormConfig: Partial<FormProps> = {
showActionButtonGroup: false,
......@@ -47,24 +214,116 @@
const tabsFormSchema = reactive<TabsFormType[]>([]);
async function addItem() {
tabsFormSchema.push({
async function add() {
openModal();
}
async function handleNewData(info: any) {
if (info) {
info.map((i) => {
handleNew(i);
});
}
}
/***
*
*/
async function handleNew(info: any) {
const item = {
name: '序号' + (tabsFormSchema.length + 1),
forceRender: true,
Form: useForm(Object.assign({ schemas: formSchema }, baseFormConfig) as FormProps),
table: useTable({
title: '表尾行合计示例',
// api: demoListApi,
// rowSelection: { type: 'checkbox' },
columns: getBasicColumns(),
showSummary: true,
summaryData: show,
maxHeight: 180,
maxWidth: 200,
showIndexColumn: false,
pagination: false,
// scroll: { x: 2000 },
// canResize: false,
// showSelectionBar: true, // 显示多选状态栏
}),
};
const { setTableData } = item.table[1];
// console.log('item.table',setTableData)
const { setFieldsValue } = item.Form[1];
tabsFormSchema.push(item);
formData.value.tenderPlanPro.push({
proId: info.id,
});
nextTick(() => {
setTableData([
{
year: '2022',
no: '',
},
{
year: '2023',
no: '',
},
{
year: '2024',
no: '',
},
]);
setFieldsValue({
projectName: info.projectName,
constructionSite: info.constructionSite,
constructionMode: info.constructionMode,
projectType: info.projectType,
constructionScale: info.constructionScale,
projectOverview: info.projectOverview,
fundingSource: info.fundingSource,
implementingEntity: info.implementingEntity,
});
});
}
async function deleteItem(index: any) {
tabsFormSchema.splice(index, 1);
formData.value.tenderPlanPro.splice(index, 1);
}
async function delect() {
openModal(true, {
// data: ['year'],
async function handleAdd() {
openDrawer(true, {
isUpdate: false,
});
}
const handleNew = (e) => {
console.log('e', e);
};
async function handleSuccess(params: any) {
console.log(params);
handleNew(params);
}
async function handleSubmit() {
console.log('tabsFormSchema', tabsFormSchema);
loading.value = true;
try {
for (let i = 0; i < tabsFormSchema.length; i++) {
let item = tabsFormSchema[i];
const { validate, getFieldsValue } = item.Form[1];
await validate();
let res = getFieldsValue();
console.log(' getFieldsValue()', getFieldsValue());
// res.biddingPeriod = res.biddingPeriod.join(',');
// res.plannedPeriod = res.plannedPeriod.join(',');
formData.value.tenderPlanPro[i] = deepMerge(formData.value.tenderPlanPro[i], res);
console.log(formData.value.tenderPlanPro);
}
formData.value.proNumber = formData.value.tenderPlanPro.Length;
console.log(' formData()', formData);
console.log(' setTableData()', setTableData);
let res = isUpdate.value ? await updateItem(unref(formData)) : await addItem(unref(formData));
loading.value = false;
console.log(res);
createMessage.success('提交成功!');
} catch (e) {
// 验证失败或出错,切换到对应标签页
console.log(e);
} finally {
loading.value = false;
}
}
</script>
<style lang="less" scoped>
// .vben-page-wrapper-content-bg {
// background-color: transparent;
// }
</style>
......@@ -16,11 +16,13 @@
<TableAction
:actions="[
{
icon: 'clarity:note-edit-line',
label: '修改',
// icon: 'clarity:note-edit-line',
onClick: handleEdit.bind(null, record),
},
{
icon: 'ant-design:delete-outlined',
label: '删除',
// icon: 'ant-design:delete-outlined',
color: 'error',
popConfirm: {
title: '是否确认删除',
......@@ -68,7 +70,7 @@
bordered: true,
showIndexColumn: false,
actionColumn: {
width: 80,
width: 160,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
......@@ -77,9 +79,15 @@
});
function handleEdit(record: Recordable) {
openDrawer(true, {
record,
isUpdate: true,
// openDrawer(true, {
// record,
// isUpdate: true,
// });
router.push({
path: '/engineeringProject/edit',
query: {
id: record.id,
},
});
}
......
import { optionsListApi } from '@/api/demo/select';
import { FormProps, FormSchema, BasicColumn } from '@/components/Table';
import { VxeFormItemProps, VxeGridPropTypes } from '@/components/VxeTable';
import { ref } from 'vue';
import { Input } from 'ant-design-vue';
export function getBasicColumns(): BasicColumn[] {
return [
// {
// title: 'ID',
// dataIndex: 'id',
// fixed: 'left',
// width: 200,
// },
// {
// title: '姓名',
// dataIndex: 'name',
// width: 150,
// filters: [
// { text: 'Male', value: 'male' },
// { text: 'Female', value: 'female' },
// ],
// },
// {
// title: '地址',
// dataIndex: 'address',
// },
{
title: '年份',
dataIndex: 'year',
width: 80,
},
{
title: '金额(万元)',
dataIndex: 'no',
width: 150,
// sorter: true,
// defaultHidden: true,
edit: true,
},
// {
// title: '开始时间',
// width: 150,
// sorter: true,
// dataIndex: 'beginTime',
// },
// {
// title: '结束时间',
// width: 150,
// sorter: true,
// dataIndex: 'endTime',
// },
];
}
export function getBasicShortColumns(): BasicColumn[] {
return [
{
title: 'ID',
width: 150,
dataIndex: 'id',
sorter: true,
sortOrder: 'ascend',
},
{
title: '姓名',
dataIndex: 'name',
width: 120,
},
{
title: '地址',
dataIndex: 'address',
},
{
title: '编号',
dataIndex: 'no',
width: 80,
},
];
}
export function getMultipleHeaderColumns(): BasicColumn[] {
const testRef = ref('姓名:');
return [
{
title: 'ID',
dataIndex: 'id',
width: 200,
},
{
title: '姓名',
customHeaderRender() {
return (
<Input placeholder="输入值 更新 自定义title" size="small" v-model:value={testRef.value} />
);
},
dataIndex: 'name',
width: 120,
},
{
title: '地址',
dataIndex: 'address',
sorter: true,
children: [
{
title: '编号',
customHeaderRender(column) {
// 【自定义渲染的】
return (
<div>
_ <span style="background: #f00; color: #fff;">{testRef.value}</span> _
{column.customTitle}
</div>
);
},
dataIndex: 'no',
width: 120,
filters: [
{ text: 'Male', value: 'male', children: [] },
{ text: 'Female', value: 'female', children: [] },
],
},
{
title: '开始时间',
dataIndex: 'beginTime',
width: 120,
},
{
title: '结束时间',
dataIndex: 'endTime',
width: 120,
},
],
},
];
}
export function getCustomHeaderColumns(): BasicColumn[] {
return [
{
title: 'ID',
dataIndex: 'id',
helpMessage: 'headerHelpMessage方式1',
width: 200,
},
{
// title: '姓名',
dataIndex: 'name',
width: 120,
},
{
// title: '地址',
dataIndex: 'address',
width: 120,
sorter: true,
},
{
title: '编号',
dataIndex: 'no',
width: 120,
filters: [
{ text: 'Male', value: 'male', children: [] },
{ text: 'Female', value: 'female', children: [] },
],
},
{
title: '开始时间',
dataIndex: 'beginTime',
width: 120,
},
{
title: '结束时间',
dataIndex: 'endTime',
width: 120,
},
];
}
const cellContent = (_, index) => ({
colSpan: index === 9 ? 0 : 1,
});
export function getMergeHeaderColumns(): BasicColumn[] {
return [
{
title: 'ID',
dataIndex: 'id',
width: 300,
customCell: (_, index) => ({
colSpan: index === 9 ? 6 : 1,
}),
},
{
title: '姓名',
dataIndex: 'name',
width: 300,
customCell: cellContent,
},
{
title: '地址',
dataIndex: 'address',
colSpan: 2,
width: 120,
sorter: true,
customCell: (_, index) => ({
rowSpan: index === 2 ? 2 : 1,
colSpan: index === 3 || index === 9 ? 0 : 1,
}),
},
{
title: '编号',
dataIndex: 'no',
colSpan: 0,
filters: [
{ text: 'Male', value: 'male', children: [] },
{ text: 'Female', value: 'female', children: [] },
],
customCell: cellContent,
},
{
title: '开始时间',
dataIndex: 'beginTime',
width: 200,
customCell: cellContent,
},
{
title: '结束时间',
dataIndex: 'endTime',
width: 200,
customCell: cellContent,
},
];
}
export const getAdvanceSchema = (itemNumber = 6): FormSchema[] => {
const arr: FormSchema[] = [];
for (let index = 0; index < itemNumber; index++) {
arr.push({
field: `field${index}`,
label: `字段${index}`,
component: 'Input',
colProps: {
xl: 12,
xxl: 8,
},
});
}
return arr;
};
export function getFormConfig(): Partial<FormProps> {
return {
labelWidth: 100,
schemas: [
...getAdvanceSchema(5),
{
field: `field11`,
label: `Slot示例`,
slot: 'custom',
colProps: {
xl: 12,
xxl: 8,
},
},
],
};
}
export function getBasicData() {
return (() => {
const arr: any = [];
for (let index = 0; index < 40; index++) {
arr.push({
id: `${index}`,
name: 'John Brown',
age: `1${index}`,
no: `${index + 10}`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
});
}
return arr;
})();
}
export function getTreeTableData() {
return (() => {
const arr: any = [];
for (let index = 0; index < 40; index++) {
arr.push({
id: `${index}`,
name: 'John Brown',
age: `1${index}`,
no: `${index + 10}`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
children: [
{
id: `l2-${index}-1`,
name: 'John Brown',
age: `1`,
no: `${index + 10}`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
children: [
{
id: `l3-${index}-1-1`,
name: 'John Brown',
age: `11`,
no: `11`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
},
{
id: `l3-${index}-1-2`,
name: 'John Brown',
age: `12`,
no: `12`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
},
],
},
{
id: `l2-${index}-2`,
name: 'John Brown',
age: `2`,
no: `${index + 10}`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
children: [
{
id: `l3-${index}-2-1`,
name: 'John Brown',
age: `21`,
no: `21`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
},
{
id: `l3-${index}-2-2`,
name: 'John Brown',
age: `22`,
no: `22`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
},
],
},
],
});
}
return arr;
})();
}
export const vxeTableColumns: VxeGridPropTypes.Columns = [
{
title: '序号',
type: 'seq',
fixed: 'left',
width: '50',
align: 'center',
},
{
title: '固定列',
field: 'name',
width: 150,
showOverflow: 'tooltip',
fixed: 'left',
},
{
title: '自适应列',
field: 'address',
},
{
title: '自定义列(自定义导出)',
field: 'no',
width: 200,
showOverflow: 'tooltip',
align: 'center',
slots: {
default: ({ row }) => {
const text = `自定义${row.no}`;
return [<div class="text-red-500">{text}</div>];
},
},
exportMethod: ({ row }) => {
return `自定义${row.no}导出`;
},
},
{
title: '自定义编辑',
width: 150,
field: 'name1',
align: 'center',
editRender: {
name: 'AInput',
placeholder: '请点击输入',
},
},
{
title: '开始时间',
width: 150,
field: 'beginTime',
showOverflow: 'tooltip',
align: 'center',
},
{
title: '结束时间',
width: 150,
field: 'endTime',
showOverflow: 'tooltip',
align: 'center',
},
{
width: 160,
title: '操作',
align: 'center',
slots: { default: 'action' },
fixed: 'right',
},
];
export const vxeTableFormSchema: VxeFormItemProps[] = [
{
field: 'field0',
title: 'field0',
itemRender: {
name: 'AInput',
},
span: 6,
},
{
field: 'field1',
title: 'field1',
itemRender: {
name: 'AApiSelect',
props: {
api: optionsListApi,
resultField: 'list',
labelField: 'name',
valueField: 'id',
},
},
span: 6,
},
{
span: 12,
align: 'right',
className: '!pr-0',
itemRender: {
name: 'AButtonGroup',
children: [
{
props: { type: 'primary', content: '查询', htmlType: 'submit' },
attrs: { class: 'mr-2' },
},
{ props: { type: 'default', htmlType: 'reset', content: '重置' } },
],
},
},
];
<template>
<PageWrapper :class="prefixCls">
<PageCard>
<div class="header">
<div class="header-tab">
<img class="header-tab-logo" src="../../assets/images/logo.png" alt="" />
<div class="header-tab-right">
<div class="header-tab-right-title">{{ detail.projectName }}</div>
<div class="header-tab-right-desc">{{ detail.projectName }}</div>
</div>
</div>
<div class="header-body">
<div class="header-body-item">
<div class="header-body-item-title">实施主体</div>
<div class="header-body-item-value">{{ detail.implementingEntity }}</div>
</div>
<div class="header-body-item">
<div class="header-body-item-title">建设模式</div>
<div class="header-body-item-value">{{ detail.constructionMode }}</div>
</div>
<div class="header-body-item">
<div class="header-body-item-title">建设地点</div>
<div class="header-body-item-value">{{ detail.constructionSite }}</div>
</div>
<div class="header-body-item">
<div class="header-body-item-title">项目类型</div>
<div class="header-body-item-value">{{ detail.projectType }}</div>
</div>
<div class="header-body-item">
<div class="header-body-item-title">资金来源</div>
<div class="header-body-item-value">{{ detail.fundingSource }}</div>
</div>
<div class="header-body-item">
<div class="header-body-item-title">建设规模</div>
<div class="header-body-item-value">{{ detail.constructionScale }}</div>
</div>
<div class="header-body-item">
<div class="header-body-item-title">建设目的及项目功能</div>
<div class="header-body-item-value">{{ detail.constructionPurpose }}</div>
</div>
<div class="header-body-item">
<div class="header-body-item-title">更新人/更新时间</div>
<div class="header-body-item-value"
>{{ detail.updateBy || '--' }}/{{ detail.updateTime || '--' }}</div
>
</div>
</div>
<!-- <Descriptions></Descriptions> -->
</div>
</PageCard>
<BasicTable @register="registerTable">
<template #tabSlot>
<Tabs v-model:activeKey="activeKey" @change="reload()">
<template v-for="item in tabList" :key="item.key">
<TabPane :tab="item.tab" />
</template>
</Tabs>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'projectName'">
<Tag color="warning" v-if="record.isReserveProject == 'true'"> 储备 </Tag>
{{ record.projectName }}
</template>
<template v-if="column.key === 'constructionMode'">
<Tag color="processing">
{{ record.constructionMode }}
</Tag>
</template>
<template v-if="column.key === 'action'">
<TableAction
:actions="[
// {
// label: '详情',
// onClick: handleDetail.bind(null, record),
// },
// {
// label: '编辑',
// onClick: handleEdit.bind(null, record, false),
// },
// {
// label: '删除',
// color: 'error',
// popConfirm: {
// title: '是否确认删除',
// placement: 'left',
// confirm: handleDelete.bind(null, record),
// },
// },
]"
/>
</template>
</template>
</BasicTable>
</PageWrapper>
</template>
<script lang="ts" setup>
import { Tabs } from 'ant-design-vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { getListByPage, getItem } from '@/api/project/project';
import { columns, searchFormSchema, tabList } from './project.data';
import { ref, onMounted } from 'vue';
import { useRoute } from 'vue-router';
let detail = ref<any>({});
const activeKey = ref('1');
const [registerTable, { reload }] = useTable({
api: getListByPage,
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
searchInfo: { tabName: activeKey },
useSearchForm: true,
showTableSetting: false,
bordered: true,
showIndexColumn: false,
actionColumn: {
width: 200,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
fixed: undefined,
},
});
onMounted(async () => {
const route = useRoute();
const id = route.query.id; // 获取名为id的参数
let res = await getItem({ id });
console.log(res);
detail.value = res;
console.log(detail.value);
});
</script>
<style lang="less" scoped>
.header {
background-color: #ffffff;
margin: 0 16px;
margin-top: 16px;
height: 208px;
&-tab {
padding: 30px;
display: flex;
justify-content: flex-start;
align-items: center;
&-logo {
border-radius: 100%;
width: 72px;
height: 72px;
margin-right: 10px;
}
&-right {
display: flex;
flex-flow: column;
color: #1c1c1c;
&-title {
font-size: 36px;
}
&-desc {
font-size: 14px;
margin-top: 6px;
}
}
}
&-body {
display: flex;
flex-wrap: wrap;
&-item {
flex: 1;
&-title {
text-align: center;
color: #536387;
font-size: 14px;
}
&-value {
text-align: center;
color: #000000;
margin-top: 16px;
font-size: 12px;
}
}
}
}
</style>
......@@ -52,7 +52,7 @@
:actions="[
{
label: '详情',
onClick: handleEdit.bind(null, record, true),
onClick: handleDetail.bind(null, record),
},
{
label: '编辑',
......@@ -83,6 +83,8 @@
import { Row, Col } from 'ant-design-vue';
import projectDrawer from './projectDrawer.vue';
import { useDrawer } from '@/components/Drawer';
import { useRouter } from 'vue-router';
const { push } = useRouter();
const [registerDrawer, { openDrawer }] = useDrawer();
const prefixCls = 'list-basic';
const [registerTable, { reload }] = useTable({
......@@ -110,7 +112,14 @@
isUpdate: false,
});
}
function handleDetail(record: any) {
push({
path: '/project/detail',
query: {
id: record.id,
},
});
}
async function handleEdit(record: Recordable, disabled: boolean) {
// let res = await getItem({ id: record.id });
// console.log(res);
......
......@@ -211,144 +211,19 @@ export const formSchema: FormSchema[] = [
];
export const searchFormSchema: FormSchema[] = [
{
field: 'projectName',
field: 'year',
label: '',
component: 'Input',
componentProps: {
placeholder: '输入搜索关键词',
},
colProps: { span: 4 },
},
{
field: 'constructionMode',
component: 'RadioButtonGroup',
colProps: {
span: 6,
},
componentProps: {
options: [
{
label: '全部项目',
value: undefined,
},
{
label: '自建',
value: '1自建',
},
{
label: '委托建设',
value: '委托建设',
},
{
label: '代理',
value: '代理',
},
{
label: '承建',
value: '承建',
},
],
},
},
{
field: 'isReserveProject',
component: 'Switch',
colProps: {
span: 2,
},
componentProps: {
checkedValue: 'true',
unCheckedValue: 'false',
},
label: '储备项目',
labelWidth: 70,
},
{
field: 'ImplementingEntity',
label: '',
component: 'Select',
componentProps: {
placeholder: '实施主体',
options: [
{
label: '了解产品',
value: '了解产品',
key: '了解产品',
},
{
label: '正在跟进',
value: '正在跟进',
key: '正在跟进',
},
{
label: '正在试用',
value: '正在试用',
key: '正在试用',
},
{
label: '准备购买',
value: '准备购买',
key: '准备购买',
},
{
label: '准备付款',
value: '准备付款',
key: '准备付款',
},
{
label: '已经购买',
value: '已经购买',
key: '已经购买',
},
{
label: '暂时闲置',
value: '暂时闲置',
key: '暂时闲置',
},
],
},
colProps: { span: 3 },
},
{
field: 'projectType',
label: '',
component: 'Select',
component: 'DatePicker',
required: true,
componentProps: {
placeholder: '项目类型',
options: [
{
label: '公共设施配套类',
value: '公共设施配套类',
key: '公共设施配套类',
},
{
label: '基础设施类',
value: '基础设施类',
key: '基础设施类',
},
{
label: '产业载体类',
value: '产业载体类',
key: '产业载体类',
},
{
label: '房地产类',
value: '房地产类',
key: '房地产类',
},
{
label: '存量盘活类',
value: '存量盘活类',
key: '存量盘活类',
},
{
label: '其他类(零星工程)',
value: '其他类(零星工程)',
key: '其他类(零星工程)',
},
],
placeholder: '选择填报周期',
valueFormat: 'YYYY-MM-dd',
format: 'YYYY-MM-dd',
style: {
width: '100%',
},
},
colProps: { span: 3 },
colProps: { span: 5 },
},
];
......@@ -394,3 +269,61 @@ export const columns: BasicColumn[] = [
width: 180,
},
];
export const tabList = [
{
key: '1',
tab: '投资计划',
},
{
key: '2',
tab: '计划完成情况',
},
{
key: '3',
tab: '年度资金计划',
},
{
key: '4',
tab: '月度资金计划',
},
{
key: '5',
tab: '已竣工验收项目陈欠资金计划',
},
{
key: '6',
tab: '招标计划',
},
{
key: '7',
tab: '招标管理',
},
{
key: '8',
tab: '结算管理',
},
{
key: '9',
tab: '变更签证管理',
},
{
key: '10',
tab: '安全隐患管理',
},
{
key: '11',
tab: '安全教育培训',
},
{
key: '12',
tab: '合同管理',
},
{
key: '13',
tab: '附件记录',
},
{
key: '14',
tab: '更新记录',
},
];
......@@ -18,8 +18,8 @@ export default defineApplicationConfig({
server: {
proxy: {
'/api': {
// target: 'https://dev.unitj.cn',
target: 'http://58.223.177.48:8088',
target: 'https://dev.unitj.cn',
// target: 'http://58.223.177.48:8088',
changeOrigin: true,
// ws: false,
rewrite: (path) => path.replace(new RegExp(`^/api`), ''),
......
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