ss
jiangping
2025-06-19 1c7a34a34497107eb5bb4501bfd7ee0b72e5c9f7
ss
已添加7个文件
765 ■■■■■ 文件已修改
admin/src/api/business/carousel.js 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/information.js 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaCarouselWindow.vue 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaInformationWindow.vue 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/carousel.vue 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/information.vue 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/ContextFinalizer.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/carousel.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
import request from '../../utils/request'
// æŸ¥è¯¢
export function fetchList (data) {
  return request.post('/business/carousel/page', data, {
    trim: true
  })
}
// å¯¼å‡ºExcel
export function exportExcel (data) {
  return request.post('/business/carousel/exportExcel', data, {
    trim: true,
    download: true
  })
}
// åˆ›å»º
export function create (data) {
  return request.post('/business/carousel/create', data)
}
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/business/carousel/updateById', data)
}
export function updateStatus (data) {
  return request.post('/business/carousel/updateStatus', data)
}
// åˆ é™¤
export function deleteById (id) {
  return request.get(`/business/carousel/delete/${id}`)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
  return request.get('/business/carousel/delete/batch', {
    params: {
      ids
    }
  })
}
export function getFoodDataVO () {
  return request.get('/business/carousel/getFoodDataVO')
}
// ä¿®æ”¹åº•部访配置
export function updFoodData (data) {
  return request.post('/business/carousel/updFoodData', data)
}
admin/src/api/business/information.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
import request from '../../utils/request'
// æŸ¥è¯¢
export function fetchList (data) {
  return request.post('/business/information/page', data, {
    trim: true
  })
}
// å¯¼å‡ºExcel
export function exportExcel (data) {
  return request.post('/business/information/exportExcel', data, {
    trim: true,
    download: true
  })
}
// åˆ›å»º
export function create (data) {
  return request.post('/business/information/create', data)
}
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/business/information/updateById', data)
}
export function updateStatus (data) {
  return request.post('/business/information/updateStatus', data)
}
// åˆ é™¤
export function deleteById (id) {
  return request.get(`/business/information/delete/${id}`)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
  return request.get('/business/information/delete/batch', {
    params: {
      ids
    }
  })
}
admin/src/components/business/OperaCarouselWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,141 @@
<template>
  <GlobalWindow
    :title="title"
    width="60%"
    :visible.sync="visible"
    :confirm-working="isWorking"
    @confirm="confirm"
  >
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="标题" prop="title">
        <el-input v-model="form.title" placeholder="请输入标题" v-trim/>
      </el-form-item>
      <el-form-item label="概述" prop="detail">
        <el-input  type="textarea"  v-model="form.detail" placeholder="请输入描述" v-trim/>
      </el-form-item>
      <div style="display: flex">
        <el-form-item label="缩略图" prop="thumbnailImgurl" style="display:inline-block;flex: 1">
          <div class="upload_wrap">
            <UploadAvatarImage :file="{ 'imgurlfull': form.fullThumbnailImgurl, 'imgurl': form.thumbnailImgurl }" :uploadData="{folder:''}"
                               @uploadSuccess="uploadAvatarSuccess1"   />
          </div>
        </el-form-item>
        <el-form-item label="高清图" prop="imgurl"  style="display:inline-block;flex: 3">
          <div class="upload_wrap">
            <UploadAvatarImage :file="{ 'imgurlfull': form.fullImgurl, 'imgurl': form.imgurl }" :uploadData="{folder:''}"
                               @uploadSuccess="uploadAvatarSuccess"   />
          </div>
        </el-form-item>
      </div>
      <el-form-item label="内容类型" prop="jumpType" >
        <el-radio-group v-model="form.jumpType">
          <el-radio :label="0" :value="0">外链</el-radio>
          <el-radio :label="1" :value="1">富文本</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="跳转内容" prop="content"   >
        <RichEditor v-if="form.jumpType === 1"  :richData="form.content" :styleEditor="styleEditor"  @getWangedditor="getWangedditor" :readonly="false"/>
        <el-input v-if="form.jumpType === 0"  v-model="form.content" placeholder="请输入跳转链接地址" v-trim/>
      </el-form-item>
      <el-form-item label="状态" prop="status" required class="form-item-status">
        <el-switch v-model="form.status" :active-value="0" :inactive-value="1" active-color="#13ce66"/>
      </el-form-item>
      <el-form-item label="排序码(降序)" prop="sortnum">
        <el-input v-model="form.sortnum" 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>
  </GlobalWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import RichEditor from '@/components/common/RichEditor'
import UploadAvatarImage from '@/components/common/UploadAvatarImage'
export default {
  name: 'OperaCarouselWindow',
  extends: BaseOpera,
  components: { GlobalWindow, UploadAvatarImage, RichEditor },
  data () {
    return {
      // è¡¨å•数据
      styleEditor: 'border: 1px solid #ccc;display: inline-block;height:500px',
      form: {
        id: null,
        remark: '',
        title: '',
        detail: '',
        imgurl: '',
        fullImgurl: '',
        thumbnailImgurl: '',
        fullThumbnailImgurl: '',
        jumpType: 0,
        content: '',
        sortnum: '',
        status: 0
      },
      // éªŒè¯è§„则
      rules: {
        title: [
          { required: true, message: '请输入标题' }
        ]
      }
    }
  },
  created () {
    this.config({
      api: '/business/carousel',
      'field.id': 'id'
    })
  },
  methods: {
    open (title, target) {
      this.title = title
      this.visible = true
      // æ–°å»º
      if (target == null) {
        this.$nextTick(() => {
          this.$refs.form.resetFields()
          this.form= {
            id: null,
            remark: '',
            title: '',
            detail: '',
            imgurl: '',
            imgurlFull: '',
            thumbnailImgurl: '',
            thumbnailImgurlFull: '',
            jumpType: 0,
            content: '',
            sortnum: '',
            status: 0
          }
        })
        return
      }
      // ç¼–辑
      this.$nextTick(() => {
        for (const key in this.form) {
          this.form[key] = target[key]
        }
      })
    },
    // ä¸Šä¼ å›¾ç‰‡
    getWangedditor (val) {
      this.form.content = val
    },
    uploadAvatarSuccess (file) {
      this.form.imgurl = file.imgurl
      this.form.fullImgurl = file.imgurlfull
    },
    uploadAvatarSuccess1 (file) {
      this.form.thumbnailImgurl = file.imgurl
      this.form.fullThumbnailImgurl = file.imgurlfull
    }
  }
}
</script>
admin/src/components/business/OperaInformationWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,123 @@
<template>
  <GlobalWindow
      :title="title"
      width="60%"
      :visible.sync="visible"
      :confirm-working="isWorking"
      @confirm="confirm"
  >
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="标题" prop="title">
        <el-input v-model="form.title" placeholder="请输入标题" v-trim/>
      </el-form-item>
      <el-form-item label="列表图" prop="imgurl" >
        <div class="upload_wrap">
          <UploadAvatarImage :file="{ 'imgurlfull': form.fullImgurl, 'imgurl': form.imgurl }" :uploadData="{folder:''}"   @uploadSuccess="uploadAvatarSuccess"   />
        </div>
      </el-form-item>
      <el-form-item label="简介" prop="detail">
        <el-input  type="textarea"  v-model="form.detail" placeholder="请输入简介" v-trim/>
      </el-form-item>
      <el-form-item label="发布日期" prop="releaseDate" >
        <el-date-picker v-model="form.releaseDate" value-format="yyyy-MM-dd HH:mm:ss" type="datetime">  </el-date-picker>
      </el-form-item>
      <el-form-item label="内容" prop="content"   >
        <RichEditor    :richData="form.content" :styleEditor="styleEditor"  @getWangedditor="getWangedditor" :readonly="false"/>
      </el-form-item>
      <el-form-item label="状态" prop="status" required class="form-item-status">
        <el-switch v-model="form.status" :active-value="0" :inactive-value="1" active-color="#13ce66"/>
      </el-form-item>
      <el-form-item label="排序码(降序)" prop="sortnum">
        <el-input v-model="form.sortnum" 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>
  </GlobalWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import RichEditor from '@/components/common/RichEditor'
import UploadAvatarImage from '@/components/common/UploadAvatarImage'
export default {
  name: 'OperaInformationWindow',
  extends: BaseOpera,
  components: { GlobalWindow, UploadAvatarImage, RichEditor },
  data () {
    return {
      // è¡¨å•数据
      styleEditor: 'border: 1px solid #ccc;display: inline-block;height:500px',
      form: {
        id: null,
        remark: '',
        title: '',
        detail: '',
        imgurl: '',
        fullImgurl: '',
        jumpType: 0,
        content: '',
        releaseDate: new Date(),
        sortnum: '',
        status: 0
      },
      // éªŒè¯è§„则
      rules: {
        title: [
          { required: true, message: '请输入标题' }
        ]
      }
    }
  },
  created () {
    this.config({
      api: '/business/information',
      'field.id': 'id'
    })
  },
  methods: {
    open (title, target) {
      this.title = title
      this.visible = true
      // æ–°å»º
      if (target == null) {
        this.$nextTick(() => {
          this.$refs.form.resetFields()
          this.form= {
            id: null,
            remark: '',
            title: '',
            detail: '',
            releaseDate: new Date(),
            imgurl: '',
            imgurlFull: '',
            thumbnailImgurl: '',
            thumbnailImgurlFull: '',
            jumpType: 0,
            content: '',
            sortnum: '',
            status: 0
          }
        })
        return
      }
      // ç¼–辑
      this.$nextTick(() => {
        for (const key in this.form) {
          this.form[key] = target[key]
        }
      })
    },
    // ä¸Šä¼ å›¾ç‰‡
    getWangedditor (val) {
      this.form.content = val
    },
    uploadAvatarSuccess (file) {
      this.form.imgurl = file.imgurl
      this.form.fullImgurl = file.imgurlfull
    }
  }
}
</script>
admin/src/views/business/carousel.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,191 @@
<template>
  <TableLayout :permissions="['business:carousel:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="标题" prop="title">
        <el-input v-model="searchForm.title" clearable placeholder="请输入标题" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="searchForm.status" clearable @change="search" placeholder="状态">
          <el-option label="正常" value="1"></el-option>
          <el-option label="禁用" value="0"></el-option>
        </el-select>
      </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:carousel:create', 'business:carousel:delete']">
        <li><el-button type="primary" @click="$refs.operaCarouselWindow.open('新建轮播图')" icon="el-icon-plus" v-permissions="['business:carousel:create']">新建</el-button></li>
        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:carousel: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="title" label="标题" min-width="150px"></el-table-column>
        <el-table-column prop="thumbnailImgurl" label="缩略图" min-width="100px">
          <template slot-scope="{row}">
            <el-image v-if="row.fullThumbnailImgurl" style="width: 60px; height: 60px" :src="row.fullThumbnailImgurl"
                      :preview-src-list="[row.fullThumbnailImgurl]">
            </el-image>
          </template>
        </el-table-column>
        <el-table-column prop="imgurl" label="高清图" min-width="100px">
          <template slot-scope="{row}">
            <el-image v-if="row.fullImgurl" style="width: 60px; height: 60px" :src="row.fullImgurl"
                      :preview-src-list="[row.fullImgurl]">
            </el-image>
          </template>
        </el-table-column>
        <el-table-column prop="detail" label="概述" min-width="200px"></el-table-column>
        <el-table-column prop="jumpType" label="跳转类型" align="center" min-width="150px">
          <template slot-scope="{row}">
              <span v-if="row.jumpType == 0 && row.content!=null && row.content!=''"><a :href="row.content" target="_blank">点击跳转</a></span>
              <span v-else-if="row.jumpType == 1 && row.content!=null && row.content!=''"><el-button @click="showContentDo(row)" >查看内容</el-button></span>
              <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" min-width="100px">
          <template slot-scope="{row}">
            <el-switch @change="changeStatus($event, row)" v-model="row.status" active-color="#13ce66"
                       inactive-color="#ff4949" :active-value="0" :inactive-value="1">
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column prop="remark" label="备注" min-width="100px"></el-table-column>
        <el-table-column prop="sortnum" label="排序码" min-width="80px"></el-table-column>
        <el-table-column prop="createDate" label="创建时间" min-width="150px"></el-table-column>
        <el-table-column prop="editDate" label="更新时间" min-width="150px"></el-table-column>
        <el-table-column
          v-if="containPermissions(['business:carousel:update', 'business:carousel:delete'])"
          label="操作"
          min-width="120"
          fixed="right"
        >
          <template slot-scope="{row}">
            <el-button type="text" @click="$refs.operaCarouselWindow.open('编辑轮播图', row)" icon="el-icon-edit" v-permissions="['business:carousel:update']">编辑</el-button>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:carousel:delete']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
        :pagination="tableData.pagination"
      >
      </pagination>
    </template>
    <!-- æ–°å»º/修改 -->
    <OperaCarouselWindow ref="operaCarouselWindow" @success="handlePageChange"/>
    <el-dialog
        class="center-title"
        :title="showTitle||'显示内容'"
        width="70%"
        height="70%"
        text="内容"
        :visible.sync="visible1"
        append-to-body
    >
      <div class="agree-list"  v-html="showContent">
      </div>
      <template  v-slot:footer>
        <el-button @click="visible1=false">返回</el-button>
      </template>
    </el-dialog>
  </TableLayout>
</template>
<script>
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import OperaCarouselWindow from '@/components/business/OperaCarouselWindow'
export default {
  name: 'Carousel',
  extends: BaseTable,
  components: { TableLayout, Pagination, OperaCarouselWindow },
  data () {
    return {
      // æœç´¢
      visible1: false,
      showContent: '',
      showTitle: '',
      searchForm: {
        id: '',
        creator: '',
        createDate: '',
        editor: '',
        editDate: '',
        isdeleted: '',
        remark: '',
        title: '',
        describe: '',
        imgurl: '',
        thumbnailImgurl: '',
        type: '',
        jumpType: '',
        contnet: '',
        sortnum: '',
        status: ''
      }
    }
  },
  created () {
    this.config({
      module: '轮播图',
      api: '/business/carousel',
      'field.id': 'id',
      'field.main': 'id'
    })
    this.search()
  },
  methods: {
    showContentDo(row){
      this.showTitle=row.showTitle
      this.showContent=row.content
      this.visible1=true
    },
    changeStatus (e, row) {
      this.canvisiting = true
      this.api.updateStatus({ id: row.id, status: e })
        .then(res => {
          this.$tip.apiSuccess(res || '操作成功')
          this.search()
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
        .finally(() => {
          this.canvisiting = false
        })
        .catch(() => { })
    }
  }
}
</script>
<style scoped lang="scss">
.agree-list{
  height: 550px;
  //max-height: 50%;
  overflow: auto;
}
/deep/ .window__body {
  .table-content {
    padding: 0;
    .table-wrap {
      padding-top: 0;
    }
  }
}
</style>
admin/src/views/business/information.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,184 @@
<template>
  <TableLayout :permissions="['business:information:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="标题" prop="title">
        <el-input v-model="searchForm.title" clearable placeholder="请输入标题" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="searchForm.status" clearable @change="search" placeholder="状态">
          <el-option label="正常" value="1"></el-option>
          <el-option label="禁用" value="0"></el-option>
        </el-select>
      </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:information:create', 'business:information:delete']">
        <li><el-button type="primary" @click="$refs.operaInformationWindow.open('新建动态资讯')" icon="el-icon-plus" v-permissions="['business:information:create']">新建</el-button></li>
        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:information: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="title" label="标题" min-width="150px"></el-table-column>
        <el-table-column prop="releaseDate" label="发布时间" min-width="150px"></el-table-column>
        <el-table-column prop="imgurl" label="列表图" min-width="100px">
          <template slot-scope="{row}">
            <el-image v-if="row.fullImgurl" style="width: 60px; height: 60px" :src="row.fullImgurl"
                      :preview-src-list="[row.fullImgurl]">
            </el-image>
          </template>
        </el-table-column>
        <el-table-column prop="detail" label="简介" min-width="200px"></el-table-column>
        <el-table-column prop="jumpType" label="内容" align="center" min-width="150px">
          <template slot-scope="{row}">
            <span v-if=  "row.content!=null && row.content!=''"><el-button @click="showContentDo(row)" >查看内容</el-button></span>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" min-width="100px">
          <template slot-scope="{row}">
            <el-switch @change="changeStatus($event, row)" v-model="row.status" active-color="#13ce66"
                       inactive-color="#ff4949" :active-value="0" :inactive-value="1">
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column prop="remark" label="备注" min-width="100px"></el-table-column>
        <el-table-column prop="sortnum" label="排序码" min-width="80px"></el-table-column>
        <el-table-column prop="createDate" label="创建时间" min-width="150px"></el-table-column>
        <el-table-column prop="editDate" label="更新时间" min-width="150px"></el-table-column>
        <el-table-column
            v-if="containPermissions(['business:information:update', 'business:information:delete'])"
            label="操作"
            min-width="120"
            fixed="right"
        >
          <template slot-scope="{row}">
            <el-button type="text" @click="$refs.operaInformationWindow.open('编辑动态资讯', row)" icon="el-icon-edit" v-permissions="['business:information:update']">编辑</el-button>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:information:delete']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination
          @size-change="handleSizeChange"
          @current-change="handlePageChange"
          :pagination="tableData.pagination"
      >
      </pagination>
    </template>
    <!-- æ–°å»º/修改 -->
    <OperaInformationWindow ref="operaInformationWindow" @success="handlePageChange"/>
    <el-dialog
        class="center-title"
        :title="showTitle||'显示内容'"
        width="70%"
        height="70%"
        text="内容"
        :visible.sync="visible1"
        append-to-body
    >
      <div class="agree-list"  v-html="showContent">
      </div>
      <template  v-slot:footer>
        <el-button @click="visible1=false">返回</el-button>
      </template>
    </el-dialog>
  </TableLayout>
</template>
<script>
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import OperaInformationWindow from '@/components/business/OperaInformationWindow'
export default {
  name: 'Information',
  extends: BaseTable,
  components: { TableLayout, Pagination, OperaInformationWindow },
  data () {
    return {
      // æœç´¢
      visible1: false,
      showContent: '',
      showTitle: '',
      searchForm: {
        id: '',
        creator: '',
        createDate: '',
        editor: '',
        editDate: '',
        isdeleted: '',
        remark: '',
        title: '',
        describe: '',
        imgurl: '',
        thumbnailImgurl: '',
        type: '',
        jumpType: '',
        contnet: '',
        sortnum: '',
        status: ''
      }
    }
  },
  created () {
    this.config({
      module: '动态咨询',
      api: '/business/information',
      'field.id': 'id',
      'field.main': 'id'
    })
    this.search()
  },
  methods: {
    showContentDo (row) {
      this.showTitle = row.showTitle
      this.showContent = row.content
      this.visible1 = true
    },
    changeStatus (e, row) {
      this.canvisiting = true
      this.api.updateStatus({ id: row.id, status: e })
        .then(res => {
          this.$tip.apiSuccess(res || '操作成功')
          this.search()
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
        .finally(() => {
          this.canvisiting = false
        })
        .catch(() => { })
    }
  }
}
</script>
<style scoped lang="scss">
.agree-list{
  height: 550px;
  //max-height: 50%;
  overflow: auto;
}
/deep/ .window__body {
  .table-content {
    padding: 0;
    .table-wrap {
      padding-top: 0;
    }
  }
}
</style>
server/src/main/java/com/doumee/ContextFinalizer.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.doumee;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
//@WebListener
public class ContextFinalizer implements ServletContextListener{
    public void contextInitialized(ServletContextEvent sce) {}
    public void contextDestroyed(ServletContextEvent sce) {
        Enumeration<Driver> drivers = DriverManager.getDrivers();
        Driver d = null;
        while (drivers.hasMoreElements()) {
            try {
                d = drivers.nextElement();
                DriverManager.deregisterDriver(d);
            } catch (SQLException ex) {
            }
        }
        try {
            // æ³¨æ„ï¼šmysql8版本的jar好像shutdown方法私有了,只能调用checkedShutdown或uncheckedShutdown
            AbandonedConnectionCleanupThread.checkedShutdown();
        } catch ( Exception e) {
            e.printStackTrace();
        }
    }
}