分享复制链接处理

This commit is contained in:
jianzhichu
2025-11-30 02:01:32 +08:00
parent ea8f8948f8
commit d4b3e36591
5 changed files with 80 additions and 56 deletions
@@ -4,8 +4,8 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<_PublishTargetUrl>bin\Release\net6.0\publish\</_PublishTargetUrl>
<History>True|2025-11-27T05:37:08.6884390Z||;False|2025-11-27T13:36:54.2595622+08:00||;True|2025-11-27T11:03:33.8401644+08:00||;False|2025-11-27T11:02:48.8942827+08:00||;True|2025-11-26T23:48:02.3957186+08:00||;True|2025-11-26T23:43:06.8154188+08:00||;False|2025-11-26T23:42:05.9191485+08:00||;True|2025-11-26T23:30:11.1295861+08:00||;True|2025-11-26T00:00:42.1507258+08:00||;True|2025-11-26T00:00:17.0107229+08:00||;True|2025-11-25T23:42:07.4349629+08:00||;False|2025-11-25T23:41:56.9328658+08:00||;True|2025-11-25T23:19:32.5262917+08:00||;True|2025-11-25T14:08:53.3850967+08:00||;True|2025-11-24T23:53:54.4283003+08:00||;True|2025-11-24T23:41:15.8248332+08:00||;True|2025-11-24T23:33:57.1844427+08:00||;True|2025-11-24T23:31:54.9228836+08:00||;True|2025-11-24T23:24:15.8681502+08:00||;True|2025-11-24T23:22:57.9046229+08:00||;True|2025-11-24T23:18:04.1131647+08:00||;True|2025-11-24T22:47:54.1336448+08:00||;True|2025-11-24T22:47:18.3613833+08:00||;True|2025-11-24T08:17:50.3994607+08:00||;True|2025-11-24T08:07:00.9951205+08:00||;True|2025-11-23T23:34:50.0030826+08:00||;True|2025-11-23T23:32:36.7452616+08:00||;True|2025-11-22T23:18:56.3202345+08:00||;True|2025-11-22T22:52:51.7203302+08:00||;True|2025-11-22T22:52:42.9620946+08:00||;True|2025-11-22T22:52:09.8257640+08:00||;True|2025-11-22T22:39:31.5894141+08:00||;True|2025-11-22T22:31:11.0704815+08:00||;True|2025-11-22T22:20:36.4579131+08:00||;True|2025-11-22T22:19:10.2281364+08:00||;True|2025-11-22T19:34:45.9336901+08:00||;True|2025-11-12T23:06:38.7834109+08:00||;False|2025-11-12T23:01:02.2269478+08:00||;True|2025-10-22T22:08:11.6423148+08:00||;True|2025-10-22T21:54:24.7180547+08:00||;True|2025-10-22T21:40:03.5194315+08:00||;True|2025-10-22T21:28:28.8962766+08:00||;True|2025-10-22T21:22:47.9631689+08:00||;True|2025-10-22T21:18:24.5274318+08:00||;True|2025-10-22T21:14:51.6386326+08:00||;False|2025-10-22T21:14:07.6282769+08:00||;True|2025-10-22T21:03:48.9892860+08:00||;True|2025-10-22T21:00:56.3617243+08:00||;False|2025-10-22T21:00:30.5472941+08:00||;True|2025-10-22T20:51:29.6155916+08:00||;False|2025-10-22T20:50:47.1882956+08:00||;True|2025-10-22T15:01:04.1668366+08:00||;True|2025-10-22T14:49:43.6340569+08:00||;True|2025-10-22T14:38:39.4685603+08:00||;True|2025-10-21T18:35:28.8392541+08:00||;True|2025-10-20T10:31:05.5865212+08:00||;True|2025-10-20T10:20:41.5717101+08:00||;True|2025-10-19T10:08:33.6669332+08:00||;False|2025-10-19T10:07:22.3337545+08:00||;False|2025-10-19T10:05:22.9484805+08:00||;True|2025-10-10T16:54:27.1472888+08:00||;False|2025-10-10T16:53:44.1700030+08:00||;False|2025-10-10T16:52:48.1740453+08:00||;False|2025-10-10T16:51:21.5067253+08:00||;False|2025-10-10T16:50:19.2140597+08:00||;False|2025-10-10T16:49:21.2213290+08:00||;False|2025-10-10T16:48:47.7229948+08:00||;False|2025-10-10T16:48:15.1258700+08:00||;True|2025-09-30T13:29:42.2354235+08:00||;True|2025-09-25T11:44:52.6858389+08:00||;True|2025-09-25T11:08:27.8810109+08:00||;True|2025-09-25T09:28:50.2563374+08:00||;True|2025-09-24T16:14:02.3072184+08:00||;True|2025-09-23T22:38:52.4414757+08:00||;True|2025-09-23T22:19:07.1006356+08:00||;True|2025-09-23T22:18:01.5945225+08:00||;True|2025-09-23T22:06:15.6293613+08:00||;True|2025-09-23T21:53:14.2977444+08:00||;True|2025-09-23T21:46:55.2322411+08:00||;False|2025-09-23T21:45:23.7858854+08:00||;False|2025-09-23T21:03:51.8325689+08:00||;True|2025-09-23T10:03:32.2251920+08:00||;False|2025-09-23T09:38:08.2372201+08:00||;False|2025-09-23T09:37:49.9390545+08:00||;True|2024-03-11T21:31:45.8102398+08:00||;True|2024-03-11T07:26:24.7660541+08:00||;True|2024-03-08T22:08:40.0154831+08:00||;True|2024-03-03T10:14:36.8109114+08:00||;True|2024-03-02T18:44:57.3288537+08:00||;True|2024-01-24T17:51:37.9164415+08:00||;True|2024-01-24T16:36:50.5612157+08:00||;True|2024-01-24T15:51:35.7556653+08:00||;True|2024-01-17T23:40:40.7526618+08:00||;True|2024-01-17T23:36:10.3692844+08:00||;True|2024-01-17T23:22:03.2378834+08:00||;True|2024-01-03T11:35:44.7118292+08:00||;True|2024-01-03T11:11:23.4270453+08:00||;True|2024-01-03T11:04:35.2081526+08:00||;True|2024-01-03T10:57:03.7053107+08:00||;True|2024-01-03T10:51:50.7463989+08:00||;</History>
<_PublishTargetUrl>E:\code\dysync\bin\Release\net6.0\publish\</_PublishTargetUrl>
<History>True|2025-11-29T17:49:46.4358206Z||;False|2025-11-30T01:49:34.4884036+08:00||;True|2025-11-30T01:43:41.1028753+08:00||;True|2025-11-30T01:38:18.2856609+08:00||;True|2025-11-30T01:23:02.4378259+08:00||;True|2025-11-30T01:08:29.4041159+08:00||;True|2025-11-30T00:56:33.4172007+08:00||;False|2025-11-30T00:56:21.2777389+08:00||;True|2025-11-27T13:37:08.6884390+08:00||;False|2025-11-27T13:36:54.2595622+08:00||;True|2025-11-27T11:03:33.8401644+08:00||;False|2025-11-27T11:02:48.8942827+08:00||;True|2025-11-26T23:48:02.3957186+08:00||;True|2025-11-26T23:43:06.8154188+08:00||;False|2025-11-26T23:42:05.9191485+08:00||;True|2025-11-26T23:30:11.1295861+08:00||;True|2025-11-26T00:00:42.1507258+08:00||;True|2025-11-26T00:00:17.0107229+08:00||;True|2025-11-25T23:42:07.4349629+08:00||;False|2025-11-25T23:41:56.9328658+08:00||;True|2025-11-25T23:19:32.5262917+08:00||;True|2025-11-25T14:08:53.3850967+08:00||;True|2025-11-24T23:53:54.4283003+08:00||;True|2025-11-24T23:41:15.8248332+08:00||;True|2025-11-24T23:33:57.1844427+08:00||;True|2025-11-24T23:31:54.9228836+08:00||;True|2025-11-24T23:24:15.8681502+08:00||;True|2025-11-24T23:22:57.9046229+08:00||;True|2025-11-24T23:18:04.1131647+08:00||;True|2025-11-24T22:47:54.1336448+08:00||;True|2025-11-24T22:47:18.3613833+08:00||;True|2025-11-24T08:17:50.3994607+08:00||;True|2025-11-24T08:07:00.9951205+08:00||;True|2025-11-23T23:34:50.0030826+08:00||;True|2025-11-23T23:32:36.7452616+08:00||;True|2025-11-22T23:18:56.3202345+08:00||;True|2025-11-22T22:52:51.7203302+08:00||;True|2025-11-22T22:52:42.9620946+08:00||;True|2025-11-22T22:52:09.8257640+08:00||;True|2025-11-22T22:39:31.5894141+08:00||;True|2025-11-22T22:31:11.0704815+08:00||;True|2025-11-22T22:20:36.4579131+08:00||;True|2025-11-22T22:19:10.2281364+08:00||;True|2025-11-22T19:34:45.9336901+08:00||;True|2025-11-12T23:06:38.7834109+08:00||;False|2025-11-12T23:01:02.2269478+08:00||;True|2025-10-22T22:08:11.6423148+08:00||;True|2025-10-22T21:54:24.7180547+08:00||;True|2025-10-22T21:40:03.5194315+08:00||;True|2025-10-22T21:28:28.8962766+08:00||;True|2025-10-22T21:22:47.9631689+08:00||;True|2025-10-22T21:18:24.5274318+08:00||;True|2025-10-22T21:14:51.6386326+08:00||;False|2025-10-22T21:14:07.6282769+08:00||;True|2025-10-22T21:03:48.9892860+08:00||;True|2025-10-22T21:00:56.3617243+08:00||;False|2025-10-22T21:00:30.5472941+08:00||;True|2025-10-22T20:51:29.6155916+08:00||;False|2025-10-22T20:50:47.1882956+08:00||;True|2025-10-22T15:01:04.1668366+08:00||;True|2025-10-22T14:49:43.6340569+08:00||;True|2025-10-22T14:38:39.4685603+08:00||;True|2025-10-21T18:35:28.8392541+08:00||;True|2025-10-20T10:31:05.5865212+08:00||;True|2025-10-20T10:20:41.5717101+08:00||;True|2025-10-19T10:08:33.6669332+08:00||;False|2025-10-19T10:07:22.3337545+08:00||;False|2025-10-19T10:05:22.9484805+08:00||;True|2025-10-10T16:54:27.1472888+08:00||;False|2025-10-10T16:53:44.1700030+08:00||;False|2025-10-10T16:52:48.1740453+08:00||;False|2025-10-10T16:51:21.5067253+08:00||;False|2025-10-10T16:50:19.2140597+08:00||;False|2025-10-10T16:49:21.2213290+08:00||;False|2025-10-10T16:48:47.7229948+08:00||;False|2025-10-10T16:48:15.1258700+08:00||;True|2025-09-30T13:29:42.2354235+08:00||;True|2025-09-25T11:44:52.6858389+08:00||;True|2025-09-25T11:08:27.8810109+08:00||;True|2025-09-25T09:28:50.2563374+08:00||;True|2025-09-24T16:14:02.3072184+08:00||;True|2025-09-23T22:38:52.4414757+08:00||;True|2025-09-23T22:19:07.1006356+08:00||;True|2025-09-23T22:18:01.5945225+08:00||;True|2025-09-23T22:06:15.6293613+08:00||;True|2025-09-23T21:53:14.2977444+08:00||;True|2025-09-23T21:46:55.2322411+08:00||;False|2025-09-23T21:45:23.7858854+08:00||;False|2025-09-23T21:03:51.8325689+08:00||;True|2025-09-23T10:03:32.2251920+08:00||;False|2025-09-23T09:38:08.2372201+08:00||;False|2025-09-23T09:37:49.9390545+08:00||;True|2024-03-11T21:31:45.8102398+08:00||;True|2024-03-11T07:26:24.7660541+08:00||;True|2024-03-08T22:08:40.0154831+08:00||;True|2024-03-03T10:14:36.8109114+08:00||;True|2024-03-02T18:44:57.3288537+08:00||;True|2024-01-24T17:51:37.9164415+08:00||;True|2024-01-24T16:36:50.5612157+08:00||;True|2024-01-24T15:51:35.7556653+08:00||;</History>
<LastFailureDetails />
</PropertyGroup>
<ItemGroup>
+4 -2
View File
@@ -114,7 +114,7 @@
<span>系统运行日志的保留天数范围1-90过期自动清理</span>
</div>
</a-form-item>
<a-form-item has-feedback label="是否统一存储" name="AutoDistinct" :wrapper-col="{ span: 10 }">
<a-form-item has-feedback label="是否自动去重" name="AutoDistinct" :wrapper-col="{ span: 10 }">
<a-switch v-model:checked="formState.AutoDistinct" />
<div class="flex items-start mt-1 text-sm text-gray-500">
<InfoCircleOutlined class="text-blue-400 mr-1 mt-0.5" />
@@ -132,7 +132,9 @@
<a-button type="primary" @click="onUpdate" v-if="componentDisabled">
<SaveOutlined />修改配置
</a-button>
<a-button type="primary" danger @click="onSubmit" v-if="!componentDisabled">确认保存</a-button>
<a-button type="primary" danger @click="onSubmit" v-if="!componentDisabled">
<CheckOutlined />确认保存
</a-button>
<a-button type="default" @click="onCancel" v-if="!componentDisabled">取消</a-button>
</a-space>
</a-form-item>
+69 -50
View File
@@ -36,7 +36,10 @@
</a-radio-group>
</a-form-item>
<a-form-item class="form-item batch-operation-item">
<a-button type="primary" @click="GetRecords" class="query-button">
<SearchOutlined />查询
</a-button>
<a-form-item class="form-item batch-operation-item" style="margin-left:20px;">
<a-switch v-model:checked="isBatchMode" checked-children="批量操作" un-checked-children="批量操作" class="batch-switch" />
</a-form-item>
@@ -47,20 +50,16 @@
分享选中
</a-button>
<a-button type="danger" @click="handleBatchDelete" class="delete-button" v-if="isBatchMode" :disabled="selectedRowKeys.length === 0 || isSyncing">
<DeleteOutlined />
删除选中
<SyncOutlined />
重新同步
</a-button>
<a-button type="primary" @click="GetRecords" class="query-button">
<SearchOutlined />查询
</a-button>
<a-button type="danger" @click="StartNow" :disabled="isSyncing" class="sync-button">
<!-- <a-button type="danger" @click="StartNow" :disabled="isSyncing" class="sync-button">
<template #icon>
<a-spin v-if="isSyncing" size="small" />
</template>
<SyncOutlined />
立即同步
</a-button>
</a-button> -->
</a-space>
</a-form-item>
</div>
@@ -113,7 +112,7 @@
<template v-if="column.key === 'operation'">
<a-space size="small">
<a-button type="link" @click="handleReDownload(record)" :disabled="isSyncing">
<DownloadOutlined />
<SyncOutlined />
重新同步
</a-button>
<a-button type="link" @click="handleShare(record)" :disabled="!record.id">
@@ -206,6 +205,12 @@ const columns = ref([
align: 'center',
width: 180,
},
{
title: '发布时间',
dataIndex: 'createTimeStr',
align: 'center',
width: 180,
},
{
title: '同步类型',
dataIndex: 'viedoTypeStr',
@@ -234,7 +239,7 @@ const columns = ref([
title: 'CK名称',
dataIndex: 'dyUser',
align: 'center',
width: 200,
width: 120,
},
{
title: '操作',
@@ -644,35 +649,63 @@ const handleBatchShare = () => {
try {
// console.log('执行分享操作,视频ID', record.id, '视频标题:', record.videoTitle);
// 生成分享链接
const currentDomain = window.location.origin;
let shareUrl = '';
matchedItems.forEach((record) => {
let k = CryptoJS.MD5(record.fileHash + record.authorId).toString();
shareUrl += `${import.meta.env.VITE_API_URL}share/${record.id}/${k}
shareUrl += `${currentDomain}/share/${record.id}/${k}
`;
});
// 复制链接到剪贴板
navigator.clipboard
.writeText(shareUrl)
.then(() => {
message.success('分享链接已复制到剪贴板!');
})
.catch(() => {
// 降级方案:显示链接让用户手动复制
Modal.info({
title: '视频分享',
content: `
<p>分享链接:<a href="${shareUrl}" target="_blank" rel="noopener noreferrer">${shareUrl}</a></p>
<p style="margin-top: 8px;">复制链接后可分享给他人</p>
`,
okText: '已复制',
});
});
copyToClipboard(shareUrl);
} catch (error) {
console.error('分享失败:', error);
message.error('分享功能异常,请稍后重试');
}
};
// 复制链接到剪贴板(兼容生产环境)
const copyToClipboard = async (shareUrl) => {
try {
// 方案1:优先使用 navigator.clipboard(现代浏览器+HTTPS环境)
if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
await navigator.clipboard.writeText(shareUrl);
message.success('分享链接已复制到剪贴板!');
} else {
// 方案2:降级使用 document.execCommand(兼容HTTP/旧浏览器)
const textarea = document.createElement('textarea');
// 隐藏文本域(避免影响页面布局)
textarea.style.position = 'absolute';
textarea.style.top = '-9999px';
textarea.style.left = '-9999px';
// 设置要复制的内容
textarea.value = shareUrl;
document.body.appendChild(textarea);
// 选中并复制
textarea.select();
const success = document.execCommand('copy');
document.body.removeChild(textarea); // 清理DOM
if (success) {
message.success('分享链接已复制到剪贴板!');
} else {
// 方案3:最终降级 - 显示链接让用户手动复制
throw new Error('自动复制失败');
}
}
} catch (error) {
console.warn('复制失败,触发手动复制方案:', error);
// 最终降级:显示链接弹窗
Modal.info({
title: '视频分享',
content: `
<p>分享链接:<a href="${shareUrl}" target="_blank" rel="noopener noreferrer">${shareUrl}</a></p>
<p style="margin-top: 8px; color: #666;">请手动复制链接后分享给他人</p>
`,
okText: '已复制',
onOk: () => {},
});
}
};
/** 分享事件 */
const handleShare = (record: DataItem) => {
if (!record.id) {
@@ -681,27 +714,12 @@ const handleShare = (record: DataItem) => {
}
try {
const currentDomain = window.location.origin;
// console.log('执行分享操作,视频ID', record.id, '视频标题:', record.videoTitle);
// 生成分享链接
let k = CryptoJS.MD5(record.fileHash + record.authorId).toString();
const shareUrl = `${import.meta.env.VITE_API_URL}share/${record.id}/${k}`;
// 复制链接到剪贴板
navigator.clipboard
.writeText(shareUrl)
.then(() => {
message.success('分享链接已复制到剪贴板!');
})
.catch(() => {
// 降级方案:显示链接让用户手动复制
Modal.info({
title: '视频分享',
content: `
<p>分享链接:<a href="${shareUrl}" target="_blank" rel="noopener noreferrer">${shareUrl}</a></p>
<p style="margin-top: 8px;">复制链接后可分享给他人</p>
`,
okText: '已复制',
});
});
const shareUrl = `${currentDomain}/share/${record.id}/${k}`;
copyToClipboard(shareUrl);
} catch (error) {
console.error('分享失败:', error);
message.error('分享功能异常,请稍后重试');
@@ -759,7 +777,8 @@ onMounted(() => {
/* 新增:批量操作开关样式 */
.batch-operation-item {
margin-right: 16px !important;
margin-left: 20 !important;
/* margin-right: 16px !important; */
}
.batch-switch {
@@ -826,7 +845,7 @@ onMounted(() => {
align-items: flex-start !important;
}
.batch-operation-item {
margin-left: 0 !important;
margin-left: 20 !important;
margin-top: 8px !important;
}
.button-group-item {
+1 -1
View File
@@ -129,7 +129,7 @@ namespace dy.net.model
/// 作者发布视频日期
/// </summary>
[SugarColumn(IsIgnore = true)]
public string createTimeStr => SyncTime.ToString("yyyy-MM-dd HH:mm:ss");
public string createTimeStr => CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
[SugarColumn(IsIgnore = true)]
public string SyncTimeStr => SyncTime.ToString("yyyy-MM-dd HH:mm:ss");
+4 -1
View File
@@ -67,6 +67,9 @@ namespace dy.net.utils
{
title = id;
}
title = Regex.Replace(title, @"[^a-zA-Z0-9\u4e00-\u9fa5]", "-");
// 步骤1:移除话题标签(#xxx 或 #xxx#yyy
//title = Regex.Replace(title, @"#\S+", "", RegexOptions.Compiled);
@@ -147,7 +150,7 @@ namespace dy.net.utils
// 步骤2:移除表情符号(匹配常见表情Unicode区块)
//string emojiPattern = @"[\u1F600-\u1F64F\u1F300-\u1F5FF\u1F680-\u1F6FF\u1E000-\u1EFFF\u2600-\u2B55\u200D]";
//path = Regex.Replace(path, emojiPattern, "", RegexOptions.Compiled);
path = Regex.Replace(path, @"[^a-zA-Z0-9\u4e00-\u9fa5]", "-");
foreach (var c in Path.GetInvalidFileNameChars())
{