feat(credit): 添加企业信用模块功能

- 在应用配置中注册公司管理页面路由
- 实现首页轮播图组件优化,支持CSS尺寸转换和图片加载
- 新增企业ID修正API功能
- 实现信用模块数据权限控制工具
- 添加客户、联系人、数据查询等页面配置
- 完善行政许可、破产重整、分支机构等信用数据模型
- 实现各类信用数据的增删改查和导入导出接口
- 建立企业信用数据完整管理功能体系
This commit is contained in:
2026-03-05 10:58:39 +08:00
parent 61397b1711
commit 6e6fd43017
66 changed files with 6971 additions and 101 deletions

View File

@@ -5,11 +5,22 @@ import {Image} from '@nutui/nutui-react-taro'
import {getCmsAdByCode} from "@/api/cms/cmsAd";
const MyPage = () => {
const [item, setItem] = useState<CmsAd>()
const [ad, setAd] = useState<CmsAd>()
const toCssSize = (value?: string | number) => {
if (value === undefined || value === null) return undefined
const s = String(value).trim()
if (!s) return undefined
// If it's a pure number, default unit is px; otherwise keep backend-provided unit (e.g. rpx/px/%).
return Number.isNaN(Number(s)) ? s : `${Number(s)}px`
}
const bannerHeight = toCssSize(ad?.height)
const reload = async () => {
const flash = await getCmsAdByCode('flash')
console.log(flash)
setItem(flash)
setAd(flash)
}
useEffect(() => {
@@ -18,12 +29,22 @@ const MyPage = () => {
return (
<>
<Swiper defaultValue={0} height={item?.height} indicator style={{ height: item?.height + 'px' }}>
{item?.imageList?.map((item) => (
<Swiper.Item key={item}>
<Image width="100%" height="100%" src={item.url} mode={'scaleToFill'} lazyLoad={false} style={{ height: item.height + 'px' }} />
</Swiper.Item>
))}
<Swiper defaultValue={0} height={170} indicator>
{ad?.imageList?.map((img, idx) => {
const url = typeof img === 'string' ? img : img?.url
if (!url) return null
return (
<Swiper.Item key={url || idx}>
<Image
width='100%'
height='100%'
src={url}
mode='scaleToFill'
lazyLoad={false}
/>
</Swiper.Item>
)
})}
</Swiper>
</>
)

View File

@@ -1,15 +1,20 @@
import Taro, {useShareAppMessage, useShareTimeline} from '@tarojs/taro'
import {Image, Swiper, SwiperItem, Text, View} from '@tarojs/components'
import {Image, Text, View} from '@tarojs/components'
import {useEffect, useState} from 'react'
import Banner from './Banner'
import iconShop from '@/assets/tabbar/shop.png'
import iconFind from '@/assets/tabbar/find.png'
import iconKefu from '@/assets/tabbar/kefu.png'
import './index.scss'
import navTo from "@/utils/common";
import {pageCmsArticle} from '@/api/cms/cmsArticle'
import {getByCode as getArticleByCode, pageCmsArticle} from '@/api/cms/cmsArticle'
import type {CmsArticle} from '@/api/cms/cmsArticle/model'
import {useUser} from '@/hooks/useUser'
function Home() {
const {isAdmin} = useUser()
const admin = isAdmin()
useShareTimeline(() => {
return {
title: '易赊宝',
@@ -40,12 +45,19 @@ function Home() {
Taro.showToast({title: `${textMap[type]}(示例)`, icon: 'none'})
}
const onDemand = () => {
Taro.showToast({title: '发需求(示例)', icon: 'none'})
}
const FAQ_CATEGORY_ID = 4558
const [faqList, setFaqList] = useState<CmsArticle[]>([])
const [aboutArticle, setAboutArticle] = useState<CmsArticle | null>(null)
const loadAbout = async () => {
try {
const res = await getArticleByCode('about')
setAboutArticle(res || null)
} catch (e) {
console.error('loadAbout error:', e)
setAboutArticle(null)
}
}
const loadFaq = async () => {
try {
@@ -65,119 +77,138 @@ function Home() {
useEffect(() => {
loadFaq().then()
loadAbout().then()
}, [])
const aboutText =
(aboutArticle?.comments || '')
.replace(/<[^>]*>/g, '')
.replace(/&nbsp;|&#160;/g, ' ')
.trim() ||
'易赊宝是提供专业回款咨询服务的小程序!我们重视企业需求,加速回款咨询服务能力助力企业资金流动畅通循环,服务团队全国覆盖。'
return (
<View className='home'>
<View className='bannerCard'>
<Swiper
className='bannerSwiper'
circular
autoplay
interval={3500}
duration={400}
indicatorDots
indicatorColor='rgba(255,255,255,0.55)'
indicatorActiveColor='#ffffff'
>
<SwiperItem>
<View className='bannerSlide bannerSlide1'>
<View className='bannerLogo'>
<Text className='bannerLogoText'></Text>
</View>
<Text className='bannerSlogan'></Text>
</View>
</SwiperItem>
<SwiperItem>
<View className='bannerSlide bannerSlide2'>
<View className='bannerLogo'>
<Text className='bannerLogoText'></Text>
</View>
<Text className='bannerSlogan'></Text>
</View>
</SwiperItem>
</Swiper>
{/* 顶部活动主视觉:使用 Banner 组件 */}
<Banner />
</View>
<View className='actionCard'>
<View className='actionRow'>
<View className='actionItem' onClick={() => onAction('progress')}>
<View className='actionIcon'>
<Image className='actionIconImg' src={iconShop} mode='aspectFit' />
{!admin && (
<View className='actionCard'>
<View className='actionRow'>
<View className='actionItem' onClick={() => onAction('progress')}>
<View className='actionIcon'>
<Image className='actionIconImg' src={iconShop} mode='aspectFit' />
</View>
<Text className='actionLabel'></Text>
</View>
<Text className='actionLabel'></Text>
</View>
<View className='actionItem' onClick={() => onAction('guide')}>
<View className='actionIcon'>
<Image className='actionIconImg' src={iconFind} mode='aspectFit' />
<View className='actionItem' onClick={() => onAction('guide')}>
<View className='actionIcon'>
<Image className='actionIconImg' src={iconFind} mode='aspectFit' />
</View>
<Text className='actionLabel'></Text>
</View>
<Text className='actionLabel'></Text>
</View>
<View className='actionItem' onClick={() => onAction('kefu')}>
<View className='actionIcon'>
<Image className='actionIconImg' src={iconKefu} mode='aspectFit' />
<View className='actionItem' onClick={() => onAction('kefu')}>
<View className='actionIcon'>
<Image className='actionIconImg' src={iconKefu} mode='aspectFit' />
</View>
<Text className='actionLabel'>线</Text>
</View>
<Text className='actionLabel'>线</Text>
</View>
</View>
</View>
)}
<View className='sectionCard'>
<View className='sectionHeader'>
<View className='sectionAccent' />
<Text className='sectionTitle'></Text>
<Text className='sectionMore'></Text>
<Text
className='sectionMore'
onClick={() => {
if (aboutArticle?.articleId) {
navTo(`/cms/detail/index?id=${aboutArticle.articleId}`)
} else {
Taro.showToast({title: '暂无简介内容', icon: 'none'})
}
}}
>
</Text>
</View>
<View className='introBox'>
<Text className='introText'>
{aboutText}
</Text>
</View>
<View className='ctaWrap'>
<View className='ctaBtn' onClick={() => navTo('/credit/order/add', true)}>
<Text className='ctaBtnText'></Text>
</View>
<Text className='ctaHint'></Text>
</View>
</View>
<View className='sectionCard'>
<View className='sectionHeader'>
<View className='sectionAccent' />
<Text className='sectionTitle'></Text>
<Text
className='sectionMore'
onClick={() => navTo(`/cms/category/index?id=${FAQ_CATEGORY_ID}`)}
>
&gt;&gt;
</Text>
</View>
<View className='faqList'>
{faqList.length > 0 ? (
faqList.map((item, idx, arr) => (
<View
key={item.articleId || `${item.title}-${idx}`}
className={`faqItem ${idx === arr.length - 1 ? 'faqItemLast' : ''}`}
onClick={() => item.articleId && navTo(`/cms/detail/index?id=${item.articleId}`)}
>
<Text className='faqTitle'>{item.title}</Text>
<Text className='faqDate'>{(item.createTime || '').slice(0, 10)}</Text>
</View>
))
) : (
<View className='faqItem faqItemLast'>
<Text className='faqTitle'></Text>
<Text className='faqDate' />
{admin && (
<View className='ctaWrap gap-2'>
<View className='ctaBtn' onClick={() => navTo('/credit/company/index', true)}>
<Text className='ctaBtnText'></Text>
</View>
)}
</View>
<View className='ctaBtn' onClick={() => navTo('/credit/order/index', true)}>
<Text className='ctaBtnText'></Text>
</View>
<View className='ctaBtn' onClick={() => navTo('/credit/data/index', true)}>
<Text className='ctaBtnText'></Text>
</View>
<View className='ctaBtn' onClick={() => navTo('/credit/customer/index', true)}>
<Text className='ctaBtnText'></Text>
</View>
</View>
)}
{!admin && (
<View className='ctaWrap'>
<View className='ctaBtn' onClick={() => navTo('/credit/order/add', true)}>
<Text className='ctaBtnText'></Text>
</View>
<Text className='ctaHint'></Text>
</View>
)}
</View>
{!admin && (
<View className='sectionCard'>
<View className='sectionHeader'>
<View className='sectionAccent' />
<Text className='sectionTitle'></Text>
<Text
className='sectionMore'
onClick={() => navTo(`/cms/category/index?id=${FAQ_CATEGORY_ID}`)}
>
&gt;&gt;
</Text>
</View>
<View className='faqList'>
{faqList.length > 0 ? (
faqList.map((item, idx, arr) => (
<View
key={item.articleId || `${item.title}-${idx}`}
className={`faqItem ${idx === arr.length - 1 ? 'faqItemLast' : ''}`}
onClick={() => item.articleId && navTo(`/cms/detail/index?id=${item.articleId}`)}
>
<Text className='faqTitle'>{item.title}</Text>
<Text className='faqDate'>{(item.createTime || '').slice(0, 10)}</Text>
</View>
))
) : (
<View className='faqItem faqItemLast'>
<Text className='faqTitle'></Text>
<Text className='faqDate' />
</View>
)}
</View>
</View>
)}
<View className='bottomSpacer' />
</View>
)

View File

@@ -1,11 +1,9 @@
import {useEffect, useRef, useState} from 'react'
import {PullToRefresh} from '@nutui/nutui-react-taro'
import UserCard from "./components/UserCard";
import UserOrder from "./components/UserOrder";
import UserFooter from "./components/UserFooter";
import {View} from '@tarojs/components';
import './user.scss'
import IsDealer from "./components/IsDealer";
import {useThemeStyles} from "@/hooks/useTheme";
import UserGrid from "@/pages/user/components/UserGrid";
import { useDidShow } from '@tarojs/taro'