From 94222c2b891cc18b1a6dedb0dc6cf9455bbf8895 Mon Sep 17 00:00:00 2001 From: lix Date: Thu, 12 Jun 2025 17:16:06 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=BB=BA=E6=A1=A3=EF=BC=9A?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E9=A1=B5=E3=80=81=E6=96=B0=E5=BB=BA=E3=80=81?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/router.config.ts | 13 + mock/projectFile.js | 26 ++ src/components/CitySelect.tsx | 336 ++++++++++++++ src/pages/Loading/service.ts | 2 +- src/pages/ProjectFiles/data.d.ts | 16 + src/pages/ProjectFiles/dict.ts | 137 ++++++ src/pages/ProjectFiles/file.tsx | 747 ++++++++++++++++++++++++++++++ src/pages/ProjectFiles/index.tsx | 104 +++++ src/pages/ProjectFiles/service.ts | 36 ++ src/pages/ProjectFiles/style.less | 70 +++ 10 files changed, 1486 insertions(+), 1 deletion(-) create mode 100644 mock/projectFile.js create mode 100644 src/components/CitySelect.tsx create mode 100644 src/pages/ProjectFiles/data.d.ts create mode 100644 src/pages/ProjectFiles/dict.ts create mode 100644 src/pages/ProjectFiles/file.tsx create mode 100644 src/pages/ProjectFiles/index.tsx create mode 100644 src/pages/ProjectFiles/service.ts create mode 100644 src/pages/ProjectFiles/style.less diff --git a/config/router.config.ts b/config/router.config.ts index 2e27551..6cbe387 100644 --- a/config/router.config.ts +++ b/config/router.config.ts @@ -121,6 +121,19 @@ export default [ path: '/ToAgencyAgent', component: './Agency/AgencyManager/agentIndex', }, + /** + * 项目建档 + */ + { + // 项目建档列表 + path: '/ProjectFiles', + component: './ProjectFiles', + }, + { + // 项目建档新增 + path: '/ProjectFiles/file', + component: './ProjectFiles/file', + }, //==============================================================引入的业务路由 ...approvalForm,//审批单 ...juryRoom,//评标室内所有路由 diff --git a/mock/projectFile.js b/mock/projectFile.js new file mode 100644 index 0000000..360d877 --- /dev/null +++ b/mock/projectFile.js @@ -0,0 +1,26 @@ +export default { + 'GET /api/projectFiles': (req, res) => { + res.json({ + data: [ + { + id: 1, + name: '项目1', + projectCode: '123456', + createTime: '2021-01-01', + purchaseType: '1', + purchaseType: '1', + }, + { + id: 2, + name: '项目2', + projectCode: '123456', + createTime: '2021-01-01', + purchaseType: '1', + purchaseType: '1', + }, + ], + success: true, + total: 2, + }); + }, +} \ No newline at end of file diff --git a/src/components/CitySelect.tsx b/src/components/CitySelect.tsx new file mode 100644 index 0000000..d661d8c --- /dev/null +++ b/src/components/CitySelect.tsx @@ -0,0 +1,336 @@ +import React, { useState, useEffect } from 'react'; +import { Select, Row, Col } from 'antd'; +import type { FormInstance } from 'antd/lib/form'; + +const { Option } = Select; + +// 省市区数据结构 +interface District { + value: string; + label: string; +} + +interface City { + value: string; + label: string; + districts: District[]; +} + +interface Province { + value: string; + label: string; + cities: City[]; +} + +// 模拟省市区数据 +const provinceData: Province[] = [ + { + value: 'beijing', + label: '北京市', + cities: [ + { + value: 'dongcheng', + label: '东城区', + districts: [ + { value: 'chaoyangmen', label: '朝阳门街道' }, + { value: 'jianguomennei', label: '建国门内街道' }, + { value: 'donghuamen', label: '东华门街道' }, + ], + }, + { + value: 'xicheng', + label: '西城区', + districts: [ + { value: 'xichang', label: '西长安街街道' }, + { value: 'xinjieku', label: '新街口街道' }, + { value: 'yuetan', label: '月坛街道' }, + ], + }, + { + value: 'chaoyang', + label: '朝阳区', + districts: [ + { value: 'jianwai', label: '建外街道' }, + { value: 'chaowai', label: '朝外街道' }, + { value: 'hujialou', label: '呼家楼街道' }, + ], + }, + ], + }, + { + value: 'shanghai', + label: '上海市', + cities: [ + { + value: 'huangpu', + label: '黄浦区', + districts: [ + { value: 'nanking', label: '南京东路街道' }, + { value: 'waitan', label: '外滩街道' }, + { value: 'yuyuan', label: '豫园街道' }, + ], + }, + { + value: 'xuhui', + label: '徐汇区', + districts: [ + { value: 'xujiahui', label: '徐家汇街道' }, + { value: 'tianlin', label: '田林街道' }, + { value: 'kangjianlou', label: '康健楼街道' }, + ], + }, + { + value: 'changning', + label: '长宁区', + districts: [ + { value: 'huayang', label: '华阳路街道' }, + { value: 'jiangsu', label: '江苏路街道' }, + { value: 'xinhua', label: '新华路街道' }, + ], + }, + ], + }, + { + value: 'guangdong', + label: '广东省', + cities: [ + { + value: 'guangzhou', + label: '广州市', + districts: [ + { value: 'yuexiu', label: '越秀区' }, + { value: 'liwan', label: '荔湾区' }, + { value: 'haizhu', label: '海珠区' }, + ], + }, + { + value: 'shenzhen', + label: '深圳市', + districts: [ + { value: 'futian', label: '福田区' }, + { value: 'luohu', label: '罗湖区' }, + { value: 'nanshan', label: '南山区' }, + ], + }, + { + value: 'zhuhai', + label: '珠海市', + districts: [ + { value: 'xiangzhou', label: '香洲区' }, + { value: 'doumen', label: '斗门区' }, + { value: 'jinwan', label: '金湾区' }, + ], + }, + ], + }, + { + value: 'jiangsu', + label: '江苏省', + cities: [ + { + value: 'nanjing', + label: '南京市', + districts: [ + { value: 'xuanwu', label: '玄武区' }, + { value: 'qinhuai', label: '秦淮区' }, + { value: 'jianye', label: '建邺区' }, + ], + }, + { + value: 'suzhou', + label: '苏州市', + districts: [ + { value: 'gusu', label: '姑苏区' }, + { value: 'wuzhong', label: '吴中区' }, + { value: 'xiangcheng', label: '相城区' }, + ], + }, + ], + }, +]; + +export interface CitySelectValue { + province?: string; + city?: string; + district?: string; +} + +export interface CitySelectProps { + value?: CitySelectValue; + onChange?: (value: CitySelectValue) => void; + form?: FormInstance; + placeholder?: { + province?: string; + city?: string; + district?: string; + }; + disabled?: boolean; + size?: 'large' | 'middle' | 'small'; +} + +const CitySelect: React.FC = ({ + value = {}, + onChange, + form, + placeholder = { + province: '请选择省份', + city: '请选择城市', + district: '请选择区域', + }, + disabled = false, + size = 'middle', +}) => { + const [cities, setCities] = useState([]); + const [districts, setDistricts] = useState([]); + const [selectedProvince, setSelectedProvince] = useState(value.province); + const [selectedCity, setSelectedCity] = useState(value.city); + const [selectedDistrict, setSelectedDistrict] = useState(value.district); + + + + // 处理省份选择变化 + const handleProvinceChange = (provinceValue?: string) => { + setSelectedProvince(provinceValue); + setSelectedCity(undefined); + setSelectedDistrict(undefined); + setDistricts([]); + + if (provinceValue) { + const province = provinceData.find(p => p.value === provinceValue); + setCities(province?.cities || []); + } else { + setCities([]); + } + + // 清空城市和区域的表单字段 + if (form) { + form.setFieldsValue({ + city: undefined, + district: undefined, + }); + } + + // 触发变化回调 + const newValue: CitySelectValue = { + province: provinceValue, + city: undefined, + district: undefined, + }; + onChange?.(newValue); + }; + + // 处理城市选择变化 + const handleCityChange = (cityValue?: string) => { + setSelectedCity(cityValue); + setSelectedDistrict(undefined); + + if (cityValue && selectedProvince) { + const province = provinceData.find(p => p.value === selectedProvince); + const city = province?.cities.find(c => c.value === cityValue); + setDistricts(city?.districts || []); + } else { + setDistricts([]); + } + + // 清空区域的表单字段 + if (form) { + form.setFieldsValue({ + district: undefined, + }); + } + + // 触发变化回调 + const newValue: CitySelectValue = { + province: selectedProvince, + city: cityValue, + district: undefined, + }; + onChange?.(newValue); + }; + + // 处理区域选择变化 + const handleDistrictChange = (districtValue?: string) => { + setSelectedDistrict(districtValue); + + // 触发变化回调 + const newValue: CitySelectValue = { + province: selectedProvince, + city: selectedCity, + district: districtValue, + }; + onChange?.(newValue); + }; + + // 监听外部值变化 + useEffect(() => { + if (value.province !== selectedProvince) { + setSelectedProvince(value.province); + handleProvinceChange(value.province); + } + if (value.city !== selectedCity) { + setSelectedCity(value.city); + handleCityChange(value.city); + } + if (value.district !== selectedDistrict) { + setSelectedDistrict(value.district); + } + }, [value]); + + return ( + + + + + + + + + + + + ); +}; + +export default CitySelect; diff --git a/src/pages/Loading/service.ts b/src/pages/Loading/service.ts index 43af287..f7890e7 100644 --- a/src/pages/Loading/service.ts +++ b/src/pages/Loading/service.ts @@ -1,7 +1,7 @@ import request from '@/utils/request'; export async function fgetUserMsg(params: any) { - return request('/api/core-service-ebtp-userinfo/v1/userinfo/get', { + return request('/api/sys-manager-ebtp-project/v1/userinfo/get', { method: 'GET', headers: { 'Authorization': params }, data: params, diff --git a/src/pages/ProjectFiles/data.d.ts b/src/pages/ProjectFiles/data.d.ts new file mode 100644 index 0000000..5bd27f9 --- /dev/null +++ b/src/pages/ProjectFiles/data.d.ts @@ -0,0 +1,16 @@ +export type TableListItem = { + id: string; + name: string; + projectCode: string; + createTime: string; + purchaseType: string; + purchaseType: string; + status: string; + version: string; +}; + +export type TableListPagination = { + total: number; + pageSize: number; + current: number; +}; \ No newline at end of file diff --git a/src/pages/ProjectFiles/dict.ts b/src/pages/ProjectFiles/dict.ts new file mode 100644 index 0000000..c1ca6e8 --- /dev/null +++ b/src/pages/ProjectFiles/dict.ts @@ -0,0 +1,137 @@ +// 资金性质 +const fundNatureOptions = [ + { label: '固定资产投资', value: '1' }, + { label: '费用成本开支', value: '2' }, + { label: '通用物资固定资产投资为主', value: '3' }, + { label: '通用物资费用成本开支为主', value: '4' }, + { label: '无收无支', value: '5' }, + { label: '通用物资固定资产购置为主', value: '6' }, + { label: '固定资产购置', value: '7' }, +]; + +// 资金来源 +const fundsProviderOptions = [ + { label: '国企自筹', value: '1' }, + { label: '中央投资', value: '2' }, + { label: '地方政府投资', value: '3' }, + { label: '财政资金', value: '4' }, + { label: '外贷', value: '5' }, + { label: '其他', value: '6' }, +]; + +// 预算类型 +const budgetTypeOptions = [ + { label: '标段预算', value: '1' }, + { label: '仅有整体项目预算', value: '2' }, + { label: '有预估采购规模(标段预计金额)', value: '3' }, + { label: '无预算', value: '4' }, +]; + +// 项目所在行政区域类型 +const regionDictTypeOptions = [ + { label: '境内', value: '1' }, + { label: '境外', value: '2' }, +]; +const regionOutsideOptions = [ + { label: '亚洲(除中国)', value: '1' }, + { label: '欧洲', value: '2' }, + { label: '北美洲', value: '3' }, + { label: '南美洲', value: '4' }, + { label: '非洲', value: '5' }, + { label: '大洋洲', value: '6' }, + { label: '南极洲', value: '7' }, +]; + +// 币种 +const currencyCodeOptions = [ + { label: 'CNY', value: 'CNY' }, + { label: 'EUR', value: 'EUR' }, + { label: 'USD', value: 'USD' }, +]; + +// 招标类型 +const openTenderFormEnum = { + 1: '依法必招', + 2: '自愿招标', +}; + +// 采购方式 +const purchaseTypeEnum = { + 1: '公开招标', + 2: '邀请招标', +}; + +// 资审方式 +const reviewMethodEnum = { + 1: '后审', + 2: '资审', +}; + +// 组织形式 +const organizationFormEnum = { + 1: '自主招标', + 2: '委托代理', +}; + +// 招标代理机构 +const tenderAgencyEnum = { + 1: '广州中远海运建设实业有限公司', +}; + +// 报价方式 +const bidMethodEnum = { + 1: '总价', + 2: '单价', + 3: '优惠率', + 4: '折扣率', +}; + +// 评价方法 +const evaluationMethodEnum = { + 1: '最低价法', + 2: '综合评估法', + 3: '合理低价法', +}; + +// 资格审查方法 +const reviewWayEnum = { + 1: '合格制', + 2: '有限数量制', +}; + +// 流程类型 +const processEnum = { + 1: '第一轮初审详审,固定流程', +}; + +// 标的类别1 +const subjectTypeOptions = [ + { label: '货物', value: '1' }, + { label: '工程', value: '2' }, + { label: '服务', value: '3' }, +] + +// 标的类别2 +const subjectType2Options = [ + { label: '土地、建筑物及构筑物', value: '1' }, +]; + +export { + fundNatureOptions, + fundsProviderOptions, + budgetTypeOptions, + regionDictTypeOptions, + regionOutsideOptions, + currencyCodeOptions, + purchaseTypeEnum, + openTenderFormEnum, + reviewMethodEnum, + organizationFormEnum, + tenderAgencyEnum, + bidMethodEnum, + evaluationMethodEnum, + reviewWayEnum, + processEnum, + subjectTypeOptions, + subjectType2Options, +}; diff --git a/src/pages/ProjectFiles/file.tsx b/src/pages/ProjectFiles/file.tsx new file mode 100644 index 0000000..bf4329d --- /dev/null +++ b/src/pages/ProjectFiles/file.tsx @@ -0,0 +1,747 @@ +import { CloseCircleOutlined, MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; +import { Button, Card, Col, Form, Popover, Row, message, Divider, Select, Input, Upload } from 'antd'; +import { history, useLocation } from 'umi'; +import type { Location } from 'umi'; + +import type { FC } from 'react'; +import React, { useState, Fragment } from 'react'; +import ProForm, { + ProFormSelect, + ProFormText, + ProFormRadio, + ProFormDigit, + ProFormDependency, + ProFormUploadButton, +} from '@ant-design/pro-form'; +import { PageContainer, FooterToolbar } from '@ant-design/pro-layout'; +import { submitForm } from './service'; +import styles from './style.less'; +import { + fundNatureOptions, + fundsProviderOptions, + budgetTypeOptions, + regionDictTypeOptions, + regionOutsideOptions, + currencyCodeOptions, + purchaseTypeEnum, + openTenderFormEnum, + reviewMethodEnum, + organizationFormEnum, + tenderAgencyEnum, + bidMethodEnum, + evaluationMethodEnum, + reviewWayEnum, + processEnum, + subjectTypeOptions, + subjectType2Options, +} from './dict'; +import CitySelect from '@/components/CitySelect'; + + +type InternalNamePath = (string | number)[]; + +const fieldLabels = { + projectName: '项目名称', + ProjectBizNo: '项目编号', + tendereeOrgId: '项目归属单位', // + tendereeId: '项目归属部门', // + appManagerId: '项目负责人', + appManagerTel: '联系电话', + fundNature: '资金性质', // + fundsProviderDict: '资金来源', + budgetType: '预算类型', // + regionDictType: '项目所在行政区域类型', //? + regionDict: '项目所在行政区域', //? + budgetAmount: '项目预算', + currencyCode: '币种', + openTenderForm: '招标类型', + bidMethodDict: '采购方式', + reviewMethod: '资审方式', // + bidOrgDict: '组织形式', // + tenderAgencyId: '招标代理机构', // +}; + + +interface ErrorField { + name: InternalNamePath; + errors: string[]; +} + +// 主要标的表单控件 +const SubjectFormItem = ({ value = [], onChange, disabled = false }: { value?: string[], onChange?: (value: string[]) => void, disabled?: boolean }) => { + return ( + + + + + + + + + ) +} + +const normFile = (e: any) => { + console.log('Upload event:', e); + if (Array.isArray(e)) { + return e; + } + return e?.fileList; +}; + +const ProjectFileCreate: FC> = () => { + const { query }: Location = useLocation(); + const readOnly = query?.action === 'view'; + const id = query?.id; // 文件 id + + const [regionDictType, setRegionDictType] = useState('1'); + const [error, setError] = useState([]); + const getErrorInfo = (errors: ErrorField[]) => { + const errorCount = errors.filter((item) => item.errors.length > 0).length; + if (!errors || errorCount === 0) { + return null; + } + const scrollToField = (fieldKey: string) => { + const labelNode = document.querySelector(`label[for="${fieldKey}"]`); + if (labelNode) { + labelNode.scrollIntoView(true); + } + }; + const errorList = errors.map((err) => { + if (!err || err.errors.length === 0) { + return null; + } + const key = err.name[0] as string; + return ( +
  • scrollToField(key)}> + +
    {err.errors[0]}
    +
    {fieldLabels[key as keyof typeof fieldLabels]}
    +
  • + ); + }); + return ( + + { + if (trigger && trigger.parentNode) { + return trigger.parentNode as HTMLElement; + } + return trigger; + }} + > + + + {errorCount} + + ); + }; + + const onFinish = async (values: Record) => { + setError([]); + try { + console.log(values); + await submitForm(values); + message.success('提交成功'); + } catch { + // console.log + } + }; + + const onFinishFailed = (errorInfo: any) => { + setError(errorInfo.errorFields); + }; + + return ( +
    + { + if (readOnly) { + return ( + + + + ); + } + const _dom = dom.filter((item: JSX.Element) => item.key !== 'rest').concat([ + + ]).concat([ + + ]); + return ( + + {getErrorInfo(error)} + {_dom} + + ); + }, + }} + initialValues={{ + budgetType: '1', + regionDictType: '1', + budgetAmount: 0, + currencyCode: 'CNY', + bidSection: [{ + bidSectionIndex: 1, + bidSectionName: '', + bidSectionNo: '', + bidSectionBudget: 0, + bidMethod: '', + bidSectionCategory: [{ + type: [], + percent: 0, + }], + }], + }} + onFinish={onFinish} + onFinishFailed={onFinishFailed} + labelCol={{ span: 5 }} + wrapperCol={{ span: 19 }} + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + setRegionDictType(e.target.value); + }, + disabled: readOnly, + }} + /> + + + + + + {({ bidSection }) => { + // 计算所有标段预算之和 + const total = Array.isArray(bidSection) + ? bidSection.reduce((sum, item) => sum + (parseFloat(item?.bidSectionBudget) || 0), 0) + : 0; + return ( + + ); + }} + + + + {regionDictType === '1' ? ( + ​} + required={false} + colon={false} + rules={[ + { + required: true, + validator: (_, value) => { + if (!value || !value.province || !value.city || !value.district) { + return Promise.reject(new Error('请完整选择省市区')); + } + return Promise.resolve(); + } + } + ]} + > + + + ) : ( + ​} + required={false} + colon={false} + rules={[{ required: true, message: '请选择项目所在行政区域' }]} + options={regionOutsideOptions} + placeholder="请选择行政区域" + fieldProps={{ + disabled: readOnly, + }} + /> + )} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {(fields, { add, remove }) => ( + <> + + + + + + {fields.map(field => ( + + {field.key !== 0 && } + + + + + + + + + + + + + + + + + + {({ currencyCode }) => { + return ( + <> + + {currencyCode} + + ); + }} + + + + + + + + + + + + + + + + + + + + + + + + + {(subFields, { add: addCategory, remove: removeCategory }) => ( + <> + {subFields.map(subField => ( + + + + { + if (!value || !value[0] || !value[1]) { + return Promise.reject(new Error('请完整选择主要标的类别')); + } + return Promise.resolve(); + } + } + ]}> + + + + + + % + + + removeCategory(subField.name)} disabled={readOnly} /> + + + + ))} + + + + + + + )} + + + + + ))} + + )} + + + + + + + + { + e.preventDefault(); + }} + disabled={readOnly} + /> + + + + + { + const isRarOrZipOrDocOrDocxOrPdf = file.type === 'application/x-rar-compressed' || + file.type === 'application/zip' || + file.type === 'application/msword' || + file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || + file.type === 'application/pdf'; + + if (!isRarOrZipOrDocOrDocxOrPdf) { + message.error('你只能上传 rar/zip/doc/docx/pdf 文件!'); + return Upload.LIST_IGNORE; + } + + const isLt20M = file.size / 1024 / 1024 < 20; + if (!isLt20M) { + message.error('文件大小不能超过 20MB!'); + return Upload.LIST_IGNORE; + } + + return true; + }, + }} + /> + + + + +
    + ); +}; + +export default ProjectFileCreate; \ No newline at end of file diff --git a/src/pages/ProjectFiles/index.tsx b/src/pages/ProjectFiles/index.tsx new file mode 100644 index 0000000..0418908 --- /dev/null +++ b/src/pages/ProjectFiles/index.tsx @@ -0,0 +1,104 @@ +import { Button } from 'antd'; +import React, { useRef } from 'react'; +import { history } from 'umi'; +import { PageContainer } from '@ant-design/pro-layout'; +import type { ProColumns, ActionType } from '@ant-design/pro-table'; +import ProTable from '@ant-design/pro-table'; +import { fetchProjectFileList } from './service'; +import type { TableListItem, TableListPagination } from './data'; +import { purchaseTypeEnum } from './dict'; + +const ProjectFiles: React.FC = () => { + const actionRef = useRef(); + + const columns: ProColumns[] = [ + { + title: '序号', + dataIndex: 'index', + renderText: (text, record, index) => index + 1, + width: 50, + hideInSearch: true, + }, + { + title: '项目名称', + dataIndex: 'projectName', + valueType: 'text', + }, + { + title: '项目编号', + dataIndex: 'ebpProjectNumber', + hideInSearch: true, + }, + { + title: '创建时间', + dataIndex: 'createDate', + hideInSearch: true, + }, + { + title: '采购方式', + dataIndex: 'purchaseType', + valueType: 'select', + valueEnum: purchaseTypeEnum, + }, + { + title: '采购类型', + dataIndex: 'purchaseType', + hideInSearch: true, + }, + { + title: '状态', + dataIndex: 'status', + valueType: 'select', + }, + { + title: '版本号', + dataIndex: 'version', + hideInSearch: true, + }, + { + title: '操作', + dataIndex: 'option', + valueType: 'option', + render: (_, record) => [ + { + history.push(`/ProjectFiles/file?action=view&id=${record.id}`); + }} + > + 查看 + , + ], + }, + ]; + + return ( +
    + + + actionRef={actionRef} + rowKey="id" + search={{ + labelWidth: 120, + }} + toolBarRender={() => [ + , + ]} + options={{ density: false, reload: false, setting: false, fullScreen: false }} + request={fetchProjectFileList} + columns={columns} + /> + +
    + ); +}; + +export default ProjectFiles; \ No newline at end of file diff --git a/src/pages/ProjectFiles/service.ts b/src/pages/ProjectFiles/service.ts new file mode 100644 index 0000000..cf0fd38 --- /dev/null +++ b/src/pages/ProjectFiles/service.ts @@ -0,0 +1,36 @@ +// @ts-ignore +/* eslint-disable */ +import { request } from 'umi'; +import { TableListItem } from './data'; + +/** 获取规则列表 GET /api/rule */ +export async function fetchProjectFileList( + params: { + // query + /** 当前的页码 */ + current?: number; + /** 页面的容量 */ + pageSize?: number; + }, +) { + console.log(params); + + return request<{ + data: TableListItem[]; + /** 列表的内容总数 */ + total?: number; + success?: boolean; + }>('/api/projectFiles', { + method: 'GET', + params: { + ...params, + }, + }); +} + +export async function submitForm(params: any) { + return request('/api/projectFile', { + method: 'POST', + data: params, + }); +} \ No newline at end of file diff --git a/src/pages/ProjectFiles/style.less b/src/pages/ProjectFiles/style.less new file mode 100644 index 0000000..92835fe --- /dev/null +++ b/src/pages/ProjectFiles/style.less @@ -0,0 +1,70 @@ +@import '~antd/es/style/themes/default.less'; + +.card { + margin-bottom: 24px; + + :global { + .ant-legacy-form-item .ant-legacy-form-item-control-wrapper { + width: 100%; + } + } +} + +.errorIcon { + margin-right: 24px; + color: @error-color; + cursor: pointer; + + span.anticon { + margin-right: 4px; + } +} + +.errorPopover { + :global { + .ant-popover-inner-content { + min-width: 256px; + max-height: 290px; + padding: 0; + overflow: auto; + } + } +} + +.errorListItem { + padding: 8px 16px; + list-style: none; + border-bottom: 1px solid @border-color-split; + cursor: pointer; + transition: all 0.3s; + &:hover { + background: @item-active-bg; + } + &:last-child { + border: 0; + } + .errorIcon { + float: left; + margin-top: 4px; + margin-right: 12px; + padding-bottom: 22px; + color: @error-color; + } + .errorField { + margin-top: 2px; + color: @text-color-secondary; + font-size: 12px; + } +} + +.createProjectFile { + min-height: 100vh; + .footerToolbar { + justify-content: center; + :global { + .ant-pro-footer-bar-left { + display: none; + } + } + } +} \ No newline at end of file