123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- <template>
- <a-card>
- <div :class="$style.action">
- <a-input-search @search="onSearch" />
- <span v-if="!module && !appNodeId">
- <a-button type="primary" @click="addNode">新建</a-button>
- <a-button v-if="!appId" @click="importVisible = true">导入</a-button>
- <a-button v-if="!appId" :disabled="!selectedRows.length" @click="exportTree">导出</a-button>
- <a-button :disabled="!selectedRows.length" @click="delNode">删除</a-button>
- </span>
- </div>
- <a-table
- :key="key"
- :columns="columns"
- :data-source="searchData || treeData"
- :expanded-row-keys.sync="expandedRowKeys"
- :replace-fields="replaceFields"
- row-key="id"
- :row-selection="rowSelection"
- :pagination="false"
- @expand="expand"
- >
- <a
- v-if="!module && !appNodeId"
- slot="name"
- slot-scope="text, record"
- @click="editNode(record)"
- >{{ text }}</a
- >
- <span v-else>{{ text }}</span>
- </a-table>
- <a-modal v-model="formVisible" title="数据字典" destroy-on-close @ok="handleOk">
- <sd-form ref="form" :init-values="pageFormData">
- <template>
- <sd-form-item name="appId" hidden :input-props="{ defaultValue: appId }"></sd-form-item>
- <sd-form-item name="id" hidden />
- <sd-form-item name="parentCode" hidden :input-props="{ defaultValue: -1 }">
- </sd-form-item>
- <a-form-item label="上级分类">
- <sd-tree-picker
- v-model="parentCat"
- single
- :load-tree-data="loadTreeData"
- @change="parentCatChange"
- ></sd-tree-picker>
- </a-form-item>
- <sd-form-item name="categoryName" />
- <sd-form-item name="categoryCode" />
- <sd-form-item name="sortNumber" />
- </template>
- </sd-form>
- </a-modal>
- <a-modal v-model="importVisible" title="导入树形字典" :footer="null" :width="700">
- <a-upload-dragger :file-list="[]" :custom-request="(file) => uploadExcel(file)">
- <p class="ant-upload-drag-icon">
- <a-icon type="inbox" />
- </p>
- <p class="ant-upload-text">
- 点击或将文件拖拽到这里上传
- </p>
- </a-upload-dragger>
- </a-modal>
- </a-card>
- </template>
- <script>
- import qs from 'qs'
- import axios from '@/common/services/axios-instance'
- import { Modal, Message } from 'ant-design-vue'
- import download from '@/common/services/download'
- import components from './_import-components/sd-treedata-dictionary-import'
- const columns = [
- {
- title: '名称',
- dataIndex: 'name',
- key: 'name',
- scopedSlots: { customRender: 'name' },
- },
- {
- title: '编码',
- dataIndex: 'code',
- key: 'code',
- },
- ]
- const handleTreeData = (arr, picker) => {
- return arr.map((item) => {
- item.isLeaf = item.leaf
- if (!item.leaf && !picker) item.children = []
- return item
- })
- }
- const searchParentNode = (arr, parentCode) => {
- let node = {}
- arr.forEach((a) => {
- if (a.id === parentCode) {
- node = a
- } else if (a.children) node = { ...searchParentNode(a.children, parentCode), ...node }
- })
- return node
- }
- export default {
- name: 'SdTreedataDictionary',
- metaInfo: {
- title: '树形字典',
- },
- components,
- props: {
- appId: {
- type: String,
- default: '',
- },
- module: {
- type: Boolean,
- default: false,
- },
- appNodeId: {
- type: String,
- default: undefined,
- },
- },
- data() {
- return {
- columns,
- treeData: [],
- expandedRowKeys: [],
- searchData: null,
- pageFlowId: '',
- importVisible: false,
- pageFormData: [],
- selectedRows: [],
- formVisible: false,
- disabledKeys: [],
- exporting: false,
- replaceFields: {
- key: 'id',
- title: 'name',
- },
- key: 0,
- parentCat: [],
- searchVal: '',
- }
- },
- computed: {
- rowSelection() {
- return {
- selectedRowKeys: this.selectedRows?.map((row) => row.id) || [],
- onChange: (selectedRowKeys, selectedRows) => {
- this.selectChange(selectedRowKeys, selectedRows)
- },
- }
- },
- },
- created() {
- this.getTreeData()
- },
- methods: {
- uploadExcel(file) {
- const formData = new FormData()
- formData.append('file', file.file)
- axios
- .post('api/framework/v1/onl-treemodule/excel-import', formData, {
- headers: {
- 'Content-Type': 'multipart/form-data',
- },
- })
- .then((res) => {
- Message.success('导入成功')
- })
- .catch((err) => {
- Message.error(err.response?.data?.errors || '导入失败')
- })
- .finally(() => {
- this.importVisible = false
- this.getTreeData()
- })
- },
- exportTree() {
- if (this.selectedRows.find((row) => row.parentCode !== -1)) {
- Message.warn('导出时只能选择根节点节点,请重新选择!')
- return
- }
- const ids = this.selectedRows.map((row) => row.props?.beanId).join()
- const url = `api/framework/v1/onl-treemodule/excel-export?ids=${ids}`
- const fname = '树形字典.xls'
- download(url, fname)
- this.selectedRows = []
- },
- onSearch(value) {
- this.searchVal = value
- const expressions = [
- {
- dataType: 'str',
- name: 'categoryName',
- op: 'like',
- stringValue: `%${this.searchVal}%`,
- },
- ]
- if (this.appId) {
- expressions.push({
- dataType: 'str',
- name: 'appId',
- op: 'eq',
- stringValue: this.appId,
- })
- } else {
- expressions.push({
- dataType: 'str',
- name: 'appId',
- op: 'is_null',
- })
- }
- if (value) {
- const params = {
- columns: 'categoryName,categoryCode,parentCode',
- expressions,
- formId: 'weOnlTreeModule',
- maxResults: -1,
- startPosition: 0,
- }
- axios.post('api/framework/v1/page/businessList', params).then((res) => {
- if (res.data.data) {
- this.searchData = res.data.data.map((item) => {
- return {
- id: item.id,
- code: item.categoryCode,
- name: item.categoryName,
- parentCode: item.parentCode,
- props: {
- beanId: item.id,
- },
- }
- })
- }
- })
- } else this.searchData = null
- },
- parentCatChange(parentCat) {
- this.$refs.form.setFieldValue('parentCode', parentCat.length ? parentCat[0].id : -1)
- },
- loadTreeData(parentCatId) {
- const fun = parentCatId ? this.getChildrenNode(parentCatId, true) : this.getRootNode(true)
- return fun.then((res) => {
- return res.filter((r) => !this.disabledKeys.includes(r.id))
- })
- },
- getRootNode(picker) {
- let params = { appId: this.appId, appNodeId: this.appNodeId }
- params = qs.stringify(params, { filter: (prefix, value) => value || undefined })
- return axios
- .get(
- `api/framework/v1/onl-treemodule/categories/topCategoryList${params ? '?' + params : ''}`
- )
- .then((res) => {
- return handleTreeData(res.data, picker)
- })
- },
- getTreeData() {
- this.searchData = null
- this.searchVal = ''
- this.getRootNode().then((res) => {
- if (res)
- this.treeData = res.map((r) => {
- r.parentCode = -1
- return r
- })
- })
- },
- expand(expanded, record) {
- if (expanded) {
- this.refreshNode(record)
- } else {
- this.expandedRowKeys = this.expandedRowKeys.filter((key) => key !== record.id)
- }
- },
- getChildrenNode(id, picker) {
- return axios
- .get(
- `api/framework/v1/onl-treemodule/categories/categoryTree?parentCode=${id}${
- this.appNodeId ? '&appNodeId=' + this.appNodeId : ''
- }`
- )
- .then((res) => {
- return handleTreeData(res.data, picker)
- })
- },
- refreshNode(record) {
- this.getChildrenNode(record.id).then((res) => {
- if (res.length) {
- record.children = res.map((r) => {
- r.parentCode = record.id
- return r
- })
- record.isLeaf = false
- this.expandedRowKeys.push(record.id)
- this.expandedRowKeys = this.expandedRowKeys.filter(
- (key) => res.findIndex((r) => r.id === key) === -1
- )
- } else {
- record.children = null
- res.isLeaf = true
- this.expandedRowKeys = this.expandedRowKeys.filter((key) => key !== record.id)
- }
- const replaceNode = (arr) => {
- arr.forEach((item, index) => {
- if (item.id === record.id) {
- arr[index] = record
- }
- if (item.children) replaceNode(item.children)
- })
- }
- replaceNode(this.treeData)
- this.key++
- })
- },
- addNode() {
- this.disabledKeys = []
- this.parentCat = []
- this.getDetail()
- },
- getDetail(id) {
- axios
- .get(
- `api/xcoa-mobile/v1/page/wp/base/onltreemodule/weOnlTreeModule${id ? '?id=' + id : ''}`
- )
- .then((res) => {
- this.pageFlowId = res.data.attrs?.pageflowId
- this.pageFormData = res.data.pageFormData.pageFieldInfos
- this.formVisible = true
- this.$nextTick(() => {
- this.parentCatChange(this.parentCat)
- })
- })
- },
- editNode(record) {
- this.disabledKeys = [record.id]
- const parentCat = searchParentNode(this.treeData, record.parentCode)
- this.parentCat = parentCat.id ? [parentCat] : []
- this.getDetail(record.props?.beanId)
- },
- handleOk() {
- const parentCode = this.$refs.form.getFieldValue('parentCode')
- const nodeId = this.$refs.form.getFieldValue('id')
- const params = {
- eventId: 'save',
- inputs: this.$refs.form.getBackendValues(),
- pageFlowId: this.pageFlowId,
- pagePath: '/base/onltreemodule/weOnlTreeModule',
- }
- axios
- .post('api/framework/v1/page/handleData', params)
- .then((res) => {
- if (res.data) {
- if (this.searchData) {
- this.onSearch(this.searchVal)
- } else {
- const record = searchParentNode(this.treeData, parentCode)
- this.delOldNode(this.treeData, nodeId)
- if (parentCode !== -1 && record.id) {
- this.refreshNode(record)
- } else {
- this.getTreeData()
- this.expandedRowKeys = []
- }
- }
- this.formVisible = false
- }
- })
- .catch((err) => {
- Message.error(err.response?.data?.message || '保存失败')
- })
- },
- delOldNode(treeData, targetId) {
- for (let i = 0; i < treeData.length; i++) {
- const node = treeData[i]
- if (node.id === targetId) treeData.splice(i, 1)
- else if (node.children) this.delOldNode(node.children, targetId)
- }
- },
- selectChange(selectedRowKeys, selectedRows) {
- this.selectedRows = selectedRows
- },
- delNode() {
- const ids = this.selectedRows.map((row) => row.props?.beanId).toString()
- Modal.confirm({
- content: '确认删除该项及其所有子项吗?',
- onOk: () => {
- axios.delete(`api/framework/v1/page/weOnlTreeModule?ids=${ids}`).then((res) => {
- if (this.searchData) this.onSearch(this.searchVal)
- else {
- this.selectedRows.forEach((row) => {
- const parentCode = row.parentCode
- if (parentCode === -1) {
- this.treeData = this.treeData.filter((t) => t.id !== row.id)
- } else {
- const parentNode = searchParentNode(this.treeData, row.parentCode)
- this.refreshNode(parentNode)
- }
- })
- }
- })
- },
- })
- },
- },
- }
- </script>
- <style module lang="scss">
- @use '@/common/design' as *;
- .action {
- position: relative;
- z-index: 100;
- float: right;
- :global .ant-btn {
- margin: 0 0 10px 10px;
- }
- :global .ant-input-search {
- width: auto;
- }
- }
- </style>
|