feat(pages): 添加管理页面功能和配置

- 创建 .editorconfig 文件统一代码风格配置
- 配置 .eslintrc 使用 taro/react 规则集
- 完善 .gitignore 忽略编译产物和敏感文件
- 添加 admin/article/add 页面实现文章管理功能
- 添加 dealer/apply/add 页面实现经销商申请功能
- 添加 dealer/bank/add 页面实现银行卡管理功能
- 添加 dealer/customer/add 页面实现客户管理功能
- 添加 user/address/add 页面实现用户地址管理功能
- 添加 user/chat/message/add 页面实现消息功能
- 添加 user/gift/add 页面实现礼品管理功能
- 配置各页面导航栏标题和样式
- 实现表单验证和数据提交功能
- 集成图片上传和头像选择功能
- 添加日期选择和数据校验逻辑
- 实现编辑和新增模式切换
- 集成用户权限和角色管理功能
This commit is contained in:
2026-02-08 12:15:31 +08:00
commit ec252beb4b
548 changed files with 76314 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
export default definePageConfig({
navigationBarTitleText: '网点',
navigationBarTextStyle: 'black',
navigationBarBackgroundColor: '#ffffff'
})

144
src/pages/find/find.scss Normal file
View File

@@ -0,0 +1,144 @@
page {
background: #f7f7f7;
}
.sitePage {
min-height: 100vh;
background: linear-gradient(180deg, #fde8ea 0%, #f7f7f7 320rpx, #f7f7f7 100%);
padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
}
.searchArea {
padding: 22rpx 24rpx 18rpx;
}
.searchBox {
height: 86rpx;
background: #fff;
border: 2rpx solid #b51616;
border-radius: 12rpx;
display: flex;
align-items: center;
overflow: hidden;
}
.searchInput {
flex: 1;
height: 86rpx;
padding: 0 20rpx;
font-size: 30rpx;
color: #222;
}
.searchPlaceholder {
color: #9e9e9e;
font-size: 30rpx;
}
.searchIconWrap {
width: 88rpx;
height: 86rpx;
display: flex;
align-items: center;
justify-content: center;
}
.siteList {
padding: 0 24rpx 24rpx;
}
.siteCard {
background: #fff;
border-radius: 18rpx;
padding: 22rpx 22rpx 18rpx;
margin-top: 18rpx;
box-shadow: 0 10rpx 24rpx rgba(0, 0, 0, 0.04);
}
.siteCardInner {
display: flex;
align-items: stretch;
}
.siteInfo {
flex: 1;
padding-right: 10rpx;
}
.siteRow {
display: flex;
align-items: flex-start;
padding: 10rpx 0;
}
.siteRowTop {
padding-top: 2rpx;
padding-bottom: 14rpx;
}
.siteLabel {
width: 170rpx;
flex: 0 0 170rpx;
color: #9a9a9a;
font-size: 30rpx;
line-height: 1.6;
}
.siteValue {
flex: 1;
color: #222;
font-size: 30rpx;
line-height: 1.6;
word-break: break-all;
}
.siteValueStrong {
font-weight: 700;
}
.siteDivider {
height: 2rpx;
background: #ededed;
}
.siteSide {
width: 160rpx;
flex: 0 0 160rpx;
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: center;
padding-left: 12rpx;
}
.navArrow {
width: 34rpx;
height: 34rpx;
border-top: 8rpx solid #e60012;
border-right: 8rpx solid #e60012;
border-radius: 4rpx;
transform: rotate(45deg);
margin-right: 8rpx;
}
.distanceText {
margin-top: 18rpx;
font-size: 28rpx;
color: #e60012;
font-weight: 700;
}
.emptyWrap {
padding: 40rpx 0;
display: flex;
justify-content: center;
}
.emptyText {
font-size: 28rpx;
color: #9a9a9a;
}
.bottomSafe {
height: 20rpx;
}

130
src/pages/find/find.tsx Normal file
View File

@@ -0,0 +1,130 @@
import {useMemo, useState} from 'react'
import Taro from '@tarojs/taro'
import {Input, Text, View} from '@tarojs/components'
import {Search} from '@nutui/icons-react-taro'
import './find.scss'
type SiteItem = {
id: string
cityName: string
address: string
phone: string
contact: string
distanceMeter: number
}
const MOCK_SITES: SiteItem[] = [
{
id: '1',
cityName: '北京朝阳区网点',
address: '地安门西大街(南门)',
phone: '15878179339',
contact: '刘先生',
distanceMeter: 100
},
{
id: '2',
cityName: '兰州某某区网点',
address: '地安门西大街(南门)',
phone: '15878179339',
contact: '黄先生',
distanceMeter: 150
},
{
id: '3',
cityName: '合肥市某某区网点',
address: '地安门西大街(南门)',
phone: '15878179339',
contact: '黄先生',
distanceMeter: 250
},
{
id: '4',
cityName: '南宁市某某区网点',
address: '广西壮族自治区南宁市良庆区五象新区五象大道403号富雅国际金融中心G1栋高层6006',
phone: '15878179339',
contact: '柳先生',
distanceMeter: 1250
}
]
const Find = () => {
const [keyword, setKeyword] = useState<string>('')
const filtered = useMemo(() => {
const key = keyword.trim()
if (!key) return MOCK_SITES
return MOCK_SITES.filter((it) => it.cityName.includes(key))
}, [keyword])
const onNavigate = (item: SiteItem) => {
Taro.showToast({title: `导航至:${item.cityName}(示例)`, icon: 'none'})
}
const onSearch = () => {
Taro.showToast({title: '查询(示例)', icon: 'none'})
}
return (
<View className='sitePage'>
<View className='searchArea'>
<View className='searchBox'>
<Input
className='searchInput'
value={keyword}
placeholder='请输入城市名称查询'
placeholderClass='searchPlaceholder'
confirmType='search'
onInput={(e) => setKeyword(e.detail.value)}
onConfirm={onSearch}
/>
<View className='searchIconWrap' onClick={onSearch}>
<Search size={18} color='#b51616' />
</View>
</View>
</View>
<View className='siteList'>
{filtered.map((item) => (
<View key={item.id} className='siteCard'>
<View className='siteCardInner'>
<View className='siteInfo'>
<View className='siteRow siteRowTop'>
<Text className='siteLabel'></Text>
<Text className='siteValue siteValueStrong'>{item.cityName}</Text>
</View>
<View className='siteDivider' />
<View className='siteRow'>
<Text className='siteLabel'></Text>
<Text className='siteValue'>{item.address}</Text>
</View>
<View className='siteRow'>
<Text className='siteLabel'></Text>
<Text className='siteValue'>{item.phone}</Text>
</View>
<View className='siteRow'>
<Text className='siteLabel'></Text>
<Text className='siteValue'>{item.contact}</Text>
</View>
</View>
<View className='siteSide' onClick={() => onNavigate(item)}>
<View className='navArrow' />
<Text className='distanceText'>{item.distanceMeter}</Text>
</View>
</View>
</View>
))}
{filtered.length === 0 && (
<View className='emptyWrap'>
<Text className='emptyText'></Text>
</View>
)}
</View>
<View className='bottomSafe' />
</View>
)
}
export default Find