From b2ab3de804425caf06d49f0eeb743b2e703bf311 Mon Sep 17 00:00:00 2001 From: peng <peng.com> Date: 星期三, 25 六月 2025 10:46:44 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- manager/src/api/tag-type.js | 48 ++ manager/src/views/news/index.vue | 543 ++++++++++++++++++++++ manager/src/api/news.js | 39 + manager/src/api/tag.js | 47 + manager/src/views/tag/tag/index.vue | 403 ++++++++++++++++ manager/src/views/tag/tag-type/index.vue | 311 ++++++++++++ 6 files changed, 1,391 insertions(+), 0 deletions(-) diff --git a/manager/src/api/news.js b/manager/src/api/news.js new file mode 100644 index 0000000..19aca4e --- /dev/null +++ b/manager/src/api/news.js @@ -0,0 +1,39 @@ +import service from "../libs/axios"; + +export const getNews = (params) =>{ + return service({ + url: "/news/page", + method: "GET", + params: params + }) +} + +export const addNews = (params) =>{ + return service({ + url: "/news", + method: "POST", + data: params + }) +} + +export const editNews = (params) =>{ + return service({ + url: "/news", + method: "PUT", + data: params + }) +} + +export const publish = (param) =>{ + return service({ + url: "/news/publish/"+ param, + method: "PUT", + }) +} + +export const delById = (param) =>{ + return service({ + url: "/news/"+ param, + method: "DELETE", + }) +} diff --git a/manager/src/api/tag-type.js b/manager/src/api/tag-type.js new file mode 100644 index 0000000..7776630 --- /dev/null +++ b/manager/src/api/tag-type.js @@ -0,0 +1,48 @@ +import service from "@/libs/axios"; + +// 鑾峰彇鏍囩鍒嗙被鍒楄〃 +export const getTagTypeList = (params) => { + return service({ + url: "/lmk/tag-type/list", + method: "GET", + params: params + }) +} + +export const getTagKeyTypeList = () => { + return service({ + url: "/lmk/tag-type/key/list", + method: "GET" + }) +} + + + +// 閫氳繃id鍒犻櫎鏍囩鍒嗙被 +export const deleteTagTypeById = (params) => { + return service({ + url: "/lmk/tag-type/" + params, + method: "DELETE" + }) +} + + +// 淇敼鏍囩鍒嗙被 +export const updateTagType = (params) => { + return service({ + url: "/lmk/tag-type/", + method: "PUT", + data: params + }) +} + +// 娣诲姞鏍囩鍒嗙被 +export const saveTagType = (params) => { + return service({ + url: "/lmk/tag-type/", + method: "POST", + data: params + }) +} + + diff --git a/manager/src/api/tag.js b/manager/src/api/tag.js new file mode 100644 index 0000000..a97d17a --- /dev/null +++ b/manager/src/api/tag.js @@ -0,0 +1,47 @@ +import service from "@/libs/axios"; + +// 鑾峰彇鏍囩鍒嗛〉 +export const getTags = (data) => { + return service({ + url: "/lmk/tag/page", + method: "GET", + params: data + }) +} + +// 鑾峰彇鏍囩鍒楄〃 +export const getTagList = () => { + return service({ + url: "/lmk/tag/list", + method: "GET" + }) +} + + +// 閫氳繃id鍒犻櫎鏍囩 +export const deleteTagById = (params) => { + return service({ + url: "/lmk/tag/" + params, + method: "DELETE" + }) +} + + +// 淇敼鏍囩 +export const editTag = (params) => { + return service({ + url: "/lmk/tag/", + method: "PUT", + data: params + }) +} + +// 娣诲姞鏍囩 +export const addTag = (params) => { + return service({ + url: "/lmk/tag/", + method: "POST", + data: params + }) +} + diff --git a/manager/src/views/news/index.vue b/manager/src/views/news/index.vue new file mode 100644 index 0000000..e9d2d95 --- /dev/null +++ b/manager/src/views/news/index.vue @@ -0,0 +1,543 @@ +<template> + <div class="news-management"> + <Card> + <!-- 鎼滅储琛ㄥ崟 --> + <Form + ref="searchForm" + @keydown.enter.native="handleSearch" + :model="searchForm" + inline + :label-width="80" + class="search-form" + > + <FormItem label="鏍囬" prop="title"> + <Input + type="text" + v-model="searchForm.title" + placeholder="璇疯緭鍏ユ爣棰樺悕绉�" + clearable + @on-clear="handleSearch" + style="width: 180px" + /> + </FormItem> + <FormItem label="鏄惁鍙戝竷" prop="publish"> + <Select + v-model="searchForm.publish" + placeholder="璇烽�夋嫨" + style="width: 180px" + clearable + @on-clear="handleSearch" + @on-change="handleSearch" + > + <Option + v-for="item in typeSelect" + :value="item.value" + :key="item.id" + > + {{ item.label }} + </Option> + </Select> + </FormItem> + <Button + @click="handleSearch" + type="primary" + icon="ios-search" + class="search-btn" + >鎼滅储</Button> + <Button + @click="resetSearch" + icon="md-refresh" + style="margin-left: 8px" + >閲嶇疆</Button> + </Form> + + <!-- 鎿嶄綔鎸夐挳 --> + <Row class="operation"> + <Button @click="openAdd" type="primary" icon="md-add">鏂板娲诲姩</Button> + <Button @click="delBatch" type="error" icon="md-trash" :disabled="selectCount === 0">鎵归噺鍒犻櫎</Button> + </Row> + + <!-- 娲诲姩琛ㄦ牸 --> + <Table + :loading="loading" + border + :columns="columns" + :data="newsList" + ref="table" + @on-selection-change="showSelect" + class="news-table" + > + <!-- 灏侀潰灞曠ず鎻掓Ы --> + <!-- 鎿嶄綔鎸夐挳鎻掓Ы --> + <template slot-scope="{ row }" slot="action"> + <div class="action-btns"> + <Button + type="primary" + size="small" + @click="changeStatus(row, row.publish ? '涓嬫灦' : '鍙戝竷')" + :loading="row.statusLoading" + > + {{ row.publish ? '涓嬫灦' : '鍙戝竷' }} + </Button> + <Button + type="info" + size="small" + @click="detail(row)" + >璇︽儏</Button> + <Button + type="info" + size="small" + @click="openEdit(row)" + >缂栬緫</Button> + <Button + type="error" + size="small" + @click="delById(row)" + >鍒犻櫎</Button> + </div> + </template> + </Table> + + <!-- 鍒嗛〉 --> + <Row type="flex" justify="end" class="page-footer"> + <Page + :current="searchForm.pageNumber" + :total="total" + :page-size="searchForm.pageSize" + @on-change="changePage" + @on-page-size-change="changePageSize" + :page-size-opts="[10, 20, 50]" + size="small" + show-total + show-elevator + show-sizer + ></Page> + </Row> + + <!-- 鏂伴椈缂栬緫/鏂板妯℃�佹 --> + <Modal + v-model="modelShow" + :title="modelTitle" + @on-cancel="modelClose" + width="800" + :mask-closable="false" + > + <Form ref="form" :model="newsForm" :label-width="100" :rules="rules"> + <Row :gutter="16"> + <Col span="12"> + <FormItem label="鏍囬" prop="title"> + <Input + v-model="newsForm.title" + placeholder="璇疯緭鍏ユ爣棰樺悕绉�" + clearable + /> + </FormItem> + </Col> + <Col span="24"> + <FormItem label="鏂伴椈鍐呭锛�" prop="content"> + <editor ref="editor" @input="getReason" /> + </FormItem> + </Col> + </Row> + </Form> + + <div slot="footer"> + <Button @click="modelClose">鍙栨秷</Button> + <Button type="primary" :loading="submitLoading" @click="saveOrUpdate">鎻愪氦</Button> + </div> + </Modal> + + + <Modal + v-model="infoModelShow" + :title="modelTitle" + @on-cancel="infoModelClose" + width="800" + :mask-closable="false" + > + <div class="detail-container"> + <Row :gutter="16"> + <Col span="12"> + <div class="detail-item"> + <label>鏍囬锛�</label> + <span>{{ newsInfo.title || '-' }}</span> + </div> + </Col> + <Col span="12"> + <div class="detail-item"> + <label>鏄惁鍙戝竷锛�</label> + <span>{{newsInfo.publish ? '宸插彂甯�':'鏈彂甯�'}}</span> + </div> + </Col> + + <Col span="12"> + <div class="detail-item" v-if="newsInfo.publish"> + <label>鍙戝竷鏃堕棿锛�</label> + <span>{{ newsInfo.publishDate}}</span> + </div> + </Col> + <Col span="24"> + <div class="detail-item"> + <label>鏂伴椈鍐呭锛�</label> + <div + class="news-content" + v-html="newsInfo.content || '鏃犲唴瀹�'" + ></div> + </div> + </Col> + </Row> + </div> + + <div slot="footer"> + <Button @click="infoModelClose">鍏抽棴</Button> + </div> + </Modal> + + + <!-- 鍥剧墖棰勮妯℃�佹 --> + <Modal v-model="previewVisible" title="鍥剧墖棰勮" footer-hide> + <img :src="previewImageUrl" style="width: 100%"> + </Modal> + </Card> + </div> +</template> +<script> +import Editor from '@/components/editor/index.vue' +import { getNews,editNews,addNews,publish,delById } from '@/api/news.js' +export default { + name: "newsManagement", + components: {Editor}, + data(){ + return{ + // 鍥剧墖棰勮 + previewVisible: false, + previewImageUrl: '', + + modelShow:false, + modelTitle:'', + submitLoading:false, + infoModelShow:false, + //琛ㄥご + columns: [ + { + type: 'selection', + width: 60, + align: 'center' + }, + { + title: '鏍囬', + key: 'title', + minWidth: 120, + tooltip: true + }, + { + title: '鍙戝竷', + key: 'publish', + width: 100, + align: 'center', + render: (h, params) => { + return h('Tag', { + props: { + color: params.row.publish ? 'green' : 'default' + } + }, params.row.publish ? '宸插彂甯�' : '鏈彂甯�') + } + }, + { + title: '鍙戝竷鏃堕棿', + key: 'publishDate', + width: 300, + align: 'center', + render: (h, { row }) => { + // 濡傛灉 publishDate 涓� null 鎴� undefined锛屾樉绀� "鏈彂甯�" + if (row.publishDate == null) { + return h('span', { style: { color: '#999' } }, '鏆傛棤'); + } + // 鍚﹀垯姝e父鏄剧ず鏃ユ湡 + return h('span', row.publishDate); + }, + }, + { + title: '鎿嶄綔', + slot: 'action', + width: 280, + align: 'center', + fixed: 'right' + } + ], + + newsList:[], + total:0, + newsForm:{ + id:'', + title:'', + content:'', + publish:0, + }, + newsInfo:{ + title:'', + publish:false, + publishDate:'', + content:'' + }, + rules: { + title: [ + { required: true, message: '璇疯緭鍏ユ爣棰�', trigger: 'blur' }, + { max: 50, message: '闀垮害涓嶈兘瓒呰繃50涓瓧绗�', trigger: 'blur' } + ], + publish: [ + { required: true, message: '璇烽�夋嫨鏄惁鍙戝竷', trigger: 'blur' }, + ], + content: [ + { required: true, message: '璇疯緭鍏ユ柊闂诲唴瀹�', trigger: 'blur' } + ] + }, + + selectList:[], + selectCount:0, + + loading:false, + + searchForm: { + title: '', + publish: 0, + pageNumber: 1, + pageSize: 10 + }, + typeSelect:[ + { + id:1, + label:'鏈彂甯�', + value:0 + }, + { + id:2, + label:'宸插彂甯�', + value:1 + } + + ] + } + }, + mounted() { + this.getNewsList(); + }, + methods:{ + getNewsList(){ + this.loading = true + getNews(this.searchForm).then(res =>{ + this.loading = false + if (res.code === 200) { + // 涓烘瘡涓�琛屾坊鍔爈oading鐘舵�� + this.newsList = res.data.map(item => ({ + ...item, + })) + this.total = res.total + } + }).catch(() => { + this.loading = false + }) + }, + getReason(content) { + this.newsForm.content = content + }, + saveOrUpdate(){ + this.$refs.form.validate(valid => { + if (valid) { + this.submitLoading = true + const submitData = { + ...this.newsForm, + publish: this.newsForm.publish !== 0, // true 鈫� 1, false 鈫� 0 + }; + if (this.newsForm.id){ + editNews(submitData).then(res => { + this.submitLoading = false + if (res.code === 200) { + this.$Message.success(res.msg) + this.modelClose() + this.getNewsList() + } + }).catch(() => { + this.submitLoading = false + }) + }else { + addNews(submitData).then(res => { + this.submitLoading = false + if (res.code === 200) { + this.$Message.success(res.msg) + this.modelClose() + this.getNewsList() + } + }).catch(() => { + this.submitLoading = false + }) + } + + } + }) + }, + infoModelClose(){ + this.infoModelShow = false; + }, + modelClose(){ + this.modelShow = false; + }, + changePage(page) { + this.searchForm.pageNumber = page + this.getNewsList() + }, + // 鏀瑰彉姣忛〉鏉℃暟 + changePageSize(pageSize) { + this.searchForm.pageNumber = 1 + this.searchForm.pageSize = pageSize + this.getNewsList() + }, + + delById(row){ + delById(row.id).then(res =>{ + if (res.code === 200){ + this.$Message.success(res.msg); + this.getNewsList(); + } + + }) + }, + openEdit(row){ + this.modelTitle = '淇敼鏂伴椈'; + this.modelShow = true; + this.$refs.form.resetFields(); + this.newsForm.title = row.title; + this.newsForm.content = row.content; + this.newsForm.id = row.id; + this.$refs.editor.setContent(this.newsForm.content) + }, + openAdd(){ + this.modelTitle = '鏂板鏂伴椈'; + this.modelShow = true; + this.$refs.form.resetFields() + this.newsForm.id = ''; + + }, + detail(row){ + this.modelTitle = '娲诲姩璇︽儏' + this.infoModelShow = true + this.newsInfo = row + }, + changeStatus(row,action){ + row.statusLoading = true; + + publish(row.id).then(res =>{ + row.statusLoading = false + if (res.code === 200){ + this.$Message.success(res.msg); + this.getNewsList(); + } + }).catch(() => { + row.statusLoading = false + }) + }, + // 琛ㄦ牸閫夋嫨鍙樺寲 + showSelect(selection) { + this.selectList = selection.map(item => item.id) + this.selectCount = selection.length + }, + + delBatch(){ + + }, + handleSearch(type, value){ + this.searchForm.pageNumber = 1 + this.getNewsList() + }, + resetSearch(){ + this.$refs.searchForm.resetFields() + this.searchForm.pageNumber = 1 + this.getNewsList() + }, + + } +} +</script> + +<style scoped lang="scss"> +.activity-management { + .search-form { + padding: 16px; + background: #f8f8f9; + border-radius: 4px; + margin-bottom: 16px; + + .ivu-form-item { + margin-bottom: 16px; + margin-right: 16px; + } + + .search-btn { + margin-left: 8px; + } + } +} +.detail-container { + padding: 16px; +} + +.detail-item { + margin-bottom: 18px; + line-height: 1.5; + + label { + display: inline-block; + width: 100px; + color: #666; + font-weight: bold; + vertical-align: top; + } + + span { + display: inline-block; + width: calc(100% - 110px); + } +} + +.news-content { + border: 1px solid #dcdee2; + border-radius: 4px; + padding: 12px; + min-height: 100px; + margin-top: 8px; +} +.news-table { + .media-container { + display: flex; + justify-content: center; + align-items: center; + height: 100px; + + .thumbnail { + max-width: 100%; + max-height: 100%; + object-fit: contain; + cursor: pointer; + transition: all 0.3s; + + &:hover { + transform: scale(1.05); + box-shadow: 0 0 8px rgba(0, 0, 0, 0.2); + } + } + } + + .action-btns { + display: flex; + flex-wrap: wrap; + justify-content: center; + + .ivu-btn { + margin: 4px; + font-size: 12px; + padding: 2px 6px; + min-width: 60px; + } + } +} +</style> diff --git a/manager/src/views/tag/tag-type/index.vue b/manager/src/views/tag/tag-type/index.vue new file mode 100644 index 0000000..a97eba3 --- /dev/null +++ b/manager/src/views/tag/tag-type/index.vue @@ -0,0 +1,311 @@ +<template> + <div> + <Card> + <div class="operation mb_10"> + <Button @click="addParent" type="primary" icon="md-add">娣诲姞涓�绾у垎绫�</Button> + </div> + <tree-table ref="treeTable" size="default" :loading="loading" :data="tableData" :columns="columns" + :border="true" :show-index="false" :is-fold="true" :expand-type="false" primary-key="id"> + <template slot="action" slot-scope="scope"> + <Button type="info" @click="edit(scope.row)" size="small" style="margin-right: 5px">缂栬緫 + </Button> + + <Button type="error" @click="remove(scope.row)" size="small" style="margin-right: 5px">鍒犻櫎 + </Button> + <Button v-show="scope.row.level != 1" type="success" @click="addChildren(scope.row)" size="small" + style="margin-right: 5px">娣诲姞瀛愬垎绫� + </Button> + </template> + </tree-table> + </Card> + <Modal :title="modalTitle" v-model="modalVisible" :mask-closable="false" :width="500"> + <Form ref="formAdd" :model="formAdd" :label-width="100" :rules="formValidate"> + <div v-if="showParent"> + <FormItem label="涓婄骇鍒嗙被" prop="parentId"> + {{ parentTitle }} + <Input v-model="formAdd.parentId" clearable style="width: 100%; display: none" /> + </FormItem> + </div> + <FormItem label="鍒嗙被鍚嶇О" prop="tagTypeName"> + <Input v-model="formAdd.tagTypeName" clearable style="width: 100%" /> + </FormItem> + <FormItem label="鍒嗙被鏍囪瘑" prop="typeKey"> + + <Select v-model="formAdd.typeKey" :disabled="formAdd.parentId!==0" placeholder="璇烽�夋嫨鍒嗙被鏍囪瘑" filterable :popper-append-to-body="false" + popper-class="spec-values-popper" style="width: 100%; text-align: left; margin-right: 10px"> + <Option v-for="item in typeKeyList" :value="item.value" :label="item.value" :key="item.value"> + </Option> + </Select> + </FormItem> + <FormItem label="鎺掑簭鍊�" prop="sortNum"> + <InputNumber v-model="formAdd.sortNum"></InputNumber> + </FormItem> + </Form> + <div slot="footer"> + <Button type="text" @click="modalVisible = false">鍙栨秷</Button> + <Button type="primary" :loading="submitLoading" @click="Submit">鎻愪氦</Button> + </div> + </Modal> + </div> +</template> +<script> +import { + saveTagType, + getTagTypeList , + deleteTagTypeById, + updateTagType,getTagKeyTypeList +} from "@/api/tag-type"; +import TreeTable from "@/components/tree-table/Table/Table"; +import uploadPicInput from "@/components/lili/upload-pic-input"; +import { regular } from "@/utils"; +export default { + name: "lili-components", + components: { + TreeTable, + uploadPicInput, + }, + data() { + return { + submitLoading: false, + loading: false, // 鍔犺浇鐘舵�� + expandLevel: 1, // 灞曞紑鐨勫眰绾� + modalType: 0, // 娣诲姞鎴栫紪杈戞爣璇� + modalVisible: false, // 娣诲姞鎴栫紪杈戞樉绀� + modalTitle: "", // 娣诲姞鎴栫紪杈戞爣棰� + showParent: false, // 鏄惁灞曠ず涓婄骇鑿滃崟 + parentTitle: "", // 鐖剁骇鑿滃崟鍚嶇О + formAdd: { + // 娣诲姞鎴栫紪杈戣〃鍗曞璞″垵濮嬪寲鏁版嵁 + parentId: "", + sortNum: 1, + level: 0, + tagTypeName: "", + typeKey:'' + }, + // 琛ㄥ崟楠岃瘉瑙勫垯 + formValidate: { + tagTypeName: [regular.REQUIRED], + typeKey: [regular.REQUIRED], + sortNum: [regular.REQUIRED, regular.INTEGER], + }, + columns: [ + { + title: "鍒嗙被鍚嶇О", + key: "tagTypeName", + witt: "100px", + }, + { + title: "鍒嗙被鏍囪瘑", + key: "typeKey", + witt: "100px", + }, + { + title: "鎺掑簭", + key: "sortNum", + width: "100px", + }, + { + title: "鎿嶄綔", + key: "action", + align: "center", + headerAlign: "center", + width: "400px", + type: "template", + template: "action", + }, + ], + typeKeyList: [], + tableData: [], // 琛ㄦ牸鏁版嵁 + }; + }, + methods: { + // 鍒濆鍖栨暟鎹� + init() { + this.getAllList(); + this.getKeyTypeList(); + }, + getKeyTypeList() { + getTagKeyTypeList().then((res) => { + this.typeKeyList = res.data + }) + }, + // 娣诲姞瀛愬垎绫� + addChildren(v) { + this.modalType = 0; + this.modalTitle = "娣诲姞瀛愬垎绫�"; + this.formAdd.tagTypeName = ""; + this.parentTitle = v.tagTypeName; + this.formAdd.typeKey = v.typeKey; + this.typeKeyEdit = false + this.formAdd.level = eval(v.level + "+1"); + this.showParent = true; + delete this.formAdd.id; + this.formAdd.parentId = v.id; + this.modalVisible = true; + }, + // 缂栬緫鍒嗙被 + edit(v) { + this.modalType = 1; + this.modalTitle = "缂栬緫"; + this.formAdd.id = v.id; + this.formAdd.tagTypeName = v.tagTypeName; + this.formAdd.level = v.level; + this.formAdd.parentId = v.parentId; + this.formAdd.sortNum = v.sortNum; + this.showParent = false; + this.modalVisible = true; + }, + // 娣诲姞涓�绾у垎绫� + addParent() { + this.modalType = 0; + this.modalTitle = "娣诲姞涓�绾у垎绫�"; + this.parentTitle = "椤剁骇鍒嗙被"; + this.showParent = true; + this.$refs.formAdd.resetFields(); + delete this.formAdd.id; + this.formAdd.parentId = 0; + this.modalVisible = true; + }, + // 鎻愪氦 + Submit() { + this.$refs.formAdd.validate((valid) => { + if (valid) { + this.submitLoading = true; + if (this.modalType === 0) { + // 娣诲姞 閬垮厤缂栬緫鍚庝紶鍏d绛夋暟鎹� 璁板緱鍒犻櫎 + delete this.formAdd.id; + saveTagType(this.formAdd).then((res) => { + this.submitLoading = false; + if (res.success) { + this.$Message.success("娣诲姞鎴愬姛"); + + this.formAdd = { + // 娣诲姞鎴栫紪杈戣〃鍗曞璞″垵濮嬪寲鏁版嵁 + parentId: "", + sortNum: 1, + level: 0, + tagTypeName: "", + }; + } else { + // this.$Message.error(res.message); + } + this.getAllList(); + this.modalVisible = false; + }); + } else { + // 缂栬緫 + updateTagType(this.formAdd, this.formAdd.id).then((res) => { + this.submitLoading = false; + if (res.success) { + this.$Message.success("淇敼鎴愬姛"); + } else { + // this.$Message.error(res.message); + } + this.getAllList(); + this.modalVisible = false; + this.$refs.formAdd.resetFields(); + }); + } + } + }); + }, + // 鍒犻櫎鍒嗙被 + remove(v) { + this.$Modal.confirm({ + title: "纭鍒犻櫎", + content: "鎮ㄧ‘璁よ鍒犻櫎 " + v.tagTypeName + " ?", + loading: true, + onOk: () => { + // 鍒犻櫎 + deleteTagTypeById(v.id).then((res) => { + this.$Modal.remove(); + if (res.code===200) { + this.$Message.success("鎿嶄綔鎴愬姛"); + this.getAllList(); + } + }); + }, + }); + }, + // 鑾峰彇鍒嗙被鏁版嵁 + getAllList(newval) { + this.loading = true; + getTagTypeList().then((res) => { + this.loading = false; + if (res.code===200) { + // 浠呭睍寮�鎸囧畾绾ф暟 榛樿鍚庡彴宸插睍寮�鎵�鏈� + let expandLevel = this.expandLevel; + res.data.forEach(function (e) { + if (expandLevel == 1) { + if (e.level == 0) { + e.expand = false; + } + if (e.children && e.children.length > 0) { + e.children.forEach(function (c) { + if (c.level == 1) { + c.expand = false; + } + if (c.children && c.children.length > 0) { + c.children.forEach(function (b) { + if (b.level == 2) { + b.expand = false; + } + }); + } + }); + } + } else if (expandLevel == 2) { + if (e.level == 0) { + e.expand = true; + } + if (e.children && e.children.length > 0) { + e.children.forEach(function (c) { + if (c.level == 1) { + c.expand = false; + } + if (c.children && c.children.length > 0) { + c.children.forEach(function (b) { + if (b.level == 2) { + b.expand = false; + } + }); + } + }); + } + } else if (expandLevel == 3) { + if (e.level == 0) { + e.expand = true; + } + if (e.children && e.children.length > 0) { + e.children.forEach(function (c) { + if (c.level == 1) { + c.expand = true; + } + if (c.children && c.children.length > 0) { + c.children.forEach(function (b) { + if (b.level == 2) { + b.expand = false; + } + }); + } + }); + } + } + }); + this.tableData = res.data; + } + }); + }, + }, + mounted() { + this.init(); + }, +}; +</script> +<style lang="scss" scoped> +.article { + font-size: 16px; + font-weight: 400; + margin: 12px 0; +} +</style> diff --git a/manager/src/views/tag/tag/index.vue b/manager/src/views/tag/tag/index.vue new file mode 100644 index 0000000..51c9c9d --- /dev/null +++ b/manager/src/views/tag/tag/index.vue @@ -0,0 +1,403 @@ +<template> + <div class="wrapper"> + <Row> + <Col span="4"> + <Card style="height: 100%;" class="article-category mr_10"> + <Tree :data="treeData" @on-select-change="handleCateChange"></Tree> + </Card> + </Col> + <Col span="20"> + <Card class="article-detail"> + <Row @keydown.enter.native="handleSearch"> + <Form ref="searchForm" :model="searchForm" inline :label-width="70" style="width: 100%" class="search-form"> + <Form-item label="鏍囩鍚嶇О" prop="tagName"> + <Input type="text" v-model="searchForm.tagName" placeholder="璇疯緭鍏ユ爣绛惧悕绉�" clearable style="width: 200px" /> + </Form-item> + <Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">鎼滅储</Button> + </Form> + </Row> + <Row class="operation padding-row"> + <Button @click="add" v-if="!selected" type="primary">娣诲姞</Button> + </Row> + <Table :loading="loading" border :columns="columns" :data="data" style="height: calc(100vh - 328px);" + ref="table"> + <!-- 椤甸潰灞曠ず --> + <template slot="openStatusSlot" slot-scope="scope"> + <div></div> + <i-switch size="large" v-model="scope.row.openStatus" @on-change="changeSwitch(scope.row)"> + <span slot="open">灞曠ず</span> + <span slot="close">闅愯棌</span> + </i-switch> + </template> + </Table> + <Row type="flex" justify="end" class="mt_10"> + <Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" + @on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small" show-total show-elevator> + </Page> + </Row> + </Card> + </Col> + </Row> + <template v-if="!selected"> + <Modal :tagName="modalTitle" v-model="modalVisible" :mask-closable="false" :width="1100"> + <Form ref="form" :model="form" :label-width="100"> + <FormItem label="鏍囩鍚嶇О" prop="tagName"> + <Input v-model="form.tagName" clearable style="width: 40%" /> + </FormItem> + <FormItem label="鏍囩鍒嗙被" prop="tagTypeId"> + <Select v-model="treeValue" placeholder="璇烽�夋嫨" clearable style="width: 180px"> + <Option v-if="treeValue" :value="treeValue" style="display: none">{{ treeValue }} + </Option> + <Tree :data="treeDataDefault" @on-select-change="handleCheckChange"></Tree> + </Select> + </FormItem> + <FormItem label="鎺掑簭" prop="sortNum"> + <Input type="number" v-model="form.sortNum" clearable style="width: 10%" /> + </FormItem> + </Form> + <div slot="footer"> + <Button type="text" @click="modalVisible = false">鍙栨秷</Button> + <Button type="primary" :loading="submitLoading" @click="handleSubmit">鎻愪氦</Button> + </div> + </Modal> + </template> + </div> +</template> + +<script> +import { getTagTypeList } from "@/api/tag-type"; +import { getTags, deleteTagById, editTag, addTag } from "@/api/tag"; +import tinymec from "@/components/editor/index.vue"; +export default { + components: { + tinymec: tinymec, + }, + props: { + selected: { + type: Boolean, + default: false, + }, + }, + data() { + return { + selectedIndex: 99999, // 宸查�変笅鏍� + loading: true, // 琛ㄥ崟鍔犺浇鐘舵�� + modalType: 0, // 娣诲姞鎴栫紪杈戞爣璇� + modalVisible: false, // 娣诲姞鎴栫紪杈戞樉绀� + modalTitle: "", // 娣诲姞鎴栫紪杈戞爣棰� + treeDataDefault: [], + searchForm: { + // 鎼滅储妗嗗垵濮嬪寲瀵硅薄 + pageNumber: 1, // 褰撳墠椤垫暟 + pageSize: 10, // 椤甸潰澶у皬 + sortNum: "createTime", // 榛樿鎺掑簭瀛楁 + order: "desc", // 榛樿鎺掑簭鏂瑰紡 + tagTypeId: "", + }, + searchTreeValue: "", // 鍒囨崲 + form: { + // 娣诲姞鎴栫紪杈戣〃鍗曞璞″垵濮嬪寲鏁版嵁 + tagName: "", + tagTypeId: "", + sortNum: 1, + id: "", + }, + list: [], // 鍒楄〃 + treeValue: "", // 閫夋嫨鐨勫垎绫� + //鏍戠粨鏋� + treeData: [], + submitLoading: false, // 娣诲姞鎴栫紪杈戞彁浜ょ姸鎬� + columns: [ + // 琛ㄥご + { + title: "鍒嗙被鍚嶇О", + key: "tagTypeName", + width: 150, + }, + { + title: "鏍囩鍚嶇О", + key: "tagName", + minWidth: 200, + tooltip: true, + }, + { + title: "鎺掑簭", + key: "sortNum", + width: 100, + }, + { + title: "鎿嶄綔", + key: "action", + align: "center", + + width: 230, + render: (h, params) => { + return h("div", [ + h( + "Button", + { + props: { + size: "small", + type: + this.selectedIndex == params.index + ? "primary" + : "default", + }, + style: { + marginRight: "5px", + display: this.selected ? "" : "none", + }, + on: { + click: () => { + this.selectedIndex = params.index; + this.$emit("callbacked", params.row); + }, + }, + }, + this.selectedIndex == params.index ? "宸查��" : "閫夋嫨" + ), + h( + "Button", + { + props: { + size: "small", + type: "info", + }, + style: { + marginRight: "5px", + }, + on: { + click: () => { + this.edit(params.row); + }, + }, + }, + "缂栬緫" + ), + h( + "Button", + { + props: { + type: "error", + size: "small", + }, + on: { + click: () => { + this.remove(params.row); + }, + }, + }, + "鍒犻櫎" + ), + ]); + }, + }, + ], + data: [], // 琛ㄥ崟鏁版嵁 + total: 0, // 琛ㄥ崟鏁版嵁鎬绘暟 + }; + }, + watch: { + "searchForm.tagTypeId": { + handler() { + this.handleSearch(); + }, + deep: true, + }, + "searchForm.tagName": { + handler() { + this.handleSearch(); + }, + deep: true, + }, + }, + methods: { + // 鍒濆鍖栨暟鎹� + init() { + this.getDataList(); + this.getAllList(0); + }, + // 閫夋嫨鍒嗙被鍥炶皟 + handleCateChange(data) { + let { value, title } = data[0]; + this.list.push({ + value, + title, + }); + this.searchForm.tagTypeId = value; + this.searchTreeValue = title; + this.getDataList() + }, + // 鏍囩鍒嗙被鐨勯�夋嫨浜嬩欢 + handleCheckChange(data) { + let value = ""; + let title = ""; + this.list = []; + data.forEach((item, index) => { + value += `${item.value},`; + title += `${item.title},`; + }); + value = value.substring(0, value.length - 1); + title = title.substring(0, title.length - 1); + this.list.push({ + value, + title, + }); + this.form.tagTypeId = value; + this.treeValue = title; + }, + // 鏀瑰彉椤垫暟 + changePage(v) { + this.searchForm.pageNumber = v; + this.getDataList(); + }, + // 鏀瑰彉椤电爜 + changePageSize(v) { + this.selected.pageNumber = 1; + this.searchForm.pageSize = v; + this.getDataList(); + }, + // 鎼滅储鍒楄〃 + handleSearch() { + this.searchForm.pageNumber = 1; + this.searchForm.pageSize = 10; + this.getDataList(); + }, + // 鑾峰彇鍏ㄩ儴鏍囩鍒嗙被 + getAllList(parent_id) { + this.loading = true; + getTagTypeList(parent_id).then((res) => { + this.loading = false; + if (res.code == 200) { + this.treeData = this.getTree(res.data); + this.treeDataDefault = this.getTree(res.data); + this.treeData.unshift({ + title: "鍏ㄩ儴", + level: 0, + children: [], + id: "0", + tagTypeId: 0, + }); + } + }); + }, + // 鏍囩鍒嗙被鏍煎紡鍖栨柟娉� + getTree(tree = []) { + let arr = []; + if (!!tree && tree.length !== 0) { + tree.forEach((item) => { + let obj = {}; + obj.title = item.tagTypeName; + obj.value = item.id; + obj.attr = item.tagTypeName; // 鍏朵粬浣犳兂瑕佹坊鍔犵殑灞炴�� + obj.expand = false; + obj.selected = false; + obj.children = this.getTree(item.children); // 閫掑綊璋冪敤 + arr.push(obj); + }); + } + return arr; + }, + // 鑾峰彇鏍囩鍒楄〃 + getDataList(val) { + if (val) this.form = {}; + this.loading = true; + getTags(this.searchForm).then((res) => { + this.loading = false; + if (res.code === 200) { + this.total = res.total; + //涓轰簡鍦ㄦ槸鍚﹀睍绀轰竴鍒楀睍绀哄紑鍏� 闇�瑕佹敼涓�涓嬫暟鎹被鍨嬶紝鏈�缁堟彁浜ゅ啀娆℃洿鏀� + this.data = []; + if (res.data.length > 0) { + this.data = res.data; + } + } + }); + this.total = this.data?.length; + this.loading = false; + }, + // 娣诲姞鏍囩 + handleSubmit() { + this.$refs.form.validate((valid) => { + if (valid) { + this.submitLoading = true; + if (this.modalType === 0) { + // 娣诲姞 閬垮厤缂栬緫鍚庝紶鍏d绛夋暟鎹� 璁板緱鍒犻櫎 + delete this.form.id; + addTag(this.form).then((res) => { + this.submitLoading = false; + if (res.code === 200) { + this.$Message.success("鎿嶄綔鎴愬姛"); + this.getDataList(); + this.modalVisible = false; + } + }); + } else { + // 缂栬緫 + editTag(this.form).then((res) => { + this.submitLoading = false; + if (res.code === 200) { + this.$Message.success("鎿嶄綔鎴愬姛"); + this.getDataList(); + this.modalVisible = false; + } + }); + } + } + }); + }, + // 娣诲姞鏍囩modal + add() { + this.modalType = 0; + this.modalTitle = "娣诲姞鏍囩"; + this.treeValue = ""; + + this.form = { + sortNum: 1, + tagName: "", + }; + this.$refs.form.resetFields(); + delete this.form.id; + this.modalVisible = true; + }, + // 缂栬緫鏍囩modal + edit(data) { + this.modalType = 1; + this.modalTitle = "缂栬緫鏍囩"; + this.treeValue = ""; + this.form = { + tagName: "", + }; + this.$refs.form.resetFields(); + + this.modalVisible = true; + this.form.tagTypeId = data.tagTypeId; + this.treeValue = data.tagTypeName; + this.form.id = data.id; + this.form.tagName = data.tagName; + this.form.sortNum = data.sortNum; + }, + // 鍒犻櫎鏍囩 + remove(v) { + this.$Modal.confirm({ + tagName: "纭鍒犻櫎", + content: "鎮ㄧ‘璁よ鍒犻櫎涔�?", + loading: true, + onOk: () => { + // 鍒犻櫎 + deleteTagById(v.id).then((res) => { + this.$Modal.remove(); + if (res.code === 200) { + this.$Message.success("鎿嶄綔鎴愬姛"); + this.getDataList(); + } + }); + }, + }); + }, + }, + mounted() { + this.init(); + }, +}; +</script> -- Gitblit v1.8.0