会员
This commit is contained in:
@@ -4,13 +4,17 @@ import com.ruoyi.common.annotation.Log;
|
|||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.entity.ShopUser;
|
import com.ruoyi.common.core.domain.entity.ShopUser;
|
||||||
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.system.service.IShopUserService;
|
import com.ruoyi.system.service.IShopUserService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -25,13 +29,15 @@ import java.util.List;
|
|||||||
@RequestMapping("/back/user")
|
@RequestMapping("/back/user")
|
||||||
public class ShopUserController extends BaseController
|
public class ShopUserController extends BaseController
|
||||||
{
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ShopUserController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IShopUserService shopUserService;
|
private IShopUserService shopUserService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询用户管理列表
|
* 查询用户管理列表
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('system:user:list')")
|
// @PreAuthorize("@ss.hasPermi('system:user:list')")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo list(ShopUser shopUser)
|
public TableDataInfo list(ShopUser shopUser)
|
||||||
{
|
{
|
||||||
@@ -95,4 +101,72 @@ public class ShopUserController extends BaseController
|
|||||||
{
|
{
|
||||||
return toAjax(shopUserService.deleteShopUserByIds(ids));
|
return toAjax(shopUserService.deleteShopUserByIds(ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户在线时长
|
||||||
|
* 客户端每5分钟调用一次,更新数据库在线时长字段online
|
||||||
|
*/
|
||||||
|
@GetMapping("/updateOnlineTime/{online}")
|
||||||
|
public AjaxResult updateOnlineTime(@PathVariable("online") String online)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// 获取当前登录用户
|
||||||
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||||
|
if (loginUser == null || loginUser.getUserId() == null) {
|
||||||
|
return AjaxResult.error("用户未登录或用户ID为空");
|
||||||
|
}
|
||||||
|
ShopUser shopUser = loginUser.getShopUser();
|
||||||
|
|
||||||
|
// 设置在线时长
|
||||||
|
shopUser.setOnline(online);
|
||||||
|
|
||||||
|
// 记录用户在线时长更新日志
|
||||||
|
log.info("更新用户[{}]在线时长: {}", shopUser.getUserId(), online);
|
||||||
|
|
||||||
|
// 调用服务更新用户在线时长
|
||||||
|
int rows = shopUserService.updateUserOnlineTime(shopUser);
|
||||||
|
|
||||||
|
if (rows > 0) {
|
||||||
|
return AjaxResult.success("更新在线时长成功");
|
||||||
|
} else {
|
||||||
|
return AjaxResult.error("更新在线时长失败,用户可能不存在");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新用户在线时长异常", e);
|
||||||
|
return AjaxResult.error("更新在线时长异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新指定用户的在线时长(管理员使用)
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:user:edit')")
|
||||||
|
@PostMapping("/updateUserOnlineTime")
|
||||||
|
public AjaxResult updateUserOnlineTime(@RequestBody ShopUser shopUser)
|
||||||
|
{
|
||||||
|
if (shopUser == null || shopUser.getUserId() == null) {
|
||||||
|
return AjaxResult.error("用户ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shopUser.getOnline() == null) {
|
||||||
|
return AjaxResult.error("在线时长不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 记录用户在线时长更新日志
|
||||||
|
log.info("管理员更新用户[{}]在线时长: {}", shopUser.getUserId(), shopUser.getOnline());
|
||||||
|
|
||||||
|
// 调用服务更新用户在线时长
|
||||||
|
int rows = shopUserService.updateUserOnlineTime(shopUser);
|
||||||
|
|
||||||
|
if (rows > 0) {
|
||||||
|
return AjaxResult.success("更新在线时长成功");
|
||||||
|
} else {
|
||||||
|
return AjaxResult.error("更新在线时长失败,用户可能不存在");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新用户[{}]在线时长异常", shopUser.getUserId(), e);
|
||||||
|
return AjaxResult.error("更新在线时长异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.ruoyi.common.core.domain.entity;
|
|||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import com.ruoyi.common.annotation.Excel;
|
import com.ruoyi.common.annotation.Excel;
|
||||||
@@ -13,6 +14,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
|
|||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
* @date 2025-07-20
|
* @date 2025-07-20
|
||||||
*/
|
*/
|
||||||
|
@Data
|
||||||
public class ActivityInfo extends BaseEntity
|
public class ActivityInfo extends BaseEntity
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -58,119 +60,11 @@ public class ActivityInfo extends BaseEntity
|
|||||||
@Excel(name = "活动图片")
|
@Excel(name = "活动图片")
|
||||||
private String img;
|
private String img;
|
||||||
|
|
||||||
public void setId(String id)
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
{
|
private Date createTIme;
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId()
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
{
|
private Date updateTime;
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name)
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContent(String content)
|
|
||||||
{
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContent()
|
|
||||||
{
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStartTime(Date startTime)
|
|
||||||
{
|
|
||||||
this.startTime = startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getStartTime()
|
|
||||||
{
|
|
||||||
return startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEndTime(Date endTime)
|
|
||||||
{
|
|
||||||
this.endTime = endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getEndTime()
|
|
||||||
{
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreator(String creator)
|
|
||||||
{
|
|
||||||
this.creator = creator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCreator()
|
|
||||||
{
|
|
||||||
return creator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setModify(String modify)
|
|
||||||
{
|
|
||||||
this.modify = modify;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getModify()
|
|
||||||
{
|
|
||||||
return modify;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShelf(Long shelf)
|
|
||||||
{
|
|
||||||
this.shelf = shelf;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getShelf()
|
|
||||||
{
|
|
||||||
return shelf;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsDel(Long isDel)
|
|
||||||
{
|
|
||||||
this.isDel = isDel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getIsDel()
|
|
||||||
{
|
|
||||||
return isDel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setImg(String img)
|
|
||||||
{
|
|
||||||
this.img = img;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getImg()
|
|
||||||
{
|
|
||||||
return img;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
|
||||||
.append("id", getId())
|
|
||||||
.append("name", getName())
|
|
||||||
.append("content", getContent())
|
|
||||||
.append("startTime", getStartTime())
|
|
||||||
.append("endTime", getEndTime())
|
|
||||||
.append("creator", getCreator())
|
|
||||||
.append("modify", getModify())
|
|
||||||
.append("shelf", getShelf())
|
|
||||||
.append("isDel", getIsDel())
|
|
||||||
.append("img", getImg())
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,4 +70,12 @@ public interface ShopUserMapper {
|
|||||||
*/
|
*/
|
||||||
public int deleteShopUserByIds(String[] ids);
|
public int deleteShopUserByIds(String[] ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户在线时长
|
||||||
|
*
|
||||||
|
* @param shopUser 用户信息(包含userId和online字段)
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateUserOnlineTime(ShopUser shopUser);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -61,4 +61,12 @@ public interface IShopUserService
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public int deleteShopUserById(String id);
|
public int deleteShopUserById(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户在线时长
|
||||||
|
*
|
||||||
|
* @param shopUser 用户信息(包含userId和online字段)
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateUserOnlineTime(ShopUser shopUser);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package com.ruoyi.system.service.impl;
|
package com.ruoyi.system.service.impl;
|
||||||
|
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.domain.entity.ShopUser;
|
import com.ruoyi.common.core.domain.entity.ShopUser;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
|
import com.ruoyi.system.config.AliConfig;
|
||||||
import com.ruoyi.system.mapper.ShopUserMapper;
|
import com.ruoyi.system.mapper.ShopUserMapper;
|
||||||
import com.ruoyi.system.service.IShopUserService;
|
import com.ruoyi.system.service.IShopUserService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -18,6 +22,7 @@ import java.util.List;
|
|||||||
@Service
|
@Service
|
||||||
public class ShopUserServiceImpl implements IShopUserService
|
public class ShopUserServiceImpl implements IShopUserService
|
||||||
{
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ShopUserServiceImpl.class);
|
||||||
@Autowired
|
@Autowired
|
||||||
private ShopUserMapper shopUserMapper;
|
private ShopUserMapper shopUserMapper;
|
||||||
|
|
||||||
@@ -94,4 +99,61 @@ public class ShopUserServiceImpl implements IShopUserService
|
|||||||
{
|
{
|
||||||
return shopUserMapper.deleteShopUserById(id);
|
return shopUserMapper.deleteShopUserById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户在线时长
|
||||||
|
*
|
||||||
|
* @param shopUser 用户信息(包含userId和online字段)
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int updateUserOnlineTime(ShopUser shopUser)
|
||||||
|
{
|
||||||
|
if (shopUser == null || shopUser.getUserId() == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先查询用户当前的在线时长
|
||||||
|
ShopUser currentUser = shopUserMapper.selectShopUserByUserId(shopUser.getUserId());
|
||||||
|
if (currentUser == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在原有时长基础上累加新的时长
|
||||||
|
String currentOnline = currentUser.getOnline();
|
||||||
|
String newOnline = shopUser.getOnline();
|
||||||
|
|
||||||
|
// 计算累加后的在线时长
|
||||||
|
double currentOnlineValue = 0;
|
||||||
|
double newOnlineValue = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (currentOnline != null && !currentOnline.isEmpty()) {
|
||||||
|
currentOnlineValue = Double.parseDouble(currentOnline);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newOnline != null && !newOnline.isEmpty()) {
|
||||||
|
// 接口传入的是分钟,需要转换为小时
|
||||||
|
newOnlineValue = Double.parseDouble(newOnline) / 60.0;
|
||||||
|
// 保留两位小数
|
||||||
|
newOnlineValue = Math.round(newOnlineValue * 100) / 100.0;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// 如果解析失败,使用默认值
|
||||||
|
log.error("解析在线时长失败", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 累加时长(数据库中存储的是小时)
|
||||||
|
double totalOnline = currentOnlineValue + newOnlineValue;
|
||||||
|
// 保留两位小数
|
||||||
|
totalOnline = Math.round(totalOnline * 100) / 100.0;
|
||||||
|
|
||||||
|
// 更新用户在线时长
|
||||||
|
ShopUser updateUser = new ShopUser();
|
||||||
|
updateUser.setUserId(shopUser.getUserId());
|
||||||
|
updateUser.setOnline(String.valueOf(totalOnline));
|
||||||
|
updateUser.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
|
||||||
|
return shopUserMapper.updateUserOnlineTime(updateUser);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="shelf" column="shelf" />
|
<result property="shelf" column="shelf" />
|
||||||
<result property="isDel" column="is_del" />
|
<result property="isDel" column="is_del" />
|
||||||
<result property="img" column="img" />
|
<result property="img" column="img" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectActivityInfoVo">
|
<sql id="selectActivityInfoVo">
|
||||||
select id, name, content, start_time, end_time, creator, modify, shelf, is_del, img from activity_info
|
select id, name, content, start_time, end_time, creator, modify, shelf, is_del, img,update_time,create_time from activity_info
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectActivityInfoList" parameterType="ActivityInfo" resultMap="ActivityInfoResult">
|
<select id="selectActivityInfoList" parameterType="ActivityInfo" resultMap="ActivityInfoResult">
|
||||||
|
|||||||
@@ -190,4 +190,14 @@
|
|||||||
<include refid="selectShopUserVo"/>
|
<include refid="selectShopUserVo"/>
|
||||||
where shop_user.user_id = #{userId}
|
where shop_user.user_id = #{userId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 更新用户在线时长 -->
|
||||||
|
<update id="updateUserOnlineTime" parameterType="ShopUser">
|
||||||
|
update shop_user
|
||||||
|
<set>
|
||||||
|
<if test="online != null">online = #{online},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
|
</set>
|
||||||
|
where user_id = #{userId}
|
||||||
|
</update>
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -20,7 +20,7 @@ export function getActivity(id) {
|
|||||||
// 新增活动
|
// 新增活动
|
||||||
export function addActivity(data) {
|
export function addActivity(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/back/activity/add',
|
url: '/back/activity/addActivity',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
@@ -29,8 +29,8 @@ export function addActivity(data) {
|
|||||||
// 修改活动
|
// 修改活动
|
||||||
export function updateActivity(data) {
|
export function updateActivity(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/back/activity/update',
|
url: '/back/activity',
|
||||||
method: 'post',
|
method: 'put',
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,17 @@
|
|||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="活动状态" prop="status">
|
<!-- <el-form-item label="活动状态" prop="status">-->
|
||||||
<el-select v-model="queryParams.status" placeholder="请选择活动状态" clearable>
|
<!-- <el-select v-model="queryParams.status" placeholder="请选择活动状态" clearable>-->
|
||||||
<el-option label="进行中" value="1" />
|
<!-- <el-option label="进行中" value="1" />-->
|
||||||
<el-option label="已结束" value="0" />
|
<!-- <el-option label="已结束" value="0" />-->
|
||||||
<el-option label="未开始" value="2" />
|
<!-- <el-option label="未开始" value="2" />-->
|
||||||
|
<!-- </el-select>-->
|
||||||
|
<!-- </el-form-item>-->
|
||||||
|
<el-form-item label="状态" prop="shelf">
|
||||||
|
<el-select v-model="queryParams.shelf" placeholder="请选择商家状态" clearable>
|
||||||
|
<el-option label="上架" value="1" />
|
||||||
|
<el-option label="下架" value="2" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -26,27 +32,36 @@
|
|||||||
<el-table v-loading="loading" :data="activityList">
|
<el-table v-loading="loading" :data="activityList">
|
||||||
<el-table-column label="序号" align="center" type="index" width="60" />
|
<el-table-column label="序号" align="center" type="index" width="60" />
|
||||||
<el-table-column label="活动名称" align="center" prop="name" :show-overflow-tooltip="true" />
|
<el-table-column label="活动名称" align="center" prop="name" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="活动描述" align="center" prop="description" :show-overflow-tooltip="true" />
|
<el-table-column label="活动内容" align="center" prop="content" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="活动图片" align="center" prop="imageUrl" width="120">
|
<el-table-column label="活动图片" align="center" prop="img" width="120">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-image
|
<el-image
|
||||||
style="width: 60px; height: 60px"
|
style="width: 60px; height: 60px"
|
||||||
:src="getImageUrlMethod(scope.row.imageUrl)"
|
:src="baseUrl + scope.row.img"
|
||||||
:preview-src-list="[getImageUrlMethod(scope.row.imageUrl)]"
|
:preview-src-list="[baseUrl + scope.row.img]"
|
||||||
fit="cover"
|
fit="cover"
|
||||||
|
v-if="scope.row.img"
|
||||||
>
|
>
|
||||||
<div slot="error" class="image-slot">
|
<div slot="error" class="image-slot">
|
||||||
<i class="el-icon-picture-outline"></i>
|
<i class="el-icon-picture-outline"></i>
|
||||||
</div>
|
</div>
|
||||||
</el-image>
|
</el-image>
|
||||||
|
<i class="el-icon-picture-outline" v-else></i>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="开始时间" align="center" prop="startTime" width="120" />
|
<el-table-column label="开始时间" align="center" prop="startTime" width="120" />
|
||||||
<el-table-column label="结束时间" align="center" prop="endTime" width="120" />
|
<el-table-column label="结束时间" align="center" prop="endTime" width="120" />
|
||||||
<el-table-column label="活动状态" align="center" prop="status" width="100">
|
<!-- <el-table-column label="活动状态" align="center" prop="status" width="100">-->
|
||||||
|
<!-- <template slot-scope="scope">-->
|
||||||
|
<!-- <el-tag :type="scope.row.s === '1' ? 'success' : scope.row.status === '2' ? 'warning' : 'info'">-->
|
||||||
|
<!-- {{ scope.row.status === '1' ? '进行中' : scope.row.status === '2' ? '未开始' : '已结束' }}-->
|
||||||
|
<!-- </el-tag>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<!-- </el-table-column>-->
|
||||||
|
<el-table-column label="商家状态" align="center" prop="shelf" width="100">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag :type="scope.row.status === '1' ? 'success' : scope.row.status === '2' ? 'warning' : 'info'">
|
<el-tag :type="scope.row.shelf === '1' ? 'success' : 'danger'">
|
||||||
{{ scope.row.status === '1' ? '进行中' : scope.row.status === '2' ? '未开始' : '已结束' }}
|
{{ scope.row.shelf === '1' ? '上架' : '下架' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -83,21 +98,24 @@
|
|||||||
<el-form-item label="活动名称" prop="name">
|
<el-form-item label="活动名称" prop="name">
|
||||||
<el-input v-model="form.name" placeholder="请输入活动名称" />
|
<el-input v-model="form.name" placeholder="请输入活动名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="活动描述" prop="description">
|
<el-form-item label="活动内容" prop="content">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="form.description"
|
v-model="form.content"
|
||||||
type="textarea"
|
placeholder="请输入活动内容(只能填数字)"
|
||||||
:rows="3"
|
@input="validateNumberInput"
|
||||||
placeholder="请输入活动描述"
|
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="活动图片" prop="imageUrl">
|
<el-form-item label="活动图片" prop="img">
|
||||||
<image-upload
|
<image-upload
|
||||||
v-model="form.imageUrl"
|
v-model="form.img"
|
||||||
:limit="1"
|
:limit="1"
|
||||||
:file-type="['jpg', 'jpeg', 'png', 'gif']"
|
:file-type="['jpg', 'jpeg', 'png', 'gif']"
|
||||||
action="/back/upload/config/file"
|
action="/back/upload/config/file"
|
||||||
|
:data="{type: 'activity'}"
|
||||||
/>
|
/>
|
||||||
|
<div class="el-upload__tip" slot="tip">
|
||||||
|
图片将保存到服务器,请确保上传的图片符合要求
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="开始时间" prop="startTime">
|
<el-form-item label="开始时间" prop="startTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
@@ -117,11 +135,10 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="活动状态" prop="status">
|
<el-form-item label="商家状态" prop="shelf">
|
||||||
<el-radio-group v-model="form.status">
|
<el-radio-group v-model="form.shelf">
|
||||||
<el-radio label="0">已结束</el-radio>
|
<el-radio label="1">上架</el-radio>
|
||||||
<el-radio label="1">进行中</el-radio>
|
<el-radio label="2">下架</el-radio>
|
||||||
<el-radio label="2">未开始</el-radio>
|
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="活动链接" prop="activityUrl">
|
<el-form-item label="活动链接" prop="activityUrl">
|
||||||
@@ -140,10 +157,26 @@
|
|||||||
import { listActivity, getActivity, delActivity, addActivity, updateActivity } from "@/api/activity/activity";
|
import { listActivity, getActivity, delActivity, addActivity, updateActivity } from "@/api/activity/activity";
|
||||||
import { getImageUrl } from "@/utils/image";
|
import { getImageUrl } from "@/utils/image";
|
||||||
|
|
||||||
|
// 获取服务器基础URL
|
||||||
|
const baseUrl = process.env.VUE_APP_BASE_API || '';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Activity",
|
name: "Activity",
|
||||||
data() {
|
data() {
|
||||||
|
// 验证结束时间必须大于开始时间
|
||||||
|
const validateEndTime = (rule, value, callback) => {
|
||||||
|
if (value && this.form.startTime) {
|
||||||
|
if (new Date(value) <= new Date(this.form.startTime)) {
|
||||||
|
callback(new Error('结束时间必须大于开始时间'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
|
baseUrl: process.env.VUE_APP_BASE_API,
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 选中数组
|
// 选中数组
|
||||||
@@ -167,26 +200,42 @@ export default {
|
|||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
name: null,
|
name: null,
|
||||||
status: null
|
status: null,
|
||||||
|
shelf: null
|
||||||
},
|
},
|
||||||
// 表单参数
|
// 表单参数
|
||||||
form: {},
|
form: {
|
||||||
|
id: null,
|
||||||
|
name: null,
|
||||||
|
content: null,
|
||||||
|
img: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
status: "1",
|
||||||
|
shelf: "1",
|
||||||
|
activityUrl: null
|
||||||
|
},
|
||||||
// 表单校验
|
// 表单校验
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: "活动名称不能为空", trigger: "blur" }
|
{ required: true, message: "活动名称不能为空", trigger: "blur" }
|
||||||
],
|
],
|
||||||
description: [
|
content: [
|
||||||
{ required: true, message: "活动描述不能为空", trigger: "blur" }
|
{ required: true, message: "活动内容不能为空", trigger: "blur" },
|
||||||
|
{ pattern: /^\d+$/, message: "活动内容只能填数字", trigger: "blur" }
|
||||||
|
],
|
||||||
|
img: [
|
||||||
|
{ required: true, message: "活动图片不能为空", trigger: "change" }
|
||||||
],
|
],
|
||||||
startTime: [
|
startTime: [
|
||||||
{ required: true, message: "开始时间不能为空", trigger: "change" }
|
{ required: true, message: "开始时间不能为空", trigger: "change" }
|
||||||
],
|
],
|
||||||
endTime: [
|
endTime: [
|
||||||
{ required: true, message: "结束时间不能为空", trigger: "change" }
|
{ required: true, message: "结束时间不能为空", trigger: "change" },
|
||||||
|
{ validator: validateEndTime, trigger: "change" }
|
||||||
],
|
],
|
||||||
status: [
|
shelf: [
|
||||||
{ required: true, message: "活动状态不能为空", trigger: "change" }
|
{ required: true, message: "商家状态不能为空", trigger: "change" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -214,11 +263,12 @@ export default {
|
|||||||
this.form = {
|
this.form = {
|
||||||
id: null,
|
id: null,
|
||||||
name: null,
|
name: null,
|
||||||
description: null,
|
content: null,
|
||||||
imageUrl: null,
|
img: null,
|
||||||
startTime: null,
|
startTime: null,
|
||||||
endTime: null,
|
endTime: null,
|
||||||
status: "1",
|
status: "1",
|
||||||
|
shelf: "1",
|
||||||
activityUrl: null
|
activityUrl: null
|
||||||
};
|
};
|
||||||
this.resetForm("form");
|
this.resetForm("form");
|
||||||
@@ -251,6 +301,22 @@ export default {
|
|||||||
const id = row.id || this.ids
|
const id = row.id || this.ids
|
||||||
getActivity(id).then(response => {
|
getActivity(id).then(response => {
|
||||||
this.form = response.data;
|
this.form = response.data;
|
||||||
|
// 确保图片URL正确处理,用于回显
|
||||||
|
if (this.form.img) {
|
||||||
|
// 如果img不是完整URL,则处理为相对路径
|
||||||
|
if (this.form.img.startsWith('http://') || this.form.img.startsWith('https://')) {
|
||||||
|
// 完整URL保持不变
|
||||||
|
} else {
|
||||||
|
// 确保路径格式正确,移除baseUrl前缀(如果有)
|
||||||
|
if (this.form.img.startsWith(baseUrl)) {
|
||||||
|
this.form.img = this.form.img.substring(baseUrl.length);
|
||||||
|
}
|
||||||
|
// 确保路径不以/开头(因为上传组件期望的是相对路径)
|
||||||
|
if (this.form.img.startsWith('/')) {
|
||||||
|
this.form.img = this.form.img.substring(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
this.open = true;
|
this.open = true;
|
||||||
this.title = "修改活动";
|
this.title = "修改活动";
|
||||||
});
|
});
|
||||||
@@ -287,7 +353,26 @@ export default {
|
|||||||
},
|
},
|
||||||
// 获取图片完整URL的方法
|
// 获取图片完整URL的方法
|
||||||
getImageUrlMethod(imagePath) {
|
getImageUrlMethod(imagePath) {
|
||||||
return getImageUrl(imagePath);
|
if (!imagePath) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已经是完整URL,直接返回
|
||||||
|
if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) {
|
||||||
|
return imagePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保路径以/开头
|
||||||
|
if (!imagePath.startsWith('/')) {
|
||||||
|
imagePath = '/' + imagePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回完整URL
|
||||||
|
return baseUrl + imagePath;
|
||||||
|
},
|
||||||
|
// 验证活动内容只能输入数字
|
||||||
|
validateNumberInput() {
|
||||||
|
this.form.content = this.form.content.replace(/[^\d]/g, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<el-table-column label="昵称" align="center" prop="nickname" :show-overflow-tooltip="true" />
|
<el-table-column label="昵称" align="center" prop="nickname" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="性别" align="center" prop="gender" width="60">
|
<el-table-column label="性别" align="center" prop="gender" width="60">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ scope.row.gender === 1 ? '男' : '女' }}</span>
|
<span>{{ scope.row.gender === '1' ? '男' : scope.row.gender === '2' ? '女' : '未知' }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="生日" align="center" prop="birthday" width="100">
|
<el-table-column label="生日" align="center" prop="birthday" width="100">
|
||||||
@@ -42,14 +42,14 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="状态" align="center" prop="status" width="80">
|
<el-table-column label="状态" align="center" prop="status" width="80">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'" size="mini">
|
<el-tag :type="scope.row.status === '1' ? 'success' : 'danger'" size="mini">
|
||||||
{{ scope.row.status === 1 ? '正常' : '黑名单' }}
|
{{ scope.row.status === '1' ? '正常' : '黑名单' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="会员状态" align="center" prop="vipStatus" width="100">
|
<el-table-column label="会员状态" align="center" prop="vipStatus" width="100">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ scope.row.vipStatus === 1 ? 'vip' : '普通用户' }}</span>
|
<span>{{ scope.row.vipStatus === '1' ? 'vip' : '普通用户' }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="播放标签" align="center" prop="playTag" width="100">
|
<el-table-column label="播放标签" align="center" prop="playTag" width="100">
|
||||||
@@ -57,9 +57,9 @@
|
|||||||
<el-tag type="warning" size="mini">{{ scope.row.playTag }}</el-tag>
|
<el-tag type="warning" size="mini">{{ scope.row.playTag }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="本周在线时长" align="center" prop="onlineTime" width="120">
|
<el-table-column label="本周在线时长" align="center" prop="online" width="120">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ scope.row.onlineTime }}小时</span>
|
<span>{{ scope.row.online }}小时</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120">
|
||||||
@@ -67,10 +67,10 @@
|
|||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
type="text"
|
type="text"
|
||||||
:style="{ color: scope.row.status === 1 ? '#F56C6C' : '#67C23A' }"
|
:style="{ color: scope.row.status === '1' ? '#F56C6C' : '#67C23A' }"
|
||||||
@click="handleStatusChange(scope.row)"
|
@click="handleStatusChange(scope.row)"
|
||||||
>
|
>
|
||||||
{{ scope.row.status === 1 ? '加入黑名单' : '取消加入黑名单' }}
|
{{ scope.row.status === '1' ? '加入黑名单' : '取消加入黑名单' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -134,8 +134,8 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 状态修改 */
|
/** 状态修改 */
|
||||||
handleStatusChange(row) {
|
handleStatusChange(row) {
|
||||||
const statusText = row.status === 1 ? "加入黑名单" : "取消加入黑名单";
|
const statusText = row.status === '1' ? "加入黑名单" : "取消加入黑名单";
|
||||||
const newStatus = row.status === 1 ? 0 : 1;
|
const newStatus = row.status === '1' ? '2' : '1';
|
||||||
|
|
||||||
this.$modal.confirm('确认要' + statusText + '用户"' + row.nickname + '"吗?').then(function() {
|
this.$modal.confirm('确认要' + statusText + '用户"' + row.nickname + '"吗?').then(function() {
|
||||||
return updateUserStatus(row.id, newStatus);
|
return updateUserStatus(row.id, newStatus);
|
||||||
|
|||||||
Reference in New Issue
Block a user