type.vue 6.7 KB

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