From d94d4cd9d82e364f5bcaa9be5605a3ff167a710d Mon Sep 17 00:00:00 2001
From: yangmf_0726 <13243152557@163.com>
Date: Sat, 8 Nov 2025 11:24:22 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E8=B4=A7=E9=81=93=E5=A4=8D=E5=88=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/views/Login/components/LoginForm.vue | 46 ++++++++++
src/views/mall/product/channel/index.vue | 104 ++++++++++++++++++++++-
2 files changed, 147 insertions(+), 3 deletions(-)
diff --git a/src/views/Login/components/LoginForm.vue b/src/views/Login/components/LoginForm.vue
index 89893417..7c554e99 100644
--- a/src/views/Login/components/LoginForm.vue
+++ b/src/views/Login/components/LoginForm.vue
@@ -264,10 +264,32 @@ const handleLogin = async (params: any) => {
}
const loginDataLoginForm = { ...loginData.loginForm }
loginDataLoginForm.captchaVerification = params.captchaVerification
+
+ // 打印登录信息
+ console.log('========== 用户登录信息 ==========')
+ console.log('登录表单数据:', {
+ username: loginDataLoginForm.username,
+ tenantName: loginDataLoginForm.tenantName,
+ rememberMe: loginDataLoginForm.rememberMe,
+ captchaVerification: loginDataLoginForm.captchaVerification ? '已填写' : '未填写'
+ })
+
const res = await LoginApi.login(loginDataLoginForm)
if (!res) {
return
}
+
+ // 打印登录返回的Token信息
+ console.log('登录返回Token信息:', {
+ id: res.id,
+ userId: res.userId,
+ userType: res.userType,
+ clientId: res.clientId,
+ expiresTime: res.expiresTime ? new Date(res.expiresTime).toLocaleString() : '无',
+ accessToken: res.accessToken ? `${res.accessToken.substring(0, 20)}...` : '无',
+ refreshToken: res.refreshToken ? `${res.refreshToken.substring(0, 20)}...` : '无'
+ })
+
loading.value = ElLoading.service({
lock: true,
text: '正在加载系统中...',
@@ -279,6 +301,30 @@ const handleLogin = async (params: any) => {
authUtil.removeLoginForm()
}
authUtil.setToken(res)
+
+ // 获取用户详细信息并打印
+ try {
+ const userInfo = await LoginApi.getInfo()
+ console.log('用户详细信息:', {
+ 用户ID: userInfo.user?.id,
+ 用户名: userInfo.user?.username,
+ 昵称: userInfo.user?.nickname,
+ 头像: userInfo.user?.avatar,
+ 部门ID: userInfo.user?.deptId,
+ 邮箱: userInfo.user?.email,
+ 手机号: userInfo.user?.mobile,
+ 性别: userInfo.user?.sex,
+ 登录IP: userInfo.user?.loginIp,
+ 登录时间: userInfo.user?.loginDate,
+ 角色: userInfo.roles,
+ 权限数量: userInfo.permissions?.length || 0
+ })
+ console.log('所有权限:', userInfo.permissions)
+ console.log('菜单列表:', userInfo.menus)
+ } catch (error) {
+ console.error('获取用户信息失败:', error)
+ }
+ console.log('================================')
if (!redirect.value) {
redirect.value = '/'
}
diff --git a/src/views/mall/product/channel/index.vue b/src/views/mall/product/channel/index.vue
index ff4b5788..76258991 100644
--- a/src/views/mall/product/channel/index.vue
+++ b/src/views/mall/product/channel/index.vue
@@ -70,10 +70,12 @@
- 新增
+ 复制
-
+
+
@@ -154,6 +163,8 @@ const { t } = useI18n() // 国际化
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据
const total = ref(0) // 列表的总页数
+const selectedRows = ref([]) // 选中的货道
+const copyLoading = ref(false) // 复制操作的加载中
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
@@ -174,6 +185,8 @@ const getList = async () => {
const data = await ChannelApi.getChannelPage(queryParams)
list.value = data.list
total.value = data.total
+ // 清空选中状态(因为列表数据已更新)
+ selectedRows.value = []
} finally {
loading.value = false
}
@@ -191,6 +204,91 @@ const resetQuery = () => {
handleQuery()
}
+/** 处理表格选择变化 */
+const handleSelectionChange = (selection: ChannelVO[]) => {
+ selectedRows.value = selection
+}
+
+/** 查找可用的货道号 */
+const findAvailableChannel = async (originalChannel: string, deviceId: string): Promise => {
+ // 获取所有货道列表用于检查
+ const allChannels = await ChannelApi.getChannelPage({ pageNo: 1, pageSize: 100 })
+ const existingChannels = allChannels.list
+ .filter((ch: ChannelVO) => ch.deviceId === deviceId)
+ .map((ch: ChannelVO) => ch.cabinetChannel)
+
+ // 解析原始货道号(可能是纯数字或包含其他字符)
+ const match = originalChannel.match(/(\d+)$/)
+ if (!match) {
+ // 如果无法解析数字,直接返回原值加1
+ return originalChannel + '1'
+ }
+
+ const baseNumber = parseInt(match[1], 10)
+ const prefix = originalChannel.substring(0, originalChannel.length - match[1].length)
+ let newNumber = baseNumber + 1
+
+ // 如果新货道号已存在,继续递增
+ while (existingChannels.includes(prefix + newNumber)) {
+ newNumber++
+ }
+
+ return prefix + newNumber
+}
+
+/** 复制货道 */
+const handleCopy = async () => {
+ if (selectedRows.value.length === 0) {
+ message.warning('请至少选择一个货道进行复制')
+ return
+ }
+
+ try {
+ await message.confirm(`确认要复制选中的 ${selectedRows.value.length} 个货道吗?`)
+ copyLoading.value = true
+
+ // 遍历选中的货道,逐个复制
+ for (const row of selectedRows.value) {
+ try {
+ // 获取货道详情
+ const channelDetail = await ChannelApi.getChannel(row.id)
+
+ // 查找可用的货道号(在原有基础上加1,如果存在则继续加1)
+ const newCabinetChannel = await findAvailableChannel(
+ channelDetail.cabinetChannel,
+ channelDetail.deviceId
+ )
+
+ // 准备新货道数据,明确复制指定字段,货道号递增
+ const newChannel = {
+ name: channelDetail.name, // 复制名称
+ maxNum: channelDetail.maxNum, // 复制最大数量
+ deviceId: channelDetail.deviceId, // 复制设备IMEI
+ channelLine: channelDetail.channelLine, // 复制货道行号
+ cabinetChannel: newCabinetChannel // 货道号加一
+ // 编号(id)不复制,由系统自动生成
+ } as ChannelVO
+
+ // 创建新货道
+ await ChannelApi.createChannel(newChannel)
+ } catch (error) {
+ console.error(`复制货道 ${row.name} 失败:`, error)
+ message.error(`复制货道 "${row.name}" 失败`)
+ }
+ }
+
+ message.success(`成功复制 ${selectedRows.value.length} 个货道`)
+ // 清空选中
+ selectedRows.value = []
+ // 刷新列表
+ await getList()
+ } catch {
+ // 用户取消操作
+ } finally {
+ copyLoading.value = false
+ }
+}
+
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {