ss
jiangping
2025-07-04 0bf3f3967322f09ec83051b93309866d2ef091c9
ss
已添加8个文件
已修改3个文件
672 ■■■■■ 文件已修改
admin/src/api/business/seo.js 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaSeoWindow.vue 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/seo.vue 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/api/business/SeoController.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/dao/business/SeoMapper.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/dao/business/model/Information.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/dao/business/model/Seo.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/service/business/SeoService.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/service/business/impl/CarouselServiceImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/service/business/impl/InformationServiceImpl.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/service/business/impl/SeoServiceImpl.java 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/seo.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
import request from '../../utils/request'
// æŸ¥è¯¢
export function fetchList (data) {
  return request.post('/business/seo/page', data, {
    trim: true
  })
}
// åˆ›å»º
export function create (data) {
  return request.post('/business/seo/create', data)
}
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/business/seo/updateById', data)
}
// åˆ é™¤
export function deleteById (id) {
  return request.get(`/business/seo/delete/${id}`)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
  return request.get('/business/seo/delete/batch', {
    params: {
      ids
    }
  })
}
admin/src/components/business/OperaSeoWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
<template>
  <GlobalWindow
    :title="title"
    :visible.sync="visible"
    :confirm-working="isWorking"
    @confirm="confirm"
  >
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="页面名称" prop="name">
        <el-input v-model="form.name" placeholder="请输入页面名称" v-trim/>
      </el-form-item>
      <el-form-item label="页面地址" prop="pageAddr">
        <el-input v-model="form.pageAddr" placeholder="请输入页面地址(/default.html è¡¨ç¤ºç½‘站默认配置项)" v-trim/>
      </el-form-item>
      <el-form-item label="标题" prop="title">
        <el-input v-model="form.title" placeholder="请输入标题" v-trim/>
      </el-form-item>
      <el-form-item label="关键字" prop="keywords">
        <el-input type="textarea" v-model="form.keywords" placeholder="请输入关键字" v-trim/>
      </el-form-item>
      <el-form-item label="作者信息" prop="author">
        <el-input v-model="form.author" placeholder="请输入作者信息" v-trim/>
      </el-form-item>
      <el-form-item label="排序码(升序)" prop="sortnum">
        <el-input v-model="form.sortnum" type="number" placeholder="请输入排序码" v-trim/>
      </el-form-item>
      <el-form-item label="描述" prop="remark">
        <el-input v-model="form.remark" type="textarea" placeholder="请输入描述" v-trim/>
      </el-form-item>
      <el-form-item label="图片alt" prop="imgalt">
        <el-input v-model="form.imgalt" placeholder="请输入图片alt" v-trim/>
      </el-form-item>
    </el-form>
  </GlobalWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
export default {
  name: 'OperaSeoWindow',
  extends: BaseOpera,
  components: { GlobalWindow },
  data () {
    return {
      // è¡¨å•数据
      form: {
        id: null,
        remark: '',
        name: '',
        title: '',
        keywords: '',
        author: '',
        icon: '',
        pageAddr: '',
        sortnum: '',
        imgalt: ''
      },
      // éªŒè¯è§„则
      rules: {
      }
    }
  },
  created () {
    this.config({
      api: '/business/seo',
      'field.id': 'id'
    })
  }
}
</script>
admin/src/views/business/seo.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
<template>
  <TableLayout :permissions="['business:seo:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="页面名称" prop="name">
        <el-input v-model="searchForm.name" placeholder="请输入页面名称" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="标题" prop="title">
        <el-input v-model="searchForm.title" placeholder="请输入标题" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="关键字" prop="keywords">
        <el-input v-model="searchForm.keywords" placeholder="请输入关键字" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="页面地址" prop="pageAddr">
        <el-input v-model="searchForm.pageAddr" placeholder="请输入页面地址" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <section>
        <el-button type="primary" @click="search">搜索</el-button>
        <el-button @click="reset">重置</el-button>
      </section>
    </el-form>
    <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
    <template v-slot:table-wrap>
      <ul class="toolbar" v-permissions="['business:seo:create', 'business:seo:delete']">
        <li><el-button type="primary" @click="$refs.operaSeoWindow.open('新建网站SEO配置')" icon="el-icon-plus" v-permissions="['business:seo:create']">新建</el-button></li>
        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:seo:delete']">删除</el-button></li>
      </ul>
      <el-table
        v-loading="isWorking.search"
        :data="tableData.list"
        stripe
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="name" label="页面名称" min-width="100px"></el-table-column>
        <el-table-column prop="title" label="标题" min-width="100px"></el-table-column>
        <el-table-column prop="keywords" label="关键字" min-width="150px"></el-table-column>
        <el-table-column prop="author" label="作者信息" min-width="100px"></el-table-column>
        <el-table-column prop="pageAddr" label="页面地址" min-width="150px"></el-table-column>
        <el-table-column prop="remark" label="描述" min-width="100px"></el-table-column>
        <el-table-column prop="imgalt" label="图片alt" min-width="100px"></el-table-column>
        <el-table-column prop="sortnum" label="排序码" min-width="100px"></el-table-column>
        <el-table-column prop="editDate" label="操作时间" min-width="150px"></el-table-column>
        <el-table-column prop="editorName" label="操作人" min-width="100px"></el-table-column>
        <el-table-column
          v-if="containPermissions(['business:seo:update', 'business:seo:delete'])"
          label="操作"
          min-width="120"
          fixed="right"
        >
          <template slot-scope="{row}">
            <el-button type="text" @click="$refs.operaSeoWindow.open('编辑网站SEO配置', row)" icon="el-icon-edit" v-permissions="['business:seo:update']">编辑</el-button>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:seo:delete']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
        :pagination="tableData.pagination"
      >
      </pagination>
    </template>
    <!-- æ–°å»º/修改 -->
    <OperaSeoWindow ref="operaSeoWindow" @success="handlePageChange"/>
  </TableLayout>
</template>
<script>
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import OperaSeoWindow from '@/components/business/OperaSeoWindow'
export default {
  name: 'Seo',
  extends: BaseTable,
  components: { TableLayout, Pagination, OperaSeoWindow },
  data () {
    return {
      // æœç´¢
      searchForm: {
        name: '',
        title: '',
        keywords: '',
        author: '',
        pageAddr: ''
      }
    }
  },
  created () {
    this.config({
      module: '网站SEO配置',
      api: '/business/seo',
      'field.id': 'id',
      'field.main': 'id'
    })
    this.search()
  }
}
</script>
server/src/main/java/com/doumee/api/business/SeoController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
package com.doumee.api.business;
import com.doumee.api.BaseController;
import com.doumee.core.annotation.excel.ExcelExporter;
import com.doumee.core.annotation.pr.PreventRepeat;
import com.doumee.core.model.ApiResponse;
import com.doumee.core.model.PageWrap;
import com.doumee.core.model.PageData;
import com.doumee.dao.business.model.Seo;
import com.doumee.service.business.SeoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
 * @author æ±Ÿè¹„蹄
 * @since 2025/07/02 11:35
 */
@Api(tags = "网站SEO配置")
@RestController
@RequestMapping("/business/seo")
public class SeoController extends BaseController {
    @Autowired
    private SeoService seoService;
    @PreventRepeat
    @ApiOperation("新建")
    @PostMapping("/create")
    @RequiresPermissions("business:seo:create")
    public ApiResponse create(@RequestBody Seo seo) {
        return ApiResponse.success(seoService.create(seo));
    }
    @ApiOperation("根据ID删除")
    @GetMapping("/delete/{id}")
    @RequiresPermissions("business:seo:delete")
    public ApiResponse deleteById(@PathVariable Integer id) {
        seoService.deleteById(id);
        return ApiResponse.success(null);
    }
    @ApiOperation("批量删除")
    @GetMapping("/delete/batch")
    @RequiresPermissions("business:seo:delete")
    public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
        seoService.deleteByIdInBatch(this.getIdList(ids));
        return ApiResponse.success(null);
    }
    @ApiOperation("根据ID修改")
    @PostMapping("/updateById")
    @RequiresPermissions("business:seo:update")
    public ApiResponse updateById(@RequestBody Seo seo) {
        seoService.updateById(seo);
        return ApiResponse.success(null);
    }
    @ApiOperation("分页查询")
    @PostMapping("/page")
    @RequiresPermissions("business:seo:query")
    public ApiResponse<PageData<Seo>> findPage (@RequestBody PageWrap<Seo> pageWrap) {
        return ApiResponse.success(seoService.findPage(pageWrap));
    }
    @ApiOperation("导出Excel")
    @PostMapping("/exportExcel")
    @RequiresPermissions("business:seo:exportExcel")
    public void exportExcel (@RequestBody PageWrap<Seo> pageWrap, HttpServletResponse response) {
        ExcelExporter.build(Seo.class).export(seoService.findPage(pageWrap).getRecords(), "网站SEO配置", response);
    }
    @ApiOperation("根据ID查询")
    @GetMapping("/{id}")
    @RequiresPermissions("business:seo:query")
    public ApiResponse findById(@PathVariable Integer id) {
        return ApiResponse.success(seoService.findById(id));
    }
}
server/src/main/java/com/doumee/dao/business/SeoMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.doumee.dao.business;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.doumee.dao.business.model.Seo;
import com.github.yulichang.base.MPJBaseMapper;
/**
 * @author æ±Ÿè¹„蹄
 * @since 2025/07/02 11:35
 */
public interface SeoMapper extends MPJBaseMapper<Seo> {
}
server/src/main/java/com/doumee/dao/business/model/Information.java
@@ -81,6 +81,11 @@
    @ApiModelProperty(value = "状态 0正常 1禁用", example = "1")
    @ExcelColumn(name="状态 0正常 1禁用")
    private Integer status;
    @ApiModelProperty(value = "所属模块 0行业资讯、1运营经验、2功能介绍、3市场信息", example = "1")
    @ExcelColumn(name="module 0正常 1禁用")
    private Integer module;
    @ApiModelProperty(value = "封面图片地址")
    @TableField(exist = false)
server/src/main/java/com/doumee/dao/business/model/Seo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,91 @@
package com.doumee.dao.business.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.doumee.core.annotation.excel.ExcelColumn;
import com.doumee.core.annotation.excel.ExcelColumn;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
/**
 * ç½‘ç«™SEO配置
 * @author æ±Ÿè¹„蹄
 * @since 2025/07/02 11:35
 */
@Data
@ApiModel("网站SEO配置")
@TableName("`seo`")
public class Seo {
    @TableId(type = IdType.AUTO)
    @ApiModelProperty(value = "主键", example = "1")
    @ExcelColumn(name="主键")
    private Integer id;
    @ApiModelProperty(value = "创建人编码", example = "1")
    @ExcelColumn(name="创建人编码")
    private Integer creator;
    @ApiModelProperty(value = "创建时间")
    @ExcelColumn(name="创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date createDate;
    @ApiModelProperty(value = "更新人编码", example = "1")
    @ExcelColumn(name="更新人编码")
    private Integer editor;
    @ApiModelProperty(value = "更新时间")
    @ExcelColumn(name="更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date editDate;
    @ApiModelProperty(value = "是否删除0否 1是", example = "1")
    @ExcelColumn(name="是否删除0否 1是")
    private Integer isdeleted;
    @ApiModelProperty(value = "备注")
    @ExcelColumn(name="备注")
    private String remark;
    @ApiModelProperty(value = "页面名称")
    @ExcelColumn(name="页面名称")
    private String name;
    @ApiModelProperty(value = "标题")
    @ExcelColumn(name="标题")
    private String title;
    @ApiModelProperty(value = "关键字")
    @ExcelColumn(name="关键字")
    private String keywords;
    @ApiModelProperty(value = "作者信息")
    @ExcelColumn(name="作者信息")
    private String author;
    @ApiModelProperty(value = "图标地址", example = "1")
    @ExcelColumn(name="图标地址")
    private Integer icon;
    @ApiModelProperty(value = "页面地址(/default.html è¡¨ç¤ºç½‘站默认配置项)")
    @ExcelColumn(name="页面地址(/default.html è¡¨ç¤ºç½‘站默认配置项)")
    private String pageAddr;
    @ApiModelProperty(value = "图片alt属性值")
    @ExcelColumn(name="图片alt属性值")
    private String imgalt;
    @ApiModelProperty(value = "排序码", example = "1")
    @ExcelColumn(name="排序码")
    private Integer sortnum;
    @ApiModelProperty(value = "更新人编码", example = "1")
    @TableField(exist = false)
    private String editorName;
}
server/src/main/java/com/doumee/service/business/SeoService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,97 @@
package com.doumee.service.business;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.dao.business.model.Seo;
import java.util.List;
/**
 * ç½‘ç«™SEO配置Service定义
 * @author æ±Ÿè¹„蹄
 * @since 2025/07/02 11:35
 */
public interface SeoService {
    /**
     * åˆ›å»º
     *
     * @param seo å®žä½“对象
     * @return Integer
     */
    Integer create(Seo seo);
    /**
     * ä¸»é”®åˆ é™¤
     *
     * @param id ä¸»é”®
     */
    void deleteById(Integer id);
    /**
     * åˆ é™¤
     *
     * @param seo å®žä½“对象
     */
    void delete(Seo seo);
    /**
     * æ‰¹é‡ä¸»é”®åˆ é™¤
     *
     * @param ids ä¸»é”®é›†
     */
    void deleteByIdInBatch(List<Integer> ids);
    /**
     * ä¸»é”®æ›´æ–°
     *
     * @param seo å®žä½“对象
     */
    void updateById(Seo seo);
    /**
     * æ‰¹é‡ä¸»é”®æ›´æ–°
     *
     * @param seos å®žä½“集
     */
    void updateByIdInBatch(List<Seo> seos);
    /**
     * ä¸»é”®æŸ¥è¯¢
     *
     * @param id ä¸»é”®
     * @return Seo
     */
    Seo findById(Integer id);
    /**
     * æ¡ä»¶æŸ¥è¯¢å•条记录
     *
     * @param seo å®žä½“对象
     * @return Seo
     */
    Seo findOne(Seo seo);
    /**
     * æ¡ä»¶æŸ¥è¯¢
     *
     * @param seo å®žä½“对象
     * @return List<Seo>
     */
    List<Seo> findList(Seo seo);
    /**
     * åˆ†é¡µæŸ¥è¯¢
     *
     * @param pageWrap åˆ†é¡µå¯¹è±¡
     * @return PageData<Seo>
     */
    PageData<Seo> findPage(PageWrap<Seo> pageWrap);
    /**
     * æ¡ä»¶ç»Ÿè®¡
     *
     * @param seo å®žä½“对象
     * @return long
     */
    long count(Seo seo);
}
server/src/main/java/com/doumee/service/business/impl/CarouselServiceImpl.java
@@ -86,7 +86,9 @@
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        carouselMapper.deleteBatchIds(ids);
        for(Integer id :ids){
            this.deleteById(id);
        }
    }
    @Override
server/src/main/java/com/doumee/service/business/impl/InformationServiceImpl.java
@@ -77,7 +77,9 @@
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        informationMapper.deleteBatchIds(ids);
        for (Integer id : ids) {
            this.deleteById(id);
        }
    }
    @Override
@@ -140,6 +142,7 @@
        queryWrapper.lambda()
                .eq(Information::getIsdeleted,Constants.ZERO)
                .eq(pageWrap.getModel().getId() != null, Information::getId, pageWrap.getModel().getId())
                .eq(pageWrap.getModel().getModule() != null, Information::getModule, pageWrap.getModel().getModule())
                .eq(pageWrap.getModel().getType() != null, Information::getType, pageWrap.getModel().getType())
                .eq(pageWrap.getModel().getStatus() != null, Information::getStatus, pageWrap.getModel().getStatus())
                .eq(pageWrap.getModel().getRemark() != null, Information::getRemark, pageWrap.getModel().getRemark())
server/src/main/java/com/doumee/service/business/impl/SeoServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,169 @@
package com.doumee.service.business.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.model.LoginUserInfo;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.SeoMapper;
import com.doumee.dao.business.model.Carousel;
import com.doumee.dao.business.model.Seo;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.service.business.SeoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * ç½‘ç«™SEO配置Service实现
 * @author æ±Ÿè¹„蹄
 * @since 2025/07/02 11:35
 */
@Service
public class SeoServiceImpl implements SeoService {
    @Autowired
    private SeoMapper seoMapper;
    @Override
    public Integer create(Seo seo) {
        LoginUserInfo user = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        if(Objects.isNull(seo)
                || Objects.isNull(seo.getPageAddr())
                || Objects.isNull(seo.getName())
        ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        if(seoMapper.selectCount(new LambdaQueryWrapper<Seo>().eq(Seo::getIsdeleted,Constants.ZERO)
                .eq(Seo::getPageAddr,seo.getPageAddr())) >0 ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"该页面地址已配置,请勿重复配置!");
        }
        seo.setIsdeleted(Constants.ZERO);
        seo.setCreateDate(new Date());
        seo.setCreator(user.getId());
        seo.setEditDate(new Date());
        seo.setEditor(user.getId());
        seoMapper.insert(seo);
        return seo.getId();
    }
    @Override
    public void deleteById(Integer id) {
        LoginUserInfo user = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        seoMapper.update(new UpdateWrapper<Seo>().lambda()
                .set(Seo::getEditDate,new Date())
                .set(Seo::getEditor,user.getId())
                .set(Seo::getIsdeleted,Constants.ONE)
                .eq(Seo::getId,id));
    }
    @Override
    public void delete(Seo seo) {
        UpdateWrapper<Seo> deleteWrapper = new UpdateWrapper<>(seo);
        seoMapper.delete(deleteWrapper);
    }
    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        for(Integer id :ids){
            this.deleteById(id);
        }
    }
    @Override
    public void updateById(Seo seo) {
        LoginUserInfo user = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        if(StringUtils.isNotBlank(seo.getPageAddr()) &&
                seoMapper.selectCount(new LambdaQueryWrapper<Seo>().eq(Seo::getIsdeleted,Constants.ZERO)
                .eq(Seo::getPageAddr,seo.getPageAddr()).ne(Seo::getId,seo.getId())) >0 ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"该页面地址已配置,请勿重复配置!");
        }
        seo.setIsdeleted(Constants.ZERO);
        seo.setEditDate(new Date());
        seo.setEditor(user.getId());
        seoMapper.updateById(seo);
    }
    @Override
    public void updateByIdInBatch(List<Seo> seos) {
        if (CollectionUtils.isEmpty(seos)) {
            return;
        }
        for (Seo seo: seos) {
            this.updateById(seo);
        }
    }
    @Override
    public Seo findById(Integer id) {
        return seoMapper.selectById(id);
    }
    @Override
    public Seo findOne(Seo seo) {
        QueryWrapper<Seo> wrapper = new QueryWrapper<>(seo);
        return seoMapper.selectOne(wrapper);
    }
    @Override
    public List<Seo> findList(Seo seo) {
        seo.setIsdeleted(Constants.ZERO);
        QueryWrapper<Seo> wrapper = new QueryWrapper<>(seo);
        return seoMapper.selectList(wrapper);
    }
    @Override
    public PageData<Seo> findPage(PageWrap<Seo> pageWrap) {
        IPage<Seo> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        MPJLambdaWrapper<Seo> queryWrapper = new MPJLambdaWrapper<Seo>();
        Utils.MP.blankToNull(pageWrap.getModel());
        pageWrap.getModel().setIsdeleted(Constants.ZERO);
        queryWrapper.selectAll(Seo.class )
                .selectAs(SystemUser::getUsername,Seo::getEditorName)
                .leftJoin(SystemUser.class,SystemUser::getId,Seo::getEditor)
                .eq(pageWrap.getModel().getId() != null, Seo::getId, pageWrap.getModel().getId())
                .eq(pageWrap.getModel().getCreator() != null, Seo::getCreator, pageWrap.getModel().getCreator())
                .ge(pageWrap.getModel().getCreateDate() != null, Seo::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()))
                .le(pageWrap.getModel().getCreateDate() != null, Seo::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()))
                .eq(pageWrap.getModel().getEditor() != null, Seo::getEditor, pageWrap.getModel().getEditor())
                .ge(pageWrap.getModel().getEditDate() != null, Seo::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()))
                .le(pageWrap.getModel().getEditDate() != null, Seo::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()))
                .eq(pageWrap.getModel().getIsdeleted() != null, Seo::getIsdeleted, pageWrap.getModel().getIsdeleted())
                .eq(pageWrap.getModel().getRemark() != null, Seo::getRemark, pageWrap.getModel().getRemark())
                .like(pageWrap.getModel().getName() != null, Seo::getName, pageWrap.getModel().getName())
                .like(pageWrap.getModel().getTitle() != null, Seo::getTitle, pageWrap.getModel().getTitle())
                .like(pageWrap.getModel().getKeywords() != null, Seo::getKeywords, pageWrap.getModel().getKeywords())
                .like(pageWrap.getModel().getAuthor() != null, Seo::getAuthor, pageWrap.getModel().getAuthor())
                .eq(pageWrap.getModel().getIcon() != null, Seo::getIcon, pageWrap.getModel().getIcon())
                .like(pageWrap.getModel().getImgalt() != null, Seo::getImgalt, pageWrap.getModel().getImgalt())
                .like(pageWrap.getModel().getPageAddr() != null, Seo::getPageAddr, pageWrap.getModel().getPageAddr())
                .eq(pageWrap.getModel().getSortnum() != null, Seo::getSortnum, pageWrap.getModel().getSortnum())
                  .orderByAsc(Seo::getSortnum);
        return PageData.from(seoMapper.selectPage(page, queryWrapper));
    }
    @Override
    public long count(Seo seo) {
        QueryWrapper<Seo> wrapper = new QueryWrapper<>(seo);
        return seoMapper.selectCount(wrapper);
    }
}