mirror of
https://github.com/kuaifan/dootask.git
synced 2026-02-26 11:40:28 +00:00
Compare commits
5 Commits
dd2cd1df9a
...
f65da118d7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f65da118d7 | ||
|
|
a86bd9a05e | ||
|
|
f2719eb742 | ||
|
|
4f9ee1dfa9 | ||
|
|
e6ad1218bc |
@ -22,7 +22,7 @@ class AI
|
|||||||
'qianwen',
|
'qianwen',
|
||||||
'wenxin'
|
'wenxin'
|
||||||
];
|
];
|
||||||
protected const OPENAI_DEFAULT_MODEL = 'gpt-5-mini';
|
protected const OPENAI_DEFAULT_MODEL = 'gpt-5.1-mini';
|
||||||
|
|
||||||
protected $post = [];
|
protected $post = [];
|
||||||
protected $headers = [];
|
protected $headers = [];
|
||||||
@ -730,6 +730,12 @@ class AI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$model = $provider['model'] ?? '';
|
$model = $provider['model'] ?? '';
|
||||||
return str_starts_with($model, 'gpt-5');
|
|
||||||
|
// 匹配 gpt- 开头后跟数字的模型名称
|
||||||
|
if (preg_match('/^gpt-(\d+)/', $model, $matches)) {
|
||||||
|
return intval($matches[1]) >= 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -96,7 +96,7 @@ services:
|
|||||||
appstore:
|
appstore:
|
||||||
container_name: "dootask-appstore-${APP_ID}"
|
container_name: "dootask-appstore-${APP_ID}"
|
||||||
privileged: true
|
privileged: true
|
||||||
image: "dootask/appstore:0.3.0"
|
image: "dootask/appstore:0.3.2"
|
||||||
volumes:
|
volumes:
|
||||||
- shared_data:/usr/share/dootask
|
- shared_data:/usr/share/dootask
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
|||||||
5
electron/electron.js
vendored
5
electron/electron.js
vendored
@ -521,6 +521,11 @@ function createChildWindow(args) {
|
|||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
}, webPreferences),
|
}, webPreferences),
|
||||||
}, config)
|
}, config)
|
||||||
|
|
||||||
|
options.width = utils.normalizeSize(options.width, 1280)
|
||||||
|
options.height = utils.normalizeSize(options.height, 800)
|
||||||
|
options.minWidth = utils.normalizeSize(options.minWidth, 360)
|
||||||
|
options.minHeight = utils.normalizeSize(options.minHeight, 360)
|
||||||
if (!options.webPreferences.contextIsolation) {
|
if (!options.webPreferences.contextIsolation) {
|
||||||
delete options.webPreferences.preload;
|
delete options.webPreferences.preload;
|
||||||
}
|
}
|
||||||
|
|||||||
11
electron/lib/utils.js
vendored
11
electron/lib/utils.js
vendored
@ -108,6 +108,17 @@ const utils = {
|
|||||||
return _s;
|
return _s;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兜底处理尺寸类数值,确保传入的是有限数字
|
||||||
|
* @param value
|
||||||
|
* @param fallback
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
normalizeSize(value, fallback) {
|
||||||
|
const parsed = Number(value);
|
||||||
|
return Number.isFinite(parsed) ? parsed : fallback;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 随机字符串
|
* 随机字符串
|
||||||
* @param len
|
* @param len
|
||||||
|
|||||||
@ -2261,4 +2261,10 @@ AI 分析已更新
|
|||||||
保存 AI 分析失败
|
保存 AI 分析失败
|
||||||
补充你想强调的重点或特殊说明,AI 将在此基础上整理汇报
|
补充你想强调的重点或特殊说明,AI 将在此基础上整理汇报
|
||||||
拖动卡片调整顺序,保存后仅自己可见
|
拖动卡片调整顺序,保存后仅自己可见
|
||||||
恢复默认
|
恢复默认
|
||||||
|
|
||||||
|
当前列表没有可归档的已完成任务
|
||||||
|
归档已完成任务
|
||||||
|
你确定将列表【(*)】中所有已完成的任务归档吗?
|
||||||
|
已归档列表中所有已完成任务
|
||||||
|
归档失败,请稍后再试
|
||||||
@ -32422,5 +32422,65 @@
|
|||||||
"fr": "Utilisateur",
|
"fr": "Utilisateur",
|
||||||
"id": "Pengguna",
|
"id": "Pengguna",
|
||||||
"ru": "Пользователь"
|
"ru": "Пользователь"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "当前列表没有可归档的已完成任务",
|
||||||
|
"zh": "",
|
||||||
|
"zh-CHT": "當前列表沒有可歸檔的已完成任務",
|
||||||
|
"en": "There are no completed tasks in the current list that can be archived",
|
||||||
|
"ko": "현재 목록에는 보관할 수 있는 완료된 작업이 없습니다",
|
||||||
|
"ja": "現在のリストにはアーカイブ可能な完了タスクがありません",
|
||||||
|
"de": "In der aktuellen Liste gibt es keine abgeschlossenen Aufgaben, die archiviert werden können",
|
||||||
|
"fr": "Il n’y a aucune tâche terminée pouvant être archivée dans la liste actuelle",
|
||||||
|
"id": "Tidak ada tugas selesai yang dapat diarsipkan dalam daftar saat ini",
|
||||||
|
"ru": "В текущем списке нет завершённых задач, которые можно архивировать"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "归档已完成任务",
|
||||||
|
"zh": "",
|
||||||
|
"zh-CHT": "歸檔已完成任務",
|
||||||
|
"en": "Archive completed tasks",
|
||||||
|
"ko": "완료된 작업 보관",
|
||||||
|
"ja": "完了タスクをアーカイブ",
|
||||||
|
"de": "Abgeschlossene Aufgaben archivieren",
|
||||||
|
"fr": "Archiver les tâches terminées",
|
||||||
|
"id": "Arsipkan tugas yang selesai",
|
||||||
|
"ru": "Архивировать завершённые задачи"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "你确定将列表【(*)】中所有已完成的任务归档吗?",
|
||||||
|
"zh": "",
|
||||||
|
"zh-CHT": "你確定將列表【(*)】中所有已完成的任務歸檔嗎?",
|
||||||
|
"en": "Are you sure you want to archive all completed tasks in the list 【(*)】?",
|
||||||
|
"ko": "목록 【(*)】의 모든 완료된 작업을 정말로 보관하시겠습니까?",
|
||||||
|
"ja": "リスト【(*)】内のすべての完了タスクをアーカイブしてよろしいですか?",
|
||||||
|
"de": "Möchten Sie wirklich alle abgeschlossenen Aufgaben in der Liste 【(*)】 archivieren?",
|
||||||
|
"fr": "Voulez-vous vraiment archiver toutes les tâches terminées de la liste 【(*)】 ?",
|
||||||
|
"id": "Anda yakin ingin mengarsipkan semua tugas yang sudah selesai di daftar 【(*)】?",
|
||||||
|
"ru": "Вы уверены, что хотите архивировать все завершённые задачи в списке 【(*)】?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "已归档列表中所有已完成任务",
|
||||||
|
"zh": "",
|
||||||
|
"zh-CHT": "已歸檔列表中所有已完成任務",
|
||||||
|
"en": "All completed tasks in the list have been archived",
|
||||||
|
"ko": "목록의 모든 완료된 작업이 보관되었습니다",
|
||||||
|
"ja": "リスト内のすべての完了タスクをアーカイブしました",
|
||||||
|
"de": "Alle abgeschlossenen Aufgaben in der Liste wurden archiviert",
|
||||||
|
"fr": "Toutes les tâches terminées de la liste ont été archivées",
|
||||||
|
"id": "Semua tugas yang selesai dalam daftar telah diarsipkan",
|
||||||
|
"ru": "Все завершённые задачи в списке были архивированы"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "归档失败,请稍后再试",
|
||||||
|
"zh": "",
|
||||||
|
"zh-CHT": "歸檔失敗,請稍後再試",
|
||||||
|
"en": "Archiving failed, please try again later",
|
||||||
|
"ko": "보관에 실패했습니다. 나중에 다시 시도해주세요",
|
||||||
|
"ja": "アーカイブに失敗しました。しばらくしてからもう一度お試しください",
|
||||||
|
"de": "Archivierung fehlgeschlagen, bitte versuchen Sie es später erneut",
|
||||||
|
"fr": "Échec de l’archivage, veuillez réessayer plus tard",
|
||||||
|
"id": "Pengarsipan gagal, silakan coba lagi nanti",
|
||||||
|
"ru": "Не удалось выполнить архивирование, повторите попытку позже"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -174,8 +174,8 @@ if (count($needs) > 0) {
|
|||||||
$openAi->setProxy($openAiProxy);
|
$openAi->setProxy($openAiProxy);
|
||||||
}
|
}
|
||||||
$result = $openAi->chat([
|
$result = $openAi->chat([
|
||||||
"model" => "gpt-5",
|
"model" => "gpt-5.1",
|
||||||
"reasoning_effort" => "minimal",
|
"reasoning_effort" => "low",
|
||||||
'messages' => [
|
'messages' => [
|
||||||
[
|
[
|
||||||
"role" => "system",
|
"role" => "system",
|
||||||
|
|||||||
2
public/language/web/de.js
vendored
2
public/language/web/de.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/en.js
vendored
2
public/language/web/en.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/fr.js
vendored
2
public/language/web/fr.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/id.js
vendored
2
public/language/web/id.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/ja.js
vendored
2
public/language/web/ja.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/key.js
vendored
2
public/language/web/key.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/ko.js
vendored
2
public/language/web/ko.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/ru.js
vendored
2
public/language/web/ru.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/zh-CHT.js
vendored
2
public/language/web/zh-CHT.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/zh.js
vendored
2
public/language/web/zh.js
vendored
File diff suppressed because one or more lines are too long
@ -130,6 +130,7 @@
|
|||||||
<EDropdown
|
<EDropdown
|
||||||
v-else
|
v-else
|
||||||
trigger="click"
|
trigger="click"
|
||||||
|
size="medium"
|
||||||
@command="dropColumn(column, $event)">
|
@command="dropColumn(column, $event)">
|
||||||
<Icon type="ios-more" />
|
<Icon type="ios-more" />
|
||||||
<EDropdownMenu slot="dropdown" class="project-panel-more-dropdown-menu">
|
<EDropdownMenu slot="dropdown" class="project-panel-more-dropdown-menu">
|
||||||
@ -140,6 +141,11 @@
|
|||||||
<Icon type="md-create" />{{$L('修改')}}
|
<Icon type="md-create" />{{$L('修改')}}
|
||||||
</div>
|
</div>
|
||||||
</EDropdownItem>
|
</EDropdownItem>
|
||||||
|
<EDropdownItem command="archive_completed">
|
||||||
|
<div class="item">
|
||||||
|
<Icon type="ios-filing" />{{$L('归档')}}
|
||||||
|
</div>
|
||||||
|
</EDropdownItem>
|
||||||
<EDropdownItem command="remove">
|
<EDropdownItem command="remove">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<Icon type="md-trash" />{{$L('删除')}}
|
<Icon type="md-trash" />{{$L('删除')}}
|
||||||
@ -1249,6 +1255,9 @@ export default {
|
|||||||
if (command === 'title') {
|
if (command === 'title') {
|
||||||
this.titleColumn(column);
|
this.titleColumn(column);
|
||||||
}
|
}
|
||||||
|
else if (command === 'archive_completed') {
|
||||||
|
this.archiveColumnCompletedTasks(column);
|
||||||
|
}
|
||||||
else if (command === 'remove') {
|
else if (command === 'remove') {
|
||||||
this.removeColumn(column);
|
this.removeColumn(column);
|
||||||
}
|
}
|
||||||
@ -1304,6 +1313,51 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
archiveColumnCompletedTasks(column) {
|
||||||
|
const tasks = this.getColumnCompletedTasks(column);
|
||||||
|
if (tasks.length === 0) {
|
||||||
|
$A.messageWarning('当前列表没有可归档的已完成任务');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$A.modalConfirm({
|
||||||
|
title: '归档已完成任务',
|
||||||
|
content: `你确定将列表【${column.name}】中所有已完成的任务归档吗?`,
|
||||||
|
loading: true,
|
||||||
|
onOk: () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.batchArchiveTasks(tasks).then(() => {
|
||||||
|
$A.messageSuccess('已归档列表中所有已完成任务');
|
||||||
|
resolve();
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError(msg || '归档失败,请稍后再试');
|
||||||
|
reject();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getColumnCompletedTasks(column) {
|
||||||
|
if (!column || !Array.isArray(column.tasks)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return column.tasks.filter(task => task && task.complete_at && !task.archived_at);
|
||||||
|
},
|
||||||
|
|
||||||
|
batchArchiveTasks(tasks) {
|
||||||
|
const archive = (index = 0) => {
|
||||||
|
if (index >= tasks.length) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
const task = tasks[index];
|
||||||
|
return this.$store.dispatch("archivedTask", {task_id: task.id}).then(() => {
|
||||||
|
this.$store.dispatch("saveTaskBrowse", task.id);
|
||||||
|
return archive(index + 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return archive();
|
||||||
|
},
|
||||||
|
|
||||||
removeColumn(column) {
|
removeColumn(column) {
|
||||||
$A.modalConfirm({
|
$A.modalConfirm({
|
||||||
title: '删除列表',
|
title: '删除列表',
|
||||||
|
|||||||
@ -966,6 +966,9 @@
|
|||||||
max-height: calc(100vh - 250px);
|
max-height: calc(100vh - 250px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
.item {
|
.item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user