type.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. tags = tags.replace(/,|;/g,',')
  106. let tagArr = tags.split(',')
  107. // 标签去重
  108. tagArr = [...new Set(tagArr)]
  109. // 移除空标签
  110. tagArr = tagArr.filter(item => item)
  111. return tagArr
  112. },
  113. handleAddType() {
  114. this.opentypeEdit();
  115. this.$nextTick(() => {
  116. this.$refs.type_edit.init("文章类型", apiMap.addNewsType.path,
  117. null,
  118. {
  119. parent_type: this.parentType,
  120. })
  121. })
  122. },
  123. parentTypeChange(value) {
  124. if (!this.typeEditShow )
  125. {
  126. return;
  127. }
  128. this.$nextTick(() => {
  129. this.$refs.type_edit.updateQueryParams({
  130. parent_type: this.parentType,
  131. });
  132. })
  133. },
  134. handleEditType(item){
  135. //
  136. this.opentypeEdit();
  137. this.$nextTick(() => {
  138. this.$refs.type_edit.init("文章类型",
  139. apiMap.editNewsType.path, item,
  140. {
  141. parent_type: this.parentType,
  142. }
  143. );
  144. })
  145. },
  146. handleDeleteType(item){
  147. // 询问是否要删除
  148. this.$confirm({
  149. content: '确定要删除吗?',
  150. okText: '确定',
  151. cancelText: '取消',
  152. onOk: () => {
  153. this.executeDeleteType(item);
  154. }});
  155. },
  156. handleCloseEdit(){
  157. this.closeTypeEdit();
  158. },
  159. opentypeEdit(){
  160. this.typeEditShow = true;
  161. },
  162. closeTypeEdit(){
  163. this.typeEditShow = false;
  164. this.getTypes();
  165. },
  166. async executeDeleteType(item){
  167. let url = apiMap.deleteNewsType.path;
  168. url += `?id=${item.type_id}`
  169. let [err,res] = await handle(axios.delete(url, {id: item.type_id}));
  170. if(err){
  171. this.$message.error(`[删除类型] 失败:${err.message}`)
  172. console.log(err)
  173. return err
  174. }
  175. let result = res.data
  176. if(result.code !== rCode.OK) {
  177. this.$message.error(`[移除类型] 失败:${result.msg}`)
  178. return result
  179. }
  180. this.$message.success(`[移除类型] 成功`)
  181. this.closeTypeEdit();
  182. }
  183. }
  184. }
  185. </script>
  186. <template>
  187. <div class="w-full p-2 h-full" >
  188. <rounded-title class="text-xl">
  189. <span>文章分类管理</span>
  190. <a href="/manger/news"
  191. class="inline-flex px-10 h-full ml-5 rounded bg-blue-400 text-white cursor-pointer
  192. hover:text-orange-500 ">文章中心</a>
  193. <a-button
  194. class="ml-2 flex items-center"
  195. type="primary"
  196. @click="handleAddType"
  197. >新增
  198. </a-button>
  199. </rounded-title>
  200. <div class="w-full rounded border mt-2 bg-white p-2">
  201. <!-- tab 选择 -->
  202. <a-radio-group
  203. v-model="parentType"
  204. @change="parentTypeChange"
  205. >
  206. <a-radio-button
  207. v-for="item in parentTypes"
  208. :key="item.key"
  209. :value="item.key"
  210. >
  211. {{ item.value }}
  212. </a-radio-button>
  213. </a-radio-group>
  214. <!-- 一级分类 -->
  215. <a-table
  216. :columns="typeColumns"
  217. :loading="loading"
  218. :row-key="record => record.id"
  219. :pagination="false"
  220. :data-source="showTypes"
  221. >
  222. <template class="logo_view" slot="type_logo" slot-scope="text,record">
  223. <svg-icon :class="''" :svgHref="text"></svg-icon>
  224. </template>
  225. <template class="tags" slot="seo_key" slot-scope="text,record">
  226. <a-tag
  227. v-for="tag in parseTags(text)"
  228. :key="tag"
  229. color="#2db7f5"
  230. >
  231. {{ tag }}
  232. </a-tag>
  233. </template>
  234. <template class="flex justify-center" slot="operation" slot-scope="text,record">
  235. <a-button
  236. type="primary"
  237. @click="handleEditType(record)"
  238. >编辑
  239. </a-button>
  240. <a-button type="danger" @click="handleDeleteType(record)">移除</a-button>
  241. </template>
  242. </a-table>
  243. </div>
  244. <pop :show="typeEditShow" :loading="loading">
  245. <pop-card>
  246. <template slot="close-group">
  247. <a-button type="danger" @click="handleCloseEdit">关闭</a-button>
  248. </template>
  249. <type-edit ref="type_edit" @close="handleCloseEdit"></type-edit>
  250. </pop-card>
  251. </pop>
  252. </div>
  253. </template>
  254. <style scoped>
  255. </style>