feat: 新增客户功能,新增客户和客户列表页面,添加到管理区域
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Agent
2026-03-28 15:10:06 +00:00
parent 8c71045175
commit ec89799970
4 changed files with 249 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
<template>
<view class="page">
<view class="form-card">
<view class="form-item">
<text class="label">手机号 *</text>
<input class="input" v-model="form.phone" placeholder="请输入手机号" type="number" />
</view>
<view class="form-item">
<text class="label">客户姓名 *</text>
<input class="input" v-model="form.name" placeholder="请输入客户姓名" />
</view>
<view class="form-item">
<text class="label">微信号</text>
<input class="input" v-model="form.wechat" placeholder="请输入微信号" />
</view>
</view>
<button class="submit-btn" @click="submit">保存</button>
</view>
</template>
<script>
import customerApi from '@/api/customer'
export default {
data() {
return {
form: {
phone: '',
name: '',
wechat: ''
}
}
},
methods: {
async submit() {
if (!this.form.phone) {
uni.showToast({ title: '请输入手机号', icon: 'none' })
return
}
if (!this.form.name) {
uni.showToast({ title: '请输入客户姓名', icon: 'none' })
return
}
try {
await customerApi.createCustomer(this.form)
uni.showToast({ title: '添加成功', icon: 'success' })
setTimeout(() => uni.navigateBack(), 1500)
} catch (e) {
uni.showToast({ title: e.message || '添加失败', icon: 'none' })
}
}
}
}
</script>
<style>
.page {
padding: 30rpx;
background: #f5f5f5;
min-height: 100vh;
}
.form-card {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
}
.form-item {
margin-bottom: 30rpx;
}
.label {
display: block;
font-size: 26rpx;
color: #333;
margin-bottom: 16rpx;
}
.input {
width: 100%;
height: 80rpx;
background: #f5f5f5;
border-radius: 12rpx;
padding: 0 20rpx;
font-size: 28rpx;
box-sizing: border-box;
}
.submit-btn {
margin-top: 40rpx;
height: 88rpx;
background: #1890ff;
color: #fff;
border-radius: 44rpx;
font-size: 30rpx;
border: none;
}
</style>

128
src/pages/customer/list.vue Normal file
View File

@@ -0,0 +1,128 @@
<template>
<view class="page">
<view class="search-bar">
<input class="search-input" v-model="keyword" placeholder="搜索客户姓名或手机号" @input="search" />
</view>
<scroll-view scroll-y class="list">
<view
v-for="item in customers"
:key="item.customerId"
class="customer-card"
@click="viewDetail(item)"
>
<view class="info">
<text class="name">{{ item.name }}</text>
<text class="phone">{{ item.phone }}</text>
<text class="wechat" v-if="item.wechat">{{ item.wechat }}</text>
</view>
<text class="arrow"></text>
</view>
<view v-if="customers.length === 0" class="empty">暂无客户</view>
</scroll-view>
</view>
</template>
<script>
import customerApi from '@/api/customer'
export default {
data() {
return {
keyword: '',
customers: []
}
},
onLoad() {
this.loadCustomers()
},
methods: {
async loadCustomers() {
try {
const res = await customerApi.getCustomers({ keyword: this.keyword, page: 1, pageSize: 100 })
this.customers = res.records || []
} catch (e) {
console.error(e)
}
},
search() {
this.loadCustomers()
},
viewDetail(item) {
uni.showModal({
title: '客户详情',
content: `姓名: ${item.name}\n手机: ${item.phone}\n微信: ${item.wechat || '-'}`,
showCancel: false
})
}
}
}
</script>
<style>
.page {
padding: 20rpx;
background: #f5f5f5;
height: 100vh;
display: flex;
flex-direction: column;
}
.search-bar {
background: #fff;
border-radius: 16rpx;
padding: 20rpx;
margin-bottom: 20rpx;
}
.search-input {
width: 100%;
height: 64rpx;
background: #f5f5f5;
border-radius: 32rpx;
padding: 0 30rpx;
font-size: 26rpx;
}
.list {
flex: 1;
}
.customer-card {
background: #fff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 16rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.info {
display: flex;
flex-direction: column;
}
.name {
font-size: 28rpx;
font-weight: bold;
color: #333;
}
.phone, .wechat {
font-size: 24rpx;
color: #999;
margin-top: 6rpx;
}
.arrow {
font-size: 36rpx;
color: #ccc;
}
.empty {
text-align: center;
color: #999;
padding: 60rpx;
}
</style>

View File

@@ -58,6 +58,14 @@
<text class="section-title">管理</text>
<view class="menu-grid">
<template v-if="isAdmin">
<view class="menu-item" @click="goTo('/pages/customer/create')">
<view class="menu-icon-box blue"><text class="icon-text">新增</text></view>
<text class="menu-text">新增客户</text>
</view>
<view class="menu-item" @click="goTo('/pages/customer/list')">
<view class="menu-icon-box cyan"><text class="icon-text"></text></view>
<text class="menu-text">客户列表</text>
</view>
<view class="menu-item" @click="goTo('/pages/product/manage')">
<view class="menu-icon-box purple"><text class="icon-text"></text></view>
<text class="menu-text">商品管理</text>