From 4d51af31b49927bf401e432138d584f9ef40ef22 Mon Sep 17 00:00:00 2001
From: inleft <inleft@qq.com>
Date: Thu, 17 Feb 2022 18:10:11 +0800
Subject: [PATCH] 友链添加

---
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/controller/BlogFriendshipLinkController.java    |  148 +++++
 _web/src/views/main/blogfriendshiplink/editForm.vue                                                             |  140 +++++
 _web/src/views/main/blogfriendshiplink/addForm.vue                                                              |  119 ++++
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/service/BlogFriendshipLinkService.java          |   97 +++
 snowy-main/src/main/resources/application-local.yml                                                             |    5 
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogLinkVo.java                           |   45 +
 snowy-main/src/main/resources/application.yml                                                                   |    3 
 snowy-main/src/main/java/vip/xiaonuo/modular/blogarticle/entity/BlogArticle.java                                |    6 
 snowy-main/src/main/java/vip/xiaonuo/modular/blogStatistics/BlogStatisticsController.java                       |   16 
 snowy-main/src/main/resources/application-prod.yml                                                              |   14 
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/enums/BlogFriendshipLinkExceptionEnum.java      |   64 ++
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogFriendshipLinkParam.java              |  104 +++
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/controller/BlogLinkOutsideController.java       |  112 ++++
 _web/src/api/modular/main/blogfriendshiplink/blogFriendshipLinkManage.js                                        |   86 +++
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/entity/BlogFriendshipLink.java                  |  111 +++
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogFriendshipLinkVo.java                 |   76 ++
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/mapper/mapping/BlogFriendshipLinkMapper.xml     |    5 
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/service/impl/BlogFriendshipLinkServiceImpl.java |  140 +++++
 _web/src/views/main/blogfriendshiplink/index.vue                                                                |  309 +++++++++++
 snowy-main/src/main/java/vip/xiaonuo/modular/blogarticletype/controller/BlogArticleTypeOutsideController.java   |    3 
 snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/mapper/BlogFriendshipLinkMapper.java            |   37 +
 21 files changed, 1,618 insertions(+), 22 deletions(-)

diff --git a/_web/src/api/modular/main/blogfriendshiplink/blogFriendshipLinkManage.js b/_web/src/api/modular/main/blogfriendshiplink/blogFriendshipLinkManage.js
new file mode 100644
index 0000000..da55397
--- /dev/null
+++ b/_web/src/api/modular/main/blogfriendshiplink/blogFriendshipLinkManage.js
@@ -0,0 +1,86 @@
+import { axios } from '@/utils/request'
+
+/**
+ * 查询友情链接
+ *
+ * @author inleft
+ * @date 2022-02-17 14:50:13
+ */
+export function blogFriendshipLinkPage (parameter) {
+  return axios({
+    url: '/blogFriendshipLink/page',
+    method: 'get',
+    params: parameter
+  })
+}
+
+/**
+ * 友情链接列表
+ *
+ * @author inleft
+ * @date 2022-02-17 14:50:13
+ */
+export function blogFriendshipLinkList (parameter) {
+  return axios({
+    url: '/blogFriendshipLink/list',
+    method: 'get',
+    params: parameter
+  })
+}
+
+/**
+ * 添加友情链接
+ *
+ * @author inleft
+ * @date 2022-02-17 14:50:13
+ */
+export function blogFriendshipLinkAdd (parameter) {
+  return axios({
+    url: '/blogFriendshipLink/add',
+    method: 'post',
+    data: parameter
+  })
+}
+
+/**
+ * 编辑友情链接
+ *
+ * @author inleft
+ * @date 2022-02-17 14:50:13
+ */
+export function blogFriendshipLinkEdit (parameter) {
+  return axios({
+    url: '/blogFriendshipLink/edit',
+    method: 'post',
+    data: parameter
+  })
+}
+
+/**
+ * 删除友情链接
+ *
+ * @author inleft
+ * @date 2022-02-17 14:50:13
+ */
+export function blogFriendshipLinkDelete (parameter) {
+  return axios({
+    url: '/blogFriendshipLink/delete',
+    method: 'post',
+    data: parameter
+  })
+}
+
+/**
+ * 导出友情链接
+ *
+ * @author inleft
+ * @date 2022-02-17 14:50:13
+ */
+export function blogFriendshipLinkExport (parameter) {
+  return axios({
+    url: '/blogFriendshipLink/export',
+    method: 'get',
+    params: parameter,
+    responseType: 'blob'
+  })
+}
diff --git a/_web/src/views/main/blogfriendshiplink/addForm.vue b/_web/src/views/main/blogfriendshiplink/addForm.vue
new file mode 100644
index 0000000..5dc36aa
--- /dev/null
+++ b/_web/src/views/main/blogfriendshiplink/addForm.vue
@@ -0,0 +1,119 @@
+<template>
+  <a-modal title="新增友情链接" :width="900" :visible="visible" :confirmLoading="confirmLoading" @ok="handleSubmit"
+    @cancel="handleCancel">
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <a-form-item label="名称" :labelCol="labelCol" :wrapperCol="wrapperCol" has-feedback>
+          <a-input placeholder="请输入名称" v-decorator="['name', {rules: [{required: true, message: '请输入名称!'}]}]" />
+        </a-form-item>
+        <a-form-item label="url地址" :labelCol="labelCol" :wrapperCol="wrapperCol" has-feedback>
+          <a-input placeholder="请输入url地址" v-decorator="['url', {rules: [{required: true, message: '请输入url地址!'}]}]" />
+        </a-form-item>
+        <a-form-item label="头像地址" :labelCol="labelCol" :wrapperCol="wrapperCol" has-feedback>
+          <a-input placeholder="请输入头像地址"
+            v-decorator="['avatar', {rules: [{required: false, message: '请输入头像地址!'}]}]" />
+        </a-form-item>
+        <a-form-item label="描述" :labelCol="labelCol" :wrapperCol="wrapperCol" has-feedback>
+          <a-input placeholder="请输入描述" v-decorator="['remark', {rules: [{required: false, message: '请输入描述!'}]}]" />
+        </a-form-item>
+        <a-form-item label="链接类型" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-radio-group placeholder="请选择链接类型"
+            v-decorator="['linkType',{rules: [{ required: true, message: '请选择链接类型!' }]}]">
+            <a-radio v-for="(item,index) in linkTypeData" :key="index" :value="item.code">{{ item.name }}</a-radio>
+          </a-radio-group>
+        </a-form-item>
+        <a-form-item label="权重" :labelCol="labelCol" :wrapperCol="wrapperCol" has-feedback>
+          <a-input placeholder="请输入权重" v-decorator="['topValue', {rules: [{required: true, message: '请输入权重!'}]}]" />
+        </a-form-item>
+        <a-form-item label="是否新窗口打开" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-radio-group placeholder="请选择是否新窗口打开"
+            v-decorator="['isNewWindowOpen',{rules: [{ required: true, message: '请选择是否新窗口打开!' }]}]">
+            <a-radio v-for="(item,index) in isNewWindowOpenData" :key="index" :value="item.code">{{ item.name }}
+            </a-radio>
+          </a-radio-group>
+        </a-form-item>
+      </a-form>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+  import {
+    blogFriendshipLinkAdd
+  } from '@/api/modular/main/blogfriendshiplink/blogFriendshipLinkManage'
+  export default {
+    data() {
+      return {
+        labelCol: {
+          xs: {
+            span: 24
+          },
+          sm: {
+            span: 5
+          }
+        },
+        wrapperCol: {
+          xs: {
+            span: 24
+          },
+          sm: {
+            span: 15
+          }
+        },
+        linkTypeData: [],
+        isNewWindowOpenData: [],
+        visible: false,
+        confirmLoading: false,
+        form: this.$form.createForm(this)
+      }
+    },
+    methods: {
+      // 初始化方法
+      add(record) {
+        this.visible = true
+        const linkTypeOption = this.$options
+        this.linkTypeData = linkTypeOption.filters['dictData']('blog_link_type')
+        const isNewWindowOpenOption = this.$options
+        this.isNewWindowOpenData = isNewWindowOpenOption.filters['dictData']('blog_yes_or_no')
+      },
+      /**
+       * 提交表单
+       */
+      handleSubmit() {
+        const {
+          form: {
+            validateFields
+          }
+        } = this
+        this.confirmLoading = true
+        validateFields((errors, values) => {
+          if (!errors) {
+            for (const key in values) {
+              if (typeof(values[key]) === 'object' && values[key] != null) {
+                values[key] = JSON.stringify(values[key])
+              }
+            }
+            blogFriendshipLinkAdd(values).then((res) => {
+              if (res.success) {
+                this.$message.success('新增成功')
+                this.confirmLoading = false
+                this.$emit('ok', values)
+                this.handleCancel()
+              } else {
+                this.$message.error('新增失败') // + res.message
+              }
+            }).finally((res) => {
+              this.confirmLoading = false
+            })
+          } else {
+            this.confirmLoading = false
+          }
+        })
+      },
+      handleCancel() {
+        this.form.resetFields()
+        this.visible = false
+      }
+    }
+  }
+</script>
diff --git a/_web/src/views/main/blogfriendshiplink/editForm.vue b/_web/src/views/main/blogfriendshiplink/editForm.vue
new file mode 100644
index 0000000..5c723bd
--- /dev/null
+++ b/_web/src/views/main/blogfriendshiplink/editForm.vue
@@ -0,0 +1,140 @@
+<template>
+  <a-modal title="编辑友情链接" :width="900" :visible="visible" :confirmLoading="confirmLoading" @ok="handleSubmit"
+    @cancel="handleCancel">
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <a-form-item v-show="false">
+          <a-input v-decorator="['id']" />
+        </a-form-item>
+        <a-form-item label="名称" :labelCol="labelCol" :wrapperCol="wrapperCol" has-feedback>
+          <a-input placeholder="请输入名称" v-decorator="['name', {rules: [{required: true, message: '请输入名称!'}]}]" />
+        </a-form-item>
+        <a-form-item label="url地址" :labelCol="labelCol" :wrapperCol="wrapperCol" has-feedback>
+          <a-input placeholder="请输入url地址" v-decorator="['url', {rules: [{required: true, message: '请输入url地址!'}]}]" />
+        </a-form-item>
+        <a-form-item label="头像地址" :labelCol="labelCol" :wrapperCol="wrapperCol" has-feedback>
+          <a-input placeholder="请输入头像地址" v-decorator="['avatar', {rules: [{required: false, message: '请输入头像地址!'}]}]" />
+        </a-form-item>
+        <a-form-item label="描述" :labelCol="labelCol" :wrapperCol="wrapperCol" has-feedback>
+          <a-input placeholder="请输入描述" v-decorator="['remark', {rules: [{required: true, message: '请输入描述!'}]}]" />
+        </a-form-item>
+        <a-form-item label="链接类型" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-radio-group placeholder="请选择链接类型"
+            v-decorator="['linkType',{rules: [{ required: true, message: '请选择链接类型!' }]}]">
+            <a-radio v-for="(item,index) in linkTypeData" :key="index" :value="item.code">{{ item.name }}</a-radio>
+          </a-radio-group>
+        </a-form-item>
+        <a-form-item label="权重" :labelCol="labelCol" :wrapperCol="wrapperCol" has-feedback>
+          <a-input placeholder="请输入权重" v-decorator="['topValue', {rules: [{required: true, message: '请输入权重!'}]}]" />
+        </a-form-item>
+        <a-form-item label="是否新窗口打开" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-radio-group placeholder="请选择是否新窗口打开"
+            v-decorator="['isNewWindowOpen',{rules: [{ required: true, message: '请选择是否新窗口打开!' }]}]">
+            <a-radio v-for="(item,index) in isNewWindowOpenData" :key="index" :value="item.code">{{ item.name }}
+            </a-radio>
+          </a-radio-group>
+        </a-form-item>
+        <a-form-item label="是否启用" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-radio-group placeholder="请选择是否启用"
+            v-decorator="['isEnable',{rules: [{ required: true, message: '请选择是否启用!' }]}]">
+            <a-radio v-for="(item,index) in isEnableData" :key="index" :value="item.code">{{ item.name }}</a-radio>
+          </a-radio-group>
+        </a-form-item>
+      </a-form>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+  import {
+    blogFriendshipLinkEdit
+  } from '@/api/modular/main/blogfriendshiplink/blogFriendshipLinkManage'
+  export default {
+    data() {
+      return {
+        labelCol: {
+          xs: {
+            span: 24
+          },
+          sm: {
+            span: 5
+          }
+        },
+        wrapperCol: {
+          xs: {
+            span: 24
+          },
+          sm: {
+            span: 15
+          }
+        },
+        linkTypeData: [],
+        isEnableData: [],
+        isNewWindowOpenData: [],
+        visible: false,
+        confirmLoading: false,
+        form: this.$form.createForm(this)
+      }
+    },
+    methods: {
+      // 初始化方法
+      edit(record) {
+        this.visible = true
+        const linkTypeOption = this.$options
+        this.linkTypeData = linkTypeOption.filters['dictData']('blog_link_type')
+        const isNewWindowOpenOption = this.$options
+        this.isNewWindowOpenData = isNewWindowOpenOption.filters['dictData']('blog_yes_or_no')
+        const isEnableOption = this.$options
+        this.isEnableData = isEnableOption.filters['dictData']('blog_yes_or_no')
+        setTimeout(() => {
+          this.form.setFieldsValue({
+            id: record.id,
+            name: record.name,
+            url: record.url,
+            avatar: record.avatar,
+            isEnable: record.isEnable,
+            remark: record.remark,
+            linkType: record.linkType,
+            topValue: record.topValue,
+            isNewWindowOpen: record.isNewWindowOpen
+          })
+        }, 100)
+      },
+      handleSubmit() {
+        const {
+          form: {
+            validateFields
+          }
+        } = this
+        this.confirmLoading = true
+        validateFields((errors, values) => {
+          if (!errors) {
+            for (const key in values) {
+              if (typeof(values[key]) === 'object' && values[key] != null) {
+                values[key] = JSON.stringify(values[key])
+              }
+            }
+            blogFriendshipLinkEdit(values).then((res) => {
+              if (res.success) {
+                this.$message.success('编辑成功')
+                this.confirmLoading = false
+                this.$emit('ok', values)
+                this.handleCancel()
+              } else {
+                this.$message.error('编辑失败') //  + res.message
+              }
+            }).finally((res) => {
+              this.confirmLoading = false
+            })
+          } else {
+            this.confirmLoading = false
+          }
+        })
+      },
+      handleCancel() {
+        this.form.resetFields()
+        this.visible = false
+      }
+    }
+  }
+</script>
diff --git a/_web/src/views/main/blogfriendshiplink/index.vue b/_web/src/views/main/blogfriendshiplink/index.vue
new file mode 100644
index 0000000..fd6753c
--- /dev/null
+++ b/_web/src/views/main/blogfriendshiplink/index.vue
@@ -0,0 +1,309 @@
+<template>
+  <div>
+    <a-card :bordered="false" :bodyStyle="tstyle">
+      <div class="table-page-search-wrapper" v-if="hasPerm('blogFriendshipLink:page')">
+        <a-form layout="inline">
+          <a-row :gutter="48">
+            <a-col :md="8" :sm="24">
+              <a-form-item label="名称">
+                <a-input v-model="queryParam.name" allow-clear placeholder="请输入名称" />
+              </a-form-item>
+            </a-col>
+            <a-col :md="8" :sm="24">
+              <a-form-item label="链接类型">
+                <a-select style="width: 100%" v-model="queryParam.linkType" placeholder="请选择链接类型">
+                  <a-select-option v-for="(item,index) in linkTypeData" :key="index" :value="item.code">{{ item.name }}
+                  </a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+            <template v-if="advanced">
+              <a-col :md="8" :sm="24">
+                <a-form-item label="权重">
+                  <a-input v-model="queryParam.topValue" allow-clear placeholder="请输入权重" />
+                </a-form-item>
+              </a-col>
+              <a-col :md="8" :sm="24">
+                <a-form-item label="是否启用">
+                  <a-input v-model="queryParam.isEnable" allow-clear placeholder="请输入是否启用" />
+                </a-form-item>
+              </a-col>
+              <a-col :md="8" :sm="24">
+                <a-form-item label="是否新窗口打开">
+                  <a-select style="width: 100%" v-model="queryParam.isNewWindowOpen" placeholder="请选择是否新窗口打开">
+                    <a-select-option v-for="(item,index) in isNewWindowOpenData" :key="index" :value="item.code">
+                      {{ item.name }}</a-select-option>
+                  </a-select>
+                </a-form-item>
+              </a-col>
+              <a-col :md="8" :sm="24">
+                <a-form-item label="创建时间">
+                  <a-date-picker style="width: 100%" placeholder="请选择创建时间" v-model="queryParam.createDateDate"
+                    @change="onChangecreateDate" />
+                </a-form-item>
+              </a-col>
+            </template>
+            <a-col :md="8" :sm="24">
+              <span class="table-page-search-submitButtons">
+                <a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>
+                <a-button style="margin-left: 8px" @click="() => queryParam = {}">重置</a-button>
+                <a @click="toggleAdvanced" style="margin-left: 8px">
+                  {{ advanced ? '收起' : '展开' }}
+                  <a-icon :type="advanced ? 'up' : 'down'" />
+                </a>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+    </a-card>
+    <a-card :bordered="false">
+      <s-table ref="table" :columns="columns" :data="loadData" :alert="options.alert" :rowKey="(record) => record.id"
+        :rowSelection="options.rowSelection">
+        <template class="table-operator" slot="operator" v-if="hasPerm('blogFriendshipLink:add')">
+          <a-button type="primary" v-if="hasPerm('blogFriendshipLink:add')" icon="plus" @click="$refs.addForm.add()">
+            新增友情链接</a-button>
+          <a-button type="danger" :disabled="selectedRowKeys.length < 1" v-if="hasPerm('blogFriendshipLink:delete')"
+            @click="batchDelete">
+            <a-icon type="delete" />批量删除
+          </a-button>
+          <x-down v-if="hasPerm('blogFriendshipLink:export')" ref="batchExport" @batchExport="batchExport" />
+        </template>
+        <span slot="linkTypeScopedSlots" slot-scope="text">
+          {{ 'blog_link_type' | dictType(text) }}
+        </span>
+        <span slot="isEnableScopedSlots" slot-scope="text">
+          {{ 'blog_yes_or_no' | dictType(text) }}
+        </span>
+        <span slot="isNewWindowOpenScopedSlots" slot-scope="text">
+          {{ 'blog_yes_or_no' | dictType(text) }}
+        </span>
+        <span slot="action" slot-scope="text, record">
+          <a v-if="hasPerm('blogFriendshipLink:edit')" @click="$refs.editForm.edit(record)">编辑</a>
+          <a-divider type="vertical" v-if="hasPerm('blogFriendshipLink:edit') & hasPerm('blogFriendshipLink:delete')" />
+          <a-popconfirm v-if="hasPerm('blogFriendshipLink:delete')" placement="topRight" title="确认删除?"
+            @confirm="() => singleDelete(record)">
+            <a>删除</a>
+          </a-popconfirm>
+        </span>
+      </s-table>
+      <add-form ref="addForm" @ok="handleOk" />
+      <edit-form ref="editForm" @ok="handleOk" />
+    </a-card>
+  </div>
+</template>
+<script>
+  import {
+    STable,
+    XDown
+  } from '@/components'
+  import moment from 'moment'
+  import {
+    blogFriendshipLinkPage,
+    blogFriendshipLinkDelete,
+    blogFriendshipLinkExport
+  } from '@/api/modular/main/blogfriendshiplink/blogFriendshipLinkManage'
+  import addForm from './addForm.vue'
+  import editForm from './editForm.vue'
+  export default {
+    components: {
+      STable,
+      addForm,
+      editForm,
+      XDown
+    },
+    data() {
+      return {
+        // 高级搜索 展开/关闭
+        advanced: false,
+        // 查询参数
+        queryParam: {},
+        // 表头
+        columns: [{
+            title: '名称',
+            align: 'center',
+            dataIndex: 'name'
+          },
+          {
+            title: 'url地址',
+            align: 'center',
+            dataIndex: 'url'
+          },
+          {
+            title: '头像地址',
+            align: 'center',
+            dataIndex: 'avatar'
+          },
+          {
+            title: '描述',
+            align: 'center',
+            dataIndex: 'remark'
+          },
+          {
+            title: '链接类型',
+            align: 'center',
+            dataIndex: 'linkType',
+            scopedSlots: {
+              customRender: 'linkTypeScopedSlots'
+            }
+          },
+          {
+            title: '权重',
+            align: 'center',
+            dataIndex: 'topValue'
+          },
+          {
+            title: '是否启用',
+            align: 'center',
+            dataIndex: 'isEnable',
+            scopedSlots: {
+              customRender: 'isEnableScopedSlots'
+            }
+          },
+          {
+            title: '是否新窗口打开',
+            align: 'center',
+            dataIndex: 'isNewWindowOpen',
+            scopedSlots: {
+              customRender: 'isNewWindowOpenScopedSlots'
+            }
+          },
+          {
+            title: '更新时间',
+            align: 'center',
+            dataIndex: 'updateDate'
+          },
+          {
+            title: '创建时间',
+            align: 'center',
+            dataIndex: 'createDate'
+          }
+        ],
+        tstyle: {
+          'padding-bottom': '0px',
+          'margin-bottom': '10px'
+        },
+        // 加载数据方法 必须为 Promise 对象
+        loadData: parameter => {
+          return blogFriendshipLinkPage(Object.assign(parameter, this.switchingDate())).then((res) => {
+            return res.data
+          })
+        },
+        linkTypeData: [],
+        isNewWindowOpenData: [],
+        selectedRowKeys: [],
+        selectedRows: [],
+        options: {
+          alert: {
+            show: true,
+            clear: () => {
+              this.selectedRowKeys = []
+            }
+          },
+          rowSelection: {
+            selectedRowKeys: this.selectedRowKeys,
+            onChange: this.onSelectChange
+          }
+        }
+      }
+    },
+    created() {
+      if (this.hasPerm('blogFriendshipLink:edit') || this.hasPerm('blogFriendshipLink:delete')) {
+        this.columns.push({
+          title: '操作',
+          width: '150px',
+          dataIndex: 'action',
+          scopedSlots: {
+            customRender: 'action'
+          }
+        })
+      }
+      const linkTypeOption = this.$options
+      this.linkTypeData = linkTypeOption.filters['dictData']('blog_link_type')
+      const isNewWindowOpenOption = this.$options
+      this.isNewWindowOpenData = isNewWindowOpenOption.filters['dictData']('blog_yes_or_no')
+    },
+    methods: {
+      moment,
+      /**
+       * 查询参数组装
+       */
+      switchingDate() {
+        const queryParamcreateDate = this.queryParam.createDateDate
+        if (queryParamcreateDate != null) {
+          this.queryParam.createDate = moment(queryParamcreateDate).format('YYYY-MM-DD')
+          if (queryParamcreateDate.length < 1) {
+            delete this.queryParam.createDate
+          }
+        }
+        const obj = JSON.parse(JSON.stringify(this.queryParam))
+        return obj
+      },
+      /**
+       * 单个删除
+       */
+      singleDelete(record) {
+        const param = [{
+          'id': record.id
+        }]
+        this.blogFriendshipLinkDelete(param)
+      },
+      /**
+       * 批量删除
+       */
+      batchDelete() {
+        const paramIds = this.selectedRowKeys.map((d) => {
+          return {
+            'id': d
+          }
+        })
+        this.blogFriendshipLinkDelete(paramIds)
+      },
+      blogFriendshipLinkDelete(record) {
+        blogFriendshipLinkDelete(record).then((res) => {
+          if (res.success) {
+            this.$message.success('删除成功')
+            this.$refs.table.clearRefreshSelected()
+          } else {
+            this.$message.error('删除失败') // + res.message
+          }
+        })
+      },
+      toggleAdvanced() {
+        this.advanced = !this.advanced
+      },
+      onChangecreateDate(date, dateString) {
+        this.createDateDateString = dateString
+      },
+      /**
+       * 批量导出
+       */
+      batchExport() {
+        const paramIds = this.selectedRowKeys.map((d) => {
+          return {
+            'id': d
+          }
+        })
+        blogFriendshipLinkExport(paramIds).then((res) => {
+          this.$refs.batchExport.downloadfile(res)
+        })
+      },
+      handleOk() {
+        this.$refs.table.refresh()
+      },
+      onSelectChange(selectedRowKeys, selectedRows) {
+        this.selectedRowKeys = selectedRowKeys
+        this.selectedRows = selectedRows
+      }
+    }
+  }
+</script>
+<style lang="less">
+  .table-operator {
+    margin-bottom: 18px;
+  }
+
+  button {
+    margin-right: 8px;
+  }
+</style>
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogStatistics/BlogStatisticsController.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogStatistics/BlogStatisticsController.java
index a315ead..d5d77d3 100644
--- a/snowy-main/src/main/java/vip/xiaonuo/modular/blogStatistics/BlogStatisticsController.java
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogStatistics/BlogStatisticsController.java
@@ -63,21 +63,17 @@
     @BusinessLog(title = "外部blog系统_统计_查询", opType = LogAnnotionOpTypeEnum.QUERY)
     public ResponseData statistics() {
 
-        //相差一个月,31天
-        long betweenDay = DateUtil.between(DateUtil.parseDate("2020-05-27"), new Date(), DateUnit.DAY);
-        String updateDate;
-        BlogArticle lastUpdateBlog = blogArticleService.lambdaQuery().orderByDesc(BlogArticle::getUpdateDate)
-                .last(" limit 1 ").one();
+        String updateDate = "--";
+        BlogArticle lastUpdateBlog = blogArticleService.lambdaQuery().orderByDesc(BlogArticle::getUpdateDate).last(" limit 1 ").one();
         if (lastUpdateBlog != null && lastUpdateBlog.getUpdateDate() != null) {
             updateDate = DateUtil.formatDate(lastUpdateBlog.getUpdateDate());
-        } else {
-            updateDate = "--";
         }
+
         String startFrom = "从这开始: 2020-05-27 ";
-        String aliveDayCount = "已稳定运行:" + betweenDay + "天";
+        String aliveDayCount = "已稳定运行:" + DateUtil.between(DateUtil.parseDate("2022-02-14"), new Date(), DateUnit.DAY) + "天";
         String lastUpdateDate = "上次更新:" + updateDate;
-        String visitCount = "累计访问:1010次";
-        String visitorCount = "累计访客:1001名";
+        String visitCount = "累计访问:1010次"; //24小时ip 访问次数
+        String visitorCount = "累计访客:1001名";//所有时间ip个数
 
         List<BlogStatisticsVo.simpleVo> res = new ArrayList<>();
         res.add(new BlogStatisticsVo.simpleVo().setName(startFrom));
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogarticle/entity/BlogArticle.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogarticle/entity/BlogArticle.java
index 6c06354..7f5b13d 100644
--- a/snowy-main/src/main/java/vip/xiaonuo/modular/blogarticle/entity/BlogArticle.java
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogarticle/entity/BlogArticle.java
@@ -25,9 +25,7 @@
 package vip.xiaonuo.modular.blogarticle.entity;
 
 import cn.afterturn.easypoi.excel.annotation.Excel;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.*;
 import lombok.Data;
 
 import java.util.Date;
@@ -154,12 +152,14 @@
      * 更新时间
      */
     @Excel(name = "更新时间", databaseFormat = "yyyy-MM-dd HH:mm:ss", format = "yyyy-MM-dd", width = 20)
+    @TableField(fill = FieldFill.INSERT_UPDATE)
     private Date updateDate;
 
     /**
      * 创建时间
      */
     @Excel(name = "创建时间", databaseFormat = "yyyy-MM-dd HH:mm:ss", format = "yyyy-MM-dd", width = 20)
+    @TableField(fill = FieldFill.INSERT)
     private Date createDate;
 
 }
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogarticletype/controller/BlogArticleTypeOutSideController.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogarticletype/controller/BlogArticleTypeOutsideController.java
similarity index 98%
rename from snowy-main/src/main/java/vip/xiaonuo/modular/blogarticletype/controller/BlogArticleTypeOutSideController.java
rename to snowy-main/src/main/java/vip/xiaonuo/modular/blogarticletype/controller/BlogArticleTypeOutsideController.java
index b47c1c5..b8ef9e8 100644
--- a/snowy-main/src/main/java/vip/xiaonuo/modular/blogarticletype/controller/BlogArticleTypeOutSideController.java
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogarticletype/controller/BlogArticleTypeOutsideController.java
@@ -49,7 +49,7 @@
  */
 @RestController
 @RequestMapping("/outside")
-public class BlogArticleTypeOutSideController {
+public class BlogArticleTypeOutsideController {
 
     @Resource
     private BlogArticleTypeService blogArticleTypeService;
@@ -75,6 +75,7 @@
                     return vo;
                 }).collect(Collectors.toList());
 
+
         return new SuccessResponseData(list);
     }
 }
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/controller/BlogFriendshipLinkController.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/controller/BlogFriendshipLinkController.java
new file mode 100644
index 0000000..09da8d5
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/controller/BlogFriendshipLinkController.java
@@ -0,0 +1,148 @@
+/*
+Copyright [2020] [https://www.xiaonuo.vip]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+
+1.请不要删除和修改根目录下的LICENSE文件。
+2.请不要删除和修改Snowy源码头部的版权声明。
+3.请保留源码和相关描述文件的项目出处,作者声明等。
+4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.modular.blogfriendshiplink.controller;
+
+import vip.xiaonuo.core.annotion.BusinessLog;
+import vip.xiaonuo.core.annotion.Permission;
+import vip.xiaonuo.core.enums.LogAnnotionOpTypeEnum;
+import vip.xiaonuo.core.pojo.response.ResponseData;
+import vip.xiaonuo.core.pojo.response.SuccessResponseData;
+import vip.xiaonuo.modular.blogfriendshiplink.param.BlogFriendshipLinkParam;
+import vip.xiaonuo.modular.blogfriendshiplink.service.BlogFriendshipLinkService;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 友情链接控制器
+ *
+ * @author inleft
+ * @date 2022-02-17 15:05:44
+ */
+@RestController
+public class BlogFriendshipLinkController {
+
+    @Resource
+    private BlogFriendshipLinkService blogFriendshipLinkService;
+
+    /**
+     * 查询友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    @Permission
+    @GetMapping("/blogFriendshipLink/page")
+    @BusinessLog(title = "友情链接_查询", opType = LogAnnotionOpTypeEnum.QUERY)
+    public ResponseData page(BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        return new SuccessResponseData(blogFriendshipLinkService.page(blogFriendshipLinkParam));
+    }
+
+    /**
+     * 添加友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    @Permission
+    @PostMapping("/blogFriendshipLink/add")
+    @BusinessLog(title = "友情链接_增加", opType = LogAnnotionOpTypeEnum.ADD)
+    public ResponseData add(@RequestBody @Validated(BlogFriendshipLinkParam.add.class) BlogFriendshipLinkParam blogFriendshipLinkParam) {
+            blogFriendshipLinkService.add(blogFriendshipLinkParam);
+        return new SuccessResponseData();
+    }
+
+    /**
+     * 删除友情链接,可批量删除
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    @Permission
+    @PostMapping("/blogFriendshipLink/delete")
+    @BusinessLog(title = "友情链接_删除", opType = LogAnnotionOpTypeEnum.DELETE)
+    public ResponseData delete(@RequestBody @Validated(BlogFriendshipLinkParam.delete.class) List<BlogFriendshipLinkParam> blogFriendshipLinkParamList) {
+            blogFriendshipLinkService.delete(blogFriendshipLinkParamList);
+        return new SuccessResponseData();
+    }
+
+    /**
+     * 编辑友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    @Permission
+    @PostMapping("/blogFriendshipLink/edit")
+    @BusinessLog(title = "友情链接_编辑", opType = LogAnnotionOpTypeEnum.EDIT)
+    public ResponseData edit(@RequestBody @Validated(BlogFriendshipLinkParam.edit.class) BlogFriendshipLinkParam blogFriendshipLinkParam) {
+            blogFriendshipLinkService.edit(blogFriendshipLinkParam);
+        return new SuccessResponseData();
+    }
+
+    /**
+     * 查看友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    @Permission
+    @GetMapping("/blogFriendshipLink/detail")
+    @BusinessLog(title = "友情链接_查看", opType = LogAnnotionOpTypeEnum.DETAIL)
+    public ResponseData detail(@Validated(BlogFriendshipLinkParam.detail.class) BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        return new SuccessResponseData(blogFriendshipLinkService.detail(blogFriendshipLinkParam));
+    }
+
+    /**
+     * 友情链接列表
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    @Permission
+    @GetMapping("/blogFriendshipLink/list")
+    @BusinessLog(title = "友情链接_列表", opType = LogAnnotionOpTypeEnum.QUERY)
+    public ResponseData list(BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        return new SuccessResponseData(blogFriendshipLinkService.list(blogFriendshipLinkParam));
+    }
+
+    /**
+     * 导出系统用户
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    @Permission
+    @GetMapping("/blogFriendshipLink/export")
+    @BusinessLog(title = "友情链接_导出", opType = LogAnnotionOpTypeEnum.EXPORT)
+    public void export(BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        blogFriendshipLinkService.export(blogFriendshipLinkParam);
+    }
+
+}
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/controller/BlogLinkOutsideController.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/controller/BlogLinkOutsideController.java
new file mode 100644
index 0000000..78f8d64
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/controller/BlogLinkOutsideController.java
@@ -0,0 +1,112 @@
+/*
+Copyright [2020] [https://www.xiaonuo.vip]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+
+1.请不要删除和修改根目录下的LICENSE文件。
+2.请不要删除和修改Snowy源码头部的版权声明。
+3.请保留源码和相关描述文件的项目出处,作者声明等。
+4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.modular.blogfriendshiplink.controller;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.Dict;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import vip.xiaonuo.core.annotion.BusinessLog;
+import vip.xiaonuo.core.consts.CommonConstant;
+import vip.xiaonuo.core.consts.MyConstant;
+import vip.xiaonuo.core.enums.LogAnnotionOpTypeEnum;
+import vip.xiaonuo.core.pojo.response.ResponseData;
+import vip.xiaonuo.core.pojo.response.SuccessResponseData;
+import vip.xiaonuo.modular.blogfriendshiplink.entity.BlogFriendshipLink;
+import vip.xiaonuo.modular.blogfriendshiplink.param.BlogFriendshipLinkVo;
+import vip.xiaonuo.modular.blogfriendshiplink.param.BlogLinkVo;
+import vip.xiaonuo.modular.blogfriendshiplink.service.BlogFriendshipLinkService;
+import vip.xiaonuo.sys.modular.dict.param.SysDictTypeParam;
+import vip.xiaonuo.sys.modular.dict.service.SysDictTypeService;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 友情链接 控制器
+ *
+ * @author inleft
+ * @date 2022-02-15 15:17:15
+ */
+@RestController
+@RequestMapping("/outside")
+public class BlogLinkOutsideController {
+
+    @Resource
+    private BlogFriendshipLinkService blogFriendshipLinkService;
+
+
+    @Resource
+    private SysDictTypeService sysDictTypeService;
+
+    /**
+     * 查询blog友情链接
+     *
+     * @author inleft
+     * @date 2022-02-09 18:20:22
+     */
+    @GetMapping("/blogLink/queryBlogLinkGroup")
+    @BusinessLog(title = "外部blog系统_blog友情链接组_查询", opType = LogAnnotionOpTypeEnum.QUERY)
+    public ResponseData queryBlogLinkGroup() {
+
+        List<BlogFriendshipLink> linkList = blogFriendshipLinkService.lambdaQuery()
+                .eq(BlogFriendshipLink::getIsEnable,MyConstant.Yes)
+                .orderByAsc(BlogFriendshipLink::getTopValue)
+                .orderByAsc(BlogFriendshipLink::getName)
+                .list();
+        Map<String, List<BlogFriendshipLink>> groupLink = linkList.stream()
+                .collect(Collectors.groupingBy(e -> e.getLinkType().toString(), LinkedHashMap::new, Collectors.mapping(Function.identity(),
+                        Collectors.toList())));
+
+        SysDictTypeParam param = new SysDictTypeParam();
+        param.setCode("blog_link_type");
+        List<Dict> dictList = sysDictTypeService.dropDown(param);
+
+        List<BlogLinkVo> res = new ArrayList<>(dictList.size());
+        List<BlogFriendshipLink> tempLink;
+        BlogLinkVo vo;
+
+        for (Dict dict : dictList) {
+            if ((tempLink = groupLink.get(dict.get(CommonConstant.CODE))) != null) {
+                vo = new BlogLinkVo();
+                vo.setGroupName(dict.get(CommonConstant.VALUE).toString());
+                vo.setLinkVoList(tempLink.stream().map(e -> {
+                    BlogFriendshipLinkVo tempLinkVo = new BlogFriendshipLinkVo();
+                    BeanUtil.copyProperties(e, tempLinkVo);
+                    return tempLinkVo;
+                }).collect(Collectors.toList()));
+                res.add(vo);
+            }
+        }
+
+        return new SuccessResponseData(res);
+    }
+}
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/entity/BlogFriendshipLink.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/entity/BlogFriendshipLink.java
new file mode 100644
index 0000000..f433931
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/entity/BlogFriendshipLink.java
@@ -0,0 +1,111 @@
+/*
+Copyright [2020] [https://www.xiaonuo.vip]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+
+1.请不要删除和修改根目录下的LICENSE文件。
+2.请不要删除和修改Snowy源码头部的版权声明。
+3.请保留源码和相关描述文件的项目出处,作者声明等。
+4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.modular.blogfriendshiplink.entity;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 友情链接
+ *
+ * @author inleft
+ * @date 2022-02-17 15:05:44
+ */
+@Data
+@TableName("blog_friendship_link")
+public class BlogFriendshipLink {
+
+    /**
+     * 自增id
+     */
+    @TableId(type = IdType.ASSIGN_ID)
+    private Long id;
+
+    /**
+     * 名称
+     */
+    @Excel(name = "名称")
+    private String name;
+
+    /**
+     * url地址
+     */
+    @Excel(name = "url地址")
+    private String url;
+
+    /**
+     * 头像地址
+     */
+    @Excel(name = "头像地址")
+    private String avatar;
+
+    /**
+     * 描述
+     */
+    @Excel(name = "描述")
+    private String remark;
+
+    /**
+     * 链接类型
+     */
+    @Excel(name = "链接类型")
+    private Integer linkType;
+
+    /**
+     * 权重
+     */
+    @Excel(name = "权重")
+    private Integer topValue;
+
+    /**
+     * 是否启用
+     */
+    @Excel(name = "是否启用")
+    private Integer isEnable;
+
+    /**
+     * 是否新窗口打开
+     */
+    @Excel(name = "是否新窗口打开")
+    private Integer isNewWindowOpen;
+
+    /**
+     * 更新时间
+     */
+    @Excel(name = "更新时间", databaseFormat = "yyyy-MM-dd HH:mm:ss", format = "yyyy-MM-dd", width = 20)
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Date updateDate;
+
+    /**
+     * 创建时间
+     */
+    @Excel(name = "创建时间", databaseFormat = "yyyy-MM-dd HH:mm:ss", format = "yyyy-MM-dd", width = 20)
+    @TableField(fill = FieldFill.INSERT)
+    private Date createDate;
+
+}
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/enums/BlogFriendshipLinkExceptionEnum.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/enums/BlogFriendshipLinkExceptionEnum.java
new file mode 100644
index 0000000..5ac788a
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/enums/BlogFriendshipLinkExceptionEnum.java
@@ -0,0 +1,64 @@
+/*
+Copyright [2020] [https://www.xiaonuo.vip]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+
+1.请不要删除和修改根目录下的LICENSE文件。
+2.请不要删除和修改Snowy源码头部的版权声明。
+3.请保留源码和相关描述文件的项目出处,作者声明等。
+4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.modular.blogfriendshiplink.enums;
+
+import vip.xiaonuo.core.annotion.ExpEnumType;
+import vip.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum;
+import vip.xiaonuo.core.factory.ExpEnumCodeFactory;
+import vip.xiaonuo.sys.core.consts.SysExpEnumConstant;
+
+/**
+ * 友情链接
+ *
+ * @author inleft
+ * @date 2022-02-17 15:05:44
+ */
+@ExpEnumType(module = SysExpEnumConstant.SNOWY_SYS_MODULE_EXP_CODE)
+public enum BlogFriendshipLinkExceptionEnum implements AbstractBaseExceptionEnum {
+
+    /**
+     * 数据不存在
+     */
+    NOT_EXIST(1, "此数据不存在");
+
+    private final Integer code;
+
+    private final String message;
+        BlogFriendshipLinkExceptionEnum(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    @Override
+    public Integer getCode() {
+        return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code);
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+}
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/mapper/BlogFriendshipLinkMapper.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/mapper/BlogFriendshipLinkMapper.java
new file mode 100644
index 0000000..7170fac
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/mapper/BlogFriendshipLinkMapper.java
@@ -0,0 +1,37 @@
+/*
+Copyright [2020] [https://www.xiaonuo.vip]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+
+1.请不要删除和修改根目录下的LICENSE文件。
+2.请不要删除和修改Snowy源码头部的版权声明。
+3.请保留源码和相关描述文件的项目出处,作者声明等。
+4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.modular.blogfriendshiplink.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import vip.xiaonuo.modular.blogfriendshiplink.entity.BlogFriendshipLink;
+
+/**
+ * 友情链接
+ *
+ * @author inleft
+ * @date 2022-02-17 15:05:44
+ */
+public interface BlogFriendshipLinkMapper extends BaseMapper<BlogFriendshipLink> {
+}
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/mapper/mapping/BlogFriendshipLinkMapper.xml b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/mapper/mapping/BlogFriendshipLinkMapper.xml
new file mode 100644
index 0000000..af9475a
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/mapper/mapping/BlogFriendshipLinkMapper.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="vip.xiaonuo.modular.blogfriendshiplink.mapper.BlogFriendshipLinkMapper">
+
+</mapper>
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogFriendshipLinkParam.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogFriendshipLinkParam.java
new file mode 100644
index 0000000..00fc567
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogFriendshipLinkParam.java
@@ -0,0 +1,104 @@
+/*
+Copyright [2020] [https://www.xiaonuo.vip]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+
+1.请不要删除和修改根目录下的LICENSE文件。
+2.请不要删除和修改Snowy源码头部的版权声明。
+3.请保留源码和相关描述文件的项目出处,作者声明等。
+4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.modular.blogfriendshiplink.param;
+
+import lombok.Data;
+import vip.xiaonuo.core.pojo.base.param.BaseParam;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+* 友情链接参数类
+ *
+ * @author inleft
+ * @date 2022-02-17 15:05:44
+*/
+@Data
+public class BlogFriendshipLinkParam extends BaseParam {
+
+    /**
+     * 自增id
+     */
+    @NotNull(message = "自增id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class})
+    private Long id;
+
+    /**
+     * 名称
+     */
+    @NotBlank(message = "名称不能为空,请检查name参数", groups = {add.class, edit.class})
+    private String name;
+
+    /**
+     * url地址
+     */
+    @NotBlank(message = "url地址不能为空,请检查url参数", groups = {add.class, edit.class})
+    private String url;
+
+    /**
+     * 头像地址
+     */
+    private String avatar;
+
+    /**
+     * 描述
+     */
+    //@NotBlank(message = "描述不能为空,请检查remark参数", groups = {add.class, edit.class})
+    private String remark;
+
+    /**
+     * 链接类型
+     */
+    @NotNull(message = "链接类型不能为空,请检查linkType参数", groups = {add.class, edit.class})
+    private Integer linkType;
+
+    /**
+     * 权重
+     */
+    @NotNull(message = "权重不能为空,请检查topValue参数", groups = {add.class, edit.class})
+    private Integer topValue;
+
+    /**
+     * 是否启用
+     */
+    private Integer isEnable;
+
+    /**
+     * 是否新窗口打开
+     */
+    @NotNull(message = "是否新窗口打开不能为空,请检查isNewWindowOpen参数", groups = {add.class, edit.class})
+    private Integer isNewWindowOpen;
+
+    /**
+     * 更新时间
+     */
+    private String updateDate;
+
+    /**
+     * 创建时间
+     */
+    private String createDate;
+
+}
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogFriendshipLinkVo.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogFriendshipLinkVo.java
new file mode 100644
index 0000000..3535d86
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogFriendshipLinkVo.java
@@ -0,0 +1,76 @@
+/*
+Copyright [2020] [https://www.xiaonuo.vip]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+
+1.请不要删除和修改根目录下的LICENSE文件。
+2.请不要删除和修改Snowy源码头部的版权声明。
+3.请保留源码和相关描述文件的项目出处,作者声明等。
+4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.modular.blogfriendshiplink.param;
+
+import lombok.Data;
+
+/**
+ * 友情链接
+ *
+ * @author inleft
+ * @date 2022-02-17 15:05:44
+ */
+@Data
+public class BlogFriendshipLinkVo {
+
+    /**
+     * 自增id
+     */
+    private Long id;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * url地址
+     */
+    private String url;
+
+
+    /**
+     * 头像地址
+     */
+    private String avatar;
+
+    /**
+     * 描述
+     */
+    private String remark;
+
+    /**
+     * 链接类型
+     */
+    private Integer linkType;
+
+
+    /**
+     * 是否新窗口打开
+     */
+    private Integer isNewWindowOpen;
+
+
+}
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogLinkVo.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogLinkVo.java
new file mode 100644
index 0000000..a5e6383
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/param/BlogLinkVo.java
@@ -0,0 +1,45 @@
+/*
+Copyright [2020] [https://www.xiaonuo.vip]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+
+1.请不要删除和修改根目录下的LICENSE文件。
+2.请不要删除和修改Snowy源码头部的版权声明。
+3.请保留源码和相关描述文件的项目出处,作者声明等。
+4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.modular.blogfriendshiplink.param;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 友情链接参数类
+ *
+ * @author inleft
+ * @date 2022-02-17 15:05:44
+ */
+@Data
+public class BlogLinkVo {
+
+    private String groupName;
+
+
+    private List<BlogFriendshipLinkVo> linkVoList;
+
+}
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/service/BlogFriendshipLinkService.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/service/BlogFriendshipLinkService.java
new file mode 100644
index 0000000..61c7330
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/service/BlogFriendshipLinkService.java
@@ -0,0 +1,97 @@
+/*
+Copyright [2020] [https://www.xiaonuo.vip]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+
+1.请不要删除和修改根目录下的LICENSE文件。
+2.请不要删除和修改Snowy源码头部的版权声明。
+3.请保留源码和相关描述文件的项目出处,作者声明等。
+4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.modular.blogfriendshiplink.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import vip.xiaonuo.core.pojo.page.PageResult;
+import vip.xiaonuo.modular.blogfriendshiplink.entity.BlogFriendshipLink;
+import vip.xiaonuo.modular.blogfriendshiplink.param.BlogFriendshipLinkParam;
+import java.util.List;
+
+/**
+ * 友情链接service接口
+ *
+ * @author inleft
+ * @date 2022-02-17 15:05:44
+ */
+public interface BlogFriendshipLinkService extends IService<BlogFriendshipLink> {
+
+    /**
+     * 查询友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    PageResult<BlogFriendshipLink> page(BlogFriendshipLinkParam blogFriendshipLinkParam);
+
+    /**
+     * 友情链接列表
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    List<BlogFriendshipLink> list(BlogFriendshipLinkParam blogFriendshipLinkParam);
+
+    /**
+     * 添加友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    void add(BlogFriendshipLinkParam blogFriendshipLinkParam);
+
+    /**
+     * 删除友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    void delete(List<BlogFriendshipLinkParam> blogFriendshipLinkParamList);
+
+    /**
+     * 编辑友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    void edit(BlogFriendshipLinkParam blogFriendshipLinkParam);
+
+    /**
+     * 查看友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+     BlogFriendshipLink detail(BlogFriendshipLinkParam blogFriendshipLinkParam);
+
+    /**
+     * 导出友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+     void export(BlogFriendshipLinkParam blogFriendshipLinkParam);
+
+}
diff --git a/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/service/impl/BlogFriendshipLinkServiceImpl.java b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/service/impl/BlogFriendshipLinkServiceImpl.java
new file mode 100644
index 0000000..042664b
--- /dev/null
+++ b/snowy-main/src/main/java/vip/xiaonuo/modular/blogfriendshiplink/service/impl/BlogFriendshipLinkServiceImpl.java
@@ -0,0 +1,140 @@
+/*
+Copyright [2020] [https://www.xiaonuo.vip]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+
+1.请不要删除和修改根目录下的LICENSE文件。
+2.请不要删除和修改Snowy源码头部的版权声明。
+3.请保留源码和相关描述文件的项目出处,作者声明等。
+4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
+6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.modular.blogfriendshiplink.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.core.exception.ServiceException;
+import vip.xiaonuo.core.factory.PageFactory;
+import vip.xiaonuo.core.pojo.page.PageResult;
+import vip.xiaonuo.core.util.PoiUtil;
+import vip.xiaonuo.modular.blogfriendshiplink.entity.BlogFriendshipLink;
+import vip.xiaonuo.modular.blogfriendshiplink.enums.BlogFriendshipLinkExceptionEnum;
+import vip.xiaonuo.modular.blogfriendshiplink.mapper.BlogFriendshipLinkMapper;
+import vip.xiaonuo.modular.blogfriendshiplink.param.BlogFriendshipLinkParam;
+import vip.xiaonuo.modular.blogfriendshiplink.service.BlogFriendshipLinkService;
+
+import java.util.List;
+
+/**
+ * 友情链接service接口实现类
+ *
+ * @author inleft
+ * @date 2022-02-17 15:05:44
+ */
+@Service
+public class BlogFriendshipLinkServiceImpl extends ServiceImpl<BlogFriendshipLinkMapper, BlogFriendshipLink> implements BlogFriendshipLinkService {
+
+    @Override
+    public PageResult<BlogFriendshipLink> page(BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        QueryWrapper<BlogFriendshipLink> queryWrapper = new QueryWrapper<>();
+        if (ObjectUtil.isNotNull(blogFriendshipLinkParam)) {
+
+            // 根据名称 查询
+            if (ObjectUtil.isNotEmpty(blogFriendshipLinkParam.getName())) {
+                queryWrapper.lambda().like(BlogFriendshipLink::getName, blogFriendshipLinkParam.getName());
+            }
+            // 根据链接类型 查询
+            if (ObjectUtil.isNotEmpty(blogFriendshipLinkParam.getLinkType())) {
+                queryWrapper.lambda().eq(BlogFriendshipLink::getLinkType, blogFriendshipLinkParam.getLinkType());
+            }
+            // 根据权重 查询
+            if (ObjectUtil.isNotEmpty(blogFriendshipLinkParam.getTopValue())) {
+                queryWrapper.lambda().eq(BlogFriendshipLink::getTopValue, blogFriendshipLinkParam.getTopValue());
+            }
+            // 根据是否启用 查询
+            if (ObjectUtil.isNotEmpty(blogFriendshipLinkParam.getIsEnable())) {
+                queryWrapper.lambda().eq(BlogFriendshipLink::getIsEnable, blogFriendshipLinkParam.getIsEnable());
+            }
+            // 根据是否新窗口打开 查询
+            if (ObjectUtil.isNotEmpty(blogFriendshipLinkParam.getIsNewWindowOpen())) {
+                queryWrapper.lambda().eq(BlogFriendshipLink::getIsNewWindowOpen, blogFriendshipLinkParam.getIsNewWindowOpen());
+            }
+            // 根据创建时间 查询
+            if (ObjectUtil.isNotEmpty(blogFriendshipLinkParam.getCreateDate())) {
+                queryWrapper.lambda().eq(BlogFriendshipLink::getCreateDate, blogFriendshipLinkParam.getCreateDate());
+            }
+        }
+        return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper));
+    }
+
+    @Override
+    public List<BlogFriendshipLink> list(BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        return this.list();
+    }
+
+    @Override
+    public void add(BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        BlogFriendshipLink blogFriendshipLink = new BlogFriendshipLink();
+        BeanUtil.copyProperties(blogFriendshipLinkParam, blogFriendshipLink);
+        this.save(blogFriendshipLink);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<BlogFriendshipLinkParam> blogFriendshipLinkParamList) {
+        blogFriendshipLinkParamList.forEach(blogFriendshipLinkParam -> {
+            this.removeById(blogFriendshipLinkParam.getId());
+        });
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        BlogFriendshipLink blogFriendshipLink = this.queryBlogFriendshipLink(blogFriendshipLinkParam);
+        BeanUtil.copyProperties(blogFriendshipLinkParam, blogFriendshipLink);
+        this.updateById(blogFriendshipLink);
+    }
+
+    @Override
+    public BlogFriendshipLink detail(BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        return this.queryBlogFriendshipLink(blogFriendshipLinkParam);
+    }
+
+    /**
+     * 获取友情链接
+     *
+     * @author inleft
+     * @date 2022-02-17 15:05:44
+     */
+    private BlogFriendshipLink queryBlogFriendshipLink(BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        BlogFriendshipLink blogFriendshipLink = this.getById(blogFriendshipLinkParam.getId());
+        if (ObjectUtil.isNull(blogFriendshipLink)) {
+            throw new ServiceException(BlogFriendshipLinkExceptionEnum.NOT_EXIST);
+        }
+        return blogFriendshipLink;
+    }
+
+    @Override
+    public void export(BlogFriendshipLinkParam blogFriendshipLinkParam) {
+        List<BlogFriendshipLink> list = this.list(blogFriendshipLinkParam);
+        PoiUtil.exportExcelWithStream("SnowyBlogFriendshipLink.xls", BlogFriendshipLink.class, list);
+    }
+
+}
diff --git a/snowy-main/src/main/resources/application-local.yml b/snowy-main/src/main/resources/application-local.yml
index a56b002..33a7b15 100644
--- a/snowy-main/src/main/resources/application-local.yml
+++ b/snowy-main/src/main/resources/application-local.yml
@@ -13,6 +13,11 @@
     port: 6379
     password: mpw:xMwjz92TmxCDCJYvcfwIZA==
 
+mybatis-plus:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+
+
+
 # Oracle数据库
 #spring:
 #  datasource:
diff --git a/snowy-main/src/main/resources/application-prod.yml b/snowy-main/src/main/resources/application-prod.yml
index ea82253..58313ea 100644
--- a/snowy-main/src/main/resources/application-prod.yml
+++ b/snowy-main/src/main/resources/application-prod.yml
@@ -1,14 +1,16 @@
-JwtAuthenticationTokenFilter# Mysql数据库
 spring:
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://localhost:3306/snowy-pub?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true
-    username: root
-    password: 123456
+    url: mpw:pOR3O+UltK0HTNqvX/MeDsJDOCUeDoAnP5TsPqREtj384CDziueYbj8Z0bha3LWM1LdIKYTQuyS9cEaTceRHtJQIZymWMwsKEV++JDZgqBVnx9B5ztb3dGk3IhB678/E/rH1lJ8Jpzw21EkgPcie3A6ELU62rlJUycpcnK95oBDXKYZeMclnNdMVH5PVP70z5cWc5Ai741/1a/doxqo92IFnBMMyJG+r4B7KXBf3/LMm6xpvUm6e4xYPzpoy4hhNFp4TfNBWcsO0BEMH1GJaMw==
+    username: mpw:Zr3vDuEdTm3NPpydFgU2eA==
+    password: mpw:KWYe3LgV6I2rToYRn3k35g==
+#    url: jdbc:mysql://localhost:3306/blog?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true
+#    username: root
+#    password: root
   redis:
-    host: localhost
+    host: mpw:74taZBJwkaUlVuljmdqsRg==
     port: 6379
-    password:
+    password: mpw:xMwjz92TmxCDCJYvcfwIZA==
 
 # Oracle数据库
 #spring:
diff --git a/snowy-main/src/main/resources/application.yml b/snowy-main/src/main/resources/application.yml
index b992ef6..8378d9e 100644
--- a/snowy-main/src/main/resources/application.yml
+++ b/snowy-main/src/main/resources/application.yml
@@ -27,8 +27,7 @@
     cache-enabled: true
     lazy-loading-enabled: true
     multiple-result-sets-enabled: true
-    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
-#    log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+    log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
   global-config:
     banner: false
     db-config:

--
Gitblit v1.9.1