diff --git a/public/resource/font_2024484_0fh6xrzocbtk.js b/public/resource/font_2024484_0fh6xrzocbtk.js
new file mode 100644
index 0000000..2106d85
--- /dev/null
+++ b/public/resource/font_2024484_0fh6xrzocbtk.js
@@ -0,0 +1 @@
+window._iconfont_svg_string_2024484='',(c=>{var l=(a=(a=document.getElementsByTagName("script"))[a.length-1]).getAttribute("data-injectcss"),a=a.getAttribute("data-disable-injectsvg");if(!a){var h,t,p,i,M,z=function(l,a){a.parentNode.insertBefore(l,a)};if(l&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}h=function(){var l,a=document.createElement("div");a.innerHTML=c._iconfont_svg_string_2024484,(a=a.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",a=a,(l=document.body).firstChild?z(a,l.firstChild):l.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),h()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(p=h,i=c.document,M=!1,F(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,d())})}function d(){M||(M=!0,p())}function F(){try{i.documentElement.doScroll("left")}catch(l){return void setTimeout(F,50)}d()}})(window);
diff --git a/public/resource/font_2024484_3m5puxhkyzz.js b/public/resource/font_2024484_3m5puxhkyzz.js
deleted file mode 100644
index a51a031..0000000
--- a/public/resource/font_2024484_3m5puxhkyzz.js
+++ /dev/null
@@ -1 +0,0 @@
-window._iconfont_svg_string_2024484='',(c=>{var l=(a=(a=document.getElementsByTagName("script"))[a.length-1]).getAttribute("data-injectcss"),a=a.getAttribute("data-disable-injectsvg");if(!a){var h,t,p,i,M,z=function(l,a){a.parentNode.insertBefore(l,a)};if(l&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}h=function(){var l,a=document.createElement("div");a.innerHTML=c._iconfont_svg_string_2024484,(a=a.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",a=a,(l=document.body).firstChild?z(a,l.firstChild):l.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),h()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(p=h,i=c.document,M=!1,F(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,d())})}function d(){M||(M=!0,p())}function F(){try{i.documentElement.doScroll("left")}catch(l){return void setTimeout(F,50)}d()}})(window);
diff --git a/src/api/direct-file.js b/src/api/direct-file.js
new file mode 100644
index 0000000..d3a2980
--- /dev/null
+++ b/src/api/direct-file.js
@@ -0,0 +1,40 @@
+import request from '@/utils/request'
+
+export default {
+ /**
+ * 创建直链
+ * @param params
+ * @returns {*}
+ */
+ createDirectLink: function(params) {
+ return request({
+ url: 'direct-link/create',
+ method: 'post',
+ params
+ })
+ },
+ /**
+ * 重置直链
+ * @param params
+ * @returns {*}
+ */
+ resetDirectLink: function(params) {
+ return request({
+ url: 'direct-link/reset',
+ method: 'put',
+ params
+ })
+ },
+ /**
+ * 重置直链
+ * @param params
+ * @returns {*}
+ */
+ resetAllDirectLink: function(params) {
+ return request({
+ url: 'direct-link/reset-all',
+ method: 'delete',
+ params
+ })
+ },
+}
diff --git a/src/components/DirectLinkDialog/index.vue b/src/components/DirectLinkDialog/index.vue
new file mode 100644
index 0000000..625d2bc
--- /dev/null
+++ b/src/components/DirectLinkDialog/index.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
diff --git a/src/components/Icon/Icon.vue b/src/components/Icon/Icon.vue
index 82e4f42..0eb168c 100644
--- a/src/components/Icon/Icon.vue
+++ b/src/components/Icon/Icon.vue
@@ -5,7 +5,7 @@
import { Icon } from 'ant-design-vue'
const IconFont = Icon.createFromIconfontCN({
- scriptUrl: document.location.protocol + '/resource/font_2024484_3m5puxhkyzz.js'
+ scriptUrl: document.location.protocol + '/resource/font_2024484_0fh6xrzocbtk.js'
})
// 把此段代码贴到iconfont项目页面的控制台中, 以获取图标列表
@@ -15,7 +15,7 @@ const IconFont = Icon.createFromIconfontCN({
// console.log(iconNames.slice(80,160))
export const iconFonts = {
- list: ['surge', 'dwg', 'epub', 'huanyuan', 'huishouzhan', 'glb', 'gengxinjindu', 'duigou', 'bars-solid', 'sort-amount-down-solid', 'sort-amount-up-alt-solid', 'tag2', 'guazai', 'duplicate', 'play1', "qrcode", "arrow1_left", "wulianwang-","zuji","disk-drive", "menu-fuzhi", "iso", "zuijinhuoyue","key", "shouquan", "sort", "grid", "list", "emoji-a", "emoji-bizui", "emoji-baiyan", "emoji-aixin", "emoji-dajing", "emoji-ziya", "emoji-daxiao", "emoji-esi", "emoji-fadai", "emoji-fankun", "emoji-ganga", "emoji-fennu", "emoji-hanyan", "emoji-jingkong", "emoji-haochi", "emoji-emo", "emoji-jingsong", "emoji-jingya", "emoji-kaixin", "emoji-lengku", "emoji-danao", "emoji-liukoushui", "emoji-liulei", "emoji-mengbi", "mianwubiaoqing", "nanguo", "shuizhuo", "taoyan", "tanchi", "siliao", "tiaopi", "xiaochulei", "wuliao", "xingxingyan", "xieyan", "xiasi", "xiaolian", "ku", "shengqi", "yousiliao", "en", "bushufu", "bianbian", "fankun1", "feiwen", "ganmao", "huaixiao", "liuhan", "outu", "keshui", "renzhe", "santiaoxian", "guaiwu", "shoushang", "tianshi", "shuai", "xianwen", "xiaodiaodaya", "xiong", "yiwen", "yun", "liubixie", "shimo", "dianzan", "biti", "fendou", "huqi", "heng", "kulou", "leng", "taoyan1", "shuixing", "aini", "aixin1", "zhadan", "xinsui",
+ list: ['a-editlink_nor', 'link', 'copy-link', 'surge', 'dwg', 'epub', 'huanyuan', 'huishouzhan', 'glb', 'gengxinjindu', 'duigou', 'bars-solid', 'sort-amount-down-solid', 'sort-amount-up-alt-solid', 'tag2', 'guazai', 'duplicate', 'play1', "qrcode", "arrow1_left", "wulianwang-","zuji","disk-drive", "menu-fuzhi", "iso", "zuijinhuoyue","key", "shouquan", "sort", "grid", "list", "emoji-a", "emoji-bizui", "emoji-baiyan", "emoji-aixin", "emoji-dajing", "emoji-ziya", "emoji-daxiao", "emoji-esi", "emoji-fadai", "emoji-fankun", "emoji-ganga", "emoji-fennu", "emoji-hanyan", "emoji-jingkong", "emoji-haochi", "emoji-emo", "emoji-jingsong", "emoji-jingya", "emoji-kaixin", "emoji-lengku", "emoji-danao", "emoji-liukoushui", "emoji-liulei", "emoji-mengbi", "mianwubiaoqing", "nanguo", "shuizhuo", "taoyan", "tanchi", "siliao", "tiaopi", "xiaochulei", "wuliao", "xingxingyan", "xieyan", "xiasi", "xiaolian", "ku", "shengqi", "yousiliao", "en", "bushufu", "bianbian", "fankun1", "feiwen", "ganmao", "huaixiao", "liuhan", "outu", "keshui", "renzhe", "santiaoxian", "guaiwu", "shoushang", "tianshi", "shuai", "xianwen", "xiaodiaodaya", "xiong", "yiwen", "yun", "liubixie", "shimo", "dianzan", "biti", "fendou", "huqi", "heng", "kulou", "leng", "taoyan1", "shuixing", "aini", "aixin1", "zhadan", "xinsui",
"maren", "zhutou", "qie", "youling", "apple-fill", "attachment", "android-fill", "apple", "download", "arrow-up-circle", "arrow-right-circle", "arrow-down", "ashbin", "add", "file_music", "menu", "role", "jiaoseguanli", "yemianshezhi", "drop_down", "yuandian", "tag", "service-directory", "fabu", "wailian", "bianji-", "WEBSITE", "wangzhanguanli", "Up", "up", "fenlei", "guanlizhuanjiawenzhang", "pifu", "tuichudenglu", "shezhi", "wangzhan", "huaban", "yunshezhi", "UserSettings", "blogger", "biaoqian", "myself", "guidang", "quxiaoyulan1-copy", "yulan-copy", "quxiaoyulan1", "yulan"]
}
diff --git a/src/components/ShowFile/ShowFile.vue b/src/components/ShowFile/ShowFile.vue
index 3ea68a0..1a1dd48 100644
--- a/src/components/ShowFile/ShowFile.vue
+++ b/src/components/ShowFile/ShowFile.vue
@@ -775,6 +775,7 @@
@onSuccess="shareSuccess"
@onCancelShare="onCancelShare"
>
+
-1) {
- this.menus.splice(index, 1)
- }
+ const reservations = ['open', 'tag']
+ // 删除this.menus中不要的菜单, 仅保留reservations中的菜单
+ this.menus = this.menus.filter(item =>
+ reservations.includes(item.operation)
+ )
}
this.setMenusCopyDownLoadLinks(row)
}
@@ -3656,20 +3661,20 @@ export default {
e.clientX = event.clientX + 50
e.clientY = event.clientY + 2
e.top = event.clientY
- e.left = event.clientX
+ e.left = event.clientX + 2
const dividerSize = this.menus.filter(item => item.divider).length
- const containerWidth = 180 + 5
- const containerHeight = (this.menus.length - dividerSize) * 35 + (dividerSize * 10) + 21
+ const containerWidth = 180 + 10
+ const containerHeight = (this.menus.length - dividerSize) * 35 + (dividerSize * 11) + 18 + 10
const distanceToBottom = document.documentElement.clientHeight - event.clientY
const distanceToRight = document.documentElement.clientWidth - event.clientX
if (distanceToBottom < containerHeight) {
- e.top = event.clientY - containerHeight
+ e.top = event.clientY - (containerHeight - distanceToBottom)
}
if (distanceToRight < containerWidth) {
- e.left = event.clientX - containerWidth
+ e.left = event.clientX - containerWidth + 8
}
@@ -3896,6 +3901,15 @@ export default {
// 返回原处
this.restoreFile()
break
+ case 'manageDirectLink':
+ // 管理直链
+ this.directLinkDialogVisible = true
+ this.$refs.directLinkDialog.getDirectLink(this.rowContextData)
+ break
+ case 'copyDirectLink':
+ // 复制直链
+ this.$refs.directLinkDialog.getDirectLink(this.rowContextData, true)
+ break
}
this.$refs.contextShow.hideMenu()
},
@@ -4769,6 +4783,9 @@ export default {
if (this.shareDialogVisible) {
return true
}
+ if (this.directLinkDialogVisible) {
+ return true
+ }
if (this.tagDialogVisible) {
return true
}
diff --git a/src/components/VContextmenu/file-contextmenu.vue b/src/components/VContextmenu/file-contextmenu.vue
index 68e8b4e..1433cb9 100644
--- a/src/components/VContextmenu/file-contextmenu.vue
+++ b/src/components/VContextmenu/file-contextmenu.vue
@@ -124,7 +124,7 @@ export default {
padding: 0 10px;
display: flex;
align-items: center;
- justify-content: space-between;
+ justify-content: flex-start;
>>> .svg-icon {
margin-right: 10px;
diff --git a/src/utils/copy-text.js b/src/utils/copy-text.js
new file mode 100644
index 0000000..33acca2
--- /dev/null
+++ b/src/utils/copy-text.js
@@ -0,0 +1,36 @@
+export async function copyText(text) {
+ if (navigator.clipboard && navigator.clipboard.writeText) {
+ try {
+ await navigator.clipboard.writeText(text);
+ this.$message.success('复制成功');
+ } catch (err) {
+ fallbackCopyText(text);
+ }
+ } else {
+ fallbackCopyText(text);
+ }
+}
+
+export function fallbackCopyText(text) {
+ const textarea = document.createElement('textarea');
+ textarea.value = text;
+ textarea.setAttribute('readonly', ''); // 防止手机端弹出键盘
+ textarea.style.position = 'absolute';
+ textarea.style.left = '-9999px';
+ document.body.appendChild(textarea);
+ // 兼容 Safari 和 Chrome 的选中文本方式
+ textarea.select();
+ textarea.setSelectionRange(0, textarea.value.length); // 额外设置范围,兼容 Safari
+ try {
+ const successful = document.execCommand('copy');
+ if (successful) {
+ Vue.prototype.$message.success('复制成功');
+ } else {
+ Vue.prototype.$message.error('复制失败');
+ }
+ } catch (err) {
+ console.error('execCommand 复制失败:', err);
+ Vue.prototype.$message.error('复制失败');
+ }
+ document.body.removeChild(textarea);
+}
diff --git a/src/utils/file-config.js b/src/utils/file-config.js
index a456e4b..c23424c 100644
--- a/src/utils/file-config.js
+++ b/src/utils/file-config.js
@@ -143,4 +143,11 @@ export default {
}
return null;
},
+ directFileUrl: function(mark, file) {
+ if (file.isFolder) {
+ return window.location.origin + `${this.baseUrl}/direct-file/${mark}/${file.name}.zip`
+ } else {
+ return window.location.origin + `${this.baseUrl}/direct-file/${mark}/${file.name}`
+ }
+ }
}
diff --git a/src/utils/file-operations.js b/src/utils/file-operations.js
index ee53f6f..0fba291 100644
--- a/src/utils/file-operations.js
+++ b/src/utils/file-operations.js
@@ -14,6 +14,11 @@ export const fileOperations = {
}
}
+export const directLinkSubMenus = [
+ { label: '管理...', operation: 'manageDirectLink', iconClass: 'a-editlink_nor'},
+ { label: '复制', operation: 'copyDirectLink', iconClass: 'copy-link'},
+]
+
export const fileArrangements = [
{ label: '名称', operation: 'orderName', orderProp: 'name'},
{ label: '大小', operation: 'orderSize', orderProp: 'size'},