Merge branch 'develop' of https://gitee.com/likeshop_gitee/likeadmin-java into develop
# Conflicts: # app/src/pages.json
This commit is contained in:
commit
89f58728cc
|
|
@ -15,3 +15,38 @@ export function getArticleCate() {
|
||||||
export function getArticleList(data: Record<string, any>) {
|
export function getArticleList(data: Record<string, any>) {
|
||||||
return request.get({ url: '/article/list', data: data })
|
return request.get({ url: '/article/list', data: data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取文章详情
|
||||||
|
* @param { number } id
|
||||||
|
* @return { Promise }
|
||||||
|
*/
|
||||||
|
export function getArticleDetail(data: { id: number }) {
|
||||||
|
return request.get({ url: '/article/detail', data: data })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 加入收藏
|
||||||
|
* @param { number } articleId
|
||||||
|
* @return { Promise }
|
||||||
|
*/
|
||||||
|
export function addCollect(data: { articleId: number }) {
|
||||||
|
return request.post({ url: '/article/addCollect', data: data })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 取消收藏
|
||||||
|
* @param { number } id
|
||||||
|
* @return { Promise }
|
||||||
|
*/
|
||||||
|
export function cancelCollect(data: { articleId: number }) {
|
||||||
|
return request.post({ url: '/article/cancelCollect', data: data })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取收藏列表
|
||||||
|
* @return { Promise }
|
||||||
|
*/
|
||||||
|
export function getCollect() {
|
||||||
|
return request.get({ url: '/article/collect' })
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<navigator :url="`/pages/news_detail/news_detail?id=${item.id}`">
|
<navigator :url="`/pages/news_detail/news_detail?id=${ newsId }`">
|
||||||
<view class="news-card flex bg-white px-[20rpx] py-[32rpx]">
|
<view class="news-card flex bg-white px-[20rpx] py-[32rpx]">
|
||||||
<view class="mr-[20rpx]" v-if="item.image">
|
<view class="mr-[20rpx]" v-if="item.image">
|
||||||
<u-image :src="item.image" width="240" height="180"></u-image>
|
<u-image :src="item.image" width="240" height="180"></u-image>
|
||||||
|
|
@ -24,9 +24,11 @@
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
const props = withDefaults(defineProps < {
|
const props = withDefaults(defineProps < {
|
||||||
item: any
|
item: any,
|
||||||
|
newsId: number
|
||||||
} > (), {
|
} > (), {
|
||||||
item: {}
|
item: {},
|
||||||
|
newsId: ''
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,13 @@
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "个人设置"
|
"navigationBarTitleText": "个人设置"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/collection/collection",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的收藏"
|
||||||
|
}
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
<template>
|
||||||
|
<z-paging ref="paging" v-model="collectData" @query="queryList" :fixed="false" height="100%"
|
||||||
|
use-page-scroll>
|
||||||
|
|
||||||
|
<u-swipe-action :show="item.show" :index="index" v-for="(item, index) in collectData" :key="item.id"
|
||||||
|
@click="handleCollect" :options="options" btn-width="120">
|
||||||
|
<news-card :item="item" :newsId="item.articleId"></news-card>
|
||||||
|
</u-swipe-action>
|
||||||
|
</z-paging>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, shallowRef } from 'vue';
|
||||||
|
import { getCollect, cancelCollect } from "@/api/news"
|
||||||
|
|
||||||
|
|
||||||
|
const paging = shallowRef()
|
||||||
|
const options = reactive([{
|
||||||
|
text: '取消收藏',
|
||||||
|
style: {
|
||||||
|
color: '#FFFFFF',
|
||||||
|
backgroundColor: '#FF2C3C'
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
const collectData: any = ref([])
|
||||||
|
|
||||||
|
const queryList = async (pageNo, pageSize) => {
|
||||||
|
const { lists } = await getCollect()
|
||||||
|
lists.forEach(item => {
|
||||||
|
item.show = false
|
||||||
|
})
|
||||||
|
collectData.value = lists
|
||||||
|
paging.value.complete(lists);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCollect = async (index: number): Promise<void> => {
|
||||||
|
try{
|
||||||
|
const articleId: number = collectData.value[index].articleId
|
||||||
|
await cancelCollect({ articleId })
|
||||||
|
paging.value.reload()
|
||||||
|
}catch(err){
|
||||||
|
//TODO handle the exception
|
||||||
|
console.log('取消收藏报错=>', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<z-paging ref="paging" v-model="dataList" v-if="i == index" @query="queryList" :fixed="false" height="100%"
|
<z-paging ref="paging" v-model="dataList" v-if="i == index" @query="queryList" :fixed="false" height="100%"
|
||||||
use-page-scroll>
|
use-page-scroll>
|
||||||
<block v-for="(newsItem,newsIndex) in dataList" :key="newsIndex">
|
<block v-for="(newsItem,newsIndex) in dataList" :key="newsIndex">
|
||||||
<news-card :item="newsItem"></news-card>
|
<news-card :item="newsItem" :newsId="newsItem.id"></news-card>
|
||||||
</block>
|
</block>
|
||||||
</z-paging>
|
</z-paging>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,95 @@
|
||||||
<template>
|
<template>
|
||||||
</template>
|
<view class="news-detail bg-white" >
|
||||||
|
<!-- 标题信心 -->
|
||||||
|
<view class="news-detail-header py-[20rpx] px-[30rpx]">
|
||||||
|
<view class="text-3xl font-medium">{{ newsData.title }}</view>
|
||||||
|
<view class="flex mt-[20rpx] text-xs">
|
||||||
|
<view class="mr-[40rpx]" v-if="newsData.author">作者: {{ newsData.author }}</view>
|
||||||
|
<view class="text-muted mr-[40rpx]">{{ newsData.createTime }}</view>
|
||||||
|
<view class="flex items-center text-muted ">
|
||||||
|
<image src="/static/images/icon_visit.png" class="w-[30rpx] h-[30rpx]"></image>
|
||||||
|
<view class="ml-[10rpx]">{{ newsData.visit }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 咨询内容 -->
|
||||||
|
<view class="news-detail-section bg-white p-[20rpx]">
|
||||||
|
<!-- 摘要 -->
|
||||||
|
<view class="summary p-[20rpx] text-base" v-if="newsData.summary">
|
||||||
|
摘要: {{ newsData.summary }}
|
||||||
|
</view>
|
||||||
|
<!-- 封面 -->
|
||||||
|
<view class="mt-[20rpx]" v-if="newsData.image">
|
||||||
|
<image class="w-full" :src="newsData.image" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
<!-- 内容 -->
|
||||||
|
<view class="mt-[20rpx]">
|
||||||
|
<u-parse :html="newsData.content"></u-parse>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="panel-btn flex items-center px-[34rpx]" @click="handleAddCollect(newsData.id)">
|
||||||
|
<u-icon :name="newsData.collect ? 'star-fill' : 'star'" size="36"></u-icon>
|
||||||
|
<text class="ml-[10rpx]">收藏</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, computed } from "vue"
|
||||||
|
import { onLoad, onShow, onReady } from "@dcloudio/uni-app";
|
||||||
|
import { getArticleDetail, addCollect, cancelCollect } from "@/api/news"
|
||||||
|
|
||||||
<script>
|
|
||||||
</script>
|
const newsData = ref< any >({})
|
||||||
|
let newsId = ''
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
|
const getData = async (id) => {
|
||||||
|
newsData.value = await getArticleDetail({ id })
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddCollect = async (articleId: number) => {
|
||||||
|
try{
|
||||||
|
if( newsData.value.collect ) {
|
||||||
|
await cancelCollect({ articleId })
|
||||||
|
} else await addCollect({ articleId })
|
||||||
|
getData(newsId)
|
||||||
|
}catch(e){
|
||||||
|
//TODO handle the exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad((options: any) => {
|
||||||
|
newsId = options.id
|
||||||
|
getData(newsId)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.news-detail {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
border-bottom: 2rpx solid #F8F8F8;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-section {
|
||||||
|
.summary {
|
||||||
|
border-radius: 12rpx;
|
||||||
|
background-color: #F7F7F7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-btn {
|
||||||
|
position: fixed;
|
||||||
|
right: 30rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
bottom: 80rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package com.mdd.admin.controller.user;
|
package com.mdd.admin.controller.user;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||||
import com.mdd.admin.service.user.IUserService;
|
import com.mdd.admin.service.user.IUserService;
|
||||||
import com.mdd.admin.validate.common.PageParam;
|
import com.mdd.admin.validate.common.PageParam;
|
||||||
import com.mdd.admin.validate.user.UserInfoParam;
|
|
||||||
import com.mdd.admin.vo.user.UserVo;
|
import com.mdd.admin.vo.user.UserVo;
|
||||||
import com.mdd.common.core.AjaxResult;
|
import com.mdd.common.core.AjaxResult;
|
||||||
import com.mdd.common.core.PageResult;
|
import com.mdd.common.core.PageResult;
|
||||||
|
|
@ -55,12 +55,15 @@ public class UserController {
|
||||||
* 用户编辑
|
* 用户编辑
|
||||||
*
|
*
|
||||||
* @author fzr
|
* @author fzr
|
||||||
* @param userInfoParam 用户参数
|
* @param params 参数
|
||||||
* @return Object
|
* @return Object
|
||||||
*/
|
*/
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
public Object edit(@Validated @RequestBody UserInfoParam userInfoParam) {
|
public Object edit(@RequestBody Map<String, String> params) {
|
||||||
iUserService.edit(userInfoParam);
|
Assert.notNull(params.get("id"), "id参数缺失");
|
||||||
|
Assert.notNull(params.get("field"), "field参数缺失");
|
||||||
|
Assert.notNull(params.get("value"), "value参数缺失");
|
||||||
|
iUserService.edit(params);
|
||||||
return AjaxResult.success();
|
return AjaxResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.mdd.admin.service.user;
|
package com.mdd.admin.service.user;
|
||||||
|
|
||||||
import com.mdd.admin.validate.common.PageParam;
|
import com.mdd.admin.validate.common.PageParam;
|
||||||
import com.mdd.admin.validate.user.UserInfoParam;
|
|
||||||
import com.mdd.admin.vo.user.UserVo;
|
import com.mdd.admin.vo.user.UserVo;
|
||||||
import com.mdd.common.core.PageResult;
|
import com.mdd.common.core.PageResult;
|
||||||
|
|
||||||
|
|
@ -35,8 +34,8 @@ public interface IUserService {
|
||||||
* 用户编辑
|
* 用户编辑
|
||||||
*
|
*
|
||||||
* @author fzr
|
* @author fzr
|
||||||
* @param userInfoParam 参数
|
* @param params 参数
|
||||||
*/
|
*/
|
||||||
void edit(UserInfoParam userInfoParam);
|
void edit(Map<String, String> params);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.mdd.admin.service.user.IUserService;
|
import com.mdd.admin.service.user.IUserService;
|
||||||
import com.mdd.admin.validate.common.PageParam;
|
import com.mdd.admin.validate.common.PageParam;
|
||||||
import com.mdd.admin.validate.user.UserInfoParam;
|
|
||||||
import com.mdd.admin.vo.article.ArticleListVo;
|
|
||||||
import com.mdd.admin.vo.user.UserVo;
|
import com.mdd.admin.vo.user.UserVo;
|
||||||
import com.mdd.common.core.PageResult;
|
import com.mdd.common.core.PageResult;
|
||||||
import com.mdd.common.entity.user.User;
|
import com.mdd.common.entity.user.User;
|
||||||
|
|
@ -17,7 +15,6 @@ import com.mdd.common.mapper.user.UserMapper;
|
||||||
import com.mdd.common.utils.StringUtil;
|
import com.mdd.common.utils.StringUtil;
|
||||||
import com.mdd.common.utils.TimeUtil;
|
import com.mdd.common.utils.TimeUtil;
|
||||||
import com.mdd.common.utils.UrlUtil;
|
import com.mdd.common.utils.UrlUtil;
|
||||||
import org.checkerframework.checker.units.qual.A;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|
@ -136,39 +133,55 @@ public class UserServiceImpl implements IUserService {
|
||||||
* 用户编辑
|
* 用户编辑
|
||||||
*
|
*
|
||||||
* @author fzr
|
* @author fzr
|
||||||
* @param userInfoParam 参数
|
* @param params 参数
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void edit(UserInfoParam userInfoParam) {
|
public void edit(Map<String, String> params) {
|
||||||
User user = userMapper.selectOne(new QueryWrapper<User>()
|
Integer id = Integer.parseInt(params.get("id"));
|
||||||
.eq("id", userInfoParam.getId())
|
String field = params.get("field").trim();
|
||||||
.eq("is_delete", 0)
|
String value = params.get("value").trim();
|
||||||
.last("limit 1"));
|
|
||||||
|
|
||||||
Assert.notNull(user, "用户不存在!");
|
User user = userMapper.selectOne(new QueryWrapper<User>()
|
||||||
|
.eq("id", id)
|
||||||
|
.eq("is_delete", 0)
|
||||||
|
.last("limit 1"));
|
||||||
|
|
||||||
if (!user.getUsername().equals(userInfoParam.getUsername())) {
|
Assert.notNull(user, "用户不存在!");
|
||||||
User u = userMapper.selectOne(new QueryWrapper<User>()
|
|
||||||
.eq("username", userInfoParam.getUsername())
|
switch (field) {
|
||||||
.eq("is_delete", 0)
|
case "username":
|
||||||
.last("limit 1"));
|
if (!user.getUsername().equals(value)) {
|
||||||
System.out.println(u);
|
User u = userMapper.selectOne(new QueryWrapper<User>()
|
||||||
if (StringUtil.isNotNull(u) && !u.getId().equals(userInfoParam.getId())) {
|
.eq("username", value)
|
||||||
throw new OperateException("当前账号已存在!");
|
.eq("is_delete", 0)
|
||||||
|
.last("limit 1"));
|
||||||
|
|
||||||
|
if (StringUtil.isNotNull(u) && !u.getId().equals(id)) {
|
||||||
|
throw new OperateException("当前账号已存在!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
user.setUsername(value);
|
||||||
|
break;
|
||||||
if (!userInfoParam.getMobile().equals("")) {
|
case "realName":
|
||||||
if(!Pattern.matches("^[1][3,4,5,6,7,8,9][0-9]{9}$", userInfoParam.getMobile())){
|
user.setRealName(value);
|
||||||
throw new OperateException("手机号格式不正确!");
|
break;
|
||||||
|
case "sex":
|
||||||
|
user.setSex(Integer.parseInt(value));
|
||||||
|
break;
|
||||||
|
case "mobile":
|
||||||
|
if (!value.equals("")) {
|
||||||
|
if(!Pattern.matches("^[1][3,4,5,6,7,8,9][0-9]{9}$", value)){
|
||||||
|
throw new OperateException("手机号格式不正确!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
user.setMobile(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new OperateException("不被支持的字段类型!");
|
||||||
|
}
|
||||||
|
|
||||||
user.setUsername(userInfoParam.getUsername());
|
user.setUpdateTime(System.currentTimeMillis() / 1000);
|
||||||
user.setRealName(userInfoParam.getRealName());
|
userMapper.updateById(user);
|
||||||
user.setSex(userInfoParam.getSex());
|
|
||||||
user.setMobile(userInfoParam.getMobile());
|
|
||||||
userMapper.updateById(user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
package com.mdd.admin.validate.user;
|
|
||||||
|
|
||||||
import com.mdd.common.validator.annotation.IDMust;
|
|
||||||
import com.mdd.common.validator.annotation.IntegerContains;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
import org.hibernate.validator.constraints.Length;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Pattern;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户信息参数
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = false)
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class UserInfoParam implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@IDMust(message = "id参数必传且需大于0")
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
@NotNull(message = "username参数缺失")
|
|
||||||
@NotEmpty(message = "账号不能为空")
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
@NotNull(message = "realName参数缺失")
|
|
||||||
@NotEmpty(message = "真实名称不能为空")
|
|
||||||
private String realName;
|
|
||||||
|
|
||||||
@NotNull(message = "sex参数缺失")
|
|
||||||
@IntegerContains(values = {0, 1, 2}, message = "请正确选择性别")
|
|
||||||
private Integer sex;
|
|
||||||
|
|
||||||
private String mobile;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -107,10 +107,10 @@ public class ArticleController {
|
||||||
*/
|
*/
|
||||||
@PostMapping("/cancelCollect")
|
@PostMapping("/cancelCollect")
|
||||||
public Object cancelCollect(@RequestBody Map<String, String> params) {
|
public Object cancelCollect(@RequestBody Map<String, String> params) {
|
||||||
Assert.notNull(params.get("id"), "id参数缺失");
|
Assert.notNull(params.get("articleId"), "id参数缺失");
|
||||||
Integer id = Integer.parseInt(params.get("id"));
|
Integer articleId = Integer.parseInt(params.get("articleId"));
|
||||||
Integer userId = LikeFrontThreadLocal.getUserId();
|
Integer userId = LikeFrontThreadLocal.getUserId();
|
||||||
iArticleService.cancelCollect(id, userId);
|
iArticleService.cancelCollect(articleId, userId);
|
||||||
return AjaxResult.success();
|
return AjaxResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,9 +66,9 @@ public interface IArticleService {
|
||||||
* 取消收藏
|
* 取消收藏
|
||||||
*
|
*
|
||||||
* @author fzr
|
* @author fzr
|
||||||
* @param id 主键
|
* @param articleId 主键
|
||||||
* @param userId 用户ID
|
* @param userId 用户ID
|
||||||
*/
|
*/
|
||||||
void cancelCollect(Integer id, Integer userId);
|
void cancelCollect(Integer articleId, Integer userId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,14 +230,14 @@ public class ArticleServiceImpl implements IArticleService {
|
||||||
* 取消收藏
|
* 取消收藏
|
||||||
*
|
*
|
||||||
* @author fzr
|
* @author fzr
|
||||||
* @param id 主键
|
* @param articleId 文章ID
|
||||||
* @param userId 用户ID
|
* @param userId 用户ID
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void cancelCollect(Integer id, Integer userId) {
|
public void cancelCollect(Integer articleId, Integer userId) {
|
||||||
ArticleCollect articleCollect = articleCollectMapper.selectOne(
|
ArticleCollect articleCollect = articleCollectMapper.selectOne(
|
||||||
new QueryWrapper<ArticleCollect>()
|
new QueryWrapper<ArticleCollect>()
|
||||||
.eq("id", id)
|
.eq("article_id", articleId)
|
||||||
.eq("user_id", userId)
|
.eq("user_id", userId)
|
||||||
.eq("is_delete", 0)
|
.eq("is_delete", 0)
|
||||||
.last("limit 1"));
|
.last("limit 1"));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue