Files
shop-platform/docs/readme.md

429 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 说明
## 基本概念
店铺和门店的关系可以从不同角度来理解,让我为您详细解释:
## 🏪 **店铺 vs 门店:概念解析**
### **1. 从层级关系理解**
#### **店铺(总店/品牌店)**
```mermaid
graph TD
A[品牌总部/总店] --> B1[门店A]
A --> B2[门店B]
A --> B3[门店C]
A --> B4[线上店铺]
B1 --> C1[分店A-1]
B1 --> C2[分店A-2]
B2 --> C3[分店B-1]
```
**店铺特征:**
- **管理层面**:品牌、总部、总店的概念
- **业务范围**:可能包含多个物理门店和线上渠道
- **功能定位**:战略决策、品牌管理、供应链控制
#### **门店(分店/实体店)**
```mermaid
graph LR
A[门店] --> B[具体营业场所]
A --> C[固定地址]
A --> D[面对面服务]
```
**门店特征:**
- **物理存在**:有具体的营业场所和地址
- **服务范围**:服务特定区域客户
- **运营独立**:相对独立的日常运营
### **2. 从业务模式区分**
| 维度 | 店铺Shop | 门店Store |
|------|-------------|--------------|
| **存在形式** | 可虚拟可实体 | 必须是实体 |
| **数量关系** | 1个店铺可有多门店 | 1个门店属于1个店铺 |
| **管理范围** | 品牌、战略、标准 | 日常运营、客户服务 |
| **系统关系** | 总部系统、ERP | POS系统、库存管理 |
### **3. 实际业务场景**
#### **场景1连锁品牌**
```
店铺(总店)
├── 北京门店(朝阳区店)
├── 上海门店(浦东店)
├── 广州门店(天河店)
└── 线上官方店铺
```
#### **场景2电商+实体结合**
```
店铺(品牌旗舰店)
├── 天猫官方店铺(线上)
├── 京东官方店铺(线上)
├── 线下体验门店(实体)
└── 微信小程序店铺(线上)
```
#### **场景3单店经营**
```
店铺 = 门店(合二为一)
└── 既是品牌也是具体营业点
```
## 💼 **在智能客服系统中的数据建模**
### **1. 数据库设计**
```sql
-- 店铺表(总店/品牌)
CREATE TABLE shops (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL, -- 店铺名称
brand_name VARCHAR(100), -- 品牌名称
type ENUM('single', 'chain', 'online'), -- 店铺类型
status ENUM('active', 'inactive'),
created_at TIMESTAMP
);
-- 门店表(分店/实体店)
CREATE TABLE stores (
id INT PRIMARY KEY AUTO_INCREMENT,
shop_id INT, -- 所属店铺
name VARCHAR(100) NOT NULL, -- 门店名称
address TEXT, -- 具体地址
phone VARCHAR(20),
manager_id INT, -- 店长
business_hours JSON, -- 营业时间
latitude DECIMAL(10, 8), -- 纬度
longitude DECIMAL(11, 8), -- 经度
status ENUM('open', 'closed', 'maintenance'),
FOREIGN KEY (shop_id) REFERENCES shops(id)
);
-- 员工表(关联门店)
CREATE TABLE staff (
id INT PRIMARY KEY AUTO_INCREMENT,
store_id INT, -- 所属门店
name VARCHAR(50),
role ENUM('manager', 'assistant', 'cashier'),
phone VARCHAR(20),
FOREIGN KEY (store_id) REFERENCES stores(id)
);
```
### **2. 业务逻辑实现**
```javascript
// 店铺管理类
class ShopManager {
constructor() {
this.shops = new Map();
this.stores = new Map();
}
// 创建店铺
createShop(shopData) {
const shop = {
id: this.generateId(),
name: shopData.name,
brand: shopData.brand,
type: shopData.type || 'single',
stores: [], // 下属门店
createdAt: new Date(),
status: 'active'
};
this.shops.set(shop.id, shop);
return shop;
}
// 添加门店到店铺
addStoreToShop(shopId, storeData) {
const shop = this.shops.get(shopId);
if (!shop) throw new Error('店铺不存在');
const store = {
id: this.generateId(),
shopId: shopId,
name: storeData.name,
address: storeData.address,
contact: storeData.contact,
coordinates: storeData.coordinates,
businessHours: storeData.businessHours,
staff: [],
createdAt: new Date()
};
shop.stores.push(store.id);
this.stores.set(store.id, store);
return store;
}
// 根据位置查找最近门店
findNearestStore(shopId, userLocation) {
const shop = this.shops.get(shopId);
if (!shop) return null;
let nearestStore = null;
let minDistance = Infinity;
shop.stores.forEach(storeId => {
const store = this.stores.get(storeId);
if (store && store.status === 'open') {
const distance = this.calculateDistance(
userLocation,
store.coordinates
);
if (distance < minDistance) {
minDistance = distance;
nearestStore = store;
}
}
});
return nearestStore;
}
// 计算距离(简化版)
calculateDistance(loc1, loc2) {
const R = 6371; // 地球半径公里
const dLat = this.deg2rad(loc2.lat - loc1.lat);
const dLon = this.deg2rad(loc2.lon - loc1.lon);
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(this.deg2rad(loc1.lat)) * Math.cos(this.deg2rad(loc2.lat)) *
Math.sin(dLon/2) * Math.sin(dLon/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
deg2rad(deg) {
return deg * (Math.PI/180);
}
}
```
### **3. 在智能客服中的对话逻辑**
```javascript
// 店铺门店相关的对话处理
class StoreDialogHandler {
constructor(shopManager) {
this.shopManager = shopManager;
}
// 处理用户查询
handleStoreQuery(userMessage, userContext) {
const intent = this.detectIntent(userMessage);
switch(intent) {
case 'find_nearest':
return this.handleFindNearest(userMessage, userContext);
case 'store_hours':
return this.handleStoreHours(userMessage, userContext);
case 'store_contact':
return this.handleStoreContact(userMessage, userContext);
case 'all_stores':
return this.handleAllStores(userMessage, userContext);
default:
return this.handleGeneralQuery(userMessage, userContext);
}
}
// 查找最近门店
handleFindNearest(userMessage, userContext) {
const location = this.extractLocation(userMessage);
const shopId = userContext.currentShopId;
if (!location) {
return {
type: 'request_location',
message: '请问您当前在哪个位置?我可以帮您查找最近的门店。',
options: ['使用当前位置', '手动输入地址']
};
}
const nearestStore = this.shopManager.findNearestStore(shopId, location);
if (nearestStore) {
return {
type: 'store_info',
message: `离您最近的门店是:${nearestStore.name}`,
data: {
store: nearestStore,
distance: this.calculateDistance(location, nearestStore.coordinates),
estimatedTime: this.estimateTravelTime(nearestStore.coordinates, location)
},
actions: [
{ text: '查看详情', action: 'show_store_detail' },
{ text: '导航前往', action: 'navigate_to_store' },
{ text: '联系门店', action: 'contact_store' }
]
};
} else {
return {
type: 'no_store_found',
message: '在您附近没有找到我们的门店,建议您尝试线上服务或查看其他区域的门店。',
alternatives: this.findAlternativeStores(shopId)
};
}
}
// 处理营业时间查询
handleStoreHours(userMessage, userContext) {
const storeName = this.extractStoreName(userMessage);
const store = this.findStoreByName(storeName, userContext.currentShopId);
if (store) {
const hours = store.businessHours;
const currentStatus = this.getCurrentStatus(store);
return {
type: 'business_hours',
message: `${store.name}的营业时间:${this.formatBusinessHours(hours)}`,
data: {
store: store,
currentStatus: currentStatus,
todayHours: this.getTodayHours(hours)
}
};
}
}
}
```
### **4. 响应消息模板**
```javascript
// 店铺门店信息响应模板
const StoreResponseTemplates = {
// 门店列表响应
storeList: (stores, options = {}) => {
return {
type: 'store_list',
layout: 'card',
title: options.title || '我们的门店',
items: stores.map(store => ({
title: store.name,
description: store.address,
image: store.image,
meta: {
distance: store.distance ? `${store.distance}km` : '',
status: store.status === 'open' ? '营业中' : '休息中',
hours: store.businessHours ? '查看营业时间' : ''
},
actions: [
{ text: '导航', action: 'navigate', data: { storeId: store.id } },
{ text: '电话', action: 'call', data: { phone: store.phone } },
{ text: '详情', action: 'detail', data: { storeId: store.id } }
]
})),
quickReplies: [
'找最近的门店',
'查看所有门店',
'联系客服'
]
};
},
// 单个门店详情
storeDetail: (store) => {
return {
type: 'store_detail',
layout: 'detail',
title: store.name,
sections: [
{
title: '📍 地址',
content: store.address,
action: { type: 'map', data: store.coordinates }
},
{
title: '📞 联系方式',
content: store.phone,
action: { type: 'call', data: store.phone }
},
{
title: '🕒 营业时间',
content: formatBusinessHours(store.businessHours),
action: { type: 'hours', data: store.businessHours }
},
{
title: '👥 门店服务',
content: store.services.join('、'),
action: { type: 'services', data: store.services }
}
],
actions: [
{ text: '分享门店', action: 'share' },
{ text: '收藏门店', action: 'favorite' },
{ text: '投诉建议', action: 'feedback' }
]
};
},
// 营业时间响应
businessHours: (store, currentStatus) => {
return {
type: 'business_hours',
message: `**${store.name}**\n\n` +
`当前状态:**${currentStatus}**\n\n` +
`营业时间:\n${formatBusinessHours(store.businessHours)}`,
quickActions: [
{ text: '明天营业时间', action: 'tomorrow_hours' },
{ text: '节假日安排', action: 'holiday_hours' },
{ text: '联系确认', action: 'confirm_hours' }
]
};
}
};
// 工具函数
function formatBusinessHours(hours) {
if (!hours) return '暂无信息';
const days = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
return days.map((day, index) => {
const dayHours = hours[index] || hours['default'];
return `${day}: ${dayHours || '休息'}`;
}).join('\n');
}
```
## 🎯 **总结:店铺与门店的关系**
### **核心关系**
1. **包含关系**店铺包含门店1:N
2. **品牌关系**:店铺是品牌,门店是落地实体
3. **管理关系**:店铺管理门店的标准和运营
### **在智能客服中的应用**
- **用户说"我要找店铺"** → 理解为品牌/总店概念
- **用户说"找最近的门店"** → 理解为具体营业点
- **用户说"你们店在哪里"** → 需要区分是指品牌还是具体门店
### **数据处理建议**
```javascript
// 在客服系统中这样区分:
const customerQuery = {
"找苹果店": { type: "shop", brand: "apple" },
"找朝阳区的苹果店": { type: "store", brand: "apple", location: "朝阳区" },
"线上店铺": { type: "online_shop" },
"实体门店": { type: "physical_store" }
};
```
这样的区分让智能客服能够更精准地理解用户意图,提供更准确的店铺/门店信息服务。