Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d31106b0f | ||
|
|
fbd1c829a1 | ||
|
|
82d2ca6360 | ||
|
|
717e520556 | ||
|
|
c8ddb511cf | ||
|
|
caf728de8d | ||
|
|
a7cd4d7fa8 | ||
|
|
ddc0046e24 | ||
|
|
1059630b9d | ||
|
|
e1c1fc030f | ||
|
|
09edb14d56 | ||
|
|
f27cef2d66 | ||
|
|
07a2e6df29 | ||
|
|
f521f0df65 | ||
|
|
a67fcd6f02 | ||
|
|
d17f404853 | ||
|
|
8def4addc4 | ||
|
|
0ecaf9740f | ||
|
|
bc75680ee9 | ||
|
|
6a71964592 | ||
|
|
00a2ea3d2f | ||
|
|
95e97333b4 | ||
|
|
9e65500748 | ||
|
|
a2acd6f6e4 | ||
|
|
ee96730268 | ||
|
|
f925f238dd | ||
|
|
39c6ca3e8c | ||
|
|
c798faa8db |
83
.claude/skills/release/SKILL.md
Normal file
83
.claude/skills/release/SKILL.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
name: release
|
||||
description: Use when releasing a new DooTask frontend version from the `pro` branch. Rigid sequential workflow (translate → version → build → commit → push) with strict pre-checks (branch, clean worktree, Node 20+) and per-step user confirmation. Use when user says "发布新版本", "release", "出新版本", "打版本". Stop on any failure; do NOT auto-fix dirty worktree, do NOT add tag step, do NOT use `git add -A`.
|
||||
---
|
||||
|
||||
# DooTask 发布流程
|
||||
|
||||
**刚性技能**——严格按顺序执行,每步向用户确认,任何一步失败立即停止。
|
||||
|
||||
## 核心原则
|
||||
|
||||
**违反字面规则 = 违反流程精神。** 不要擅自增加、省略、合并或重排步骤。
|
||||
|
||||
## 前置检查(全部通过才能继续)
|
||||
|
||||
执行任何发布步骤前,依次检查:
|
||||
|
||||
1. **分支**:必须是 `pro`,否则停止,提示用户切换
|
||||
2. **工作区**:`git status` 必须干净(无未提交变更、无未跟踪文件),否则**停止**并交由用户处理
|
||||
3. **Node.js**:必须 ≥ 20,否则停止
|
||||
|
||||
检查通过后汇报结果,用户确认后再开始执行。
|
||||
|
||||
## 发布步骤
|
||||
|
||||
**每步执行前**向用户确认;**每步执行后**报告结果。
|
||||
|
||||
### Step 1: 翻译
|
||||
```shell
|
||||
npm run translate
|
||||
```
|
||||
更新多语言翻译文件。
|
||||
|
||||
### Step 2: 版本号
|
||||
```shell
|
||||
npm run version
|
||||
```
|
||||
更新版本号。
|
||||
|
||||
### Step 3: 构建前端
|
||||
```shell
|
||||
npm run build
|
||||
```
|
||||
构建前端生产版本。
|
||||
|
||||
## 最终:提交并推送
|
||||
|
||||
所有步骤完成后:
|
||||
|
||||
1. 通过 `git diff` + `git status` 汇总所有变更,向用户报告摘要
|
||||
2. **询问用户是否提交并推送**
|
||||
3. 用户明确确认后才执行 `git add`、`git commit`、`git push`
|
||||
4. 未确认一律不执行
|
||||
|
||||
提交规范:
|
||||
- 提交信息使用 `release: v<新版本号>`(与历史提交风格一致,参见 `git log --oneline | grep '^release:'`)
|
||||
- **只 add 本次发布相关改动**,按文件名显式添加(例如 `git add package.json public/js/...`),**不要用 `git add -A` 或 `git add .`**,以免卷入未跟踪的本地实验文件
|
||||
|
||||
## 失败处理
|
||||
|
||||
- 任何步骤失败立即停止,报告错误信息
|
||||
- **不要**自动重试
|
||||
- **不要**自动跳过失败步骤
|
||||
- 由用户决定如何处理
|
||||
|
||||
## 禁止项(基线测试暴露的反模式)
|
||||
|
||||
| 错误做法 | 正确做法 |
|
||||
|---------|---------|
|
||||
| 遇到脏工作区主动提出修复方案(加 `.gitignore`、先 push 等) | **停下**,报告脏工作区事实,交用户决定 |
|
||||
| 增加 `git tag v1.7.xx` 步骤 | DooTask 现行发布流程**不打 tag**,不要擅自添加 |
|
||||
| `git add -A` / `git add .` | 按文件名显式添加发布相关改动 |
|
||||
| 一次性 add + commit + push,不给确认机会 | 摘要 → 问确认 → 再 add/commit/push 三步分离 |
|
||||
| 把 translate/version/build 顺序自作主张调整 | 顺序固定为 translate → version → build |
|
||||
| 失败后"我再试一次"或"跳过这步" | 立即停止,交还给用户 |
|
||||
|
||||
## Red Flags —— 出现这些念头立即停下
|
||||
|
||||
- "这个脏工作区我来帮 TA 搞定一下" → 停下,交用户
|
||||
- "顺便打个 tag 吧" → 不,没有这一步
|
||||
- "`git add -A` 省事" → 不,显式 add
|
||||
- "翻译这步没改动可以跳" → 不,按顺序执行、执行后报告结果即可
|
||||
- "一起 commit + push 一气呵成" → 必须先让用户确认
|
||||
193
.github/workflows/ios-publish.yml
vendored
Normal file
193
.github/workflows/ios-publish.yml
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
name: "iOS Publish"
|
||||
|
||||
# Required GitHub Secrets:
|
||||
#
|
||||
# IOS_CERTIFICATE_BASE64 - Apple distribution certificate (.p12) encoded in base64
|
||||
# IOS_CERTIFICATE_PASSWORD - Password for the .p12 certificate
|
||||
# IOS_PROVISION_PROFILE_BASE64 - App Store provisioning profile (.mobileprovision) encoded in base64
|
||||
# ASC_API_KEY_P8_BASE64 - App Store Connect API key (.p8) encoded in base64
|
||||
# ASC_API_KEY_ID - App Store Connect API Key ID
|
||||
# ASC_ISSUER_ID - App Store Connect Issuer ID
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
prepare-assets:
|
||||
name: Prepare iOS Assets
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.get-version.outputs.version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Get version from package.json
|
||||
id: get-version
|
||||
run: |
|
||||
VERSION=$(node -p "require('./package.json').version")
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Version: $VERSION"
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Install electron dependencies
|
||||
run: |
|
||||
pushd electron
|
||||
npm install
|
||||
popd
|
||||
|
||||
- name: Init mobile submodule
|
||||
run: |
|
||||
git submodule init
|
||||
git submodule update --remote "resources/mobile"
|
||||
|
||||
- name: Build app assets
|
||||
run: ./cmd appbuild publish
|
||||
|
||||
- name: Upload iOS platform artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ios-platform
|
||||
path: resources/mobile/platforms/ios/
|
||||
retention-days: 1
|
||||
|
||||
build-ios:
|
||||
name: Build & Submit iOS
|
||||
needs: prepare-assets
|
||||
runs-on: macos-15
|
||||
environment: build
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Init mobile submodule
|
||||
run: |
|
||||
git submodule init
|
||||
git submodule update --remote "resources/mobile"
|
||||
|
||||
- name: Download prepared assets
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ios-platform
|
||||
path: resources/mobile/platforms/ios/
|
||||
|
||||
- name: Select Xcode
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: latest-stable
|
||||
|
||||
- name: Install CocoaPods
|
||||
run: |
|
||||
if [ -f "resources/mobile/platforms/ios/eeuiApp/Podfile" ]; then
|
||||
cd resources/mobile/platforms/ios/eeuiApp
|
||||
pod install
|
||||
fi
|
||||
|
||||
- name: Import signing certificate
|
||||
env:
|
||||
IOS_CERTIFICATE_BASE64: ${{ secrets.IOS_CERTIFICATE_BASE64 }}
|
||||
IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
|
||||
run: |
|
||||
# Create temporary keychain
|
||||
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
||||
KEYCHAIN_PASSWORD=$(openssl rand -hex 20)
|
||||
|
||||
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
|
||||
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
|
||||
# Import certificate
|
||||
CERTIFICATE_PATH=$RUNNER_TEMP/certificate.p12
|
||||
echo "$IOS_CERTIFICATE_BASE64" | base64 --decode > "$CERTIFICATE_PATH"
|
||||
security import "$CERTIFICATE_PATH" \
|
||||
-P "$IOS_CERTIFICATE_PASSWORD" \
|
||||
-A \
|
||||
-t cert \
|
||||
-f pkcs12 \
|
||||
-k "$KEYCHAIN_PATH"
|
||||
|
||||
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
security list-keychain -d user -s "$KEYCHAIN_PATH"
|
||||
|
||||
- name: Import provisioning profile
|
||||
env:
|
||||
IOS_PROVISION_PROFILE_BASE64: ${{ secrets.IOS_PROVISION_PROFILE_BASE64 }}
|
||||
run: |
|
||||
PROFILE_PATH=$RUNNER_TEMP/profile.mobileprovision
|
||||
echo "$IOS_PROVISION_PROFILE_BASE64" | base64 --decode > "$PROFILE_PATH"
|
||||
|
||||
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
cp "$PROFILE_PATH" ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
|
||||
- name: Build archive
|
||||
run: |
|
||||
cd resources/mobile/platforms/ios/eeuiApp
|
||||
xcodebuild archive \
|
||||
-workspace eeuiApp.xcworkspace \
|
||||
-scheme eeuiApp \
|
||||
-configuration Release \
|
||||
-archivePath $RUNNER_TEMP/eeuiApp.xcarchive \
|
||||
-allowProvisioningUpdates \
|
||||
CODE_SIGN_STYLE=Manual \
|
||||
| xcpretty
|
||||
|
||||
- name: Export IPA
|
||||
run: |
|
||||
cd resources/mobile/platforms/ios/eeuiApp
|
||||
|
||||
# Generate ExportOptions.plist
|
||||
cat > $RUNNER_TEMP/ExportOptions.plist << 'PLIST'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>method</key>
|
||||
<string>app-store</string>
|
||||
<key>uploadBitcode</key>
|
||||
<false/>
|
||||
<key>uploadSymbols</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST
|
||||
|
||||
xcodebuild -exportArchive \
|
||||
-archivePath $RUNNER_TEMP/eeuiApp.xcarchive \
|
||||
-exportOptionsPlist $RUNNER_TEMP/ExportOptions.plist \
|
||||
-exportPath $RUNNER_TEMP/ipa-output \
|
||||
-allowProvisioningUpdates \
|
||||
| xcpretty
|
||||
|
||||
- name: Submit to App Store Connect
|
||||
env:
|
||||
ASC_API_KEY_ID: ${{ secrets.ASC_API_KEY_ID }}
|
||||
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
|
||||
ASC_API_KEY_P8_BASE64: ${{ secrets.ASC_API_KEY_P8_BASE64 }}
|
||||
run: |
|
||||
# Prepare API key
|
||||
mkdir -p ~/private_keys
|
||||
echo "$ASC_API_KEY_P8_BASE64" | base64 --decode > ~/private_keys/AuthKey_${ASC_API_KEY_ID}.p8
|
||||
|
||||
# Find and upload IPA
|
||||
IPA_PATH=$(find $RUNNER_TEMP/ipa-output -name "*.ipa" | head -1)
|
||||
echo "Uploading: $IPA_PATH"
|
||||
|
||||
xcrun altool --upload-app \
|
||||
-f "$IPA_PATH" \
|
||||
--type ios \
|
||||
--apiKey "$ASC_API_KEY_ID" \
|
||||
--apiIssuer "$ASC_ISSUER_ID"
|
||||
|
||||
- name: Clean up
|
||||
if: always()
|
||||
run: |
|
||||
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db 2>/dev/null || true
|
||||
rm -f $RUNNER_TEMP/certificate.p12
|
||||
rm -f $RUNNER_TEMP/profile.mobileprovision
|
||||
rm -rf ~/private_keys
|
||||
76
.github/workflows/publish.yml
vendored
76
.github/workflows/publish.yml
vendored
@@ -52,53 +52,18 @@ jobs:
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
// 获取最新的 tag
|
||||
const { data: tags } = await github.rest.repos.listTags({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
per_page: 1
|
||||
});
|
||||
const fs = require('fs');
|
||||
const version = '${{ needs.check-version.outputs.version }}';
|
||||
|
||||
// 获取提交日志
|
||||
// 从 CHANGELOG.md 提取当前版本段落
|
||||
let changelog = '';
|
||||
if (tags.length > 0) {
|
||||
const { data: commits } = await github.rest.repos.compareCommits({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
base: tags[0].name,
|
||||
head: 'HEAD'
|
||||
});
|
||||
|
||||
// 按类型分组提交
|
||||
const groups = {
|
||||
'feat:': { title: '## Features', commits: new Set() },
|
||||
'fix:': { title: '## Bug Fixes', commits: new Set() },
|
||||
'perf:': { title: '## Performance Improvements', commits: new Set() }
|
||||
};
|
||||
|
||||
// 分类收集提交,使用 Set 去重
|
||||
commits.commits.forEach(commit => {
|
||||
const message = commit.commit.message.split('\n')[0].trim();
|
||||
for (const [prefix, group] of Object.entries(groups)) {
|
||||
if (message.startsWith(prefix)) {
|
||||
// 移除前缀后添加到对应分组
|
||||
const cleanMessage = message.slice(prefix.length).trim();
|
||||
group.commits.add(cleanMessage); // 使用 Set.add 自动去重
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 生成更新日志
|
||||
const sections = [];
|
||||
for (const group of Object.values(groups)) {
|
||||
if (group.commits.size > 0) {
|
||||
sections.push(`${group.title}\n\n${Array.from(group.commits).map(msg => `- ${msg}`).join('\n')}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (sections.length > 0) {
|
||||
changelog = '# Changelog\n\n' + sections.join('\n\n');
|
||||
const changelogPath = 'CHANGELOG.md';
|
||||
if (fs.existsSync(changelogPath)) {
|
||||
const content = fs.readFileSync(changelogPath, 'utf-8');
|
||||
const regex = new RegExp(`## \\[${version.replace(/\./g, '\\.')}\\][\\s\\S]*?(?=\\n## \\[|$)`);
|
||||
const match = content.match(regex);
|
||||
if (match) {
|
||||
changelog = match[0].trim();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,8 +71,8 @@ jobs:
|
||||
const { data } = await github.rest.repos.createRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
tag_name: `v${{ needs.check-version.outputs.version }}`,
|
||||
name: `${{ needs.check-version.outputs.version }}`,
|
||||
tag_name: `v${version}`,
|
||||
name: version,
|
||||
body: changelog || 'No significant changes in this release.',
|
||||
draft: true,
|
||||
prerelease: false
|
||||
@@ -215,7 +180,8 @@ jobs:
|
||||
- name: (Android) Upload File
|
||||
if: matrix.build_type == 'android'
|
||||
env:
|
||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
||||
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||
run: |
|
||||
node ./electron/build.js android-upload
|
||||
|
||||
@@ -253,7 +219,8 @@ jobs:
|
||||
APPLEIDPASS: ${{ secrets.APPLEIDPASS }}
|
||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
||||
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
run: |
|
||||
@@ -263,7 +230,8 @@ jobs:
|
||||
- name: (Windows) Build Client
|
||||
if: matrix.build_type == 'windows'
|
||||
env:
|
||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
||||
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
shell: bash
|
||||
@@ -294,11 +262,13 @@ jobs:
|
||||
prerelease: false
|
||||
})
|
||||
|
||||
- name: Publish Official
|
||||
- name: Upload Changelog & Publish to Website
|
||||
env:
|
||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
||||
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||
run: |
|
||||
pushd electron || exit
|
||||
npm install
|
||||
popd || exit
|
||||
node ./electron/build.js published
|
||||
node ./electron/build.js upload-changelog
|
||||
node ./electron/build.js release
|
||||
|
||||
45
.github/workflows/sync-gitee.yml
vendored
Normal file
45
.github/workflows/sync-gitee.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
name: "Sync to Gitee"
|
||||
|
||||
# Required GitHub Secrets:
|
||||
#
|
||||
# GITEE_SSH_PRIVATE_KEY - SSH private key with push access to gitee.com/aipaw/dootask
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Publish"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
name: Push to Gitee
|
||||
if: github.event.workflow_run.conclusion == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup SSH key
|
||||
env:
|
||||
GITEE_SSH_PRIVATE_KEY: ${{ secrets.GITEE_SSH_PRIVATE_KEY }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$GITEE_SSH_PRIVATE_KEY" > ~/.ssh/gitee_key
|
||||
chmod 600 ~/.ssh/gitee_key
|
||||
cat >> ~/.ssh/config << EOF
|
||||
Host gitee.com
|
||||
HostName gitee.com
|
||||
IdentityFile ~/.ssh/gitee_key
|
||||
StrictHostKeyChecking no
|
||||
EOF
|
||||
|
||||
- name: Push to Gitee
|
||||
run: |
|
||||
git remote add gitee git@gitee.com:aipaw/dootask.git
|
||||
git push gitee pro
|
||||
|
||||
- name: Clean up
|
||||
if: always()
|
||||
run: rm -rf ~/.ssh/gitee_key
|
||||
44
CHANGELOG.md
44
CHANGELOG.md
@@ -2,6 +2,50 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [1.7.29]
|
||||
|
||||
### Features
|
||||
|
||||
- AI 助手聊天记录现在可自动保存,换设备或重新打开后也能继续查看历史对话。
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- 改善 AI 助手中长图的显示清晰度,减少图片被压缩后变模糊的问题。
|
||||
- 修复部分企业账号环境下用户搜索失败、密码规则异常的问题。
|
||||
|
||||
## [1.7.23]
|
||||
|
||||
### Features
|
||||
|
||||
- 支持使用非邮箱形式的用户名登录,登录方式更灵活,也更适合接入常见的企业账号环境。
|
||||
- 进一步优化与 Active Directory 的兼容性,企业用户接入和登录更顺畅。
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- 修复部分企业账号环境下的登录问题,提升账号验证的稳定性和成功率。
|
||||
- 修复上传或发布失败时提示不明确的问题,方便更快发现并处理失败情况。
|
||||
|
||||
## [1.7.20]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- 优化了 LDAP 登录方式,更好兼容 Active Directory,企业账号登录更稳定。
|
||||
|
||||
## [1.7.14]
|
||||
|
||||
### Features
|
||||
|
||||
- 新增消息合并转发,支持批量选择后一次转发,分享聊天内容更方便。
|
||||
- 现在可以按项目负责人筛选任务,查找和整理任务更省时。
|
||||
- 支持解除任务关联,调整任务关系更灵活。
|
||||
- 新增 AI 自动分析开关,可按需开启或关闭,使用起来更可控。
|
||||
- 安装和修改设置时会自动检查应用编号与端口是否冲突,减少配置出错和无法启动的情况。
|
||||
- 支持自定义 AI 服务地址,连接和接入方式更灵活。
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- 修复了 AI 助手在部分页面显示异常的问题,查看和使用时更稳定。
|
||||
|
||||
## [1.6.89]
|
||||
|
||||
### Features
|
||||
|
||||
@@ -36,6 +36,11 @@ Laravel 8 (LaravelS/Swoole) + Vue 2 (Vite) + Electron。开源任务/项目管
|
||||
- API 调用使用 `store.dispatch("call", params)`,不要在组件中直接 axios/fetch
|
||||
- `$A.modalXXX`、`$A.messageXXX`、`$A.noticeXXX` 内部自动处理 `$L` 翻译,调用方不要额外包 `$L`。仅当传入 `language: false` 时由调用方自行处理翻译
|
||||
|
||||
### 国际化
|
||||
|
||||
- 新增用户可见文本须追加原文(简体中文)到:前端 `language/original-web.txt`,后端 `language/original-api.txt`(去重)
|
||||
- 前端翻译用 `$L("文本")`,动态值用 `(*)` 占位:`$L('共(*)条', n)`——禁止拼接翻译
|
||||
|
||||
## 交互规范
|
||||
|
||||
- **提问时附带建议**:当需要向用户提问或请求澄清时,应同时提供具体的建议选项或推荐方案,帮助用户快速决策,而非仅抛出开放式问题
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\AiAssistantSession;
|
||||
use App\Models\User;
|
||||
use App\Module\AI;
|
||||
use App\Module\Apps;
|
||||
@@ -155,4 +156,152 @@ class AssistantController extends AbstractController
|
||||
}
|
||||
return $dotProduct / $denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话列表
|
||||
*/
|
||||
public function session__list()
|
||||
{
|
||||
$user = User::auth();
|
||||
$sessionKey = trim(Request::input('session_key', 'default'));
|
||||
|
||||
$sessions = AiAssistantSession::where('userid', $user->userid)
|
||||
->where('session_key', $sessionKey)
|
||||
->orderByDesc('updated_at')
|
||||
->get();
|
||||
|
||||
$list = [];
|
||||
foreach ($sessions as $session) {
|
||||
$data = Base::json2array($session->data);
|
||||
$images = Base::json2array($session->images);
|
||||
foreach ($images as $imageId => $path) {
|
||||
$images[$imageId] = Base::fillUrl($path);
|
||||
}
|
||||
$list[] = [
|
||||
'id' => $session->session_id,
|
||||
'title' => $session->title,
|
||||
'responses' => $data,
|
||||
'images' => $images,
|
||||
'sceneKey' => $session->scene_key,
|
||||
'createdAt' => $session->created_at ? $session->created_at->getTimestampMs() : 0,
|
||||
'updatedAt' => $session->updated_at ? $session->updated_at->getTimestampMs() : 0,
|
||||
];
|
||||
}
|
||||
|
||||
return Base::retSuccess('success', $list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存会话
|
||||
*/
|
||||
public function session__save()
|
||||
{
|
||||
$user = User::auth();
|
||||
$sessionKey = trim(Request::input('session_key', 'default'));
|
||||
$sessionId = trim(Request::input('session_id', ''));
|
||||
$sceneKey = trim(Request::input('scene_key', ''));
|
||||
$title = trim(Request::input('title', ''));
|
||||
$data = Request::input('data', []);
|
||||
$newImages = Request::input('new_images', []);
|
||||
|
||||
if (empty($sessionId)) {
|
||||
return Base::retError('session_id 不能为空');
|
||||
}
|
||||
|
||||
$newImageUrls = [];
|
||||
if (is_array($newImages)) {
|
||||
$path = 'uploads/assistant/' . date('Ym') . '/' . $user->userid . '/';
|
||||
foreach ($newImages as $img) {
|
||||
$imageId = $img['imageId'] ?? '';
|
||||
$dataUrl = $img['dataUrl'] ?? '';
|
||||
if (empty($imageId) || empty($dataUrl)) {
|
||||
continue;
|
||||
}
|
||||
$result = Base::image64save([
|
||||
'image64' => $dataUrl,
|
||||
'path' => $path,
|
||||
'autoThumb' => false,
|
||||
]);
|
||||
if (Base::isSuccess($result)) {
|
||||
$newImageUrls[$imageId] = $result['data']['path'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$session = AiAssistantSession::where('userid', $user->userid)
|
||||
->where('session_key', $sessionKey)
|
||||
->where('session_id', $sessionId)
|
||||
->first();
|
||||
|
||||
$imageMap = $newImageUrls;
|
||||
if ($session) {
|
||||
$existingImages = Base::json2array($session->images);
|
||||
$imageMap = array_merge($existingImages, $newImageUrls);
|
||||
}
|
||||
|
||||
$session = AiAssistantSession::createInstance([
|
||||
'userid' => $user->userid,
|
||||
'session_key' => $sessionKey,
|
||||
'session_id' => $sessionId,
|
||||
'scene_key' => $sceneKey,
|
||||
'title' => mb_substr($title, 0, 255),
|
||||
'data' => Base::array2json(is_array($data) ? $data : []),
|
||||
'images' => Base::array2json($imageMap),
|
||||
], $session?->id);
|
||||
$session->save();
|
||||
|
||||
// 仅返回本次新增的图片URL
|
||||
$urls = [];
|
||||
foreach ($newImageUrls as $imageId => $path) {
|
||||
$urls[$imageId] = Base::fillUrl($path);
|
||||
}
|
||||
|
||||
return Base::retSuccess('success', [
|
||||
'image_urls' => $urls,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除会话
|
||||
*/
|
||||
public function session__delete()
|
||||
{
|
||||
$user = User::auth();
|
||||
$sessionKey = trim(Request::input('session_key', 'default'));
|
||||
$sessionId = trim(Request::input('session_id', ''));
|
||||
$clearAll = Request::input('clear_all', false);
|
||||
|
||||
$query = AiAssistantSession::where('userid', $user->userid)
|
||||
->where('session_key', $sessionKey);
|
||||
|
||||
if ($clearAll) {
|
||||
$sessions = $query->get();
|
||||
foreach ($sessions as $session) {
|
||||
$this->deleteSessionImages($session);
|
||||
}
|
||||
$query->delete();
|
||||
} else {
|
||||
if (empty($sessionId)) {
|
||||
return Base::retError('session_id 不能为空');
|
||||
}
|
||||
$session = $query->where('session_id', $sessionId)->first();
|
||||
if ($session) {
|
||||
$this->deleteSessionImages($session);
|
||||
$session->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return Base::retSuccess('success');
|
||||
}
|
||||
|
||||
private function deleteSessionImages(AiAssistantSession $session)
|
||||
{
|
||||
$images = Base::json2array($session->images);
|
||||
foreach ($images as $path) {
|
||||
$fullPath = public_path($path);
|
||||
if (file_exists($fullPath)) {
|
||||
@unlink($fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2334,6 +2334,9 @@ class DialogController extends AbstractController
|
||||
}
|
||||
WebSocketDialog::checkDialog($msgs->first()->dialog_id);
|
||||
foreach ($msgs as $msg) {
|
||||
if (in_array($msg->type, WebSocketDialogMsg::$unforwardableTypes)) {
|
||||
continue;
|
||||
}
|
||||
$res = $msg->forwardMsg($dialogids, $userids, $user, $show_source, $leave_message);
|
||||
if (Base::isSuccess($res)) {
|
||||
$allMsgs = array_merge($allMsgs, $res['data']['msgs']);
|
||||
@@ -2356,12 +2359,12 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/merge-forward 合并转发消息
|
||||
* @api {get} api/dialog/msg/mergeforward 合并转发消息
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup dialog
|
||||
* @apiName msg__merge_forward
|
||||
* @apiName msg__mergeforward
|
||||
*
|
||||
* @apiParam {Array} msg_ids 消息ID数组(最多100条)
|
||||
* @apiParam {Array} dialogids 转发给的对话ID
|
||||
@@ -2373,7 +2376,7 @@ class DialogController extends AbstractController
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*/
|
||||
public function msg__merge_forward()
|
||||
public function msg__mergeforward()
|
||||
{
|
||||
$user = User::auth();
|
||||
//
|
||||
@@ -2396,6 +2399,57 @@ class DialogController extends AbstractController
|
||||
return WebSocketDialogMsg::mergeForwardMsg($msg_ids, $dialogids, $userids, $user, $show_source, $leave_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/mergedetail 合并转发消息详情
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup dialog
|
||||
* @apiName msg__mergedetail
|
||||
*
|
||||
* @apiParam {Number} msg_id 合并转发消息ID
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*/
|
||||
public function msg__mergedetail()
|
||||
{
|
||||
User::auth();
|
||||
//
|
||||
$msg_id = intval(Request::input('msg_id'));
|
||||
if ($msg_id <= 0) {
|
||||
return Base::retError('参数错误');
|
||||
}
|
||||
$dialogMsg = WebSocketDialogMsg::find($msg_id);
|
||||
if (!$dialogMsg || $dialogMsg->type !== 'merge-forward') {
|
||||
return Base::retError('消息不存在或已被删除');
|
||||
}
|
||||
WebSocketDialog::checkDialog($dialogMsg->dialog_id);
|
||||
//
|
||||
$msgData = Base::json2array($dialogMsg->getRawOriginal('msg'));
|
||||
$msgIds = $msgData['msg_ids'] ?? [];
|
||||
if (empty($msgIds)) {
|
||||
return Base::retError('消息不存在或已被删除');
|
||||
}
|
||||
$msgs = WebSocketDialogMsg::withTrashed()
|
||||
->whereIn('id', $msgIds)
|
||||
->orderBy('created_at')
|
||||
->get()
|
||||
->map(function ($msg) {
|
||||
return [
|
||||
'id' => $msg->id,
|
||||
'userid' => $msg->userid,
|
||||
'type' => $msg->type,
|
||||
'msg' => $msg->msg,
|
||||
'created_at' => $msg->created_at->toDateTimeString(),
|
||||
];
|
||||
});
|
||||
return Base::retSuccess('success', [
|
||||
'msgs' => $msgs,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/emoji emoji回复
|
||||
*
|
||||
|
||||
@@ -612,6 +612,7 @@ class SystemController extends AbstractController
|
||||
'ldap_password',
|
||||
'ldap_user_dn',
|
||||
'ldap_base_dn',
|
||||
'ldap_login_attr',
|
||||
'ldap_sync_local'
|
||||
])) {
|
||||
unset($all[$key]);
|
||||
@@ -625,6 +626,7 @@ class SystemController extends AbstractController
|
||||
//
|
||||
$setting['ldap_open'] = $setting['ldap_open'] ?: 'close';
|
||||
$setting['ldap_port'] = intval($setting['ldap_port']) ?: 389;
|
||||
$setting['ldap_login_attr'] = $setting['ldap_login_attr'] ?: 'cn';
|
||||
$setting['ldap_sync_local'] = $setting['ldap_sync_local'] ?: 'close';
|
||||
//
|
||||
return Base::retSuccess($type == 'save' ? '保存成功' : 'success', $setting ?: json_decode('{}'));
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
namespace App\Ldap;
|
||||
|
||||
use App\Exceptions\ApiException;
|
||||
use App\Models\User;
|
||||
use App\Module\Base;
|
||||
use App\Services\RequestContext;
|
||||
use LdapRecord\Configuration\ConfigurationException;
|
||||
use LdapRecord\Container;
|
||||
use LdapRecord\LdapRecordException;
|
||||
@@ -11,20 +13,18 @@ use LdapRecord\Models\Model;
|
||||
|
||||
class LdapUser extends Model
|
||||
{
|
||||
protected static $init = null;
|
||||
/**
|
||||
* The object classes of the LDAP model.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $objectClasses = [
|
||||
'inetOrgPerson',
|
||||
'organizationalPerson',
|
||||
'person',
|
||||
'top',
|
||||
'posixAccount',
|
||||
];
|
||||
|
||||
private static $emailAttrs = ['mail', 'cn', 'uid', 'userPrincipalName'];
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
@@ -68,19 +68,29 @@ class LdapUser extends Model
|
||||
return Base::settingFind('thirdAccessSetting', 'ldap_sync_local') === 'open';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录属性名
|
||||
* @return string
|
||||
*/
|
||||
public static function getLoginAttr(): string
|
||||
{
|
||||
$attr = Base::settingFind('thirdAccessSetting', 'ldap_login_attr');
|
||||
return in_array($attr, ['cn', 'uid', 'mail', 'sAMAccountName', 'userPrincipalName']) ? $attr : 'cn';
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化配置
|
||||
* @return bool
|
||||
*/
|
||||
public static function initConfig()
|
||||
{
|
||||
if (is_bool(self::$init)) {
|
||||
return self::$init;
|
||||
if (RequestContext::has('ldap_init')) {
|
||||
return RequestContext::get('ldap_init');
|
||||
}
|
||||
//
|
||||
$setting = Base::setting('thirdAccessSetting');
|
||||
if ($setting['ldap_open'] !== 'open') {
|
||||
return self::$init = false;
|
||||
return RequestContext::save('ldap_init', false);
|
||||
}
|
||||
//
|
||||
$connection = Container::getDefaultConnection();
|
||||
@@ -92,15 +102,15 @@ class LdapUser extends Model
|
||||
"username" => $setting['ldap_user_dn'],
|
||||
"password" => $setting['ldap_password'],
|
||||
]);
|
||||
return self::$init = true;
|
||||
return RequestContext::save('ldap_init', true);
|
||||
} catch (ConfigurationException $e) {
|
||||
info($e->getMessage());
|
||||
return self::$init = false;
|
||||
return RequestContext::save('ldap_init', false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* 通过管理员绑定搜索用户,然后用用户 DN 做 Bind 认证
|
||||
* @param $username
|
||||
* @param $password
|
||||
* @return Model|null
|
||||
@@ -111,16 +121,68 @@ class LdapUser extends Model
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return self::static()
|
||||
->where([
|
||||
'cn' => $username,
|
||||
'userPassword' => $password
|
||||
])->first();
|
||||
$loginAttr = self::getLoginAttr();
|
||||
$row = self::static()
|
||||
->whereRaw($loginAttr, '=', $username)
|
||||
->first();
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
$connection = Container::getDefaultConnection();
|
||||
if (!$connection->auth()->attempt($row->getDn(), $password)) {
|
||||
return null;
|
||||
}
|
||||
// Swoole 下连接共享,必须恢复管理员绑定
|
||||
$connection->auth()->attempt(
|
||||
$connection->getConfiguration()->get('username'),
|
||||
$connection->getConfiguration()->get('password')
|
||||
);
|
||||
return $row;
|
||||
} catch (\Exception $e) {
|
||||
info("[LDAP] auth fail: " . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过邮箱查找 LDAP 用户
|
||||
* @param $email
|
||||
* @return Model|null
|
||||
*/
|
||||
public static function findByEmail($email): ?Model
|
||||
{
|
||||
if (!self::initConfig()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
foreach (self::$emailAttrs as $attr) {
|
||||
$row = self::static()->whereRaw($attr, '=', $email)->first();
|
||||
if ($row) {
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (\Exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的邮箱(从 LDAP 记录中提取)
|
||||
* @param Model $row
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getUserEmail(Model $row): ?string
|
||||
{
|
||||
foreach (self::$emailAttrs as $attr) {
|
||||
$val = $row->getFirstAttribute($attr);
|
||||
if ($val && Base::isEmail($val)) {
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @param $username
|
||||
@@ -138,7 +200,18 @@ class LdapUser extends Model
|
||||
return null;
|
||||
}
|
||||
if (empty($user)) {
|
||||
$user = User::reg($username, $password);
|
||||
$email = self::getUserEmail($row);
|
||||
if (empty($email)) {
|
||||
throw new ApiException('LDAP 用户缺少邮箱属性,请联系管理员配置');
|
||||
}
|
||||
$user = User::whereEmail($email)->first();
|
||||
if (empty($user)) {
|
||||
// LDAP 用户通过 LDAP 认证,本地密码用随机值以满足密码策略
|
||||
$localPassword = Base::generatePassword(16) . 'Aa1!';
|
||||
$user = User::reg($email, $localPassword);
|
||||
} elseif (!$user->isLdap()) {
|
||||
info("[LDAP] merged with existing local account: userid={$user->userid}, email={$email}");
|
||||
}
|
||||
}
|
||||
if ($user) {
|
||||
$userimg = $row->getPhoto();
|
||||
@@ -173,7 +246,7 @@ class LdapUser extends Model
|
||||
}
|
||||
//
|
||||
if (self::isSyncLocal()) {
|
||||
$row = self::userFirst($user->email, $password);
|
||||
$row = self::findByEmail($user->email);
|
||||
if ($row) {
|
||||
return;
|
||||
}
|
||||
@@ -184,17 +257,18 @@ class LdapUser extends Model
|
||||
} else {
|
||||
$userimg = '';
|
||||
}
|
||||
self::static()->create([
|
||||
$attrs = [
|
||||
'cn' => $user->email,
|
||||
'gidNumber' => 0,
|
||||
'homeDirectory' => '/home/ldap/dootask/' . env("APP_NAME"),
|
||||
'sn' => $user->email,
|
||||
'uid' => $user->email,
|
||||
'uidNumber' => $user->userid,
|
||||
'userPassword' => $password,
|
||||
'displayName' => $user->nickname,
|
||||
'jpegPhoto' => $userimg,
|
||||
]);
|
||||
'mail' => $user->email,
|
||||
];
|
||||
if ($userimg) {
|
||||
$attrs['jpegPhoto'] = $userimg;
|
||||
}
|
||||
self::static()->create($attrs);
|
||||
$user->identity = Base::arrayImplode(array_merge(array_diff($user->identity, ['ldap']), ['ldap']));
|
||||
$user->save();
|
||||
} catch (LdapRecordException $e) {
|
||||
@@ -205,11 +279,11 @@ class LdapUser extends Model
|
||||
|
||||
/**
|
||||
* 更新
|
||||
* @param $username
|
||||
* @param $email
|
||||
* @param $array
|
||||
* @return void
|
||||
*/
|
||||
public static function userUpdate($username, $array)
|
||||
public static function userUpdate($email, $array)
|
||||
{
|
||||
if (empty($array)) {
|
||||
return;
|
||||
@@ -218,10 +292,7 @@ class LdapUser extends Model
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$row = self::static()
|
||||
->where([
|
||||
'cn' => $username,
|
||||
])->first();
|
||||
$row = self::findByEmail($email);
|
||||
$row?->update($array);
|
||||
} catch (\Exception $e) {
|
||||
info("[LDAP] update fail: " . $e->getMessage());
|
||||
@@ -230,19 +301,16 @@ class LdapUser extends Model
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param $username
|
||||
* @param $email
|
||||
* @return void
|
||||
*/
|
||||
public static function userDelete($username)
|
||||
public static function userDelete($email)
|
||||
{
|
||||
if (!self::initConfig()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$row = self::static()
|
||||
->where([
|
||||
'cn' => $username,
|
||||
])->first();
|
||||
$row = self::findByEmail($email);
|
||||
$row?->delete();
|
||||
} catch (\Exception $e) {
|
||||
info("[LDAP] delete fail: " . $e->getMessage());
|
||||
|
||||
22
app/Models/AiAssistantSession.php
Normal file
22
app/Models/AiAssistantSession.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* AI 助手会话
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $userid
|
||||
* @property string $session_key
|
||||
* @property string $session_id
|
||||
* @property string $scene_key
|
||||
* @property string $title
|
||||
* @property string|null $data
|
||||
* @property string|null $images
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
*/
|
||||
class AiAssistantSession extends AbstractModel
|
||||
{
|
||||
protected $table = 'ai_assistant_sessions';
|
||||
}
|
||||
@@ -199,7 +199,6 @@ class Setting extends AbstractModel
|
||||
$key = trim((string)($setting[$vendor . '_key'] ?? ''));
|
||||
return match ($vendor) {
|
||||
'ollama' => $key !== '' || !empty($setting['ollama_base_url']),
|
||||
'wenxin' => $key !== '' && !empty($setting['wenxin_secret']),
|
||||
default => $key !== '',
|
||||
};
|
||||
}
|
||||
@@ -501,7 +500,7 @@ class Setting extends AbstractModel
|
||||
}
|
||||
$limitTime = Carbon::parse($dialogMsg->created_at)->addMinutes($limitNum);
|
||||
if ($limitTime->lt(Carbon::now())) {
|
||||
throw new ApiException('已超过' . Doo::translate(Base::forumMinuteDay($limitNum)) . ',' . $error);
|
||||
throw new ApiException('已超过' . Base::forumMinuteDay($limitNum) . ',' . $error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,9 +533,17 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
return $dialogs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 不支持转发的消息类型
|
||||
*/
|
||||
public static $unforwardableTypes = ['tag', 'top', 'todo', 'notice', 'word-chain', 'vote', 'template'];
|
||||
|
||||
public function forwardMsg($dialogids, $userids, $user, $showSource = 1, $leaveMessage = '')
|
||||
{
|
||||
return AbstractModel::transaction(function () use ($dialogids, $user, $userids, $showSource, $leaveMessage) {
|
||||
if (in_array($this->type, self::$unforwardableTypes)) {
|
||||
throw new ApiException('此类型消息不支持转发');
|
||||
}
|
||||
$msgData = Base::json2array($this->getRawOriginal('msg'));
|
||||
$forwardData = is_array($msgData['forward_data']) ? $msgData['forward_data'] : [];
|
||||
$forwardId = $forwardData['id'] ?: $this->id;
|
||||
@@ -601,31 +609,35 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
throw new ApiException('只能合并转发同一对话的消息');
|
||||
}
|
||||
WebSocketDialog::checkDialog($dialogId);
|
||||
// 收集发送者生成标题
|
||||
// 过滤不支持转发的消息类型
|
||||
$msgs = $msgs->filter(function ($msg) {
|
||||
return !in_array($msg->type, self::$unforwardableTypes);
|
||||
});
|
||||
if ($msgs->isEmpty()) {
|
||||
throw new ApiException('所选消息均不支持转发');
|
||||
}
|
||||
// 收集发送者信息
|
||||
$senderIds = $msgs->pluck('userid')->unique()->values()->toArray();
|
||||
$senderNames = User::whereIn('userid', array_slice($senderIds, 0, 2))
|
||||
->pluck('nickname')
|
||||
->toArray();
|
||||
$title = implode(Doo::translate('和'), $senderNames);
|
||||
if (count($senderIds) > 2) {
|
||||
$title .= Doo::translate('等人');
|
||||
}
|
||||
$title .= Doo::translate('的聊天记录');
|
||||
// 组装消息列表
|
||||
$list = [];
|
||||
foreach ($msgs as $msg) {
|
||||
$list[] = [
|
||||
// 组装预览列表(前4条,精简字段)
|
||||
$msgIds = $msgs->pluck('id')->toArray();
|
||||
$preview = [];
|
||||
foreach ($msgs->take(4) as $msg) {
|
||||
$preview[] = [
|
||||
'userid' => $msg->userid,
|
||||
'type' => $msg->type,
|
||||
'msg' => Base::json2array($msg->getRawOriginal('msg')),
|
||||
'created_at' => $msg->created_at->toDateTimeString(),
|
||||
'msg' => self::buildPreviewMsg($msg->type, Base::json2array($msg->getRawOriginal('msg'))),
|
||||
];
|
||||
}
|
||||
// 构建合并转发消息体
|
||||
$msgData = [
|
||||
'title' => $title,
|
||||
'list' => $list,
|
||||
'count' => count($list),
|
||||
'sender_names' => $senderNames,
|
||||
'sender_total' => count($senderIds),
|
||||
'msg_ids' => $msgIds,
|
||||
'preview' => $preview,
|
||||
'count' => count($msgIds),
|
||||
'forward_data' => [
|
||||
'show' => $showSource,
|
||||
'leave' => $leaveMessage ? 1 : 0,
|
||||
@@ -652,6 +664,26 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建预览消息(精简字段)
|
||||
* @param string $type
|
||||
* @param array $msg
|
||||
* @return array
|
||||
*/
|
||||
private static function buildPreviewMsg($type, $msg)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'text':
|
||||
return ['text' => $msg['text'] ?? ''];
|
||||
case 'file':
|
||||
return ['name' => $msg['name'] ?? '', 'ext' => $msg['ext'] ?? ''];
|
||||
case 'location':
|
||||
return ['title' => $msg['title'] ?? ''];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除消息
|
||||
* @param array|int $ids
|
||||
@@ -784,8 +816,7 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
return self::previewTemplateMsg($data['msg']);
|
||||
|
||||
case 'merge-forward':
|
||||
$action = Doo::translate("聊天记录");
|
||||
return "[{$action}] " . Base::cutStr($data['msg']['title'] ?? '', 50);
|
||||
return "[" . Doo::translate("聊天记录") . "]";
|
||||
|
||||
case 'preview':
|
||||
return $data['msg']['preview'];
|
||||
|
||||
@@ -204,12 +204,6 @@ class AI
|
||||
}
|
||||
|
||||
$apiKey = Base::val($setting, $modelType . '_key');
|
||||
if ($modelType === 'wenxin') {
|
||||
$wenxinSecret = Base::val($setting, 'wenxin_secret');
|
||||
if ($wenxinSecret) {
|
||||
$apiKey = trim(($apiKey ?: '') . ':' . $wenxinSecret);
|
||||
}
|
||||
}
|
||||
if ($modelType === 'ollama' && empty($apiKey)) {
|
||||
$apiKey = Base::strRandom(6);
|
||||
}
|
||||
@@ -768,14 +762,6 @@ class AI
|
||||
}
|
||||
$model = trim((string)($setting[$vendor . '_model'] ?? ''));
|
||||
break;
|
||||
case 'wenxin':
|
||||
$secret = trim((string)($setting['wenxin_secret'] ?? ''));
|
||||
if ($key === '' || $secret === '' || $baseUrl === '') {
|
||||
return null;
|
||||
}
|
||||
$key = $key . ':' . $secret;
|
||||
$model = trim((string)($setting[$vendor . '_model'] ?? ''));
|
||||
break;
|
||||
default:
|
||||
if ($key === '' || $baseUrl === '') {
|
||||
return null;
|
||||
|
||||
@@ -490,10 +490,6 @@ class BotReceiveMsgTask extends AbstractTask
|
||||
if ($dialog->session_id) {
|
||||
$extras['context_key'] = 'session_' . $dialog->session_id;
|
||||
}
|
||||
// 设置文心一言的API密钥
|
||||
if ($type === 'wenxin') {
|
||||
$extras['api_key'] .= ':' . $setting['wenxin_secret'];
|
||||
}
|
||||
// 群聊清理上下文(群聊不使用上下文)
|
||||
if ($dialog->type === 'group') {
|
||||
$extras['before_clear'] = 1;
|
||||
|
||||
2
bin/version.js
vendored
2
bin/version.js
vendored
@@ -229,7 +229,7 @@ async function enhanceWithAI(version, changelogSection) {
|
||||
return changelogSection;
|
||||
}
|
||||
const proxyUrl = (process.env.OPENAI_PROXY_URL || "").trim();
|
||||
const explicitApiUrl = process.env.CHANGELOG_AI_URL || process.env.OPENAI_API_URL;
|
||||
const explicitApiUrl = process.env.CHANGELOG_AI_URL || process.env.OPENAI_API_URL || process.env.OPENAI_BASE_URL;
|
||||
const apiUrl = resolveApiEndpoint(explicitApiUrl);
|
||||
const dispatcher = createProxyDispatcher(proxyUrl);
|
||||
const model = process.env.CHANGELOG_AI_MODEL || process.env.OPENAI_API_MODEL || "gpt-4o-mini";
|
||||
|
||||
39
cmd
39
cmd
@@ -391,6 +391,7 @@ env_set() {
|
||||
local val=$2
|
||||
local exist=`cat ${WORK_DIR}/.env | grep "^$key="`
|
||||
if [ -z "$exist" ]; then
|
||||
echo "" >> $WORK_DIR/.env
|
||||
echo "$key=$val" >> $WORK_DIR/.env
|
||||
else
|
||||
if [[ `uname` == 'Linux' ]]; then
|
||||
@@ -501,10 +502,36 @@ DooTask 管理脚本
|
||||
EOF
|
||||
}
|
||||
|
||||
# 检测APP_ID是否与其他实例冲突
|
||||
check_instance() {
|
||||
local app_id=$(env_get APP_ID)
|
||||
local container_name="dootask-php-${app_id}"
|
||||
local mount_path=$(docker inspect "$container_name" --format '{{range .Mounts}}{{if eq .Destination "/var/www"}}{{.Source}}{{end}}{{end}}' 2>/dev/null)
|
||||
if [[ -n "$mount_path" ]] && [[ "$mount_path" != "$WORK_DIR" ]]; then
|
||||
error "APP_ID(${app_id})已被其他实例使用:${mount_path}"
|
||||
error "请先清空 .env 中的 APP_ID 和 APP_IPPR 再重新安装"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测端口是否被占用
|
||||
# 参数1: 端口号, 参数2: 当前端口号(可选,相同则跳过检测)
|
||||
check_port() {
|
||||
local port=$1
|
||||
local current_port=$2
|
||||
if [[ "$port" -gt 0 ]] && [[ "$port" != "$current_port" ]]; then
|
||||
if ! docker run --rm -p "${port}:80" --entrypoint true nginx:alpine 2>/dev/null; then
|
||||
error "端口 ${port} 已被占用,请指定其他端口"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 安装函数
|
||||
handle_install() {
|
||||
check_sudo
|
||||
|
||||
check_instance
|
||||
|
||||
local relock=$(arg_get relock)
|
||||
local port=$(arg_get port)
|
||||
|
||||
@@ -561,8 +588,17 @@ handle_install() {
|
||||
done
|
||||
|
||||
# 设置端口
|
||||
local old_port=$(env_get APP_PORT)
|
||||
[[ "$port" -gt 0 ]] && env_set APP_PORT "$port"
|
||||
|
||||
# 检测端口占用(首次安装或端口变更时)
|
||||
local new_port=$(env_get APP_PORT)
|
||||
if [ -z "$(docker_name nginx)" ] || [[ "$new_port" != "$old_port" ]]; then
|
||||
check_port "$new_port"
|
||||
local ssl_port=$(env_get APP_SSL_PORT)
|
||||
check_port "$ssl_port"
|
||||
fi
|
||||
|
||||
# 启动PHP容器
|
||||
$COMPOSE up php -d
|
||||
|
||||
@@ -763,6 +799,7 @@ case "$1" in
|
||||
;;
|
||||
"port")
|
||||
shift 1
|
||||
check_port "$1" "$(env_get APP_PORT)"
|
||||
env_set APP_PORT "$1"
|
||||
$COMPOSE up -d
|
||||
success "修改成功"
|
||||
|
||||
@@ -13,6 +13,9 @@ class CreateManticoreSyncFailuresTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
if (Schema::hasTable('manticore_sync_failures')) {
|
||||
return;
|
||||
}
|
||||
Schema::create('manticore_sync_failures', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('data_type', 20)->comment('数据类型: msg/file/task/project/user');
|
||||
|
||||
@@ -8,6 +8,9 @@ class CreateProjectTaskAiEventsTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if (Schema::hasTable('project_task_ai_events')) {
|
||||
return;
|
||||
}
|
||||
Schema::create('project_task_ai_events', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->bigInteger('task_id')->comment('任务ID');
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateAiAssistantSessionsTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if (Schema::hasTable('ai_assistant_sessions')) {
|
||||
return;
|
||||
}
|
||||
Schema::create('ai_assistant_sessions', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->bigInteger('userid')->default(0)->comment('用户ID');
|
||||
$table->string('session_key', 100)->default('')->comment('场景分类key');
|
||||
$table->string('session_id', 100)->default('')->comment('前端生成的会话ID');
|
||||
$table->string('scene_key', 200)->default('')->comment('具体场景标识');
|
||||
$table->string('title', 255)->default('')->comment('会话标题');
|
||||
$table->longText('data')->nullable()->comment('responses JSON');
|
||||
$table->longText('images')->nullable()->comment('图片映射 {imageId: relativePath}');
|
||||
$table->timestamps();
|
||||
$table->index('userid', 'idx_userid');
|
||||
$table->unique(['userid', 'session_key', 'session_id'], 'uk_user_session');
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('ai_assistant_sessions');
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,7 @@ services:
|
||||
appstore:
|
||||
container_name: "dootask-appstore-${APP_ID}"
|
||||
privileged: true
|
||||
image: "dootask/appstore:0.3.9"
|
||||
image: "dootask/appstore:0.4.0"
|
||||
volumes:
|
||||
- shared_data:/usr/share/dootask
|
||||
- ${HOST_DOCKER_SOCK:-/var/run/docker.sock}:/var/run/docker.sock
|
||||
|
||||
397
electron/build.js
vendored
397
electron/build.js
vendored
@@ -12,7 +12,7 @@ const utils = require('./lib/utils');
|
||||
const config = require('../package.json')
|
||||
const env = require('dotenv').config({ path: './.env' })
|
||||
const argv = process.argv;
|
||||
const {BUILD_FRONTEND, APPLEID, APPLEIDPASS, GITHUB_TOKEN, GITHUB_REPOSITORY, PUBLISH_KEY} = process.env;
|
||||
const {BUILD_FRONTEND, APPLEID, APPLEIDPASS, GITHUB_TOKEN, GITHUB_REPOSITORY, UPLOAD_TOKEN, UPLOAD_URL} = process.env;
|
||||
|
||||
const electronDir = path.resolve(__dirname, "public");
|
||||
const nativeCachePath = path.resolve(__dirname, ".native");
|
||||
@@ -320,7 +320,7 @@ function axiosAutoTry(data) {
|
||||
if (typeof data.retryNumber == 'number' && data.retryNumber > 0) {
|
||||
data.retryNumber--;
|
||||
if (typeof data.onRetry === "function") {
|
||||
data.onRetry()
|
||||
data.onRetry(error)
|
||||
}
|
||||
if (error.code == 'ECONNABORTED' || error.code == 'ECONNRESET') {
|
||||
// 中止,超时
|
||||
@@ -350,192 +350,151 @@ function axiosAutoTry(data) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传app应用
|
||||
* @param url
|
||||
* 官网发布器
|
||||
*/
|
||||
function androidUpload(url) {
|
||||
if (!PUBLISH_KEY) {
|
||||
console.error("缺少 PUBLISH_KEY 环境变量");
|
||||
process.exit()
|
||||
class WebsitePublisher {
|
||||
constructor({baseUrl, token, version}) {
|
||||
this.baseUrl = baseUrl
|
||||
this.token = token
|
||||
this.version = version
|
||||
}
|
||||
const releaseDir = path.resolve(__dirname, "../resources/mobile/platforms/android/eeuiApp/app/build/outputs/apk/release");
|
||||
if (!fs.existsSync(releaseDir)) {
|
||||
console.error("发布文件未找到");
|
||||
process.exit()
|
||||
}
|
||||
fs.readdir(releaseDir, async (err, files) => {
|
||||
if (err) {
|
||||
console.warn(err)
|
||||
} else {
|
||||
const uploadOras = {}
|
||||
for (const filename of files) {
|
||||
const localFile = path.join(releaseDir, filename)
|
||||
if (/\.apk$/.test(filename) && fs.existsSync(localFile)) {
|
||||
const fileStat = fs.statSync(localFile)
|
||||
if (fileStat.isFile()) {
|
||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
||||
const formData = new FormData()
|
||||
formData.append("file", fs.createReadStream(localFile));
|
||||
formData.append("action", "draft");
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: url,
|
||||
data: formData,
|
||||
headers: {
|
||||
'Publish-Version': config.version,
|
||||
'Publish-Key': PUBLISH_KEY,
|
||||
'Content-Type': 'multipart/form-data;boundary=' + formData.getBoundary(),
|
||||
},
|
||||
onUploadProgress: progress => {
|
||||
const complete = Math.min(99, Math.round(progress.loaded / progress.total * 100 | 0)) + '%'
|
||||
uploadOras[filename].text = `Upload [${complete}] ${filename}`
|
||||
},
|
||||
},
|
||||
onRetry: _ => {
|
||||
uploadOras[filename].warn(`Upload [retry] ${filename}`)
|
||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
||||
},
|
||||
retryNumber: 3
|
||||
}).then(({status, data}) => {
|
||||
if (status !== 200) {
|
||||
uploadOras[filename].fail(`Upload [fail:${status}] ${filename}`)
|
||||
return
|
||||
}
|
||||
if (!utils.isJson(data)) {
|
||||
uploadOras[filename].fail(`Upload [fail:not json] ${filename}`)
|
||||
return
|
||||
}
|
||||
if (data.ret !== 1) {
|
||||
uploadOras[filename].fail(`Upload [fail:ret ${data.ret}] ${filename}`)
|
||||
return
|
||||
}
|
||||
uploadOras[filename].succeed(`Upload [100%] ${filename}`)
|
||||
}).catch(_ => {
|
||||
uploadOras[filename].fail(`Upload [fail] ${filename}`)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传单个文件
|
||||
* @param localFile 本地文件路径
|
||||
* @param options { platform, arch } 可选,有则为安装包
|
||||
*/
|
||||
async uploadPackage(localFile, options = {}) {
|
||||
const filename = path.basename(localFile)
|
||||
let spinner = ora(`Upload [0%] ${filename}`).start()
|
||||
const formData = new FormData()
|
||||
formData.append("version", this.version)
|
||||
if (options.platform) {
|
||||
formData.append("platform", options.platform)
|
||||
if (options.arch) {
|
||||
formData.append("arch", options.arch)
|
||||
}
|
||||
}
|
||||
});
|
||||
formData.append("file", fs.createReadStream(localFile))
|
||||
const {status, data} = await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: `${this.baseUrl}/api/upload/package`,
|
||||
data: formData,
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
'Content-Type': 'multipart/form-data;boundary=' + formData.getBoundary(),
|
||||
},
|
||||
onUploadProgress: progress => {
|
||||
const complete = Math.min(99, Math.round(progress.loaded / progress.total * 100 | 0)) + '%'
|
||||
spinner.text = `Upload [${complete}] ${filename}`
|
||||
},
|
||||
},
|
||||
onRetry: (err) => {
|
||||
const reason = err?.response?.status || err?.code || err?.message || ''
|
||||
spinner.warn(`Upload [retry] ${filename}${reason ? ': ' + reason : ''}`)
|
||||
spinner = ora(`Upload [0%] ${filename}`).start()
|
||||
},
|
||||
retryNumber: 3
|
||||
})
|
||||
if (status !== 200 || !utils.isJson(data) || !data.success) {
|
||||
const reason = data?.message || `status ${status}`
|
||||
spinner.fail(`Upload [fail] ${filename}: ${reason}`)
|
||||
throw new Error(`Upload failed: ${filename}: ${reason}`)
|
||||
}
|
||||
spinner.succeed(`Upload [100%] ${filename}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传 changelog
|
||||
*/
|
||||
async uploadChangelog(content) {
|
||||
const spinner = ora('Uploading changelog...').start()
|
||||
const {status, data} = await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: `${this.baseUrl}/api/upload/changelog`,
|
||||
data: { content },
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
retryNumber: 3
|
||||
})
|
||||
if (status !== 200 || !data.success) {
|
||||
spinner.fail('Changelog upload failed')
|
||||
throw new Error('Changelog upload failed')
|
||||
}
|
||||
spinner.succeed('Changelog uploaded')
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知发布完成
|
||||
*/
|
||||
async release() {
|
||||
const spinner = ora('Publishing release...').start()
|
||||
const {status, data} = await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: `${this.baseUrl}/api/upload/release`,
|
||||
data: { version: this.version },
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
retryNumber: 3
|
||||
})
|
||||
if (status !== 200 || !data.success) {
|
||||
spinner.fail(`Release failed: ${data?.message || status}`)
|
||||
throw new Error(`Release failed: ${data?.message || status}`)
|
||||
}
|
||||
spinner.succeed('Release published')
|
||||
}
|
||||
}
|
||||
|
||||
// 安装包扩展名
|
||||
const INSTALLER_EXTS = ['.dmg', '.exe', '.msi', '.appimage', '.deb', '.rpm', '.apk']
|
||||
|
||||
/**
|
||||
* 通知发布完成
|
||||
* @param url
|
||||
* 创建 WebsitePublisher 实例(如果环境变量齐全)
|
||||
*/
|
||||
async function published(url) {
|
||||
if (!PUBLISH_KEY) {
|
||||
console.error("缺少 PUBLISH_KEY 环境变量");
|
||||
process.exit()
|
||||
function createPublisher() {
|
||||
if (!UPLOAD_TOKEN || !UPLOAD_URL) {
|
||||
return null
|
||||
}
|
||||
const spinner = ora('完成发布...').start();
|
||||
const formData = new FormData()
|
||||
formData.append("action", "release");
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: url,
|
||||
data: formData,
|
||||
headers: {
|
||||
'Publish-Version': config.version,
|
||||
'Publish-Key': PUBLISH_KEY,
|
||||
},
|
||||
},
|
||||
retryNumber: 3
|
||||
}).then(({status, data}) => {
|
||||
if (status !== 200) {
|
||||
spinner.fail('发布失败, status: ' + status)
|
||||
return
|
||||
}
|
||||
if (!utils.isJson(data)) {
|
||||
spinner.fail('发布失败, not json')
|
||||
return
|
||||
}
|
||||
if (data.ret !== 1) {
|
||||
spinner.fail(`发布失败, ${JSON.stringify(data)}`)
|
||||
return
|
||||
}
|
||||
spinner.succeed('发布完成')
|
||||
}).catch(_ => {
|
||||
spinner.fail('发布失败')
|
||||
return new WebsitePublisher({
|
||||
baseUrl: UPLOAD_URL.replace(/\/+$/, ''),
|
||||
token: UPLOAD_TOKEN,
|
||||
version: config.version
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用发布
|
||||
* @param url
|
||||
* @param key
|
||||
* @param version
|
||||
* @param output
|
||||
* 从文件名判断是否为安装包
|
||||
*/
|
||||
function genericPublish({url, key, version, output}) {
|
||||
if (!/https?:\/\//i.test(url)) {
|
||||
console.warn("发布地址无效: " + url)
|
||||
return
|
||||
}
|
||||
const filePath = path.resolve(__dirname, output)
|
||||
if (!fs.existsSync(filePath)) {
|
||||
console.warn("发布文件未找到: " + filePath)
|
||||
return
|
||||
}
|
||||
fs.readdir(filePath, async (err, files) => {
|
||||
if (err) {
|
||||
console.warn(err)
|
||||
} else {
|
||||
const uploadOras = {}
|
||||
for (const filename of files) {
|
||||
const localFile = path.join(filePath, filename)
|
||||
if (fs.existsSync(localFile)) {
|
||||
const fileStat = fs.statSync(localFile)
|
||||
if (fileStat.isFile()) {
|
||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
||||
const formData = new FormData()
|
||||
formData.append("file", fs.createReadStream(localFile));
|
||||
formData.append("action", "draft");
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: url,
|
||||
data: formData,
|
||||
headers: {
|
||||
'Publish-Version': version,
|
||||
'Publish-Key': key,
|
||||
'Content-Type': 'multipart/form-data;boundary=' + formData.getBoundary(),
|
||||
},
|
||||
onUploadProgress: progress => {
|
||||
const complete = Math.min(99, Math.round(progress.loaded / progress.total * 100 | 0)) + '%'
|
||||
uploadOras[filename].text = `Upload [${complete}] ${filename}`
|
||||
},
|
||||
},
|
||||
onRetry: _ => {
|
||||
uploadOras[filename].warn(`Upload [retry] ${filename}`)
|
||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
||||
},
|
||||
retryNumber: 3
|
||||
}).then(({status, data}) => {
|
||||
if (status !== 200) {
|
||||
uploadOras[filename].fail(`Upload [fail:${status}] ${filename}`)
|
||||
return
|
||||
}
|
||||
if (!utils.isJson(data)) {
|
||||
uploadOras[filename].fail(`Upload [fail:not json] ${filename}`)
|
||||
return
|
||||
}
|
||||
if (data.ret !== 1) {
|
||||
uploadOras[filename].fail(`Upload [fail:ret ${data.ret}] ${filename}`)
|
||||
return
|
||||
}
|
||||
uploadOras[filename].succeed(`Upload [100%] ${filename}`)
|
||||
}).catch(_ => {
|
||||
uploadOras[filename].fail(`Upload [fail] ${filename}`)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
function isInstaller(filename) {
|
||||
return INSTALLER_EXTS.some(ext => filename.toLowerCase().endsWith(ext))
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件名提取 arch
|
||||
*/
|
||||
function parseArchFromFilename(filename) {
|
||||
if (/-arm64[.-]/i.test(filename)) return 'arm64'
|
||||
if (/-x64[.-]/i.test(filename)) return 'x64'
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 将构建平台名映射为 API platform
|
||||
*/
|
||||
function mapPlatform(buildPlatform) {
|
||||
if (buildPlatform.includes('mac')) return 'mac'
|
||||
if (buildPlatform.includes('win')) return 'win'
|
||||
if (buildPlatform.includes('linux')) return 'linux'
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -703,13 +662,27 @@ async function startBuild(data) {
|
||||
appConfig.build.directories.output = `${output}-generic`;
|
||||
fs.writeFileSync(packageFile, JSON.stringify(appConfig, null, 4), 'utf8');
|
||||
child_process.execSync(`npm run ${platform}`, {stdio: "inherit", cwd: "electron"});
|
||||
if (publish === true && PUBLISH_KEY) {
|
||||
genericPublish({
|
||||
url: appConfig.build.publish.url,
|
||||
key: PUBLISH_KEY,
|
||||
version: config.version,
|
||||
output: appConfig.build.directories.output
|
||||
})
|
||||
if (publish === true) {
|
||||
const publisher = createPublisher()
|
||||
if (publisher) {
|
||||
const outputDir = path.resolve(__dirname, appConfig.build.directories.output)
|
||||
if (fs.existsSync(outputDir)) {
|
||||
const apiPlatform = mapPlatform(platform)
|
||||
const files = fs.readdirSync(outputDir)
|
||||
for (const filename of files) {
|
||||
const localFile = path.join(outputDir, filename)
|
||||
const fileStat = fs.statSync(localFile)
|
||||
if (!fileStat.isFile()) continue
|
||||
|
||||
if (isInstaller(filename) && apiPlatform) {
|
||||
const arch = parseArchFromFilename(filename)
|
||||
await publisher.uploadPackage(localFile, { platform: apiPlatform, arch })
|
||||
} else {
|
||||
await publisher.uploadPackage(localFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// package.json Recovery
|
||||
recoveryPackage(true)
|
||||
@@ -746,17 +719,59 @@ if (["dev"].includes(argv[2])) {
|
||||
})
|
||||
} else if (["android-upload"].includes(argv[2])) {
|
||||
// 上传安卓文件(GitHub Actions)
|
||||
config.app.forEach(({publish}) => {
|
||||
if (publish.provider === 'generic') {
|
||||
androidUpload(publish.url)
|
||||
(async () => {
|
||||
const publisher = createPublisher()
|
||||
if (!publisher) {
|
||||
console.error("缺少 UPLOAD_TOKEN 或 UPLOAD_URL 环境变量")
|
||||
process.exit(1)
|
||||
}
|
||||
const releaseDir = path.resolve(__dirname, "../resources/mobile/platforms/android/eeuiApp/app/build/outputs/apk/release");
|
||||
if (!fs.existsSync(releaseDir)) {
|
||||
console.error("发布文件未找到")
|
||||
process.exit(1)
|
||||
}
|
||||
const files = fs.readdirSync(releaseDir)
|
||||
for (const filename of files) {
|
||||
const localFile = path.join(releaseDir, filename)
|
||||
if (/\.apk$/.test(filename) && fs.existsSync(localFile) && fs.statSync(localFile).isFile()) {
|
||||
await publisher.uploadPackage(localFile, { platform: 'android' })
|
||||
}
|
||||
}
|
||||
})().catch(err => {
|
||||
console.error(err.message || err)
|
||||
process.exit(1)
|
||||
})
|
||||
} else if (["published"].includes(argv[2])) {
|
||||
// 发布完成(GitHub Actions)
|
||||
config.app.forEach(async ({publish}) => {
|
||||
if (publish.provider === 'generic') {
|
||||
await published(publish.url)
|
||||
} else if (["release"].includes(argv[2])) {
|
||||
// 通知官网发布完成(GitHub Actions)
|
||||
(async () => {
|
||||
const publisher = createPublisher()
|
||||
if (!publisher) {
|
||||
console.error("缺少 UPLOAD_TOKEN 或 UPLOAD_URL 环境变量")
|
||||
process.exit(1)
|
||||
}
|
||||
await publisher.release()
|
||||
})().catch(err => {
|
||||
console.error(err.message || err)
|
||||
process.exit(1)
|
||||
})
|
||||
} else if (["upload-changelog"].includes(argv[2])) {
|
||||
// 上传 changelog(GitHub Actions)
|
||||
(async () => {
|
||||
const publisher = createPublisher()
|
||||
if (!publisher) {
|
||||
console.error("缺少 UPLOAD_TOKEN 或 UPLOAD_URL 环境变量")
|
||||
process.exit(1)
|
||||
}
|
||||
const changelogPath = path.resolve(__dirname, "../CHANGELOG.md")
|
||||
if (!fs.existsSync(changelogPath)) {
|
||||
console.error("CHANGELOG.md 未找到")
|
||||
process.exit(1)
|
||||
}
|
||||
const content = fs.readFileSync(changelogPath, 'utf8')
|
||||
await publisher.uploadChangelog(content)
|
||||
})().catch(err => {
|
||||
console.error(err.message || err)
|
||||
process.exit(1)
|
||||
})
|
||||
} else if (["all", "win", "mac"].includes(argv[2])) {
|
||||
// 自动编译(GitHub Actions)
|
||||
@@ -907,8 +922,8 @@ if (["dev"].includes(argv[2])) {
|
||||
|
||||
// 发布判断环境变量
|
||||
if (answers.publish) {
|
||||
if (!PUBLISH_KEY && (!GITHUB_TOKEN || !utils.strExists(GITHUB_REPOSITORY, "/"))) {
|
||||
console.error("发布需要 PUBLISH_KEY 或 GitHub Token 和 Repository, 请检查环境变量!");
|
||||
if (!(UPLOAD_TOKEN && UPLOAD_URL) && !(GITHUB_TOKEN && utils.strExists(GITHUB_REPOSITORY, "/"))) {
|
||||
console.error("发布需要 UPLOAD_TOKEN + UPLOAD_URL 或 GITHUB_TOKEN + GITHUB_REPOSITORY, 请检查环境变量!");
|
||||
process.exit()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
```dotenv
|
||||
OPENAI_API_KEY=你的OpenAI密钥
|
||||
OPENAI_BASE_URL=可选的自定义API地址
|
||||
OPENAI_PROXY_URL=可选的代理地址
|
||||
```
|
||||
|
||||
|
||||
@@ -963,3 +963,14 @@ AI建议:采纳(*)建议
|
||||
消息内容格式错误
|
||||
AI 调用失败
|
||||
AI 返回内容为空
|
||||
|
||||
修改AI自动分析
|
||||
关联不存在
|
||||
只能合并转发同一对话的消息
|
||||
所选消息均不支持转发
|
||||
无法创建任务对话
|
||||
最多转发(*)条消息
|
||||
此类型消息不支持转发
|
||||
没有权限操作此任务
|
||||
请选择要转发的消息
|
||||
LDAP 用户缺少邮箱属性,请联系管理员配置
|
||||
|
||||
@@ -2329,3 +2329,35 @@ AI 消息助手
|
||||
指派
|
||||
关联
|
||||
采纳
|
||||
|
||||
逐条转发
|
||||
合并转发
|
||||
复制原文
|
||||
所属部门
|
||||
留空则不修改密码
|
||||
职位
|
||||
请输入电话号码
|
||||
正在编辑帐号【ID:(*)】的信息。
|
||||
编辑用户信息
|
||||
|
||||
AI任务分析
|
||||
关闭后所有项目将不再自动分析任务。
|
||||
关闭后本项目将不再自动分析任务。
|
||||
新建任务后AI自动分析并给出建议。
|
||||
关闭后本项目将不再自动分析任务。
|
||||
(最多(*)条)
|
||||
最多选择(*)条消息
|
||||
系统已关闭AI任务分析功能。
|
||||
聊天记录
|
||||
确定要解除与任务 #(*) 的关联吗?
|
||||
共(*)条消息
|
||||
已选(*)条
|
||||
(*)的聊天记录
|
||||
(*)和(*)的聊天记录
|
||||
(*)和(*)等人的聊天记录
|
||||
|
||||
生日
|
||||
请选择生日
|
||||
登录属性
|
||||
用于匹配登录用户名的 LDAP 属性,Active Directory 请选择 sAMAccountName
|
||||
请输入帐号
|
||||
|
||||
@@ -33238,5 +33238,461 @@
|
||||
"fr": "L’IA a renvoyé un contenu vide.",
|
||||
"id": "AI mengembalikan konten kosong.",
|
||||
"ru": "ИИ вернул пустое содержимое."
|
||||
},
|
||||
{
|
||||
"key": "逐条转发",
|
||||
"zh": "",
|
||||
"zh-CHT": "逐條轉發",
|
||||
"en": "Forward individually",
|
||||
"ko": "개별 전달",
|
||||
"ja": "個別に転送",
|
||||
"de": "Einzeln weiterleiten",
|
||||
"fr": "Transférer individuellement",
|
||||
"id": "Teruskan satu per satu",
|
||||
"ru": "Переслать по отдельности"
|
||||
},
|
||||
{
|
||||
"key": "合并转发",
|
||||
"zh": "",
|
||||
"zh-CHT": "合併轉發",
|
||||
"en": "Forward as a combined message",
|
||||
"ko": "묶어서 전달",
|
||||
"ja": "まとめて転送",
|
||||
"de": "Zusammengefasst weiterleiten",
|
||||
"fr": "Transférer en message groupé",
|
||||
"id": "Teruskan sebagai pesan gabungan",
|
||||
"ru": "Переслать одним сообщением"
|
||||
},
|
||||
{
|
||||
"key": "复制原文",
|
||||
"zh": "",
|
||||
"zh-CHT": "複製原文",
|
||||
"en": "Copy original text",
|
||||
"ko": "원문 복사",
|
||||
"ja": "原文をコピー",
|
||||
"de": "Originaltext kopieren",
|
||||
"fr": "Copier le texte original",
|
||||
"id": "Salin teks asli",
|
||||
"ru": "Копировать исходный текст"
|
||||
},
|
||||
{
|
||||
"key": "所属部门",
|
||||
"zh": "",
|
||||
"zh-CHT": "所屬部門",
|
||||
"en": "Department",
|
||||
"ko": "소속 부서",
|
||||
"ja": "所属部署",
|
||||
"de": "Abteilung",
|
||||
"fr": "Service",
|
||||
"id": "Departemen",
|
||||
"ru": "Подразделение"
|
||||
},
|
||||
{
|
||||
"key": "留空则不修改密码",
|
||||
"zh": "",
|
||||
"zh-CHT": "留空則不修改密碼",
|
||||
"en": "Leave blank to keep the password unchanged",
|
||||
"ko": "비워 두면 비밀번호가 변경되지 않습니다",
|
||||
"ja": "空欄の場合、パスワードは変更されません",
|
||||
"de": "Leer lassen, um das Passwort nicht zu ändern",
|
||||
"fr": "Laissez vide pour ne pas modifier le mot de passe",
|
||||
"id": "Kosongkan untuk tidak mengubah kata sandi",
|
||||
"ru": "Оставьте пустым, чтобы не менять пароль"
|
||||
},
|
||||
{
|
||||
"key": "职位",
|
||||
"zh": "",
|
||||
"zh-CHT": "職位",
|
||||
"en": "Job title",
|
||||
"ko": "직책",
|
||||
"ja": "役職",
|
||||
"de": "Position",
|
||||
"fr": "Poste",
|
||||
"id": "Jabatan",
|
||||
"ru": "Должность"
|
||||
},
|
||||
{
|
||||
"key": "请输入电话号码",
|
||||
"zh": "",
|
||||
"zh-CHT": "請輸入電話號碼",
|
||||
"en": "Please enter a phone number",
|
||||
"ko": "전화번호를 입력해 주세요",
|
||||
"ja": "電話番号を入力してください",
|
||||
"de": "Bitte geben Sie eine Telefonnummer ein",
|
||||
"fr": "Veuillez saisir un numéro de téléphone",
|
||||
"id": "Silakan masukkan nomor telepon",
|
||||
"ru": "Введите номер телефона"
|
||||
},
|
||||
{
|
||||
"key": "正在编辑帐号【ID:(%T1)】的信息。",
|
||||
"zh": "",
|
||||
"zh-CHT": "正在編輯帳號【ID:(%T1)】的資訊。",
|
||||
"en": "Editing the account information for 【ID:(%T1)】.",
|
||||
"ko": "계정 【ID:(%T1)】 정보를 편집 중입니다.",
|
||||
"ja": "アカウント【ID:(%T1)】の情報を編集中です。",
|
||||
"de": "Bearbeitung der Kontoinformationen für 【ID:(%T1)】.",
|
||||
"fr": "Modification des informations du compte 【ID:(%T1)】.",
|
||||
"id": "Sedang mengedit informasi akun 【ID:(%T1)】.",
|
||||
"ru": "Редактирование информации учетной записи 【ID:(%T1)】."
|
||||
},
|
||||
{
|
||||
"key": "编辑用户信息",
|
||||
"zh": "",
|
||||
"zh-CHT": "編輯使用者資訊",
|
||||
"en": "Edit user information",
|
||||
"ko": "사용자 정보 편집",
|
||||
"ja": "ユーザー情報を編集",
|
||||
"de": "Benutzerinformationen bearbeiten",
|
||||
"fr": "Modifier les informations utilisateur",
|
||||
"id": "Edit informasi pengguna",
|
||||
"ru": "Редактировать информацию о пользователе"
|
||||
},
|
||||
{
|
||||
"key": "AI任务分析",
|
||||
"zh": "",
|
||||
"zh-CHT": "AI任務分析",
|
||||
"en": "AI task analysis",
|
||||
"ko": "AI 작업 분석",
|
||||
"ja": "AIタスク分析",
|
||||
"de": "KI-Aufgabenanalyse",
|
||||
"fr": "Analyse des tâches par IA",
|
||||
"id": "Analisis tugas AI",
|
||||
"ru": "AI-анализ задач"
|
||||
},
|
||||
{
|
||||
"key": "关闭后所有项目将不再自动分析任务。",
|
||||
"zh": "",
|
||||
"zh-CHT": "關閉後所有專案將不再自動分析任務。",
|
||||
"en": "After disabling, all projects will no longer automatically analyze tasks.",
|
||||
"ko": "비활성화하면 모든 프로젝트에서 작업이 더 이상 자동으로 분석되지 않습니다.",
|
||||
"ja": "無効にすると、すべてのプロジェクトでタスクの自動分析が行われなくなります。",
|
||||
"de": "Nach dem Deaktivieren werden in allen Projekten Aufgaben nicht mehr automatisch analysiert.",
|
||||
"fr": "Après désactivation, tous les projets n’analyseront plus automatiquement les tâches.",
|
||||
"id": "Setelah dinonaktifkan, semua proyek tidak akan lagi menganalisis tugas secara otomatis.",
|
||||
"ru": "После отключения во всех проектах задачи больше не будут анализироваться автоматически."
|
||||
},
|
||||
{
|
||||
"key": "关闭后本项目将不再自动分析任务。",
|
||||
"zh": "",
|
||||
"zh-CHT": "關閉後本專案將不再自動分析任務。",
|
||||
"en": "After disabling, this project will no longer automatically analyze tasks.",
|
||||
"ko": "비활성화하면 이 프로젝트에서 작업이 더 이상 자동으로 분석되지 않습니다.",
|
||||
"ja": "無効にすると、このプロジェクトでタスクの自動分析が行われなくなります。",
|
||||
"de": "Nach dem Deaktivieren werden in diesem Projekt Aufgaben nicht mehr automatisch analysiert.",
|
||||
"fr": "Après désactivation, ce projet n’analysera plus automatiquement les tâches.",
|
||||
"id": "Setelah dinonaktifkan, proyek ini tidak akan lagi menganalisis tugas secara otomatis.",
|
||||
"ru": "После отключения в этом проекте задачи больше не будут анализироваться автоматически."
|
||||
},
|
||||
{
|
||||
"key": "新建任务后AI自动分析并给出建议。",
|
||||
"zh": "",
|
||||
"zh-CHT": "新建任務後 AI 會自動分析並給出建議。",
|
||||
"en": "After creating a task, AI automatically analyzes it and provides suggestions.",
|
||||
"ko": "작업을 생성하면 AI가 자동으로 분석하고 제안을 제공합니다.",
|
||||
"ja": "タスク作成後、AIが自動で分析し提案を提示します。",
|
||||
"de": "Nach dem Erstellen einer Aufgabe analysiert die KI automatisch und gibt Vorschläge.",
|
||||
"fr": "Après la création d’une tâche, l’IA l’analyse automatiquement et propose des suggestions.",
|
||||
"id": "Setelah membuat tugas, AI akan menganalisis secara otomatis dan memberikan saran.",
|
||||
"ru": "После создания задачи ИИ автоматически анализирует её и предлагает рекомендации."
|
||||
},
|
||||
{
|
||||
"key": "系统已关闭AI任务分析功能。",
|
||||
"zh": "",
|
||||
"zh-CHT": "系統已關閉 AI 任務分析功能。",
|
||||
"en": "AI task analysis has been disabled.",
|
||||
"ko": "AI 작업 분석 기능이 비활성화되었습니다.",
|
||||
"ja": "AIタスク分析機能は無効になりました。",
|
||||
"de": "Die KI-Aufgabenanalyse wurde deaktiviert.",
|
||||
"fr": "La fonctionnalité d’analyse des tâches par IA a été désactivée.",
|
||||
"id": "Fitur analisis tugas AI telah dinonaktifkan.",
|
||||
"ru": "Функция ИИ-анализа задач отключена."
|
||||
},
|
||||
{
|
||||
"key": "聊天记录",
|
||||
"zh": "",
|
||||
"zh-CHT": "聊天記錄",
|
||||
"en": "Chat history",
|
||||
"ko": "채팅 기록",
|
||||
"ja": "チャット履歴",
|
||||
"de": "Chatverlauf",
|
||||
"fr": "Historique de chat",
|
||||
"id": "Riwayat chat",
|
||||
"ru": "История чата"
|
||||
},
|
||||
{
|
||||
"key": "(%T1)的聊天记录",
|
||||
"zh": "",
|
||||
"zh-CHT": "(%T1)的聊天記錄",
|
||||
"en": "Chat history with (%T1)",
|
||||
"ko": "(%T1)와의 채팅 기록",
|
||||
"ja": "(%T1)とのチャット履歴",
|
||||
"de": "Chatverlauf mit (%T1)",
|
||||
"fr": "Historique de discussion avec (%T1)",
|
||||
"id": "Riwayat chat dengan (%T1)",
|
||||
"ru": "История чата с (%T1)"
|
||||
},
|
||||
{
|
||||
"key": "(%T1)和(%T2)的聊天记录",
|
||||
"zh": "",
|
||||
"zh-CHT": "(%T1)和(%T2)的聊天記錄",
|
||||
"en": "Chat history with (%T1) and (%T2)",
|
||||
"ko": "(%T1) 및 (%T2)와의 채팅 기록",
|
||||
"ja": "(%T1)と(%T2)とのチャット履歴",
|
||||
"de": "Chatverlauf mit (%T1) und (%T2)",
|
||||
"fr": "Historique de discussion avec (%T1) et (%T2)",
|
||||
"id": "Riwayat chat dengan (%T1) dan (%T2)",
|
||||
"ru": "История чата с (%T1) и (%T2)"
|
||||
},
|
||||
{
|
||||
"key": "(%T1)和(%T2)等人的聊天记录",
|
||||
"zh": "",
|
||||
"zh-CHT": "(%T1)和(%T2)等人的聊天記錄",
|
||||
"en": "Chat history with (%T1), (%T2), and others",
|
||||
"ko": "(%T1), (%T2) 등과의 채팅 기록",
|
||||
"ja": "(%T1)や(%T2)などとのチャット履歴",
|
||||
"de": "Chatverlauf mit (%T1), (%T2) und anderen",
|
||||
"fr": "Historique de discussion avec (%T1), (%T2) et d'autres personnes",
|
||||
"id": "Riwayat chat dengan (%T1), (%T2), dan lainnya",
|
||||
"ru": "История чата с (%T1), (%T2) и другими"
|
||||
},
|
||||
{
|
||||
"key": "生日",
|
||||
"zh": "",
|
||||
"zh-CHT": "生日",
|
||||
"en": "Birthday",
|
||||
"ko": "생일",
|
||||
"ja": "誕生日",
|
||||
"de": "Geburtstag",
|
||||
"fr": "Date de naissance",
|
||||
"id": "Tanggal lahir",
|
||||
"ru": "Дата рождения"
|
||||
},
|
||||
{
|
||||
"key": "请选择生日",
|
||||
"zh": "",
|
||||
"zh-CHT": "請選擇生日",
|
||||
"en": "Please select a birthday",
|
||||
"ko": "생일을 선택해 주세요",
|
||||
"ja": "誕生日を選択してください",
|
||||
"de": "Bitte wählen Sie ein Geburtsdatum aus",
|
||||
"fr": "Veuillez sélectionner une date de naissance",
|
||||
"id": "Silakan pilih tanggal lahir",
|
||||
"ru": "Выберите дату рождения"
|
||||
},
|
||||
{
|
||||
"key": "修改AI自动分析",
|
||||
"zh": "",
|
||||
"zh-CHT": "修改AI自動分析",
|
||||
"en": "Edit AI auto analysis",
|
||||
"ko": "AI 자동 분석 수정",
|
||||
"ja": "AI自動分析を編集",
|
||||
"de": "KI-Autoanalyse bearbeiten",
|
||||
"fr": "Modifier l'analyse automatique de l'IA",
|
||||
"id": "Ubah analisis otomatis AI",
|
||||
"ru": "Изменить автоанализ ИИ"
|
||||
},
|
||||
{
|
||||
"key": "关联不存在",
|
||||
"zh": "",
|
||||
"zh-CHT": "關聯不存在",
|
||||
"en": "Association does not exist",
|
||||
"ko": "연결된 항목이 없습니다",
|
||||
"ja": "関連付けが存在しません",
|
||||
"de": "Verknüpfung existiert nicht",
|
||||
"fr": "L'association n'existe pas",
|
||||
"id": "Tautan tidak ada",
|
||||
"ru": "Связь не существует"
|
||||
},
|
||||
{
|
||||
"key": "只能合并转发同一对话的消息",
|
||||
"zh": "",
|
||||
"zh-CHT": "只能合併轉發同一對話的消息",
|
||||
"en": "You can only merge and forward messages from the same chat",
|
||||
"ko": "동일한 대화의 메시지만 합쳐서 전달할 수 있습니다",
|
||||
"ja": "同一の会話のメッセージのみまとめて転送できます",
|
||||
"de": "Sie können nur Nachrichten aus demselben Chat zusammenführen und weiterleiten",
|
||||
"fr": "Vous ne pouvez regrouper et transférer que des messages provenant de la même conversation",
|
||||
"id": "Anda hanya dapat menggabungkan dan meneruskan pesan dari percakapan yang sama",
|
||||
"ru": "Можно объединять и пересылать только сообщения из одного и того же чата"
|
||||
},
|
||||
{
|
||||
"key": "所选消息均不支持转发",
|
||||
"zh": "",
|
||||
"zh-CHT": "所選消息均不支援轉發",
|
||||
"en": "None of the selected messages can be forwarded",
|
||||
"ko": "선택한 메시지는 모두 전달을 지원하지 않습니다",
|
||||
"ja": "選択したメッセージはいずれも転送できません",
|
||||
"de": "Keine der ausgewählten Nachrichten kann weitergeleitet werden",
|
||||
"fr": "Aucun des messages sélectionnés ne peut être transféré",
|
||||
"id": "Tidak ada pesan yang dipilih dapat diteruskan",
|
||||
"ru": "Ни одно из выбранных сообщений нельзя переслать"
|
||||
},
|
||||
{
|
||||
"key": "无法创建任务对话",
|
||||
"zh": "",
|
||||
"zh-CHT": "無法建立任務對話",
|
||||
"en": "Unable to create a task chat",
|
||||
"ko": "업무 대화를 만들 수 없습니다",
|
||||
"ja": "タスクチャットを作成できません",
|
||||
"de": "Task-Chat kann nicht erstellt werden",
|
||||
"fr": "Impossible de créer une discussion de tâche",
|
||||
"id": "Tidak dapat membuat chat tugas",
|
||||
"ru": "Не удалось создать чат задачи"
|
||||
},
|
||||
{
|
||||
"key": "最多转发(%T1)条消息",
|
||||
"zh": "",
|
||||
"zh-CHT": "最多轉發(%T1)條訊息",
|
||||
"en": "You can forward up to (%T1) messages",
|
||||
"ko": "최대 (%T1)개의 메시지만 전달할 수 있습니다",
|
||||
"ja": "最大(%T1)件のメッセージまで転送できます",
|
||||
"de": "Sie können bis zu (%T1) Nachrichten weiterleiten",
|
||||
"fr": "Vous pouvez transférer jusqu’à (%T1) messages",
|
||||
"id": "Anda dapat meneruskan hingga (%T1) pesan",
|
||||
"ru": "Можно переслать не более (%T1) сообщений"
|
||||
},
|
||||
{
|
||||
"key": "此类型消息不支持转发",
|
||||
"zh": "",
|
||||
"zh-CHT": "此類型訊息不支援轉發",
|
||||
"en": "This type of message cannot be forwarded",
|
||||
"ko": "이 유형의 메시지는 전달을 지원하지 않습니다",
|
||||
"ja": "この種類のメッセージは転送できません",
|
||||
"de": "Dieser Nachrichtentyp kann nicht weitergeleitet werden",
|
||||
"fr": "Ce type de message ne peut pas être transféré",
|
||||
"id": "Jenis pesan ini tidak mendukung penerusan",
|
||||
"ru": "Этот тип сообщений не поддерживает пересылку"
|
||||
},
|
||||
{
|
||||
"key": "没有权限操作此任务",
|
||||
"zh": "",
|
||||
"zh-CHT": "沒有權限操作此任務",
|
||||
"en": "You don’t have permission to operate this task",
|
||||
"ko": "이 작업을 처리할 권한이 없습니다",
|
||||
"ja": "このタスクを操作する権限がありません",
|
||||
"de": "Sie haben keine Berechtigung, diese Aufgabe zu bearbeiten",
|
||||
"fr": "Vous n’avez pas l’autorisation d’effectuer cette opération sur cette tâche",
|
||||
"id": "Anda tidak memiliki izin untuk mengoperasikan tugas ini",
|
||||
"ru": "У вас нет прав для выполнения операций с этой задачей"
|
||||
},
|
||||
{
|
||||
"key": "请选择要转发的消息",
|
||||
"zh": "",
|
||||
"zh-CHT": "請選擇要轉發的訊息",
|
||||
"en": "Please select the messages to forward",
|
||||
"ko": "전달할 메시지를 선택하세요",
|
||||
"ja": "転送するメッセージを選択してください",
|
||||
"de": "Bitte wählen Sie die weiterzuleitenden Nachrichten aus",
|
||||
"fr": "Veuillez sélectionner les messages à transférer",
|
||||
"id": "Silakan pilih pesan yang akan diteruskan",
|
||||
"ru": "Выберите сообщения для пересылки"
|
||||
},
|
||||
{
|
||||
"key": "(最多(%T1)条)",
|
||||
"zh": "",
|
||||
"zh-CHT": "(最多(%T1)條)",
|
||||
"en": "(Up to (%T1) items)",
|
||||
"ko": "(최대 (%T1)개)",
|
||||
"ja": "(最大(%T1)件)",
|
||||
"de": "(Maximal (%T1) Einträge)",
|
||||
"fr": "(Jusqu’à (%T1) éléments)",
|
||||
"id": "(Maksimal (%T1) item)",
|
||||
"ru": "(Максимум (%T1) шт.)"
|
||||
},
|
||||
{
|
||||
"key": "最多选择(%T1)条消息",
|
||||
"zh": "",
|
||||
"zh-CHT": "最多選擇(%T1)則訊息",
|
||||
"en": "Select up to (%T1) messages",
|
||||
"ko": "최대 (%T1)개의 메시지를 선택할 수 있습니다",
|
||||
"ja": "最大(%T1)件のメッセージを選択できます",
|
||||
"de": "Wählen Sie bis zu (%T1) Nachrichten aus",
|
||||
"fr": "Sélectionnez jusqu’à (%T1) messages",
|
||||
"id": "Pilih hingga (%T1) pesan",
|
||||
"ru": "Можно выбрать до (%T1) сообщений"
|
||||
},
|
||||
{
|
||||
"key": "确定要解除与任务 #(%T1) 的关联吗?",
|
||||
"zh": "",
|
||||
"zh-CHT": "確定要解除與任務 #(%T1) 的關聯嗎?",
|
||||
"en": "Are you sure you want to unlink from task #(%T1)?",
|
||||
"ko": "작업 #(%T1)과의 연결을 해제하시겠습니까?",
|
||||
"ja": "タスク #(%T1) との関連付けを解除してもよろしいですか?",
|
||||
"de": "Möchten Sie die Verknüpfung mit Aufgabe #(%T1) wirklich aufheben?",
|
||||
"fr": "Voulez-vous vraiment dissocier la tâche #(%T1) ?",
|
||||
"id": "Yakin ingin membatalkan tautan dengan tugas #(%T1)?",
|
||||
"ru": "Вы уверены, что хотите отвязать от задачи #(%T1)?"
|
||||
},
|
||||
{
|
||||
"key": "共(%T1)条消息",
|
||||
"zh": "",
|
||||
"zh-CHT": "共(%T1)則訊息",
|
||||
"en": "Total: (%T1) messages",
|
||||
"ko": "총 (%T1)개 메시지",
|
||||
"ja": "合計(%T1)件のメッセージ",
|
||||
"de": "Insgesamt (%T1) Nachrichten",
|
||||
"fr": "Total : (%T1) messages",
|
||||
"id": "Total (%T1) pesan",
|
||||
"ru": "Всего: (%T1) сообщений"
|
||||
},
|
||||
{
|
||||
"key": "已选(%T1)条",
|
||||
"zh": "",
|
||||
"zh-CHT": "已選(%T1)條",
|
||||
"en": "Selected: (%T1)",
|
||||
"ko": "(%T1)개 선택됨",
|
||||
"ja": "(%T1)件選択済み",
|
||||
"de": "(%T1) ausgewählt",
|
||||
"fr": "(%T1) sélectionné(s)",
|
||||
"id": "(%T1) dipilih",
|
||||
"ru": "Выбрано: (%T1)"
|
||||
},
|
||||
{
|
||||
"key": "登录属性",
|
||||
"zh": "",
|
||||
"zh-CHT": "登入屬性",
|
||||
"en": "Login attribute",
|
||||
"ko": "로그인 속성",
|
||||
"ja": "ログイン属性",
|
||||
"de": "Anmeldeattribut",
|
||||
"fr": "Attribut de connexion",
|
||||
"id": "Atribut login",
|
||||
"ru": "Атрибут входа"
|
||||
},
|
||||
{
|
||||
"key": "用于匹配登录用户名的 LDAP 属性,Active Directory 请选择 sAMAccountName",
|
||||
"zh": "",
|
||||
"zh-CHT": "用於比對登入使用者名稱的 LDAP 屬性,Active Directory 請選擇 sAMAccountName",
|
||||
"en": "LDAP attribute used to match the login username. For Active Directory, select sAMAccountName.",
|
||||
"ko": "로그인 사용자 이름을 일치시키는 데 사용되는 LDAP 속성입니다. Active Directory의 경우 sAMAccountName을 선택하세요.",
|
||||
"ja": "ログインユーザー名の照合に使用する LDAP 属性です。Active Directory の場合は sAMAccountName を選択してください。",
|
||||
"de": "LDAP-Attribut zum Abgleich des Anmeldenamens. Wählen Sie für Active Directory sAMAccountName.",
|
||||
"fr": "Attribut LDAP utilisé pour faire correspondre le nom d’utilisateur de connexion. Pour Active Directory, sélectionnez sAMAccountName.",
|
||||
"id": "Atribut LDAP yang digunakan untuk mencocokkan nama pengguna login. Untuk Active Directory, pilih sAMAccountName.",
|
||||
"ru": "LDAP-атрибут для сопоставления имени пользователя при входе. Для Active Directory выберите sAMAccountName."
|
||||
},
|
||||
{
|
||||
"key": "请输入帐号",
|
||||
"zh": "",
|
||||
"zh-CHT": "請輸入帳號",
|
||||
"en": "Please enter your account",
|
||||
"ko": "계정을 입력하세요",
|
||||
"ja": "アカウントを入力してください",
|
||||
"de": "Bitte geben Sie Ihr Konto ein",
|
||||
"fr": "Veuillez saisir votre compte",
|
||||
"id": "Silakan masukkan akun Anda",
|
||||
"ru": "Пожалуйста, введите учетную запись"
|
||||
},
|
||||
{
|
||||
"key": "LDAP 用户缺少邮箱属性,请联系管理员配置",
|
||||
"zh": "",
|
||||
"zh-CHT": "LDAP 使用者缺少郵箱屬性,請聯繫管理員進行設定",
|
||||
"en": "The LDAP user is missing the email attribute. Please contact the administrator to configure it.",
|
||||
"ko": "LDAP 사용자에게 이메일 속성이 없습니다. 관리자에게 문의하여 설정해 주세요.",
|
||||
"ja": "LDAPユーザーにメール属性がありません。管理者に連絡して設定してください。",
|
||||
"de": "Dem LDAP-Benutzer fehlt das E-Mail-Attribut. Bitte wenden Sie sich an den Administrator, um es zu konfigurieren.",
|
||||
"fr": "Il manque l’attribut e-mail pour l’utilisateur LDAP. Veuillez contacter l’administrateur pour le configurer.",
|
||||
"id": "Pengguna LDAP tidak memiliki atribut email. Silakan hubungi administrator untuk mengonfigurasinya.",
|
||||
"ru": "У пользователя LDAP отсутствует атрибут электронной почты. Пожалуйста, свяжитесь с администратором для настройки."
|
||||
}
|
||||
]
|
||||
@@ -75,6 +75,7 @@ if ($openAiKey === '') {
|
||||
exit(1);
|
||||
}
|
||||
$openAiProxy = trim(language_env_value('OPENAI_PROXY_URL', $languageEnv) ?? '');
|
||||
$openAiBaseUrl = trim(language_env_value('OPENAI_BASE_URL', $languageEnv) ?? '');
|
||||
|
||||
// 读取所有要翻译的内容
|
||||
$originals = [];
|
||||
@@ -170,6 +171,9 @@ if (count($needs) > 0) {
|
||||
// 开始翻译
|
||||
print_r("正在翻译:" . (count($keys) + $done) . "/" . count($needs) . "...\n");
|
||||
$openAi = new OpenAi($openAiKey);
|
||||
if ($openAiBaseUrl !== '') {
|
||||
$openAi->setBaseURL(rtrim(preg_replace('#/v\d+/?$#', '', $openAiBaseUrl), '/'));
|
||||
}
|
||||
if ($openAiProxy !== '') {
|
||||
$openAi->setProxy($openAiProxy);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "DooTask",
|
||||
"version": "1.6.89",
|
||||
"codeVerson": 228,
|
||||
"version": "1.7.29",
|
||||
"codeVerson": 232,
|
||||
"description": "DooTask is task management system.",
|
||||
"scripts": {
|
||||
"start": "./cmd dev",
|
||||
@@ -90,7 +90,7 @@
|
||||
],
|
||||
"publish": {
|
||||
"provider": "generic",
|
||||
"url": "https://www.dootask.com/desktop/publish"
|
||||
"url": "https://www.dootask.com/api/download/update"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
BIN
public/images/avatar/default_assistant.png
Normal file
BIN
public/images/avatar/default_assistant.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
1
public/js/build/404.1970a86e.js
vendored
Normal file
1
public/js/build/404.1970a86e.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{n as m}from"./app.20ce4f8e.js";import"./jquery.26755d2b.js";import"./@babel.9410f858.js";import"./dayjs.29a2c04b.js";import"./localforage.a7f8d307.js";import"./markdown-it.0450edb4.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.acea8861.js";import"./vue.adba9046.js";import"./vuex.cc7cb26e.js";import"./openpgp_hi.15f91b1d.js";import"./axios.37c7f908.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.ca2ea0cc.js";import"./parchment.d5c5924e.js";import"./quill-delta.385a10bf.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.3cc09a31.js";import"./lodash.isequal.dbdc2157.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.76e3a28b.js";import"./quill-mention-hi.4eeb5a2d.js";import"./view-design-hi.f1128b4d.js";import"./html-to-md.f297036e.js";import"./lodash.8fcd6fd4.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.fd43a5bc.js";import"./clipboard.37b37361.js";import"./vuedraggable.f464b992.js";import"./sortablejs.3488b922.js";import"./vue-resize-observer.5af23a43.js";import"./element-sea.f8a64907.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.5d591c5f.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.dca2b951.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var p=function(){var t=this,r=t.$createElement;return t._self._c,t._m(0)},e=[function(){var t=this,r=t.$createElement,i=t._self._c||r;return i("div",{staticClass:"page-404"},[i("div",{staticClass:"flex-center position-ref full-height"},[i("div",{staticClass:"code"},[t._v("404")]),i("div",{staticClass:"message"},[t._v("Not Found")])])])}];const s={},o={};var _=m(s,p,e,!1,n,"7d7154a8",null,null);function n(t){for(let r in o)this[r]=o[r]}var it=function(){return _.exports}();export{it as default};
|
||||
1
public/js/build/404.85da9b1f.js
vendored
1
public/js/build/404.85da9b1f.js
vendored
@@ -1 +0,0 @@
|
||||
import{n as m}from"./app.5029512e.js";import"./jquery.2060430b.js";import"./@babel.ad55b12f.js";import"./dayjs.dfa73531.js";import"./localforage.3e4ebad6.js";import"./markdown-it.bda97caf.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.561c583d.js";import"./vue.baba6da0.js";import"./vuex.cc7cb26e.js";import"./openpgp_hi.15f91b1d.js";import"./axios.554fcc10.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.978f208d.js";import"./parchment.d5c5924e.js";import"./quill-delta.4f1e4697.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.8fb065bb.js";import"./lodash.isequal.84238944.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.df04b444.js";import"./quill-mention-hi.2a6582e4.js";import"./view-design-hi.e9360295.js";import"./html-to-md.96d5de37.js";import"./lodash.2fa8f497.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.89894d1b.js";import"./clipboard.6caea48c.js";import"./vuedraggable.e8809463.js";import"./sortablejs.b1e23af3.js";import"./vue-resize-observer.df5b985e.js";import"./element-sea.9d03b085.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.18409ee0.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.e1b191c9.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var p=function(){var t=this,r=t.$createElement;return t._self._c,t._m(0)},e=[function(){var t=this,r=t.$createElement,i=t._self._c||r;return i("div",{staticClass:"page-404"},[i("div",{staticClass:"flex-center position-ref full-height"},[i("div",{staticClass:"code"},[t._v("404")]),i("div",{staticClass:"message"},[t._v("Not Found")])])])}];const s={},o={};var _=m(s,p,e,!1,n,"7d7154a8",null,null);function n(t){for(let r in o)this[r]=o[r]}var it=function(){return _.exports}();export{it as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
263
public/js/build/@traptitech.561c583d.js
vendored
263
public/js/build/@traptitech.561c583d.js
vendored
File diff suppressed because one or more lines are too long
267
public/js/build/@traptitech.acea8861.js
vendored
Normal file
267
public/js/build/@traptitech.acea8861.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
public/js/build/DialogWrapper.1f50fe2a.js
vendored
Normal file
4
public/js/build/DialogWrapper.1f50fe2a.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
public/js/build/DialogWrapper.7a5bb3ac.js
vendored
4
public/js/build/DialogWrapper.7a5bb3ac.js
vendored
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{m as s}from"./vuex.cc7cb26e.js";import{I as m}from"./IFrame.7173ab75.js";import{n as p,l as o}from"./app.5029512e.js";import"./jquery.2060430b.js";import"./@babel.ad55b12f.js";import"./dayjs.dfa73531.js";import"./localforage.3e4ebad6.js";import"./markdown-it.bda97caf.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.561c583d.js";import"./vue.baba6da0.js";import"./openpgp_hi.15f91b1d.js";import"./axios.554fcc10.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.978f208d.js";import"./parchment.d5c5924e.js";import"./quill-delta.4f1e4697.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.8fb065bb.js";import"./lodash.isequal.84238944.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.df04b444.js";import"./quill-mention-hi.2a6582e4.js";import"./view-design-hi.e9360295.js";import"./html-to-md.96d5de37.js";import"./lodash.2fa8f497.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.89894d1b.js";import"./clipboard.6caea48c.js";import"./vuedraggable.e8809463.js";import"./sortablejs.b1e23af3.js";import"./vue-resize-observer.df5b985e.js";import"./element-sea.9d03b085.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.18409ee0.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.e1b191c9.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var l=function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"drawio-content"},[i("IFrame",{ref:"frame",staticClass:"drawio-iframe",attrs:{src:t.url},on:{"on-message":t.onMessage}}),t.loadIng?i("div",{staticClass:"drawio-loading"},[i("Loading")],1):t._e()],1)},d=[];const u={name:"Drawio",components:{IFrame:m},props:{value:{type:Object,default:function(){return{}}},title:{type:String,default:""},readOnly:{type:Boolean,default:!1}},data(){return{loadIng:!0,url:null,bakData:""}},created(){let t=o;switch(o){case"zh-CHT":t="zh-tw";break}let e=this.readOnly?1:0,i=this.readOnly?0:1,n=this.themeName==="dark"?"dark":"kennedy",r=`?title=${this.title?encodeURIComponent(this.title):""}&chrome=${i}&lightbox=${e}&ui=${n}&lang=${t}&offline=1&pwa=0&embed=1&noLangIcon=1&noExitBtn=1&noSaveBtn=1&saveAndExit=0&spin=1&proto=json`;this.$Electron?this.url=$A.originUrl(`drawio/webapp/index.html${r}`):this.url=$A.mainUrl(`drawio/webapp/${r}`)},mounted(){window.addEventListener("message",this.handleMessage)},beforeDestroy(){window.removeEventListener("message",this.handleMessage)},watch:{value:{handler(t){this.bakData!=$A.jsonStringify(t)&&(this.bakData=$A.jsonStringify(t),this.updateContent())},deep:!0}},computed:{...s(["themeName"])},methods:{formatZoom(t){return t+"%"},updateContent(){this.$refs.frame.postMessage(JSON.stringify({action:"load",autosave:1,xml:this.value.xml}))},onMessage(t){switch(t.event){case"init":this.loadIng=!1,this.updateContent();break;case"load":typeof this.value.xml=="undefined"&&this.$refs.frame.postMessage(JSON.stringify({action:"template"}));break;case"autosave":const e={xml:t.xml};this.bakData=$A.jsonStringify(e),this.$emit("input",e);break;case"save":this.$emit("saveData");break}}}},a={};var c=p(u,l,d,!1,h,"39021859",null,null);function h(t){for(let e in a)this[e]=a[e]}var pt=function(){return c.exports}();export{pt as default};
|
||||
import{m as s}from"./vuex.cc7cb26e.js";import{I as m}from"./IFrame.b849e339.js";import{n as p,l as o}from"./app.20ce4f8e.js";import"./jquery.26755d2b.js";import"./@babel.9410f858.js";import"./dayjs.29a2c04b.js";import"./localforage.a7f8d307.js";import"./markdown-it.0450edb4.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.acea8861.js";import"./vue.adba9046.js";import"./openpgp_hi.15f91b1d.js";import"./axios.37c7f908.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.ca2ea0cc.js";import"./parchment.d5c5924e.js";import"./quill-delta.385a10bf.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.3cc09a31.js";import"./lodash.isequal.dbdc2157.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.76e3a28b.js";import"./quill-mention-hi.4eeb5a2d.js";import"./view-design-hi.f1128b4d.js";import"./html-to-md.f297036e.js";import"./lodash.8fcd6fd4.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.fd43a5bc.js";import"./clipboard.37b37361.js";import"./vuedraggable.f464b992.js";import"./sortablejs.3488b922.js";import"./vue-resize-observer.5af23a43.js";import"./element-sea.f8a64907.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.5d591c5f.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.dca2b951.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var l=function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"drawio-content"},[i("IFrame",{ref:"frame",staticClass:"drawio-iframe",attrs:{src:t.url},on:{"on-message":t.onMessage}}),t.loadIng?i("div",{staticClass:"drawio-loading"},[i("Loading")],1):t._e()],1)},d=[];const u={name:"Drawio",components:{IFrame:m},props:{value:{type:Object,default:function(){return{}}},title:{type:String,default:""},readOnly:{type:Boolean,default:!1}},data(){return{loadIng:!0,url:null,bakData:""}},created(){let t=o;switch(o){case"zh-CHT":t="zh-tw";break}let e=this.readOnly?1:0,i=this.readOnly?0:1,n=this.themeName==="dark"?"dark":"kennedy",r=`?title=${this.title?encodeURIComponent(this.title):""}&chrome=${i}&lightbox=${e}&ui=${n}&lang=${t}&offline=1&pwa=0&embed=1&noLangIcon=1&noExitBtn=1&noSaveBtn=1&saveAndExit=0&spin=1&proto=json`;this.$Electron?this.url=$A.originUrl(`drawio/webapp/index.html${r}`):this.url=$A.mainUrl(`drawio/webapp/${r}`)},mounted(){window.addEventListener("message",this.handleMessage)},beforeDestroy(){window.removeEventListener("message",this.handleMessage)},watch:{value:{handler(t){this.bakData!=$A.jsonStringify(t)&&(this.bakData=$A.jsonStringify(t),this.updateContent())},deep:!0}},computed:{...s(["themeName"])},methods:{formatZoom(t){return t+"%"},updateContent(){this.$refs.frame.postMessage(JSON.stringify({action:"load",autosave:1,xml:this.value.xml}))},onMessage(t){switch(t.event){case"init":this.loadIng=!1,this.updateContent();break;case"load":typeof this.value.xml=="undefined"&&this.$refs.frame.postMessage(JSON.stringify({action:"template"}));break;case"autosave":const e={xml:t.xml};this.bakData=$A.jsonStringify(e),this.$emit("input",e);break;case"save":this.$emit("saveData");break}}}},a={};var c=p(u,l,d,!1,h,"39021859",null,null);function h(t){for(let e in a)this[e]=a[e]}var pt=function(){return c.exports}();export{pt as default};
|
||||
File diff suppressed because one or more lines are too long
1
public/js/build/FilePreview.293a42e1.js
vendored
Normal file
1
public/js/build/FilePreview.293a42e1.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/js/build/FilePreview.cb6f2328.js
vendored
1
public/js/build/FilePreview.cb6f2328.js
vendored
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n}from"./app.5029512e.js";var i=function(){var e=this,s=e.$createElement,r=e._self._c||s;return r("iframe",{directives:[{name:"show",rawName:"v-show",value:e.src,expression:"src"}],ref:"iframe",attrs:{src:e.src}})},a=[];const o={name:"IFrame",props:{src:{type:String,default:""}},mounted(){this.$refs.iframe.addEventListener("load",this.handleLoad),window.addEventListener("message",this.handleMessage)},beforeDestroy(){this.$refs.iframe.removeEventListener("load",this.handleLoad),window.removeEventListener("message",this.handleMessage)},methods:{handleLoad(){this.$emit("on-load")},handleMessage({data:e,source:s}){var r;s===((r=this.$refs.iframe)==null?void 0:r.contentWindow)&&(e=$A.jsonParse(e),e.source==="fileView"&&e.action==="picture"&&this.$store.dispatch("previewImage",{index:e.params.index,list:e.params.array}),this.$emit("on-message",e))},postMessage(e,s="*"){this.$refs.iframe&&this.$refs.iframe.contentWindow.postMessage(e,s)}}},t={};var m=n(o,i,a,!1,c,null,null,null);function c(e){for(let s in t)this[s]=t[s]}var l=function(){return m.exports}();export{l as I};
|
||||
import{n}from"./app.20ce4f8e.js";var i=function(){var e=this,s=e.$createElement,r=e._self._c||s;return r("iframe",{directives:[{name:"show",rawName:"v-show",value:e.src,expression:"src"}],ref:"iframe",attrs:{src:e.src}})},a=[];const o={name:"IFrame",props:{src:{type:String,default:""}},mounted(){this.$refs.iframe.addEventListener("load",this.handleLoad),window.addEventListener("message",this.handleMessage)},beforeDestroy(){this.$refs.iframe.removeEventListener("load",this.handleLoad),window.removeEventListener("message",this.handleMessage)},methods:{handleLoad(){this.$emit("on-load")},handleMessage({data:e,source:s}){var r;s===((r=this.$refs.iframe)==null?void 0:r.contentWindow)&&(e=$A.jsonParse(e),e.source==="fileView"&&e.action==="picture"&&this.$store.dispatch("previewImage",{index:e.params.index,list:e.params.array}),this.$emit("on-message",e))},postMessage(e,s="*"){this.$refs.iframe&&this.$refs.iframe.contentWindow.postMessage(e,s)}}},t={};var m=n(o,i,a,!1,c,null,null,null);function c(e){for(let s in t)this[s]=t[s]}var l=function(){return m.exports}();export{l as I};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as r}from"./app.5029512e.js";var a=function(){var t=this,n=t.$createElement,e=t._self._c||n;return t.windowTouch?e("div",[e("Button",{attrs:{loading:t.loading,type:"primary",icon:"ios-search"},on:{click:t.onSearch}},[t._v(t._s(t.$L("\u641C\u7D22")))]),t.filtering?e("Button",{attrs:{type:"text"},on:{click:t.onCancelFilter}},[t._v(t._s(t.$L("\u53D6\u6D88\u7B5B\u9009")))]):e("Button",{attrs:{loading:t.loading,type:"text",icon:"md-refresh"},on:{click:t.onRefresh}},[t._v(t._s(t.$L("\u5237\u65B0")))])],1):e("Tooltip",{attrs:{theme:"light",placement:t.placement,"transfer-class-name":"search-button-clear",transfer:""}},[e("Button",{attrs:{loading:t.loading,type:"primary",icon:"ios-search"},on:{click:t.onSearch}},[t._v(t._s(t.$L("\u641C\u7D22")))]),e("div",{attrs:{slot:"content"},slot:"content"},[t.filtering?e("Button",{attrs:{type:"text"},on:{click:t.onCancelFilter}},[t._v(t._s(t.$L("\u53D6\u6D88\u7B5B\u9009")))]):e("Button",{attrs:{loading:t.loading,type:"text"},on:{click:t.onRefresh}},[t._v(t._s(t.$L("\u5237\u65B0")))])],1)],1)},i=[];const l={name:"SearchButton",props:{loading:{type:Boolean,default:!1},filtering:{type:Boolean,default:!1},placement:{type:String,default:"bottom"}},methods:{onSearch(){this.$emit("search")},onRefresh(){this.$emit("refresh")},onCancelFilter(){this.$emit("cancelFilter")}}},o={};var s=r(l,a,i,!1,c,null,null,null);function c(t){for(let n in o)this[n]=o[n]}var h=function(){return s.exports}();export{h as S};
|
||||
import{n as r}from"./app.20ce4f8e.js";var a=function(){var t=this,n=t.$createElement,e=t._self._c||n;return t.windowTouch?e("div",[e("Button",{attrs:{loading:t.loading,type:"primary",icon:"ios-search"},on:{click:t.onSearch}},[t._v(t._s(t.$L("\u641C\u7D22")))]),t.filtering?e("Button",{attrs:{type:"text"},on:{click:t.onCancelFilter}},[t._v(t._s(t.$L("\u53D6\u6D88\u7B5B\u9009")))]):e("Button",{attrs:{loading:t.loading,type:"text",icon:"md-refresh"},on:{click:t.onRefresh}},[t._v(t._s(t.$L("\u5237\u65B0")))])],1):e("Tooltip",{attrs:{theme:"light",placement:t.placement,"transfer-class-name":"search-button-clear",transfer:""}},[e("Button",{attrs:{loading:t.loading,type:"primary",icon:"ios-search"},on:{click:t.onSearch}},[t._v(t._s(t.$L("\u641C\u7D22")))]),e("div",{attrs:{slot:"content"},slot:"content"},[t.filtering?e("Button",{attrs:{type:"text"},on:{click:t.onCancelFilter}},[t._v(t._s(t.$L("\u53D6\u6D88\u7B5B\u9009")))]):e("Button",{attrs:{loading:t.loading,type:"text"},on:{click:t.onRefresh}},[t._v(t._s(t.$L("\u5237\u65B0")))])],1)],1)},i=[];const l={name:"SearchButton",props:{loading:{type:Boolean,default:!1},filtering:{type:Boolean,default:!1},placement:{type:String,default:"bottom"}},methods:{onSearch(){this.$emit("search")},onRefresh(){this.$emit("refresh")},onCancelFilter(){this.$emit("cancelFilter")}}},o={};var s=r(l,a,i,!1,c,null,null,null);function c(t){for(let n in o)this[n]=o[n]}var h=function(){return s.exports}();export{h as S};
|
||||
File diff suppressed because one or more lines are too long
1
public/js/build/TaskDetail.2c4b0eba.js
vendored
1
public/js/build/TaskDetail.2c4b0eba.js
vendored
File diff suppressed because one or more lines are too long
1
public/js/build/TaskDetail.60331a91.js
vendored
Normal file
1
public/js/build/TaskDetail.60331a91.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
public/js/build/application.0cea6f6e.js
vendored
Normal file
1
public/js/build/application.0cea6f6e.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/js/build/application.4b2e46d4.js
vendored
1
public/js/build/application.4b2e46d4.js
vendored
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{m}from"./vuex.cc7cb26e.js";import{M as e}from"./index.e9f06da4.js";import{n as a}from"./app.5029512e.js";import"./vue.baba6da0.js";import"./@babel.ad55b12f.js";import"./view-design-hi.e9360295.js";import"./@micro-zoe.cbc3b3ff.js";import"./DialogWrapper.7a5bb3ac.js";import"./index.cef192c4.js";import"./vue-virtual-scroll-list-hi.aadd1a98.js";import"./lodash.2fa8f497.js";import"./ImgUpload.cb2bd871.js";import"./webhook.378987f3.js";import"./jquery.2060430b.js";import"./dayjs.dfa73531.js";import"./localforage.3e4ebad6.js";import"./markdown-it.bda97caf.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.561c583d.js";import"./openpgp_hi.15f91b1d.js";import"./axios.554fcc10.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.978f208d.js";import"./parchment.d5c5924e.js";import"./quill-delta.4f1e4697.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.8fb065bb.js";import"./lodash.isequal.84238944.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.df04b444.js";import"./quill-mention-hi.2a6582e4.js";import"./html-to-md.96d5de37.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.89894d1b.js";import"./clipboard.6caea48c.js";import"./vuedraggable.e8809463.js";import"./sortablejs.b1e23af3.js";import"./vue-resize-observer.df5b985e.js";import"./element-sea.9d03b085.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.18409ee0.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.e1b191c9.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var n=function(){var t=this,o=t.$createElement,r=t._self._c||o;return r("MicroApps",{ref:"app",attrs:{"window-type":"popout"}})},s=[];const u={components:{MicroApps:e},computed:{...m(["userIsAdmin"])},async mounted(){const{name:t}=this.$route.params;if(!t){$A.modalError("\u5E94\u7528\u4E0D\u5B58\u5728");return}if(t==="iframe-test"){if(!this.userIsAdmin){$A.modalError("\u4EC5\u7BA1\u7406\u5458\u53EF\u4F7F\u7528\u6B64\u529F\u80FD");return}let{url:r}=this.$route.query;if(!r){if(r=await this.promptIframeUrl(),!r)return;this.$router.replace({path:this.$route.path,query:{...this.$route.query,url:r}}).catch(()=>{})}await this.$refs.app.onOpen({id:"iframe-test",name:"iframe-test",url:r,type:"iframe",transparent:!0,keep_alive:!1});return}const o=(await $A.IDBArray("cacheMicroApps")).reverse().find(r=>r.name===t);if(!o){$A.modalError("\u5E94\u7528\u4E0D\u5B58\u5728");return}await this.$refs.app.onOpen(o)},methods:{promptIframeUrl(){return new Promise((t,o)=>{$A.modalInput({title:this.$L("\u8BF7\u8F93\u5165 URL"),placeholder:"https://example.com",onOk:r=>{const i=(r||"").trim();if(!i)return this.$L("URL\u4E0D\u80FD\u4E3A\u7A7A");t(i)},onCancel:()=>o()})}).catch(()=>null)}}},p={};var c=a(u,n,s,!1,l,null,null,null);function l(t){for(let o in p)this[o]=p[o]}var lr=function(){return c.exports}();export{lr as default};
|
||||
import{m}from"./vuex.cc7cb26e.js";import{M as e}from"./index.96ab2c5d.js";import{n as a}from"./app.20ce4f8e.js";import"./vue.adba9046.js";import"./@babel.9410f858.js";import"./view-design-hi.f1128b4d.js";import"./@micro-zoe.39406924.js";import"./DialogWrapper.1f50fe2a.js";import"./index.571c9d21.js";import"./vue-virtual-scroll-list-hi.74ad83f0.js";import"./lodash.8fcd6fd4.js";import"./ImgUpload.a3251af4.js";import"./webhook.378987f3.js";import"./jquery.26755d2b.js";import"./dayjs.29a2c04b.js";import"./localforage.a7f8d307.js";import"./markdown-it.0450edb4.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.acea8861.js";import"./openpgp_hi.15f91b1d.js";import"./axios.37c7f908.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.ca2ea0cc.js";import"./parchment.d5c5924e.js";import"./quill-delta.385a10bf.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.3cc09a31.js";import"./lodash.isequal.dbdc2157.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.76e3a28b.js";import"./quill-mention-hi.4eeb5a2d.js";import"./html-to-md.f297036e.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.fd43a5bc.js";import"./clipboard.37b37361.js";import"./vuedraggable.f464b992.js";import"./sortablejs.3488b922.js";import"./vue-resize-observer.5af23a43.js";import"./element-sea.f8a64907.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.5d591c5f.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.dca2b951.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var n=function(){var t=this,o=t.$createElement,r=t._self._c||o;return r("MicroApps",{ref:"app",attrs:{"window-type":"popout"}})},s=[];const u={components:{MicroApps:e},computed:{...m(["userIsAdmin"])},async mounted(){const{name:t}=this.$route.params;if(!t){$A.modalError("\u5E94\u7528\u4E0D\u5B58\u5728");return}if(t==="iframe-test"){if(!this.userIsAdmin){$A.modalError("\u4EC5\u7BA1\u7406\u5458\u53EF\u4F7F\u7528\u6B64\u529F\u80FD");return}let{url:r}=this.$route.query;if(!r){if(r=await this.promptIframeUrl(),!r)return;this.$router.replace({path:this.$route.path,query:{...this.$route.query,url:r}}).catch(()=>{})}await this.$refs.app.onOpen({id:"iframe-test",name:"iframe-test",url:r,type:"iframe",transparent:!0,keep_alive:!1});return}const o=(await $A.IDBArray("cacheMicroApps")).reverse().find(r=>r.name===t);if(!o){$A.modalError("\u5E94\u7528\u4E0D\u5B58\u5728");return}await this.$refs.app.onOpen(o)},methods:{promptIframeUrl(){return new Promise((t,o)=>{$A.modalInput({title:this.$L("\u8BF7\u8F93\u5165 URL"),placeholder:"https://example.com",onOk:r=>{const i=(r||"").trim();if(!i)return this.$L("URL\u4E0D\u80FD\u4E3A\u7A7A");t(i)},onCancel:()=>o()})}).catch(()=>null)}}},p={};var c=a(u,n,s,!1,l,null,null,null);function l(t){for(let o in p)this[o]=p[o]}var lr=function(){return c.exports}();export{lr as default};
|
||||
File diff suppressed because one or more lines are too long
6
public/js/build/axios.37c7f908.js
vendored
Normal file
6
public/js/build/axios.37c7f908.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
public/js/build/axios.554fcc10.js
vendored
6
public/js/build/axios.554fcc10.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{c as M}from"./@babel.ad55b12f.js";var P={exports:{}};/*!
|
||||
import{c as M}from"./@babel.9410f858.js";var P={exports:{}};/*!
|
||||
* clipboard.js v2.0.11
|
||||
* https://clipboardjs.com/
|
||||
*
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as l}from"./app.5029512e.js";import"./jquery.2060430b.js";import"./@babel.ad55b12f.js";import"./dayjs.dfa73531.js";import"./localforage.3e4ebad6.js";import"./markdown-it.bda97caf.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.561c583d.js";import"./vue.baba6da0.js";import"./vuex.cc7cb26e.js";import"./openpgp_hi.15f91b1d.js";import"./axios.554fcc10.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.978f208d.js";import"./parchment.d5c5924e.js";import"./quill-delta.4f1e4697.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.8fb065bb.js";import"./lodash.isequal.84238944.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.df04b444.js";import"./quill-mention-hi.2a6582e4.js";import"./view-design-hi.e9360295.js";import"./html-to-md.96d5de37.js";import"./lodash.2fa8f497.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.89894d1b.js";import"./clipboard.6caea48c.js";import"./vuedraggable.e8809463.js";import"./sortablejs.b1e23af3.js";import"./vue-resize-observer.df5b985e.js";import"./element-sea.9d03b085.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.18409ee0.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.e1b191c9.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var m=function(){var t=this,r=t.$createElement,i=t._self._c||r;return i("div",{staticClass:"setting-device"},[i("ul",[t.loadIng>0&&t.devices.length===0?i("li",{staticClass:"loading"},[i("Loading")],1):t._l(t.devices,function(e){return i("li",{key:e.id},[i("div",{staticClass:"icon"},[i("span",{class:t.getIcon(e.detail)})]),i("div",{staticClass:"info"},[i("div",{staticClass:"title"},[i("span",{staticClass:"name"},[t._v(t._s(t.getName(e.detail)))]),i("span",{staticClass:"device"},[t._v(t._s(t.getOs(e.detail)))])]),i("div",{staticClass:"time"},[i("EPopover",{attrs:{placement:"bottom-start",trigger:"click"}},[i("div",{staticClass:"setting-device-popover"},[i("p",[t._v(t._s(t.$L("\u767B\u5F55\u65F6\u95F4"))+": "+t._s(e.created_at))]),i("p",[t._v(t._s(t.$L("\u66F4\u65B0\u65F6\u95F4"))+": "+t._s(e.updated_at))]),i("p",[t._v(t._s(t.$L("\u8FC7\u671F\u65F6\u95F4"))+": "+t._s(e.expired_at))])]),i("span",{attrs:{slot:"reference"},slot:"reference"},[t._v(t._s(e.updated_at))])])],1)]),i("div",[e.is_current?i("span",{staticClass:"current"},[t._v(t._s(t.$L("\u5F53\u524D\u8BBE\u5907")))]):i("Button",{on:{click:function(o){return t.onLogout(e)}}},[t._v(t._s(t.$L("\u9000\u51FA\u767B\u5F55")))])],1)])})],2)])},p=[];const c={name:"SettingDevice",data(){return{loadIng:0,devices:[]}},mounted(){this.getDeviceList()},methods:{getDeviceList(){this.loadIng++,this.$store.dispatch("call",{url:"users/device/list"}).then(({data:t})=>{this.devices=t.list,typeof this.$parent.updateDeviceCount=="function"&&this.$parent.updateDeviceCount(this.devices.length)}).catch(({msg:t})=>{$A.modalError(t),this.devices=[]}).finally(()=>{this.loadIng--})},getIcon({app_type:t,app_name:r}){return/ios/i.test(t)?/ipad/i.test(r)?"tablet":/iphone/i.test(r)?"phone":"apple":/android/i.test(t)?/(tablet|phablet)/i.test(r)?"tablet":"android":/mac/i.test(t)?"macos":/win/i.test(t)?"window":"web"},getName({app_brand:t,app_model:r,device_name:i,app_type:e,app_name:o,browser:a}){const s=[];if(/web/i.test(e))s.push(a,this.$L("\u6D4F\u89C8\u5668"));else{if(i)return i;t?s.push(t,r):s.push(o||e,this.$L("\u5BA2\u6237\u7AEF"))}return s.join(" ")},getOs({app_os:t,os:r}){return t||r},onLogout(t){$A.modalConfirm({title:"\u9000\u51FA\u767B\u5F55",content:"\u662F\u5426\u5728\u8BE5\u8BBE\u5907\u4E0A\u9000\u51FA\u767B\u5F55\uFF1F",loading:!0,onOk:()=>new Promise((r,i)=>{this.$store.dispatch("call",{url:"users/device/logout",data:{id:t.id}}).then(({msg:e})=>{r(e),this.getDeviceList()}).catch(({msg:e})=>{i(e)})})})}}},n={};var u=l(c,m,p,!1,d,null,null,null);function d(t){for(let r in n)this[r]=n[r]}var nt=function(){return u.exports}();export{nt as default};
|
||||
import{n as l}from"./app.20ce4f8e.js";import"./jquery.26755d2b.js";import"./@babel.9410f858.js";import"./dayjs.29a2c04b.js";import"./localforage.a7f8d307.js";import"./markdown-it.0450edb4.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.acea8861.js";import"./vue.adba9046.js";import"./vuex.cc7cb26e.js";import"./openpgp_hi.15f91b1d.js";import"./axios.37c7f908.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.ca2ea0cc.js";import"./parchment.d5c5924e.js";import"./quill-delta.385a10bf.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.3cc09a31.js";import"./lodash.isequal.dbdc2157.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.76e3a28b.js";import"./quill-mention-hi.4eeb5a2d.js";import"./view-design-hi.f1128b4d.js";import"./html-to-md.f297036e.js";import"./lodash.8fcd6fd4.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.fd43a5bc.js";import"./clipboard.37b37361.js";import"./vuedraggable.f464b992.js";import"./sortablejs.3488b922.js";import"./vue-resize-observer.5af23a43.js";import"./element-sea.f8a64907.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.5d591c5f.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.dca2b951.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var m=function(){var t=this,r=t.$createElement,i=t._self._c||r;return i("div",{staticClass:"setting-device"},[i("ul",[t.loadIng>0&&t.devices.length===0?i("li",{staticClass:"loading"},[i("Loading")],1):t._l(t.devices,function(e){return i("li",{key:e.id},[i("div",{staticClass:"icon"},[i("span",{class:t.getIcon(e.detail)})]),i("div",{staticClass:"info"},[i("div",{staticClass:"title"},[i("span",{staticClass:"name"},[t._v(t._s(t.getName(e.detail)))]),i("span",{staticClass:"device"},[t._v(t._s(t.getOs(e.detail)))])]),i("div",{staticClass:"time"},[i("EPopover",{attrs:{placement:"bottom-start",trigger:"click"}},[i("div",{staticClass:"setting-device-popover"},[i("p",[t._v(t._s(t.$L("\u767B\u5F55\u65F6\u95F4"))+": "+t._s(e.created_at))]),i("p",[t._v(t._s(t.$L("\u66F4\u65B0\u65F6\u95F4"))+": "+t._s(e.updated_at))]),i("p",[t._v(t._s(t.$L("\u8FC7\u671F\u65F6\u95F4"))+": "+t._s(e.expired_at))])]),i("span",{attrs:{slot:"reference"},slot:"reference"},[t._v(t._s(e.updated_at))])])],1)]),i("div",[e.is_current?i("span",{staticClass:"current"},[t._v(t._s(t.$L("\u5F53\u524D\u8BBE\u5907")))]):i("Button",{on:{click:function(o){return t.onLogout(e)}}},[t._v(t._s(t.$L("\u9000\u51FA\u767B\u5F55")))])],1)])})],2)])},p=[];const c={name:"SettingDevice",data(){return{loadIng:0,devices:[]}},mounted(){this.getDeviceList()},methods:{getDeviceList(){this.loadIng++,this.$store.dispatch("call",{url:"users/device/list"}).then(({data:t})=>{this.devices=t.list,typeof this.$parent.updateDeviceCount=="function"&&this.$parent.updateDeviceCount(this.devices.length)}).catch(({msg:t})=>{$A.modalError(t),this.devices=[]}).finally(()=>{this.loadIng--})},getIcon({app_type:t,app_name:r}){return/ios/i.test(t)?/ipad/i.test(r)?"tablet":/iphone/i.test(r)?"phone":"apple":/android/i.test(t)?/(tablet|phablet)/i.test(r)?"tablet":"android":/mac/i.test(t)?"macos":/win/i.test(t)?"window":"web"},getName({app_brand:t,app_model:r,device_name:i,app_type:e,app_name:o,browser:a}){const s=[];if(/web/i.test(e))s.push(a,this.$L("\u6D4F\u89C8\u5668"));else{if(i)return i;t?s.push(t,r):s.push(o||e,this.$L("\u5BA2\u6237\u7AEF"))}return s.join(" ")},getOs({app_os:t,os:r}){return t||r},onLogout(t){$A.modalConfirm({title:"\u9000\u51FA\u767B\u5F55",content:"\u662F\u5426\u5728\u8BE5\u8BBE\u5907\u4E0A\u9000\u51FA\u767B\u5F55\uFF1F",loading:!0,onOk:()=>new Promise((r,i)=>{this.$store.dispatch("call",{url:"users/device/logout",data:{id:t.id}}).then(({msg:e})=>{r(e),this.getDeviceList()}).catch(({msg:e})=>{i(e)})})})}}},n={};var u=l(c,m,p,!1,d,null,null,null);function d(t){for(let r in n)this[r]=n[r]}var nt=function(){return u.exports}();export{nt as default};
|
||||
1
public/js/build/dialog.635de896.js
vendored
Normal file
1
public/js/build/dialog.635de896.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{D as p}from"./DialogWrapper.1f50fe2a.js";import{m}from"./vuex.cc7cb26e.js";import{n as a}from"./app.20ce4f8e.js";import"./index.571c9d21.js";import"./vue-virtual-scroll-list-hi.74ad83f0.js";import"./@babel.9410f858.js";import"./vue.adba9046.js";import"./lodash.8fcd6fd4.js";import"./ImgUpload.a3251af4.js";import"./webhook.378987f3.js";import"./jquery.26755d2b.js";import"./dayjs.29a2c04b.js";import"./localforage.a7f8d307.js";import"./markdown-it.0450edb4.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.acea8861.js";import"./openpgp_hi.15f91b1d.js";import"./axios.37c7f908.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.ca2ea0cc.js";import"./parchment.d5c5924e.js";import"./quill-delta.385a10bf.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.3cc09a31.js";import"./lodash.isequal.dbdc2157.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.76e3a28b.js";import"./quill-mention-hi.4eeb5a2d.js";import"./view-design-hi.f1128b4d.js";import"./html-to-md.f297036e.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.fd43a5bc.js";import"./clipboard.37b37361.js";import"./vuedraggable.f464b992.js";import"./sortablejs.3488b922.js";import"./vue-resize-observer.5af23a43.js";import"./element-sea.f8a64907.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.5d591c5f.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.dca2b951.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var e=function(){var t=this,o=t.$createElement,r=t._self._c||o;return r("div",{staticClass:"electron-dialog"},[r("PageTitle",{attrs:{title:t.dialogData.name}}),t.dialogId>0?r("DialogWrapper",{attrs:{dialogId:t.dialogId}}):t._e()],1)},n=[];const s={components:{DialogWrapper:p},computed:{...m(["cacheDialogs"]),dialogId(){const{dialogId:t}=this.$route.params;return parseInt(/^\d+$/.test(t)?t:0)},dialogData(){return this.cacheDialogs.find(({id:t})=>t===this.dialogId)||{}}}},i={};var l=a(s,e,n,!1,d,"4f6d7c8a",null,null);function d(t){for(let o in i)this[o]=i[o]}var st=function(){return l.exports}();export{st as default};
|
||||
1
public/js/build/dialog.d08cbf50.js
vendored
1
public/js/build/dialog.d08cbf50.js
vendored
@@ -1 +0,0 @@
|
||||
import{D as p}from"./DialogWrapper.7a5bb3ac.js";import{m}from"./vuex.cc7cb26e.js";import{n as a}from"./app.5029512e.js";import"./index.cef192c4.js";import"./vue-virtual-scroll-list-hi.aadd1a98.js";import"./@babel.ad55b12f.js";import"./vue.baba6da0.js";import"./lodash.2fa8f497.js";import"./ImgUpload.cb2bd871.js";import"./webhook.378987f3.js";import"./jquery.2060430b.js";import"./dayjs.dfa73531.js";import"./localforage.3e4ebad6.js";import"./markdown-it.bda97caf.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.561c583d.js";import"./openpgp_hi.15f91b1d.js";import"./axios.554fcc10.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.978f208d.js";import"./parchment.d5c5924e.js";import"./quill-delta.4f1e4697.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.8fb065bb.js";import"./lodash.isequal.84238944.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.df04b444.js";import"./quill-mention-hi.2a6582e4.js";import"./view-design-hi.e9360295.js";import"./html-to-md.96d5de37.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.89894d1b.js";import"./clipboard.6caea48c.js";import"./vuedraggable.e8809463.js";import"./sortablejs.b1e23af3.js";import"./vue-resize-observer.df5b985e.js";import"./element-sea.9d03b085.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.18409ee0.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.e1b191c9.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var e=function(){var t=this,o=t.$createElement,r=t._self._c||o;return r("div",{staticClass:"electron-dialog"},[r("PageTitle",{attrs:{title:t.dialogData.name}}),t.dialogId>0?r("DialogWrapper",{attrs:{dialogId:t.dialogId}}):t._e()],1)},n=[];const s={components:{DialogWrapper:p},computed:{...m(["cacheDialogs"]),dialogId(){const{dialogId:t}=this.$route.params;return parseInt(/^\d+$/.test(t)?t:0)},dialogData(){return this.cacheDialogs.find(({id:t})=>t===this.dialogId)||{}}}},i={};var l=a(s,e,n,!1,d,"4f6d7c8a",null,null);function d(t){for(let o in i)this[o]=i[o]}var st=function(){return l.exports}();export{st as default};
|
||||
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import n from"./FileContent.28e405be.js";import m from"./FilePreview.cb6f2328.js";import{n as l}from"./app.5029512e.js";import"./openpgp_hi.15f91b1d.js";import"./IFrame.7173ab75.js";import"./jquery.2060430b.js";import"./@babel.ad55b12f.js";import"./dayjs.dfa73531.js";import"./localforage.3e4ebad6.js";import"./markdown-it.bda97caf.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.561c583d.js";import"./vue.baba6da0.js";import"./vuex.cc7cb26e.js";import"./axios.554fcc10.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.978f208d.js";import"./parchment.d5c5924e.js";import"./quill-delta.4f1e4697.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.8fb065bb.js";import"./lodash.isequal.84238944.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.df04b444.js";import"./quill-mention-hi.2a6582e4.js";import"./view-design-hi.e9360295.js";import"./html-to-md.96d5de37.js";import"./lodash.2fa8f497.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.89894d1b.js";import"./clipboard.6caea48c.js";import"./vuedraggable.e8809463.js";import"./sortablejs.b1e23af3.js";import"./vue-resize-observer.df5b985e.js";import"./element-sea.9d03b085.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.18409ee0.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.e1b191c9.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var s=function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"single-file"},[i("PageTitle",{attrs:{title:t.pageName}}),t.loadIng>0?i("Loading"):t.fileInfo?[t.isPreview?i("FilePreview",{attrs:{code:t.code,file:t.fileInfo,historyId:t.historyId,headerShow:!t.$isEEUIApp}}):i("FileContent",{attrs:{file:t.fileInfo},model:{value:t.fileShow,callback:function(r){t.fileShow=r},expression:"fileShow"}})]:t._e()],2)},p=[];const a={components:{FilePreview:m,FileContent:n},data(){return{loadIng:0,code:null,fileShow:!0,fileInfo:null}},mounted(){},computed:{historyId(){return this.$route.query?$A.runNum(this.$route.query.history_id):0},isPreview(){return this.windowPortrait||this.code||this.historyId>0||this.fileInfo&&this.fileInfo.permission===0},pageName(){return this.$route.query&&this.$route.query.history_title?this.$route.query.history_title:this.fileInfo?`${this.fileInfo.name} [${this.fileInfo.created_at}]`:""}},watch:{$route:{handler(){this.getInfo()},immediate:!0}},methods:{getInfo(){let{codeOrFileId:t}=this.$route.params,e={id:t};if(/^\d+$/.test(t))this.code=null;else if(t)this.code=t;else return;setTimeout(i=>{this.loadIng++},600),this.$store.dispatch("call",{url:"file/one",data:e}).then(({data:i})=>{this.fileInfo=i}).catch(({msg:i})=>{$A.modalError({content:i,onOk:()=>{window.close()}})}).finally(i=>{this.loadIng--})}}},o={};var f=l(a,s,p,!1,u,"662d0b64",null,null);function u(t){for(let e in o)this[e]=o[e]}var st=function(){return f.exports}();export{st as default};
|
||||
import n from"./FileContent.529916bc.js";import m from"./FilePreview.293a42e1.js";import{n as l}from"./app.20ce4f8e.js";import"./openpgp_hi.15f91b1d.js";import"./IFrame.b849e339.js";import"./jquery.26755d2b.js";import"./@babel.9410f858.js";import"./dayjs.29a2c04b.js";import"./localforage.a7f8d307.js";import"./markdown-it.0450edb4.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.acea8861.js";import"./vue.adba9046.js";import"./vuex.cc7cb26e.js";import"./axios.37c7f908.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.ca2ea0cc.js";import"./parchment.d5c5924e.js";import"./quill-delta.385a10bf.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.3cc09a31.js";import"./lodash.isequal.dbdc2157.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.76e3a28b.js";import"./quill-mention-hi.4eeb5a2d.js";import"./view-design-hi.f1128b4d.js";import"./html-to-md.f297036e.js";import"./lodash.8fcd6fd4.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.fd43a5bc.js";import"./clipboard.37b37361.js";import"./vuedraggable.f464b992.js";import"./sortablejs.3488b922.js";import"./vue-resize-observer.5af23a43.js";import"./element-sea.f8a64907.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.5d591c5f.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.dca2b951.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var s=function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"single-file"},[i("PageTitle",{attrs:{title:t.pageName}}),t.loadIng>0?i("Loading"):t.fileInfo?[t.isPreview?i("FilePreview",{attrs:{code:t.code,file:t.fileInfo,historyId:t.historyId,headerShow:!t.$isEEUIApp}}):i("FileContent",{attrs:{file:t.fileInfo},model:{value:t.fileShow,callback:function(r){t.fileShow=r},expression:"fileShow"}})]:t._e()],2)},p=[];const a={components:{FilePreview:m,FileContent:n},data(){return{loadIng:0,code:null,fileShow:!0,fileInfo:null}},mounted(){},computed:{historyId(){return this.$route.query?$A.runNum(this.$route.query.history_id):0},isPreview(){return this.windowPortrait||this.code||this.historyId>0||this.fileInfo&&this.fileInfo.permission===0},pageName(){return this.$route.query&&this.$route.query.history_title?this.$route.query.history_title:this.fileInfo?`${this.fileInfo.name} [${this.fileInfo.created_at}]`:""}},watch:{$route:{handler(){this.getInfo()},immediate:!0}},methods:{getInfo(){let{codeOrFileId:t}=this.$route.params,e={id:t};if(/^\d+$/.test(t))this.code=null;else if(t)this.code=t;else return;setTimeout(i=>{this.loadIng++},600),this.$store.dispatch("call",{url:"file/one",data:e}).then(({data:i})=>{this.fileInfo=i}).catch(({msg:i})=>{$A.modalError({content:i,onOk:()=>{window.close()}})}).finally(i=>{this.loadIng--})}}},o={};var f=l(a,s,p,!1,u,"662d0b64",null,null);function u(t){for(let e in o)this[e]=o[e]}var st=function(){return f.exports}();export{st as default};
|
||||
File diff suppressed because one or more lines are too long
1
public/js/build/fileMsg.771940b1.js
vendored
1
public/js/build/fileMsg.771940b1.js
vendored
File diff suppressed because one or more lines are too long
1
public/js/build/fileMsg.d5a4e089.js
vendored
Normal file
1
public/js/build/fileMsg.d5a4e089.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/js/build/fileTask.aee39482.js
vendored
Normal file
1
public/js/build/fileTask.aee39482.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/js/build/fileTask.eddebadd.js
vendored
1
public/js/build/fileTask.eddebadd.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{c as it,g as at}from"./@babel.ad55b12f.js";var G={exports:{}};(function($,ut){(function(_,s){$.exports=s()})(it,function(){return function(_){var s={};function p(l){if(s[l])return s[l].exports;var f=s[l]={i:l,l:!1,exports:{}};return _[l].call(f.exports,f,f.exports,p),f.l=!0,f.exports}return p.m=_,p.c=s,p.d=function(l,f,c){p.o(l,f)||Object.defineProperty(l,f,{enumerable:!0,get:c})},p.r=function(l){typeof Symbol!="undefined"&&Symbol.toStringTag&&Object.defineProperty(l,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(l,"__esModule",{value:!0})},p.t=function(l,f){if(1&f&&(l=p(l)),8&f||4&f&&typeof l=="object"&&l&&l.__esModule)return l;var c=Object.create(null);if(p.r(c),Object.defineProperty(c,"default",{enumerable:!0,value:l}),2&f&&typeof l!="string")for(var i in l)p.d(c,i,function(t){return l[t]}.bind(null,i));return c},p.n=function(l){var f=l&&l.__esModule?function(){return l.default}:function(){return l};return p.d(f,"a",f),f},p.o=function(l,f){return Object.prototype.hasOwnProperty.call(l,f)},p.p="",p(p.s=46)}([function(_,s,p){Object.defineProperty(s,"__esModule",{value:!0});var l=p(1),f=p(12),c=p(6),i=p(7),t=p(2),e=function(){function o(n,a,r){var u=r===void 0?{}:r,h=u.keepSpace,d=h!==void 0&&h,y=u.prevTagName,v=y===void 0?"":y,g=u.nextTagName,b=g===void 0?"":g,O=u.prevTagStr,T=O===void 0?"":O,x=u.nextTagStr,j=x===void 0?"":x,P=u.parentTag,S=P===void 0?"":P,m=u.isFirstSubTag,w=m===void 0||m,M=u.calcLeading,E=M!==void 0&&M,C=u.leadingSpace,N=C===void 0?"":C,L=u.layer,J=L===void 0?1:L,A=u.noWrap,z=A!==void 0&&A,H=u.prevHasEndSpace,K=H!==void 0&&H,W=u.prevHasStartSpace,Y=W!==void 0&&W,V=u.match,Z=V===void 0?null:V,R=u.indentSpace,Q=R===void 0?"":R,I=u.language,X=I===void 0?"":I,D=u.count,tt=D===void 0?1:D,q=u.tableColumnCount,et=q===void 0?0:q,U=u.noExtraLine,nt=U!==void 0&&U,B=u.inTable,ot=B!==void 0&&B;if(this.tagName=a,this.rawStr=n,this.parentTag=S,this.prevTagName=v,this.nextTagName=b,this.prevTagStr=T,this.nextTagStr=j,this.isFirstSubTag=w,this.calcLeading=E,this.leadingSpace=N,this.layer=J,this.noWrap=z,this.match=Z,this.indentSpace=Q,this.language=X,this.count=tt,this.inTable=ot,this.tableColumnCount=et,this.noExtraLine=nt,this.prevHasEndSpace=K,this.prevHasStartSpace=Y,this.hasStartSpace=!1,this.hasEndSpace=!1,this.keepSpace=d,!this.__detectStr__(n,this.tagName))return this.attrs={},void(this.innerHTML="");var F=this.__fetchTagAttrAndInnerHTML__(n),rt=F.attr,k=F.innerHTML;k.startsWith(" ")&&(0,l.isSpacePassingTag)(a)&&(this.hasStartSpace=!0),k.endsWith(" ")&&(0,l.isSpacePassingTag)(a)&&(this.hasEndSpace=!0),this.attrs=rt,this.innerHTML=k}return o.prototype.__detectStr__=function(n,a){if(n[0]!=="<")return"Not a valid tag, current tag name: ".concat(this.tagName,", tag content: ").concat(n),!1;for(var r="",u=!1,h=1;h<n.length&&n[h]!==">";h++)!u&&/(\s|\/)/.test(n[h])&&(u=!0),u||(r+=n[h]);return r===a},o.prototype.__fetchTagAttrAndInnerHTML__=function(n){for(var a="",r=1;r<n.length&&n[r]!==">";r++)a+=n[r];for(var u=n.slice(r+1),h="",d=-1,y=u.length-1;y>=0;y--)if((h=u[y]+h).startsWith("</")){h.startsWith("</"+this.tagName+">")&&(d=y);break}d===-1&&(0,l.isSelfClosing)(this.tagName)&&this.tagName;var v=(0,l.getTagAttributes)(a);return this.tagName&&delete v[this.tagName],{attr:v,innerHTML:u.slice(0,d)}},o.prototype.__onlyLeadingSpace__=function(n){n=n.trim();for(var a=0;a<n.length;a++)if(n[a]!==c.SINGLE)return!1;return!0},o.prototype.__isEmpty__=function(n){return!this.keepSpace&&(n===""&&this.tagName!=="td"||this.calcLeading&&this.__onlyLeadingSpace__(n))},o.prototype.getValidSubTagName=function(n){return n},o.prototype.beforeParse=function(){var n=t.default.get().tagListener;if(n){var a=n(this.tagName,{parentTag:this.parentTag,prevTagName:this.prevTagName,nextTagName:this.nextTagName,isFirstSubTag:this.isFirstSubTag,attrs:this.attrs,innerHTML:this.innerHTML,language:this.language,match:this.match,isSelfClosing:!1}),r=a.attrs,u=a.language,h=a.match;this.attrs=r,typeof u=="string"&&(this.language=u),typeof h!="undefined"&&(this.match=h)}return""},o.prototype.parseValidSubTag=function(n,a,r){var u=new((0,l.getTagConstructor)(a))(n,a,r);return[u.exec(),u]},o.prototype.parseOnlyString=function(n,a,r){var u=new f.default(n,a,r);return[u.exec(),u]},o.prototype.afterParsed=function(n){return n},o.prototype.slim=function(n){return this.keepSpace?n:n.trim()},o.prototype.beforeMergeSpace=function(n){return n},o.prototype.mergeSpace=function(n,a,r){return this.keepSpace&&this.tagName!=="pre"?n.endsWith(`
|
||||
import{c as it,g as at}from"./@babel.9410f858.js";var G={exports:{}};(function($,ut){(function(_,s){$.exports=s()})(it,function(){return function(_){var s={};function p(l){if(s[l])return s[l].exports;var f=s[l]={i:l,l:!1,exports:{}};return _[l].call(f.exports,f,f.exports,p),f.l=!0,f.exports}return p.m=_,p.c=s,p.d=function(l,f,c){p.o(l,f)||Object.defineProperty(l,f,{enumerable:!0,get:c})},p.r=function(l){typeof Symbol!="undefined"&&Symbol.toStringTag&&Object.defineProperty(l,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(l,"__esModule",{value:!0})},p.t=function(l,f){if(1&f&&(l=p(l)),8&f||4&f&&typeof l=="object"&&l&&l.__esModule)return l;var c=Object.create(null);if(p.r(c),Object.defineProperty(c,"default",{enumerable:!0,value:l}),2&f&&typeof l!="string")for(var i in l)p.d(c,i,function(t){return l[t]}.bind(null,i));return c},p.n=function(l){var f=l&&l.__esModule?function(){return l.default}:function(){return l};return p.d(f,"a",f),f},p.o=function(l,f){return Object.prototype.hasOwnProperty.call(l,f)},p.p="",p(p.s=46)}([function(_,s,p){Object.defineProperty(s,"__esModule",{value:!0});var l=p(1),f=p(12),c=p(6),i=p(7),t=p(2),e=function(){function o(n,a,r){var u=r===void 0?{}:r,h=u.keepSpace,d=h!==void 0&&h,y=u.prevTagName,v=y===void 0?"":y,g=u.nextTagName,b=g===void 0?"":g,O=u.prevTagStr,T=O===void 0?"":O,x=u.nextTagStr,j=x===void 0?"":x,P=u.parentTag,S=P===void 0?"":P,m=u.isFirstSubTag,w=m===void 0||m,M=u.calcLeading,E=M!==void 0&&M,C=u.leadingSpace,N=C===void 0?"":C,L=u.layer,J=L===void 0?1:L,A=u.noWrap,z=A!==void 0&&A,H=u.prevHasEndSpace,K=H!==void 0&&H,W=u.prevHasStartSpace,Y=W!==void 0&&W,V=u.match,Z=V===void 0?null:V,R=u.indentSpace,Q=R===void 0?"":R,I=u.language,X=I===void 0?"":I,D=u.count,tt=D===void 0?1:D,q=u.tableColumnCount,et=q===void 0?0:q,U=u.noExtraLine,nt=U!==void 0&&U,B=u.inTable,ot=B!==void 0&&B;if(this.tagName=a,this.rawStr=n,this.parentTag=S,this.prevTagName=v,this.nextTagName=b,this.prevTagStr=T,this.nextTagStr=j,this.isFirstSubTag=w,this.calcLeading=E,this.leadingSpace=N,this.layer=J,this.noWrap=z,this.match=Z,this.indentSpace=Q,this.language=X,this.count=tt,this.inTable=ot,this.tableColumnCount=et,this.noExtraLine=nt,this.prevHasEndSpace=K,this.prevHasStartSpace=Y,this.hasStartSpace=!1,this.hasEndSpace=!1,this.keepSpace=d,!this.__detectStr__(n,this.tagName))return this.attrs={},void(this.innerHTML="");var F=this.__fetchTagAttrAndInnerHTML__(n),rt=F.attr,k=F.innerHTML;k.startsWith(" ")&&(0,l.isSpacePassingTag)(a)&&(this.hasStartSpace=!0),k.endsWith(" ")&&(0,l.isSpacePassingTag)(a)&&(this.hasEndSpace=!0),this.attrs=rt,this.innerHTML=k}return o.prototype.__detectStr__=function(n,a){if(n[0]!=="<")return"Not a valid tag, current tag name: ".concat(this.tagName,", tag content: ").concat(n),!1;for(var r="",u=!1,h=1;h<n.length&&n[h]!==">";h++)!u&&/(\s|\/)/.test(n[h])&&(u=!0),u||(r+=n[h]);return r===a},o.prototype.__fetchTagAttrAndInnerHTML__=function(n){for(var a="",r=1;r<n.length&&n[r]!==">";r++)a+=n[r];for(var u=n.slice(r+1),h="",d=-1,y=u.length-1;y>=0;y--)if((h=u[y]+h).startsWith("</")){h.startsWith("</"+this.tagName+">")&&(d=y);break}d===-1&&(0,l.isSelfClosing)(this.tagName)&&this.tagName;var v=(0,l.getTagAttributes)(a);return this.tagName&&delete v[this.tagName],{attr:v,innerHTML:u.slice(0,d)}},o.prototype.__onlyLeadingSpace__=function(n){n=n.trim();for(var a=0;a<n.length;a++)if(n[a]!==c.SINGLE)return!1;return!0},o.prototype.__isEmpty__=function(n){return!this.keepSpace&&(n===""&&this.tagName!=="td"||this.calcLeading&&this.__onlyLeadingSpace__(n))},o.prototype.getValidSubTagName=function(n){return n},o.prototype.beforeParse=function(){var n=t.default.get().tagListener;if(n){var a=n(this.tagName,{parentTag:this.parentTag,prevTagName:this.prevTagName,nextTagName:this.nextTagName,isFirstSubTag:this.isFirstSubTag,attrs:this.attrs,innerHTML:this.innerHTML,language:this.language,match:this.match,isSelfClosing:!1}),r=a.attrs,u=a.language,h=a.match;this.attrs=r,typeof u=="string"&&(this.language=u),typeof h!="undefined"&&(this.match=h)}return""},o.prototype.parseValidSubTag=function(n,a,r){var u=new((0,l.getTagConstructor)(a))(n,a,r);return[u.exec(),u]},o.prototype.parseOnlyString=function(n,a,r){var u=new f.default(n,a,r);return[u.exec(),u]},o.prototype.afterParsed=function(n){return n},o.prototype.slim=function(n){return this.keepSpace?n:n.trim()},o.prototype.beforeMergeSpace=function(n){return n},o.prototype.mergeSpace=function(n,a,r){return this.keepSpace&&this.tagName!=="pre"?n.endsWith(`
|
||||
`)?n:n+r.replace(/\n+/g,`
|
||||
`):a+n+r},o.prototype.afterMergeSpace=function(n){return n},o.prototype.beforeReturn=function(n){return!((0,l.isSpacePassingTag)(this.prevTagName)&&this.prevHasEndSpace||(0,l.isSpacePassingTag)(this.tagName)&&this.hasStartSpace)||/^\s+/.test(n)||/\s+$/.test(this.prevTagStr)?n:" "+n},o.prototype.exec=function(n,a){n===void 0&&(n=""),a===void 0&&(a="");for(var r=this.beforeParse(),u=(0,l.generateGetNextValidTag)(this.innerHTML),h=u(),d=h[0],y=h[1],v=null,g=!1,b=!1;y!=="";){var O,T=u(),x=T[0],j=T[1],P={parentTag:this.tagName,nextTagName:x,nextTagStr:j,prevTagName:v,prevTagStr:r,prevHasEndSpace:b,prevHasStartSpace:g,leadingSpace:this.leadingSpace,layer:this.layer,keepSpace:this.keepSpace,inTable:this.inTable,calcLeading:(this.tagName==="li"||this.tagName==="ol"||this.tagName==="ul")&&this.calcLeading},S=void 0,m=void 0;d!=null?(S=(O=this.parseValidSubTag(y,d,P))[0],m=O[1]):(S=(O=this.parseOnlyString(y,d,P))[0],m=O[1]),b=(m==null?void 0:m.hasEndSpace)||!1,g=(m==null?void 0:m.hasStartSpace)||!1;var w=this.getValidSubTagName(d);d=x,y=j,w==null&&this.__isEmpty__(S)||(!this.keepSpace&&(0,i.default)(v)&&(0,i.default)(w)&&(r=r.replace(/\n+$/,`
|
||||
`),S=S.replace(/^\n+/,`
|
||||
File diff suppressed because one or more lines are too long
1
public/js/build/index.7770f938.js
vendored
Normal file
1
public/js/build/index.7770f938.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{_ as m}from"./openpgp_hi.15f91b1d.js";import{e as n}from"./index.40a8e116.js";import{n as p}from"./app.20ce4f8e.js";import"./jquery.26755d2b.js";import"./@babel.9410f858.js";import"./dayjs.29a2c04b.js";import"./localforage.a7f8d307.js";import"./markdown-it.0450edb4.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.acea8861.js";import"./vue.adba9046.js";import"./vuex.cc7cb26e.js";import"./axios.37c7f908.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.ca2ea0cc.js";import"./parchment.d5c5924e.js";import"./quill-delta.385a10bf.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.3cc09a31.js";import"./lodash.isequal.dbdc2157.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.76e3a28b.js";import"./quill-mention-hi.4eeb5a2d.js";import"./view-design-hi.f1128b4d.js";import"./html-to-md.f297036e.js";import"./lodash.8fcd6fd4.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.fd43a5bc.js";import"./clipboard.37b37361.js";import"./vuedraggable.f464b992.js";import"./sortablejs.3488b922.js";import"./vue-resize-observer.5af23a43.js";import"./element-sea.f8a64907.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.5d591c5f.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.dca2b951.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var a=function(){var t=this,o=t.$createElement,i=t._self._c||o;return t.ready?i("VEditor",{attrs:{leftToolbar:t.leftToolbar,rightToolbar:t.rightToolbar,tocNavPositionRight:t.tocNavPositionRight,includeLevel:t.includeLevel},model:{value:t.content,callback:function(e){t.content=e},expression:"content"}}):i("Loading")},s=[];const l={name:"VMEditor",mixins:[n],components:{VEditor:()=>m(()=>import("./editor.0e956fa2.js"),["js/build/editor.0e956fa2.js","js/build/editor.90492550.css","js/build/@kangc.b5fe0a56.js","js/build/@kangc.d8464d83.css","js/build/@babel.9410f858.js","js/build/vue.adba9046.js","js/build/copy-to-clipboard.a53c061d.js","js/build/toggle-selection.d2487283.js","js/build/prismjs.94ec9288.js","js/build/app.20ce4f8e.js","js/build/app.99bc3a02.css","js/build/jquery.26755d2b.js","js/build/dayjs.29a2c04b.js","js/build/localforage.a7f8d307.js","js/build/markdown-it.0450edb4.js","js/build/mdurl.ce6c1dd8.js","js/build/uc.micro.8d343c98.js","js/build/entities.48a44fec.js","js/build/linkify-it.c5e8196e.js","js/build/punycode.js.4b3f125a.js","js/build/highlight.js.cbbfb885.js","js/build/markdown-it-link-attributes.e1d5d151.js","js/build/@traptitech.acea8861.js","js/build/vuex.cc7cb26e.js","js/build/openpgp_hi.15f91b1d.js","js/build/axios.37c7f908.js","js/build/mitt.1ea0a2a3.js","js/build/quill-hi.ca2ea0cc.js","js/build/parchment.d5c5924e.js","js/build/quill-delta.385a10bf.js","js/build/fast-diff.f17881f3.js","js/build/lodash.clonedeep.3cc09a31.js","js/build/lodash.isequal.dbdc2157.js","js/build/eventemitter3.78b735ad.js","js/build/lodash-es.76e3a28b.js","js/build/quill-mention-hi.4eeb5a2d.js","js/build/view-design-hi.f1128b4d.js","js/build/html-to-md.f297036e.js","js/build/lodash.8fcd6fd4.js","js/build/vue-router.2d566cd7.js","js/build/vue-clipboard2.fd43a5bc.js","js/build/clipboard.37b37361.js","js/build/vuedraggable.f464b992.js","js/build/sortablejs.3488b922.js","js/build/vue-resize-observer.5af23a43.js","js/build/element-sea.f8a64907.js","js/build/deepmerge.cecf392e.js","js/build/resize-observer-polyfill.5d591c5f.js","js/build/throttle-debounce.7c3948b2.js","js/build/babel-helper-vue-jsx-merge-props.5ed215c3.js","js/build/normalize-wheel.2a034b9f.js","js/build/async-validator.dca2b951.js","js/build/babel-runtime.4773988a.js","js/build/core-js.314b4a1d.js","js/build/codemirror.9d10b9e4.js","js/build/codemirror.9ace6687.css","js/build/index.40a8e116.js","js/build/ImgUpload.a3251af4.js"])},data(){return{ready:!1,content:""}},async mounted(){await $A.loadScriptS(["js/katex/katex.min.js","js/katex/katex.min.css","js/mermaid.min.js"]),this.ready=!0},watch:{value:{handler(t){t==null&&(t=""),this.content=t},immediate:!0},content(t){this.$emit("input",t)}}},r={};var c=p(l,a,s,!1,_,null,null,null);function _(t){for(let o in r)this[o]=r[o]}var nt=function(){return c.exports}();export{nt as default};
|
||||
1
public/js/build/index.79ce7fd0.js
vendored
1
public/js/build/index.79ce7fd0.js
vendored
@@ -1 +0,0 @@
|
||||
import{_ as m}from"./openpgp_hi.15f91b1d.js";import{e as n}from"./index.40a8e116.js";import{n as p}from"./app.5029512e.js";import"./jquery.2060430b.js";import"./@babel.ad55b12f.js";import"./dayjs.dfa73531.js";import"./localforage.3e4ebad6.js";import"./markdown-it.bda97caf.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.561c583d.js";import"./vue.baba6da0.js";import"./vuex.cc7cb26e.js";import"./axios.554fcc10.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.978f208d.js";import"./parchment.d5c5924e.js";import"./quill-delta.4f1e4697.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.8fb065bb.js";import"./lodash.isequal.84238944.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.df04b444.js";import"./quill-mention-hi.2a6582e4.js";import"./view-design-hi.e9360295.js";import"./html-to-md.96d5de37.js";import"./lodash.2fa8f497.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.89894d1b.js";import"./clipboard.6caea48c.js";import"./vuedraggable.e8809463.js";import"./sortablejs.b1e23af3.js";import"./vue-resize-observer.df5b985e.js";import"./element-sea.9d03b085.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.18409ee0.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.e1b191c9.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var a=function(){var t=this,o=t.$createElement,i=t._self._c||o;return t.ready?i("VEditor",{attrs:{leftToolbar:t.leftToolbar,rightToolbar:t.rightToolbar,tocNavPositionRight:t.tocNavPositionRight,includeLevel:t.includeLevel},model:{value:t.content,callback:function(e){t.content=e},expression:"content"}}):i("Loading")},s=[];const l={name:"VMEditor",mixins:[n],components:{VEditor:()=>m(()=>import("./editor.13391917.js"),["js/build/editor.13391917.js","js/build/editor.90492550.css","js/build/@kangc.12b15229.js","js/build/@kangc.d8464d83.css","js/build/@babel.ad55b12f.js","js/build/vue.baba6da0.js","js/build/copy-to-clipboard.a53c061d.js","js/build/toggle-selection.d2487283.js","js/build/prismjs.069537ae.js","js/build/app.5029512e.js","js/build/app.fbf39e7c.css","js/build/jquery.2060430b.js","js/build/dayjs.dfa73531.js","js/build/localforage.3e4ebad6.js","js/build/markdown-it.bda97caf.js","js/build/mdurl.ce6c1dd8.js","js/build/uc.micro.8d343c98.js","js/build/entities.48a44fec.js","js/build/linkify-it.c5e8196e.js","js/build/punycode.js.4b3f125a.js","js/build/highlight.js.cbbfb885.js","js/build/markdown-it-link-attributes.e1d5d151.js","js/build/@traptitech.561c583d.js","js/build/vuex.cc7cb26e.js","js/build/openpgp_hi.15f91b1d.js","js/build/axios.554fcc10.js","js/build/mitt.1ea0a2a3.js","js/build/quill-hi.978f208d.js","js/build/parchment.d5c5924e.js","js/build/quill-delta.4f1e4697.js","js/build/fast-diff.f17881f3.js","js/build/lodash.clonedeep.8fb065bb.js","js/build/lodash.isequal.84238944.js","js/build/eventemitter3.78b735ad.js","js/build/lodash-es.df04b444.js","js/build/quill-mention-hi.2a6582e4.js","js/build/view-design-hi.e9360295.js","js/build/html-to-md.96d5de37.js","js/build/lodash.2fa8f497.js","js/build/vue-router.2d566cd7.js","js/build/vue-clipboard2.89894d1b.js","js/build/clipboard.6caea48c.js","js/build/vuedraggable.e8809463.js","js/build/sortablejs.b1e23af3.js","js/build/vue-resize-observer.df5b985e.js","js/build/element-sea.9d03b085.js","js/build/deepmerge.cecf392e.js","js/build/resize-observer-polyfill.18409ee0.js","js/build/throttle-debounce.7c3948b2.js","js/build/babel-helper-vue-jsx-merge-props.5ed215c3.js","js/build/normalize-wheel.2a034b9f.js","js/build/async-validator.e1b191c9.js","js/build/babel-runtime.4773988a.js","js/build/core-js.314b4a1d.js","js/build/codemirror.99a3984d.js","js/build/codemirror.9ace6687.css","js/build/index.40a8e116.js","js/build/ImgUpload.cb2bd871.js"])},data(){return{ready:!1,content:""}},async mounted(){await $A.loadScriptS(["js/katex/katex.min.js","js/katex/katex.min.css","js/mermaid.min.js"]),this.ready=!0},watch:{value:{handler(t){t==null&&(t=""),this.content=t},immediate:!0},content(t){this.$emit("input",t)}}},r={};var c=p(l,a,s,!1,_,null,null,null);function _(t){for(let o in r)this[o]=r[o]}var nt=function(){return c.exports}();export{nt as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as m}from"./app.5029512e.js";import"./jquery.2060430b.js";import"./@babel.ad55b12f.js";import"./dayjs.dfa73531.js";import"./localforage.3e4ebad6.js";import"./markdown-it.bda97caf.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.561c583d.js";import"./vue.baba6da0.js";import"./vuex.cc7cb26e.js";import"./openpgp_hi.15f91b1d.js";import"./axios.554fcc10.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.978f208d.js";import"./parchment.d5c5924e.js";import"./quill-delta.4f1e4697.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.8fb065bb.js";import"./lodash.isequal.84238944.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.df04b444.js";import"./quill-mention-hi.2a6582e4.js";import"./view-design-hi.e9360295.js";import"./html-to-md.96d5de37.js";import"./lodash.2fa8f497.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.89894d1b.js";import"./clipboard.6caea48c.js";import"./vuedraggable.e8809463.js";import"./sortablejs.b1e23af3.js";import"./vue-resize-observer.df5b985e.js";import"./element-sea.9d03b085.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.18409ee0.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.e1b191c9.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var e=function(){var t=this,o=t.$createElement,i=t._self._c||o;return i("div")},n=[];const p={data(){return{}},mounted(){if(/^https?:/i.test(window.location.protocol)){let t=null;if(this.$router.mode==="hash"?$A.stringLength(window.location.pathname)>2&&(t=`${window.location.origin}/#${window.location.pathname}${window.location.search}`):this.$router.mode==="history"&&$A.strExists(window.location.href,"/#/")&&(t=window.location.href.replace("/#/","/")),t)throw this.$store.dispatch("userUrl",t).then(o=>{window.location.href=o}),SyntaxError()}},activated(){this.start()},methods:{start(){this.userId>0?this.goForward({name:"manage-dashboard"},!0):this.goForward({name:"login"},!0)}}},r={};var a=m(p,e,n,!1,s,null,null,null);function s(t){for(let o in r)this[o]=r[o]}var rt=function(){return a.exports}();export{rt as default};
|
||||
import{n as m}from"./app.20ce4f8e.js";import"./jquery.26755d2b.js";import"./@babel.9410f858.js";import"./dayjs.29a2c04b.js";import"./localforage.a7f8d307.js";import"./markdown-it.0450edb4.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.acea8861.js";import"./vue.adba9046.js";import"./vuex.cc7cb26e.js";import"./openpgp_hi.15f91b1d.js";import"./axios.37c7f908.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.ca2ea0cc.js";import"./parchment.d5c5924e.js";import"./quill-delta.385a10bf.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.3cc09a31.js";import"./lodash.isequal.dbdc2157.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.76e3a28b.js";import"./quill-mention-hi.4eeb5a2d.js";import"./view-design-hi.f1128b4d.js";import"./html-to-md.f297036e.js";import"./lodash.8fcd6fd4.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.fd43a5bc.js";import"./clipboard.37b37361.js";import"./vuedraggable.f464b992.js";import"./sortablejs.3488b922.js";import"./vue-resize-observer.5af23a43.js";import"./element-sea.f8a64907.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.5d591c5f.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.dca2b951.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var e=function(){var t=this,o=t.$createElement,i=t._self._c||o;return i("div")},n=[];const p={data(){return{}},mounted(){if(/^https?:/i.test(window.location.protocol)){let t=null;if(this.$router.mode==="hash"?$A.stringLength(window.location.pathname)>2&&(t=`${window.location.origin}/#${window.location.pathname}${window.location.search}`):this.$router.mode==="history"&&$A.strExists(window.location.href,"/#/")&&(t=window.location.href.replace("/#/","/")),t)throw this.$store.dispatch("userUrl",t).then(o=>{window.location.href=o}),SyntaxError()}},activated(){this.start()},methods:{start(){this.userId>0?this.goForward({name:"manage-dashboard"},!0):this.goForward({name:"login"},!0)}}},r={};var a=m(p,e,n,!1,s,null,null,null);function s(t){for(let o in r)this[o]=r[o]}var rt=function(){return a.exports}();export{rt as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{c as Wr}from"./@babel.ad55b12f.js";var kn={exports:{}};/*!
|
||||
import{c as Wr}from"./@babel.9410f858.js";var kn={exports:{}};/*!
|
||||
* jQuery JavaScript Library v3.7.1
|
||||
* https://jquery.com/
|
||||
*
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{h as e,l as n,r as s,n as p}from"./app.5029512e.js";import{m as l}from"./vuex.cc7cb26e.js";import"./jquery.2060430b.js";import"./@babel.ad55b12f.js";import"./dayjs.dfa73531.js";import"./localforage.3e4ebad6.js";import"./markdown-it.bda97caf.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.561c583d.js";import"./vue.baba6da0.js";import"./openpgp_hi.15f91b1d.js";import"./axios.554fcc10.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.978f208d.js";import"./parchment.d5c5924e.js";import"./quill-delta.4f1e4697.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.8fb065bb.js";import"./lodash.isequal.84238944.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.df04b444.js";import"./quill-mention-hi.2a6582e4.js";import"./view-design-hi.e9360295.js";import"./html-to-md.96d5de37.js";import"./lodash.2fa8f497.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.89894d1b.js";import"./clipboard.6caea48c.js";import"./vuedraggable.e8809463.js";import"./sortablejs.b1e23af3.js";import"./vue-resize-observer.df5b985e.js";import"./element-sea.9d03b085.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.18409ee0.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.e1b191c9.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var u=function(){var t=this,a=t.$createElement,r=t._self._c||a;return r("div",{staticClass:"setting-item submit"},[r("Form",t._b({ref:"formData",attrs:{model:t.formData,rules:t.ruleData},nativeOn:{submit:function(o){o.preventDefault()}}},"Form",t.formOptions,!1),[r("FormItem",{attrs:{label:t.$L("\u9009\u62E9\u8BED\u8A00"),prop:"language"}},[r("Select",{attrs:{placeholder:t.$L("\u9009\u9879\u8BED\u8A00")},model:{value:t.formData.language,callback:function(o){t.$set(t.formData,"language",o)},expression:"formData.language"}},t._l(t.languageList,function(o,i){return r("Option",{key:i,attrs:{value:i}},[t._v(t._s(o))])}),1)],1)],1),r("div",{staticClass:"setting-footer"},[r("Button",{attrs:{loading:t.loadIng>0,type:"primary"},on:{click:t.submitForm}},[t._v(t._s(t.$L("\u63D0\u4EA4")))]),r("Button",{staticStyle:{"margin-left":"8px"},attrs:{loading:t.loadIng>0},on:{click:t.resetForm}},[t._v(t._s(t.$L("\u91CD\u7F6E")))])],1)],1)},f=[];const g={data(){return{loadIng:0,languageList:e,formData:{language:""},ruleData:{}}},mounted(){this.initData()},computed:{...l(["formOptions"])},methods:{initData(){this.$set(this.formData,"language",n),this.formData_bak=$A.cloneJSON(this.formData)},submitForm(){this.$refs.formData.validate(t=>{t&&s(this.formData.language)})},resetForm(){this.formData=$A.cloneJSON(this.formData_bak)}}},m={};var c=p(g,u,f,!1,_,null,null,null);function _(t){for(let a in m)this[a]=m[a]}var st=function(){return c.exports}();export{st as default};
|
||||
import{h as e,l as n,r as s,n as p}from"./app.20ce4f8e.js";import{m as l}from"./vuex.cc7cb26e.js";import"./jquery.26755d2b.js";import"./@babel.9410f858.js";import"./dayjs.29a2c04b.js";import"./localforage.a7f8d307.js";import"./markdown-it.0450edb4.js";import"./mdurl.ce6c1dd8.js";import"./uc.micro.8d343c98.js";import"./entities.48a44fec.js";import"./linkify-it.c5e8196e.js";import"./punycode.js.4b3f125a.js";import"./highlight.js.cbbfb885.js";import"./markdown-it-link-attributes.e1d5d151.js";import"./@traptitech.acea8861.js";import"./vue.adba9046.js";import"./openpgp_hi.15f91b1d.js";import"./axios.37c7f908.js";import"./mitt.1ea0a2a3.js";import"./quill-hi.ca2ea0cc.js";import"./parchment.d5c5924e.js";import"./quill-delta.385a10bf.js";import"./fast-diff.f17881f3.js";import"./lodash.clonedeep.3cc09a31.js";import"./lodash.isequal.dbdc2157.js";import"./eventemitter3.78b735ad.js";import"./lodash-es.76e3a28b.js";import"./quill-mention-hi.4eeb5a2d.js";import"./view-design-hi.f1128b4d.js";import"./html-to-md.f297036e.js";import"./lodash.8fcd6fd4.js";import"./vue-router.2d566cd7.js";import"./vue-clipboard2.fd43a5bc.js";import"./clipboard.37b37361.js";import"./vuedraggable.f464b992.js";import"./sortablejs.3488b922.js";import"./vue-resize-observer.5af23a43.js";import"./element-sea.f8a64907.js";import"./deepmerge.cecf392e.js";import"./resize-observer-polyfill.5d591c5f.js";import"./throttle-debounce.7c3948b2.js";import"./babel-helper-vue-jsx-merge-props.5ed215c3.js";import"./normalize-wheel.2a034b9f.js";import"./async-validator.dca2b951.js";import"./babel-runtime.4773988a.js";import"./core-js.314b4a1d.js";var u=function(){var t=this,a=t.$createElement,r=t._self._c||a;return r("div",{staticClass:"setting-item submit"},[r("Form",t._b({ref:"formData",attrs:{model:t.formData,rules:t.ruleData},nativeOn:{submit:function(o){o.preventDefault()}}},"Form",t.formOptions,!1),[r("FormItem",{attrs:{label:t.$L("\u9009\u62E9\u8BED\u8A00"),prop:"language"}},[r("Select",{attrs:{placeholder:t.$L("\u9009\u9879\u8BED\u8A00")},model:{value:t.formData.language,callback:function(o){t.$set(t.formData,"language",o)},expression:"formData.language"}},t._l(t.languageList,function(o,i){return r("Option",{key:i,attrs:{value:i}},[t._v(t._s(o))])}),1)],1)],1),r("div",{staticClass:"setting-footer"},[r("Button",{attrs:{loading:t.loadIng>0,type:"primary"},on:{click:t.submitForm}},[t._v(t._s(t.$L("\u63D0\u4EA4")))]),r("Button",{staticStyle:{"margin-left":"8px"},attrs:{loading:t.loadIng>0},on:{click:t.resetForm}},[t._v(t._s(t.$L("\u91CD\u7F6E")))])],1)],1)},f=[];const g={data(){return{loadIng:0,languageList:e,formData:{language:""},ruleData:{}}},mounted(){this.initData()},computed:{...l(["formOptions"])},methods:{initData(){this.$set(this.formData,"language",n),this.formData_bak=$A.cloneJSON(this.formData)},submitForm(){this.$refs.formData.validate(t=>{t&&s(this.formData.language)})},resetForm(){this.formData=$A.cloneJSON(this.formData_bak)}}},m={};var c=p(g,u,f,!1,_,null,null,null);function _(t){for(let a in m)this[a]=m[a]}var st=function(){return c.exports}();export{st as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{c as ne,d as te}from"./@babel.ad55b12f.js";var Fe={exports:{}};/*!
|
||||
import{c as ne,d as te}from"./@babel.9410f858.js";var Fe={exports:{}};/*!
|
||||
localForage -- Offline Storage, Improved
|
||||
Version 1.10.0
|
||||
https://localforage.github.io/localForage
|
||||
27
public/js/build/lodash.2fa8f497.js
vendored
27
public/js/build/lodash.2fa8f497.js
vendored
File diff suppressed because one or more lines are too long
27
public/js/build/lodash.8fcd6fd4.js
vendored
Normal file
27
public/js/build/lodash.8fcd6fd4.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user