diff --git a/src/Common/HostUrl.ts b/src/Common/HostUrl.ts index dd42fc1e8..0e210c3a1 100644 --- a/src/Common/HostUrl.ts +++ b/src/Common/HostUrl.ts @@ -40,6 +40,7 @@ export const MaterialUrls = { detail: CURRENT_HOST + "/CAD-materialDetail", delete: CURRENT_HOST + "/CAD-materialDelete", update: CURRENT_HOST + "/CAD-materialUpdate", + move: CURRENT_HOST + "/CAD-materialMove", } export const ShopUrls = { @@ -53,6 +54,7 @@ export const ToplineUrls = { detail: CURRENT_HOST + "/CAD-toplineDetail", delete: CURRENT_HOST + "/CAD-toplineDelete", update: CURRENT_HOST + "/CAD-toplineUpdate", + move: CURRENT_HOST + "/CAD-toplineMove", } export const FileUrls = { @@ -61,6 +63,7 @@ export const FileUrls = { detail: CURRENT_HOST + "/CAD-fileDetail", list: CURRENT_HOST + "/CAD-fileList", update: CURRENT_HOST + "/CAD-fileUpdate", + move: CURRENT_HOST + "/CAD-fileMove", } export const TemplateUrls = { create: CURRENT_HOST + "/CAD-moduleCreate", @@ -69,6 +72,7 @@ export const TemplateUrls = { list: CURRENT_HOST + "/CAD-moduleList", update: CURRENT_HOST + "/CAD-moduleUpdate", search: CURRENT_HOST + "/GoodsSearch-WebCad", + move: CURRENT_HOST + "/CAD-moduleMove", } export const ConfigUrls = { diff --git a/src/UI/Components/SourceManage/CommonPanel.tsx b/src/UI/Components/SourceManage/CommonPanel.tsx index 9530cf18e..30c45a20d 100644 --- a/src/UI/Components/SourceManage/CommonPanel.tsx +++ b/src/UI/Components/SourceManage/CommonPanel.tsx @@ -1,8 +1,8 @@ import { Alignment, Button, Card, Checkbox, Classes, ContextMenu, Intent, ITreeNode, Menu, MenuItem, Navbar, Popover, Position, Tree, HTMLSelect } from '@blueprintjs/core'; -import { observable } from 'mobx'; +import { observable, toJS } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { DirUrl } from '../../../Common/HostUrl'; +import { DirUrl, FileUrls } from '../../../Common/HostUrl'; import { MouseKey } from '../../../Common/KeyEnum'; import { DirectoryId, PostJson, RequestStatus } from '../../../Common/Request'; import { AppToaster } from '../Toaster'; @@ -10,6 +10,7 @@ import { HandleDirComponent } from './HandleDirComponent'; import { Pagination } from './Pagination'; import './TexturePanel.less'; import { PopoverButton } from '../Common/PopoverButton'; +import { arrayLast } from '../../../Common/ArrayExt'; export interface IDirectoryProps { @@ -70,7 +71,7 @@ export class CommonPanel extends React.Component @@ -238,6 +240,7 @@ export class CommonPanel extends React.Component 0, + className: dir.dir_id, //为了识别这个元素的目录id childNodes: this.parseNodes(dir.childs), }; newNodes.push(node); @@ -282,6 +285,7 @@ export class CommonPanel extends React.Component + { + const getQuery = (idKey: string) => + { + let deleteMats = this.state.isSelectAll ? this.dataList : [...this.needDeleteData]; + return deleteMats.map(m => m[idKey]); + } + if (this.props.defaultDirId === DirectoryId.ImgDir) + return getQuery("image_id"); + else if (this.props.defaultDirId === DirectoryId.MaterialDir) + return getQuery("material_id"); + else if (this.props.defaultDirId === DirectoryId.ToplineDir) + return getQuery("topline_id"); + else if (this.props.defaultDirId === DirectoryId.FileDir) + return getQuery("file_id"); + else if (this.props.defaultDirId === DirectoryId.TemplateDir) + return getQuery("module_id"); + else + { + console.warn("未知目录id"); + return [] + } + } //删除数据 private handDeleteData = async (dataList?) => { @@ -499,6 +527,138 @@ export class CommonPanel extends React.Component + { + if (this.props.defaultDirId === DirectoryId.ImgDir) + return; + + + let targetId: string; + let el = e.target as HTMLElement; + while (true) + { + if (el.nodeName === "LI") + { + el.firstElementChild.classList.remove('moveenter'); + targetId = arrayLast(Array.from(el.classList)); + break; + } + else + el = el.parentElement; + if (el === null || el === this.tree) + break; + } + let dataIds = this.getSelectDataIds(); + if (targetId && dataIds.length > 0) + { + let url = ""; + let query: any = { dir_id: targetId }; + switch (this.props.defaultDirId) + { + case DirectoryId.FileDir: + url = FileUrls.move; + query.file_ids = dataIds; + break; + case DirectoryId.MaterialDir: + url = FileUrls.move; + query.material_ids = dataIds; + break; + case DirectoryId.ToplineDir: + url = FileUrls.move; + query.topline_ids = dataIds; + break; + case DirectoryId.TemplateDir: + url = FileUrls.move; + query.module_ids = dataIds; + break; + default: + console.warn("未知id"); + break; + } + + let data = await PostJson(url, query); + if (data.err_code === RequestStatus.Ok) + { + AppToaster.show({ + message: "文件移动成功", + timeout: 1500, + intent: Intent.SUCCESS + }); + await this.handleGetData(); + } + } + } + private handleDragEnterFile = (e: DragEvent) => + { + let el = e.target as HTMLLIElement; + if (el.nodeName === "DIV" && el.parentElement.nodeName === "LI") + { + this.handleDragEnd(); + el.classList.add("moveenter"); + let targetId = arrayLast(Array.from(el.parentElement.classList)); + let nodeData = this.state.nodes.find(node => node.id === targetId && node.childNodes.length > 0); + if (nodeData && !nodeData.isExpanded) + this.handleNodeCollapse(nodeData, false); + } + e.preventDefault(); + } + private handleDragLeave = (e: DragEvent) => + { + let el = e.target as HTMLLIElement; + if (el.classList.contains("bp3-tree")) + { + this.handleDragEnd(); + return; + } + if (el.nodeName === "DIV" && el.parentElement.nodeName === "LI") + { + let el2 = e.relatedTarget as HTMLElement; + while (true) + { + if (el2.nodeName === "DIV" && el2.parentElement.nodeName === "LI") break; + el2 = el2.parentElement; + if (el2 === null || el2 === this.tree) break; + if (el2 === el) return false; + } + el.classList.remove('moveenter'); + } + } + //点击节点容器的动作 + private handleTreeMouseDown = (e: MouseEvent) => + { + let el = e.target as HTMLElement; + if (e.button === MouseKey.Right) + { + if (el.classList.contains('bp3-tree')) + { + this.showContextMenu(undefined, undefined, e); + e.stopPropagation(); + } + } + else + { + if (el.classList.contains('bp3-tree')) + { + this.forEachNode(this.state.nodes, n => (n.isSelected = false)); + if (this.currentDir.id !== this.props.defaultDirId) + { + Object.assign(this.currentDir, { id: this.props.defaultDirId, path: "", pathNum: [] }); + this.handleGetData(); + } + } + } + } + private updateNodeEls = () => + { + this.nodeEls = Array.from(this.tree.querySelectorAll(".bp3-tree-node-content")); + } + private handleDragEnd = () => + { + for (let node of this.nodeEls) + { + node.classList.remove("moveenter"); + } + } async UNSAFE_componentWillMount() { //初始化目录 @@ -512,30 +672,20 @@ export class CommonPanel extends React.Component - { - let el = e.target as HTMLElement; - if (e.button === MouseKey.Right) - { - if (el.classList.contains('bp3-tree')) - { - this.showContextMenu(undefined, undefined, e); - e.stopPropagation(); - } - } - else - { - if (el.classList.contains('bp3-tree')) - { - this.forEachNode(this.state.nodes, n => (n.isSelected = false)); - if (this.currentDir.id !== this.props.defaultDirId) - { - Object.assign(this.currentDir, { id: this.props.defaultDirId, path: "", pathNum: [] }); - this.handleGetData(); - } - } - } - }); + this.tree.addEventListener('mousedown', this.handleTreeMouseDown); + this.tree.addEventListener('dragenter', this.handleDragEnterFile); + this.tree.addEventListener('dragleave', this.handleDragLeave); + this.tree.addEventListener("drop", this.handleMoveFiles); + document.addEventListener('dragend', this.handleDragEnd); + this.updateNodeEls(); + } + componentWillUnmount() + { + this.tree.removeEventListener('mousedown', this.handleTreeMouseDown); + this.tree.removeEventListener('dragenter', this.handleDragEnterFile); + this.tree.removeEventListener('dragleave', this.handleDragLeave); + this.tree.removeEventListener("drop", this.handleMoveFiles); + document.removeEventListener('dragend', this.handleDragEnd); } render() { @@ -634,7 +784,12 @@ export class CommonPanel extends React.Component - + + { + if (this.needDeleteData.size === 0) e.preventDefault(); + }}> { React.Children.map(this.props.children, child => child && React.cloneElement(child as React.DetailedReactHTMLElement, diff --git a/src/UI/Components/SourceManage/FileList.tsx b/src/UI/Components/SourceManage/FileList.tsx index 9418376f6..5f80ba043 100644 --- a/src/UI/Components/SourceManage/FileList.tsx +++ b/src/UI/Components/SourceManage/FileList.tsx @@ -90,7 +90,7 @@ export class FileList extends React.Component { className="look-mat" onMouseDown={(e) => this.handleMouseDown(e, file.file_id, file.name)} > - this.handleOpenFile(file.file_id)} /> + { this.isShowSize && diff --git a/src/UI/Components/SourceManage/FilePanel.tsx b/src/UI/Components/SourceManage/FilePanel.tsx index c6cc79f1a..aed3125d9 100644 --- a/src/UI/Components/SourceManage/FilePanel.tsx +++ b/src/UI/Components/SourceManage/FilePanel.tsx @@ -110,6 +110,15 @@ export class FilePanel extends React.Component<{ store?: TopPanelStore }, {}> { let server = FileServer.GetInstance() as FileServer; let data = this.commonPanel["needDeleteData"] as Set; + if (data.size === 0) + { + AppToaster.show({ + message: "请选择要下载的文件", + timeout: 1500, + intent: Intent.DANGER + }); + return; + } for (let f of data) await server.Download(f.file_id); } @@ -189,6 +198,15 @@ export class FilePanel extends React.Component<{ store?: TopPanelStore }, {}> BatchSend = () => { let data = [...this.commonPanel["needDeleteData"] as Set].map(f => f.file_id); + if (data.length === 0) + { + AppToaster.show({ + message: "请选择要发送的文件", + timeout: 1500, + intent: Intent.DANGER + }); + return; + } if (data.length > 0) window.open(`${CURRENT_HOST}/CAD-fileSend?file_id=${data.join(",")}`); } diff --git a/src/UI/Css/blue.less b/src/UI/Css/blue.less index 8745dd4e1..582cbe627 100644 --- a/src/UI/Css/blue.less +++ b/src/UI/Css/blue.less @@ -1,12 +1,13 @@ - //因为蓝图的按钮样式可能导致元素被撑大。 -.bp3-control.bp3-switch.bp3-align-right .bp3-control-indicator{ - margin-top: 0px; +.bp3-control.bp3-switch.bp3-align-right .bp3-control-indicator { + margin-top: 0px; } -.souce-panel{ - .bp3-tabs,.bp3-tab-panel{ - width: 100%; +.souce-panel { + + .bp3-tabs, + .bp3-tab-panel { + width: 100%; } } @@ -15,19 +16,22 @@ margin-right: 12px; } -#bp3-tab-panel_Tabs_fl li[id]{ +#bp3-tab-panel_Tabs_fl li[id] { margin-right: 0; } + //鼠标移到disable按钮上时 不要变成notallow -.bp3-button:not([class*="bp3-intent-"]):disabled, .bp3-button:not([class*="bp3-intent-"]).bp3-disabled{ +.bp3-button:not([class*="bp3-intent-"]):disabled, +.bp3-button:not([class*="bp3-intent-"]).bp3-disabled { cursor: default; } + /****************文件资源管理器*********************/ -#bp3-tab-panel_Tabs_fl li[id] input{ - width:14rem; +#bp3-tab-panel_Tabs_fl li[id] input { + width: 14rem; padding: 4px; - border: 1px solid transparent; + border: 1px solid transparent; outline: none; background-color: #30404d; color: #ffffff; @@ -35,144 +39,156 @@ font-weight: bold; } -#bp3-tab-panel_Tabs_fl li[id] input:focus{ +#bp3-tab-panel_Tabs_fl li[id] input:focus { padding: 4px; border-radius: 4px; - border: 1px solid #03a9f4; - box-shadow: 0 0 10px #03a9f4; - background: #2D3B46; + border: 1px solid #03a9f4; + box-shadow: 0 0 10px #03a9f4; + background: #2D3B46; } -#bp3-tab-panel_Tabs_fl .ul-unstyle{ +#bp3-tab-panel_Tabs_fl .ul-unstyle { margin-top: 5px; } -#bp3-tab-panel_Tabs_fl .bp3-card>.ul-unstyle{ - box-shadow: - 0 0 0 1px rgba(16, 22, 26, 0.15), - 0 0 0 rgba(16, 22, 26, 0), - 0 0 0 rgba(16, 22, 26, 0); +#bp3-tab-panel_Tabs_fl .bp3-card>.ul-unstyle { + box-shadow: + 0 0 0 1px rgba(16, 22, 26, 0.15), + 0 0 0 rgba(16, 22, 26, 0), + 0 0 0 rgba(16, 22, 26, 0); border-radius: 3px; } + //修改模态框body边距 -.bp3-dialog-body{ +.bp3-dialog-body { margin: 0; } + // .bp3-portal{ // z-index: 27; // }//此处无效 见DoorModal.less中 /**************** DownPanel *********************/ //修改字体select的箭头图标位置 -#DownPanel .bp3-html-select .bp3-icon -{ - top:0px; +#DownPanel .bp3-html-select .bp3-icon { + top: 0px; } + /**********魔改蓝图 工具栏tabs专用样式*****************/ -#TopToolBar .tabs-unstyle .bp3-tab.tab-unstyle{ - border:1px solid ; - border-width:0 1px 0 0; -} -.bp3-tab.tab-unstyle -{ - border:1px solid #25313a; - border-width:0 0 0 1px; +#TopToolBar .tabs-unstyle .bp3-tab.tab-unstyle { + border: 1px solid; + border-width: 0 1px 0 0; +} + +.bp3-tab.tab-unstyle { + border: 1px solid #25313a; + border-width: 0 0 0 1px; line-height: 20px; width: 95px; text-align: center; font-size: 10px; - &:hover - { + + &:hover { background: #394b59; } } + //tabs改颜色(详见颜色切换管理 .changeGolden) -.tabs-unstyle .bp3-tab-list > *:not(:last-child) -{ +.tabs-unstyle .bp3-tab-list>*:not(:last-child) { margin: 0; } + //去掉选中项的下box-shadow -.bp3-dark .tabs-unstyle .bp3-tab[aria-selected="true"] -{ - -webkit-box-shadow: none; +.bp3-dark .tabs-unstyle .bp3-tab[aria-selected="true"] { + -webkit-box-shadow: none; box-shadow: none; outline: none; } -.tabs-unstyle .bp3-tab[aria-selected="true"] -{ + +.tabs-unstyle .bp3-tab[aria-selected="true"] { -webkit-box-shadow: none; box-shadow: none; outline: none; } -.bp3-dark .tabs-unstyle .bp3-tab[aria-selected="true"], .tabs-unstyle .bp3-tab:not([aria-disabled="true"]):hover { + +.bp3-dark .tabs-unstyle .bp3-tab[aria-selected="true"], +.tabs-unstyle .bp3-tab:not([aria-disabled="true"]):hover { color: #f5f8fa; background: #394b59; } -.bp3-dark .tabs-unstyle .bp3-tab[aria-selected="true"], .bp3-dark .tabs-unstyle .bp3-tab:not([aria-disabled="true"]):hover{ + +.bp3-dark .tabs-unstyle .bp3-tab[aria-selected="true"], +.bp3-dark .tabs-unstyle .bp3-tab:not([aria-disabled="true"]):hover { color: #f5f8fa; background: #394b59; } -.tabs-unstyle .bp3-tab-panel{ + +.tabs-unstyle .bp3-tab-panel { margin: 0; } + /******************Vertical bp3-tabs*********************/ -.tabs-unstyle .bp3-tabs.bp3-vertical{ +.tabs-unstyle .bp3-tabs.bp3-vertical { height: 100%; // width: 280px; } -.tabs-unstyle .bp3-tabs.bp3-vertical > .bp3-tab-list{ + +.tabs-unstyle .bp3-tabs.bp3-vertical>.bp3-tab-list { writing-mode: vertical-rl; flex-direction: row; - .bp3-tab{ + + .bp3-tab { padding: 0; - flex:1; + flex: 1; border-radius: 0px; - border-width:0; + border-width: 0; outline: none; } } -.tabs-unstyle .bp3-tabs.bp3-vertical > .bp3-tab-panel { + +.tabs-unstyle .bp3-tabs.bp3-vertical>.bp3-tab-panel { padding-left: 0px; } /**********TopPanel大小调整*****************/ //TopPanel缩小 -#TopPanel .bp3-navbar -{ +#TopPanel .bp3-navbar { height: 27px; } -#TopPanel .bp3-navbar-group -{ + +#TopPanel .bp3-navbar-group { display: flex; -webkit-box-align: center; -ms-flex-align: center; align-items: center; height: 18px; + // padding-top: 5px; - &.bp3-align-left - { + &.bp3-align-left { height: 27px; } - &.bp3-align-right - { + + &.bp3-align-right { height: 27px; } - &.bp3-input - { + + &.bp3-input { height: 20px; } - &.bp3-button - { + + &.bp3-button { height: 20px; } } //Toaster自定义按钮 -.toaster-message{ +.toaster-message { align-items: center; - &>div{ + + &>div { margin-left: 20px; - button{ + + button { padding: 0; font-size: 11px; height: 18px; @@ -182,9 +198,13 @@ } } -.space-process{ +.space-process { transition: all 0.2s; height: 100%; background-color: #428bca; border-radius: 5; -} \ No newline at end of file +} + +.bp3-tree-node-content.moveenter { + background: #3DCC91; +}