From 173cd6b975af4f86df5e43543be2de79749366d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E4=BC=8A=E5=B8=86?= Date: Fri, 11 Sep 2026 08:02:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E9=A6=96=E9=A1=B5=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/AppTabBar.vue | 24 +- src/constants/business-detail.ts | 34 + src/constants/business-types.ts | 13 + src/constants/case-library.ts | 126 ++++ src/constants/quick-entries.ts | 41 + src/hooks/use-quick-entries.ts | 71 ++ src/pages.json | 12 + .../Login/user-register-success/index.vue | 4 + .../case-library/components/CaseCard.vue | 185 +++++ .../components/CaseFilterPanel.vue | 526 +++++++++++++ .../components/LoadMoreFooter.vue | 83 ++ src/pages/case-library/index.vue | 308 +++++++- .../home-index/business-detail/index.vue | 335 +++++++++ .../components/HomeFloatingActions.vue | 112 +++ .../home-index/components/ProjectCard.vue | 97 ++- .../components/QuickEntryEditor.vue | 244 ++++++ .../home-index/components/ServiceCard.vue | 17 +- src/pages/home-index/index.vue | 105 ++- .../home-index/requirement-submit/index.vue | 706 ++++++++++++++++++ src/static/icons/PDF.png | Bin 0 -> 1066 bytes src/static/icons/PNG.png | Bin 0 -> 1074 bytes src/static/icons/X.png | Bin 0 -> 570 bytes src/static/icons/about.png | Bin 0 -> 2244 bytes src/static/icons/add.png | Bin 0 -> 979 bytes src/static/icons/address.png | Bin 0 -> 2242 bytes src/static/icons/background.png | Bin 0 -> 60475 bytes src/static/icons/contract-list.png | Bin 0 -> 1990 bytes src/static/icons/delete.png | Bin 0 -> 813 bytes src/static/icons/feedback.png | Bin 0 -> 2390 bytes src/static/icons/help.png | Bin 0 -> 2139 bytes src/static/icons/icon-filter.svg | 3 + src/static/icons/icon-float-service.png | Bin 0 -> 7917 bytes src/static/icons/icon-heart-filled.svg | 3 + src/static/icons/icon-heart.svg | 3 + src/static/icons/icon-search.svg | 4 + src/static/icons/invoice.png | Bin 0 -> 2610 bytes src/static/icons/new-card.png | Bin 0 -> 26677 bytes src/static/icons/qualification.png | Bin 0 -> 2490 bytes src/static/icons/security.png | Bin 0 -> 3113 bytes src/static/icons/service-app.png | Bin 0 -> 2559 bytes src/static/icons/service-desktop.png | Bin 0 -> 2682 bytes src/static/icons/service-mini.png | Bin 0 -> 2866 bytes src/static/icons/service-secondary.png | Bin 0 -> 2980 bytes src/static/icons/service-secondary.svg | 4 + src/static/icons/service-web.png | Bin 0 -> 2051 bytes src/static/icons/tab-case-active.png | Bin 0 -> 938 bytes src/static/icons/tab-case.png | Bin 0 -> 991 bytes src/static/icons/tab-case.svg | 6 - src/static/icons/tab-home-active.png | Bin 0 -> 455 bytes src/static/icons/tab-home.png | Bin 0 -> 507 bytes src/static/icons/tab-home.svg | 4 - src/static/icons/tab-message-active.png | Bin 0 -> 467 bytes src/static/icons/tab-message.png | Bin 0 -> 388 bytes src/static/icons/tab-message.svg | 3 - src/static/icons/tab-messages.png | Bin 0 -> 2115 bytes src/static/icons/tab-personal-active.png | Bin 0 -> 679 bytes src/static/icons/tab-personal.png | Bin 0 -> 753 bytes src/static/icons/tab-personal.svg | 4 - src/static/icons/tab-personals.png | Bin 0 -> 2401 bytes src/static/icons/tab-project-active.png | Bin 0 -> 336 bytes src/static/icons/tab-project.png | Bin 0 -> 364 bytes src/static/icons/tab-project.svg | 3 - src/types/business-detail.ts | 15 + src/types/case-library.ts | 25 + src/types/home.ts | 3 +- src/types/result-page.ts | 8 +- src/utils/case-filter.ts | 147 ++++ src/utils/navigate-back.ts | 15 + 68 files changed, 3181 insertions(+), 112 deletions(-) create mode 100644 src/constants/business-detail.ts create mode 100644 src/constants/business-types.ts create mode 100644 src/constants/case-library.ts create mode 100644 src/constants/quick-entries.ts create mode 100644 src/hooks/use-quick-entries.ts create mode 100644 src/pages/case-library/components/CaseCard.vue create mode 100644 src/pages/case-library/components/CaseFilterPanel.vue create mode 100644 src/pages/case-library/components/LoadMoreFooter.vue create mode 100644 src/pages/home-index/business-detail/index.vue create mode 100644 src/pages/home-index/components/HomeFloatingActions.vue create mode 100644 src/pages/home-index/components/QuickEntryEditor.vue create mode 100644 src/pages/home-index/requirement-submit/index.vue create mode 100644 src/static/icons/PDF.png create mode 100644 src/static/icons/PNG.png create mode 100644 src/static/icons/X.png create mode 100644 src/static/icons/about.png create mode 100644 src/static/icons/add.png create mode 100644 src/static/icons/address.png create mode 100644 src/static/icons/background.png create mode 100644 src/static/icons/contract-list.png create mode 100644 src/static/icons/delete.png create mode 100644 src/static/icons/feedback.png create mode 100644 src/static/icons/help.png create mode 100644 src/static/icons/icon-filter.svg create mode 100644 src/static/icons/icon-float-service.png create mode 100644 src/static/icons/icon-heart-filled.svg create mode 100644 src/static/icons/icon-heart.svg create mode 100644 src/static/icons/icon-search.svg create mode 100644 src/static/icons/invoice.png create mode 100644 src/static/icons/new-card.png create mode 100644 src/static/icons/qualification.png create mode 100644 src/static/icons/security.png create mode 100644 src/static/icons/service-app.png create mode 100644 src/static/icons/service-desktop.png create mode 100644 src/static/icons/service-mini.png create mode 100644 src/static/icons/service-secondary.png create mode 100644 src/static/icons/service-secondary.svg create mode 100644 src/static/icons/service-web.png create mode 100644 src/static/icons/tab-case-active.png create mode 100644 src/static/icons/tab-case.png delete mode 100644 src/static/icons/tab-case.svg create mode 100644 src/static/icons/tab-home-active.png create mode 100644 src/static/icons/tab-home.png delete mode 100644 src/static/icons/tab-home.svg create mode 100644 src/static/icons/tab-message-active.png create mode 100644 src/static/icons/tab-message.png delete mode 100644 src/static/icons/tab-message.svg create mode 100644 src/static/icons/tab-messages.png create mode 100644 src/static/icons/tab-personal-active.png create mode 100644 src/static/icons/tab-personal.png delete mode 100644 src/static/icons/tab-personal.svg create mode 100644 src/static/icons/tab-personals.png create mode 100644 src/static/icons/tab-project-active.png create mode 100644 src/static/icons/tab-project.png delete mode 100644 src/static/icons/tab-project.svg create mode 100644 src/types/business-detail.ts create mode 100644 src/types/case-library.ts create mode 100644 src/utils/case-filter.ts create mode 100644 src/utils/navigate-back.ts diff --git a/src/components/AppTabBar.vue b/src/components/AppTabBar.vue index 28d7dba..d8b16ad 100644 --- a/src/components/AppTabBar.vue +++ b/src/components/AppTabBar.vue @@ -5,14 +5,18 @@ const props = defineProps<{ active: TabKey }>() -const tabs: Array<{ key: TabKey, label: string, icon: string, path: string }> = [ - { key: 'home', label: '首页', icon: '/static/icons/tab-home.svg', path: '/pages/home-index/index' }, - { key: 'case', label: '案例库', icon: '/static/icons/tab-case.svg', path: '/pages/case-library/index' }, - { key: 'message', label: '消息中心', icon: '/static/icons/tab-message.svg', path: '/pages/message-center/index' }, - { key: 'project', label: '项目中心', icon: '/static/icons/tab-project.svg', path: '/pages/project-center/index' }, - { key: 'personal', label: '个人中心', icon: '/static/icons/tab-personal.svg', path: '/pages/personal-center/index' }, +const tabs: Array<{ key: TabKey, label: string, icon: string, activeIcon: string, path: string }> = [ + { key: 'home', label: '首页', icon: '/static/icons/tab-home.png', activeIcon: '/static/icons/tab-home-active.png', path: '/pages/home-index/index' }, + { key: 'case', label: '案例库', icon: '/static/icons/tab-case.png', activeIcon: '/static/icons/tab-case-active.png', path: '/pages/case-library/index' }, + { key: 'message', label: '消息中心', icon: '/static/icons/tab-message.png', activeIcon: '/static/icons/tab-message-active.png', path: '/pages/message-center/index' }, + { key: 'project', label: '项目中心', icon: '/static/icons/tab-project.png', activeIcon: '/static/icons/tab-project-active.png', path: '/pages/project-center/index' }, + { key: 'personal', label: '个人中心', icon: '/static/icons/tab-personal.png', activeIcon: '/static/icons/tab-personal-active.png', path: '/pages/personal-center/index' }, ] +function getTabIcon(tab: typeof tabs[number]) { + return tab.key === props.active ? tab.activeIcon : tab.icon +} + function handleSwitch(path: string, key: TabKey) { if (key === props.active) return @@ -30,8 +34,7 @@ function handleSwitch(path: string, key: TabKey) { > = { + software: { + id: 'software', + title: '互联网软件', + subtitle: '专业的软件定制开发服务,从需求到上线全流程保障', + icon: softwareIllus, + serviceTypes: [ + { id: 'web', label: 'Web应用', icon: '/static/icons/service-web.png' }, + { id: 'mini', label: '小程序', icon: '/static/icons/service-mini.png' }, + { id: 'app', label: 'APP', icon: '/static/icons/service-app.png' }, + { id: 'secondary', label: '二次开发', icon: '/static/icons/service-secondary.png' }, + { id: 'desktop', label: '桌面工具', icon: '/static/icons/service-desktop.png' }, + ], + contentTitle: '服务内容', + contentSections: [ + '一、产品咨询与规划服务', + '1. 业务诊断与梳理:深入了解客户业务现状,梳理核心流程与痛点,输出业务诊断报告。', + '2. 竞品分析与市场调研:分析行业竞品功能与商业模式,为产品定位提供数据支撑。', + '3. 产品定位与MVP规划:明确产品核心价值,制定最小可行产品(MVP)路线图。', + '4. 技术可行性评估:评估技术实现路径、开发周期与成本,降低项目风险。', + '二、UI/UX 设计服务', + '1. 用户体验研究:通过用户访谈、可用性测试等方法,洞察用户需求与行为。', + '2. 交互原型设计:输出高保真交互原型,确保产品逻辑清晰、操作流畅。', + '3. 视觉界面设计:打造统一、美观、符合品牌调性的视觉设计体系。', + ], + }, +} + +export function getBusinessDetail(id: string) { + return BUSINESS_DETAIL_MAP[id] +} diff --git a/src/constants/business-types.ts b/src/constants/business-types.ts new file mode 100644 index 0000000..478ee49 --- /dev/null +++ b/src/constants/business-types.ts @@ -0,0 +1,13 @@ +export const BUSINESS_TYPE_OPTIONS = [ + '互联网软件', + '硬件电路', + '物联网全案', + '生产制造', +] + +export const BUSINESS_TYPE_DETAIL_ID: Record = { + 互联网软件: 'software', + 硬件电路: 'hardware', + 物联网全案: 'iot', + 生产制造: 'production', +} diff --git a/src/constants/case-library.ts b/src/constants/case-library.ts new file mode 100644 index 0000000..ee3903d --- /dev/null +++ b/src/constants/case-library.ts @@ -0,0 +1,126 @@ +import type { CaseCategory, CaseFilterValues, CaseItem } from '@/types/case-library' + +export const CASE_CATEGORIES: CaseCategory[] = [ + '全部', + '互联网软件', + '硬件电路', + '物联网全案', + '生产制造', +] + +export const CASE_PAGE_SIZE = 4 + +export const CASE_TOTAL_COUNT = 6 + +export const CASE_FILTER_INDUSTRIES = [ + '金融科技', + '电商零售', + '教育培训', + '医疗健康', + '硬件电路', + '能源环保', + '房地产', +] as const + +export const CASE_FILTER_SCALES = [ + '全部', + '50万以下', + '50-100万', + '100-300万', + '300-500万', + '500万以上', +] as const + +export const CASE_FILTER_TIME_RANGES = [ + '全部', + '近3个月', + '近半年', + '近一年', +] as const + +export const DEFAULT_CASE_FILTER: CaseFilterValues = { + industries: [], + scales: [], + timeRanges: [], + dateRange: { + start: '', + end: '', + }, +} + +export const CASE_LIBRARY_LIST: CaseItem[] = [ + { + id: '1', + title: '智能园区综合管理平台开发', + category: '互联网软件', + cover: '/static/icons/background.png', + clientType: '企业', + industry: '房地产', + scale: '200万', + cycle: '200个工作日', + teamSize: '20人', + completedAt: '2026/8/10', + favorite: true, + }, + { + id: '2', + title: '工业设备远程监控系统', + category: '物联网全案', + cover: '/static/icons/1.png', + clientType: '企业', + industry: '金融科技', + scale: '150万', + cycle: '180个工作日', + teamSize: '16人', + completedAt: '2026/7/22', + }, + { + id: '3', + title: '社区康养智能服务系统', + category: '互联网软件', + cover: '/static/icons/software.png', + clientType: '政府', + industry: '医疗健康', + scale: '320万', + cycle: '240个工作日', + teamSize: '24人', + completedAt: '2026/6/15', + favorite: true, + }, + { + id: '4', + title: '新能源充电桩控制主板设计', + category: '硬件电路', + cover: '/static/icons/hardware.png', + clientType: '企业', + industry: '能源环保', + scale: '80万', + cycle: '90个工作日', + teamSize: '8人', + completedAt: '2026/5/28', + }, + { + id: '5', + title: '智慧农业环境监测平台', + category: '物联网全案', + cover: '/static/icons/iot.png', + clientType: '企业', + industry: '教育培训', + scale: '260万', + cycle: '210个工作日', + teamSize: '18人', + completedAt: '2026/4/12', + }, + { + id: '6', + title: '智能穿戴设备批量生产项目', + category: '生产制造', + cover: '/static/icons/production.png', + clientType: '企业', + industry: '电商零售', + scale: '500万', + cycle: '300个工作日', + teamSize: '30人', + completedAt: '2026/3/8', + }, +] diff --git a/src/constants/quick-entries.ts b/src/constants/quick-entries.ts new file mode 100644 index 0000000..4fdb6a3 --- /dev/null +++ b/src/constants/quick-entries.ts @@ -0,0 +1,41 @@ +import type { QuickEntryItem } from '@/types/home' + +export const QUICK_ENTRY_MAX = 5 + +export const QUICK_ENTRY_STORAGE_KEY = 'home-quick-entry-ids' + +export const DEFAULT_QUICK_ENTRY_IDS = [ + 'project', + 'report', + 'service', + 'contract', + 'finance', +] + +export const QUICK_ENTRY_CATALOG: QuickEntryItem[] = [ + { id: 'project', label: '项目中心', icon: '/static/icons/quick-project.png', bgColor: '#E8F0FF' }, + { id: 'report', label: '快捷提报', icon: '/static/icons/quick-report.png', bgColor: '#E8FAF4' }, + { id: 'service', label: '在线客服', icon: '/static/icons/quick-service.png', bgColor: '#F3E8FF' }, + { id: 'contract', label: '合同管理', icon: '/static/icons/quick-contract.png', bgColor: '#FEE2E2' }, + { id: 'finance', label: '财务管理', icon: '/static/icons/quick-finance.png', bgColor: '#E0F2FE' }, + { id: 'personal', label: '个人中心', icon: '/static/icons/tab-personals.png', bgColor: '#E8F0FF' }, + { id: 'message', label: '消息中心', icon: '/static/icons/tab-messages.png', bgColor: '#F3E8FF' }, + { id: 'security', label: '账号安全', icon: '/static/icons/security.png', bgColor: '#E8FAF4' }, + { id: 'feedback', label: '意见反馈', icon: '/static/icons/feedback.png', bgColor: '#FFECE1' }, + { id: 'contract-list', label: '合同列表', icon: '/static/icons/contract-list.png', bgColor: '#FEE2E2' }, + { id: 'invoice', label: '发票列表', icon: '/static/icons/invoice.png', bgColor: '#E0F2FE' }, + { id: 'address', label: '地址管理', icon: '/static/icons/address.png', bgColor: '#E8F0FF' }, + { id: 'qualification', label: '资质列表', icon: '/static/icons/qualification.png', bgColor: '#FFF3EB' }, + { id: 'help', label: '帮助中心', icon: '/static/icons/help.png', bgColor: '#F3E8FF' }, + { id: 'about', label: '关于我们', icon: '/static/icons/about.png', bgColor: '#E8F0FF' }, +] + +export function getQuickEntryById(id: string) { + return QUICK_ENTRY_CATALOG.find(item => item.id === id) +} + +export function mapQuickEntryIds(ids: string[]) { + return ids + .map(id => getQuickEntryById(id)) + .filter((item): item is QuickEntryItem => Boolean(item)) +} diff --git a/src/hooks/use-quick-entries.ts b/src/hooks/use-quick-entries.ts new file mode 100644 index 0000000..2e5343b --- /dev/null +++ b/src/hooks/use-quick-entries.ts @@ -0,0 +1,71 @@ +import { computed, ref } from 'vue' +import { + DEFAULT_QUICK_ENTRY_IDS, + mapQuickEntryIds, + QUICK_ENTRY_CATALOG, + QUICK_ENTRY_MAX, + QUICK_ENTRY_STORAGE_KEY, +} from '@/constants/quick-entries' + +function loadPinnedIds(): string[] { + try { + const stored = uni.getStorageSync(QUICK_ENTRY_STORAGE_KEY) + if (Array.isArray(stored) && stored.length > 0) + return stored.slice(0, QUICK_ENTRY_MAX) + } + catch { + // ignore storage read errors + } + return [...DEFAULT_QUICK_ENTRY_IDS] +} + +function savePinnedIds(ids: string[]) { + uni.setStorageSync(QUICK_ENTRY_STORAGE_KEY, ids.slice(0, QUICK_ENTRY_MAX)) +} + +export function useQuickEntries() { + const pinnedIds = ref(loadPinnedIds()) + const editorVisible = ref(false) + + const pinnedEntries = computed(() => mapQuickEntryIds(pinnedIds.value)) + + const otherEntries = computed(() => + QUICK_ENTRY_CATALOG.filter(item => !pinnedIds.value.includes(item.id)), + ) + + function openEditor() { + editorVisible.value = true + } + + function closeEditor() { + editorVisible.value = false + } + + function removeFromPinned(id: string) { + pinnedIds.value = pinnedIds.value.filter(itemId => itemId !== id) + savePinnedIds(pinnedIds.value) + } + + function addToPinned(id: string) { + if (pinnedIds.value.includes(id)) + return + + if (pinnedIds.value.length >= QUICK_ENTRY_MAX) { + uni.showToast({ title: `最多添加${QUICK_ENTRY_MAX}个快捷入口`, icon: 'none' }) + return + } + + pinnedIds.value = [...pinnedIds.value, id] + savePinnedIds(pinnedIds.value) + } + + return { + pinnedEntries, + otherEntries, + editorVisible, + openEditor, + closeEditor, + removeFromPinned, + addToPinned, + } +} diff --git a/src/pages.json b/src/pages.json index 83c9f70..771d364 100644 --- a/src/pages.json +++ b/src/pages.json @@ -49,6 +49,18 @@ "navigationStyle": "custom" } }, + { + "path": "pages/home-index/business-detail/index", + "style": { + "navigationStyle": "custom" + } + }, + { + "path": "pages/home-index/requirement-submit/index", + "style": { + "navigationStyle": "custom" + } + }, { "path": "pages/case-library/index", "style": { diff --git a/src/pages/Login/user-register-success/index.vue b/src/pages/Login/user-register-success/index.vue index e98aa37..dd8c19f 100644 --- a/src/pages/Login/user-register-success/index.vue +++ b/src/pages/Login/user-register-success/index.vue @@ -25,6 +25,10 @@ onLoad((options) => { } if (type === 'loginFailed') { pageType.value = 'loginFailed' + return + } + if (type === 'submitSuccess') { + pageType.value = 'submitSuccess' } }) diff --git a/src/pages/case-library/components/CaseCard.vue b/src/pages/case-library/components/CaseCard.vue new file mode 100644 index 0000000..9e7747e --- /dev/null +++ b/src/pages/case-library/components/CaseCard.vue @@ -0,0 +1,185 @@ + + + + + diff --git a/src/pages/case-library/components/CaseFilterPanel.vue b/src/pages/case-library/components/CaseFilterPanel.vue new file mode 100644 index 0000000..8f1cb6a --- /dev/null +++ b/src/pages/case-library/components/CaseFilterPanel.vue @@ -0,0 +1,526 @@ + + + + + diff --git a/src/pages/case-library/components/LoadMoreFooter.vue b/src/pages/case-library/components/LoadMoreFooter.vue new file mode 100644 index 0000000..b6784ba --- /dev/null +++ b/src/pages/case-library/components/LoadMoreFooter.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/pages/case-library/index.vue b/src/pages/case-library/index.vue index 707c630..350fcf9 100644 --- a/src/pages/case-library/index.vue +++ b/src/pages/case-library/index.vue @@ -1,41 +1,319 @@ diff --git a/src/pages/home-index/business-detail/index.vue b/src/pages/home-index/business-detail/index.vue new file mode 100644 index 0000000..6ef4aeb --- /dev/null +++ b/src/pages/home-index/business-detail/index.vue @@ -0,0 +1,335 @@ + + + + + diff --git a/src/pages/home-index/components/HomeFloatingActions.vue b/src/pages/home-index/components/HomeFloatingActions.vue new file mode 100644 index 0000000..aecf5e3 --- /dev/null +++ b/src/pages/home-index/components/HomeFloatingActions.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/src/pages/home-index/components/ProjectCard.vue b/src/pages/home-index/components/ProjectCard.vue index faa8545..9f4126d 100644 --- a/src/pages/home-index/components/ProjectCard.vue +++ b/src/pages/home-index/components/ProjectCard.vue @@ -1,5 +1,6 @@ + + + + diff --git a/src/pages/home-index/components/ServiceCard.vue b/src/pages/home-index/components/ServiceCard.vue index 61ddfc5..0e3d0b3 100644 --- a/src/pages/home-index/components/ServiceCard.vue +++ b/src/pages/home-index/components/ServiceCard.vue @@ -1,9 +1,18 @@ @@ -361,6 +390,14 @@ const projects: ProjectItem[] = [ padding-top: 20rpx } +.home__sectionss { + margin-bottom: 20rpx; + width: 711.83rpx; + background: $color-bg-page; + border-radius: 20rpx; + padding-top: 20rpx +} + .home__section--last { margin-bottom: 0; } @@ -422,34 +459,52 @@ const projects: ProjectItem[] = [ .home__stats-row { display: flex; gap: 20rpx; + padding: 0 20rpx; } .home__stat-card { display: flex; flex: 1; flex-direction: column; - padding: 28rpx 24rpx; + align-items: center; + justify-content: center; + padding: 32rpx 24rpx; border-radius: 16rpx; + text-align: center; &--blue { - background: $color-primary-light; + background: linear-gradient(180deg, #D3E1FC 0%, #FFFFFF 100%); } &--orange { - background: $color-stat-orange-bg; + background: linear-gradient(180deg, #FFECE1 0%, #FFFFFF 100%); } } .home__stat-value { - font-size: 32rpx; + display: flex; + align-items: baseline; + justify-content: center; +} + +.home__stat-num { + font-size: 56rpx; font-weight: 700; + line-height: 1; + color: $color-text-primary; +} + +.home__stat-unit { + margin-left: 4rpx; + font-size: 28rpx; + font-weight: 500; color: $color-text-primary; } .home__stat-label { - margin-top: 8rpx; + margin-top: 12rpx; font-size: 24rpx; - color: $color-text-secondary; + color: #333333; } .home__recent-title { diff --git a/src/pages/home-index/requirement-submit/index.vue b/src/pages/home-index/requirement-submit/index.vue new file mode 100644 index 0000000..4b836f8 --- /dev/null +++ b/src/pages/home-index/requirement-submit/index.vue @@ -0,0 +1,706 @@ + + +