type.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <script>
  2. import RoundedTitle from "../../../components/public/roundedTitle.vue";
  3. import PopCard from "../../../components/public/popCard.vue";
  4. import TypeEdit from "../../../components/typeEdit.vue";
  5. import Pop from "../../../components/public/pop.vue";
  6. import ImageTable from "../../../components/public/imageTable.vue";
  7. import ImageViewer from "../../../components/public/imageViewer.vue";
  8. import TableSelect from "../../../components/public/tableSelect.vue";
  9. import {handle} from "../../../until/handle";
  10. import axios from "axios";
  11. import {apiMap} from "../../../map/apiMap";
  12. import {rCode} from "../../../map/rcodeMap_esm";
  13. import dbField_esm from "@/map/dbField_esm";
  14. const typeColumns = [
  15. {
  16. title: 'ID',
  17. dataIndex: 'type_id',
  18. width: '5%',
  19. },
  20. {
  21. title: '图标',
  22. dataIndex: 'type_logo',
  23. width: '10%',
  24. scopedSlots: {customRender: 'type_logo'},
  25. },
  26. {
  27. title: '类型名称',
  28. dataIndex: 'type_name',
  29. width: '15%',
  30. },
  31. {
  32. title: '类型关键字',
  33. dataIndex: 'type_key',
  34. width: '20%',
  35. },
  36. {
  37. title: '搜索关键字',
  38. dataIndex: 'seo_key',
  39. width: '30%',
  40. scopedSlots: {customRender: 'seo_key'},
  41. },
  42. {
  43. title: '操作',
  44. scopedSlots: {customRender: 'operation'},
  45. }
  46. ];
  47. export default {
  48. name: 'newsType',
  49. components: {ImageTable, TypeEdit, PopCard, Pop, ImageViewer, TableSelect, RoundedTitle},
  50. data() {
  51. return {
  52. typeColumns,
  53. loading: false,
  54. types: [],
  55. page: 1,
  56. pageSize: 10,
  57. typeEditShow: false,
  58. parentType: dbField_esm.db_base.newsType.solution,
  59. parentTypes: [
  60. {
  61. key: dbField_esm.db_base.newsType.solution,
  62. value: '解决方案',
  63. },
  64. {
  65. key: dbField_esm.db_base.newsType.news,
  66. value: '新闻',
  67. },
  68. ]
  69. }
  70. },
  71. beforeMount() {
  72. this.getTypes();
  73. },
  74. computed: {
  75. showTypes() {
  76. return this.types.filter(item =>
  77. item.parent_type === this.parentType);
  78. }
  79. },
  80. methods: {
  81. // 获取文章类型列表
  82. async getTypes() {
  83. this.loading = true;
  84. let [err, res] = await handle(axios.get(apiMap.newsTypes.path));
  85. this.loading = false;
  86. if (err) {
  87. this.$message.error(err);
  88. return {};
  89. }
  90. let result = res.data;
  91. if (result.code !== rCode.OK) {
  92. this.$message.error(result.msg);
  93. return {};
  94. }
  95. console.log(result.data)
  96. this.types = result.data;
  97. },
  98. parseTags(tagArrStr){
  99. let tags = tagArrStr
  100. if (!tags) {
  101. return [];
  102. }
  103. // 去除空字符串
  104. tags = tags.replace(/\s/g,'')
  105. let tagArr = tags.split(',')
  106. // 标签去重
  107. tagArr = [...new Set(tagArr)]
  108. // 移除空标签
  109. tagArr = tagArr.filter(item => item)
  110. return tagArr
  111. },
  112. handleAddType() {
  113. this.opentypeEdit();
  114. this.$nextTick(() => {
  115. this.$refs.type_edit.init("文章类型", apiMap.addNewsType.path,
  116. null,
  117. {
  118. parent_type: this.parentType,
  119. })
  120. })
  121. },
  122. parentTypeChange(value) {
  123. if (!this.typeEditShow )
  124. {
  125. return;
  126. }
  127. this.$nextTick(() => {
  128. this.$refs.type_edit.updateQueryParams({
  129. parent_type: this.parentType,
  130. });
  131. })
  132. },
  133. handleEditType(item){
  134. //
  135. this.opentypeEdit();
  136. this.$nextTick(() => {
  137. this.$refs.type_edit.init("文章类型",
  138. apiMap.editNewsType.path, item,
  139. {
  140. parent_type: this.parentType,
  141. }
  142. );
  143. })
  144. },
  145. handleDeleteType(item){
  146. // 询问是否要删除
  147. this.$confirm({
  148. content: '确定要删除吗?',
  149. okText: '确定',
  150. cancelText: '取消',
  151. onOk: () => {
  152. this.executeDeleteType(item);
  153. }});
  154. },
  155. handleCloseEdit(){
  156. this.closeTypeEdit();
  157. },
  158. opentypeEdit(){
  159. this.typeEditShow = true;
  160. },
  161. closeTypeEdit(){
  162. this.typeEditShow = false;
  163. this.getTypes();
  164. },
  165. async executeDeleteType(item){
  166. let url = apiMap.deleteNewsType.path;
  167. url += `?id=${item.type_id}`
  168. let [err,res] = await handle(axios.delete(url, {id: item.type_id}));
  169. if(err){
  170. this.$message.error(`[删除类型] 失败:${err.message}`)
  171. console.log(err)
  172. return err
  173. }
  174. let result = res.data
  175. if(result.code !== rCode.OK) {
  176. this.$message.error(`[移除类型] 失败:${result.msg}`)
  177. return result
  178. }
  179. this.$message.success(`[移除类型] 成功`)
  180. this.closeTypeEdit();
  181. }
  182. }
  183. }
  184. </script>
  185. <template>
  186. <div class="w-full p-2 h-full" >
  187. <rounded-title class="text-xl">
  188. <span>文章分类管理</span>
  189. <a href="/manger/news"
  190. class="inline-flex px-10 h-full ml-5 rounded bg-blue-400 text-white cursor-pointer
  191. hover:text-orange-500 ">文章中心</a>
  192. <a-button
  193. class="ml-2 flex items-center"
  194. type="primary"
  195. @click="handleAddType"
  196. >新增
  197. </a-button>
  198. </rounded-title>
  199. <div class="w-full rounded border mt-2 bg-white p-2">
  200. <!-- tab 选择 -->
  201. <a-radio-group
  202. v-model="parentType"
  203. @change="parentTypeChange"
  204. >
  205. <a-radio-button
  206. v-for="item in parentTypes"
  207. :key="item.key"
  208. :value="item.key"
  209. >
  210. {{ item.value }}
  211. </a-radio-button>
  212. </a-radio-group>
  213. <!-- 一级分类 -->
  214. <a-table
  215. :columns="typeColumns"
  216. :loading="loading"
  217. :row-key="record => record.id"
  218. :pagination="false"
  219. :data-source="showTypes"
  220. >
  221. <template class="logo_view" slot="type_logo" slot-scope="text,record">
  222. <svg-icon :class="''" :svgHref="text"></svg-icon>
  223. </template>
  224. <template class="tags" slot="seo_key" slot-scope="text,record">
  225. <a-tag
  226. v-for="tag in parseTags(text)"
  227. :key="tag"
  228. color="#2db7f5"
  229. >
  230. {{ tag }}
  231. </a-tag>
  232. </template>
  233. <template class="flex justify-center" slot="operation" slot-scope="text,record">
  234. <a-button
  235. type="primary"
  236. @click="handleEditType(record)"
  237. >编辑
  238. </a-button>
  239. <a-button type="danger" @click="handleDeleteType(record)">移除</a-button>
  240. </template>
  241. </a-table>
  242. </div>
  243. <pop :show="typeEditShow" :loading="loading">
  244. <pop-card>
  245. <template slot="close-group">
  246. <a-button type="danger" @click="handleCloseEdit">关闭</a-button>
  247. </template>
  248. <type-edit ref="type_edit" @close="handleCloseEdit"></type-edit>
  249. </pop-card>
  250. </pop>
  251. </div>
  252. </template>
  253. <style scoped>
  254. </style>