links.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <template>
  2. <div class="container">
  3. <el-card class="box-card">
  4. <div slot="header" class="clearfix">
  5. <span>友情链接管理</span>
  6. <el-button style="float: right; padding: 3px 0" type="text" @click="adduser">添加友情链接</el-button>
  7. </div>
  8. <div class="main">
  9. <naf-grid ref="grid" @edit="edit" @delete="deletelinks" :data="linksList" :meta="meta" :total="total" @query="query"></naf-grid>
  10. </div>
  11. </el-card>
  12. <dialog-drawer type="dialog" :visible="visible" :title="isNew ? '修改友情链接' : '添加友情链接'" @close="close" :width="'30%'">
  13. <template v-slot:content>
  14. <naf-form v-if="visible" ref="ruleForm" @save="save" :meta="formmeta" :rules="rules" :data="is_data">
  15. <template v-slot:field="{ item }">
  16. <!-- 图片上传 -->
  17. <el-upload
  18. v-if="item.name == 'path'"
  19. class="avatar-uploader avatar"
  20. action="/api/files/upload"
  21. :show-file-list="false"
  22. :on-success="handleAvatarSuccess"
  23. :before-upload="beforeAvatarUpload"
  24. :data="{ type: 'resource' }"
  25. :headers="myHeaders"
  26. >
  27. <img v-if="imageUrl" :src="imageUrl" class="avatar">
  28. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  29. </el-upload>
  30. </template>
  31. </naf-form>
  32. </template>
  33. </dialog-drawer>
  34. </div>
  35. </template>
  36. <script>
  37. import nafGrid from '@naf/data/tables/naf-grid'
  38. import dialogDrawer from '@naf/data/dialog -drawer'
  39. import nafForm from '@naf/data/form'
  40. import { createNamespacedHelpers } from 'vuex'
  41. const token = sessionStorage.getItem('token')
  42. const { mapState, mapActions } = createNamespacedHelpers('links')
  43. export default {
  44. components: {
  45. nafGrid,
  46. dialogDrawer,
  47. nafForm
  48. },
  49. data () {
  50. return {
  51. imageUrl: '',
  52. is_data: {},
  53. visible: false,
  54. myHeaders: { Authorization: `Bearer ${token}` },
  55. meta: [
  56. { name: 'name', title: '链接名称', filter: true },
  57. { name: 'path', title: '图片地址' },
  58. { name: 'links', title: '访问地址' }
  59. ],
  60. formmeta: [
  61. { name: 'path', title: '链接图片', slots: 'field' },
  62. { name: 'name', title: '链接名称' },
  63. { name: 'links', title: '访问地址' }
  64. ],
  65. rules: {
  66. name: [
  67. { required: true, message: '请输入链接名称', trigger: 'blur' }
  68. ],
  69. path: [
  70. { required: true, message: '请输入链接图片', trigger: 'blur' }
  71. ],
  72. links: [
  73. { required: true, message: '请输入访问地址', trigger: 'blur' }
  74. ]
  75. }
  76. }
  77. },
  78. methods: {
  79. ...mapActions(['linksquery', 'linkscreate', 'linksupdate', 'linksdelete']),
  80. // 添加
  81. adduser () {
  82. this.is_data = {}
  83. this.visible = true
  84. },
  85. // 删除
  86. async deletelinks (e) {
  87. this.$confirm('请确认删除', '提示', {
  88. confirmButtonText: '确定',
  89. cancelButtonText: '取消',
  90. type: 'warning'
  91. }).then(async () => {
  92. const res = await this.linksdelete(e)
  93. // eslint-disable-next-line eqeqeq
  94. if (res.errcode == 0) {
  95. this.$message.success('操作成功')
  96. this.query()
  97. this.$refs.grid.resetpage(-1)
  98. }
  99. }).catch(() => {
  100. this.$message({
  101. type: 'info',
  102. message: '已取消删除'
  103. })
  104. })
  105. },
  106. // 修改
  107. edit (e) {
  108. this.is_data = e
  109. this.visible = true
  110. if (e.path) this.imageUrl = e.path
  111. },
  112. // 查询
  113. async query ({ filter = {}, paging = {} } = {}) {
  114. await this.linksquery({ filter, paging })
  115. },
  116. // 保存按钮
  117. async save (e) {
  118. let res
  119. if (this.isNew) {
  120. // 修改
  121. res = await this.linksupdate(e)
  122. } else {
  123. // 添加
  124. res = await this.linkscreate(e)
  125. }
  126. // eslint-disable-next-line eqeqeq
  127. if (res.errcode == 0) {
  128. this.$message.success('操作成功')
  129. this.query()
  130. this.visible = false
  131. this.$refs.grid.resetpage(-1)
  132. this.imageUrl = ''
  133. }
  134. },
  135. // 关闭弹窗
  136. close () {
  137. this.visible = false
  138. this.imageUrl = ''
  139. },
  140. // 图片上传
  141. // 文件上传成功时的钩子
  142. handleAvatarSuccess (res, file) {
  143. this.is_data = this.$refs.ruleForm.form
  144. this.is_data.path = res.data.path
  145. this.imageUrl = URL.createObjectURL(file.raw)
  146. },
  147. // 上传文件之前的钩子
  148. beforeAvatarUpload (file) {
  149. const isJPG = file.type === 'image/jpeg'
  150. const isPNG = file.type === 'image/png'
  151. const isLt2M = file.size / 1024 / 1024 < 2
  152. if (!isJPG && !isPNG) {
  153. this.$message.error('上传图片只能是 JPG 或 PNG 格式!')
  154. }
  155. if (!isLt2M) {
  156. this.$message.error('上传图片大小不能超过 2MB!')
  157. }
  158. return (isJPG || isPNG) && isLt2M
  159. }
  160. },
  161. async mounted () {
  162. this.query()
  163. },
  164. computed: {
  165. ...mapState(['total', 'linksList']),
  166. isNew () {
  167. return Boolean(this.is_data && this.is_data._id)
  168. }
  169. }
  170. }
  171. </script>
  172. <style lang="less" scoped>
  173. .container {
  174. height: 100%;
  175. }
  176. .box-card {
  177. height: 100%;
  178. }
  179. .avatar-uploader {
  180. border: 1px dashed #d9d9d9;
  181. border-radius: 6px;
  182. cursor: pointer;
  183. position: relative;
  184. overflow: hidden;
  185. }
  186. .avatar-uploader .el-upload:hover {
  187. border-color: #409EFF;
  188. }
  189. .avatar-uploader-icon {
  190. font-size: 28px;
  191. color: #8c939d;
  192. width: 178px;
  193. height: 178px;
  194. line-height: 178px;
  195. text-align: center;
  196. }
  197. .avatar {
  198. width: 178px;
  199. height: 178px;
  200. display: block;
  201. }
  202. </style>