地址路径修改
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
// 管理员界面 - 全屏管理面板
|
||||
import { UserInfo } from '../../types';
|
||||
import { Role } from '../../utils/roleUtils';
|
||||
import userService from '../../services/userService';
|
||||
import statisticsService from '../../services/statisticsService';
|
||||
import { API_BASE_URL } from '../../services/apiService';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -60,7 +63,7 @@ Page({
|
||||
currentTime: ''
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
onLoad: function() {
|
||||
this.getUserInfo();
|
||||
this.loadStatistics();
|
||||
this.updateCurrentTime();
|
||||
@@ -70,49 +73,143 @@ Page({
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
onShow() {
|
||||
onShow: function() {
|
||||
this.loadStatistics();
|
||||
this.updateCurrentTime();
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取完整的头像URL
|
||||
* @param avatarPath 头像相对路径
|
||||
* @returns 完整的头像URL
|
||||
*/
|
||||
getFullAvatarUrl: function(avatarPath: string | undefined): string {
|
||||
if (!avatarPath) {
|
||||
return '/images/user-avatar.png';
|
||||
}
|
||||
|
||||
// 如果已经是完整URL,直接返回
|
||||
if (avatarPath.startsWith('http')) {
|
||||
return avatarPath;
|
||||
}
|
||||
|
||||
// 将相对路径转换为完整URL
|
||||
return `${API_BASE_URL}${avatarPath}`;
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理用户信息,预先准备好完整的头像URL
|
||||
* @param userInfo 原始用户信息
|
||||
* @returns 处理后的用户信息
|
||||
*/
|
||||
processUserInfo: function(userInfo: any): any {
|
||||
if (!userInfo) {
|
||||
return {
|
||||
id: 0,
|
||||
role: Role.ADMIN,
|
||||
name: '管理员',
|
||||
fullAvatarUrl: '/images/user-avatar.png'
|
||||
};
|
||||
}
|
||||
|
||||
// 预先准备好完整的头像URL
|
||||
const processedUserInfo = { ...userInfo };
|
||||
if (userInfo.avatarPath) {
|
||||
processedUserInfo.fullAvatarUrl = this.getFullAvatarUrl(userInfo.avatarPath);
|
||||
} else {
|
||||
processedUserInfo.fullAvatarUrl = '/images/user-avatar.png';
|
||||
}
|
||||
|
||||
return processedUserInfo;
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*/
|
||||
getUserInfo() {
|
||||
const app = getApp<any>();
|
||||
if (app.globalData.userInfo) {
|
||||
const userInfo = app.globalData.userInfo;
|
||||
this.setData({ userInfo });
|
||||
getUserInfo: async function() {
|
||||
try {
|
||||
const app = getApp<any>();
|
||||
|
||||
// 验证是否为管理员
|
||||
if (userInfo.role !== 'ADMIN') {
|
||||
wx.showToast({
|
||||
title: '无权限访问',
|
||||
icon: 'none'
|
||||
});
|
||||
wx.navigateBack();
|
||||
// 如果全局数据中没有用户信息,尝试从用户服务获取
|
||||
if (!app.globalData.userInfo) {
|
||||
const userInfo = await userService.getUserInfo();
|
||||
if (userInfo) {
|
||||
app.globalData.userInfo = userInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (app.globalData.userInfo) {
|
||||
const userInfo = this.processUserInfo(app.globalData.userInfo);
|
||||
this.setData({ userInfo });
|
||||
|
||||
// 验证是否为管理员
|
||||
if (userInfo.role !== Role.ADMIN) {
|
||||
wx.showToast({
|
||||
title: '无权限访问',
|
||||
icon: 'none'
|
||||
});
|
||||
wx.navigateBack();
|
||||
}
|
||||
} else {
|
||||
// 如果仍然没有用户信息,显示默认信息
|
||||
this.setData({
|
||||
userInfo: this.processUserInfo(null)
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error);
|
||||
// 出错时显示默认信息
|
||||
this.setData({
|
||||
userInfo: this.processUserInfo(null)
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载统计数据
|
||||
*/
|
||||
loadStatistics() {
|
||||
// 模拟加载统计数据
|
||||
this.setData({
|
||||
stats: {
|
||||
employeeCount: 25,
|
||||
orderCount: 156,
|
||||
warehouseCount: 8
|
||||
}
|
||||
});
|
||||
loadStatistics: async function() {
|
||||
try {
|
||||
wx.showLoading({
|
||||
title: '加载数据中...'
|
||||
});
|
||||
|
||||
// 使用统计服务获取真实数据
|
||||
const stats = await statisticsService.getSystemStats();
|
||||
|
||||
this.setData({
|
||||
stats: {
|
||||
employeeCount: stats.employeeCount,
|
||||
orderCount: stats.orderCount,
|
||||
warehouseCount: stats.warehouseCount
|
||||
}
|
||||
});
|
||||
|
||||
wx.hideLoading();
|
||||
} catch (error) {
|
||||
console.error('加载统计数据失败:', error);
|
||||
wx.hideLoading();
|
||||
|
||||
// 出错时使用默认值
|
||||
this.setData({
|
||||
stats: {
|
||||
employeeCount: 0,
|
||||
orderCount: 0,
|
||||
warehouseCount: 0
|
||||
}
|
||||
});
|
||||
|
||||
wx.showToast({
|
||||
title: '数据加载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 菜单项点击事件
|
||||
*/
|
||||
onMenuItemTap(e: any) {
|
||||
onMenuItemTap: function(e: any) {
|
||||
const itemId = e.currentTarget.dataset.id;
|
||||
|
||||
switch (itemId) {
|
||||
@@ -152,14 +249,14 @@ Page({
|
||||
/**
|
||||
* 返回首页
|
||||
*/
|
||||
goBack() {
|
||||
goBack: function() {
|
||||
wx.navigateBack();
|
||||
},
|
||||
|
||||
/**
|
||||
* 刷新数据
|
||||
*/
|
||||
onRefresh() {
|
||||
onRefresh: function() {
|
||||
this.loadStatistics();
|
||||
this.updateCurrentTime();
|
||||
wx.showToast({
|
||||
@@ -171,7 +268,7 @@ Page({
|
||||
/**
|
||||
* 更新当前时间
|
||||
*/
|
||||
updateCurrentTime() {
|
||||
updateCurrentTime: function() {
|
||||
const now = new Date();
|
||||
const timeString = now.toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
@@ -189,7 +286,7 @@ Page({
|
||||
/**
|
||||
* 解绑微信处理
|
||||
*/
|
||||
async onUnbindWechat() {
|
||||
onUnbindWechat: async function() {
|
||||
try {
|
||||
// 确认对话框
|
||||
wx.showModal({
|
||||
|
||||
@@ -7,10 +7,14 @@
|
||||
<view class="back-icon" bindtap="goBack">
|
||||
<text class="back-arrow">‹</text>
|
||||
</view>
|
||||
<view class="admin-avatar">👑</view>
|
||||
<!-- 用户头像 -->
|
||||
<view class="admin-avatar">
|
||||
<image wx:if="{{userInfo && userInfo.fullAvatarUrl}}" src="{{userInfo.fullAvatarUrl}}" class="avatar-image" mode="aspectFill"></image>
|
||||
<text wx:else class="avatar-placeholder">{{userInfo && userInfo.name ? userInfo.name.charAt(0) : '管'}}</text>
|
||||
</view>
|
||||
<view class="admin-info">
|
||||
<text class="admin-name">{{userInfo.name || '管理员'}}</text>
|
||||
<text class="admin-role">系统管理员</text>
|
||||
<text class="admin-name">{{userInfo && userInfo.name ? userInfo.name : '管理员'}}</text>
|
||||
<text class="admin-role">{{userInfo && userInfo.role ? (userInfo.role === 'ADMIN' ? '系统管理员' : userInfo.role === 'MANAGER' ? '经理' : '员工') : '系统管理员'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="header-right">
|
||||
|
||||
@@ -58,6 +58,23 @@
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
border: 3rpx solid #667eea;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.admin-info {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
import { EmployeeInfo } from '../../types';
|
||||
import employeeService from '../../services/employeeService';
|
||||
import { Role, getRoleOptions } from '../../utils/roleUtils';
|
||||
import { avatarCache } from '../../utils/avatarCache';
|
||||
import { API_BASE_URL } from '../../services/apiService';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -10,7 +12,7 @@ Page({
|
||||
filteredEmployees: [] as EmployeeInfo[],
|
||||
|
||||
// 页面状态
|
||||
currentTab: 'list', // list: 列表页, add: 添加页
|
||||
currentTab: 'list', // list: 列表页, add: 添加页, edit: 编辑页
|
||||
loading: false,
|
||||
|
||||
// 添加员工表单数据
|
||||
@@ -20,6 +22,15 @@ Page({
|
||||
role: Role.DELIVERY_PERSON
|
||||
},
|
||||
|
||||
// 编辑员工表单数据
|
||||
editForm: {
|
||||
id: 0,
|
||||
name: '',
|
||||
phone: '',
|
||||
role: Role.DELIVERY_PERSON,
|
||||
avatarUrl: ''
|
||||
},
|
||||
|
||||
// 错误信息
|
||||
errorMessage: '',
|
||||
successMessage: '',
|
||||
@@ -31,7 +42,10 @@ Page({
|
||||
roleOptions: getRoleOptions(),
|
||||
|
||||
// 用户信息
|
||||
userInfo: null as any
|
||||
userInfo: null as any,
|
||||
|
||||
// 临时头像路径(用于头像上传)
|
||||
tempAvatarPath: ''
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
@@ -40,7 +54,10 @@ Page({
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.loadEmployees();
|
||||
// 只在页面显示时检查是否需要刷新数据,避免频繁请求
|
||||
if (this.data.employees.length === 0) {
|
||||
this.loadEmployees();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -63,6 +80,45 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取完整的头像URL
|
||||
* @param avatarPath 头像相对路径
|
||||
* @returns 完整的头像URL
|
||||
*/
|
||||
getFullAvatarUrl(avatarPath: string | undefined): string {
|
||||
if (!avatarPath) {
|
||||
return '/images/user-avatar.png';
|
||||
}
|
||||
|
||||
// 如果已经是完整URL,直接返回
|
||||
if (avatarPath.startsWith('http')) {
|
||||
return avatarPath;
|
||||
}
|
||||
|
||||
// 将相对路径转换为完整URL
|
||||
return `${API_BASE_URL}${avatarPath}`;
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取本地缓存的头像路径
|
||||
*/
|
||||
async getLocalAvatarPath(avatarPath: string | undefined): Promise<string> {
|
||||
if (!avatarPath) {
|
||||
return '/images/user-avatar.png';
|
||||
}
|
||||
|
||||
try {
|
||||
// 使用头像缓存获取本地文件路径
|
||||
const fullAvatarUrl = this.getFullAvatarUrl(avatarPath);
|
||||
const localAvatarPath = await avatarCache.getAvatarPath(fullAvatarUrl);
|
||||
return localAvatarPath;
|
||||
} catch (error) {
|
||||
console.error('获取头像缓存失败:', error);
|
||||
// 如果缓存失败,回退到远程URL
|
||||
return this.getFullAvatarUrl(avatarPath);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载员工列表
|
||||
*/
|
||||
@@ -75,11 +131,24 @@ Page({
|
||||
|
||||
try {
|
||||
const employees = await employeeService.getEmployees();
|
||||
|
||||
// 为每个员工获取本地缓存的头像路径
|
||||
const employeesWithAvatars = await Promise.all(
|
||||
employees.map(async (employee) => {
|
||||
const localAvatarPath = await this.getLocalAvatarPath(employee.avatarPath);
|
||||
|
||||
return {
|
||||
...employee,
|
||||
fullAvatarUrl: localAvatarPath
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
// 获取过滤后的员工列表
|
||||
const filteredEmployees = this.getFilteredEmployees(employees);
|
||||
const filteredEmployees = this.getFilteredEmployees(employeesWithAvatars);
|
||||
|
||||
this.setData({
|
||||
employees,
|
||||
employees: employeesWithAvatars,
|
||||
filteredEmployees,
|
||||
loading: false
|
||||
});
|
||||
@@ -103,7 +172,8 @@ Page({
|
||||
successMessage: ''
|
||||
});
|
||||
|
||||
if (tab === 'list') {
|
||||
// 只在切换到列表页且没有数据时才加载,避免频繁请求
|
||||
if (tab === 'list' && this.data.employees.length === 0) {
|
||||
this.loadEmployees();
|
||||
}
|
||||
},
|
||||
@@ -215,6 +285,220 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑员工
|
||||
*/
|
||||
editEmployee(e: any) {
|
||||
const employeeId = e.currentTarget.dataset.id;
|
||||
const employee = this.data.employees.find(emp => emp.id === employeeId);
|
||||
|
||||
if (employee) {
|
||||
this.setData({
|
||||
editForm: {
|
||||
id: employee.id || 0,
|
||||
name: employee.name || '',
|
||||
phone: employee.phone || '',
|
||||
role: employee.role || Role.DELIVERY_PERSON,
|
||||
avatarUrl: ''
|
||||
},
|
||||
currentTab: 'edit'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 提交编辑员工表单
|
||||
*/
|
||||
async submitEditForm() {
|
||||
if (!this.validateEditForm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setData({
|
||||
loading: true,
|
||||
errorMessage: '',
|
||||
successMessage: ''
|
||||
});
|
||||
|
||||
try {
|
||||
// 调用更新员工的API方法
|
||||
await employeeService.updateEmployee(this.data.editForm.id, {
|
||||
name: this.data.editForm.name,
|
||||
phone: this.data.editForm.phone,
|
||||
role: this.data.editForm.role
|
||||
});
|
||||
|
||||
// 如果有新头像,上传头像
|
||||
if (this.data.tempAvatarPath) {
|
||||
try {
|
||||
const result = await employeeService.uploadAvatar(this.data.editForm.id, this.data.tempAvatarPath);
|
||||
if (result.success && result.avatarUrl) {
|
||||
// 更新头像URL
|
||||
this.setData({
|
||||
'editForm.avatarUrl': result.avatarUrl
|
||||
});
|
||||
}
|
||||
} catch (avatarError) {
|
||||
console.error('上传头像失败:', avatarError);
|
||||
wx.showToast({
|
||||
title: '头像上传失败',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.setData({
|
||||
loading: false,
|
||||
successMessage: '员工更新成功',
|
||||
currentTab: 'list',
|
||||
tempAvatarPath: ''
|
||||
});
|
||||
|
||||
// 重新加载员工列表
|
||||
this.loadEmployees();
|
||||
|
||||
} catch (error) {
|
||||
console.error('更新员工失败:', error);
|
||||
this.setData({
|
||||
loading: false,
|
||||
errorMessage: '更新员工失败,请重试'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 选择头像
|
||||
*/
|
||||
chooseAvatar() {
|
||||
wx.chooseMedia({
|
||||
count: 1,
|
||||
mediaType: ['image'],
|
||||
sourceType: ['album'],
|
||||
maxDuration: 30,
|
||||
camera: 'back',
|
||||
success: (res) => {
|
||||
if (res.tempFiles && res.tempFiles.length > 0) {
|
||||
const tempFilePath = res.tempFiles[0].tempFilePath;
|
||||
this.setData({
|
||||
'editForm.avatarUrl': tempFilePath,
|
||||
tempAvatarPath: tempFilePath
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('选择头像失败:', err);
|
||||
wx.showToast({
|
||||
title: '选择头像失败',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 拍照
|
||||
*/
|
||||
takePhoto() {
|
||||
wx.chooseMedia({
|
||||
count: 1,
|
||||
mediaType: ['image'],
|
||||
sourceType: ['camera'],
|
||||
maxDuration: 30,
|
||||
camera: 'back',
|
||||
success: (res) => {
|
||||
if (res.tempFiles && res.tempFiles.length > 0) {
|
||||
const tempFilePath = res.tempFiles[0].tempFilePath;
|
||||
this.setData({
|
||||
'editForm.avatarUrl': tempFilePath,
|
||||
tempAvatarPath: tempFilePath
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('拍照失败:', err);
|
||||
wx.showToast({
|
||||
title: '拍照失败',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 验证编辑表单
|
||||
*/
|
||||
validateEditForm(): boolean {
|
||||
const { name, phone, role } = this.data.editForm;
|
||||
|
||||
if (!name.trim()) {
|
||||
this.setData({
|
||||
errorMessage: '请输入员工姓名'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!phone.trim()) {
|
||||
this.setData({
|
||||
errorMessage: '请输入员工工号'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 简单的工号格式验证
|
||||
const phoneRegex = /^\d+$/;
|
||||
if (!phoneRegex.test(phone)) {
|
||||
this.setData({
|
||||
errorMessage: '工号只能包含数字'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!role) {
|
||||
this.setData({
|
||||
errorMessage: '请选择员工角色'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* 取消编辑
|
||||
*/
|
||||
cancelEdit() {
|
||||
this.setData({
|
||||
currentTab: 'list',
|
||||
errorMessage: '',
|
||||
successMessage: ''
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑表单输入处理
|
||||
*/
|
||||
onEditFormInput(e: any) {
|
||||
const { field } = e.currentTarget.dataset;
|
||||
const value = e.detail.value;
|
||||
|
||||
this.setData({
|
||||
[`editForm.${field}`]: value,
|
||||
errorMessage: '',
|
||||
successMessage: ''
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理编辑角色选择
|
||||
*/
|
||||
onEditRoleChange(e: any) {
|
||||
const index = e.detail.value;
|
||||
const selectedRole = this.data.roleOptions[index].value;
|
||||
this.setData({
|
||||
'editForm.role': selectedRole
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除员工
|
||||
*/
|
||||
@@ -304,19 +588,8 @@ Page({
|
||||
return [];
|
||||
}
|
||||
|
||||
// 获取当前登录用户信息
|
||||
const app = getApp();
|
||||
const currentUser = app.globalData.userInfo;
|
||||
|
||||
// 过滤掉当前登录用户
|
||||
let filteredEmployees = employees.filter(emp => {
|
||||
// 如果没有当前用户信息,显示所有员工
|
||||
if (!currentUser || !currentUser.id) {
|
||||
return true;
|
||||
}
|
||||
// 过滤掉当前用户
|
||||
return emp.id !== currentUser.id;
|
||||
});
|
||||
// 显示所有员工,包括当前用户
|
||||
let filteredEmployees = employees;
|
||||
|
||||
// 更严格的搜索关键词检查
|
||||
if (!searchKeyword || typeof searchKeyword !== 'string' || !searchKeyword.trim()) {
|
||||
|
||||
@@ -30,6 +30,13 @@
|
||||
>
|
||||
<text class="tab-text">添加员工</text>
|
||||
</view>
|
||||
<view
|
||||
class="tab-item {{currentTab === 'edit' ? 'active' : ''}}"
|
||||
bindtap="switchTab"
|
||||
data-tab="edit"
|
||||
>
|
||||
<text class="tab-text">编辑员工</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 消息提示 -->
|
||||
@@ -70,21 +77,32 @@
|
||||
<view wx:for="{{filteredEmployees}}" wx:key="id" class="employee-item">
|
||||
<view class="employee-info">
|
||||
<view class="employee-avatar">
|
||||
<text class="avatar-text">{{item.name.charAt(0)}}</text>
|
||||
<image wx:if="{{item.fullAvatarUrl}}" class="avatar-image" src="{{item.fullAvatarUrl}}" mode="aspectFill"></image>
|
||||
<view wx:else class="avatar-placeholder">
|
||||
<text class="avatar-text">{{item.name.charAt(0)}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="employee-details">
|
||||
<view class="employee-name-row">
|
||||
<text class="employee-name">{{item.name}}</text>
|
||||
<text class="employee-role {{item.role === 'ADMIN' ? 'admin-role' : ''}}">
|
||||
<text class="role-icon">{{item.role === 'ADMIN' ? '👑' : '🚚'}}</text>
|
||||
{{getRoleText(item.role)}}
|
||||
</text>
|
||||
<view class="employee-role {{item.role === 'ADMIN' ? 'admin-role' : ''}}">
|
||||
<text class="role-icon">👤</text>
|
||||
<text>{{item.role === 'ADMIN' ? '管理员' : '配送员'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="employee-phone">工号: {{item.phone}}</text>
|
||||
<text class="employee-phone">{{item.phone}}</text>
|
||||
<text class="employee-id">ID: {{item.id}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="employee-actions">
|
||||
<button
|
||||
class="edit-btn"
|
||||
bindtap="editEmployee"
|
||||
data-id="{{item.id}}"
|
||||
size="mini"
|
||||
>
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
class="delete-btn"
|
||||
bindtap="deleteEmployee"
|
||||
@@ -165,4 +183,92 @@
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 编辑员工页面 -->
|
||||
<view wx:if="{{currentTab === 'edit'}}" class="edit-container">
|
||||
<view class="form-container">
|
||||
<view class="form-header">
|
||||
<text class="form-title">编辑员工信息</text>
|
||||
</view>
|
||||
|
||||
<!-- 头像上传区域 -->
|
||||
<view class="form-item">
|
||||
<text class="form-label">员工头像</text>
|
||||
<view class="avatar-upload-container">
|
||||
<view class="avatar-preview">
|
||||
<image wx:if="{{editForm.avatarUrl}}" class="avatar-image" src="{{editForm.avatarUrl}}" mode="aspectFill"></image>
|
||||
<view wx:else class="avatar-placeholder">
|
||||
<text class="avatar-text">{{editForm.name ? editForm.name.charAt(0) : '?'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="avatar-actions">
|
||||
<button class="avatar-btn" bindtap="chooseAvatar" size="mini">选择头像</button>
|
||||
<button class="avatar-btn" bindtap="takePhoto" size="mini">拍照</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">员工姓名</text>
|
||||
<input
|
||||
class="form-input"
|
||||
placeholder="请输入员工姓名"
|
||||
value="{{editForm.name}}"
|
||||
bindinput="onEditFormInput"
|
||||
data-field="name"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">员工工号</text>
|
||||
<input
|
||||
class="form-input"
|
||||
placeholder="请输入员工工号"
|
||||
type="number"
|
||||
value="{{editForm.phone}}"
|
||||
bindinput="onEditFormInput"
|
||||
data-field="phone"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">员工角色</text>
|
||||
<picker
|
||||
class="form-picker"
|
||||
bindchange="onEditRoleChange"
|
||||
range="{{roleOptions}}"
|
||||
range-key="label"
|
||||
>
|
||||
<view class="picker-display">
|
||||
<text class="picker-text">
|
||||
{{editForm.role === 'ADMIN' ? '管理员' : editForm.role === 'DELIVERY_PERSON' ? '配送员' : '请选择角色'}}
|
||||
</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<view class="form-hint">
|
||||
<text class="hint-text">
|
||||
提示:修改员工信息后,用户可以使用新的信息进行绑定
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="form-actions">
|
||||
<button
|
||||
class="submit-btn"
|
||||
bindtap="submitEditForm"
|
||||
disabled="{{loading}}"
|
||||
>
|
||||
{{loading ? '更新中...' : '更新员工'}}
|
||||
</button>
|
||||
<button
|
||||
class="cancel-btn"
|
||||
bindtap="cancelEdit"
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -189,19 +189,22 @@
|
||||
/* 员工列表样式 */
|
||||
.employee-list {
|
||||
flex: 1;
|
||||
padding: 0 40rpx;
|
||||
padding: 0 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.employee-item {
|
||||
background: white;
|
||||
padding: 30rpx;
|
||||
margin: 20rpx 0;
|
||||
padding: 25rpx;
|
||||
margin: 15rpx 0;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
transition: transform 0.3s ease;
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.employee-item:active {
|
||||
@@ -212,45 +215,77 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.employee-avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 25rpx;
|
||||
margin-right: 20rpx;
|
||||
color: white;
|
||||
font-size: 32rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.employee-avatar .avatar-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.employee-avatar .avatar-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
|
||||
.employee-avatar .avatar-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.employee-details {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.employee-name-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10rpx;
|
||||
margin-bottom: 8rpx;
|
||||
gap: 15rpx;
|
||||
}
|
||||
|
||||
.employee-name {
|
||||
font-size: 30rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
flex-shrink: 0;
|
||||
max-width: 200rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.employee-role {
|
||||
font-size: 24rpx;
|
||||
font-size: 22rpx;
|
||||
background: #f0f0f0;
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 16rpx;
|
||||
color: #666;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.employee-role.admin-role {
|
||||
@@ -259,23 +294,30 @@
|
||||
}
|
||||
|
||||
.role-icon {
|
||||
margin-right: 5rpx;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
|
||||
.employee-phone {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-bottom: 5rpx;
|
||||
margin-bottom: 4rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.employee-id {
|
||||
font-size: 22rpx;
|
||||
font-size: 20rpx;
|
||||
color: #999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.employee-actions {
|
||||
margin-left: 20rpx;
|
||||
margin-left: 15rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
@@ -392,4 +434,80 @@
|
||||
|
||||
.submit-btn:disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* 头像上传样式 */
|
||||
.avatar-upload-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 30rpx;
|
||||
}
|
||||
|
||||
.avatar-preview {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background: #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2rpx solid #ddd;
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
|
||||
.avatar-text {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.avatar-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15rpx;
|
||||
}
|
||||
|
||||
.avatar-btn {
|
||||
background: #f8f9fa;
|
||||
border: 1rpx solid #ddd;
|
||||
color: #333;
|
||||
padding: 15rpx 20rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.avatar-btn:active {
|
||||
background: #e9ecef;
|
||||
}
|
||||
|
||||
/* 编辑页面样式 */
|
||||
.edit-container {
|
||||
flex: 1;
|
||||
padding: 40rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
width: 100%;
|
||||
background: #f8f9fa;
|
||||
color: #666;
|
||||
border: 1rpx solid #ddd;
|
||||
padding: 30rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
7
miniprogram/pages/staff/profile.json
Normal file
7
miniprogram/pages/staff/profile.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "个人信息",
|
||||
"navigationStyle": "custom",
|
||||
"enablePullDownRefresh": true,
|
||||
"backgroundColor": "#f5f5f5"
|
||||
}
|
||||
218
miniprogram/pages/staff/profile.ts
Normal file
218
miniprogram/pages/staff/profile.ts
Normal file
@@ -0,0 +1,218 @@
|
||||
// 个人信息页面
|
||||
import { UserInfo } from '../../types';
|
||||
import userService from '../../services/userService';
|
||||
import statisticsService from '../../services/statisticsService';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
userInfo: null as UserInfo | null,
|
||||
// 个人统计数据
|
||||
personalStats: {
|
||||
totalOrders: 0, // 总订单数
|
||||
completedOrders: 0, // 已完成订单数
|
||||
pendingOrders: 0, // 待处理订单数
|
||||
deliveryRate: 0, // 配送成功率
|
||||
averageTime: 0 // 平均配送时间
|
||||
},
|
||||
// 系统统计数据
|
||||
systemStats: {
|
||||
employeeCount: 0, // 员工总数
|
||||
orderCount: 0, // 订单总数
|
||||
warehouseCount: 0 // 仓库总数
|
||||
},
|
||||
loading: true
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.loadUserInfo();
|
||||
this.loadStatistics();
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// 页面显示时重新加载数据
|
||||
this.loadUserInfo();
|
||||
this.loadStatistics();
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载用户信息
|
||||
*/
|
||||
async loadUserInfo() {
|
||||
try {
|
||||
const app = getApp<any>();
|
||||
if (app.globalData.userInfo) {
|
||||
this.setData({
|
||||
userInfo: app.globalData.userInfo
|
||||
});
|
||||
} else {
|
||||
// 如果没有全局用户信息,尝试从API获取
|
||||
const userInfo = await userService.getUserInfo();
|
||||
this.setData({ userInfo });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载用户信息失败:', error);
|
||||
wx.showToast({
|
||||
title: '加载用户信息失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载统计数据
|
||||
*/
|
||||
async loadStatistics() {
|
||||
this.setData({ loading: true });
|
||||
|
||||
try {
|
||||
wx.showLoading({
|
||||
title: '加载统计数据...'
|
||||
});
|
||||
|
||||
// 强制刷新统计数据,不使用缓存
|
||||
const systemStats = await statisticsService.getSystemStats(true);
|
||||
|
||||
// 获取个人统计数据(这里需要根据用户ID获取个人统计数据)
|
||||
const personalStats = await this.getPersonalStats();
|
||||
|
||||
this.setData({
|
||||
systemStats: {
|
||||
employeeCount: systemStats.employeeCount,
|
||||
orderCount: systemStats.orderCount,
|
||||
warehouseCount: systemStats.warehouseCount
|
||||
},
|
||||
personalStats,
|
||||
loading: false
|
||||
});
|
||||
|
||||
wx.hideLoading();
|
||||
} catch (error) {
|
||||
console.error('加载统计数据失败:', error);
|
||||
this.setData({ loading: false });
|
||||
wx.hideLoading();
|
||||
|
||||
wx.showToast({
|
||||
title: '加载统计数据失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取个人统计数据
|
||||
*/
|
||||
async getPersonalStats() {
|
||||
try {
|
||||
// 这里应该调用个人统计API
|
||||
// 暂时使用模拟数据
|
||||
return {
|
||||
totalOrders: 156,
|
||||
completedOrders: 142,
|
||||
pendingOrders: 14,
|
||||
deliveryRate: 91.0,
|
||||
averageTime: 45
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('获取个人统计数据失败:', error);
|
||||
// 返回默认值
|
||||
return {
|
||||
totalOrders: 0,
|
||||
completedOrders: 0,
|
||||
pendingOrders: 0,
|
||||
deliveryRate: 0,
|
||||
averageTime: 0
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 刷新数据
|
||||
*/
|
||||
onRefresh() {
|
||||
this.loadStatistics();
|
||||
},
|
||||
|
||||
/**
|
||||
* 返回上一页
|
||||
*/
|
||||
goBack() {
|
||||
wx.navigateBack();
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑个人信息
|
||||
*/
|
||||
onEditProfile() {
|
||||
wx.showToast({
|
||||
title: '编辑功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查看历史订单
|
||||
*/
|
||||
onViewHistory() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/staff/order-management'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 联系客服
|
||||
*/
|
||||
onContactSupport() {
|
||||
wx.makePhoneCall({
|
||||
phoneNumber: '400-123-4567'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
onLogout() {
|
||||
wx.showModal({
|
||||
title: '确认退出',
|
||||
content: '确定要退出登录吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.performLogout();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 执行退出登录操作
|
||||
*/
|
||||
async performLogout() {
|
||||
try {
|
||||
wx.showLoading({
|
||||
title: '退出中...'
|
||||
});
|
||||
|
||||
// 调用用户服务的退出登录方法
|
||||
const userService = require('../../services/userService').default;
|
||||
await userService.logout();
|
||||
|
||||
// 清除全局用户信息
|
||||
const app = getApp<any>();
|
||||
app.globalData.userInfo = null;
|
||||
|
||||
wx.hideLoading();
|
||||
|
||||
// 跳转到首页
|
||||
wx.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('退出登录失败:', error);
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
title: '退出登录失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
120
miniprogram/pages/staff/profile.wxml
Normal file
120
miniprogram/pages/staff/profile.wxml
Normal file
@@ -0,0 +1,120 @@
|
||||
<!-- 个人信息页面 -->
|
||||
<view class="profile-container">
|
||||
<!-- 顶部导航栏 -->
|
||||
<view class="profile-header">
|
||||
<view class="header-left">
|
||||
<!-- 微信风格返回按钮 -->
|
||||
<view class="back-icon" bindtap="goBack">
|
||||
<text class="back-arrow">‹</text>
|
||||
</view>
|
||||
<view class="profile-avatar">👤</view>
|
||||
<view class="profile-info">
|
||||
<text class="profile-name">{{userInfo.name || '用户'}}</text>
|
||||
<text class="profile-role">{{userInfo.role === 'ADMIN' ? '管理员' : '员工'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="header-right">
|
||||
<button class="refresh-btn" bindtap="onRefresh">刷新</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view wx:if="{{loading}}" class="loading-container">
|
||||
<view class="loading-spinner"></view>
|
||||
<text class="loading-text">正在加载数据...</text>
|
||||
</view>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<view wx:else class="profile-content">
|
||||
<!-- 个人信息卡片 -->
|
||||
<view class="info-card">
|
||||
<view class="card-header">
|
||||
<text class="card-title">个人信息</text>
|
||||
<button class="edit-btn" bindtap="onEditProfile">编辑</button>
|
||||
</view>
|
||||
<view class="info-grid">
|
||||
<view class="info-item">
|
||||
<text class="info-label">姓名</text>
|
||||
<text class="info-value">{{userInfo.name || '未设置'}}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">手机号</text>
|
||||
<text class="info-value">{{userInfo.phone || '未设置'}}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">角色</text>
|
||||
<text class="info-value">{{userInfo.role === 'ADMIN' ? '管理员' : '员工'}}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">用户ID</text>
|
||||
<text class="info-value">{{userInfo.id || '未知'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 个人统计卡片 -->
|
||||
<view class="stats-card">
|
||||
<view class="card-header">
|
||||
<text class="card-title">个人工作统计</text>
|
||||
<button class="history-btn" bindtap="onViewHistory">查看历史</button>
|
||||
</view>
|
||||
<view class="stats-grid">
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon">📦</view>
|
||||
<text class="stat-value">{{personalStats.totalOrders}}</text>
|
||||
<text class="stat-label">总订单数</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon">✅</view>
|
||||
<text class="stat-value">{{personalStats.completedOrders}}</text>
|
||||
<text class="stat-label">已完成</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon">⏳</view>
|
||||
<text class="stat-value">{{personalStats.pendingOrders}}</text>
|
||||
<text class="stat-label">待处理</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon">📊</view>
|
||||
<text class="stat-value">{{personalStats.deliveryRate}}%</text>
|
||||
<text class="stat-label">成功率</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon">⏱️</view>
|
||||
<text class="stat-value">{{personalStats.averageTime}}分钟</text>
|
||||
<text class="stat-label">平均时间</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 系统统计卡片 -->
|
||||
<view class="stats-card">
|
||||
<view class="card-header">
|
||||
<text class="card-title">系统概览</text>
|
||||
</view>
|
||||
<view class="stats-grid">
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon employee-icon">👥</view>
|
||||
<text class="stat-value">{{systemStats.employeeCount}}</text>
|
||||
<text class="stat-label">员工总数</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon order-icon">📦</view>
|
||||
<text class="stat-value">{{systemStats.orderCount}}</text>
|
||||
<text class="stat-label">订单总数</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon warehouse-icon">🏭</view>
|
||||
<text class="stat-value">{{systemStats.warehouseCount}}</text>
|
||||
<text class="stat-label">仓库数量</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 功能按钮区域 -->
|
||||
<view class="action-buttons">
|
||||
<button class="action-btn contact-btn" bindtap="onContactSupport">联系客服</button>
|
||||
<button class="action-btn logout-btn" bindtap="onLogout">退出登录</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
288
miniprogram/pages/staff/profile.wxss
Normal file
288
miniprogram/pages/staff/profile.wxss
Normal file
@@ -0,0 +1,288 @@
|
||||
/* 个人信息页面样式 */
|
||||
.profile-container {
|
||||
min-height: 100vh;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 顶部导航栏样式 */
|
||||
.profile-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 40rpx 30rpx;
|
||||
background: white;
|
||||
border-bottom: 1rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 50%;
|
||||
background: #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.back-arrow {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.profile-avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
background: #3498db;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 40rpx;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.profile-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.profile-name {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.profile-role {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
background: #f0f0f0;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 12rpx;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.refresh-btn {
|
||||
padding: 15rpx 25rpx;
|
||||
border: none;
|
||||
border-radius: 8rpx;
|
||||
font-size: 26rpx;
|
||||
background: #3498db;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.refresh-btn:active {
|
||||
transform: translateY(1rpx);
|
||||
}
|
||||
|
||||
/* 加载状态样式 */
|
||||
.loading-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 100rpx 0;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 4rpx solid #f3f3f3;
|
||||
border-top: 4rpx solid #3498db;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 主内容区域样式 */
|
||||
.profile-content {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
/* 卡片通用样式 */
|
||||
.info-card, .stats-card {
|
||||
background: white;
|
||||
border-radius: 15rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 15rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.edit-btn, .history-btn {
|
||||
padding: 10rpx 20rpx;
|
||||
border: 1rpx solid #3498db;
|
||||
border-radius: 6rpx;
|
||||
font-size: 24rpx;
|
||||
background: transparent;
|
||||
color: #3498db;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.edit-btn:active, .history-btn:active {
|
||||
background: #3498db;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 信息网格样式 */
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.info-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 统计网格样式 */
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
background: #f8f9fa;
|
||||
padding: 25rpx;
|
||||
border-radius: 10rpx;
|
||||
text-align: center;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.stat-item:active {
|
||||
transform: translateY(-2rpx);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
font-size: 40rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.employee-icon {
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
.order-icon {
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.warehouse-icon {
|
||||
color: #f39c12;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 功能按钮区域样式 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 25rpx;
|
||||
border: none;
|
||||
border-radius: 10rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.contact-btn {
|
||||
background: #27ae60;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
background: #e74c3c;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.action-btn:active {
|
||||
transform: translateY(1rpx);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 750rpx) {
|
||||
.stats-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.profile-header {
|
||||
padding: 30rpx 20rpx;
|
||||
}
|
||||
|
||||
.profile-content {
|
||||
padding: 20rpx;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ Page({
|
||||
filteredWarehouses: [] as WarehouseInfo[],
|
||||
|
||||
// 页面状态
|
||||
currentTab: 'list', // list: 列表页, add: 添加页
|
||||
currentTab: 'list', // list: 列表页, add: 添加页, edit: 编辑页
|
||||
loading: false,
|
||||
|
||||
// 添加仓库表单数据
|
||||
@@ -25,6 +25,20 @@ Page({
|
||||
latitude: 24.880095
|
||||
},
|
||||
|
||||
// 编辑仓库表单数据
|
||||
editForm: {
|
||||
id: 0,
|
||||
name: '',
|
||||
address: '',
|
||||
contact: '',
|
||||
phone: '',
|
||||
description: '',
|
||||
capacity: 500,
|
||||
longitude: 102.833722,
|
||||
latitude: 24.880095,
|
||||
status: 'open' as 'open' | 'closed' | 'maintenance'
|
||||
},
|
||||
|
||||
// 错误信息
|
||||
errorMessage: '',
|
||||
successMessage: '',
|
||||
@@ -41,8 +55,10 @@ Page({
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// 页面显示时刷新数据
|
||||
this.loadWarehouses();
|
||||
// 只在页面显示时检查是否需要刷新数据,避免频繁请求
|
||||
if (this.data.warehouses.length === 0) {
|
||||
this.loadWarehouses();
|
||||
}
|
||||
},
|
||||
|
||||
// 加载仓库列表
|
||||
@@ -145,6 +161,51 @@ Page({
|
||||
});
|
||||
},
|
||||
|
||||
// 经度输入处理
|
||||
onLongitudeInput(e: any) {
|
||||
const value = parseFloat(e.detail.value) || 0;
|
||||
this.setData({
|
||||
'addForm.longitude': value
|
||||
});
|
||||
},
|
||||
|
||||
// 纬度输入处理
|
||||
onLatitudeInput(e: any) {
|
||||
const value = parseFloat(e.detail.value) || 0;
|
||||
this.setData({
|
||||
'addForm.latitude': value
|
||||
});
|
||||
},
|
||||
|
||||
// 地图选点功能
|
||||
pickLocationFromMap() {
|
||||
console.log('开始地图选点...');
|
||||
wx.chooseLocation({
|
||||
success: (res) => {
|
||||
console.log('地图选点成功:', res);
|
||||
if (res.longitude && res.latitude) {
|
||||
console.log('更新表单数据 - 经度:', res.longitude, '纬度:', res.latitude);
|
||||
this.setData({
|
||||
'addForm.longitude': res.longitude,
|
||||
'addForm.latitude': res.latitude
|
||||
});
|
||||
console.log('表单数据更新后:', this.data.addForm);
|
||||
wx.showToast({
|
||||
title: '位置已选择',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('地图选点失败:', error);
|
||||
wx.showToast({
|
||||
title: '选点失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 验证表单
|
||||
validateForm(): boolean {
|
||||
const { name, address, contact, phone } = this.data.addForm;
|
||||
@@ -237,6 +298,168 @@ Page({
|
||||
});
|
||||
},
|
||||
|
||||
// 取消编辑
|
||||
cancelEdit() {
|
||||
this.setData({
|
||||
currentTab: 'list',
|
||||
errorMessage: '',
|
||||
successMessage: ''
|
||||
});
|
||||
},
|
||||
|
||||
// 编辑表单输入处理
|
||||
onEditNameInput(e: any) {
|
||||
this.setData({
|
||||
'editForm.name': e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
onEditAddressInput(e: any) {
|
||||
this.setData({
|
||||
'editForm.address': e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
onEditContactInput(e: any) {
|
||||
this.setData({
|
||||
'editForm.contact': e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
onEditPhoneInput(e: any) {
|
||||
this.setData({
|
||||
'editForm.phone': e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
onEditDescriptionInput(e: any) {
|
||||
this.setData({
|
||||
'editForm.description': e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
onEditCapacityInput(e: any) {
|
||||
this.setData({
|
||||
'editForm.capacity': parseInt(e.detail.value) || 500
|
||||
});
|
||||
},
|
||||
|
||||
onEditLongitudeInput(e: any) {
|
||||
this.setData({
|
||||
'editForm.longitude': parseFloat(e.detail.value) || 102.833722
|
||||
});
|
||||
},
|
||||
|
||||
onEditLatitudeInput(e: any) {
|
||||
this.setData({
|
||||
'editForm.latitude': parseFloat(e.detail.value) || 24.880095
|
||||
});
|
||||
},
|
||||
|
||||
onEditStatusChange(e: any) {
|
||||
this.setData({
|
||||
'editForm.status': e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 编辑仓库
|
||||
editWarehouse(e: any) {
|
||||
const warehouseId = e.currentTarget.dataset.id;
|
||||
const warehouse = this.data.warehouses.find(w => w.id === warehouseId);
|
||||
|
||||
if (warehouse) {
|
||||
this.setData({
|
||||
editForm: {
|
||||
id: warehouse.id || 0,
|
||||
name: warehouse.name || '',
|
||||
address: warehouse.address || '',
|
||||
contact: warehouse.contact || '',
|
||||
phone: warehouse.phone || '',
|
||||
description: warehouse.description || '',
|
||||
capacity: warehouse.capacity || 500,
|
||||
longitude: warehouse.longitude || 102.833722,
|
||||
latitude: warehouse.latitude || 24.880095,
|
||||
status: warehouse.status || 'open'
|
||||
},
|
||||
currentTab: 'edit'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 提交编辑仓库表单
|
||||
async submitEditForm() {
|
||||
this.setData({
|
||||
errorMessage: '',
|
||||
successMessage: ''
|
||||
});
|
||||
|
||||
if (!this.validateEditForm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setData({
|
||||
loading: true
|
||||
});
|
||||
|
||||
try {
|
||||
// 使用updateWarehouse更新仓库信息
|
||||
await warehouseService.updateWarehouse(this.data.editForm.id, this.data.editForm);
|
||||
|
||||
this.setData({
|
||||
loading: false,
|
||||
successMessage: '仓库更新成功',
|
||||
currentTab: 'list'
|
||||
});
|
||||
|
||||
// 重新加载仓库列表
|
||||
this.loadWarehouses();
|
||||
|
||||
showToast('仓库更新成功');
|
||||
|
||||
} catch (error) {
|
||||
console.error('更新仓库失败:', error);
|
||||
this.setData({
|
||||
loading: false,
|
||||
errorMessage: '更新仓库失败,请重试'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 验证编辑表单
|
||||
validateEditForm(): boolean {
|
||||
const { name, address, contact, phone } = this.data.editForm;
|
||||
|
||||
if (!name.trim()) {
|
||||
this.setData({
|
||||
errorMessage: '请输入仓库名称'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!address.trim()) {
|
||||
this.setData({
|
||||
errorMessage: '请输入仓库地址'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!contact?.trim()) {
|
||||
this.setData({
|
||||
errorMessage: '请输入联系人'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!phone?.trim()) {
|
||||
this.setData({
|
||||
errorMessage: '请输入联系电话'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
// 删除仓库
|
||||
async deleteWarehouse(e: any) {
|
||||
const warehouseId = e.currentTarget.dataset.id;
|
||||
|
||||
@@ -49,6 +49,13 @@
|
||||
>
|
||||
<text>添加仓库</text>
|
||||
</view>
|
||||
<view
|
||||
class="tab-item {{currentTab === 'edit' ? 'active' : ''}}"
|
||||
data-tab="edit"
|
||||
bindtap="switchTab"
|
||||
>
|
||||
<text>编辑仓库</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 仓库列表页面 -->
|
||||
@@ -86,11 +93,18 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="warehouse-actions">
|
||||
<button
|
||||
class="edit-btn"
|
||||
data-id="{{item.id}}"
|
||||
bindtap="editWarehouse"
|
||||
size="mini"
|
||||
>编辑</button>
|
||||
<button
|
||||
class="delete-btn"
|
||||
data-id="{{item.id}}"
|
||||
data-name="{{item.name}}"
|
||||
bindtap="deleteWarehouse"
|
||||
size="mini"
|
||||
>删除</button>
|
||||
</view>
|
||||
</view>
|
||||
@@ -192,6 +206,33 @@
|
||||
type="number"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">坐标位置</text>
|
||||
<view class="coordinate-inputs">
|
||||
<view class="coordinate-row">
|
||||
<text class="coordinate-label">经度:</text>
|
||||
<input
|
||||
class="coordinate-input"
|
||||
placeholder="请输入经度"
|
||||
bindinput="onLongitudeInput"
|
||||
value="{{addForm.longitude}}"
|
||||
type="digit"
|
||||
/>
|
||||
</view>
|
||||
<view class="coordinate-row">
|
||||
<text class="coordinate-label">纬度:</text>
|
||||
<input
|
||||
class="coordinate-input"
|
||||
placeholder="请输入纬度"
|
||||
bindinput="onLatitudeInput"
|
||||
value="{{addForm.latitude}}"
|
||||
type="digit"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<button class="map-pick-btn" bindtap="pickLocationFromMap">地图选点</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-section">
|
||||
@@ -216,4 +257,127 @@
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 编辑仓库页面 -->
|
||||
<view wx:if="{{currentTab === 'edit'}}" class="edit-page">
|
||||
<scroll-view class="form-container" scroll-y>
|
||||
<view class="form-section">
|
||||
<text class="section-title">编辑仓库信息</text>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">仓库名称 *</text>
|
||||
<input
|
||||
class="form-input"
|
||||
placeholder="请输入仓库名称"
|
||||
bindinput="onEditNameInput"
|
||||
value="{{editForm.name}}"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">仓库地址 *</text>
|
||||
<input
|
||||
class="form-input"
|
||||
placeholder="请输入仓库地址"
|
||||
bindinput="onEditAddressInput"
|
||||
value="{{editForm.address}}"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">联系人 *</text>
|
||||
<input
|
||||
class="form-input"
|
||||
placeholder="请输入联系人姓名"
|
||||
bindinput="onEditContactInput"
|
||||
value="{{editForm.contact}}"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">联系电话 *</text>
|
||||
<input
|
||||
class="form-input"
|
||||
placeholder="请输入联系电话"
|
||||
bindinput="onEditPhoneInput"
|
||||
value="{{editForm.phone}}"
|
||||
type="number"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">仓库容量</text>
|
||||
<input
|
||||
class="form-input"
|
||||
placeholder="请输入仓库容量(件数)"
|
||||
bindinput="onEditCapacityInput"
|
||||
value="{{editForm.capacity}}"
|
||||
type="number"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">坐标位置</text>
|
||||
<view class="coordinate-inputs">
|
||||
<view class="coordinate-row">
|
||||
<text class="coordinate-label">经度:</text>
|
||||
<input
|
||||
class="coordinate-input"
|
||||
placeholder="请输入经度"
|
||||
bindinput="onEditLongitudeInput"
|
||||
value="{{editForm.longitude}}"
|
||||
type="digit"
|
||||
/>
|
||||
</view>
|
||||
<view class="coordinate-row">
|
||||
<text class="coordinate-label">纬度:</text>
|
||||
<input
|
||||
class="coordinate-input"
|
||||
placeholder="请输入纬度"
|
||||
bindinput="onEditLatitudeInput"
|
||||
value="{{editForm.latitude}}"
|
||||
type="digit"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<button class="map-pick-btn" bindtap="pickLocationFromMap">地图选点</button>
|
||||
</view>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">仓库状态</text>
|
||||
<picker
|
||||
class="form-picker"
|
||||
range="{{['营业中', '已关闭', '维护中']}}"
|
||||
value="{{editForm.status === 'open' ? 0 : editForm.status === 'closed' ? 1 : 2}}"
|
||||
bindchange="onEditStatusChange"
|
||||
>
|
||||
<view class="picker-value">
|
||||
{{editForm.status === 'open' ? '营业中' : editForm.status === 'closed' ? '已关闭' : '维护中'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-section">
|
||||
<text class="section-title">其他信息</text>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">仓库描述</text>
|
||||
<textarea
|
||||
class="form-textarea"
|
||||
placeholder="请输入仓库描述信息(可选)"
|
||||
bindinput="onEditDescriptionInput"
|
||||
value="{{editForm.description}}"
|
||||
maxlength="200"
|
||||
/>
|
||||
<text class="textarea-counter">{{editForm.description ? editForm.description.length : 0}}/200</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-actions">
|
||||
<button class="submit-btn" bindtap="submitEditForm">更新仓库</button>
|
||||
<button class="cancel-btn" bindtap="cancelEdit">取消</button>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -148,39 +148,45 @@
|
||||
|
||||
/* 列表页面样式 */
|
||||
.list-page {
|
||||
padding: 30rpx;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 搜索框 */
|
||||
.search-container {
|
||||
margin-bottom: 30rpx;
|
||||
padding: 30rpx 40rpx;
|
||||
background: white;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.search-input-wrapper {
|
||||
position: relative;
|
||||
background: white;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx 60rpx 20rpx 30rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
padding: 25rpx 60rpx 25rpx 30rpx;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 仓库列表 */
|
||||
.warehouse-list {
|
||||
max-height: calc(100vh - 400rpx);
|
||||
flex: 1;
|
||||
padding: 0 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
@@ -198,46 +204,99 @@
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
/* 空文本样式占位 */
|
||||
}
|
||||
|
||||
/* 坐标输入样式 */
|
||||
.coordinate-inputs {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.coordinate-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.coordinate-label {
|
||||
width: 120rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.coordinate-input {
|
||||
flex: 1;
|
||||
border: 1rpx solid #e8e8e8;
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.map-pick-btn {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.map-pick-btn:active {
|
||||
background: #5a6fd8;
|
||||
}
|
||||
|
||||
.map-pick-btn {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.warehouse-item {
|
||||
background: white;
|
||||
padding: 25rpx;
|
||||
margin: 15rpx 0;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.warehouse-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20rpx;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.warehouse-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.warehouse-name {
|
||||
font-size: 32rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 10rpx;
|
||||
margin-bottom: 8rpx;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.warehouse-status {
|
||||
display: flex;
|
||||
gap: 10rpx;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
padding: 6rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 22rpx;
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 16rpx;
|
||||
font-size: 20rpx;
|
||||
font-weight: 500;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.status-badge.open {
|
||||
@@ -260,38 +319,43 @@
|
||||
|
||||
.warehouse-actions {
|
||||
display: flex;
|
||||
gap: 10rpx;
|
||||
gap: 8rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
background: #ff4757;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12rpx 20rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 24rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
/* 仓库详情 */
|
||||
.warehouse-details {
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
padding-top: 20rpx;
|
||||
padding-top: 15rpx;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
display: flex;
|
||||
margin-bottom: 12rpx;
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 10rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
color: #666;
|
||||
min-width: 120rpx;
|
||||
min-width: 100rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
color: #333;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.inventory-status {
|
||||
|
||||
Reference in New Issue
Block a user