fit:工单修改和商品关联修改
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
# 管理员后台pc端
|
||||||
|
|
||||||
# 007UI 后台管理系统
|
# 007UI 后台管理系统
|
||||||
|
|
||||||
一个基于Vue 3、Element Plus的现代化后台管理系统模板,采用蓝色扁平化高端设计风格。
|
一个基于Vue 3、Element Plus的现代化后台管理系统模板,采用蓝色扁平化高端设计风格。
|
||||||
|
|||||||
@@ -52,3 +52,8 @@ export function timeToTimestamp(time) {
|
|||||||
|
|
||||||
return Math.floor(timestamp / 1000); // 返回毫秒级时间戳(如 1751107200000)
|
return Math.floor(timestamp / 1000); // 返回毫秒级时间戳(如 1751107200000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function reducenum(num){
|
||||||
|
return num / 100
|
||||||
|
}
|
||||||
@@ -69,9 +69,19 @@
|
|||||||
<el-table-column type="selection" width="55" />
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column prop="id" label="ID" width="80" />
|
<el-table-column prop="id" label="ID" width="80" />
|
||||||
<el-table-column prop="discountId" label="代金券ID" width="120" v-if="!codeId" />
|
<el-table-column prop="discountId" label="代金券ID" width="120" v-if="!codeId" />
|
||||||
<el-table-column label="关联对象ID" min-width="150">
|
<el-table-column label="用户名" min-width="150">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.userId || row.userGroupId || '-' }}
|
{{ row?.user?.user_name || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="手机号" min-width="150">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row?.user?.phone || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="邮箱" min-width="150">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row?.user?.email || '-' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="类型" width="120">
|
<el-table-column label="类型" width="120">
|
||||||
@@ -81,11 +91,6 @@
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="创建时间" width="180">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ formatDate(row.CreatedAt) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" width="200" fixed="right">
|
<el-table-column label="操作" width="200" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
@@ -328,25 +333,24 @@ const formatDate = (dateStr) => {
|
|||||||
|
|
||||||
// 获取用户类型名称(根据行数据)
|
// 获取用户类型名称(根据行数据)
|
||||||
const getUserTypeNameByRow = (row) => {
|
const getUserTypeNameByRow = (row) => {
|
||||||
// userId 不为 0 说明是用户
|
|
||||||
if (row.userId && row.userId !== 0) {
|
//通过看是否有user对象参数判断是否为用户还是用户组类型
|
||||||
|
if(row.user){
|
||||||
return '用户'
|
return '用户'
|
||||||
}
|
}else{
|
||||||
// userGroupId 不为 0 说明是用户组
|
|
||||||
if (row.userGroupId && row.userGroupId !== 0) {
|
|
||||||
return '用户组'
|
return '用户组'
|
||||||
}
|
}
|
||||||
|
|
||||||
return '-'
|
return '-'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户类型标签(根据行数据)
|
// 获取用户类型标签(根据行数据)
|
||||||
const getUserTypeTagByRow = (row) => {
|
const getUserTypeTagByRow = (row) => {
|
||||||
// 用户用蓝色
|
|
||||||
if (row.userId && row.userId !== 0) {
|
|
||||||
|
if(row.user){
|
||||||
return 'primary'
|
return 'primary'
|
||||||
}
|
}else{
|
||||||
// 用户组用橙色
|
|
||||||
if (row.userGroupId && row.userGroupId !== 0) {
|
|
||||||
return 'warning'
|
return 'warning'
|
||||||
}
|
}
|
||||||
return 'info'
|
return 'info'
|
||||||
|
|||||||
@@ -82,8 +82,8 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="库存控制" width="100">
|
<el-table-column label="库存控制" width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag :type="row.inventory_control ? 'success' : 'info'">
|
<el-tag :type="row.inventoryControl ? 'success' : 'info'">
|
||||||
{{ row.inventory_control ? '已启用' : '未启用' }}
|
{{ row.inventoryControl ? '已启用' : '未启用' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -125,6 +125,7 @@
|
|||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
:title="dialogType === 'add' ? '新增商品' : '编辑商品'"
|
:title="dialogType === 'add' ? '新增商品' : '编辑商品'"
|
||||||
width="700px"
|
width="700px"
|
||||||
|
style="margin-top: 300px;"
|
||||||
>
|
>
|
||||||
<el-form
|
<el-form
|
||||||
ref="productFormRef"
|
ref="productFormRef"
|
||||||
@@ -154,8 +155,8 @@
|
|||||||
<el-form-item label="封面ID" prop="cover_id">
|
<el-form-item label="封面ID" prop="cover_id">
|
||||||
<el-input-number v-model="productForm.cover_id" :min="0" placeholder="请输入封面ID" style="width: 100%" />
|
<el-input-number v-model="productForm.cover_id" :min="0" placeholder="请输入封面ID" style="width: 100%" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="库存控制" prop="inventory_control">
|
<el-form-item label="库存控制" prop="inventoryControl">
|
||||||
<el-switch v-model="productForm.inventory_control" active-text="启用" inactive-text="禁用" />
|
<el-switch v-model="productForm.inventoryControl" active-text="启用" inactive-text="禁用" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="库存数量" prop="inventory">
|
<el-form-item label="库存数量" prop="inventory">
|
||||||
<el-input-number v-model="productForm.inventory" :min="0" placeholder="请输入库存" style="width: 100%" />
|
<el-input-number v-model="productForm.inventory" :min="0" placeholder="请输入库存" style="width: 100%" />
|
||||||
@@ -498,6 +499,7 @@ const handleAdd = () => {
|
|||||||
|
|
||||||
// 编辑商品
|
// 编辑商品
|
||||||
const handleEdit = (row) => {
|
const handleEdit = (row) => {
|
||||||
|
console.log("更新:",row)
|
||||||
dialogType.value = 'edit'
|
dialogType.value = 'edit'
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
Object.assign(productForm, {
|
Object.assign(productForm, {
|
||||||
@@ -507,7 +509,7 @@ const handleEdit = (row) => {
|
|||||||
content: row.content,
|
content: row.content,
|
||||||
cover_id: row.coverId,
|
cover_id: row.coverId,
|
||||||
good_group_id: row.goodGroupId,
|
good_group_id: row.goodGroupId,
|
||||||
inventory_control: row.inventory_control,
|
inventory_control: row.inventoryControl,
|
||||||
inventory: row.inventory,
|
inventory: row.inventory,
|
||||||
price: row.price,
|
price: row.price,
|
||||||
pay_num: row.payNum,
|
pay_num: row.payNum,
|
||||||
@@ -603,10 +605,12 @@ const submitForm = () => {
|
|||||||
good_group_id: Number(productForm.good_group_id), // 确保是数字类型
|
good_group_id: Number(productForm.good_group_id), // 确保是数字类型
|
||||||
cover_id: productForm.cover_id || 0,
|
cover_id: productForm.cover_id || 0,
|
||||||
inventory: productForm.inventory || 0,
|
inventory: productForm.inventory || 0,
|
||||||
price: productForm.price || 0,
|
price: productForm.price/100 || 0,
|
||||||
pay_num: productForm.pay_num || 1,
|
pay_num: productForm.pay_num || 1,
|
||||||
expire_time: productForm.expire_time || 0,
|
expire_time: productForm.expire_time || 0,
|
||||||
recommend_rebate: productForm.recommend_rebate || 0
|
recommend_rebate: productForm.recommend_rebate || 0,
|
||||||
|
inventory_control:productForm.inventoryControl
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('提交的数据:', submitData) // 调试日志
|
console.log('提交的数据:', submitData) // 调试日志
|
||||||
|
|||||||
+129
-22
@@ -545,7 +545,7 @@ const fetchTicketMessages = async (workId) => {
|
|||||||
id: msg.id,
|
id: msg.id,
|
||||||
content: msg.content !== 'empty' ? msg.content : null,
|
content: msg.content !== 'empty' ? msg.content : null,
|
||||||
images: images,
|
images: images,
|
||||||
time: new Date().toLocaleString(), // API 没有返回时间,使用当前时间
|
time: msg.created_at || msg.updated_at || new Date().toLocaleString(),
|
||||||
isAdmin: isAdminMsg,
|
isAdmin: isAdminMsg,
|
||||||
isSystem: false,
|
isSystem: false,
|
||||||
userId: msg.user?.userId,
|
userId: msg.user?.userId,
|
||||||
@@ -730,42 +730,149 @@ const updateTicketStats = () => {
|
|||||||
|
|
||||||
// 格式化消息时间
|
// 格式化消息时间
|
||||||
const formatMessageTime = (timeStr) => {
|
const formatMessageTime = (timeStr) => {
|
||||||
|
if (!timeStr) return ''
|
||||||
|
|
||||||
|
try {
|
||||||
const date = new Date(timeStr)
|
const date = new Date(timeStr)
|
||||||
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
if (isNaN(date.getTime())) return ''
|
||||||
|
|
||||||
|
// 格式化为 HH:MM
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0')
|
||||||
|
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||||||
|
return `${hours}:${minutes}`
|
||||||
|
} catch (e) {
|
||||||
|
console.error('时间格式化失败:', e)
|
||||||
|
return ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化列表项时间
|
// 格式化列表项时间
|
||||||
const formatTime = (timeStr) => {
|
const formatTime = (timeStr) => {
|
||||||
const date = new Date(timeStr)
|
if (!timeStr) return ''; // 空值兜底
|
||||||
const now = new Date()
|
|
||||||
const diff = now - date
|
|
||||||
|
|
||||||
// 今天内的消息只显示时间
|
// 步骤1:解析中文时间字符串(核心适配点)
|
||||||
if (diff < 24 * 60 * 60 * 1000 && date.getDate() === now.getDate()) {
|
let date;
|
||||||
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
try {
|
||||||
|
// 先尝试原生解析(兼容ISO格式)
|
||||||
|
date = new Date(timeStr);
|
||||||
|
// 若原生解析失败(返回Invalid Date),解析中文格式
|
||||||
|
if (isNaN(date.getTime())) {
|
||||||
|
// 正则提取中文时间的年、月、日、时、分、秒
|
||||||
|
const cnTimeMatch = timeStr.match(
|
||||||
|
/(\d{4})年(\d{1,2})月(\d{1,2})日\s*(上午|下午)\s*(\d{1,2}):(\d{1,2}):(\d{1,2})/
|
||||||
|
);
|
||||||
|
if (cnTimeMatch) {
|
||||||
|
const [, year, month, day, period, hour, minute, second] = cnTimeMatch;
|
||||||
|
// 处理下午/上午的小时转换(12小时制转24小时制)
|
||||||
|
let hour24 = parseInt(hour, 10);
|
||||||
|
if (period === '下午' && hour24 !== 12) {
|
||||||
|
hour24 += 12;
|
||||||
|
}
|
||||||
|
if (period === '上午' && hour24 === 12) {
|
||||||
|
hour24 = 0; // 上午12点转为0点
|
||||||
|
}
|
||||||
|
// 构造日期(月份从0开始,需-1)
|
||||||
|
date = new Date(
|
||||||
|
parseInt(year, 10),
|
||||||
|
parseInt(month, 10) - 1,
|
||||||
|
parseInt(day, 10),
|
||||||
|
hour24,
|
||||||
|
parseInt(minute, 10),
|
||||||
|
parseInt(second, 10)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return '无效时间'; // 既不是ISO也不是中文格式
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('时间解析失败:', e);
|
||||||
|
return '无效时间';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 一周内的显示星期几
|
const now = new Date();
|
||||||
if (diff < 7 * 24 * 60 * 60 * 1000) {
|
const dateTime = date.getTime();
|
||||||
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
const nowTime = now.getTime();
|
||||||
return weekdays[date.getDay()]
|
const diff = nowTime - dateTime;
|
||||||
|
|
||||||
|
// 步骤2:判断“今天”(年/月/日完全一致)
|
||||||
|
const isToday = date.getFullYear() === now.getFullYear() &&
|
||||||
|
date.getMonth() === now.getMonth() &&
|
||||||
|
date.getDate() === now.getDate();
|
||||||
|
|
||||||
|
if (isToday) {
|
||||||
|
// 格式化今天的时间(24小时制,补零)
|
||||||
|
const hour = String(date.getHours()).padStart(2, '0');
|
||||||
|
const minute = String(date.getMinutes()).padStart(2, '0');
|
||||||
|
return `${hour}:${minute}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 其他显示日期
|
// 步骤3:判断“一周内”
|
||||||
return date.toLocaleDateString()
|
const oneWeek = 7 * 24 * 60 * 60 * 1000;
|
||||||
}
|
if (diff < oneWeek) {
|
||||||
|
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
||||||
|
return weekdays[date.getDay()];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤4:格式化其他日期(补零,统一格式:YYYY/MM/DD)
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
return `${year}/${month}/${day}`;
|
||||||
|
};
|
||||||
|
|
||||||
// 格式化日期显示
|
// 格式化日期显示
|
||||||
const formatDate = (timeStr) => {
|
const formatDate = (timeStr) => {
|
||||||
const date = new Date(timeStr)
|
console.log("原始时间字符串:", timeStr);
|
||||||
const now = new Date()
|
if (!timeStr) return ''; // 空值兜底
|
||||||
|
|
||||||
if (date.toDateString() === now.toDateString()) {
|
let date;
|
||||||
return '今天'
|
// 1. 先尝试原生解析(兼容ISO等标准格式)
|
||||||
|
date = new Date(timeStr);
|
||||||
|
|
||||||
|
// 2. 若原生解析失败,专门解析中文时间格式
|
||||||
|
if (isNaN(date.getTime())) {
|
||||||
|
// 正则匹配:xxxx年xx月xx日 上午/下午 xx:xx:xx
|
||||||
|
const cnTimeReg = /(\d{4})年(\d{1,2})月(\d{1,2})日\s*(上午|下午)\s*(\d{1,2}):(\d{1,2}):(\d{1,2})/;
|
||||||
|
const match = timeStr.match(cnTimeReg);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
const [, year, month, day, period, hour, minute, second] = match;
|
||||||
|
// 处理12小时制转24小时制(关键适配)
|
||||||
|
let hour24 = parseInt(hour, 10);
|
||||||
|
if (period === '下午') {
|
||||||
|
hour24 = hour24 === 12 ? 12 : hour24 + 12; // 下午12点=12点,下午1-11点+12
|
||||||
|
} else { // 上午
|
||||||
|
hour24 = hour24 === 12 ? 0 : hour24; // 上午12点=0点,上午1-11点不变
|
||||||
|
}
|
||||||
|
// 手动构造合法的Date对象(月份从0开始,需-1)
|
||||||
|
date = new Date(
|
||||||
|
parseInt(year, 10),
|
||||||
|
parseInt(month, 10) - 1,
|
||||||
|
parseInt(day, 10),
|
||||||
|
hour24,
|
||||||
|
parseInt(minute, 10),
|
||||||
|
parseInt(second, 10)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return '无效时间'; // 非目标格式,返回兜底
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return date.toLocaleDateString()
|
const now = new Date();
|
||||||
}
|
// 3. 对比“今天”(按日期维度,忽略时分秒)
|
||||||
|
const isToday = date.getFullYear() === now.getFullYear() &&
|
||||||
|
date.getMonth() === now.getMonth() &&
|
||||||
|
date.getDate() === now.getDate();
|
||||||
|
|
||||||
|
if (isToday) {
|
||||||
|
return '今天';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 格式化非今天的日期(统一格式,避免环境差异)
|
||||||
|
const formattedDate = `${date.getFullYear()}/${String(date.getMonth() + 1).padStart(2, '0')}/${String(date.getDate()).padStart(2, '0')}`;
|
||||||
|
|
||||||
|
return formattedDate;
|
||||||
|
};
|
||||||
|
|
||||||
// 监听显示工单变化,更新消息和滚动
|
// 监听显示工单变化,更新消息和滚动
|
||||||
watch(currentTicket, (newVal) => {
|
watch(currentTicket, (newVal) => {
|
||||||
@@ -937,7 +1044,7 @@ const refreshTicketMessages = async (workId) => {
|
|||||||
id: msg.id,
|
id: msg.id,
|
||||||
content: msg.content !== 'empty' ? msg.content : null,
|
content: msg.content !== 'empty' ? msg.content : null,
|
||||||
images: images,
|
images: images,
|
||||||
time: new Date().toLocaleString(), // API 没有返回时间,使用当前时间
|
time: msg.created_at || msg.updated_at || new Date().toLocaleString(),
|
||||||
isAdmin: isAdminMsg,
|
isAdmin: isAdminMsg,
|
||||||
isSystem: false,
|
isSystem: false,
|
||||||
userId: msg.user?.userId,
|
userId: msg.user?.userId,
|
||||||
|
|||||||
Reference in New Issue
Block a user